mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Change timeout for polling.
This commit is contained in:
parent
27dd2b2734
commit
7aa959a4c7
5 changed files with 153 additions and 23 deletions
78
packages/web/components/elements/LoadingBar.tsx
Normal file
78
packages/web/components/elements/LoadingBar.tsx
Normal file
|
|
@ -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<SetStateAction<AnimationStatus>>) => {
|
||||
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 (
|
||||
<Box
|
||||
css={{
|
||||
height: '5px',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: props.backgroundColor,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
css={{
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
width: `${props.percentFill ?? 10}%`,
|
||||
left: `${leftOne.position}%`,
|
||||
transition: leftOne.transition,
|
||||
backgroundColor: props.fillColor,
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
css={{
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
width: `${props.percentFill ?? 10}%`,
|
||||
left: `${leftTwo.position}%`,
|
||||
transition: leftTwo.transition,
|
||||
backgroundColor: props.fillColor,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
|
@ -30,4 +30,5 @@ export type LinkedItemCardProps = {
|
|||
multiSelectMode: MultiSelectMode
|
||||
|
||||
isHovered?: boolean
|
||||
isLoading?: boolean
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
<LoadingBarOverlay
|
||||
width="100%"
|
||||
top={95}
|
||||
bottomRadius={'0px'}
|
||||
fillColor={"rgba(60, 179, 113, 1)"}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{(props.readingProgress ?? 0) > 0 && !props.isLoading && (
|
||||
<ProgressBarOverlay
|
||||
width="100%"
|
||||
top={95}
|
||||
|
|
@ -189,6 +198,7 @@ const LibraryGridCardContent = (props: LinkedItemCardProps): JSX.Element => {
|
|||
src={props.item.image}
|
||||
title={props.item.title}
|
||||
readingProgress={item.readingProgressPercent}
|
||||
isLoading={props.isLoading}
|
||||
/>
|
||||
<SpanBox
|
||||
css={{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import { ProgressBar } from '../../elements/ProgressBar'
|
|||
import { theme } from '../../tokens/stitches.config'
|
||||
import { FallbackImage } from './FallbackImage'
|
||||
import { useRouter } from 'next/router'
|
||||
import { LoadingBar } from "../../elements/LoadingBar"
|
||||
|
||||
export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
|
||||
const router = useRouter()
|
||||
|
|
@ -128,11 +129,45 @@ export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
|
|||
)
|
||||
}
|
||||
|
||||
type LoadingBarOverlayProps = {
|
||||
top: number
|
||||
width: string
|
||||
bottomRadius: string,
|
||||
fillColor?: string,
|
||||
percentFill?: number
|
||||
}
|
||||
|
||||
|
||||
type ProgressBarOverlayProps = {
|
||||
top: number
|
||||
width: string
|
||||
value: number
|
||||
bottomRadius: string
|
||||
bottomRadius: string,
|
||||
}
|
||||
|
||||
export const LoadingBarOverlay = (
|
||||
props: LoadingBarOverlayProps
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<Box
|
||||
css={{
|
||||
position: 'absolute',
|
||||
width: props.width,
|
||||
top: props.top,
|
||||
borderBottomLeftRadius: props.bottomRadius,
|
||||
borderBottomRightRadius: props.bottomRadius,
|
||||
overflow: 'clip',
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
<LoadingBar
|
||||
fillColor={props.fillColor ?? theme.colors.thProgressFg.toString()}
|
||||
backgroundColor="rgba(217, 217, 217, 0.65)"
|
||||
borderRadius={'2px'}
|
||||
percentFill={props.percentFill}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
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 && (
|
||||
<LoadingBarOverlay
|
||||
width="55px"
|
||||
top={50}
|
||||
bottomRadius="4px"
|
||||
fillColor={"rgba(60, 179, 113, 1)"}
|
||||
percentFill={30}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{(props.readingProgress ?? 0) > 0 && (
|
||||
<ProgressBarOverlay
|
||||
width="55px"
|
||||
|
|
@ -241,6 +287,7 @@ export function LibraryListCardContent(
|
|||
src={props.item.image}
|
||||
title={props.item.title}
|
||||
readingProgress={item.readingProgressPercent}
|
||||
isLoading={props.isLoading}
|
||||
/>
|
||||
</Box>
|
||||
<VStack
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ const debouncedFetchSearchResults = debounce((query, cb) => {
|
|||
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 {
|
|||
<LinkedItemCard
|
||||
layout={props.layout}
|
||||
item={linkedItem.node}
|
||||
isLoading={linkedItem.isLoading}
|
||||
viewer={props.viewer}
|
||||
isChecked={props.isChecked(linkedItem.node.id)}
|
||||
setIsChecked={props.setIsChecked}
|
||||
|
|
|
|||
Loading…
Reference in a new issue