add an even more compact entry layout

This commit is contained in:
Athou
2023-04-26 22:39:09 +02:00
parent c15db54d5a
commit 807b1f62a1
6 changed files with 18833 additions and 18813 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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"
}
} }

View File

@@ -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"

View File

@@ -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>
)} )}

View File

@@ -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: (

View File

@@ -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)