diff --git a/packages/web/components/elements/LoadingBar.tsx b/packages/web/components/elements/LoadingBar.tsx new file mode 100644 index 000000000..8231a5b19 --- /dev/null +++ b/packages/web/components/elements/LoadingBar.tsx @@ -0,0 +1,78 @@ +import { Box } from './../elements/LayoutPrimitives' +import { Dispatch, SetStateAction, useEffect, useState } from "react" + +type LoadingBarProps = { + fillColor: string + backgroundColor: string + borderRadius: string + percentFill?: number +} + +type AnimationStatus = { + position: number, + transition: string +} +export function LoadingBar(props: LoadingBarProps): JSX.Element { + // OK So, what we want to do is. + // We have two boxes. + const [leftOne, setLeftOne] = useState({ position: 0, transition: 'left 0.5s linear' }) + const [leftTwo, setLeftTwo] = useState({ position: -100, transition: 'left 0.5s linear' }) + + const calculateNewValue = (currVal: AnimationStatus, setNextVal: Dispatch>) => { + const position = currVal.position >= 100 ? -100 : currVal.position + 25; + const transition = currVal.position >= 100 ? 'left 0s linear' : 'left 0.5s linear'; + setNextVal({ position, transition }) + } + + useEffect(() => { + const interval = setTimeout(() => { + calculateNewValue(leftOne, setLeftOne) + }, 500); + + return () => { + clearTimeout(interval) + } + }, [leftOne]) + + useEffect(() => { + const interval = setTimeout(() => { + calculateNewValue(leftTwo, setLeftTwo) + }, 500); + + return () => { + clearTimeout(interval) + } + }, [leftTwo]) + + return ( + + + + + ) +} diff --git a/packages/web/components/patterns/LibraryCards/CardTypes.tsx b/packages/web/components/patterns/LibraryCards/CardTypes.tsx index 799509cb2..ab9d9dfcb 100644 --- a/packages/web/components/patterns/LibraryCards/CardTypes.tsx +++ b/packages/web/components/patterns/LibraryCards/CardTypes.tsx @@ -30,4 +30,5 @@ export type LinkedItemCardProps = { multiSelectMode: MultiSelectMode isHovered?: boolean + isLoading?: boolean } diff --git a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx index 60072a376..167fdbd05 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx @@ -5,7 +5,6 @@ import { CoverImage } from '../../elements/CoverImage' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { useCallback, useState } from 'react' -import Link from 'next/link' import { AuthorInfoStyle, CardCheckbox, @@ -28,7 +27,7 @@ import { import { CardMenu } from '../CardMenu' import { DotsThree } from 'phosphor-react' import { isTouchScreenDevice } from '../../../lib/deviceType' -import { ProgressBarOverlay } from './LibraryListCard' +import { LoadingBarOverlay, ProgressBarOverlay } from "./LibraryListCard" import { FallbackImage } from './FallbackImage' import { useRouter } from 'next/router' @@ -88,7 +87,6 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element { setIsHovered(false) }} onClick={(event) => { - console.log('click event: ', event) if (event.metaKey || event.ctrlKey) { window.open( `/${props.viewer.profile.username}/${props.item.slug}`, @@ -133,6 +131,7 @@ type GridImageProps = { src?: string title?: string readingProgress?: number + isLoading?: boolean } const GridImage = (props: GridImageProps): JSX.Element => { @@ -140,7 +139,17 @@ const GridImage = (props: GridImageProps): JSX.Element => { return ( <> - {(props.readingProgress ?? 0) > 0 && ( + { + props.isLoading && ( + + ) + } + {(props.readingProgress ?? 0) > 0 && !props.isLoading && ( { src={props.item.image} title={props.item.title} readingProgress={item.readingProgressPercent} + isLoading={props.isLoading} /> { + return ( + + + + ) } export const ProgressBarOverlay = ( @@ -164,13 +199,24 @@ type ListImageProps = { src?: string title?: string readingProgress?: number + isLoading?: boolean } const ListImage = (props: ListImageProps): JSX.Element => { const [displayFallback, setDisplayFallback] = useState(props.src == undefined) return ( - <> + <>{ + props.isLoading && ( + + ) + } {(props.readingProgress ?? 0) > 0 && ( { fetchSearchResults(query, cb) }, 300) -const TIMEOUT_DELAYS = [500, 750, 1000, 2000, 5000]; +// We set a relatively high delay for the refresh. +const TIMEOUT_DELAYS = [1000, 3000, 4000, 5000, 10000]; export function HomeFeedContainer(): JSX.Element { const { viewerData } = useGetViewerQuery() @@ -142,10 +143,11 @@ export function HomeFeedContainer(): JSX.Element { useEffect(() => { if (!router.isReady) return const q = router.query['q'] - let qs = '' + let qs = 'in:inbox' // Default to in:inbox search term. if (q && typeof q === 'string') { qs = q } + if (qs !== (queryInputs.searchQuery || '')) { setQueryInputs({ ...queryInputs, searchQuery: qs }) performActionOnItem('refresh', undefined as unknown as any) @@ -172,7 +174,7 @@ export function HomeFeedContainer(): JSX.Element { const libraryItems = useMemo(() => { const items = itemsPages?.flatMap((ad) => { - return ad.search.edges + return ad.search.edges.map(it => ({ ...it, isLoading: it.node.state === 'PROCESSING'})); }) || [] return items }, [itemsPages, performActionOnItem]) @@ -186,13 +188,16 @@ export function HomeFeedContainer(): JSX.Element { } const item = getItem(savedLink); - const username = viewerData?.me?.profile.username; + const username = viewerData?.me?.profile.username + if (item) { const link = await articleQuery({ username, slug: item.node.slug, includeFriendsHighlights: false }) if (link && link.state != "PROCESSING") { const updatedArticle = { ...item }; updatedArticle.node = {...item.node, ...link } + updatedArticle.isLoading = false; + console.log('updating') performActionOnItem('update-item', updatedArticle); return; } @@ -206,9 +211,8 @@ export function HomeFeedContainer(): JSX.Element { // If the item was not found, this suggests that we are not in the right search view. So we can bail early. } - - setTimeout(seeIfUpdated, TIMEOUT_DELAYS[0]); setSavedLink(undefined); + setTimeout(seeIfUpdated, TIMEOUT_DELAYS[0]); } }, [itemsPages]) @@ -315,13 +319,6 @@ export function HomeFeedContainer(): JSX.Element { [libraryItems] ) - const getItemByUrl = useCallback( - (url: string) => { - return libraryItems.find(it => it.node.url === url); - }, - [libraryItems] - ) - const activeItemIndex = useMemo(() => { if (!activeCardId) { return undefined @@ -755,10 +752,6 @@ export function HomeFeedContainer(): JSX.Element { [itemsPages, multiSelectMode, checkedItems] ) - const queryUntilSavedOrTimeout = async (url: string, tries : number | undefined = 5)=> { - return; - } - const handleLinkSubmission = async (link: string, timezone: string, locale: string) => { const result = await saveUrlMutation(link, timezone, locale) @@ -1283,6 +1276,7 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {