mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Merge pull request #264 from omnivore-app/fix/elastic-update-conflict
Fix/elastic update conflict
This commit is contained in:
commit
efc9a30d1e
6 changed files with 75 additions and 37 deletions
|
|
@ -201,6 +201,7 @@ export const updatePage = async (
|
|||
},
|
||||
},
|
||||
refresh: ctx.refresh,
|
||||
retry_on_conflict: 3,
|
||||
})
|
||||
|
||||
if (body.result !== 'updated') return false
|
||||
|
|
@ -237,6 +238,7 @@ export const addLabelInPage = async (
|
|||
},
|
||||
},
|
||||
refresh: ctx.refresh,
|
||||
retry_on_conflict: 3,
|
||||
})
|
||||
|
||||
return body.result === 'updated'
|
||||
|
|
|
|||
|
|
@ -707,9 +707,9 @@ export const saveArticleReadingProgressResolver = authorized<
|
|||
{ input: { id, readingProgressPercent, readingProgressAnchorIndex } },
|
||||
{ claims: { uid }, pubsub }
|
||||
) => {
|
||||
const userArticleRecord = await getPageByParam({ userId: uid, _id: id })
|
||||
const page = await getPageByParam({ userId: uid, _id: id })
|
||||
|
||||
if (!userArticleRecord) {
|
||||
if (!page) {
|
||||
return { errorCodes: [SaveArticleReadingProgressErrorCode.NotFound] }
|
||||
}
|
||||
|
||||
|
|
@ -725,26 +725,25 @@ export const saveArticleReadingProgressResolver = authorized<
|
|||
// be greater than the current reading progress.
|
||||
const shouldUpdate =
|
||||
readingProgressPercent === 0 ||
|
||||
(userArticleRecord.readingProgressPercent || 0) <
|
||||
readingProgressPercent ||
|
||||
(userArticleRecord.readingProgressAnchorIndex || 0) <
|
||||
readingProgressAnchorIndex
|
||||
page.readingProgressPercent < readingProgressPercent ||
|
||||
page.readingProgressAnchorIndex < readingProgressAnchorIndex
|
||||
|
||||
const updatedArticle = Object.assign(userArticleRecord, {
|
||||
const updatedPart = {
|
||||
readingProgressPercent: shouldUpdate
|
||||
? readingProgressPercent
|
||||
: userArticleRecord.readingProgressPercent,
|
||||
: page.readingProgressPercent,
|
||||
readingProgressAnchorIndex: shouldUpdate
|
||||
? readingProgressAnchorIndex
|
||||
: userArticleRecord.readingProgressAnchorIndex,
|
||||
})
|
||||
: page.readingProgressAnchorIndex,
|
||||
}
|
||||
|
||||
shouldUpdate && (await updatePage(id, updatedArticle, { pubsub, uid }))
|
||||
shouldUpdate && (await updatePage(id, updatedPart, { pubsub, uid }))
|
||||
|
||||
return {
|
||||
updatedArticle: {
|
||||
...updatedArticle,
|
||||
isArchived: !!updatedArticle.archivedAt,
|
||||
...page,
|
||||
...updatedPart,
|
||||
isArchived: !!page.archivedAt,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
import { Box } from './../../../components/elements/LayoutPrimitives'
|
||||
import { Box } from '../../elements/LayoutPrimitives'
|
||||
import { useReadingProgressAnchor } from '../../../lib/hooks/useReadingProgressAnchor'
|
||||
import {
|
||||
useScrollWatcher,
|
||||
ScrollOffsetChangeset,
|
||||
useScrollWatcher,
|
||||
} from '../../../lib/hooks/useScrollWatcher'
|
||||
import {
|
||||
useRef,
|
||||
useState,
|
||||
useEffect,
|
||||
MutableRefObject,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { articleReadingProgressMutation } from '../../../lib/networking/mutations/articleReadingProgressMutation'
|
||||
import { Tweet } from 'react-twitter-widgets'
|
||||
import { render } from 'react-dom'
|
||||
import { isDarkTheme } from '../../../lib/themeUpdater'
|
||||
import useDebounce from '../../../lib/hooks/useDebounce'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
export type ArticleProps = {
|
||||
articleId: string
|
||||
|
|
@ -28,7 +29,9 @@ export type ArticleProps = {
|
|||
export function Article(props: ArticleProps): JSX.Element {
|
||||
const highlightTheme = isDarkTheme() ? 'dark' : 'default'
|
||||
|
||||
const [readingProgress, setReadingProgress] = useState(props.initialReadingProgress)
|
||||
const [readingProgress, setReadingProgress] = useState(
|
||||
props.initialReadingProgress
|
||||
)
|
||||
|
||||
const [readingAnchorIndex, setReadingAnchorIndex] = useState(
|
||||
props.initialAnchorIndex
|
||||
|
|
@ -41,14 +44,30 @@ export function Article(props: ArticleProps): JSX.Element {
|
|||
|
||||
useReadingProgressAnchor(articleContentRef, setReadingAnchorIndex)
|
||||
|
||||
const debouncedReadingProgress = useDebounce(readingProgress, 1000);
|
||||
const debouncedSetReadingProgress = useMemo(
|
||||
() =>
|
||||
debounce((readingProgress: number) => {
|
||||
console.log('setReadingProgress', readingProgress)
|
||||
setReadingProgress(readingProgress)
|
||||
}, 2000),
|
||||
[]
|
||||
)
|
||||
|
||||
// Stop the invocation of the debounced function
|
||||
// after unmounting
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
debouncedSetReadingProgress.cancel()
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
if (!debouncedReadingProgress) return
|
||||
if (!readingProgress) return
|
||||
await articleReadingProgressMutation({
|
||||
id: props.articleId,
|
||||
readingProgressPercent: debouncedReadingProgress,
|
||||
// round reading progress to 100% if more than that
|
||||
readingProgressPercent: readingProgress > 100 ? 100 : readingProgress,
|
||||
readingProgressAnchorIndex: readingAnchorIndex,
|
||||
})
|
||||
})()
|
||||
|
|
@ -56,20 +75,16 @@ export function Article(props: ArticleProps): JSX.Element {
|
|||
// We don't react to changes to readingAnchorIndex we
|
||||
// only care about the progress (scroll position) changed.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [
|
||||
props.articleId,
|
||||
debouncedReadingProgress,
|
||||
readingAnchorIndex,
|
||||
])
|
||||
}, [props.articleId, readingProgress])
|
||||
|
||||
// Post message to webkit so apple app embeds get progress updates
|
||||
useEffect(() => {
|
||||
if (typeof window?.webkit != 'undefined') {
|
||||
window.webkit.messageHandlers.readingProgressUpdate?.postMessage({
|
||||
progress: debouncedReadingProgress,
|
||||
progress: readingProgress,
|
||||
})
|
||||
}
|
||||
}, [readingProgress, debouncedReadingProgress])
|
||||
}, [readingProgress])
|
||||
|
||||
const setScrollWatchedElement = useScrollWatcher(
|
||||
(changeset: ScrollOffsetChangeset) => {
|
||||
|
|
@ -79,13 +94,13 @@ export function Article(props: ArticleProps): JSX.Element {
|
|||
(changeset.current.y + scrollContainer.clientHeight) /
|
||||
scrollContainer.scrollHeight
|
||||
|
||||
setReadingProgress(newReadingProgress * 100)
|
||||
debouncedSetReadingProgress(newReadingProgress * 100)
|
||||
} else if (window && window.document.scrollingElement) {
|
||||
const newReadingProgress =
|
||||
window.scrollY / window.document.scrollingElement.scrollHeight
|
||||
const adjustedReadingProgress =
|
||||
newReadingProgress > 0.92 ? 1 : newReadingProgress
|
||||
setReadingProgress(adjustedReadingProgress * 100)
|
||||
debouncedSetReadingProgress(adjustedReadingProgress * 100)
|
||||
}
|
||||
},
|
||||
1000
|
||||
|
|
@ -152,9 +167,15 @@ export function Article(props: ArticleProps): JSX.Element {
|
|||
}
|
||||
|
||||
if (props.scrollElementRef.current) {
|
||||
props.scrollElementRef.current?.scroll(0, calculateOffset(anchorElement))
|
||||
props.scrollElementRef.current?.scroll(
|
||||
0,
|
||||
calculateOffset(anchorElement)
|
||||
)
|
||||
} else {
|
||||
window.document.documentElement.scroll(0, calculateOffset(anchorElement))
|
||||
window.document.documentElement.scroll(
|
||||
0,
|
||||
calculateOffset(anchorElement)
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [
|
||||
|
|
|
|||
|
|
@ -206,9 +206,12 @@ export function HomeFeedContainer(props: HomeFeedContainerProps): JSX.Element {
|
|||
if (activeCardId && !alreadyScrolled.current) {
|
||||
scrollToActiveCard(activeCardId)
|
||||
alreadyScrolled.current = true
|
||||
}
|
||||
if (activeItem) {
|
||||
performActionOnItem('refresh', activeItem)
|
||||
|
||||
if (activeItem) {
|
||||
console.log('refreshing')
|
||||
// refresh items on home feed
|
||||
performActionOnItem('refresh', activeItem)
|
||||
}
|
||||
}
|
||||
}, [activeCardId, scrollToActiveCard])
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
"@types/cookie": "^0.4.1",
|
||||
"@types/diff-match-patch": "^1.0.32",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/react": "17.0.2",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/segment-analytics": "^0.0.34",
|
||||
|
|
|
|||
12
yarn.lock
12
yarn.lock
|
|
@ -5443,6 +5443,18 @@
|
|||
"@types/interpret" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash.debounce@^4.0.6":
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz#c5a2326cd3efc46566c47e4c0aa248dc0ee57d60"
|
||||
integrity sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
version "4.14.180"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.180.tgz#4ab7c9ddfc92ec4a887886483bc14c79fb380670"
|
||||
integrity sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==
|
||||
|
||||
"@types/long@^4.0.0", "@types/long@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
|
|
|
|||
Loading…
Reference in a new issue