diff --git a/app/actions/remote/terms_of_service.ts b/app/actions/remote/terms_of_service.ts index ff4072706..64cb865a0 100644 --- a/app/actions/remote/terms_of_service.ts +++ b/app/actions/remote/terms_of_service.ts @@ -1,7 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import DatabaseManager from '@database/manager'; import NetworkManager from '@managers/network_manager'; +import {getCurrentUser} from '@queries/servers/user'; import {forceLogoutIfNecessary} from './session'; @@ -25,15 +27,24 @@ export async function fetchTermsOfService(serverUrl: string): Promise<{terms?: T } export async function updateTermsOfServiceStatus(serverUrl: string, id: string, status: boolean): Promise<{resp?: {status: string}; error?: any}> { - let client; - try { - client = NetworkManager.getClient(serverUrl); - } catch (error) { - return {error}; - } - try { + const client = NetworkManager.getClient(serverUrl); const resp = await client.updateMyTermsOfServiceStatus(id, status); + + const {database, operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); + const currentUser = await getCurrentUser(database); + if (currentUser) { + currentUser.prepareUpdate((u) => { + if (status) { + u.termsOfServiceCreateAt = Date.now(); + u.termsOfServiceId = id; + } else { + u.termsOfServiceCreateAt = 0; + u.termsOfServiceId = ''; + } + }); + operator.batchRecords([currentUser]); + } return {resp}; } catch (error) { forceLogoutIfNecessary(serverUrl, error as ClientError); diff --git a/app/database/operator/server_data_operator/transformers/user.ts b/app/database/operator/server_data_operator/transformers/user.ts index 420abc34f..c98afae1c 100644 --- a/app/database/operator/server_data_operator/transformers/user.ts +++ b/app/database/operator/server_data_operator/transformers/user.ts @@ -42,8 +42,8 @@ export const transformUserRecord = ({action, database, value}: TransformerArgs): user.timezone = raw.timezone || null; user.isBot = raw.is_bot ?? false; user.remoteId = raw?.remote_id ?? null; - user.termsOfServiceId = raw?.terms_of_service_id ?? ''; - user.termsOfServiceCreateAt = raw?.terms_of_service_create_at ?? 0; + user.termsOfServiceId = raw?.terms_of_service_id ?? (record?.termsOfServiceId || ''); + user.termsOfServiceCreateAt = raw?.terms_of_service_create_at ?? (record?.termsOfServiceCreateAt || 0); if (raw.status) { user.status = raw.status; } diff --git a/app/queries/servers/terms_of_service.ts b/app/queries/servers/terms_of_service.ts new file mode 100644 index 000000000..820ad88a5 --- /dev/null +++ b/app/queries/servers/terms_of_service.ts @@ -0,0 +1,43 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Database} from '@nozbe/watermelondb'; +import {of as of$, combineLatest} from 'rxjs'; +import {switchMap, distinctUntilChanged} from 'rxjs/operators'; + +import {observeLicense, observeConfigBooleanValue, observeConfigValue, observeConfigIntValue} from './system'; +import {observeCurrentUser} from './user'; + +export const observeShowToS = (database: Database) => { + const isLicensed = observeLicense(database).pipe( + switchMap((lcs) => (lcs ? of$(lcs.IsLicensed === 'true') : of$(false))), + ); + const currentUser = observeCurrentUser(database); + const customTermsOfServiceEnabled = observeConfigBooleanValue(database, 'EnableCustomTermsOfService'); + const customTermsOfServiceId = observeConfigValue(database, 'CustomTermsOfServiceId'); + const customTermsOfServicePeriod = observeConfigIntValue(database, 'CustomTermsOfServiceReAcceptancePeriod'); + + const showToS = combineLatest([ + isLicensed, + customTermsOfServiceEnabled, + currentUser, + customTermsOfServiceId, + customTermsOfServicePeriod, + ]).pipe( + switchMap(([lcs, cfg, user, id, period]) => { + if (!lcs || !cfg) { + return of$(false); + } + + if (user?.termsOfServiceId !== id) { + return of$(true); + } + + const timeElapsed = Date.now() - (user?.termsOfServiceCreateAt || 0); + return of$(timeElapsed > (period * 24 * 60 * 60 * 1000)); + }), + distinctUntilChanged(), + ); + + return showToS; +}; diff --git a/app/screens/home/channel_list/index.ts b/app/screens/home/channel_list/index.ts index 4d2a73d69..9773d664c 100644 --- a/app/screens/home/channel_list/index.ts +++ b/app/screens/home/channel_list/index.ts @@ -3,14 +3,14 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; -import {of as of$, combineLatest} from 'rxjs'; -import {switchMap, distinctUntilChanged} from 'rxjs/operators'; +import {of as of$} from 'rxjs'; +import {switchMap} from 'rxjs/operators'; import {queryAllMyChannelsForTeam} from '@queries/servers/channel'; -import {observeConfigBooleanValue, observeConfigIntValue, observeConfigValue, observeCurrentTeamId, observeLicense} from '@queries/servers/system'; +import {observeCurrentTeamId, observeLicense} from '@queries/servers/system'; import {queryMyTeams} from '@queries/servers/team'; +import {observeShowToS} from '@queries/servers/terms_of_service'; import {observeIsCRTEnabled} from '@queries/servers/thread'; -import {observeCurrentUser} from '@queries/servers/user'; import ChannelsList from './channel_list'; @@ -20,32 +20,6 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { const isLicensed = observeLicense(database).pipe( switchMap((lcs) => (lcs ? of$(lcs.IsLicensed === 'true') : of$(false))), ); - const currentUser = observeCurrentUser(database); - const customTermsOfServiceEnabled = observeConfigBooleanValue(database, 'EnableCustomTermsOfService'); - const customTermsOfServiceId = observeConfigValue(database, 'CustomTermsOfServiceId'); - const customTermsOfServicePeriod = observeConfigIntValue(database, 'CustomTermsOfServiceReAcceptancePeriod'); - - const showToS = combineLatest([ - isLicensed, - customTermsOfServiceEnabled, - currentUser, - customTermsOfServiceId, - customTermsOfServicePeriod, - ]).pipe( - switchMap(([lcs, cfg, user, id, period]) => { - if (!lcs || !cfg) { - return of$(false); - } - - if (user?.termsOfServiceId !== id) { - return of$(true); - } - - const timeElapsed = Date.now() - (user?.termsOfServiceCreateAt || 0); - return of$(timeElapsed > (period * 24 * 60 * 60 * 1000)); - }), - distinctUntilChanged(), - ); return { isCRTEnabled: observeIsCRTEnabled(database), @@ -54,7 +28,7 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { switchMap((id) => (id ? queryAllMyChannelsForTeam(database, id).observeCount() : of$(0))), ), isLicensed, - showToS, + showToS: observeShowToS(database), }; }); diff --git a/app/screens/terms_of_service/index.ts b/app/screens/terms_of_service/index.ts index 64235d35f..7f712cb5a 100644 --- a/app/screens/terms_of_service/index.ts +++ b/app/screens/terms_of_service/index.ts @@ -5,6 +5,7 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; import {observeConfigValue} from '@queries/servers/system'; +import {observeShowToS} from '@queries/servers/terms_of_service'; import TermsOfService from './terms_of_service'; @@ -13,6 +14,7 @@ import type {WithDatabaseArgs} from '@typings/database/database'; const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { return { siteName: observeConfigValue(database, 'SiteName'), + showToS: observeShowToS(database), }; }); diff --git a/app/screens/terms_of_service/terms_of_service.tsx b/app/screens/terms_of_service/terms_of_service.tsx index 036cdee12..09cfe737f 100644 --- a/app/screens/terms_of_service/terms_of_service.tsx +++ b/app/screens/terms_of_service/terms_of_service.tsx @@ -28,6 +28,7 @@ import {typography} from '@utils/typography'; type Props = { siteName?: string; + showToS: boolean; componentId: string; } @@ -91,6 +92,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { const TermsOfService = ({ siteName = 'Mattermost', + showToS, componentId, }: Props) => { const theme = useTheme(); @@ -161,21 +163,19 @@ const TermsOfService = ({ const acceptTerms = useCallback(async () => { setLoading(true); - const {resp} = await updateTermsOfServiceStatus(serverUrl, termsId, true); - if (resp?.status === 'OK') { - dismissOverlay(componentId); - } else { + const {error} = await updateTermsOfServiceStatus(serverUrl, termsId, true); + if (error) { alertError(acceptTerms); } }, [alertError, alertDecline, termsId, serverUrl, componentId]); const declineTerms = useCallback(async () => { setLoading(true); - const {resp} = await updateTermsOfServiceStatus(serverUrl, termsId, false); - if (resp?.status === 'OK') { - alertDecline(); - } else { + const {error} = await updateTermsOfServiceStatus(serverUrl, termsId, false); + if (error) { alertError(declineTerms); + } else { + alertDecline(); } }, [serverUrl, termsId, closeTermsAndLogout]); @@ -195,7 +195,13 @@ const TermsOfService = ({ return () => { NavigationStore.setToSOpen(false); }; - }); + }, []); + + useEffect(() => { + if (!showToS) { + dismissOverlay(componentId); + } + }, [showToS, componentId]); useAndroidHardwareBackHandler(componentId, onPressClose);