More moves to react-query for key library functions
This commit is contained in:
@ -8,7 +8,6 @@ import React from 'react'
|
||||
|
||||
export function ConfusedSlothIcon(): JSX.Element {
|
||||
const { currentThemeIsDark } = useCurrentTheme()
|
||||
console.log('is dark mdoe: ', currentThemeIsDark)
|
||||
return currentThemeIsDark ? (
|
||||
<ConfusedSlothIconDark />
|
||||
) : (
|
||||
|
||||
@ -80,6 +80,7 @@ export function HighlightViewNote(props: HighlightViewNoteProps): JSX.Element {
|
||||
const saveText = useCallback(
|
||||
(text: string) => {
|
||||
;(async () => {
|
||||
console.log('saving text: ', text)
|
||||
const success = await updateHighlightMutation({
|
||||
annotation: text,
|
||||
libraryItemId: props.targetId,
|
||||
|
||||
@ -50,6 +50,7 @@ export function HighlightViewNote(props: HighlightViewNoteProps): JSX.Element {
|
||||
const saveText = useCallback(
|
||||
(text: string, updateTime: Date, interactive: boolean) => {
|
||||
;(async () => {
|
||||
console.log('updating highlight text')
|
||||
const success = await updateHighlightMutation({
|
||||
annotation: text,
|
||||
libraryItemId: props.targetId,
|
||||
|
||||
@ -4,7 +4,7 @@ import {
|
||||
DropdownOption,
|
||||
DropdownSeparator,
|
||||
} from '../elements/DropdownElements'
|
||||
import { ArticleAttributes } from '../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../lib/networking/library_items/useLibraryItems'
|
||||
import { State } from '../../lib/networking/fragments/articleFragment'
|
||||
|
||||
type DropdownMenuProps = {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Separator } from '@radix-ui/react-separator'
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { Button } from '../../elements/Button'
|
||||
import { Box, SpanBox } from '../../elements/LayoutPrimitives'
|
||||
import { styled, theme } from '../../tokens/stitches.config'
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
import {
|
||||
ArticleAttributes,
|
||||
TextDirection,
|
||||
} from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { Article } from './../../../components/templates/article/Article'
|
||||
import { Box, HStack, SpanBox, VStack } from './../../elements/LayoutPrimitives'
|
||||
import { StyledText } from './../../elements/StyledText'
|
||||
@ -19,11 +15,13 @@ import { updateTheme, updateThemeLocally } from '../../../lib/themeUpdater'
|
||||
import { ArticleMutations } from '../../../lib/articleActions'
|
||||
import { LabelChip } from '../../elements/LabelChip'
|
||||
import { Label } from '../../../lib/networking/fragments/labelFragment'
|
||||
import { Recommendation } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import {
|
||||
ArticleAttributes,
|
||||
Recommendation,
|
||||
TextDirection,
|
||||
} from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { Avatar } from '../../elements/Avatar'
|
||||
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
|
||||
import { AISummary } from './AISummary'
|
||||
import { userHasFeature } from '../../../lib/featureFlag'
|
||||
|
||||
type ArticleContainerProps = {
|
||||
viewer: UserBasicData
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { Box, VStack } from '../../elements/LayoutPrimitives'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { nanoid } from 'nanoid'
|
||||
@ -42,13 +42,15 @@ type EpubPatch = {
|
||||
export default function EpubContainer(props: EpubContainerProps): JSX.Element {
|
||||
const epubRef = useRef<HTMLDivElement | null>(null)
|
||||
const renditionRef = useRef<Rendition | undefined>(undefined)
|
||||
const [shareTarget, setShareTarget] =
|
||||
useState<Highlight | undefined>(undefined)
|
||||
const [shareTarget, setShareTarget] = useState<Highlight | undefined>(
|
||||
undefined
|
||||
)
|
||||
const [touchStart, setTouchStart] = useState(0)
|
||||
const [notebookKey, setNotebookKey] = useState<string>(uuidv4())
|
||||
const [noteTarget, setNoteTarget] = useState<Highlight | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] =
|
||||
useState<number | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined)
|
||||
const highlightsRef = useRef<Highlight[]>([])
|
||||
|
||||
const book = useMemo(() => {
|
||||
|
||||
@ -9,8 +9,8 @@ import { VStack } from '../../elements/LayoutPrimitives'
|
||||
import { Highlight } from '../../../lib/networking/fragments/highlightFragment'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { StyledTextArea } from '../../elements/StyledTextArea'
|
||||
import { updateHighlightMutation } from '../../../lib/networking/mutations/updateHighlightMutation'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
import { useUpdateHighlight } from '../../../lib/networking/highlights/useItemHighlights'
|
||||
|
||||
type HighlightNoteModalProps = {
|
||||
author: string
|
||||
@ -25,6 +25,7 @@ type HighlightNoteModalProps = {
|
||||
export function HighlightNoteModal(
|
||||
props: HighlightNoteModalProps
|
||||
): JSX.Element {
|
||||
const updateHighlight = useUpdateHighlight()
|
||||
const [noteContent, setNoteContent] = useState(
|
||||
props.highlight?.annotation ?? ''
|
||||
)
|
||||
@ -38,20 +39,24 @@ export function HighlightNoteModal(
|
||||
|
||||
const saveNoteChanges = useCallback(async () => {
|
||||
if (noteContent != props.highlight?.annotation && props.highlight?.id) {
|
||||
const result = await updateHighlightMutation({
|
||||
libraryItemId: props.libraryItemId,
|
||||
highlightId: props.highlight?.id,
|
||||
annotation: noteContent,
|
||||
color: props.highlight?.color,
|
||||
})
|
||||
|
||||
if (result) {
|
||||
console.log('updating highlight textsdsdfsd')
|
||||
try {
|
||||
const result = await updateHighlight.mutateAsync({
|
||||
itemId: props.libraryItemId,
|
||||
input: {
|
||||
libraryItemId: props.libraryItemId,
|
||||
highlightId: props.highlight?.id,
|
||||
annotation: noteContent,
|
||||
color: props.highlight?.color,
|
||||
},
|
||||
})
|
||||
props.onUpdate({ ...props.highlight, annotation: noteContent })
|
||||
props.onOpenChange(false)
|
||||
} else {
|
||||
return result?.id
|
||||
} catch (err) {
|
||||
showErrorToast('Error updating your note', { position: 'bottom-right' })
|
||||
return undefined
|
||||
}
|
||||
document.dispatchEvent(new Event('highlightsUpdated'))
|
||||
}
|
||||
if (!props.highlight && props.createHighlightForNote) {
|
||||
const result = await props.createHighlightForNote(noteContent)
|
||||
|
||||
@ -16,10 +16,10 @@ import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery
|
||||
import { ReadableItem } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { SetHighlightLabelsModalPresenter } from './SetLabelsModalPresenter'
|
||||
import { ArticleNotes } from '../../patterns/ArticleNotes'
|
||||
import { useGetArticleQuery } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { formattedShortTime } from '../../../lib/dateFormatting'
|
||||
import { isDarkTheme } from '../../../lib/themeUpdater'
|
||||
import { sortHighlights } from '../../../lib/highlights/sortHighlights'
|
||||
import { useGetLibraryItemContent } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
|
||||
type NotebookContentProps = {
|
||||
viewer: UserBasicData
|
||||
@ -43,11 +43,10 @@ type NoteState = {
|
||||
export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
const isDark = isDarkTheme()
|
||||
|
||||
const { articleData, mutate } = useGetArticleQuery({
|
||||
slug: props.item.slug,
|
||||
username: props.viewer.profile.username,
|
||||
includeFriendsHighlights: false,
|
||||
})
|
||||
const { data: article } = useGetLibraryItemContent(
|
||||
props.viewer.profile.username as string,
|
||||
props.item.slug as string
|
||||
)
|
||||
const [noteText, setNoteText] = useState<string>('')
|
||||
const [showConfirmDeleteHighlightId, setShowConfirmDeleteHighlightId] =
|
||||
useState<undefined | string>(undefined)
|
||||
@ -112,7 +111,7 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
)
|
||||
|
||||
const highlights = useMemo(() => {
|
||||
const result = articleData?.article.article.highlights
|
||||
const result = article?.highlights
|
||||
const note = result?.find((h) => h.type === 'NOTE')
|
||||
if (note) {
|
||||
noteState.current.note = note
|
||||
@ -122,7 +121,7 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
setNoteText('')
|
||||
}
|
||||
return result
|
||||
}, [articleData])
|
||||
}, [article])
|
||||
|
||||
useEffect(() => {
|
||||
if (highlights && props.onAnnotationsChanged) {
|
||||
@ -179,16 +178,6 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
const [lastChanged, setLastChanged] = useState<Date | undefined>(undefined)
|
||||
const [lastSaved, setLastSaved] = useState<Date | undefined>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
const highlightsUpdated = () => {
|
||||
mutate()
|
||||
}
|
||||
document.addEventListener('highlightsUpdated', highlightsUpdated)
|
||||
return () => {
|
||||
document.removeEventListener('highlightsUpdated', highlightsUpdated)
|
||||
}
|
||||
}, [mutate])
|
||||
|
||||
return (
|
||||
<VStack
|
||||
tabIndex={-1}
|
||||
@ -256,9 +245,6 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
viewInReader={props.viewInReader}
|
||||
setSetLabelsTarget={setLabelsTarget}
|
||||
setShowConfirmDeleteHighlightId={setShowConfirmDeleteHighlightId}
|
||||
updateHighlight={() => {
|
||||
mutate()
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{sortedHighlights.length === 0 && (
|
||||
@ -298,7 +284,6 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
props.item.id,
|
||||
showConfirmDeleteHighlightId
|
||||
)
|
||||
mutate()
|
||||
if (success) {
|
||||
showSuccessToast('Highlight deleted.', {
|
||||
position: 'bottom-right',
|
||||
@ -333,7 +318,6 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
|
||||
console.log('update highlight: ', highlight)
|
||||
}}
|
||||
onOpenChange={() => {
|
||||
mutate()
|
||||
setLabelsTarget(undefined)
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { Box } from '../../elements/LayoutPrimitives'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { nanoid } from 'nanoid'
|
||||
@ -36,8 +36,9 @@ export default function PdfArticleContainer(
|
||||
const containerRef = useRef<HTMLDivElement | null>(null)
|
||||
const [notebookKey, setNotebookKey] = useState<string>(uuidv4())
|
||||
const [noteTarget, setNoteTarget] = useState<Highlight | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] =
|
||||
useState<number | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined)
|
||||
const highlightsRef = useRef<Highlight[]>([])
|
||||
|
||||
const annotationOmnivoreId = (annotation: Annotation): string | undefined => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { Button } from '../../elements/Button'
|
||||
import { HStack } from '../../elements/LayoutPrimitives'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import dayjs, { Dayjs } from 'dayjs'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { updatePageMutation } from '../../../lib/networking/mutations/updatePageMutation'
|
||||
import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery'
|
||||
import { ArticleAttributes } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { LibraryItem } from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers'
|
||||
import { CloseButton } from '../../elements/CloseButton'
|
||||
|
||||
@ -18,7 +18,10 @@ import {
|
||||
LibraryItemNode,
|
||||
LibraryItems,
|
||||
LibraryItemsQueryInput,
|
||||
useArchiveItem,
|
||||
useDeleteItem,
|
||||
useGetLibraryItems,
|
||||
useUpdateItemReadStatus,
|
||||
} from '../../../lib/networking/library_items/useLibraryItems'
|
||||
import {
|
||||
useGetViewerQuery,
|
||||
@ -110,6 +113,10 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
|
||||
const [linkToEdit, setLinkToEdit] = useState<LibraryItem>()
|
||||
const [linkToUnsubscribe, setLinkToUnsubscribe] = useState<LibraryItem>()
|
||||
|
||||
const archiveItem = useArchiveItem()
|
||||
const deleteItem = useDeleteItem()
|
||||
const updateItemReadStatus = useUpdateItemReadStatus()
|
||||
|
||||
const [queryInputs, setQueryInputs] =
|
||||
useState<LibraryItemsQueryInput>(defaultQuery)
|
||||
|
||||
@ -121,19 +128,6 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
|
||||
error: fetchItemsError,
|
||||
} = useGetLibraryItems(props.folder, queryInputs)
|
||||
|
||||
// useEffect(() => {
|
||||
// const handleRevalidate = () => {
|
||||
// ;(async () => {
|
||||
// console.log('revalidating library')
|
||||
// await mutate()
|
||||
// })()
|
||||
// }
|
||||
// document.addEventListener('revalidateLibrary', handleRevalidate)
|
||||
// return () => {
|
||||
// document.removeEventListener('revalidateLibrary', handleRevalidate)
|
||||
// }
|
||||
// }, [mutate])
|
||||
|
||||
useEffect(() => {
|
||||
if (queryValue.startsWith('#')) {
|
||||
debouncedFetchSearchResults(
|
||||
@ -167,13 +161,6 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
|
||||
window.localStorage.setItem('nav-return', router.asPath)
|
||||
}, [router.asPath])
|
||||
|
||||
// const hasMore = useMemo(() => {
|
||||
// if (!itemsPages) {
|
||||
// return false
|
||||
// }
|
||||
// return itemsPages[itemsPages.length - 1].search.pageInfo.hasNextPage
|
||||
// }, [itemsPages])
|
||||
|
||||
const libraryItems = useMemo(() => {
|
||||
const items =
|
||||
itemsPages?.pages
|
||||
@ -387,64 +374,98 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
|
||||
return
|
||||
}
|
||||
|
||||
// switch (action) {
|
||||
// case 'showDetail':
|
||||
// const username = viewerData?.me?.profile.username
|
||||
// if (username) {
|
||||
// setActiveCardId(item.node.id)
|
||||
// if (item.node.state === State.PROCESSING) {
|
||||
// router.push(`/article?url=${encodeURIComponent(item.node.url)}`)
|
||||
// } else {
|
||||
// const dl =
|
||||
// item.node.pageType === PageType.HIGHLIGHTS
|
||||
// ? `#${item.node.id}`
|
||||
// : ''
|
||||
// router.push(`/${username}/${item.node.slug}` + dl)
|
||||
// }
|
||||
// }
|
||||
// break
|
||||
// case 'showOriginal':
|
||||
// const url = item.node.originalArticleUrl
|
||||
// if (url) {
|
||||
// window.open(url, '_blank')
|
||||
// }
|
||||
// break
|
||||
// case 'archive':
|
||||
// performActionOnItem('archive', item)
|
||||
// break
|
||||
// case 'unarchive':
|
||||
// performActionOnItem('unarchive', item)
|
||||
// break
|
||||
// case 'delete':
|
||||
// performActionOnItem('delete', item)
|
||||
// break
|
||||
// case 'restore':
|
||||
// performActionOnItem('restore', item)
|
||||
// break
|
||||
// case 'mark-read':
|
||||
// performActionOnItem('mark-read', item)
|
||||
// break
|
||||
// case 'mark-unread':
|
||||
// performActionOnItem('mark-unread', item)
|
||||
// break
|
||||
// case 'set-labels':
|
||||
// setLabelsTarget(item)
|
||||
// break
|
||||
// case 'open-notebook':
|
||||
// if (!notebookTarget) {
|
||||
// setNotebookTarget(item)
|
||||
// } else {
|
||||
// setNotebookTarget(undefined)
|
||||
// }
|
||||
// break
|
||||
// case 'unsubscribe':
|
||||
// performActionOnItem('unsubscribe', item)
|
||||
// case 'update-item':
|
||||
// performActionOnItem('update-item', item)
|
||||
// break
|
||||
// default:
|
||||
// console.warn('unknown action: ', action)
|
||||
// }
|
||||
switch (action) {
|
||||
case 'showDetail':
|
||||
const username = viewerData?.me?.profile.username
|
||||
if (username) {
|
||||
setActiveCardId(item.node.id)
|
||||
if (item.node.state === State.PROCESSING) {
|
||||
router.push(`/article?url=${encodeURIComponent(item.node.url)}`)
|
||||
} else {
|
||||
router.push(`/${username}/${item.node.slug}`)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'showOriginal':
|
||||
const url = item.node.originalArticleUrl
|
||||
if (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
break
|
||||
case 'archive':
|
||||
case 'unarchive':
|
||||
try {
|
||||
await archiveItem.mutateAsync({
|
||||
linkId: item.node.id,
|
||||
archived: action == 'archive',
|
||||
})
|
||||
} catch {
|
||||
showErrorToast(`Error ${action}ing item`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
return
|
||||
}
|
||||
showSuccessToast(`Item ${action}d`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
break
|
||||
case 'delete':
|
||||
try {
|
||||
await deleteItem.mutateAsync(item.node.id)
|
||||
} catch {
|
||||
showErrorToast(`Error deleting item`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
return
|
||||
}
|
||||
showSuccessToast(`Item deleted`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
break
|
||||
case 'mark-read':
|
||||
case 'mark-unread':
|
||||
const desc = action == 'mark-read' ? 'read' : 'unread'
|
||||
const values =
|
||||
action == 'mark-read'
|
||||
? {
|
||||
readingProgressPercent: 100,
|
||||
readingProgressTopPercent: 100,
|
||||
readingProgressAnchorIndex: 0,
|
||||
}
|
||||
: {
|
||||
readingProgressPercent: 0,
|
||||
readingProgressTopPercent: 0,
|
||||
readingProgressAnchorIndex: 0,
|
||||
}
|
||||
try {
|
||||
await updateItemReadStatus.mutateAsync({
|
||||
id: item.node.id,
|
||||
force: true,
|
||||
...values,
|
||||
})
|
||||
} catch {
|
||||
showErrorToast(`Error marking as ${desc}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'set-labels':
|
||||
setLabelsTarget(item)
|
||||
break
|
||||
case 'open-notebook':
|
||||
if (!notebookTarget) {
|
||||
setNotebookTarget(item)
|
||||
} else {
|
||||
setNotebookTarget(undefined)
|
||||
}
|
||||
break
|
||||
case 'unsubscribe':
|
||||
setLinkToUnsubscribe(item.node)
|
||||
break
|
||||
default:
|
||||
console.warn('unknown action: ', action)
|
||||
}
|
||||
}
|
||||
|
||||
const modalTargetItem = useMemo(() => {
|
||||
@ -1187,9 +1208,6 @@ export function LibraryItemsLayout(
|
||||
</VStack>
|
||||
{props.showEditTitleModal && (
|
||||
<EditLibraryItemModal
|
||||
updateItem={(item: LibraryItem) =>
|
||||
props.actionHandler('update-item', item)
|
||||
}
|
||||
onOpenChange={() => {
|
||||
props.setShowEditTitleModal(false)
|
||||
props.setLinkToEdit(undefined)
|
||||
|
||||
Reference in New Issue
Block a user