Skip to content

Commit

Permalink
store view mode in localStorage (#1051)
Browse files Browse the repository at this point in the history
  • Loading branch information
Athou committed Apr 27, 2023
1 parent 155c93d commit cac05de
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 41 deletions.
15 changes: 15 additions & 0 deletions commafeed-client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions commafeed-client/package.json
Expand Up @@ -47,6 +47,7 @@
"react-swipeable": "^7.0.0",
"swagger-ui-react": "^4.15.5",
"tinycon": "^0.6.8",
"use-local-storage": "^3.0.0",
"websocket-heartbeat-js": "^1.1.1"
},
"devDependencies": {
Expand Down
9 changes: 3 additions & 6 deletions commafeed-client/src/App.tsx
@@ -1,7 +1,8 @@
import { i18n } from "@lingui/core"
import { I18nProvider } from "@lingui/react"
import { ColorScheme, ColorSchemeProvider, MantineProvider } from "@mantine/core"
import { useColorScheme, useLocalStorage } from "@mantine/hooks"
import { useColorScheme } from "@mantine/hooks"
import useLocalStorage from "use-local-storage"
import { ModalsProvider } from "@mantine/modals"
import { NotificationsProvider } from "@mantine/notifications"
import { Constants } from "app/constants"
Expand Down Expand Up @@ -32,11 +33,7 @@ import Tinycon from "tinycon"

function Providers(props: { children: React.ReactNode }) {
const preferredColorScheme = useColorScheme()
const [colorScheme, setColorScheme] = useLocalStorage<ColorScheme>({
key: "color-scheme",
defaultValue: preferredColorScheme,
getInitialValueInEffect: true,
})
const [colorScheme, setColorScheme] = useLocalStorage<ColorScheme>("color-scheme", preferredColorScheme)
const toggleColorScheme = (value?: ColorScheme) => setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"))

return (
Expand Down
73 changes: 45 additions & 28 deletions commafeed-client/src/app/slices/user.ts
Expand Up @@ -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, ViewMode } from "app/types"
import { ReadingMode, ReadingOrder, Settings, SharingSettings, UserModel } from "app/types"
// eslint-disable-next-line import/no-cycle
import { reloadEntries } from "./entries"

Expand Down Expand Up @@ -36,46 +36,67 @@ 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) => {
export const changeLanguage = createAsyncThunk<
void,
string,
{
state: RootState
}
>("settings/language", (language, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, language })
})
export const changeScrollSpeed = createAsyncThunk<void, boolean, { state: RootState }>("settings/scrollSpeed", (speed, thunkApi) => {
export const changeScrollSpeed = createAsyncThunk<
void,
boolean,
{
state: RootState
}
>("settings/scrollSpeed", (speed, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, scrollSpeed: speed ? 400 : 0 })
})
export const changeShowRead = createAsyncThunk<void, boolean, { state: RootState }>("settings/showRead", (showRead, thunkApi) => {
export const changeShowRead = createAsyncThunk<
void,
boolean,
{
state: RootState
}
>("settings/showRead", (showRead, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, showRead })
})
export const changeScrollMarks = createAsyncThunk<void, boolean, { state: RootState }>("settings/scrollMarks", (scrollMarks, thunkApi) => {
export const changeScrollMarks = createAsyncThunk<
void,
boolean,
{
state: RootState
}
>("settings/scrollMarks", (scrollMarks, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, scrollMarks })
})
export const changeSharingSetting = createAsyncThunk<void, { site: keyof SharingSettings; value: boolean }, { state: RootState }>(
"settings/sharingSetting",
(sharingSetting, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({
...settings,
sharingSettings: {
...settings.sharingSettings,
[sharingSetting.site]: sharingSetting.value,
},
})
export const changeSharingSetting = createAsyncThunk<
void,
{ site: keyof SharingSettings; value: boolean },
{
state: RootState
}
)
>("settings/sharingSetting", (sharingSetting, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({
...settings,
sharingSettings: {
...settings.sharingSettings,
[sharingSetting.site]: sharingSetting.value,
},
})
})

export const userSlice = createSlice({
name: "user",
Expand All @@ -99,10 +120,6 @@ 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
Expand Down
1 change: 0 additions & 1 deletion commafeed-client/src/app/types.ts
Expand Up @@ -228,7 +228,6 @@ export interface Settings {
language: string
readingMode: ReadingMode
readingOrder: ReadingOrder
viewMode: ViewMode
showRead: boolean
scrollMarks: boolean
theme?: string
Expand Down
3 changes: 2 additions & 1 deletion commafeed-client/src/components/content/FeedEntries.tsx
Expand Up @@ -21,14 +21,15 @@ import throttle from "lodash/throttle"
import { useEffect } from "react"
import InfiniteScroll from "react-infinite-scroller"
import { FeedEntry } from "./FeedEntry"
import { useViewMode } from "../../hooks/useViewMode"

export function FeedEntries() {
const source = useAppSelector(state => state.entries.source)
const entries = useAppSelector(state => state.entries.entries)
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 { viewMode } = useViewMode()
const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks)
const scrollingToEntry = useAppSelector(state => state.entries.scrollingToEntry)
const dispatch = useAppDispatch()
Expand Down
5 changes: 3 additions & 2 deletions commafeed-client/src/components/content/FeedEntry.tsx
@@ -1,7 +1,7 @@
import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
import { Constants } from "app/constants"
import { markEntry } from "app/slices/entries"
import { useAppDispatch, useAppSelector } from "app/store"
import { useAppDispatch } from "app/store"
import { Entry, ViewMode } from "app/types"
import React from "react"
import { useSwipeable } from "react-swipeable"
Expand All @@ -11,6 +11,7 @@ import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
import { FeedEntryContextMenu, useFeedEntryContextMenu } from "./FeedEntryContextMenu"
import { FeedEntryFooter } from "./FeedEntryFooter"
import { FeedEntryHeader } from "./FeedEntryHeader"
import { useViewMode } from "../../hooks/useViewMode"

interface FeedEntryProps {
entry: Entry
Expand Down Expand Up @@ -63,7 +64,7 @@ const useStyles = createStyles((theme, props: FeedEntryProps & { viewMode?: View
})

export function FeedEntry(props: FeedEntryProps) {
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
const { viewMode } = useViewMode()
const { classes } = useStyles({ ...props, viewMode })

const dispatch = useAppDispatch()
Expand Down
6 changes: 3 additions & 3 deletions commafeed-client/src/components/header/ProfileMenu.tsx
Expand Up @@ -3,7 +3,6 @@ import { Box, Divider, Group, Menu, SegmentedControl, SegmentedControlItem, useM
import { showNotification } from "@mantine/notifications"
import { client } from "app/client"
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"
Expand All @@ -21,6 +20,7 @@ import {
TbUsers,
TbWorldDownload,
} from "react-icons/tb"
import { useViewMode } from "../../hooks/useViewMode"

interface ProfileMenuProps {
control: React.ReactElement
Expand Down Expand Up @@ -81,7 +81,7 @@ const viewModeData: ViewModeControlItem[] = [

export function ProfileMenu(props: ProfileMenuProps) {
const [opened, setOpened] = useState(false)
const viewMode = useAppSelector(state => state.user.settings?.viewMode)
const { viewMode, setViewMode } = useViewMode()
const profile = useAppSelector(state => state.user.profile)
const admin = useAppSelector(state => state.user.profile?.admin)
const dispatch = useAppDispatch()
Expand Down Expand Up @@ -139,7 +139,7 @@ export function ProfileMenu(props: ProfileMenuProps) {
orientation="vertical"
data={viewModeData}
value={viewMode}
onChange={e => dispatch(changeViewMode(e as ViewMode))}
onChange={e => setViewMode(e as ViewMode)}
mb="xs"
/>

Expand Down
7 changes: 7 additions & 0 deletions commafeed-client/src/hooks/useViewMode.ts
@@ -0,0 +1,7 @@
import useLocalStorage from "use-local-storage"
import { ViewMode } from "../app/types"

export function useViewMode() {
const [viewMode, setViewMode] = useLocalStorage<ViewMode>("view-mode", "detailed")
return { viewMode, setViewMode }
}

0 comments on commit cac05de

Please sign in to comment.