From 764c1a6430405b20458e7a184f6333714ce3b36d Mon Sep 17 00:00:00 2001 From: Athou Date: Sun, 25 Aug 2024 18:05:34 +0200 Subject: [PATCH] add setting for showing unread count in tab/favicon (#1518) --- commafeed-client/src/App.tsx | 26 ++++++++++++------- commafeed-client/src/app/types.ts | 2 ++ commafeed-client/src/app/user/slice.ts | 12 +++++++++ commafeed-client/src/app/user/thunks.ts | 10 +++++++ .../components/settings/DisplaySettings.tsx | 18 +++++++++++++ commafeed-client/src/locales/ar/messages.po | 12 +++++++++ commafeed-client/src/locales/ca/messages.po | 12 +++++++++ commafeed-client/src/locales/cs/messages.po | 12 +++++++++ commafeed-client/src/locales/cy/messages.po | 12 +++++++++ commafeed-client/src/locales/da/messages.po | 12 +++++++++ commafeed-client/src/locales/de/messages.po | 12 +++++++++ commafeed-client/src/locales/en/messages.po | 12 +++++++++ commafeed-client/src/locales/es/messages.po | 12 +++++++++ commafeed-client/src/locales/fa/messages.po | 12 +++++++++ commafeed-client/src/locales/fi/messages.po | 12 +++++++++ commafeed-client/src/locales/fr/messages.po | 12 +++++++++ commafeed-client/src/locales/gl/messages.po | 12 +++++++++ commafeed-client/src/locales/hu/messages.po | 12 +++++++++ commafeed-client/src/locales/id/messages.po | 12 +++++++++ commafeed-client/src/locales/it/messages.po | 12 +++++++++ commafeed-client/src/locales/ja/messages.po | 12 +++++++++ commafeed-client/src/locales/ko/messages.po | 12 +++++++++ commafeed-client/src/locales/ms/messages.po | 12 +++++++++ commafeed-client/src/locales/nb/messages.po | 12 +++++++++ commafeed-client/src/locales/nl/messages.po | 12 +++++++++ commafeed-client/src/locales/nn/messages.po | 12 +++++++++ commafeed-client/src/locales/pl/messages.po | 12 +++++++++ commafeed-client/src/locales/pt/messages.po | 12 +++++++++ commafeed-client/src/locales/ru/messages.po | 12 +++++++++ commafeed-client/src/locales/sk/messages.po | 12 +++++++++ commafeed-client/src/locales/sv/messages.po | 12 +++++++++ commafeed-client/src/locales/tr/messages.po | 12 +++++++++ commafeed-client/src/locales/zh/messages.po | 12 +++++++++ .../commafeed/backend/model/UserSettings.java | 2 ++ .../commafeed/frontend/model/Settings.java | 6 +++++ .../commafeed/frontend/resource/UserREST.java | 6 +++++ .../resources/changelogs/db.changelog-5.1.xml | 17 ++++++++++++ .../src/main/resources/migrations.xml | 1 + 38 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 commafeed-server/src/main/resources/changelogs/db.changelog-5.1.xml diff --git a/commafeed-client/src/App.tsx b/commafeed-client/src/App.tsx index c8e97617..0519bf0e 100644 --- a/commafeed-client/src/App.tsx +++ b/commafeed-client/src/App.tsx @@ -71,7 +71,7 @@ function Providers(props: { children: React.ReactNode }) { ) } -// swagger-ui is very large, load only on-demand +// api documentation page is very large, load only on-demand const ApiDocumentationPage = React.lazy(async () => await import("pages/app/ApiDocumentationPage")) function AppRoutes() { @@ -142,16 +142,18 @@ function GoogleAnalyticsHandler() { return null } -function FaviconHandler() { - const root = useAppSelector(state => state.tree.rootCategory) +function UnreadCountTitleHandler({ unreadCount, enabled }: { unreadCount: number; enabled?: boolean }) { + return 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"} /> +} + +function UnreadCountFaviconHandler({ unreadCount, enabled }: { unreadCount: number; enabled?: boolean }) { useEffect(() => { - const unreadCount = categoryUnreadCount(root) - if (unreadCount === 0) { - Tinycon.reset() - } else { + if (enabled && unreadCount > 0) { Tinycon.setBubble(unreadCount) + } else { + Tinycon.reset() } - }, [root]) + }, [unreadCount, enabled]) return null } @@ -179,8 +181,13 @@ function CustomCode() { export function App() { useI18n() + const root = useAppSelector(state => state.tree.rootCategory) + const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle) + const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon) const dispatch = useAppDispatch() + const unreadCount = categoryUnreadCount(root) + useEffect(() => { dispatch(reloadServerInfos()) }, [dispatch]) @@ -188,7 +195,8 @@ export function App() { return ( <> - + + diff --git a/commafeed-client/src/app/types.ts b/commafeed-client/src/app/types.ts index d4ea0ff1..6fc41c6b 100644 --- a/commafeed-client/src/app/types.ts +++ b/commafeed-client/src/app/types.ts @@ -248,6 +248,8 @@ export interface Settings { markAllAsReadConfirmation: boolean customContextMenu: boolean mobileFooter: boolean + unreadCountTitle: boolean + unreadCountFavicon: boolean sharingSettings: SharingSettings } diff --git a/commafeed-client/src/app/user/slice.ts b/commafeed-client/src/app/user/slice.ts index f1611355..576c8e1f 100644 --- a/commafeed-client/src/app/user/slice.ts +++ b/commafeed-client/src/app/user/slice.ts @@ -16,6 +16,8 @@ import { changeSharingSetting, changeShowRead, changeStarIconDisplayMode, + changeUnreadCountFavicon, + changeUnreadCountTitle, reloadProfile, reloadSettings, reloadTags, @@ -91,6 +93,14 @@ export const userSlice = createSlice({ if (!state.settings) return state.settings.mobileFooter = action.meta.arg }) + builder.addCase(changeUnreadCountTitle.pending, (state, action) => { + if (!state.settings) return + state.settings.unreadCountTitle = action.meta.arg + }) + builder.addCase(changeUnreadCountFavicon.pending, (state, action) => { + if (!state.settings) return + state.settings.unreadCountFavicon = action.meta.arg + }) builder.addCase(changeSharingSetting.pending, (state, action) => { if (!state.settings) return state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value @@ -107,6 +117,8 @@ export const userSlice = createSlice({ changeMarkAllAsReadConfirmation.fulfilled, changeCustomContextMenu.fulfilled, changeMobileFooter.fulfilled, + changeUnreadCountTitle.fulfilled, + changeUnreadCountFavicon.fulfilled, changeSharingSetting.fulfilled ), () => { diff --git a/commafeed-client/src/app/user/thunks.ts b/commafeed-client/src/app/user/thunks.ts index dd88bd0e..63a462d3 100644 --- a/commafeed-client/src/app/user/thunks.ts +++ b/commafeed-client/src/app/user/thunks.ts @@ -77,6 +77,16 @@ export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", ( if (!settings) return client.user.saveSettings({ ...settings, mobileFooter }) }) +export const changeUnreadCountTitle = createAppAsyncThunk("settings/unreadCountTitle", (unreadCountTitle: boolean, thunkApi) => { + const { settings } = thunkApi.getState().user + if (!settings) return + client.user.saveSettings({ ...settings, unreadCountTitle }) +}) +export const changeUnreadCountFavicon = createAppAsyncThunk("settings/unreadCountFavicon", (unreadCountFavicon: boolean, thunkApi) => { + const { settings } = thunkApi.getState().user + if (!settings) return + client.user.saveSettings({ ...settings, unreadCountFavicon }) +}) export const changeSharingSetting = createAppAsyncThunk( "settings/sharingSetting", ( diff --git a/commafeed-client/src/components/settings/DisplaySettings.tsx b/commafeed-client/src/components/settings/DisplaySettings.tsx index bf444212..c3d9394a 100644 --- a/commafeed-client/src/components/settings/DisplaySettings.tsx +++ b/commafeed-client/src/components/settings/DisplaySettings.tsx @@ -17,6 +17,8 @@ import { changeSharingSetting, changeShowRead, changeStarIconDisplayMode, + changeUnreadCountFavicon, + changeUnreadCountTitle, } from "app/user/thunks" import { locales } from "i18n" import type { ReactNode } from "react" @@ -32,6 +34,8 @@ export function DisplaySettings() { const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation) const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu) const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter) + const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle) + const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon) const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings) const dispatch = useAppDispatch() const { _ } = useLingui() @@ -91,6 +95,20 @@ export function DisplaySettings() { onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))} /> + Browser tab} labelPosition="center" /> + + Show unread count in tab title} + checked={unreadCountTitle} + onChange={async e => await dispatch(changeUnreadCountTitle(e.currentTarget.checked))} + /> + + Show unread count in tab favicon} + checked={unreadCountFavicon} + onChange={async e => await dispatch(changeUnreadCountFavicon(e.currentTarget.checked))} + /> + Entry headers} labelPosition="center" />