mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
add an even more compact entry layout
This commit is contained in:
37441
commafeed-client/package-lock.json
generated
37441
commafeed-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,80 +1,81 @@
|
|||||||
{
|
{
|
||||||
"name": "commafeed-client",
|
"name": "commafeed-client",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"dev:typescript": "tsc --watch",
|
"dev:typescript": "tsc --watch",
|
||||||
"build": "npm run i18n:compile && tsc && vite build",
|
"build": "npm run i18n:compile && tsc && vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"test:ci": "vitest run",
|
"test:ci": "vitest run",
|
||||||
"eslint": "eslint --ext=.js,.jsx,.ts,.tsx src",
|
"eslint": "eslint --ext=.js,.jsx,.ts,.tsx src",
|
||||||
"i18n": "npm run i18n:extract && npm run i18n:compile",
|
"i18n": "npm run i18n:extract && npm run i18n:compile",
|
||||||
"i18n:extract": "lingui extract --clean",
|
"i18n:extract": "lingui extract --clean",
|
||||||
"i18n:compile": "lingui compile --typescript",
|
"i18n:compile": "lingui compile --typescript",
|
||||||
"postinstall": "npm run i18n:compile"
|
"postinstall": "npm run i18n:compile"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
"@fontsource/open-sans": "^4.5.14",
|
"@fontsource/open-sans": "^4.5.14",
|
||||||
"@lingui/core": "^3.17.0",
|
"@lingui/core": "^3.17.0",
|
||||||
"@lingui/macro": "^3.17.0",
|
"@lingui/macro": "^3.17.0",
|
||||||
"@lingui/react": "^3.17.0",
|
"@lingui/react": "^3.17.0",
|
||||||
"@mantine/core": "^5.10.3",
|
"@mantine/core": "^5.10.3",
|
||||||
"@mantine/form": "^5.10.3",
|
"@mantine/form": "^5.10.3",
|
||||||
"@mantine/hooks": "^5.10.3",
|
"@mantine/hooks": "^5.10.3",
|
||||||
"@mantine/modals": "^5.10.3",
|
"@mantine/modals": "^5.10.3",
|
||||||
"@mantine/notifications": "^5.10.3",
|
"@mantine/notifications": "^5.10.3",
|
||||||
"@mantine/spotlight": "^5.10.3",
|
"@mantine/spotlight": "^5.10.3",
|
||||||
"@reduxjs/toolkit": "^1.9.2",
|
"@mantine/styles": "^5.10.3",
|
||||||
"axios": "^1.3.2",
|
"@reduxjs/toolkit": "^1.9.2",
|
||||||
"dayjs": "^1.11.7",
|
"axios": "^1.3.2",
|
||||||
"interweave": "^13.0.0",
|
"dayjs": "^1.11.7",
|
||||||
"lodash": "^4.17.21",
|
"interweave": "^13.0.0",
|
||||||
"make-plural": "^7.2.0",
|
"lodash": "^4.17.21",
|
||||||
"mousetrap": "^1.6.5",
|
"make-plural": "^7.2.0",
|
||||||
"react": "^18.2.0",
|
"mousetrap": "^1.6.5",
|
||||||
"react-async-hook": "^4.0.0",
|
"react": "^18.2.0",
|
||||||
"react-contexify": "^6.0.0",
|
"react-async-hook": "^4.0.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-contexify": "^6.0.0",
|
||||||
"react-icons": "^4.7.1",
|
"react-dom": "^18.2.0",
|
||||||
"react-infinite-scroller": "^1.2.6",
|
"react-icons": "^4.7.1",
|
||||||
"react-redux": "^8.0.5",
|
"react-infinite-scroller": "^1.2.6",
|
||||||
"react-router-dom": "^6.8.0",
|
"react-redux": "^8.0.5",
|
||||||
"react-swipeable": "^7.0.0",
|
"react-router-dom": "^6.8.0",
|
||||||
"swagger-ui-react": "^4.15.5",
|
"react-swipeable": "^7.0.0",
|
||||||
"tinycon": "^0.6.8",
|
"swagger-ui-react": "^4.15.5",
|
||||||
"websocket-heartbeat-js": "^1.1.1"
|
"tinycon": "^0.6.8",
|
||||||
},
|
"websocket-heartbeat-js": "^1.1.1"
|
||||||
"devDependencies": {
|
},
|
||||||
"@lingui/cli": "^3.17.0",
|
"devDependencies": {
|
||||||
"@types/eslint": "^8.21.0",
|
"@lingui/cli": "^3.17.0",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/eslint": "^8.21.0",
|
||||||
"@types/mousetrap": "^1.6.11",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/react": "^18.0.27",
|
"@types/mousetrap": "^1.6.11",
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react": "^18.0.27",
|
||||||
"@types/react-infinite-scroller": "^1.2.3",
|
"@types/react-dom": "^18.0.10",
|
||||||
"@types/swagger-ui-react": "^4.11.0",
|
"@types/react-infinite-scroller": "^1.2.3",
|
||||||
"@types/tinycon": "^0.6.3",
|
"@types/swagger-ui-react": "^4.11.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
"@types/tinycon": "^0.6.3",
|
||||||
"@typescript-eslint/parser": "^5.50.0",
|
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||||
"@vitejs/plugin-react": "^3.1.0",
|
"@typescript-eslint/parser": "^5.50.0",
|
||||||
"eslint": "^8.33.0",
|
"@vitejs/plugin-react": "^3.1.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint": "^8.33.0",
|
||||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"eslint-config-react-app": "^7.0.1",
|
"eslint-config-prettier": "^8.6.0",
|
||||||
"eslint-plugin-hooks": "^0.4.3",
|
"eslint-config-react-app": "^7.0.1",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-hooks": "^0.4.3",
|
||||||
"prettier": "^2.8.3",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"rollup-plugin-visualizer": "^5.9.0",
|
"prettier": "^2.8.3",
|
||||||
"typescript": "^4.9.5",
|
"rollup-plugin-visualizer": "^5.9.0",
|
||||||
"vite": "^4.1.1",
|
"typescript": "^4.9.5",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite": "^4.1.1",
|
||||||
"vite-tsconfig-paths": "^4.0.5",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vitest": "^0.28.4",
|
"vite-tsconfig-paths": "^4.0.5",
|
||||||
"vitest-mock-extended": "^1.0.9"
|
"vitest": "^0.28.4",
|
||||||
}
|
"vitest-mock-extended": "^1.0.9"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,4 +306,4 @@ export type ReadingMode = "all" | "unread"
|
|||||||
|
|
||||||
export type ReadingOrder = "asc" | "desc"
|
export type ReadingOrder = "asc" | "desc"
|
||||||
|
|
||||||
export type ViewMode = "title" | "cozy" | "expanded"
|
export type ViewMode = "title" | "cozy" | "detailed" | "expanded"
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
|
|||||||
import { Constants } from "app/constants"
|
import { Constants } from "app/constants"
|
||||||
import { markEntry } from "app/slices/entries"
|
import { markEntry } from "app/slices/entries"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { useAppDispatch, useAppSelector } from "app/store"
|
||||||
import { Entry } from "app/types"
|
import { Entry, ViewMode } from "app/types"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { useSwipeable } from "react-swipeable"
|
import { useSwipeable } from "react-swipeable"
|
||||||
|
import { MantineNumberSize } from "@mantine/styles"
|
||||||
import { FeedEntryBody } from "./FeedEntryBody"
|
import { FeedEntryBody } from "./FeedEntryBody"
|
||||||
import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
|
import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
|
||||||
import { FeedEntryContextMenu, useFeedEntryContextMenu } from "./FeedEntryContextMenu"
|
import { FeedEntryContextMenu, useFeedEntryContextMenu } from "./FeedEntryContextMenu"
|
||||||
@@ -18,16 +19,18 @@ interface FeedEntryProps {
|
|||||||
onHeaderClick: (e: React.MouseEvent) => void
|
onHeaderClick: (e: React.MouseEvent) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = createStyles((theme, props: FeedEntryProps & { compact: boolean }) => {
|
const useStyles = createStyles((theme, props: FeedEntryProps & { viewMode?: ViewMode }) => {
|
||||||
let backgroundColor
|
let backgroundColor
|
||||||
if (theme.colorScheme === "dark") backgroundColor = props.entry.read ? "inherit" : theme.colors.dark[5]
|
if (theme.colorScheme === "dark") backgroundColor = props.entry.read ? "inherit" : theme.colors.dark[5]
|
||||||
else backgroundColor = props.entry.read && !props.expanded ? theme.colors.gray[0] : "inherit"
|
else backgroundColor = props.entry.read && !props.expanded ? theme.colors.gray[0] : "inherit"
|
||||||
|
|
||||||
let marginY = theme.spacing.xs
|
let marginY = theme.spacing.xs
|
||||||
if (props.compact) marginY = 6
|
if (props.viewMode === "title") marginY = 2
|
||||||
|
else if (props.viewMode === "cozy") marginY = 6
|
||||||
|
|
||||||
let mobileMarginY = 6
|
let mobileMarginY = 6
|
||||||
if (props.compact) mobileMarginY = 4
|
if (props.viewMode === "title") mobileMarginY = 2
|
||||||
|
else if (props.viewMode === "cozy") mobileMarginY = 4
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
paper: {
|
paper: {
|
||||||
@@ -53,10 +56,7 @@ const useStyles = createStyles((theme, props: FeedEntryProps & { compact: boolea
|
|||||||
|
|
||||||
export function FeedEntry(props: FeedEntryProps) {
|
export function FeedEntry(props: FeedEntryProps) {
|
||||||
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
|
||||||
const compact = viewMode === "title"
|
const { classes } = useStyles({ ...props, viewMode })
|
||||||
const compactHeader = compact && !props.expanded
|
|
||||||
|
|
||||||
const { classes } = useStyles({ ...props, compact })
|
|
||||||
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
@@ -66,9 +66,15 @@ export function FeedEntry(props: FeedEntryProps) {
|
|||||||
|
|
||||||
const { onContextMenu } = useFeedEntryContextMenu(props.entry)
|
const { onContextMenu } = useFeedEntryContextMenu(props.entry)
|
||||||
|
|
||||||
const spacing = compact ? 8 : "xs"
|
let padding: MantineNumberSize = "xs"
|
||||||
const borderRadius = compact ? "xs" : "sm"
|
if (viewMode === "title") padding = 4
|
||||||
|
else if (viewMode === "cozy") padding = 8
|
||||||
|
|
||||||
|
let borderRadius: MantineNumberSize = "sm"
|
||||||
|
if (viewMode === "title") borderRadius = 0
|
||||||
|
else if (viewMode === "cozy") borderRadius = "xs"
|
||||||
|
|
||||||
|
const compactHeader = !props.expanded && (viewMode === "title" || viewMode === "cozy")
|
||||||
return (
|
return (
|
||||||
<Paper withBorder radius={borderRadius} className={classes.paper}>
|
<Paper withBorder radius={borderRadius} className={classes.paper}>
|
||||||
<Anchor
|
<Anchor
|
||||||
@@ -80,17 +86,17 @@ export function FeedEntry(props: FeedEntryProps) {
|
|||||||
onAuxClick={props.onHeaderClick}
|
onAuxClick={props.onHeaderClick}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
>
|
>
|
||||||
<Box p={spacing} {...swipeHandlers}>
|
<Box p={padding} {...swipeHandlers}>
|
||||||
{compactHeader && <FeedEntryCompactHeader entry={props.entry} />}
|
{compactHeader && <FeedEntryCompactHeader entry={props.entry} />}
|
||||||
{!compactHeader && <FeedEntryHeader entry={props.entry} expanded={props.expanded} />}
|
{!compactHeader && <FeedEntryHeader entry={props.entry} expanded={props.expanded} />}
|
||||||
</Box>
|
</Box>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
{props.expanded && (
|
{props.expanded && (
|
||||||
<Box px={spacing} pb={spacing}>
|
<Box px={padding} pb={padding}>
|
||||||
<Box className={classes.body} sx={{ direction: props.entry.rtl ? "rtl" : "ltr" }}>
|
<Box className={classes.body} sx={{ direction: props.entry.rtl ? "rtl" : "ltr" }}>
|
||||||
<FeedEntryBody entry={props.entry} />
|
<FeedEntryBody entry={props.entry} />
|
||||||
</Box>
|
</Box>
|
||||||
<Divider variant="dashed" my={spacing} />
|
<Divider variant="dashed" my={padding} />
|
||||||
<FeedEntryFooter entry={props.entry} />
|
<FeedEntryFooter entry={props.entry} />
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
TbHelp,
|
TbHelp,
|
||||||
TbLayoutList,
|
TbLayoutList,
|
||||||
TbList,
|
TbList,
|
||||||
|
TbListDetails,
|
||||||
TbMoon,
|
TbMoon,
|
||||||
TbNotes,
|
TbNotes,
|
||||||
TbPower,
|
TbPower,
|
||||||
@@ -54,6 +55,17 @@ const viewModeData: ViewModeControlItem[] = [
|
|||||||
</Group>
|
</Group>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "detailed",
|
||||||
|
label: (
|
||||||
|
<Group>
|
||||||
|
<TbListDetails size={iconSize} />
|
||||||
|
<Box ml={6}>
|
||||||
|
<Trans>Detailed</Trans>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: "expanded",
|
value: "expanded",
|
||||||
label: (
|
label: (
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class UserSettings extends AbstractModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum ViewMode {
|
public enum ViewMode {
|
||||||
title, cozy, expanded
|
title, cozy, detailed, expanded
|
||||||
}
|
}
|
||||||
|
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
@OneToOne(fetch = FetchType.LAZY)
|
||||||
|
|||||||
Reference in New Issue
Block a user