add initial support for expanded mode

This commit is contained in:
Athou
2022-08-23 13:42:28 +02:00
parent 4c18ebf61a
commit a1fb5871d1
7 changed files with 83 additions and 7 deletions

View File

@@ -35,7 +35,7 @@
"react-hooks/exhaustive-deps": [
"warn",
{
"additionalHooks": "(^useAsync$)"
"additionalHooks": "(^useAsync$|useDidUpdate)"
}
],

View File

@@ -3,7 +3,7 @@ import { showNotification } from "@mantine/notifications"
import { createAsyncThunk, createSlice, isAnyOf } from "@reduxjs/toolkit"
import { client } from "app/client"
import { RootState } from "app/store"
import { ReadingMode, ReadingOrder, Settings, SharingSettings, UserModel } from "app/types"
import { ReadingMode, ReadingOrder, Settings, SharingSettings, UserModel, ViewMode } from "app/types"
import { reloadEntries } from "./entries"
interface UserState {
@@ -33,6 +33,12 @@ export const changeReadingOrder = createAsyncThunk<void, ReadingOrder, { state:
thunkApi.dispatch(reloadEntries())
}
)
export const changeViewMode = createAsyncThunk<void, ViewMode, { state: RootState }>("settings/viewMode", (viewMode, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, viewMode })
thunkApi.dispatch(reloadEntries())
})
export const changeLanguage = createAsyncThunk<void, string, { state: RootState }>("settings/language", (language, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
@@ -82,6 +88,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.readingOrder = action.meta.arg
})
builder.addCase(changeViewMode.pending, (state, action) => {
if (!state.settings) return
state.settings.viewMode = action.meta.arg
})
builder.addCase(changeLanguage.pending, (state, action) => {
if (!state.settings) return
state.settings.language = action.meta.arg

View File

@@ -25,6 +25,7 @@ export function FeedEntries() {
const entriesTimestamp = useAppSelector(state => state.entries.timestamp)
const selectedEntryId = useAppSelector(state => state.entries.selectedEntryId)
const hasMore = useAppSelector(state => state.entries.hasMore)
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
const dispatch = useAppDispatch()
const selectedEntry = entries.find(e => e.id === selectedEntryId)
@@ -151,7 +152,7 @@ export function FeedEntries() {
refs.current[e.id] = el!
}}
>
<FeedEntry entry={e} expanded={!!e.expanded} />
<FeedEntry entry={e} expanded={!!e.expanded || viewMode === "expanded"} />
</div>
))}
</InfiniteScroll>

View File

@@ -1,9 +1,10 @@
import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
import { useDidUpdate } from "@mantine/hooks"
import { Constants } from "app/constants"
import { markEntry, selectEntry } from "app/slices/entries"
import { useAppDispatch, useAppSelector } from "app/store"
import { Entry } from "app/types"
import React, { useEffect, useRef } from "react"
import React, { useRef } from "react"
import { FeedEntryBody } from "./FeedEntryBody"
import { FeedEntryFooter } from "./FeedEntryFooter"
import { FeedEntryHeader } from "./FeedEntryHeader"
@@ -53,8 +54,9 @@ export function FeedEntry(props: FeedEntryProps) {
}
// scroll to entry when expanded
// we use useDidUpdate to avoid scrolling towards all entries during initial load when viewMode is "expanded"
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
useDidUpdate(() => {
setTimeout(() => {
if (!ref.current) return
if (!props.expanded) return

View File

@@ -1,16 +1,48 @@
import { Trans } from "@lingui/macro"
import { Divider, Menu, useMantineColorScheme } from "@mantine/core"
import { Box, Divider, Group, Menu, SegmentedControl, SegmentedControlItem, useMantineColorScheme } from "@mantine/core"
import { redirectToAbout, redirectToAdminUsers, redirectToMetrics, redirectToSettings } from "app/slices/redirect"
import { changeViewMode } from "app/slices/user"
import { useAppDispatch, useAppSelector } from "app/store"
import { ViewMode } from "app/types"
import { useState } from "react"
import { TbChartLine, TbHelp, TbMoon, TbPower, TbSettings, TbSun, TbUsers } from "react-icons/tb"
import { TbChartLine, TbHelp, TbList, TbMoon, TbNotes, TbPower, TbSettings, TbSun, TbUsers } from "react-icons/tb"
interface ProfileMenuProps {
control: React.ReactElement
}
interface ViewModeControlItem extends SegmentedControlItem {
value: ViewMode
}
const viewModeData: ViewModeControlItem[] = [
{
value: "title",
label: (
<Group>
<TbList />
<Box ml={6}>
<Trans>Compact</Trans>
</Box>
</Group>
),
},
{
value: "expanded",
label: (
<Group>
<TbNotes />
<Box ml={6}>
<Trans>Expanded</Trans>
</Box>
</Group>
),
},
]
export function ProfileMenu(props: ProfileMenuProps) {
const [opened, setOpened] = useState(false)
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
const admin = useAppSelector(state => state.user.profile?.admin)
const dispatch = useAppDispatch()
const { colorScheme, toggleColorScheme } = useMantineColorScheme()
@@ -33,9 +65,22 @@ export function ProfileMenu(props: ProfileMenuProps) {
>
<Trans>Settings</Trans>
</Menu.Item>
<Divider />
<Menu.Label>
<Trans>Display</Trans>
</Menu.Label>
<Menu.Item icon={dark ? <TbMoon /> : <TbSun />} onClick={() => toggleColorScheme()}>
<Trans>Theme</Trans>
</Menu.Item>
<SegmentedControl
fullWidth
orientation="vertical"
data={viewModeData}
value={viewMode}
onChange={e => dispatch(changeViewMode(e as ViewMode))}
mb="xs"
/>
{admin && (
<>

View File

@@ -161,6 +161,10 @@ msgstr "CommaFeed next unread item"
msgid "CommaFeed version {version} ({revision})"
msgstr "CommaFeed version {version} ({revision})"
#: src/components/header/ProfileMenu.tsx
msgid "Compact"
msgstr "Compact"
#: src/components/header/MarkAllAsReadButton.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
@@ -202,6 +206,7 @@ msgstr "Delete user"
msgid "Desc"
msgstr "Desc"
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/SettingsPage.tsx
msgid "Display"
msgstr "Display"
@@ -252,6 +257,10 @@ msgstr "Error"
msgid "Example: {example}."
msgstr "Example: {example}."
#: src/components/header/ProfileMenu.tsx
msgid "Expanded"
msgstr "Expanded"
#: src/components/settings/ProfileSettings.tsx
msgid "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"
msgstr "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"

View File

@@ -161,6 +161,10 @@ msgstr "CommaFeed prochain article non lu"
msgid "CommaFeed version {version} ({revision})"
msgstr "CommaFeed version {version} ({revision})"
#: src/components/header/ProfileMenu.tsx
msgid "Compact"
msgstr "Compact"
#: src/components/header/MarkAllAsReadButton.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
@@ -202,6 +206,7 @@ msgstr "Effacer l'utilisateur"
msgid "Desc"
msgstr "Descendant"
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/SettingsPage.tsx
msgid "Display"
msgstr "Affichage"
@@ -252,6 +257,10 @@ msgstr "Erreur"
msgid "Example: {example}."
msgstr "Exemple : {example}."
#: src/components/header/ProfileMenu.tsx
msgid "Expanded"
msgstr "Vue étendue"
#: src/components/settings/ProfileSettings.tsx
msgid "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"
msgstr "Exporter vos abonnements et catégories en tant que fichier OPML qui peut être importé dans d'autres services de lecture de flux"