mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Rename Read Later to Non-Feed Items to clarify
This commit is contained in:
parent
54b060992a
commit
c503115582
3 changed files with 92 additions and 62 deletions
|
|
@ -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.'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Reference in a new issue