From 984b29c09811a2ea5207fbbf327eb6858bfa3390 Mon Sep 17 00:00:00 2001 From: Wolfgang Date: Fri, 25 Oct 2024 00:28:49 +0200 Subject: [PATCH] fix: counter not always synced with backend * read newestItemId when possible from api responses and fetch feed data when it differs * fetch feed data if the fetched item ids are higher then newestItemId * optimize FETCH and SET functions so that it can be used for future features like manual or timed refresh Signed-off-by: Wolfgang --- CHANGELOG.md | 1 + .../feed-display/FeedItemDisplayList.vue | 12 +++++ src/store/feed.ts | 13 +++--- src/store/folder.ts | 14 +++--- src/store/item.ts | 44 ++++++++++++++++++- src/types/MutationTypes.ts | 1 + 6 files changed, 72 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7eaefb17..f0f479ea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ You can also check [on GitHub](https://github.com/nextcloud/news/releases), the ### Changed ### Fixed +- Unread Counter becomes negative (#2839) # Releases ## [25.0.0-alpha12] - 2024-10-23 diff --git a/src/components/feed-display/FeedItemDisplayList.vue b/src/components/feed-display/FeedItemDisplayList.vue index b21fd374c..df3e97f0e 100644 --- a/src/components/feed-display/FeedItemDisplayList.vue +++ b/src/components/feed-display/FeedItemDisplayList.vue @@ -83,6 +83,7 @@ import FeedItemRow from './FeedItemRow.vue' import { FeedItem } from '../../types/FeedItem' import { FEED_ORDER } from '../../dataservices/feed.service' +import { ACTIONS } from '../../store' const DEFAULT_DISPLAY_LIST_CONFIG = { starFilter: true, @@ -166,8 +167,19 @@ export default Vue.extend({ getSelectedItem() { return this.$store.getters.selected }, + getNewestItemId() { + return this.$store.state.items.newestItemId + }, + isLoading() { + return this.$store.getters.loading + }, }, watch: { + async getNewestItemId() { + if (!this.isLoading) { + await this.$store.dispatch(ACTIONS.FETCH_FEEDS) + } + }, getSelectedItem(newVal) { this.selectedItem = newVal }, diff --git a/src/store/feed.ts b/src/store/feed.ts index 8b5ed0a17..ff98aba03 100644 --- a/src/store/feed.ts +++ b/src/store/feed.ts @@ -42,10 +42,13 @@ const getters = { export const actions = { async [FEED_ACTION_TYPES.FETCH_FEEDS]({ commit }: ActionParams) { - const feeds = await FeedService.fetchAllFeeds() + const response = await FeedService.fetchAllFeeds() + if (response.data.newestItemId) { + commit(FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID, response.data.newestItemId) + } - commit(FEED_MUTATION_TYPES.SET_FEEDS, feeds.data.feeds) - commit(FEED_ITEM_MUTATION_TYPES.SET_UNREAD_COUNT, (feeds.data.feeds.reduce((total: number, feed: Feed) => { + commit(FEED_MUTATION_TYPES.SET_FEEDS, response.data.feeds) + commit(FEED_ITEM_MUTATION_TYPES.SET_UNREAD_COUNT, (response.data.feeds.reduce((total: number, feed: Feed) => { return total + feed.unreadCount }, 0))) }, @@ -203,9 +206,7 @@ export const mutations = { state: FeedState, feeds: Feed[], ) { - feeds.forEach(it => { - state.feeds.push(it) - }) + state.feeds = [...feeds] }, [FEED_MUTATION_TYPES.ADD_FEED]( diff --git a/src/store/folder.ts b/src/store/folder.ts index 16941a6bb..882f1a62a 100644 --- a/src/store/folder.ts +++ b/src/store/folder.ts @@ -69,11 +69,7 @@ export const mutations = { state: FolderState, folders: Folder[], ) { - folders.forEach(it => { - it.feedCount = 0 - it.feeds = [] - state.folders.push(it) - }) + state.folders = [...folders] }, [FOLDER_MUTATION_TYPES.DELETE_FOLDER]( @@ -88,13 +84,19 @@ export const mutations = { state: FolderState, feeds: Feed[], ) { + const updatedFolders = state.folders.map(folder => ({ + ...folder, + feeds: [] as Feed[], + feedCount: 0, + })) feeds.forEach(it => { - const folder = state.folders.find((folder: Folder) => { return folder.id === it.folderId }) + const folder = updatedFolders.find((folder: Folder) => { return folder.id === it.folderId }) if (folder) { folder.feeds.push(it) folder.feedCount += it.unreadCount } }) + state.folders = updatedFolders }, [FEED_MUTATION_TYPES.ADD_FEED]( diff --git a/src/store/item.ts b/src/store/item.ts index b36e96b65..0961dabbc 100644 --- a/src/store/item.ts +++ b/src/store/item.ts @@ -23,6 +23,7 @@ export type ItemState = { fetchingItems: { [key: string]: boolean }; allItemsLoaded: { [key: string]: boolean }; lastItemLoaded: { [key: string]: number }; + newestItemId: number; starredCount: number; unreadCount: number; @@ -37,6 +38,7 @@ const state: ItemState = { fetchingItems: {}, allItemsLoaded: {}, lastItemLoaded: {}, + newestItemId: 0, starredCount: 0, unreadCount: 0, @@ -60,6 +62,9 @@ const getters = { allItems(state: ItemState) { return state.allItems }, + newestItemId(state: ItemState) { + return state.newestItemId + }, } export const actions = { @@ -78,6 +83,9 @@ export const actions = { commit(FEED_ITEM_MUTATION_TYPES.SET_FETCHING, { key: 'unread', fetching: true }) const response = await ItemService.debounceFetchUnread(start || state.lastItemLoaded.unread) + if (response?.data.newestItemId) { + commit(FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID, response.data.newestItemId) + } commit(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, response?.data.items) @@ -107,6 +115,9 @@ export const actions = { commit(FEED_ITEM_MUTATION_TYPES.SET_FETCHING, { key: 'all', fetching: true }) const response = await ItemService.debounceFetchAll(start || state.lastItemLoaded.all) + if (response?.data.newestItemId) { + commit(FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID, response.data.newestItemId) + } commit(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, response?.data.items) @@ -136,6 +147,10 @@ export const actions = { commit(FEED_ITEM_MUTATION_TYPES.SET_FETCHING, { key: 'starred', fetching: true }) const response = await ItemService.debounceFetchStarred(start || state.lastItemLoaded.starred) + if (response?.data.newestItemId) { + state.newestItemId = response?.data.newestItemId + } + commit(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, response?.data.items) if (response?.data.starred) { commit(FEED_ITEM_MUTATION_TYPES.SET_STARRED_COUNT, response?.data.starred) @@ -167,6 +182,9 @@ export const actions = { ) { commit(FEED_ITEM_MUTATION_TYPES.SET_FETCHING, { key: 'feed-' + feedId, fetching: true }) const response = await ItemService.debounceFetchFeedItems(feedId, start || state.lastItemLoaded['feed-' + feedId], ordering) + if (response?.data.newestItemId) { + commit(FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID, response.data.newestItemId) + } commit(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, response?.data.items) if (response?.data.items.length < 40) { commit(FEED_ITEM_MUTATION_TYPES.SET_ALL_LOADED, { key: 'feed-' + feedId, loaded: true }) @@ -193,6 +211,9 @@ export const actions = { ) { commit(FEED_ITEM_MUTATION_TYPES.SET_FETCHING, { key: 'folder-' + folderId, fetching: true }) const response = await ItemService.debounceFetchFolderFeedItems(folderId, start || state.lastItemLoaded['folder-' + folderId]) + if (response?.data.newestItemId) { + commit(FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID, response.data.newestItemId) + } commit(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, response?.data.items) if (response?.data.items.length < 40) { @@ -331,11 +352,25 @@ export const mutations = { items: FeedItem[], ) { if (items) { + let newestFetchedItemId = 0 + const newItems: FeedItem[] = [] + items.forEach(it => { if (state.allItems.find((existing: FeedItem) => existing.id === it.id) === undefined) { - state.allItems.push(it) + newItems.push(it) + if (state.newestItemId < Number(it.id)) { + newestFetchedItemId = Number(it.id) + } } }) + + if (newItems.length > 0) { + state.allItems = [...state.allItems, ...newItems] + } + + if (newestFetchedItemId > state.newestItemId) { + state.newestItemId = newestFetchedItemId + } } }, @@ -389,6 +424,13 @@ export const mutations = { state.lastItemLoaded[key] = lastItem }, + [FEED_ITEM_MUTATION_TYPES.SET_NEWEST_ITEM_ID]( + state: ItemState, + newestItemId: number, + ) { + state.newestItemId = newestItemId + }, + [FEED_MUTATION_TYPES.SET_FEED_ALL_READ]( state: ItemState, feed: Feed, diff --git a/src/types/MutationTypes.ts b/src/types/MutationTypes.ts index 323a0a7a7..17e7ad04a 100644 --- a/src/types/MutationTypes.ts +++ b/src/types/MutationTypes.ts @@ -32,6 +32,7 @@ export const FEED_ITEM_MUTATION_TYPES = { SET_FETCHING: 'SET_FETCHING', SET_ALL_LOADED: 'SET_ALL_LOADED', SET_LAST_ITEM_LOADED: 'SET_LAST_ITEM_LOADED', + SET_NEWEST_ITEM_ID: 'SET_NEWEST_ITEM_ID', } export const APPLICATION_MUTATION_TYPES = {