diff --git a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx new file mode 100644 index 000000000..47f300a3e --- /dev/null +++ b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx @@ -0,0 +1,323 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { useCurrentTheme } from '../../../lib/hooks/useCurrentTheme' +import { useDarkModeListener } from '../../../lib/hooks/useDarkModeListener' +import { IconProps } from './IconProps' + +import React from 'react' + +export function ConfusedSlothIcon(): JSX.Element { + const { currentThemeIsDark } = useCurrentTheme() + console.log('is dark mdoe: ', currentThemeIsDark) + return currentThemeIsDark ? ( + + ) : ( + + ) +} + +class ConfusedSlothIconDark extends React.Component { + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} + +class ConfusedSlothIconLight extends React.Component { + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} diff --git a/packages/web/components/elements/icons/ErrorSlothIcon.tsx b/packages/web/components/elements/icons/ErrorSlothIcon.tsx new file mode 100644 index 000000000..5d986c30c --- /dev/null +++ b/packages/web/components/elements/icons/ErrorSlothIcon.tsx @@ -0,0 +1,261 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { useCurrentTheme } from '../../../lib/hooks/useCurrentTheme' +import { IconProps } from './IconProps' + +import React from 'react' + +export function ErrorSlothIcon(): JSX.Element { + const { currentThemeIsDark } = useCurrentTheme() + return currentThemeIsDark ? : +} + +class ErrorSlothIconDark extends React.Component { + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} + +class ErrorSlothIconLight extends React.Component { + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} diff --git a/packages/web/components/templates/PrimaryDropdown.tsx b/packages/web/components/templates/PrimaryDropdown.tsx index 65ff189a6..e7f2d727a 100644 --- a/packages/web/components/templates/PrimaryDropdown.tsx +++ b/packages/web/components/templates/PrimaryDropdown.tsx @@ -15,7 +15,7 @@ import { Box, HStack, SpanBox, VStack } from '../elements/LayoutPrimitives' import { StyledText } from '../elements/StyledText' import { styled, theme, ThemeId } from '../tokens/stitches.config' import { LayoutType } from './homeFeed/HomeFeedContainer' -import { useCurrentTheme, isDarkTheme } from '../../lib/hooks/useCurrentTheme' +import { useCurrentTheme } from '../../lib/hooks/useCurrentTheme' type PrimaryDropdownProps = { children?: ReactNode @@ -41,7 +41,7 @@ export type HeaderDropdownAction = | 'logout' type TriggerButtonProps = { - name: string + name?: string } const TriggerButton = (props: TriggerButtonProps): JSX.Element => { @@ -60,7 +60,7 @@ const TriggerButton = (props: TriggerButtonProps): JSX.Element => { }, }} > - + { whiteSpace: 'nowrap', }} > - {props.name} + {props.name ?? 'Settings'} ) @@ -124,15 +124,11 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element { [router] ) - if (!viewerData?.me) { - return <> - } - return ( + props.children ?? } css={{ width: '240px', ml: '15px' }} > @@ -153,7 +149,7 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element { }} > @@ -162,7 +158,7 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element { alignment="start" distribution="around" > - {viewerData.me && ( + {viewerData?.me && ( <> @@ -302,9 +299,7 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element { }} > { setCurrentTheme(ThemeId.Light) }} @@ -313,9 +308,7 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element { { setCurrentTheme(ThemeId.Dark) }} diff --git a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx index 361f24f11..058fb8f48 100644 --- a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx +++ b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx @@ -1,14 +1,12 @@ -import { Box } from '../../elements/LayoutPrimitives' +import { Box, VStack } from '../../elements/LayoutPrimitives' import { useMemo } from 'react' -import { LIBRARY_LEFT_MENU_WIDTH } from '../navMenu/LibraryMenu' -import { LayoutType } from './HomeFeedContainer' import { SuggestionBox, SuggestionAction } from '../../elements/SuggestionBox' +import { ConfusedSlothIcon } from '../../elements/icons/ConfusedSlothIcon' +import { DEFAULT_HEADER_HEIGHT } from './HeaderSpacer' type EmptyLibraryProps = { searchTerm: string | undefined onAddLinkClicked: () => void - - layoutType: LayoutType } type MessageType = @@ -58,21 +56,13 @@ export const ErrorBox = (props: HelpMessageProps) => { return ( {errorTitle} @@ -181,6 +171,7 @@ export const EmptyLibrary = (props: EmptyLibraryProps) => { return 'files' case 'in:archive': return 'archive' + case 'in:following use:folders': case 'label:RSS': return 'feed' case 'has:subscriptions': @@ -193,40 +184,20 @@ export const EmptyLibrary = (props: EmptyLibraryProps) => { }, [props]) return ( - + - + ) } diff --git a/packages/web/components/templates/homeFeed/FetchItemsError.tsx b/packages/web/components/templates/homeFeed/FetchItemsError.tsx new file mode 100644 index 000000000..7a6f1c2d9 --- /dev/null +++ b/packages/web/components/templates/homeFeed/FetchItemsError.tsx @@ -0,0 +1,56 @@ +import { VStack } from '../../elements/LayoutPrimitives' +import { StyledText } from '../../elements/StyledText' +import { ErrorSlothIcon } from '../../elements/icons/ErrorSlothIcon' +import { DEFAULT_HEADER_HEIGHT } from './HeaderSpacer' + +export const FetchItemsError = (): JSX.Element => { + return ( + + + + Something has gone wrong. + + + We have encountered unexpected problems.{' '} + + Get help + + + + ) +} diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index f64700bca..403656aa0 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -49,6 +49,9 @@ import { saveUrlMutation } from '../../../lib/networking/mutations/saveUrlMutati import { articleQuery } from '../../../lib/networking/queries/useGetArticleQuery' import { PinnedButtons } from './PinnedButtons' import { PinnedSearch } from '../../../pages/settings/pinned-searches' +import { ErrorSlothIcon } from '../../elements/icons/ErrorSlothIcon' +import { DEFAULT_HEADER_HEIGHT } from './HeaderSpacer' +import { FetchItemsError } from './FetchItemsError' export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT' export type LibraryMode = 'reads' | 'highlights' @@ -109,8 +112,11 @@ export function HomeFeedContainer(): JSX.Element { isValidating, performActionOnItem, mutate, + error: fetchItemsError, } = useGetLibraryItemsQuery(queryInputs) + console.log('fetchItemsError fetchItemsError: ', fetchItemsError) + useEffect(() => { const handleRevalidate = () => { ;(async () => { @@ -856,6 +862,7 @@ export function HomeFeedContainer(): JSX.Element { hasData={!!itemsPages} totalItems={itemsPages?.[0].search.pageInfo.totalCount || 0} isValidating={isValidating} + fetchItemsError={!!fetchItemsError} labelsTarget={labelsTarget} setLabelsTarget={setLabelsTarget} notebookTarget={notebookTarget} @@ -890,6 +897,8 @@ export type HomeFeedContentProps = { hasData: boolean totalItems: number isValidating: boolean + fetchItemsError: boolean + loadMore: () => void labelsTarget: LibraryItem | undefined setLabelsTarget: (target: LibraryItem | undefined) => void @@ -954,6 +963,16 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { const [showFilterMenu, setShowFilterMenu] = useState(false) + const showItems = useMemo(() => { + if (props.fetchItemsError) { + return false + } + if (!props.isValidating && props.items.length <= 0) { + return false + } + return true + }, [props]) + return ( )} - {!props.isValidating && props.mode == 'highlights' && ( + + {!showItems && props.fetchItemsError && } + {!showItems && !props.fetchItemsError && props.items.length <= 0 && ( + { + props.setShowAddLinkModal(true) + }} + /> + )} + + {showItems && props.mode == 'highlights' && ( )} - {props.mode == 'reads' && ( + {showItems && props.mode == 'reads' && ( - {!props.isValidating && props.items.length == 0 ? ( - { - props.setShowAddLinkModal(true) - }} - /> - ) : ( - - )} + { + if (currentTheme) { + return isDarkTheme(currentTheme) + } + return false + }, [currentTheme]) + return { currentTheme, setCurrentTheme, resetSystemTheme, + currentThemeIsDark, } } diff --git a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx index c289b3f7c..9f9257fcf 100644 --- a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx +++ b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx @@ -34,6 +34,7 @@ type LibraryItemsQueryResponse = { itemsDataError?: unknown isLoading: boolean isValidating: boolean + error: boolean size: number setSize: ( size: number | ((_size: number) => number) @@ -447,5 +448,6 @@ export function useGetLibraryItemsQuery({ size, setSize, mutate, + error: !!error, } } diff --git a/packages/web/stories/EmptyLibrary.stories.tsx b/packages/web/stories/EmptyLibrary.stories.tsx deleted file mode 100644 index a690ad1d8..000000000 --- a/packages/web/stories/EmptyLibrary.stories.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentStory, ComponentMeta } from '@storybook/react' -import { EmptyLibrary } from '../components/templates/homeFeed/EmptyLibrary' - -export default { - title: 'Components/EmptyLibraryStory', - component: EmptyLibrary, - argTypes: { - position: { - description: 'The empty library component', - control: { type: 'select' }, - }, - }, -} as ComponentMeta - -export const EmptyLibraryStory: ComponentStory = ( - args: any -) => { - return ( - { - console.log('onAddLinkClicked') - }} - /> - ) -}