Rename Read Later to Non-Feed Items to clarify

This commit is contained in:
Jackson Harper 2023-08-28 10:27:16 +08:00
parent 54b060992a
commit c503115582
3 changed files with 92 additions and 62 deletions

View file

@ -86,7 +86,7 @@ export const EmptyLibrary = (props: EmptyLibraryProps) => {
const helpTitle = useMemo(() => {
switch (type) {
case 'feed':
return 'You do not have any feed items.'
return 'You do not have any feed items matching this query.'
case 'newsletter':
return 'You do not have any newsletter items.'
}

View file

@ -2,7 +2,7 @@ import { Action, createAction, useKBar, useRegisterActions } from 'kbar'
import debounce from 'lodash/debounce'
import { useRouter } from 'next/router'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import toast, { Toaster } from "react-hot-toast"
import toast, { Toaster } from 'react-hot-toast'
import TopBarProgress from 'react-topbar-progress-indicator'
import { useFetchMore } from '../../../lib/hooks/useFetchMoreScroll'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
@ -48,8 +48,9 @@ import {
} from '../../../lib/toastHelpers'
import { SetPageLabelsModalPresenter } from '../article/SetLabelsModalPresenter'
import { NotebookPresenter } from '../article/NotebookPresenter'
import { saveUrlMutation } from "../../../lib/networking/mutations/saveUrlMutation"
import { articleQuery } from "../../../lib/networking/queries/useGetArticleQuery"
import { saveUrlMutation } from '../../../lib/networking/mutations/saveUrlMutation'
import { articleQuery } from '../../../lib/networking/queries/useGetArticleQuery'
import { searchQuery } from '../../../lib/networking/queries/search'
export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT'
export type LibraryMode = 'reads' | 'highlights'
@ -70,7 +71,7 @@ const debouncedFetchSearchResults = debounce((query, cb) => {
// We set a relatively high delay for the refresh at the end, as it's likely there's an issue
// in processing. We give it the best attempt to be able to resolve, but if it doesn't we set
// the state as Failed. On refresh it will try again if the backend sends "PROCESSING"
const TIMEOUT_DELAYS = [1000, 2000, 2500, 3500, 5000, 10000, 60000];
const TIMEOUT_DELAYS = [1000, 2000, 2500, 3500, 5000, 10000, 60000]
export function HomeFeedContainer(): JSX.Element {
const { viewerData } = useGetViewerQuery()
@ -179,58 +180,69 @@ export function HomeFeedContainer(): JSX.Element {
return itemsPages[itemsPages.length - 1].search.pageInfo.hasNextPage
}, [itemsPages])
const libraryItems = useMemo(() => {
const items =
itemsPages?.flatMap((ad) => {
return ad.search.edges.map(it => ({ ...it, isLoading: it.node.state === 'PROCESSING'}));
return ad.search.edges.map((it) => ({
...it,
isLoading: it.node.state === 'PROCESSING',
}))
}) || []
return items
}, [itemsPages, performActionOnItem])
useEffect(() => {
const timeout : NodeJS.Timeout[] = []
const timeout: NodeJS.Timeout[] = []
const items =
(itemsPages?.flatMap((ad) => {
return ad.search.edges.map(it => ({ ...it, isLoading: it.node.state === 'PROCESSING'}));
}) || [])
.filter(it => it.isLoading);
const items = (
itemsPages?.flatMap((ad) => {
return ad.search.edges.map((it) => ({
...it,
isLoading: it.node.state === 'PROCESSING',
}))
}) || []
).filter((it) => it.isLoading)
items.map(async (item) => {
let startIdx = 0;
let startIdx = 0
const seeIfUpdated = async () => {
if (startIdx > TIMEOUT_DELAYS.length) {
item.node.state = State.FAILED;
item.node.state = State.FAILED
return
}
const username = viewerData?.me?.profile.username
const itemsToUpdate = libraryItems.filter(it => it.isLoading);
const itemsToUpdate = libraryItems.filter((it) => it.isLoading)
if (itemsToUpdate.length > 0) {
const link = await articleQuery({ username, slug: item.node.slug, includeFriendsHighlights: false })
const link = await articleQuery({
username,
slug: item.node.slug,
includeFriendsHighlights: false,
})
if (link && link.state != "PROCESSING") {
const updatedArticle = { ...item };
if (link && link.state != 'PROCESSING') {
const updatedArticle = { ...item }
updatedArticle.node = { ...item.node, ...link }
updatedArticle.isLoading = false;
updatedArticle.isLoading = false
console.log(`Updating Metadata of ${item.node.slug}.`)
performActionOnItem('update-item', updatedArticle);
return;
performActionOnItem('update-item', updatedArticle)
return
}
console.log(`Trying to get the metadata of item ${item.node.slug}... Retry ${startIdx} of 5`);
console.log(
`Trying to get the metadata of item ${item.node.slug}... Retry ${startIdx} of 5`
)
timeout.push(setTimeout(seeIfUpdated, TIMEOUT_DELAYS[startIdx++]))
}
}
await seeIfUpdated();
});
await seeIfUpdated()
})
return () => {
timeout.forEach(clearTimeout);
timeout.forEach(clearTimeout)
}
}, [itemsPages])
@ -769,36 +781,39 @@ export function HomeFeedContainer(): JSX.Element {
[itemsPages, multiSelectMode, checkedItems]
)
const handleLinkSubmission =
async (link: string, timezone: string, locale: string) => {
const result = await saveUrlMutation(link, timezone, locale)
if (result) {
toast(
() => (
<Box>
Link Saved
<span style={{ padding: '16px' }} />
<Button
style="ctaDarkYellow"
autoFocus
onClick={() => {
window.location.href = `/article?url=${encodeURIComponent(
link
)}`
}}
>
Read Now
</Button>
</Box>
),
{ position: 'bottom-right' }
)
const id = result.url?.match(/[^/]+$/)?.[0] ?? "";
performActionOnItem('refresh', undefined as unknown as any)
} else {
showErrorToast('Error saving link', { position: 'bottom-right' })
}
};
const handleLinkSubmission = async (
link: string,
timezone: string,
locale: string
) => {
const result = await saveUrlMutation(link, timezone, locale)
if (result) {
toast(
() => (
<Box>
Link Saved
<span style={{ padding: '16px' }} />
<Button
style="ctaDarkYellow"
autoFocus
onClick={() => {
window.location.href = `/article?url=${encodeURIComponent(
link
)}`
}}
>
Read Now
</Button>
</Box>
),
{ position: 'bottom-right' }
)
const id = result.url?.match(/[^/]+$/)?.[0] ?? ''
performActionOnItem('refresh', undefined as unknown as any)
} else {
showErrorToast('Error saving link', { position: 'bottom-right' })
}
}
return (
<HomeFeedGrid
@ -902,7 +917,11 @@ type HomeFeedContentProps = {
item: LibraryItem | undefined
) => Promise<void>
handleLinkSubmission: (link: string, timezone: string, locale:string) => Promise<void>,
handleLinkSubmission: (
link: string,
timezone: string,
locale: string
) => Promise<void>
setIsChecked: (itemId: string, set: boolean) => void
itemIsChecked: (itemId: string) => boolean
@ -986,7 +1005,10 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
)}
{props.showAddLinkModal && (
<AddLinkModal handleLinkSubmission={props.handleLinkSubmission} onOpenChange={() => props.setShowAddLinkModal(false)} />
<AddLinkModal
handleLinkSubmission={props.handleLinkSubmission}
onOpenChange={() => props.setShowAddLinkModal(false)}
/>
)}
</HStack>
</VStack>
@ -1044,6 +1066,7 @@ function LibraryItemsLayout(props: LibraryItemsLayoutProps): JSX.Element {
>
{!props.isValidating && props.items.length == 0 ? (
<EmptyLibrary
searchTerm={props.searchTerm}
onAddLinkClicked={() => {
props.setShowAddLinkModal(true)
}}

View file

@ -92,7 +92,7 @@ function SavedSearches(props: LibraryFilterMenuProps): JSX.Element {
term: 'in:inbox sort:read-desc is:unread',
},
{
name: 'Read Later',
name: 'Non-Feed Items',
term: 'in:library',
},
{
@ -182,7 +182,13 @@ function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
window.location.href = '/settings/subscriptions'
}}
>
{subscriptions.slice(0, viewAll ? undefined : 4).map((item) => {
<FilterButton filterTerm={`label:RSS`} text="Feeds" {...props} />
<FilterButton
filterTerm={`label:Newsletter`}
text="Newsletters"
{...props}
/>
{(subscriptions ?? []).slice(0, viewAll ? undefined : 4).map((item) => {
return (
<FilterButton
key={item.id}
@ -258,14 +264,15 @@ function MenuPanel(props: MenuPanelProps): JSX.Element {
lineHeight: '125%',
color: '$thLibraryMenuPrimary',
pl: '10px',
my: '20px',
mt: '20px',
mb: '10px',
}}
>
{props.title}
</StyledText>
<SpanBox
css={{
my: '15px',
mt: '15px',
marginLeft: 'auto',
height: '100%',
verticalAlign: 'middle',