From ccbaf402bdf5a717152c4aaf414144ce8417f517 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 22 Feb 2024 22:14:12 +0800 Subject: [PATCH 01/10] Better handling of errors in the library --- .../elements/icons/ConfusedSlothIcon.tsx | 317 ++++++++++++++++++ .../elements/icons/ErrorSlothIcon.tsx | 262 +++++++++++++++ .../components/templates/PrimaryDropdown.tsx | 16 +- .../templates/homeFeed/EmptyLibrary.tsx | 2 + .../templates/homeFeed/HomeFeedContainer.tsx | 94 +++++- .../queries/useGetLibraryItemsQuery.tsx | 2 + 6 files changed, 666 insertions(+), 27 deletions(-) create mode 100644 packages/web/components/elements/icons/ConfusedSlothIcon.tsx create mode 100644 packages/web/components/elements/icons/ErrorSlothIcon.tsx diff --git a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx new file mode 100644 index 000000000..a75126e97 --- /dev/null +++ b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx @@ -0,0 +1,317 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { isDarkTheme } from '../../../lib/themeUpdater' +import { IconProps } from './IconProps' + +import React from 'react' + +export function ConfusedSlothIcon(): JSX.Element { + const isDark = isDarkTheme() + return isDark ? : +} + +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..da38bf6d5 --- /dev/null +++ b/packages/web/components/elements/icons/ErrorSlothIcon.tsx @@ -0,0 +1,262 @@ +/* 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 ErrorSlothIcon(): JSX.Element { + const isDarkMode = useDarkModeListener() + return isDarkMode ? : +} + +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..bcf43895b 100644 --- a/packages/web/components/templates/PrimaryDropdown.tsx +++ b/packages/web/components/templates/PrimaryDropdown.tsx @@ -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 && ( <> { }, }} > + diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index f64700bca..ad17ee396 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -49,6 +49,8 @@ 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' export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT' export type LibraryMode = 'reads' | 'highlights' @@ -109,8 +111,11 @@ export function HomeFeedContainer(): JSX.Element { isValidating, performActionOnItem, mutate, + error: fetchItemsError, } = useGetLibraryItemsQuery(queryInputs) + console.log('fetchItemsError: ', fetchItemsError) + useEffect(() => { const handleRevalidate = () => { ;(async () => { @@ -856,6 +861,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} @@ -880,6 +886,51 @@ export function HomeFeedContainer(): JSX.Element { ) } +const FetchItemsError = (): JSX.Element => { + return ( + + + + Something has gone wrong. + + + We have encountered unexpected problems.{' '} + Get help + + + ) +} + export type HomeFeedContentProps = { items: LibraryItem[] searchTerm?: string @@ -890,6 +941,8 @@ export type HomeFeedContentProps = { hasData: boolean totalItems: number isValidating: boolean + fetchItemsError: boolean + loadMore: () => void labelsTarget: LibraryItem | undefined setLabelsTarget: (target: LibraryItem | undefined) => void @@ -1001,24 +1054,31 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { setShowFilterMenu={setShowFilterMenu} /> )} - {!props.isValidating && props.mode == 'highlights' && ( - - )} - {props.mode == 'reads' && ( - - )} + {props.fetchItemsError && } + + {!props.isValidating && + !props.fetchItemsError && + props.mode == 'highlights' && ( + + )} + + {!props.isValidating && + !props.fetchItemsError && + props.mode == 'reads' && ( + + )} {props.showAddLinkModal && ( number) @@ -447,5 +448,6 @@ export function useGetLibraryItemsQuery({ size, setSize, mutate, + error: !!error, } } From 88aa43c34a67a68fd2433f051b078056bacaa1f6 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 22 Feb 2024 22:15:17 +0800 Subject: [PATCH 02/10] Dark mode listener --- .../web/components/elements/icons/ConfusedSlothIcon.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx index a75126e97..a7c6e00d7 100644 --- a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx +++ b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx @@ -1,13 +1,14 @@ /* eslint-disable functional/no-class */ /* eslint-disable functional/no-this-expression */ -import { isDarkTheme } from '../../../lib/themeUpdater' +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 isDark = isDarkTheme() - return isDark ? : + const isDarkMode = useDarkModeListener() + return isDarkMode ? : } class ConfusedSlothIconDark extends React.Component { From 9a076b608f8d9dde5a8157dae0412e630e93c5c2 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 22 Feb 2024 22:18:10 +0800 Subject: [PATCH 03/10] Fallback icon --- packages/web/components/templates/PrimaryDropdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/PrimaryDropdown.tsx b/packages/web/components/templates/PrimaryDropdown.tsx index bcf43895b..a81601d76 100644 --- a/packages/web/components/templates/PrimaryDropdown.tsx +++ b/packages/web/components/templates/PrimaryDropdown.tsx @@ -60,7 +60,7 @@ const TriggerButton = (props: TriggerButtonProps): JSX.Element => { }, }} > - + Date: Fri, 23 Feb 2024 10:13:34 +0800 Subject: [PATCH 04/10] Fix link to help --- .../web/components/templates/homeFeed/HomeFeedContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index ad17ee396..487f33cec 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -925,7 +925,7 @@ const FetchItemsError = (): JSX.Element => { }} > We have encountered unexpected problems.{' '} - Get help + Get help ) From 6543c9b0173233e5200a46be676e9510f193bb7f Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 23 Feb 2024 10:54:00 +0800 Subject: [PATCH 05/10] Improve errors layout --- .../elements/icons/ConfusedSlothIcon.tsx | 9 +- .../elements/icons/ErrorSlothIcon.tsx | 5 +- .../templates/homeFeed/EmptyLibrary.tsx | 65 +++-------- .../templates/homeFeed/FetchItemsError.tsx | 56 ++++++++++ .../templates/homeFeed/HomeFeedContainer.tsx | 102 +++++++----------- packages/web/lib/hooks/useCurrentTheme.tsx | 8 ++ 6 files changed, 126 insertions(+), 119 deletions(-) create mode 100644 packages/web/components/templates/homeFeed/FetchItemsError.tsx diff --git a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx index a7c6e00d7..47f300a3e 100644 --- a/packages/web/components/elements/icons/ConfusedSlothIcon.tsx +++ b/packages/web/components/elements/icons/ConfusedSlothIcon.tsx @@ -7,8 +7,13 @@ import { IconProps } from './IconProps' import React from 'react' export function ConfusedSlothIcon(): JSX.Element { - const isDarkMode = useDarkModeListener() - return isDarkMode ? : + const { currentThemeIsDark } = useCurrentTheme() + console.log('is dark mdoe: ', currentThemeIsDark) + return currentThemeIsDark ? ( + + ) : ( + + ) } class ConfusedSlothIconDark extends React.Component { diff --git a/packages/web/components/elements/icons/ErrorSlothIcon.tsx b/packages/web/components/elements/icons/ErrorSlothIcon.tsx index da38bf6d5..c6545d997 100644 --- a/packages/web/components/elements/icons/ErrorSlothIcon.tsx +++ b/packages/web/components/elements/icons/ErrorSlothIcon.tsx @@ -1,14 +1,13 @@ /* 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 ErrorSlothIcon(): JSX.Element { - const isDarkMode = useDarkModeListener() - return isDarkMode ? : + const { currentThemeIsDark } = useCurrentTheme() + return currentThemeIsDark ? : } class ErrorSlothIconDark extends React.Component { diff --git a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx index bc3928057..058fb8f48 100644 --- a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx +++ b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx @@ -1,15 +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 = @@ -59,21 +56,13 @@ export const ErrorBox = (props: HelpMessageProps) => { return ( {errorTitle} @@ -182,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': @@ -194,41 +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 487f33cec..e160f05f8 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -51,6 +51,7 @@ 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' @@ -886,51 +887,6 @@ export function HomeFeedContainer(): JSX.Element { ) } -const FetchItemsError = (): JSX.Element => { - return ( - - - - Something has gone wrong. - - - We have encountered unexpected problems.{' '} - Get help - - - ) -} - export type HomeFeedContentProps = { items: LibraryItem[] searchTerm?: string @@ -1007,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.items.length <= 0 && ( + { + props.setShowAddLinkModal(true) + }} + /> + )} - {!props.isValidating && - !props.fetchItemsError && - props.mode == 'highlights' && ( - - )} + {showItems && props.mode == 'highlights' && ( + + )} - {!props.isValidating && - !props.fetchItemsError && - props.mode == 'reads' && ( - - )} + {showItems && props.mode == 'reads' && ( + + )} {props.showAddLinkModal && ( { + if (currentTheme) { + return isDarkTheme(currentTheme) + } + return false + }, [currentTheme]) + return { currentTheme, setCurrentTheme, resetSystemTheme, + currentThemeIsDark, } } From f85e82614656f3f2b9e69b201ddc2fdea149dfc5 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 23 Feb 2024 11:07:57 +0800 Subject: [PATCH 06/10] Simplify empty state handling, remove obsolete test --- .../templates/homeFeed/HomeFeedContainer.tsx | 38 +++++++------------ packages/web/stories/EmptyLibrary.stories.tsx | 27 ------------- 2 files changed, 14 insertions(+), 51 deletions(-) delete mode 100644 packages/web/stories/EmptyLibrary.stories.tsx diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index e160f05f8..eeaa1411f 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -1143,30 +1143,20 @@ export function LibraryItemsLayout( }} style={{ height: '100%', width: '100%' }} > - {!props.isValidating && props.items.length == 0 ? ( - { - props.setShowAddLinkModal(true) - }} - /> - ) : ( - - )} + - -export const EmptyLibraryStory: ComponentStory = ( - args: any -) => { - return ( - { - console.log('onAddLinkClicked') - }} - /> - ) -} From 72eea42b8e2c30e435b72bc50042fe7967dfe0c0 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 23 Feb 2024 14:18:53 +0800 Subject: [PATCH 07/10] Fix embedded svg --- packages/web/components/elements/icons/ErrorSlothIcon.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web/components/elements/icons/ErrorSlothIcon.tsx b/packages/web/components/elements/icons/ErrorSlothIcon.tsx index c6545d997..5d986c30c 100644 --- a/packages/web/components/elements/icons/ErrorSlothIcon.tsx +++ b/packages/web/components/elements/icons/ErrorSlothIcon.tsx @@ -80,7 +80,7 @@ class ErrorSlothIconDark extends React.Component { d="M79.7 33.5C79.7 33.5 81.8 28.7 93.8 30.5L85.1 34.1M106.4 33.5C106.4 33.5 109.7 29.6 117.5 29.9L112.1 33.5H106.4Z" fill="#3D3D3D" /> - + { strokeLinejoin="round" /> - + { d="M79.7 33.5C79.7 33.5 81.8 28.7 93.8 30.5L85.1 34.1M106.4 33.5C106.4 33.5 109.7 29.6 117.5 29.9L112.1 33.5H106.4Z" fill="#898989" /> - + { strokeLinejoin="round" /> - + Date: Fri, 23 Feb 2024 14:19:22 +0800 Subject: [PATCH 08/10] Use new dark theme handler for icons --- .../web/components/templates/PrimaryDropdown.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/web/components/templates/PrimaryDropdown.tsx b/packages/web/components/templates/PrimaryDropdown.tsx index a81601d76..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 @@ -262,7 +262,8 @@ export const StyledToggleButton = styled('button', { }) function ThemeSection(props: PrimaryDropdownProps): JSX.Element { - const { currentTheme, setCurrentTheme } = useCurrentTheme() + const { currentTheme, setCurrentTheme, currentThemeIsDark } = + useCurrentTheme() return ( <> @@ -298,9 +299,7 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element { }} > { setCurrentTheme(ThemeId.Light) }} @@ -309,9 +308,7 @@ function ThemeSection(props: PrimaryDropdownProps): JSX.Element { { setCurrentTheme(ThemeId.Dark) }} From 77e16027470f85b679b90b068c5269586eecbb08 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 23 Feb 2024 14:19:44 +0800 Subject: [PATCH 09/10] Handle error + empty library states --- .../components/templates/homeFeed/HomeFeedContainer.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index eeaa1411f..eab588201 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -115,7 +115,7 @@ export function HomeFeedContainer(): JSX.Element { error: fetchItemsError, } = useGetLibraryItemsQuery(queryInputs) - console.log('fetchItemsError: ', fetchItemsError) + console.log('fetchItemsError fetchItemsError: ', fetchItemsError) useEffect(() => { const handleRevalidate = () => { @@ -973,6 +973,8 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { return true }, [props]) + console.log('props.fetchItemsError', props.fetchItemsError) + return ( )} - {props.fetchItemsError && } - {!props.isValidating && props.items.length <= 0 && ( + {!showItems && props.fetchItemsError && } + {!showItems && !props.fetchItemsError && props.items.length <= 0 && ( { From 2ff00497b95bc2ab01f7a834eabc3fe4e9c94b2d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 23 Feb 2024 14:24:48 +0800 Subject: [PATCH 10/10] Remove debug line --- .../web/components/templates/homeFeed/HomeFeedContainer.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index eab588201..403656aa0 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -973,8 +973,6 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { return true }, [props]) - console.log('props.fetchItemsError', props.fetchItemsError) - return (