diff --git a/lib/reducers/db-ops-reducer.test.js b/lib/reducers/db-ops-reducer.test.js --- a/lib/reducers/db-ops-reducer.test.js +++ b/lib/reducers/db-ops-reducer.test.js @@ -13,6 +13,7 @@ keyserverStoreOperations: [], communityStoreOperations: [], integrityStoreOperations: [], + syncedMetadataStoreOperations: [], }; describe('DB ops reducer', () => { diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -20,6 +20,7 @@ import policiesReducer from './policies-reducer.js'; import reduceReportStore from './report-store-reducer.js'; import reduceServicesAccessToken from './services-access-token-reducer.js'; +import { reduceSyncedMetadataStore } from './synced-metadata-reducer.js'; import reduceGlobalThemeInfo from './theme-reducer.js'; import { reduceThreadActivity } from './thread-activity-reducer.js'; import { reduceThreadInfos } from './thread-reducer.js'; @@ -172,6 +173,9 @@ threadStoreOperations, ); + const { syncedMetadataStore, syncedMetadataStoreOperations } = + reduceSyncedMetadataStore(state.syncedMetadataStore, action); + return { state: { ...state, @@ -213,6 +217,7 @@ customServer: reduceCustomerServer(state.customServer, action), communityStore, dbOpsStore: reduceDBOpsStore(state.dbOpsStore, action), + syncedMetadataStore, }, storeOperations: { draftStoreOperations, @@ -223,6 +228,7 @@ keyserverStoreOperations, communityStoreOperations, integrityStoreOperations, + syncedMetadataStoreOperations, }, }; } diff --git a/lib/reducers/message-reducer.test.js b/lib/reducers/message-reducer.test.js --- a/lib/reducers/message-reducer.test.js +++ b/lib/reducers/message-reducer.test.js @@ -294,6 +294,7 @@ keyserverInfos: {}, communityInfos: {}, threadHashes: {}, + syncedMetadata: {}, }, }, { diff --git a/lib/reducers/synced-metadata-reducer.js b/lib/reducers/synced-metadata-reducer.js new file mode 100644 --- /dev/null +++ b/lib/reducers/synced-metadata-reducer.js @@ -0,0 +1,76 @@ +// @flow + +import { setClientDBStoreActionType } from '../actions/client-db-store-actions.js'; +import { + addSyncedMetadataEntryActionType, + removeSyncedMetadataEntryActionType, +} from '../actions/synced-metadata-actions.js'; +import { + syncedMetadataStoreOpsHandlers, + type SyncedMetadataStoreOperation, + type ReplaceSyncedMetadataEntryOperation, + type RemoveSyncedMetadataOperation, +} from '../ops/synced-metadata-store-ops.js'; +import type { BaseAction } from '../types/redux-types.js'; +import type { SyncedMetadataStore } from '../types/synced-metadata-types.js'; + +const { processStoreOperations: processStoreOps } = + syncedMetadataStoreOpsHandlers; + +function reduceSyncedMetadataStore( + state: SyncedMetadataStore, + action: BaseAction, +): { + +syncedMetadataStore: SyncedMetadataStore, + +syncedMetadataStoreOperations: $ReadOnlyArray, +} { + if (action.type === addSyncedMetadataEntryActionType) { + const replaceOperation: ReplaceSyncedMetadataEntryOperation = { + type: 'replace_synced_metadata_entry', + payload: action.payload, + }; + + return { + syncedMetadataStore: processStoreOps(state, [replaceOperation]), + syncedMetadataStoreOperations: [replaceOperation], + }; + } else if (action.type === removeSyncedMetadataEntryActionType) { + const removeOperation: RemoveSyncedMetadataOperation = { + type: 'remove_synced_metadata', + payload: { + names: [action.payload.name], + }, + }; + + return { + syncedMetadataStore: processStoreOps(state, [removeOperation]), + syncedMetadataStoreOperations: [removeOperation], + }; + } else if (action.type === setClientDBStoreActionType) { + const newSyncedMetadata = action.payload.syncedMetadata; + + if (!newSyncedMetadata) { + return { + syncedMetadataStore: state, + syncedMetadataStoreOperations: [], + }; + } + + const newSyncedMetadataStore: SyncedMetadataStore = { + ...state, + syncedMetadata: newSyncedMetadata, + }; + + return { + syncedMetadataStore: newSyncedMetadataStore, + syncedMetadataStoreOperations: [], + }; + } + + return { + syncedMetadataStore: state, + syncedMetadataStoreOperations: [], + }; +} + +export { reduceSyncedMetadataStore }; diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -109,6 +109,7 @@ import { type ClientStore } from './store-ops-types.js'; import type { SubscriptionUpdateResult } from './subscription-types.js'; import type { + SyncedMetadataStore, AddSyncedMetadataEntryPayload, RemoveSyncedMetadataEntryPayload, } from './synced-metadata-types.js'; @@ -162,6 +163,7 @@ +customServer: ?string, +communityStore: CommunityStore, +dbOpsStore: DBOpsStore, + +syncedMetadataStore: SyncedMetadataStore, ... }; diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js --- a/lib/types/store-ops-types.js +++ b/lib/types/store-ops-types.js @@ -13,6 +13,7 @@ ClientDBThreadMessageInfo, } from './message-types.js'; import type { ClientReportCreationRequest } from './report-types.js'; +import type { SyncedMetadata } from './synced-metadata-types.js'; import type { ClientDBThreadInfo, ThreadStore } from './thread-types.js'; import type { UserInfos } from './user-types.js'; import type { @@ -61,6 +62,7 @@ +keyserverStoreOperations: $ReadOnlyArray, +communityStoreOperations: $ReadOnlyArray, +integrityStoreOperations: $ReadOnlyArray, + +syncedMetadataStoreOperations: $ReadOnlyArray, }; export type ClientDBStoreOperations = { @@ -98,4 +100,5 @@ +keyserverInfos: ?KeyserverInfos, +communityInfos: ?CommunityInfos, +threadHashes: ?ThreadHashes, + +syncedMetadata: ?SyncedMetadata, }; diff --git a/lib/utils/reducers-utils.test.js b/lib/utils/reducers-utils.test.js --- a/lib/utils/reducers-utils.test.js +++ b/lib/utils/reducers-utils.test.js @@ -87,6 +87,9 @@ dbOpsStore: { queuedOps: [], }, + syncedMetadataStore: { + syncedMetadata: {}, + }, }; state = { ...defaultState, diff --git a/native/redux/default-state.js b/native/redux/default-state.js --- a/native/redux/default-state.js +++ b/native/redux/default-state.js @@ -87,6 +87,9 @@ dbOpsStore: { queuedOps: [], }, + syncedMetadataStore: { + syncedMetadata: {}, + }, }: AppState); export { defaultState }; diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -137,6 +137,7 @@ 'threadStore', 'storeLoaded', 'dbOpsStore', + 'syncedMetadataStore', ]; function handleReduxMigrationFailure(oldState: AppState): AppState { diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js --- a/native/redux/redux-setup.js +++ b/native/redux/redux-setup.js @@ -300,6 +300,7 @@ keyserverStoreOperations, communityStoreOperations, integrityStoreOperations, + syncedMetadataStoreOperations, } = storeOperations; const fixUnreadActiveThreadResult = fixUnreadActiveThread(state, action); @@ -319,6 +320,7 @@ keyserverStoreOperations, communityStoreOperations, integrityStoreOperations, + syncedMetadataStoreOperations, }; state = { ...state, diff --git a/native/redux/redux-utils.js b/native/redux/redux-utils.js --- a/native/redux/redux-utils.js +++ b/native/redux/redux-utils.js @@ -10,6 +10,7 @@ } from 'lib/ops/keyserver-store-ops.js'; import { messageStoreOpsHandlers } from 'lib/ops/message-store-ops.js'; import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js'; +import { syncedMetadataStoreOpsHandlers } from 'lib/ops/synced-metadata-store-ops.js'; import { threadStoreOpsHandlers } from 'lib/ops/thread-store-ops.js'; import { userStoreOpsHandlers } from 'lib/ops/user-store-ops.js'; import type { StoreOperations } from 'lib/types/store-ops-types.js'; @@ -37,6 +38,7 @@ keyserverStoreOperations, integrityStoreOperations, communityStoreOperations, + syncedMetadataStoreOperations, } = storeOperations; const convertedThreadStoreOperations = @@ -51,6 +53,10 @@ keyserverStoreOpsHandlers.convertOpsToClientDBOps(keyserverStoreOperations); const convertedCommunityStoreOperations = communityStoreOpsHandlers.convertOpsToClientDBOps(communityStoreOperations); + const convertedSyncedMetadataStoreOperations = + syncedMetadataStoreOpsHandlers.convertOpsToClientDBOps( + syncedMetadataStoreOperations, + ); const keyserversToRemoveFromNotifsStore = getKeyserversToRemoveFromNotifsStore(keyserverStoreOperations); const convertedIntegrityStoreOperations = @@ -117,6 +123,13 @@ ), ); } + if (convertedSyncedMetadataStoreOperations.length > 0) { + promises.push( + commCoreModule.processSyncedMetadataStoreOperations( + convertedSyncedMetadataStoreOperations, + ), + ); + } await Promise.all(promises); } catch (e) { if (isTaskCancelledError(e)) { diff --git a/native/redux/state-types.js b/native/redux/state-types.js --- a/native/redux/state-types.js +++ b/native/redux/state-types.js @@ -17,6 +17,7 @@ import type { MessageStore } from 'lib/types/message-types.js'; import type { UserPolicies } from 'lib/types/policy-types.js'; import type { ReportStore } from 'lib/types/report-types.js'; +import type { SyncedMetadataStore } from 'lib/types/synced-metadata-types.js'; import type { GlobalThemeInfo } from 'lib/types/theme-types.js'; import type { ThreadActivityStore } from 'lib/types/thread-activity-types'; import type { ThreadStore } from 'lib/types/thread-types.js'; @@ -79,6 +80,7 @@ +integrityStore: IntegrityStore, +communityStore: CommunityStore, +dbOpsStore: DBOpsStore, + +syncedMetadataStore: SyncedMetadataStore, }; export { nonUserSpecificFieldsNative }; diff --git a/web/redux/default-state.js b/web/redux/default-state.js --- a/web/redux/default-state.js +++ b/web/redux/default-state.js @@ -83,6 +83,9 @@ dbOpsStore: { queuedOps: [], }, + syncedMetadataStore: { + syncedMetadata: {}, + }, }); export { defaultWebState }; diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js --- a/web/redux/initial-state-gate.js +++ b/web/redux/initial-state-gate.js @@ -126,6 +126,7 @@ keyserverStoreOperations: [], communityStoreOperations: [], integrityStoreOperations: [], + syncedMetadataStoreOperations: [], }, currentLoggedInUserID, ); diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js --- a/web/redux/redux-setup.js +++ b/web/redux/redux-setup.js @@ -47,6 +47,7 @@ import type { BaseAction } from 'lib/types/redux-types.js'; import type { ReportStore } from 'lib/types/report-types.js'; import type { StoreOperations } from 'lib/types/store-ops-types.js'; +import type { SyncedMetadataStore } from 'lib/types/synced-metadata-types.js'; import type { GlobalThemeInfo } from 'lib/types/theme-types.js'; import type { ThreadActivityStore } from 'lib/types/thread-activity-types'; import type { ThreadStore } from 'lib/types/thread-types.js'; @@ -122,6 +123,7 @@ +customServer: ?string, +communityStore: CommunityStore, +dbOpsStore: DBOpsStore, + +syncedMetadataStore: SyncedMetadataStore, }; export type Action = $ReadOnly< @@ -154,6 +156,7 @@ keyserverStoreOperations: [], communityStoreOperations: [], integrityStoreOperations: [], + syncedMetadataStoreOperations: [], }; if ( diff --git a/web/shared-worker/utils/store.js b/web/shared-worker/utils/store.js --- a/web/shared-worker/utils/store.js +++ b/web/shared-worker/utils/store.js @@ -4,6 +4,7 @@ import { integrityStoreOpsHandlers } from 'lib/ops/integrity-store-ops.js'; import { keyserverStoreOpsHandlers } from 'lib/ops/keyserver-store-ops.js'; import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js'; +import { syncedMetadataStoreOpsHandlers } from 'lib/ops/synced-metadata-store-ops.js'; import { threadStoreOpsHandlers } from 'lib/ops/thread-store-ops.js'; import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js'; import type { @@ -28,6 +29,7 @@ keyserverInfos: defaultWebState.keyserverStore.keyserverInfos, communityInfos: null, threadHashes: null, + syncedMetadata: null, }; const data = await sharedWorker.schedule({ type: workerRequestMessageTypes.GET_CLIENT_STORE, @@ -92,6 +94,7 @@ keyserverStoreOperations, communityStoreOperations, integrityStoreOperations, + syncedMetadataStoreOperations, } = storeOperations; const canUseDatabase = canUseDatabaseOnWeb(userID); @@ -107,6 +110,10 @@ communityStoreOpsHandlers.convertOpsToClientDBOps(communityStoreOperations); const convertedIntegrityStoreOperations = integrityStoreOpsHandlers.convertOpsToClientDBOps(integrityStoreOperations); + const convertedSyncedMetadataStoreOperations = + syncedMetadataStoreOpsHandlers.convertOpsToClientDBOps( + syncedMetadataStoreOperations, + ); if ( convertedThreadStoreOperations.length === 0 && @@ -114,7 +121,8 @@ draftStoreOperations.length === 0 && convertedKeyserverStoreOperations.length === 0 && convertedCommunityStoreOperations.length === 0 && - convertedIntegrityStoreOperations.length === 0 + convertedIntegrityStoreOperations.length === 0 && + convertedSyncedMetadataStoreOperations.length === 0 ) { return; } @@ -134,6 +142,7 @@ keyserverStoreOperations: convertedKeyserverStoreOperations, communityStoreOperations: convertedCommunityStoreOperations, integrityStoreOperations: convertedIntegrityStoreOperations, + syncedMetadataStoreOperations: convertedSyncedMetadataStoreOperations, }, }); } catch (e) {