From e5d2e1d364891a1ffbd0b37c5a6ea87c24b99d4b Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 20 Oct 2022 10:18:41 -0300 Subject: [PATCH] auto update timezone when device changes its location (#6691) --- app/actions/remote/entry/common.ts | 3 ++- app/actions/remote/entry/gql_common.ts | 4 +++- app/actions/remote/session.ts | 14 +++----------- app/actions/remote/user.ts | 15 ++++++++++----- app/managers/global_event_handler.ts | 18 ++++++++++++++++++ 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/app/actions/remote/entry/common.ts b/app/actions/remote/entry/common.ts index 684781d99..e4f787ed6 100644 --- a/app/actions/remote/entry/common.ts +++ b/app/actions/remote/entry/common.ts @@ -11,7 +11,7 @@ import {fetchRoles} from '@actions/remote/role'; import {fetchConfigAndLicense} from '@actions/remote/systems'; import {fetchAllTeams, fetchMyTeams, fetchTeamsChannelsAndUnreadPosts, MyTeamsRequest} from '@actions/remote/team'; import {fetchNewThreads} from '@actions/remote/thread'; -import {fetchMe, MyUserRequest, updateAllUsersSince} from '@actions/remote/user'; +import {autoUpdateTimezone, fetchMe, MyUserRequest, updateAllUsersSince} from '@actions/remote/user'; import {gqlAllChannels} from '@client/graphQL/entry'; import {General, Preferences, Screens} from '@constants'; import {SYSTEM_IDENTIFIERS} from '@constants/database'; @@ -381,6 +381,7 @@ export const syncOtherServers = async (serverUrl: string) => { if (server.url !== serverUrl && server.lastActiveAt > 0) { registerDeviceToken(server.url); syncAllChannelMembersAndThreads(server.url); + autoUpdateTimezone(server.url); } } } diff --git a/app/actions/remote/entry/gql_common.ts b/app/actions/remote/entry/gql_common.ts index 316e56302..3e0683531 100644 --- a/app/actions/remote/entry/gql_common.ts +++ b/app/actions/remote/entry/gql_common.ts @@ -9,7 +9,7 @@ import {fetchGroupsForMember} from '@actions/remote/groups'; import {fetchPostsForUnreadChannels} from '@actions/remote/post'; import {MyTeamsRequest} from '@actions/remote/team'; import {fetchNewThreads} from '@actions/remote/thread'; -import {updateAllUsersSince} from '@actions/remote/user'; +import {autoUpdateTimezone, updateAllUsersSince} from '@actions/remote/user'; import {gqlEntry, gqlEntryChannels, gqlOtherChannels} from '@client/graphQL/entry'; import {Preferences} from '@constants'; import DatabaseManager from '@database/manager'; @@ -269,5 +269,7 @@ export async function deferredAppEntryActions( result = restDeferredAppEntryActions(serverUrl, since, currentUserId, currentUserLocale, preferences, config, license, teamData, chData, initialTeamId, initialChannelId); } + autoUpdateTimezone(serverUrl); + return result; } diff --git a/app/actions/remote/session.ts b/app/actions/remote/session.ts index 3c61ebacc..b451a5503 100644 --- a/app/actions/remote/session.ts +++ b/app/actions/remote/session.ts @@ -19,18 +19,16 @@ import EphemeralStore from '@store/ephemeral_store'; import {logWarning, logError} from '@utils/log'; import {scheduleExpiredNotification} from '@utils/notification'; import {getCSRFFromCookie} from '@utils/security'; -import {getDeviceTimezone, isTimezoneEnabled} from '@utils/timezone'; import {loginEntry} from './entry'; import {fetchDataRetentionPolicy} from './systems'; -import {autoUpdateTimezone} from './user'; import type ClientError from '@client/rest/error'; import type {LoginArgs} from '@typings/database/database'; const HTTP_UNAUTHORIZED = 401; -export const completeLogin = async (serverUrl: string, user: UserProfile) => { +export const completeLogin = async (serverUrl: string) => { const operator = DatabaseManager.serverDatabases[serverUrl]?.operator; if (!operator) { return {error: `${serverUrl} database not found`}; @@ -43,12 +41,6 @@ export const completeLogin = async (serverUrl: string, user: UserProfile) => { return null; } - // Set timezone - if (isTimezoneEnabled(config)) { - const timezone = getDeviceTimezone(); - await autoUpdateTimezone(serverUrl, {deviceTimezone: timezone, userId: user.id}); - } - // Data retention if (config?.DataRetentionEnableMessageDeletion === 'true' && license?.IsLicensed === 'true' && license?.DataRetention === 'true') { fetchDataRetentionPolicy(serverUrl); @@ -165,7 +157,7 @@ export const login = async (serverUrl: string, {ldapOnly = false, loginId, mfaTo try { const {error, hasTeams, time} = await loginEntry({serverUrl, user}); - completeLogin(serverUrl, user); + completeLogin(serverUrl); return {error: error as ClientError, failed: false, hasTeams, time}; } catch (error) { return {error: error as ClientError, failed: false, time: 0}; @@ -309,7 +301,7 @@ export const ssoLogin = async (serverUrl: string, serverDisplayName: string, ser try { const {error, hasTeams, time} = await loginEntry({serverUrl, user, deviceToken}); - completeLogin(serverUrl, user); + completeLogin(serverUrl); return {error: error as ClientError, failed: false, hasTeams, time}; } catch (error) { return {error: error as ClientError, failed: false, time: 0}; diff --git a/app/actions/remote/user.ts b/app/actions/remote/user.ts index c35d7d4c4..72965badf 100644 --- a/app/actions/remote/user.ts +++ b/app/actions/remote/user.ts @@ -15,9 +15,10 @@ import {debounce} from '@helpers/api/general'; import NetworkManager from '@managers/network_manager'; import {getMembersCountByChannelsId, queryChannelsByTypes} from '@queries/servers/channel'; import {queryGroupsByNames} from '@queries/servers/group'; -import {getCurrentTeamId, getCurrentUserId} from '@queries/servers/system'; -import {getCurrentUser, getUserById, prepareUsers, queryAllUsers, queryUsersById, queryUsersByIdsOrUsernames, queryUsersByUsername} from '@queries/servers/user'; +import {getConfig, getCurrentTeamId, getCurrentUserId} from '@queries/servers/system'; +import {getCurrentUser, prepareUsers, queryAllUsers, queryUsersById, queryUsersByIdsOrUsernames, queryUsersByUsername} from '@queries/servers/user'; import {logError} from '@utils/log'; +import {getDeviceTimezone, isTimezoneEnabled} from '@utils/timezone'; import {getUserTimezoneProps, removeUserFromList} from '@utils/user'; import {fetchGroupsByNames} from './groups'; @@ -850,7 +851,7 @@ export const buildProfileImageUrl = (serverUrl: string, userId: string, timestam return client.getProfilePictureUrl(userId, timestamp); }; -export const autoUpdateTimezone = async (serverUrl: string, {deviceTimezone, userId}: {deviceTimezone: string; userId: string}) => { +export const autoUpdateTimezone = async (serverUrl: string) => { let database; try { const result = DatabaseManager.getServerDatabaseAndOperator(serverUrl); @@ -859,12 +860,16 @@ export const autoUpdateTimezone = async (serverUrl: string, {deviceTimezone, use return {error: `${serverUrl} database not found`}; } - const currentUser = await getUserById(database, userId); + const config = await getConfig(database); + const currentUser = await getCurrentUser(database); - if (!currentUser) { + if (!currentUser || !config || !isTimezoneEnabled(config)) { return null; } + // Set timezone + const deviceTimezone = getDeviceTimezone(); + const currentTimezone = getUserTimezoneProps(currentUser); const newTimezoneExists = currentTimezone.automaticTimezone !== deviceTimezone; diff --git a/app/managers/global_event_handler.ts b/app/managers/global_event_handler.ts index 97a90b708..c3982330e 100644 --- a/app/managers/global_event_handler.ts +++ b/app/managers/global_event_handler.ts @@ -2,14 +2,19 @@ // See LICENSE.txt for license information. import {Alert, DeviceEventEmitter, Linking} from 'react-native'; +import RNLocalize from 'react-native-localize'; import semver from 'semver'; +import {autoUpdateTimezone} from '@actions/remote/user'; import LocalConfig from '@assets/config.json'; import {Events, Sso} from '@constants'; +import DatabaseManager from '@database/manager'; import {DEFAULT_LOCALE, getTranslations, t} from '@i18n'; import {getServerCredentials} from '@init/credentials'; import {getLaunchPropsFromDeepLink, relaunchApp} from '@init/launch'; import * as analytics from '@managers/analytics'; +import {queryAllServers} from '@queries/app/servers'; +import {logError} from '@utils/log'; import type {jsAndNativeErrorHandler} from '@typings/global/error_handling'; @@ -21,6 +26,19 @@ class GlobalEventHandler { constructor() { DeviceEventEmitter.addListener(Events.SERVER_VERSION_CHANGED, this.onServerVersionChanged); DeviceEventEmitter.addListener(Events.CONFIG_CHANGED, this.onServerConfigChanged); + RNLocalize.addEventListener('change', async () => { + try { + const {database} = DatabaseManager.getAppDatabaseAndOperator(); + const servers = await queryAllServers(database); + for (const server of servers) { + if (server.url && server.lastActiveAt > 0) { + autoUpdateTimezone(server.url); + } + } + } catch (e) { + logError('Localize change', e); + } + }); Linking.addEventListener('url', this.onDeepLink); }