diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 3bbc9a88d..da68dbe22 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -2092,6 +2092,7 @@ export enum SaveArticleReadingProgressErrorCode { } export type SaveArticleReadingProgressInput = { + force?: InputMaybe; id: Scalars['ID']; readingProgressAnchorIndex?: InputMaybe; readingProgressPercent: Scalars['Float']; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index e5192b308..dec3e34f6 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -1571,6 +1571,7 @@ enum SaveArticleReadingProgressErrorCode { } input SaveArticleReadingProgressInput { + force: Boolean id: ID! readingProgressAnchorIndex: Int readingProgressPercent: Float! diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 85a4bd4de..e9802667e 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -563,6 +563,7 @@ export const saveArticleReadingProgressResolver = authorized< readingProgressPercent, readingProgressAnchorIndex, readingProgressTopPercent, + force, }, }, { log, pubsub, uid } @@ -578,6 +579,27 @@ export const saveArticleReadingProgressResolver = authorized< return { errorCodes: [SaveArticleReadingProgressErrorCode.BadData] } } try { + if (force) { + // update reading progress without checking the current value + const updatedItem = await updateLibraryItem( + id, + { + readingProgressBottomPercent: readingProgressPercent, + readingProgressTopPercent: readingProgressTopPercent ?? undefined, + readingProgressHighestReadAnchor: + readingProgressAnchorIndex ?? undefined, + readAt: new Date(), + }, + uid, + pubsub + ) + + return { + updatedArticle: libraryItemToArticle(updatedItem), + } + } + + // update reading progress only if the current value is lower const updatedItem = await updateLibraryItemReadingProgress( id, uid, diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index de3f5209c..ff9d75664 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -637,6 +637,7 @@ const schema = gql` readingProgressTopPercent: Float readingProgressPercent: Float! readingProgressAnchorIndex: Int + force: Boolean } enum SaveArticleReadingProgressErrorCode { NOT_FOUND diff --git a/packages/api/test/resolvers/article.test.ts b/packages/api/test/resolvers/article.test.ts index 4f8a3c96e..6c1c51446 100644 --- a/packages/api/test/resolvers/article.test.ts +++ b/packages/api/test/resolvers/article.test.ts @@ -295,16 +295,18 @@ const setBookmarkQuery = (articleId: string, bookmark: boolean) => { const saveArticleReadingProgressQuery = ( articleId: string, progress: number, - topPercent: number | null = null + topPercent: number | null = null, + force: boolean | null = null ) => { return ` mutation { saveArticleReadingProgress( input: { id: "${articleId}", - readingProgressPercent: ${progress} - readingProgressAnchorIndex: 0 - readingProgressTopPercent: ${topPercent} + readingProgressPercent: ${progress}, + readingProgressAnchorIndex: 0, + readingProgressTopPercent: ${topPercent}, + force: ${force} } ) { ... on SaveArticleReadingProgressSuccess { @@ -784,6 +786,37 @@ describe('Article API', () => { 'BAD_DATA', ]) }) + + context('when force is true', () => { + before(async () => { + itemId = (await createLibraryItem({ + user: { id: user.id }, + originalUrl: 'https://blog.omnivore.app/setBookmarkArticle', + slug: 'test-with-omnivore', + readableContent: '

test

', + title: 'test title', + readingProgressBottomPercent: 100, + readingProgressTopPercent: 80, + }, user.id)).id + }) + + after(async () => { + await deleteLibraryItemById(itemId, user.id) + }) + + it('ignore position check if force is true', async () => { + query = saveArticleReadingProgressQuery(itemId, 20, 10, true) + const res = await graphqlRequest(query, authToken).expect(200) + expect( + res.body.data.saveArticleReadingProgress.updatedArticle + .readingProgressPercent + ).to.eql(20) + expect( + res.body.data.saveArticleReadingProgress.updatedArticle + .readingProgressTopPercent + ).to.eql(10) + }) + }) }) describe('SaveFile', () => {