From 8645c57d13c6778aaaab2cbf8c2d3b12763d398d Mon Sep 17 00:00:00 2001 From: Athou Date: Sun, 3 May 2026 19:14:50 +0200 Subject: [PATCH] simplify settings thunks --- commafeed-client/src/app/user/slice.ts | 141 +-------------- commafeed-client/src/app/user/thunks.ts | 162 +----------------- .../src/components/header/Header.tsx | 25 ++- .../components/settings/DisplaySettings.tsx | 118 +++++-------- .../settings/PushNotificationSettings.tsx | 4 +- 5 files changed, 80 insertions(+), 370 deletions(-) diff --git a/commafeed-client/src/app/user/slice.ts b/commafeed-client/src/app/user/slice.ts index 9f090547..e5d5dc7e 100644 --- a/commafeed-client/src/app/user/slice.ts +++ b/commafeed-client/src/app/user/slice.ts @@ -1,32 +1,8 @@ import { t } from "@lingui/core/macro" import { showNotification } from "@mantine/notifications" -import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit" +import { createSlice, type PayloadAction } from "@reduxjs/toolkit" import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types" -import { - changeCustomContextMenu, - changeDisablePullToRefresh, - changeEntriesToKeepOnTopWhenScrolling, - changeExternalLinkIconDisplayMode, - changeLanguage, - changeMarkAllAsReadConfirmation, - changeMarkAllAsReadNavigateToUnread, - changeMobileFooter, - changePrimaryColor, - changePushNotificationSettings, - changeReadingMode, - changeReadingOrder, - changeScrollMarks, - changeScrollMode, - changeScrollSpeed, - changeSharingSetting, - changeShowRead, - changeStarIconDisplayMode, - changeUnreadCountFavicon, - changeUnreadCountTitle, - reloadProfile, - reloadSettings, - reloadTags, -} from "./thunks" +import { changeSettings, reloadProfile, reloadSettings, reloadTags } from "./thunks" interface UserState { settings?: Settings @@ -73,115 +49,16 @@ export const userSlice = createSlice({ builder.addCase(reloadTags.fulfilled, (state, action) => { state.tags = action.payload }) - builder.addCase(changeReadingMode.pending, (state, action) => { + builder.addCase(changeSettings.pending, (state, action) => { if (!state.settings) return - state.settings.readingMode = action.meta.arg + state.settings = { ...state.settings, ...action.meta.arg } }) - builder.addCase(changeReadingOrder.pending, (state, action) => { - if (!state.settings) return - state.settings.readingOrder = action.meta.arg + builder.addCase(changeSettings.fulfilled, () => { + showNotification({ + message: t`Settings saved.`, + color: "green", + }) }) - builder.addCase(changeLanguage.pending, (state, action) => { - if (!state.settings) return - state.settings.language = action.meta.arg - }) - builder.addCase(changeScrollSpeed.pending, (state, action) => { - if (!state.settings) return - state.settings.scrollSpeed = action.meta.arg ? 400 : 0 - }) - builder.addCase(changeShowRead.pending, (state, action) => { - if (!state.settings) return - state.settings.showRead = action.meta.arg - }) - builder.addCase(changeScrollMarks.pending, (state, action) => { - if (!state.settings) return - state.settings.scrollMarks = action.meta.arg - }) - builder.addCase(changeScrollMode.pending, (state, action) => { - if (!state.settings) return - state.settings.scrollMode = action.meta.arg - }) - builder.addCase(changeEntriesToKeepOnTopWhenScrolling.pending, (state, action) => { - if (!state.settings) return - state.settings.entriesToKeepOnTopWhenScrolling = action.meta.arg - }) - builder.addCase(changeStarIconDisplayMode.pending, (state, action) => { - if (!state.settings) return - state.settings.starIconDisplayMode = action.meta.arg - }) - builder.addCase(changeExternalLinkIconDisplayMode.pending, (state, action) => { - if (!state.settings) return - state.settings.externalLinkIconDisplayMode = action.meta.arg - }) - builder.addCase(changeMarkAllAsReadConfirmation.pending, (state, action) => { - if (!state.settings) return - state.settings.markAllAsReadConfirmation = action.meta.arg - }) - builder.addCase(changeMarkAllAsReadNavigateToUnread.pending, (state, action) => { - if (!state.settings) return - state.settings.markAllAsReadNavigateToNextUnread = action.meta.arg - }) - builder.addCase(changeCustomContextMenu.pending, (state, action) => { - if (!state.settings) return - state.settings.customContextMenu = action.meta.arg - }) - builder.addCase(changeMobileFooter.pending, (state, action) => { - 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(changeDisablePullToRefresh.pending, (state, action) => { - if (!state.settings) return - state.settings.disablePullToRefresh = action.meta.arg - }) - builder.addCase(changePrimaryColor.pending, (state, action) => { - if (!state.settings) return - state.settings.primaryColor = action.meta.arg - }) - builder.addCase(changeSharingSetting.pending, (state, action) => { - if (!state.settings) return - state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value - }) - builder.addCase(changePushNotificationSettings.pending, (state, action) => { - if (!state.settings) return - state.settings.pushNotificationSettings = action.meta.arg - }) - - builder.addMatcher( - isAnyOf( - changeLanguage.fulfilled, - changeScrollSpeed.fulfilled, - changeShowRead.fulfilled, - changeScrollMarks.fulfilled, - changeScrollMode.fulfilled, - changeEntriesToKeepOnTopWhenScrolling.fulfilled, - changeStarIconDisplayMode.fulfilled, - changeExternalLinkIconDisplayMode.fulfilled, - changeMarkAllAsReadConfirmation.fulfilled, - changeMarkAllAsReadNavigateToUnread.fulfilled, - changeCustomContextMenu.fulfilled, - changeMobileFooter.fulfilled, - changeUnreadCountTitle.fulfilled, - changeUnreadCountFavicon.fulfilled, - changeDisablePullToRefresh.fulfilled, - changePrimaryColor.fulfilled, - changeSharingSetting.fulfilled, - changePushNotificationSettings.fulfilled - ), - () => { - showNotification({ - message: t`Settings saved.`, - color: "green", - }) - } - ) }, }) diff --git a/commafeed-client/src/app/user/thunks.ts b/commafeed-client/src/app/user/thunks.ts index aa473410..04a5990d 100644 --- a/commafeed-client/src/app/user/thunks.ts +++ b/commafeed-client/src/app/user/thunks.ts @@ -1,7 +1,6 @@ import { createAppAsyncThunk } from "@/app/async-thunk" import { client } from "@/app/client" -import { reloadEntries } from "@/app/entries/thunks" -import type { IconDisplayMode, PushNotificationSettings, ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "@/app/types" +import type { Settings } from "@/app/types" export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data)) @@ -9,163 +8,8 @@ export const reloadProfile = createAppAsyncThunk("profile/reload", async () => a export const reloadTags = createAppAsyncThunk("entries/tags", async () => await client.entry.getTags().then(r => r.data)) -export const changeReadingMode = createAppAsyncThunk("settings/readingMode", (readingMode: ReadingMode, thunkApi) => { +export const changeSettings = createAppAsyncThunk("settings/change", async (newSettings: Partial, thunkApi) => { const { settings } = thunkApi.getState().user if (!settings) return - client.user.saveSettings({ ...settings, readingMode }) - thunkApi.dispatch(reloadEntries()) + await client.user.saveSettings({ ...settings, ...newSettings }) }) - -export const changeReadingOrder = createAppAsyncThunk("settings/readingOrder", (readingOrder: ReadingOrder, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, readingOrder }) - thunkApi.dispatch(reloadEntries()) -}) - -export const changeLanguage = createAppAsyncThunk("settings/language", (language: string, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, language }) -}) - -export const changeScrollSpeed = createAppAsyncThunk("settings/scrollSpeed", (speed: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, scrollSpeed: speed ? 400 : 0 }) -}) - -export const changeShowRead = createAppAsyncThunk("settings/showRead", (showRead: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, showRead }) -}) - -export const changeScrollMarks = createAppAsyncThunk("settings/scrollMarks", (scrollMarks: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, scrollMarks }) -}) - -export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scrollMode: ScrollMode, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, scrollMode }) -}) - -export const changeEntriesToKeepOnTopWhenScrolling = createAppAsyncThunk( - "settings/entriesToKeepOnTopWhenScrolling", - (entriesToKeepOnTopWhenScrolling: number, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, entriesToKeepOnTopWhenScrolling }) - } -) - -export const changeStarIconDisplayMode = createAppAsyncThunk( - "settings/starIconDisplayMode", - (starIconDisplayMode: IconDisplayMode, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, starIconDisplayMode }) - } -) - -export const changeExternalLinkIconDisplayMode = createAppAsyncThunk( - "settings/externalLinkIconDisplayMode", - (externalLinkIconDisplayMode: IconDisplayMode, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, externalLinkIconDisplayMode }) - } -) - -export const changeMarkAllAsReadConfirmation = createAppAsyncThunk( - "settings/markAllAsReadConfirmation", - (markAllAsReadConfirmation: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, markAllAsReadConfirmation }) - } -) - -export const changeMarkAllAsReadNavigateToUnread = createAppAsyncThunk( - "settings/markAllAsReadNavigateToUnread", - (markAllAsReadNavigateToNextUnread: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, markAllAsReadNavigateToNextUnread }) - } -) - -export const changeCustomContextMenu = createAppAsyncThunk("settings/customContextMenu", (customContextMenu: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, customContextMenu }) -}) - -export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", (mobileFooter: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - 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 changeDisablePullToRefresh = createAppAsyncThunk( - "settings/disablePullToRefresh", - (disablePullToRefresh: boolean, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, disablePullToRefresh }) - } -) - -export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ ...settings, primaryColor }) -}) - -export const changeSharingSetting = createAppAsyncThunk( - "settings/sharingSetting", - ( - sharingSetting: { - site: keyof SharingSettings - value: boolean - }, - thunkApi - ) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ - ...settings, - sharingSettings: { - ...settings.sharingSettings, - [sharingSetting.site]: sharingSetting.value, - }, - }) - } -) - -export const changePushNotificationSettings = createAppAsyncThunk( - "settings/pushNotificationSettings", - (pushNotificationSettings: PushNotificationSettings, thunkApi) => { - const { settings } = thunkApi.getState().user - if (!settings) return - client.user.saveSettings({ - ...settings, - pushNotificationSettings, - }) - } -) diff --git a/commafeed-client/src/components/header/Header.tsx b/commafeed-client/src/components/header/Header.tsx index d18cd2c9..87b0d846 100644 --- a/commafeed-client/src/components/header/Header.tsx +++ b/commafeed-client/src/components/header/Header.tsx @@ -19,7 +19,7 @@ import { } from "react-icons/tb" import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "@/app/entries/thunks" import { useAppDispatch, useAppSelector } from "@/app/store" -import { changeReadingMode, changeReadingOrder } from "@/app/user/thunks" +import { changeSettings } from "@/app/user/thunks" import { ActionButton } from "@/components/ActionButton" import { Loader } from "@/components/Loader" import { useActionButton } from "@/hooks/useActionButton" @@ -73,6 +73,25 @@ export function Header() { }, [setValues, searchFromStore]) if (!settings) return + + const toggleReadingMode = async () => { + await dispatch( + changeSettings({ + readingMode: settings.readingMode === "all" ? "unread" : "all", + }) + ) + dispatch(reloadEntries()) + } + + const toggleReadingOrder = async () => { + await dispatch( + changeSettings({ + readingOrder: settings.readingOrder === "asc" ? "desc" : "asc", + }) + ) + dispatch(reloadEntries()) + } + return (
@@ -121,12 +140,12 @@ export function Header() { : } label={settings.readingMode === "all" ? msg`All` : msg`Unread`} - onClick={async () => await dispatch(changeReadingMode(settings.readingMode === "all" ? "unread" : "all"))} + onClick={toggleReadingMode} /> : } label={settings.readingOrder === "asc" ? msg`Asc` : msg`Desc`} - onClick={async () => await dispatch(changeReadingOrder(settings.readingOrder === "asc" ? "desc" : "asc"))} + onClick={toggleReadingOrder} /> diff --git a/commafeed-client/src/components/settings/DisplaySettings.tsx b/commafeed-client/src/components/settings/DisplaySettings.tsx index ff72f402..441de9ae 100644 --- a/commafeed-client/src/components/settings/DisplaySettings.tsx +++ b/commafeed-client/src/components/settings/DisplaySettings.tsx @@ -6,6 +6,7 @@ import { type ComboboxData, Divider, Group, + Loader, NumberInput, Radio, Select, @@ -18,45 +19,11 @@ import type { ReactNode } from "react" import { Constants } from "@/app/constants" import { useAppDispatch, useAppSelector } from "@/app/store" import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types" -import { - changeCustomContextMenu, - changeDisablePullToRefresh, - changeEntriesToKeepOnTopWhenScrolling, - changeExternalLinkIconDisplayMode, - changeLanguage, - changeMarkAllAsReadConfirmation, - changeMarkAllAsReadNavigateToUnread, - changeMobileFooter, - changePrimaryColor, - changeScrollMarks, - changeScrollMode, - changeScrollSpeed, - changeSharingSetting, - changeShowRead, - changeStarIconDisplayMode, - changeUnreadCountFavicon, - changeUnreadCountTitle, -} from "@/app/user/thunks" +import { changeSettings } from "@/app/user/thunks" import { locales } from "@/i18n" export function DisplaySettings() { - const language = useAppSelector(state => state.user.settings?.language) - const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed) - const showRead = useAppSelector(state => state.user.settings?.showRead) - const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks) - const scrollMode = useAppSelector(state => state.user.settings?.scrollMode) - const entriesToKeepOnTop = useAppSelector(state => state.user.settings?.entriesToKeepOnTopWhenScrolling) - const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode) - const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode) - const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation) - const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread) - 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 disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh) - const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings) - const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor + const settings = useAppSelector(state => state.user.settings) const { _ } = useLingui() const dispatch = useAppDispatch() @@ -108,50 +75,51 @@ export function DisplaySettings() { ) + if (!settings) return return ( Display} labelPosition="center" /> Primary color} data={colorData} - value={primaryColor} - onChange={async value => value && (await dispatch(changePrimaryColor(value)))} + value={settings.primaryColor} + onChange={primaryColor => primaryColor && dispatch(changeSettings({ primaryColor }))} renderOption={colorRenderer} /> Show feeds and categories with no unread entries} - checked={showRead} - onChange={async e => await dispatch(changeShowRead(e.currentTarget.checked))} + checked={settings.showRead} + onChange={e => dispatch(changeSettings({ showRead: e.currentTarget.checked }))} /> Show confirmation when marking all entries as read} - checked={markAllAsReadConfirmation} - onChange={async e => await dispatch(changeMarkAllAsReadConfirmation(e.currentTarget.checked))} + checked={settings.markAllAsReadConfirmation} + onChange={e => dispatch(changeSettings({ markAllAsReadConfirmation: e.currentTarget.checked }))} /> Navigate to the next category/feed with unread entries when marking all entries as read} - checked={markAllAsReadNavigateToNextUnread} - onChange={async e => await dispatch(changeMarkAllAsReadNavigateToUnread(e.currentTarget.checked))} + checked={settings.markAllAsReadNavigateToNextUnread} + onChange={e => dispatch(changeSettings({ markAllAsReadNavigateToNextUnread: e.currentTarget.checked }))} /> On mobile, show action buttons at the bottom of the screen} - checked={mobileFooter} - onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))} + checked={settings.mobileFooter} + onChange={e => dispatch(changeSettings({ mobileFooter: e.currentTarget.checked }))} /> Scrolling} labelPosition="center" /> @@ -159,14 +127,14 @@ export function DisplaySettings() { Disable "Pull to refresh" browser behavior} description={This setting can cause scrolling issues on some browsers (e.g. Safari)} - checked={disablePullToRefresh} - onChange={async e => await dispatch(changeDisablePullToRefresh(e.currentTarget.checked))} + checked={settings.disablePullToRefresh} + onChange={e => dispatch(changeSettings({ disablePullToRefresh: e.currentTarget.checked }))} /> Scroll selected entry to the top of the page} - value={scrollMode} - onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))} + value={settings.scrollMode} + onChange={value => dispatch(changeSettings({ scrollMode: value }))} > {Object.entries(scrollModeOptions).map(e => ( @@ -179,56 +147,56 @@ export function DisplaySettings() { label={Entries to keep above the selected entry when scrolling} description={Only applies to compact, cozy and detailed modes} min={0} - value={entriesToKeepOnTop} - onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))} + value={settings.entriesToKeepOnTopWhenScrolling} + onChange={value => dispatch(changeSettings({ entriesToKeepOnTopWhenScrolling: +value }))} /> Scroll smoothly when navigating between entries} - checked={scrollSpeed ? scrollSpeed > 0 : false} - onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))} + checked={settings.scrollSpeed ? settings.scrollSpeed > 0 : false} + onChange={e => dispatch(changeSettings({ scrollSpeed: e.currentTarget.checked ? 400 : 0 }))} /> In expanded view, scrolling through entries mark them as read} - checked={scrollMarks} - onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))} + checked={settings.scrollMarks} + onChange={e => dispatch(changeSettings({ scrollMarks: e.currentTarget.checked }))} /> Browser tab} labelPosition="center" /> Show unread count in tab title} - checked={unreadCountTitle} - onChange={async e => await dispatch(changeUnreadCountTitle(e.currentTarget.checked))} + checked={settings.unreadCountTitle} + onChange={e => dispatch(changeSettings({ unreadCountTitle: e.currentTarget.checked }))} /> Show unread count in tab favicon} - checked={unreadCountFavicon} - onChange={async e => await dispatch(changeUnreadCountFavicon(e.currentTarget.checked))} + checked={settings.unreadCountFavicon} + onChange={e => dispatch(changeSettings({ unreadCountFavicon: e.currentTarget.checked }))} /> Entry headers} labelPosition="center" /> Show external link icon} - value={externalLinkIconDisplayMode} + value={settings.externalLinkIconDisplayMode} data={displayModeData} - onChange={async s => await dispatch(changeExternalLinkIconDisplayMode(s as IconDisplayMode))} + onChange={value => dispatch(changeSettings({ externalLinkIconDisplayMode: value as IconDisplayMode }))} /> Show CommaFeed's own context menu on right click} - checked={customContextMenu} - onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))} + checked={settings.customContextMenu} + onChange={e => dispatch(changeSettings({ customContextMenu: e.currentTarget.checked }))} /> Sharing sites} labelPosition="center" /> @@ -238,12 +206,14 @@ export function DisplaySettings() { - await dispatch( - changeSharingSetting({ - site, - value: e.currentTarget.checked, + checked={settings.sharingSettings[site]} + onChange={e => + dispatch( + changeSettings({ + sharingSettings: { + ...settings.sharingSettings, + [site]: e.currentTarget.checked, + }, }) ) } diff --git a/commafeed-client/src/components/settings/PushNotificationSettings.tsx b/commafeed-client/src/components/settings/PushNotificationSettings.tsx index 584ddfc9..bbb205e6 100644 --- a/commafeed-client/src/components/settings/PushNotificationSettings.tsx +++ b/commafeed-client/src/components/settings/PushNotificationSettings.tsx @@ -10,7 +10,7 @@ import { client, errorToStrings } from "@/app/client" import { redirectToSelectedSource } from "@/app/redirect/thunks" import { useAppDispatch, useAppSelector } from "@/app/store" import type { PushNotificationSettings as PushNotificationSettingsModel } from "@/app/types" -import { changePushNotificationSettings } from "@/app/user/thunks" +import { changeSettings } from "@/app/user/thunks" import { Alert } from "@/components/Alert" export function PushNotificationSettings() { @@ -25,7 +25,7 @@ export function PushNotificationSettings() { }, [form.initialize, notificationSettings]) const handleSubmit = (values: PushNotificationSettingsModel) => { - dispatch(changePushNotificationSettings(values)) + dispatch(changeSettings({ pushNotificationSettings: values })) } const sendTestPushNotification = useAsyncCallback(client.user.sendTestPushNotification)