Update display settings, add advanced settings

This commit is contained in:
Jackson Harper
2023-03-07 15:36:24 +08:00
parent 7cc901bab8
commit 550b8d88ec
7 changed files with 232 additions and 17 deletions

View File

@ -84,7 +84,7 @@ const App = () => {
margin={window.margin}
maxWidthPercentage={window.maxWidthPercentage}
lineHeight={window.lineHeight}
highContrastFont={window.prefersHighContrastFont ?? true}
highContrastText={window.prefersHighContrastFont ?? true}
articleMutations={{
createHighlightMutation: (input) =>
mutation('createHighlight', input),

View File

@ -19,6 +19,7 @@ import { LabelChip } from '../../elements/LabelChip'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { Recommendation } from '../../../lib/networking/queries/useGetLibraryItemsQuery'
import { Avatar } from '../../elements/Avatar'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
type ArticleContainerProps = {
article: ArticleAttributes
@ -32,8 +33,9 @@ type ArticleContainerProps = {
fontFamily?: string
lineHeight?: number
maxWidthPercentage?: number
highContrastFont?: boolean
highContrastText?: boolean
showHighlightsModal: boolean
justifyText?: boolean
setShowHighlightsModal: React.Dispatch<React.SetStateAction<boolean>>
}
@ -116,8 +118,8 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
const [fontFamilyOverride, setFontFamilyOverride] = useState<string | null>(
null
)
const [highContrastFont, setHighContrastFont] = useState(
props.highContrastFont ?? false
const [highContrastText, setHighContrastText] = useState(
props.highContrastText ?? false
)
const highlightHref = useRef(
window.location.hash ? window.location.hash.split('#')[1] : null
@ -175,7 +177,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
const handleFontContrastChange = async (event: UpdateFontContrastEvent) => {
const highContrast = event.fontContrast == 'high'
setHighContrastFont(highContrast)
setHighContrastText(highContrast)
}
interface UpdateFontSizeEvent extends Event {
@ -257,7 +259,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
maxWidthPercentage: maxWidthPercentageOverride ?? props.maxWidthPercentage,
lineHeight: lineHeightOverride ?? props.lineHeight ?? 150,
fontFamily: fontFamilyOverride ?? props.fontFamily ?? 'inter',
readerFontColor: highContrastFont
readerFontColor: highContrastText
? theme.colors.readerFontHighContrast.toString()
: theme.colors.readerFont.toString(),
readerTableHeaderColor: theme.colors.readerTableHeader.toString(),
@ -283,6 +285,9 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
background: props.isAppleAppEmbed
? 'unset'
: theme.colors.readerBg.toString(),
'.article-inner-css': {
textAlign: props.justifyText ? 'justify' : 'start',
},
'--text-font-family': styles.fontFamily,
'--text-font-size': `${styles.fontSize}px`,
'--line-height': `${styles.lineHeight}%`,

View File

@ -17,11 +17,6 @@ type DisplaySettingsModalProps = {
export function DisplaySettingsModal(
props: DisplaySettingsModalProps
): JSX.Element {
const top =
props.triggerElementRef?.current?.getBoundingClientRect().bottom ?? 0
const left =
props.triggerElementRef?.current?.getBoundingClientRect().left ?? 0
return (
<ModalRoot defaultOpen onOpenChange={props.onOpenChange}>
<ModalOverlay />

View File

@ -2,7 +2,13 @@ import { HStack, VStack, SpanBox } from '../../elements/LayoutPrimitives'
import { Button } from '../../elements/Button'
import { StyledText } from '../../elements/StyledText'
import { styled, theme, ThemeId } from '../../tokens/stitches.config'
import { ArrowsHorizontal, ArrowsInLineHorizontal, Check } from 'phosphor-react'
import {
ArrowsHorizontal,
ArrowsInLineHorizontal,
CaretLeft,
CaretRight,
Check,
} from 'phosphor-react'
import { TickedRangeSlider } from '../../elements/TickedRangeSlider'
import { showSuccessToast } from '../../../lib/toastHelpers'
import { ReaderSettings } from '../../../lib/hooks/useReaderSettings'
@ -10,6 +16,8 @@ import { useCallback, useMemo, useState } from 'react'
import { currentThemeName, updateTheme } from '../../../lib/themeUpdater'
import { LineHeightIncreaseIcon } from '../../elements/images/LineHeightIncreaseIconProps'
import { LineHeightDecreaseIcon } from '../../elements/images/LineHeightDecreaseIcon'
import * as Switch from '@radix-ui/react-switch'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
type ReaderSettingsProps = {
readerSettings: ReaderSettings
@ -33,7 +41,158 @@ const FONT_FAMILIES = [
'Source Serif Pro',
]
type SettingsProps = {
readerSettings: ReaderSettings
setShowAdvanced: (show: boolean) => void
}
export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element {
const [showAdvanced, setShowAdvanced] = useState(false)
return (
<>
{showAdvanced ? (
<AdvancedSettings
readerSettings={props.readerSettings}
setShowAdvanced={setShowAdvanced}
/>
) : (
<BasicSettings
readerSettings={props.readerSettings}
setShowAdvanced={setShowAdvanced}
/>
)}
</>
)
}
function AdvancedSettings(props: SettingsProps): JSX.Element {
return (
<VStack
css={{ width: '100%', minHeight: '320px', p: '10px' }}
alignment="start"
distribution="start"
>
<Button
style="plainIcon"
css={{
m: '10px',
mb: '20px',
display: 'flex',
fontSize: '12px',
fontWeight: '400',
fontFamily: '$display',
alignItems: 'center',
borderRadius: '6px',
gap: '5px',
'&:hover': {
textDecoration: 'underline',
},
}}
onClick={() => {
props.setShowAdvanced(false)
}}
>
<CaretLeft size={12} color="#969696" weight="bold" />
Back
</Button>
<HStack
css={{
width: '100%',
pr: '30px',
alignItems: 'center',
'&:hover': {
opacity: 0.8,
},
'&[data-state="on"]': {
bg: '$thBackground',
},
}}
alignment="start"
distribution="between"
>
<Label htmlFor="justify-text" css={{ width: '100%' }}>
<StyledText style="displaySettingsLabel" css={{ pl: '20px' }}>
Justify Text
</StyledText>
</Label>
<SwitchRoot
id="justify-text"
checked={props.readerSettings.justifyText ?? false}
onCheckedChange={(checked) => {
props.readerSettings.setJustifyText(checked)
}}
>
<SwitchThumb />
</SwitchRoot>
</HStack>
<HStack
css={{
width: '100%',
pr: '30px',
alignItems: 'center',
'&:hover': {
opacity: 0.8,
},
'&[data-state="on"]': {
bg: '$thBackground',
},
}}
alignment="start"
distribution="between"
>
<Label htmlFor="high-contrast-text" css={{ width: '100%' }}>
<StyledText style="displaySettingsLabel" css={{ pl: '20px' }}>
High Contrast Text
</StyledText>
</Label>
<SwitchRoot
id="high-contrast-text"
checked={props.readerSettings.highContrastText ?? false}
onCheckedChange={(checked) => {
props.readerSettings.setHighContrastText(checked)
}}
>
<SwitchThumb />
</SwitchRoot>
</HStack>
</VStack>
)
}
const SwitchRoot = styled(Switch.Root, {
all: 'unset',
width: 42,
height: 25,
backgroundColor: '$thBorderColor',
borderRadius: '9999px',
position: 'relative',
WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)',
'&:focus': { boxShadow: `0 0 0 2px $thBorderColor` },
'&[data-state="checked"]': { backgroundColor: '$thBorderColor' },
})
const SwitchThumb = styled(Switch.Thumb, {
display: 'block',
width: 21,
height: 21,
backgroundColor: '$thTextContrast2',
borderRadius: '9999px',
transition: 'transform 100ms',
transform: 'translateX(2px)',
willChange: 'transform',
'&[data-state="checked"]': { transform: 'translateX(19px)' },
})
const Label = styled('label', {
color: 'white',
fontSize: 15,
lineHeight: 1,
})
function BasicSettings(props: SettingsProps): JSX.Element {
return (
<VStack css={{ width: '100%' }}>
<FontControls readerSettings={props.readerSettings} />
@ -48,11 +207,15 @@ export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element {
<HorizontalDivider />
<HStack distribution="start" css={{ width: '100%', p: '20px' }}>
<HStack
distribution="start"
alignment="center"
css={{ width: '100%', p: '10px' }}
>
<Button
style="plainIcon"
css={{
p: '0px',
pl: '10px',
display: 'flex',
fontSize: '12px',
fontWeight: '600',
@ -73,6 +236,29 @@ export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element {
>
Reset
</Button>
<Button
style="plainIcon"
css={{
p: '5px',
display: 'flex',
fontSize: '12px',
fontWeight: '400',
fontFamily: '$display',
marginLeft: 'auto',
alignItems: 'center',
borderRadius: '6px',
gap: '5px',
'&:hover': {
textDecoration: 'underline',
},
}}
onClick={() => {
props.setShowAdvanced(true)
}}
>
Advanced Settings
<CaretRight size={12} color="#969696" weight="bold" />
</Button>
</HStack>
</VStack>
)

View File

@ -33,10 +33,17 @@ export type ReaderSettings = {
fontFamily: string
setFontFamily: (newStyle: string) => void
justifyText: boolean | undefined
setJustifyText: (set: boolean) => void
highContrastText: boolean | undefined
setHighContrastText: (set: boolean) => void
}
export const useReaderSettings = (): ReaderSettings => {
const { preferencesData } = useGetUserPreferences()
const [, updateState] = useState({})
const [fontSize, setFontSize] = usePersistedState({
key: 'fontSize',
initialValue: preferencesData?.fontSize ?? 20,
@ -53,6 +60,17 @@ export const useReaderSettings = (): ReaderSettings => {
key: 'fontFamily',
initialValue: DEFAULT_FONT,
})
const [highContrastText, setHighContrastText] = usePersistedState<
boolean | undefined
>({
key: `--display-high-contrast-text`,
initialValue: false,
})
const [justifyText, setJustifyText] = usePersistedState<boolean | undefined>({
key: `--display-justify-text`,
initialValue: false,
})
const [showSetLabelsModal, setShowSetLabelsModal] = useState(false)
const [showEditDisplaySettingsModal, setShowEditDisplaySettingsModal] =
useState(false)
@ -65,6 +83,12 @@ export const useReaderSettings = (): ReaderSettings => {
})()
}
// const [hideMargins, setHideMargins] = usePersistedState<boolean | undefined>({
// key: `--display-hide-margins`,
// initialValue: false,
// isSessionStorage: false,
// })
const actionHandler = useCallback(
(action: string, arg?: unknown) => {
switch (action) {
@ -199,5 +223,9 @@ export const useReaderSettings = (): ReaderSettings => {
actionHandler,
setFontFamily,
fontFamily,
justifyText,
setJustifyText,
highContrastText,
setHighContrastText,
}
}

View File

@ -376,6 +376,8 @@ export default function Home(): JSX.Element {
labels={labels}
showHighlightsModal={showHighlightsModal}
setShowHighlightsModal={setShowHighlightsModal}
justifyText={readerSettings.justifyText ?? undefined}
highContrastText={readerSettings.highContrastText ?? undefined}
articleMutations={{
createHighlightMutation,
deleteHighlightMutation,
@ -413,9 +415,9 @@ export default function Home(): JSX.Element {
<DisplaySettingsModal
centerX={true}
readerSettings={readerSettings}
onOpenChange={() =>
onOpenChange={() => {
readerSettings.setShowEditDisplaySettingsModal(false)
}
}}
/>
)}
{readerSettings.showDeleteConfirmation && (

View File

@ -324,7 +324,6 @@ on smaller screens we display the note icon
}
.article-inner-css .page {
text-align: start;
word-wrap: break-word;
font-size: var(--text-font-size);