diff --git a/lib/keyserver-conn/keyserver-call-utils.js b/lib/keyserver-conn/keyserver-call-utils.js --- a/lib/keyserver-conn/keyserver-call-utils.js +++ b/lib/keyserver-conn/keyserver-call-utils.js @@ -86,8 +86,22 @@ return results; } +function getThreadIDsForKeyservers( + threadIDs: $ReadOnlyArray, + keyserverIDs: $ReadOnlyArray, +): $ReadOnlyArray { + if (keyserverIDs.length === 0) { + return []; + } + const keyserverIDsSet = new Set(keyserverIDs); + return threadIDs.filter(threadID => + keyserverIDsSet.has(extractKeyserverIDFromID(threadID)), + ); +} + export { extractKeyserverIDFromID, sortThreadIDsPerKeyserver, sortCalendarQueryPerKeyserver, + getThreadIDsForKeyservers, }; diff --git a/lib/keyserver-conn/keyserver-call-utils.test.js b/lib/keyserver-conn/keyserver-call-utils.test.js --- a/lib/keyserver-conn/keyserver-call-utils.test.js +++ b/lib/keyserver-conn/keyserver-call-utils.test.js @@ -3,6 +3,7 @@ import { extractKeyserverIDFromID, sortCalendarQueryPerKeyserver, + getThreadIDsForKeyservers, } from './keyserver-call-utils.js'; import type { CalendarQuery } from '../types/entry-types'; @@ -86,3 +87,37 @@ ); }); }); + +const keyserver1 = '256'; +const keyserver2 = '100'; +const keyserver3 = '200'; +const keyserver1ThreadIDs = [ + keyserver1 + '|1', + keyserver1 + '|2', + keyserver1 + '|3', +]; +const keyserver2ThreadIDs = [ + keyserver2 + '|1', + keyserver2 + '|2', + keyserver2 + '|3', +]; +const keyserver3ThreadIDs = [ + keyserver3 + '|1', + keyserver3 + '|2', + keyserver3 + '|3', +]; + +describe('getThreadIDsForKeyservers', () => { + it('should return thread belonging to specified keyservers', () => { + expect( + getThreadIDsForKeyservers( + [ + ...keyserver1ThreadIDs, + ...keyserver2ThreadIDs, + ...keyserver3ThreadIDs, + ], + [keyserver1, keyserver2], + ), + ).toEqual([...keyserver1ThreadIDs, ...keyserver2ThreadIDs]); + }); +}); diff --git a/lib/reducers/thread-reducer.js b/lib/reducers/thread-reducer.js --- a/lib/reducers/thread-reducer.js +++ b/lib/reducers/thread-reducer.js @@ -19,12 +19,14 @@ deleteCommunityRoleActionTypes, } from '../actions/thread-actions.js'; import { + keyserverAuthActionTypes, logOutActionTypes, deleteKeyserverAccountActionTypes, logInActionTypes, keyserverRegisterActionTypes, updateSubscriptionActionTypes, } from '../actions/user-actions.js'; +import { getThreadIDsForKeyservers } from '../keyserver-conn/keyserver-call-utils.js'; import { setNewSessionActionType } from '../keyserver-conn/keyserver-conn-types.js'; import { type ThreadStoreOperation, @@ -106,12 +108,34 @@ newThreadInconsistencies: [], threadStoreOperations, }; - } else if ( - action.type === logOutActionTypes.success || - action.type === deleteKeyserverAccountActionTypes.success || - (action.type === setNewSessionActionType && - action.payload.sessionChange.cookieInvalidated) - ) { + } else if (action.type === keyserverAuthActionTypes.success) { + const keyserverIDs = Object.keys(action.payload.updatesCurrentAsOf); + const threadIDsToRemove = getThreadIDsForKeyservers( + Object.keys(state.threadInfos), + keyserverIDs, + ); + const newThreadInfos = action.payload.threadInfos; + + const threadStoreOperations = [ + { + type: 'remove', + payload: { ids: threadIDsToRemove }, + }, + ...Object.keys(newThreadInfos).map((id: string) => ({ + type: 'replace', + payload: { id, threadInfo: newThreadInfos[id] }, + })), + ]; + const updatedThreadStore = processThreadStoreOperations( + state, + threadStoreOperations, + ); + return { + threadStore: updatedThreadStore, + newThreadInconsistencies: [], + threadStoreOperations, + }; + } else if (action.type === logOutActionTypes.success) { if (Object.keys(state.threadInfos).length === 0) { return { threadStore: state, @@ -133,6 +157,67 @@ newThreadInconsistencies: [], threadStoreOperations, }; + } else if (action.type === deleteKeyserverAccountActionTypes.success) { + const threadIDsToRemove = getThreadIDsForKeyservers( + Object.keys(state.threadInfos), + action.payload.keyserverIDs, + ); + + if (threadIDsToRemove.length === 0) { + return { + threadStore: state, + newThreadInconsistencies: [], + threadStoreOperations: [], + }; + } + + const threadStoreOperations = [ + { + type: 'remove', + payload: { ids: threadIDsToRemove }, + }, + ]; + const updatedThreadStore = processThreadStoreOperations( + state, + threadStoreOperations, + ); + return { + threadStore: updatedThreadStore, + newThreadInconsistencies: [], + threadStoreOperations, + }; + } else if ( + action.type === setNewSessionActionType && + action.payload.sessionChange.cookieInvalidated + ) { + const threadIDsToRemove = getThreadIDsForKeyservers( + Object.keys(state.threadInfos), + [action.payload.keyserverID], + ); + + if (threadIDsToRemove.length === 0) { + return { + threadStore: state, + newThreadInconsistencies: [], + threadStoreOperations: [], + }; + } + + const threadStoreOperations = [ + { + type: 'remove', + payload: { ids: threadIDsToRemove }, + }, + ]; + const updatedThreadStore = processThreadStoreOperations( + state, + threadStoreOperations, + ); + return { + threadStore: updatedThreadStore, + newThreadInconsistencies: [], + threadStoreOperations, + }; } else if ( action.type === joinThreadActionTypes.success || action.type === leaveThreadActionTypes.success ||