Merge pull request #2819 from omnivore-app/feat/web-account-limits-ux
Account limits UX test
This commit is contained in:
@ -43,7 +43,11 @@ export function SettingsLayout(props: SettingsLayoutProps): JSX.Element {
|
||||
}, [showLogout])
|
||||
|
||||
return (
|
||||
<>
|
||||
<VStack
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
css={{ width: '100%', height: '100%', minHeight: '100vh' }}
|
||||
>
|
||||
<PageMetaData path="settings" title="Settings" />
|
||||
<SettingsHeader user={viewerData?.me} />
|
||||
<VStack css={{ width: '100%', height: '100%' }}>
|
||||
@ -52,7 +56,7 @@ export function SettingsLayout(props: SettingsLayoutProps): JSX.Element {
|
||||
height: HEADER_HEIGHT,
|
||||
}}
|
||||
></Box>
|
||||
<HStack css={{ width: '100%', height: '100%' }}>
|
||||
<HStack css={{ width: '100%', height: '100%' }} distribution="start">
|
||||
<SettingsMenu />
|
||||
{props.children}
|
||||
</HStack>
|
||||
@ -70,6 +74,6 @@ export function SettingsLayout(props: SettingsLayoutProps): JSX.Element {
|
||||
onOpenChange={() => setShowKeyboardCommandsModal(false)}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
@ -0,0 +1,163 @@
|
||||
import * as Switch from '@radix-ui/react-switch'
|
||||
import { ReaderSettings } from '../../../lib/hooks/useReaderSettings'
|
||||
import { HStack, VStack } from '../../elements/LayoutPrimitives'
|
||||
import {
|
||||
ModalRoot,
|
||||
ModalContent,
|
||||
ModalOverlay,
|
||||
} from '../../elements/ModalPrimitives'
|
||||
import { StyledText } from '../../elements/StyledText'
|
||||
import { ReaderSettingsControl } from './ReaderSettingsControl'
|
||||
import { styled } from '../../tokens/stitches.config'
|
||||
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
|
||||
|
||||
type PDFDisplaySettingsModalProps = {
|
||||
centerX: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
triggerElementRef?: React.RefObject<HTMLElement>
|
||||
readerSettings: ReaderSettings
|
||||
}
|
||||
|
||||
export function PDFDisplaySettingsModal(
|
||||
props: PDFDisplaySettingsModalProps
|
||||
): JSX.Element {
|
||||
return (
|
||||
<ModalRoot defaultOpen onOpenChange={props.onOpenChange}>
|
||||
<ModalOverlay css={{ backgroundColor: 'unset' }} />
|
||||
<ModalContent
|
||||
css={{
|
||||
width: '345px',
|
||||
padding: '0px',
|
||||
top: '262px',
|
||||
left: 'calc(100% - 250px)',
|
||||
'@lgDown': {
|
||||
top: '300px',
|
||||
left: '50%',
|
||||
},
|
||||
}}
|
||||
onPointerDownOutside={(event) => {
|
||||
event.preventDefault()
|
||||
props.onOpenChange(false)
|
||||
}}
|
||||
>
|
||||
<VStack css={{ width: '100%' }}>
|
||||
<PDFSettings readerSettings={props.readerSettings} />
|
||||
</VStack>
|
||||
</ModalContent>
|
||||
</ModalRoot>
|
||||
)
|
||||
}
|
||||
|
||||
type SettingsProps = {
|
||||
readerSettings: ReaderSettings
|
||||
}
|
||||
|
||||
function PDFSettings(props: SettingsProps): JSX.Element {
|
||||
const { readerSettings } = props
|
||||
const [showPDFToolBar, setShowPDFToolBar] = usePersistedState({
|
||||
key: 'reader-show-pdf-tool-bar',
|
||||
initialValue: true,
|
||||
isSessionStorage: false,
|
||||
})
|
||||
|
||||
return (
|
||||
<VStack
|
||||
css={{ width: '100%', minHeight: '320px', p: '10px' }}
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
>
|
||||
<HStack
|
||||
css={{
|
||||
width: '100%',
|
||||
pr: '30px',
|
||||
alignItems: 'center',
|
||||
'&:hover': {
|
||||
opacity: 0.8,
|
||||
},
|
||||
'&[data-state="on"]': {
|
||||
bg: '$thBackground',
|
||||
},
|
||||
}}
|
||||
alignment="start"
|
||||
distribution="between"
|
||||
>
|
||||
<Label htmlFor="show-menu-bar" css={{ width: '100%' }}>
|
||||
<StyledText style="displaySettingsLabel" css={{ pl: '20px' }}>
|
||||
Show Tool Bar
|
||||
</StyledText>
|
||||
</Label>
|
||||
<SwitchRoot
|
||||
id="show-menu-bar"
|
||||
checked={showPDFToolBar}
|
||||
onCheckedChange={(checked: boolean) => {
|
||||
setShowPDFToolBar(checked)
|
||||
document.dispatchEvent(new Event('pdfReaderUpdateSettings'))
|
||||
}}
|
||||
>
|
||||
<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={readerSettings.highContrastText ?? false}
|
||||
onCheckedChange={(checked: boolean) => {
|
||||
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,
|
||||
})
|
||||
@ -22,6 +22,7 @@ import 'react-sliding-pane/dist/react-sliding-pane.css'
|
||||
import { NotebookContent } from './Notebook'
|
||||
import { NotebookHeader } from './NotebookHeader'
|
||||
import useWindowDimensions from '../../../lib/hooks/useGetWindowDimensions'
|
||||
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
|
||||
|
||||
export type PdfArticleContainerProps = {
|
||||
viewer: UserBasicData
|
||||
@ -36,9 +37,8 @@ export default function PdfArticleContainer(
|
||||
const containerRef = useRef<HTMLDivElement | null>(null)
|
||||
const [notebookKey, setNotebookKey] = useState<string>(uuidv4())
|
||||
const [noteTarget, setNoteTarget] = useState<Highlight | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] =
|
||||
useState<number | undefined>(undefined)
|
||||
const highlightsRef = useRef<Highlight[]>([])
|
||||
|
||||
const annotationOmnivoreId = (annotation: Annotation): string | undefined => {
|
||||
@ -65,7 +65,12 @@ export default function PdfArticleContainer(
|
||||
'spacer',
|
||||
'search',
|
||||
'export-pdf',
|
||||
'sidebar-bookmarks',
|
||||
'sidebar-thumbnails',
|
||||
'sidebar-document-outline',
|
||||
]
|
||||
|
||||
console.log('PSPDFKit.defaultToolbarItems', PSPDFKit.defaultToolbarItems)
|
||||
const toolbarItems = PSPDFKit.defaultToolbarItems.filter(
|
||||
(i) => ALLOWED_TOOLBAR_ITEM_TYPES.indexOf(i.type) !== -1
|
||||
)
|
||||
@ -194,6 +199,11 @@ export default function PdfArticleContainer(
|
||||
return props.article.readingProgressAnchorIndex
|
||||
}
|
||||
|
||||
console.log(
|
||||
'theme: ',
|
||||
isDarkTheme() ? PSPDFKit.Theme.DARK : PSPDFKit.Theme.LIGHT
|
||||
)
|
||||
|
||||
instance = await PSPDFKit.load({
|
||||
container: container || '.pdf-container',
|
||||
toolbarItems,
|
||||
@ -455,6 +465,15 @@ export default function PdfArticleContainer(
|
||||
}
|
||||
})
|
||||
|
||||
document.addEventListener('pdfReaderUpdateSettings', () => {
|
||||
const show = localStorage.getItem('reader-show-pdf-tool-bar')
|
||||
const showToolbarbar = show ? JSON.parse(show) == true : false
|
||||
|
||||
instance.setViewState((viewState) =>
|
||||
viewState.set('showToolbar', showToolbarbar)
|
||||
)
|
||||
})
|
||||
|
||||
return () => {
|
||||
PSPDFKit && container && PSPDFKit.unload(container)
|
||||
}
|
||||
|
||||
@ -302,10 +302,12 @@ export const SettingsTable = (props: SettingsTableProps): JSX.Element => {
|
||||
/>
|
||||
<HStack css={{ width: '100%' }} alignment="center">
|
||||
<VStack
|
||||
alignment="start"
|
||||
distribution="center"
|
||||
css={{
|
||||
mx: '10px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxWidth: '865px',
|
||||
color: '$grayText',
|
||||
paddingBottom: '5rem',
|
||||
|
||||
@ -48,6 +48,7 @@ import { useSetPageLabels } from '../../../lib/hooks/useSetPageLabels'
|
||||
import { updatePageMutation } from '../../../lib/networking/mutations/updatePageMutation'
|
||||
import { State } from '../../../lib/networking/fragments/articleFragment'
|
||||
import { posthog } from 'posthog-js'
|
||||
import { PDFDisplaySettingsModal } from '../../../components/templates/article/PDFDisplaySettingsModal'
|
||||
|
||||
const PdfArticleContainerNoSSR = dynamic<PdfArticleContainerProps>(
|
||||
() => import('./../../../components/templates/article/PdfArticleContainer'),
|
||||
@ -556,15 +557,26 @@ export default function Home(): JSX.Element {
|
||||
onOpenChange={() => readerSettings.setShowSetLabelsModal(false)}
|
||||
/>
|
||||
)}
|
||||
{readerSettings.showEditDisplaySettingsModal && (
|
||||
<DisplaySettingsModal
|
||||
centerX={true}
|
||||
readerSettings={readerSettings}
|
||||
onOpenChange={() => {
|
||||
readerSettings.setShowEditDisplaySettingsModal(false)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{article?.contentReader === 'PDF' &&
|
||||
readerSettings.showEditDisplaySettingsModal && (
|
||||
<PDFDisplaySettingsModal
|
||||
centerX={true}
|
||||
readerSettings={readerSettings}
|
||||
onOpenChange={() => {
|
||||
readerSettings.setShowEditDisplaySettingsModal(false)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{article?.contentReader !== 'PDF' &&
|
||||
readerSettings.showEditDisplaySettingsModal && (
|
||||
<DisplaySettingsModal
|
||||
centerX={true}
|
||||
readerSettings={readerSettings}
|
||||
onOpenChange={() => {
|
||||
readerSettings.setShowEditDisplaySettingsModal(false)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{article && showEditModal && (
|
||||
<EditArticleModal
|
||||
article={article}
|
||||
|
||||
@ -15,7 +15,9 @@ import { Button } from '../../components/elements/Button'
|
||||
import { useValidateUsernameQuery } from '../../lib/networking/queries/useValidateUsernameQuery'
|
||||
import { updateUserMutation } from '../../lib/networking/mutations/updateUserMutation'
|
||||
import { updateUserProfileMutation } from '../../lib/networking/mutations/updateUserProfileMutation'
|
||||
import { styled } from '../../components/tokens/stitches.config'
|
||||
import { styled, theme } from '../../components/tokens/stitches.config'
|
||||
import { ProgressBar } from '../../components/elements/ProgressBar'
|
||||
import { useGetLibraryItemsQuery } from '../../lib/networking/queries/useGetLibraryItemsQuery'
|
||||
|
||||
const StyledLabel = styled('label', {
|
||||
fontWeight: 600,
|
||||
@ -72,6 +74,16 @@ export default function Account(): JSX.Element {
|
||||
isUsernameValidationLoading,
|
||||
])
|
||||
|
||||
const { itemsPages, isValidating } = useGetLibraryItemsQuery({
|
||||
limit: 0,
|
||||
searchQuery: 'in:all',
|
||||
sortDescending: false,
|
||||
})
|
||||
|
||||
const libraryCount = useMemo(() => {
|
||||
return itemsPages?.find(() => true)?.search.pageInfo.totalCount
|
||||
}, [itemsPages, isValidating])
|
||||
|
||||
useEffect(() => {
|
||||
if (viewerData?.me?.profile.username) {
|
||||
setUsername(viewerData?.me?.profile.username)
|
||||
@ -268,6 +280,33 @@ export default function Account(): JSX.Element {
|
||||
<Button style="ctaDarkYellow">Update Username</Button>
|
||||
</form>
|
||||
</VStack>
|
||||
|
||||
{/* <VStack
|
||||
css={{
|
||||
padding: '24px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
bg: '$grayBg',
|
||||
gap: '10px',
|
||||
borderRadius: '5px',
|
||||
}}
|
||||
>
|
||||
<StyledLabel>Account Storage</StyledLabel>
|
||||
{!isValidating && (
|
||||
<>
|
||||
<ProgressBar
|
||||
fillPercentage={(libraryCount ?? 0) / 50000}
|
||||
fillColor={theme.colors.omnivoreCtaYellow.toString()}
|
||||
backgroundColor={theme.colors.grayText.toString()}
|
||||
borderRadius={'2px'}
|
||||
/>
|
||||
<StyledText style="footnote" css={{ mt: '0px', mb: '20px' }}>
|
||||
{`${libraryCount} of 50K library items used.`}
|
||||
</StyledText>
|
||||
</>
|
||||
)}
|
||||
<Button style="ctaDarkYellow">Upgrade</Button>
|
||||
</VStack> */}
|
||||
</VStack>
|
||||
</VStack>
|
||||
</SettingsLayout>
|
||||
|
||||
Reference in New Issue
Block a user