import { msg } from "@lingui/core/macro" import { useLingui } from "@lingui/react" import { Trans } from "@lingui/react/macro" import { Box, type ComboboxData, Divider, Group, Loader, NumberInput, Radio, Select, type SelectProps, SimpleGrid, Stack, Switch, } from "@mantine/core" 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 { changeSettings } from "@/app/user/thunks" import { locales } from "@/i18n" export function DisplaySettings() { const settings = useAppSelector(state => state.user.settings) const { _ } = useLingui() const dispatch = useAppDispatch() const scrollModeOptions: Record = { always: Always, never: Never, if_needed: If the entry doesn't entirely fit on the screen, } const displayModeData: ComboboxData = [ { value: "always", label: _(msg`Always`), }, { value: "on_desktop", label: _(msg`On desktop`), }, { value: "on_mobile", label: _(msg`On mobile`), }, { value: "never", label: _(msg`Never`), }, ] const colorData: ComboboxData = [ { value: "dark", label: _(msg`Dark`) }, { value: "gray", label: _(msg`Gray`) }, { value: "red", label: _(msg`Red`) }, { value: "pink", label: _(msg`Pink`) }, { value: "grape", label: _(msg`Grape`) }, { value: "violet", label: _(msg`Violet`) }, { value: "indigo", label: _(msg`Indigo`) }, { value: "blue", label: _(msg`Blue`) }, { value: "cyan", label: _(msg`Cyan`) }, { value: "green", label: _(msg`Green`) }, { value: "lime", label: _(msg`Lime`) }, { value: "yellow", label: _(msg`Yellow`) }, { value: "orange", label: _(msg`Orange`) }, { value: "teal", label: _(msg`Teal`) }, ].sort((a, b) => a.label.localeCompare(b.label)) const colorRenderer: SelectProps["renderOption"] = ({ option }) => ( {option.label} ) if (!settings) return return ( Display} labelPosition="center" /> Primary color} data={colorData} value={settings.primaryColor} onChange={primaryColor => primaryColor && dispatch(changeSettings({ primaryColor }))} renderOption={colorRenderer} /> Show feeds and categories with no unread entries} checked={settings.showRead} onChange={e => dispatch(changeSettings({ showRead: e.currentTarget.checked }))} /> Show confirmation when marking all entries as read} 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={settings.markAllAsReadNavigateToNextUnread} onChange={e => dispatch(changeSettings({ markAllAsReadNavigateToNextUnread: e.currentTarget.checked }))} /> On mobile, show action buttons at the bottom of the screen} checked={settings.mobileFooter} onChange={e => dispatch(changeSettings({ mobileFooter: e.currentTarget.checked }))} /> Scrolling} labelPosition="center" /> Disable "Pull to refresh" browser behavior} description={This setting can cause scrolling issues on some browsers (e.g. Safari)} checked={settings.disablePullToRefresh} onChange={e => dispatch(changeSettings({ disablePullToRefresh: e.currentTarget.checked }))} /> Scroll selected entry to the top of the page} value={settings.scrollMode} onChange={value => dispatch(changeSettings({ scrollMode: value }))} > {Object.entries(scrollModeOptions).map(e => ( ))} Entries to keep above the selected entry when scrolling} description={Only applies to compact, cozy and detailed modes} min={0} value={settings.entriesToKeepOnTopWhenScrolling} onChange={value => dispatch(changeSettings({ entriesToKeepOnTopWhenScrolling: +value }))} /> Scroll smoothly when navigating between entries} 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={settings.scrollMarks} onChange={e => dispatch(changeSettings({ scrollMarks: e.currentTarget.checked }))} /> Browser tab} labelPosition="center" /> Show unread count in tab title} checked={settings.unreadCountTitle} onChange={e => dispatch(changeSettings({ unreadCountTitle: e.currentTarget.checked }))} /> Show unread count in tab favicon} checked={settings.unreadCountFavicon} onChange={e => dispatch(changeSettings({ unreadCountFavicon: e.currentTarget.checked }))} /> Entry headers} labelPosition="center" /> Show external link icon} value={settings.externalLinkIconDisplayMode} data={displayModeData} onChange={value => dispatch(changeSettings({ externalLinkIconDisplayMode: value as IconDisplayMode }))} /> Show CommaFeed's own context menu on right click} checked={settings.customContextMenu} onChange={e => dispatch(changeSettings({ customContextMenu: e.currentTarget.checked }))} /> Sharing sites} labelPosition="center" /> {(Object.keys(Constants.sharing) as Array).map(site => ( dispatch( changeSettings({ sharingSettings: { ...settings.sharingSettings, [site]: e.currentTarget.checked, }, }) ) } /> ))} ) }