From 6ffc1055ca26d026c7ec3a67ff91756a7a220293 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 3 Oct 2023 11:10:34 +0200 Subject: [PATCH 01/28] Migrated User.js lib to TypeScript. --- src/libs/Navigation/Navigation.js | 2 +- src/libs/actions/{User.js => User.ts} | 148 +++++++++++--------------- 2 files changed, 62 insertions(+), 88 deletions(-) rename src/libs/actions/{User.js => User.ts} (85%) diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index de6162685079..5cbd8e9b0af6 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -77,7 +77,7 @@ const getActiveRouteIndex = function (route, index) { /** * Main navigation method for redirecting to a route. * @param {String} route - * @param {String} type - Type of action to perform. Currently UP is supported. + * @param {String} [type] - Type of action to perform. Currently UP is supported. */ function navigate(route = ROUTES.HOME, type) { if (!canNavigate('navigate', {route})) { diff --git a/src/libs/actions/User.js b/src/libs/actions/User.ts similarity index 85% rename from src/libs/actions/User.js rename to src/libs/actions/User.ts index 1830d1e51f6f..7f03ff7a2231 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.ts @@ -1,6 +1,4 @@ -import _ from 'underscore'; -import lodashGet from 'lodash/get'; -import Onyx from 'react-native-onyx'; +import Onyx, {OnyxUpdate} from 'react-native-onyx'; import moment from 'moment'; import ONYXKEYS from '../../ONYXKEYS'; import * as API from '../API'; @@ -18,18 +16,21 @@ import * as Session from './Session'; import * as PersonalDetails from './PersonalDetails'; import * as OnyxUpdates from './OnyxUpdates'; import redirectToSignIn from './SignInRedirect'; +import type Login from '../../types/onyx/Login'; +import type OnyxPersonalDetails from '../../types/onyx/PersonalDetails'; +import type {OnyxUpdatesFromServer} from '../../types/onyx'; -let currentUserAccountID = ''; +let currentUserAccountID = -1; let currentEmail = ''; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (val) => { - currentUserAccountID = lodashGet(val, 'accountID', -1); - currentEmail = lodashGet(val, 'email', ''); + currentUserAccountID = val?.accountID ?? -1; + currentEmail = val?.email ?? ''; }, }); -let myPersonalDetails = {}; +let myPersonalDetails: Partial = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (val) => { @@ -44,9 +45,9 @@ Onyx.connect({ /** * Attempt to close the user's account * - * @param {String} message optional reason for closing account + * @param message optional reason for closing account */ -function closeAccount(message) { +function closeAccount(message: string) { // Note: successData does not need to set isLoading to false because if the CloseAccount // command succeeds, a Pusher response will clear all Onyx data. API.write( @@ -75,20 +76,17 @@ function closeAccount(message) { /** * Resends a validation link to a given login - * - * @param {String} login - * @param {Boolean} isPasswordless - temporary param to trigger passwordless flow in backend */ -function resendValidateCode(login) { +function resendValidateCode(login: string) { Session.resendValidateCode(login); } /** * Requests a new validate code be sent for the passed contact method * - * @param {String} contactMethod - the new contact method that the user is trying to verify + * @param contactMethod - the new contact method that the user is trying to verify */ -function requestContactMethodValidateCode(contactMethod) { +function requestContactMethodValidateCode(contactMethod: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -149,11 +147,9 @@ function requestContactMethodValidateCode(contactMethod) { } /** - * Sets whether or not the user is subscribed to Expensify news - * - * @param {Boolean} isSubscribed + * Sets whether the user is subscribed to Expensify news */ -function updateNewsletterSubscription(isSubscribed) { +function updateNewsletterSubscription(isSubscribed: boolean) { API.write( 'UpdateNewsletterSubscription', { @@ -181,10 +177,9 @@ function updateNewsletterSubscription(isSubscribed) { /** * Delete a specific contact method * - * @param {String} contactMethod - the contact method being deleted - * @param {Array} loginList + * @param contactMethod - the contact method being deleted */ -function deleteContactMethod(contactMethod, loginList) { +function deleteContactMethod(contactMethod: string, loginList: Record) { const oldLoginData = loginList[contactMethod]; const optimisticData = [ @@ -243,11 +238,8 @@ function deleteContactMethod(contactMethod, loginList) { /** * Clears any possible stored errors for a specific field on a contact method - * - * @param {String} contactMethod - * @param {String} fieldName */ -function clearContactMethodErrors(contactMethod, fieldName) { +function clearContactMethodErrors(contactMethod: string, fieldName: string) { Onyx.merge(ONYXKEYS.LOGIN_LIST, { [contactMethod]: { errorFields: { @@ -263,9 +255,9 @@ function clearContactMethodErrors(contactMethod, fieldName) { /** * Resets the state indicating whether a validation code has been sent to a specific contact method. * - * @param {String} contactMethod - The identifier of the contact method to reset. + * @param contactMethod - The identifier of the contact method to reset. */ -function resetContactMethodValidateCodeSentState(contactMethod) { +function resetContactMethodValidateCodeSentState(contactMethod: string) { Onyx.merge(ONYXKEYS.LOGIN_LIST, { [contactMethod]: { validateCodeSent: false, @@ -275,10 +267,8 @@ function resetContactMethodValidateCodeSentState(contactMethod) { /** * Adds a secondary login to a user's account - * - * @param {String} contactMethod */ -function addNewContactMethodAndNavigate(contactMethod) { +function addNewContactMethodAndNavigate(contactMethod: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -333,11 +323,8 @@ function addNewContactMethodAndNavigate(contactMethod) { /** * Validates a login given an accountID and validation code - * - * @param {Number} accountID - * @param {String} validateCode */ -function validateLogin(accountID, validateCode) { +function validateLogin(accountID: number, validateCode: string) { Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, isLoading: true}); const optimisticData = [ @@ -363,10 +350,9 @@ function validateLogin(accountID, validateCode) { /** * Validates a secondary login / contact method * - * @param {String} contactMethod - The contact method the user is trying to verify - * @param {String} validateCode + * @param contactMethod - The contact method the user is trying to verify */ -function validateSecondaryLogin(contactMethod, validateCode) { +function validateSecondaryLogin(contactMethod: string, validateCode: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -448,11 +434,9 @@ function validateSecondaryLogin(contactMethod, validateCode) { * Checks the blockedFromConcierge object to see if it has an expiresAt key, * and if so whether the expiresAt date of a user's ban is before right now * - * @param {Object} blockedFromConciergeNVP - * @returns {Boolean} */ -function isBlockedFromConcierge(blockedFromConciergeNVP) { - if (_.isEmpty(blockedFromConciergeNVP)) { +function isBlockedFromConcierge(blockedFromConciergeNVP: {expiresAt: number}) { + if (!blockedFromConciergeNVP || Object.keys(blockedFromConciergeNVP).length === 0) { return false; } @@ -463,18 +447,17 @@ function isBlockedFromConcierge(blockedFromConciergeNVP) { return moment().isBefore(moment(blockedFromConciergeNVP.expiresAt), 'day'); } -function triggerNotifications(onyxUpdates) { - _.each(onyxUpdates, (update) => { +function triggerNotifications(onyxUpdates: any) { + onyxUpdates.forEach((update) => { if (!update.shouldNotify) { return; } const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); - const reportActions = _.values(update.value); + const reportActions = Object.values(update.value); - // eslint-disable-next-line rulesdir/no-negated-variables - const notifiableActions = _.filter(reportActions, (action) => ReportActionsUtils.isNotifiableReportAction(action)); - _.each(notifiableActions, (action) => Report.showReportActionNotification(reportID, action)); + const notifiableActions = reportActions.filter((action) => ReportActionsUtils.isNotifiableReportAction(action)); + notifiableActions.forEach((action) => Report.showReportActionNotification(reportID, action)); }); } @@ -490,7 +473,7 @@ function subscribeToUserEvents() { // Handles the mega multipleEvents from Pusher which contains an array of single events. // Each single event is passed to PusherUtils in order to trigger the callbacks for that event - PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.MULTIPLE_EVENTS, currentUserAccountID, (pushJSON) => { + PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.MULTIPLE_EVENTS, currentUserAccountID.toString(), (pushJSON: OnyxUpdatesFromServer) => { // The data for this push event comes in two different formats: // 1. Original format - this is what was sent before the RELIABLE_UPDATES project and will go away once RELIABLE_UPDATES is fully complete // - The data is an array of objects, where each object is an onyx update @@ -498,8 +481,8 @@ function subscribeToUserEvents() { // 1. Reliable updates format - this is what was sent with the RELIABLE_UPDATES project and will be the format from now on // - The data is an object, containing updateIDs from the server and an array of onyx updates (this array is the same format as the original format above) // Example: {lastUpdateID: 1, previousUpdateID: 0, updates: [{onyxMethod: 'whatever', key: 'foo', value: 'bar'}]} - if (_.isArray(pushJSON)) { - _.each(pushJSON, (multipleEvent) => { + if (Array.isArray(pushJSON)) { + pushJSON.forEach((multipleEvent) => { PusherUtils.triggerMultiEventHandler(multipleEvent.eventType, multipleEvent.data); }); return; @@ -512,7 +495,7 @@ function subscribeToUserEvents() { previousUpdateID: Number(pushJSON.previousUpdateID || 0), }; if (!OnyxUpdates.doesClientNeedToBeUpdated(Number(pushJSON.previousUpdateID || 0))) { - OnyxUpdates.apply(updates); + OnyxUpdates.apply(updates as any); return; } @@ -522,7 +505,7 @@ function subscribeToUserEvents() { }); // Handles Onyx updates coming from Pusher through the mega multipleEvents. - PusherUtils.subscribeToMultiEvent(Pusher.TYPE.MULTIPLE_EVENT_TYPE.ONYX_API_UPDATE, (pushJSON) => + PusherUtils.subscribeToMultiEvent(Pusher.TYPE.MULTIPLE_EVENT_TYPE.ONYX_API_UPDATE, (pushJSON: OnyxUpdate[]) => SequentialQueue.getCurrentRequest().then(() => { // If we don't have the currentUserAccountID (user is logged out) we don't want to update Onyx with data from Pusher if (!currentUserAccountID) { @@ -541,9 +524,8 @@ function subscribeToUserEvents() { /** * Sync preferredSkinTone with Onyx and Server - * @param {String} skinTone */ -function updatePreferredSkinTone(skinTone) { +function updatePreferredSkinTone(skinTone: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.SET, @@ -562,9 +544,8 @@ function updatePreferredSkinTone(skinTone) { /** * Sync frequentlyUsedEmojis with Onyx and Server - * @param {Object[]} frequentlyUsedEmojis */ -function updateFrequentlyUsedEmojis(frequentlyUsedEmojis) { +function updateFrequentlyUsedEmojis(frequentlyUsedEmojis: string[]) { const optimisticData = [ { onyxMethod: Onyx.METHOD.SET, @@ -583,9 +564,8 @@ function updateFrequentlyUsedEmojis(frequentlyUsedEmojis) { /** * Sync user chat priority mode with Onyx and Server - * @param {String} mode */ -function updateChatPriorityMode(mode) { +function updateChatPriorityMode(mode: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -603,10 +583,7 @@ function updateChatPriorityMode(mode) { Navigation.goBack(ROUTES.SETTINGS_PREFERENCES); } -/** - * @param {Boolean} shouldUseStagingServer - */ -function setShouldUseStagingServer(shouldUseStagingServer) { +function setShouldUseStagingServer(shouldUseStagingServer: boolean) { Onyx.merge(ONYXKEYS.USER, {shouldUseStagingServer}); } @@ -623,19 +600,19 @@ function clearScreenShareRequest() { /** * Open an OldDot tab linking to a screen share request. - * @param {String} accessToken Access token required to join a screen share room, generated by the backend - * @param {String} roomName Name of the screen share room to join + * @param accessToken Access token required to join a screen share room, generated by the backend + * @param roomName Name of the screen share room to join */ -function joinScreenShare(accessToken, roomName) { +function joinScreenShare(accessToken: string, roomName: string) { Link.openOldDotLink(`inbox?action=screenShare&accessToken=${accessToken}&name=${roomName}`); clearScreenShareRequest(); } /** * Downloads the statement PDF for the provided period - * @param {String} period YYYYMM format + * @param period YYYYMM format */ -function generateStatementPDF(period) { +function generateStatementPDF(period: string) { API.read( 'GetStatementPDF', {period}, @@ -673,10 +650,8 @@ function generateStatementPDF(period) { /** * Sets a contact method / secondary login as the user's "Default" contact method. - * - * @param {String} newDefaultContactMethod */ -function setContactMethodAsDefault(newDefaultContactMethod) { +function setContactMethodAsDefault(newDefaultContactMethod: string) { const oldDefaultContactMethod = currentEmail; const optimisticData = [ { @@ -754,14 +729,19 @@ function setContactMethodAsDefault(newDefaultContactMethod) { }, }, ]; - API.write('SetContactMethodAsDefault', {partnerUserID: newDefaultContactMethod}, {optimisticData, successData, failureData}); + API.write( + 'SetContactMethodAsDefault', + {partnerUserID: newDefaultContactMethod}, + { + optimisticData, + successData, + failureData, + }, + ); Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS); } -/** - * @param {String} theme - */ -function updateTheme(theme) { +function updateTheme(theme: string) { const optimisticData = [ { onyxMethod: Onyx.METHOD.SET, @@ -783,12 +763,10 @@ function updateTheme(theme) { /** * Sets a custom status - * - * @param {Object} status - * @param {String} status.text - * @param {String} status.emojiCode */ -function updateCustomStatus(status) { +type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; + +function updateCustomStatus(status: CustomStatus) { API.write('UpdateStatus', status, { optimisticData: [ { @@ -826,18 +804,14 @@ function clearCustomStatus() { /** * Sets a custom status * - * @param {Object} status - * @param {String} status.text - * @param {String} status.emojiCode - * @param {String} status.clearAfter - ISO 8601 format string, which represents the time when the status should be cleared + * @param status.clearAfter - ISO 8601 format string, which represents the time when the status should be cleared */ -function updateDraftCustomStatus(status) { +function updateDraftCustomStatus(status: CustomStatus) { Onyx.merge(ONYXKEYS.CUSTOM_STATUS_DRAFT, status); } /** * Clear the custom draft status - * */ function clearDraftCustomStatus() { Onyx.merge(ONYXKEYS.CUSTOM_STATUS_DRAFT, {text: '', emojiCode: '', clearAfter: ''}); From 7dbca33e8f5f69a5094e474a8e59365397efab2d Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 3 Oct 2023 11:13:34 +0200 Subject: [PATCH 02/28] Uninlined types. --- src/libs/actions/User.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 7f03ff7a2231..2ab91f6d59cd 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -20,6 +20,9 @@ import type Login from '../../types/onyx/Login'; import type OnyxPersonalDetails from '../../types/onyx/PersonalDetails'; import type {OnyxUpdatesFromServer} from '../../types/onyx'; +type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; +type BlockedFromConciergeNVP = {expiresAt: number}; + let currentUserAccountID = -1; let currentEmail = ''; Onyx.connect({ @@ -435,7 +438,7 @@ function validateSecondaryLogin(contactMethod: string, validateCode: string) { * and if so whether the expiresAt date of a user's ban is before right now * */ -function isBlockedFromConcierge(blockedFromConciergeNVP: {expiresAt: number}) { +function isBlockedFromConcierge(blockedFromConciergeNVP: BlockedFromConciergeNVP) { if (!blockedFromConciergeNVP || Object.keys(blockedFromConciergeNVP).length === 0) { return false; } @@ -764,8 +767,6 @@ function updateTheme(theme: string) { /** * Sets a custom status */ -type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; - function updateCustomStatus(status: CustomStatus) { API.write('UpdateStatus', status, { optimisticData: [ From 45b40db6bd5e28135feb34f1722501bffb41da00 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Thu, 5 Oct 2023 10:59:43 +0200 Subject: [PATCH 03/28] WIP: Work sync --- src/libs/actions/User.ts | 398 +++++++++++++----------- src/types/onyx/OnyxUpdatesFromServer.ts | 6 +- src/types/onyx/PersonalDetails.ts | 3 + 3 files changed, 218 insertions(+), 189 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 2ab91f6d59cd..993559ffc2ec 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -1,4 +1,4 @@ -import Onyx, {OnyxUpdate} from 'react-native-onyx'; +import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; import moment from 'moment'; import ONYXKEYS from '../../ONYXKEYS'; import * as API from '../API'; @@ -18,7 +18,9 @@ import * as OnyxUpdates from './OnyxUpdates'; import redirectToSignIn from './SignInRedirect'; import type Login from '../../types/onyx/Login'; import type OnyxPersonalDetails from '../../types/onyx/PersonalDetails'; -import type {OnyxUpdatesFromServer} from '../../types/onyx'; +import type {FrequentlyUsedEmoji, OnyxUpdatesFromServer} from '../../types/onyx'; +import {OnyxServerUpdate} from '../../types/onyx/OnyxUpdatesFromServer'; +import ReportAction from '../../types/onyx/ReportAction'; type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; type BlockedFromConciergeNVP = {expiresAt: number}; @@ -27,21 +29,21 @@ let currentUserAccountID = -1; let currentEmail = ''; Onyx.connect({ key: ONYXKEYS.SESSION, - callback: (val) => { - currentUserAccountID = val?.accountID ?? -1; - currentEmail = val?.email ?? ''; + callback: (value) => { + currentUserAccountID = value?.accountID ?? -1; + currentEmail = value?.email ?? ''; }, }); let myPersonalDetails: Partial = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, - callback: (val) => { - if (!val || !currentUserAccountID) { + callback: (value) => { + if (!value || !currentUserAccountID) { return; } - myPersonalDetails = val[currentUserAccountID]; + myPersonalDetails = value[currentUserAccountID]; }, }); @@ -53,32 +55,38 @@ Onyx.connect({ function closeAccount(message: string) { // Note: successData does not need to set isLoading to false because if the CloseAccount // command succeeds, a Pusher response will clear all Onyx data. - API.write( - 'CloseAccount', - {message}, - { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, - value: {isLoading: true}, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, - value: {isLoading: false}, - }, - ], + + type CloseAccountParam = {message: string}; + + const parameters: CloseAccountParam = {message}; + + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, + value: {isLoading: true}, }, - ); + ]; + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, + value: {isLoading: false}, + }, + ]; + + API.write('CloseAccount', parameters, { + optimisticData, + failureData, + }); // Run cleanup actions to prevent reconnection callbacks from blocking logging in again redirectToSignIn(); } /** * Resends a validation link to a given login + * @param login + * @param isPasswordless - temporary param to trigger passwordless flow in backend */ function resendValidateCode(login: string) { Session.resendValidateCode(login); @@ -90,7 +98,7 @@ function resendValidateCode(login: string) { * @param contactMethod - the new contact method that the user is trying to verify */ function requestContactMethodValidateCode(contactMethod: string) { - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, @@ -108,7 +116,7 @@ function requestContactMethodValidateCode(contactMethod: string) { }, }, ]; - const successData = [ + const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, @@ -122,7 +130,7 @@ function requestContactMethodValidateCode(contactMethod: string) { }, }, ]; - const failureData = [ + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, @@ -140,52 +148,51 @@ function requestContactMethodValidateCode(contactMethod: string) { }, ]; - API.write( - 'RequestContactMethodValidateCode', - { - email: contactMethod, - }, - {optimisticData, successData, failureData}, - ); + type RequestContactMethodValidateCodeParam = {email: string}; + + const parameters: RequestContactMethodValidateCodeParam = {email: contactMethod}; + + API.write('RequestContactMethodValidateCode', parameters, {optimisticData, successData, failureData}); } /** * Sets whether the user is subscribed to Expensify news */ function updateNewsletterSubscription(isSubscribed: boolean) { - API.write( - 'UpdateNewsletterSubscription', + type UpdateNewsletterSubscriptionParam = {isSubscribed: boolean}; + + const parameters: UpdateNewsletterSubscriptionParam = {isSubscribed}; + + const optimisticData: OnyxUpdate[] = [ { - isSubscribed, + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.USER, + value: {isSubscribedToNewsletter: isSubscribed}, }, + ]; + const failureData: OnyxUpdate[] = [ { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.USER, - value: {isSubscribedToNewsletter: isSubscribed}, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.USER, - value: {isSubscribedToNewsletter: !isSubscribed}, - }, - ], + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.USER, + value: {isSubscribedToNewsletter: !isSubscribed}, }, - ); + ]; + + API.write('UpdateNewsletterSubscription', parameters, { + optimisticData, + failureData, + }); } /** * Delete a specific contact method - * * @param contactMethod - the contact method being deleted + * @param loginList */ function deleteContactMethod(contactMethod: string, loginList: Record) { const oldLoginData = loginList[contactMethod]; - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, @@ -202,7 +209,7 @@ function deleteContactMethod(contactMethod: string, loginList: Record { if (!update.shouldNotify) { return; } const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); - const reportActions = Object.values(update.value); + const reportActions = Object.values((update.value as OnyxCollection) ?? {}); - const notifiableActions = reportActions.filter((action) => ReportActionsUtils.isNotifiableReportAction(action)); - notifiableActions.forEach((action) => Report.showReportActionNotification(reportID, action)); + const actions = reportActions.filter((action) => ReportActionsUtils.isNotifiableReportAction(action)) as ReportAction[]; + actions.forEach((action) => Report.showReportActionNotification(reportID, action)); }); } @@ -498,7 +506,7 @@ function subscribeToUserEvents() { previousUpdateID: Number(pushJSON.previousUpdateID || 0), }; if (!OnyxUpdates.doesClientNeedToBeUpdated(Number(pushJSON.previousUpdateID || 0))) { - OnyxUpdates.apply(updates as any); + OnyxUpdates.apply(updates); return; } @@ -529,60 +537,62 @@ function subscribeToUserEvents() { * Sync preferredSkinTone with Onyx and Server */ function updatePreferredSkinTone(skinTone: string) { - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, value: skinTone, }, ]; - API.write( - 'UpdatePreferredEmojiSkinTone', - { - value: skinTone, - }, - {optimisticData}, - ); + + type UpdatePreferredEmojiSkinTone = { + value: string; + }; + + const parameters: UpdatePreferredEmojiSkinTone = {value: skinTone}; + + API.write('UpdatePreferredEmojiSkinTone', parameters, {optimisticData}); } /** * Sync frequentlyUsedEmojis with Onyx and Server */ -function updateFrequentlyUsedEmojis(frequentlyUsedEmojis: string[]) { - const optimisticData = [ +function updateFrequentlyUsedEmojis(frequentlyUsedEmojis: FrequentlyUsedEmoji[]) { + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.FREQUENTLY_USED_EMOJIS, value: frequentlyUsedEmojis, }, ]; - API.write( - 'UpdateFrequentlyUsedEmojis', - { - value: JSON.stringify(frequentlyUsedEmojis), - }, - {optimisticData}, - ); + type UpdateFrequentlyUsedEmojisParam = {value: string}; + + const parameters: UpdateFrequentlyUsedEmojisParam = {value: JSON.stringify(frequentlyUsedEmojis)}; + + API.write('UpdateFrequentlyUsedEmojis', parameters, {optimisticData}); } /** * Sync user chat priority mode with Onyx and Server */ function updateChatPriorityMode(mode: string) { - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_PRIORITY_MODE, value: mode, }, ]; - API.write( - 'UpdateChatPriorityMode', - { - value: mode, - }, - {optimisticData}, - ); + + type UpdateChatPriorityModeParam = { + value: string; + }; + + const parameters: UpdateChatPriorityModeParam = { + value: mode, + }; + + API.write('UpdateChatPriorityMode', parameters, {optimisticData}); Navigation.goBack(ROUTES.SETTINGS_PREFERENCES); } @@ -616,37 +626,40 @@ function joinScreenShare(accessToken: string, roomName: string) { * @param period YYYYMM format */ function generateStatementPDF(period: string) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.WALLET_STATEMENT, + value: { + isGenerating: true, + }, + }, + ]; + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.WALLET_STATEMENT, + value: { + isGenerating: false, + }, + }, + ]; + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.WALLET_STATEMENT, + value: { + isGenerating: false, + }, + }, + ]; API.read( 'GetStatementPDF', {period}, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.WALLET_STATEMENT, - value: { - isGenerating: true, - }, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.WALLET_STATEMENT, - value: { - isGenerating: false, - }, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.WALLET_STATEMENT, - value: { - isGenerating: false, - }, - }, - ], + optimisticData, + successData, + failureData, }, ); } @@ -656,7 +669,7 @@ function generateStatementPDF(period: string) { */ function setContactMethodAsDefault(newDefaultContactMethod: string) { const oldDefaultContactMethod = currentEmail; - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.SESSION, @@ -689,7 +702,7 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { }, }, ]; - const successData = [ + const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, @@ -702,7 +715,7 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { }, }, ]; - const failureData = [ + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.SESSION, @@ -732,20 +745,25 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { }, }, ]; - API.write( - 'SetContactMethodAsDefault', - {partnerUserID: newDefaultContactMethod}, - { - optimisticData, - successData, - failureData, - }, - ); + + type SetContactMethodAsDefaultParam = { + partnerUserID: string; + }; + + const parameters: SetContactMethodAsDefaultParam = { + partnerUserID: newDefaultContactMethod, + }; + + API.write('SetContactMethodAsDefault', parameters, { + optimisticData, + successData, + failureData, + }); Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS); } function updateTheme(theme: string) { - const optimisticData = [ + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.PREFERRED_THEME, @@ -753,13 +771,15 @@ function updateTheme(theme: string) { }, ]; - API.write( - 'UpdateTheme', - { - value: theme, - }, - {optimisticData}, - ); + type UpdateThemeParam = { + value: string; + }; + + const parameters: UpdateThemeParam = { + value: theme, + }; + + API.write('UpdateTheme', parameters, {optimisticData}); Navigation.navigate(ROUTES.SETTINGS_PREFERENCES); } @@ -768,18 +788,19 @@ function updateTheme(theme: string) { * Sets a custom status */ function updateCustomStatus(status: CustomStatus) { - API.write('UpdateStatus', status, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - value: { - [currentUserAccountID]: { - status, - }, + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [currentUserAccountID]: { + status, }, }, - ], + }, + ]; + API.write('UpdateStatus', status, { + optimisticData, }); } @@ -787,24 +808,27 @@ function updateCustomStatus(status: CustomStatus) { * Clears the custom status */ function clearCustomStatus() { - API.write('ClearStatus', undefined, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - value: { - [currentUserAccountID]: { - status: null, // Clearing the field - }, + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [currentUserAccountID]: { + status: null, // Clearing the field }, }, - ], + }, + ]; + API.write('ClearStatus', undefined, { + optimisticData, }); } /** * Sets a custom status * + * @param status.text + * @param status.emojiCode * @param status.clearAfter - ISO 8601 format string, which represents the time when the status should be cleared */ function updateDraftCustomStatus(status: CustomStatus) { diff --git a/src/types/onyx/OnyxUpdatesFromServer.ts b/src/types/onyx/OnyxUpdatesFromServer.ts index 50b1503b90bd..843d3ae86e46 100644 --- a/src/types/onyx/OnyxUpdatesFromServer.ts +++ b/src/types/onyx/OnyxUpdatesFromServer.ts @@ -2,9 +2,11 @@ import {OnyxUpdate} from 'react-native-onyx'; import Request from './Request'; import Response from './Response'; +type OnyxServerUpdate = OnyxUpdate & {shouldNotify?: boolean}; + type OnyxUpdateEvent = { eventType: string; - data: OnyxUpdate[]; + data: OnyxServerUpdate[]; }; type OnyxUpdatesFromServer = { @@ -16,4 +18,4 @@ type OnyxUpdatesFromServer = { updates?: OnyxUpdateEvent[]; }; -export type {OnyxUpdatesFromServer, OnyxUpdateEvent}; +export type {OnyxUpdatesFromServer, OnyxUpdateEvent, OnyxServerUpdate}; diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts index 201273beac63..6bb41849b0b6 100644 --- a/src/types/onyx/PersonalDetails.ts +++ b/src/types/onyx/PersonalDetails.ts @@ -37,6 +37,9 @@ type PersonalDetails = { /** Pronouns of the current user from their personal details */ pronouns?: string; + /** User status */ + status: {text: string; emojiCode: string; clearAfter?: string} | null; + /** Local currency for the user */ localCurrencyCode?: string; From 9ce523714c7ecf6f4b15aa40656b848e6d730e66 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 14 Nov 2023 17:39:00 +0100 Subject: [PATCH 04/28] User.ts remigrated. --- src/libs/Network/SequentialQueue.ts | 2 +- src/libs/actions/User.ts | 52 +++++++++-------------------- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/src/libs/Network/SequentialQueue.ts b/src/libs/Network/SequentialQueue.ts index d4aee4a221e5..4ce97f349194 100644 --- a/src/libs/Network/SequentialQueue.ts +++ b/src/libs/Network/SequentialQueue.ts @@ -176,7 +176,7 @@ function push(request: OnyxRequest) { flush(); } -function getCurrentRequest(): OnyxRequest | Promise { +function getCurrentRequest(): Promise { if (currentRequest === null) { return Promise.resolve(); } diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index e58612210485..7c959b390838 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -1,7 +1,6 @@ import {isBefore} from 'date-fns'; -import lodashGet from 'lodash/get'; -import Onyx from 'react-native-onyx'; -import _ from 'underscore'; +import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; +import {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -12,25 +11,17 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; -import moment from 'moment'; -import ONYXKEYS from '../../ONYXKEYS'; -import * as API from '../API'; -import CONST from '../../CONST'; -import Navigation from '../Navigation/Navigation'; -import ROUTES from '../../ROUTES'; -import * as Pusher from '../Pusher/pusher'; +import type {FrequentlyUsedEmoji} from '@src/types/onyx'; +import type Login from '@src/types/onyx/Login'; +import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; +import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; +import ReportAction from '@src/types/onyx/ReportAction'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; import * as Report from './Report'; import * as Session from './Session'; import redirectToSignIn from './SignInRedirect'; -import type Login from '../../types/onyx/Login'; -import type OnyxPersonalDetails from '../../types/onyx/PersonalDetails'; -import type {FrequentlyUsedEmoji, OnyxUpdatesFromServer} from '../../types/onyx'; -import {OnyxServerUpdate} from '../../types/onyx/OnyxUpdatesFromServer'; -import ReportAction from '../../types/onyx/ReportAction'; type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; type BlockedFromConciergeNVP = {expiresAt: number}; @@ -96,7 +87,6 @@ function closeAccount(message: string) { /** * Resends a validation link to a given login * @param login - * @param isPasswordless - temporary param to trigger passwordless flow in backend */ function resendValidateCode(login: string) { Session.resendValidateCode(login); @@ -114,7 +104,6 @@ function requestContactMethodValidateCode(contactMethod: string) { key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { - validateCodeSent: false, errorFields: { validateCodeSent: null, validateLogin: null, @@ -132,7 +121,6 @@ function requestContactMethodValidateCode(contactMethod: string) { key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { - validateCodeSent: true, pendingFields: { validateCodeSent: null, }, @@ -146,7 +134,6 @@ function requestContactMethodValidateCode(contactMethod: string) { key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { - validateCodeSent: false, errorFields: { validateCodeSent: ErrorUtils.getMicroSecondOnyxError('contacts.genericFailureMessages.requestContactMethodValidateCode'), }, @@ -250,15 +237,8 @@ function deleteContactMethod(contactMethod: string, loginList: Record { + PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.MULTIPLE_EVENTS, currentUserAccountID.toString(), (pushJSON) => { // The data for this push event comes in two different formats: // 1. Original format - this is what was sent before the RELIABLE_UPDATES project and will go away once RELIABLE_UPDATES is fully complete // - The data is an array of objects, where each object is an onyx update @@ -520,7 +498,7 @@ function subscribeToUserEvents() { const updates = { type: CONST.ONYX_UPDATE_TYPES.PUSHER, lastUpdateID: Number(pushJSON.lastUpdateID || 0), - updates: pushJSON.updates, + updates: pushJSON.updates ?? [], previousUpdateID: Number(pushJSON.previousUpdateID || 0), }; if (!OnyxUpdates.doesClientNeedToBeUpdated(Number(pushJSON.previousUpdateID || 0))) { @@ -593,7 +571,7 @@ function updateFrequentlyUsedEmojis(frequentlyUsedEmojis: FrequentlyUsedEmoji[]) /** * Sync user chat priority mode with Onyx and Server */ -function updateChatPriorityMode(mode: string) { +function updateChatPriorityMode(mode: ValueOf) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -777,10 +755,10 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { successData, failureData, }); - Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS); + Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS.getRoute()); } -function updateTheme(theme: string) { +function updateTheme(theme: ValueOf) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, From c2f91cefea0d9ea4c1ac43d0f5b231a3ec88e4e7 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 14 Nov 2023 17:47:49 +0100 Subject: [PATCH 05/28] User.ts remigrated. --- src/libs/actions/User.ts | 11 +++++++++-- src/types/onyx/PersonalDetails.ts | 3 --- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 7c959b390838..21b5ce811e48 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -783,7 +783,7 @@ function updateTheme(theme: ValueOf) { /** * Sets a custom status */ -function updateCustomStatus(status: CustomStatus) { +function updateCustomStatus(status: string) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -795,7 +795,14 @@ function updateCustomStatus(status: CustomStatus) { }, }, ]; - API.write('UpdateStatus', status, { + + type UpdateStatusParam = { + status: string; + }; + + const params: UpdateStatusParam = {status}; + + API.write('UpdateStatus', params, { optimisticData, }); } diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts index 92204bf7bd28..8fc627158495 100644 --- a/src/types/onyx/PersonalDetails.ts +++ b/src/types/onyx/PersonalDetails.ts @@ -47,9 +47,6 @@ type PersonalDetails = { /** Pronouns of the current user from their personal details */ pronouns?: string; - /** User status */ - status: {text: string; emojiCode: string; clearAfter?: string} | null; - /** Local currency for the user */ localCurrencyCode?: string; From cba3f8cd93bdfbdc0776a1ac18aeecabd83f7a9e Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 14 Nov 2023 18:43:05 +0100 Subject: [PATCH 06/28] Small alignments. --- src/libs/actions/User.ts | 24 ++++++++++++++++-------- src/types/onyx/Login.ts | 3 +++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 21b5ce811e48..a76474541364 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -86,7 +86,6 @@ function closeAccount(message: string) { /** * Resends a validation link to a given login - * @param login */ function resendValidateCode(login: string) { Session.resendValidateCode(login); @@ -104,6 +103,7 @@ function requestContactMethodValidateCode(contactMethod: string) { key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { + validateCodeSent: false, errorFields: { validateCodeSent: null, validateLogin: null, @@ -121,6 +121,7 @@ function requestContactMethodValidateCode(contactMethod: string) { key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { + validateCodeSent: true, pendingFields: { validateCodeSent: null, }, @@ -128,12 +129,14 @@ function requestContactMethodValidateCode(contactMethod: string) { }, }, ]; + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.LOGIN_LIST, value: { [contactMethod]: { + validateCodeSent: false, errorFields: { validateCodeSent: ErrorUtils.getMicroSecondOnyxError('contacts.genericFailureMessages.requestContactMethodValidateCode'), }, @@ -265,7 +268,9 @@ function clearContactMethodErrors(contactMethod: string, fieldName: string) { */ function resetContactMethodValidateCodeSentState(contactMethod: string) { Onyx.merge(ONYXKEYS.LOGIN_LIST, { - [contactMethod]: {}, + [contactMethod]: { + validateCodeSent: false, + }, }); } @@ -408,6 +413,7 @@ function validateSecondaryLogin(contactMethod: string, validateCode: string) { value: {isLoading: false}, }, ]; + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -512,7 +518,7 @@ function subscribeToUserEvents() { }); // Handles Onyx updates coming from Pusher through the mega multipleEvents. - PusherUtils.subscribeToMultiEvent(Pusher.TYPE.MULTIPLE_EVENT_TYPE.ONYX_API_UPDATE, (pushJSON: OnyxUpdate[]) => + PusherUtils.subscribeToMultiEvent(Pusher.TYPE.MULTIPLE_EVENT_TYPE.ONYX_API_UPDATE, (pushJSON: OnyxServerUpdate[]) => SequentialQueue.getCurrentRequest().then(() => { // If we don't have the currentUserAccountID (user is logged out) we don't want to update Onyx with data from Pusher if (!currentUserAccountID) { @@ -783,26 +789,28 @@ function updateTheme(theme: ValueOf) { /** * Sets a custom status */ -function updateCustomStatus(status: string) { +function updateCustomStatus(status: CustomStatus) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.PERSONAL_DETAILS_LIST, value: { [currentUserAccountID]: { - status, + status: status.text, }, }, }, ]; type UpdateStatusParam = { - status: string; + text: string; + emojiCode: string; + clearAfter?: string; }; - const params: UpdateStatusParam = {status}; + const parameters: UpdateStatusParam = {text: status.text, emojiCode: status.emojiCode, clearAfter: status.clearAfter}; - API.write('UpdateStatus', params, { + API.write('UpdateStatus', parameters, { optimisticData, }); } diff --git a/src/types/onyx/Login.ts b/src/types/onyx/Login.ts index c770e2f81f90..deedb1b71af9 100644 --- a/src/types/onyx/Login.ts +++ b/src/types/onyx/Login.ts @@ -10,6 +10,9 @@ type Login = { /** Date login was validated, used to show info indicator status */ validatedDate?: string; + /** Whether the user validation code was sent */ + validateCodeSent?: boolean; + /** Field-specific server side errors keyed by microtime */ errorFields?: OnyxCommon.ErrorFields; From 85a2c939757f931e6888987f2bceb0d94c1b8b00 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Wed, 15 Nov 2023 10:00:08 +0100 Subject: [PATCH 07/28] Changes after review. --- src/libs/actions/User.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index a76474541364..b208c3bb0989 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -40,7 +40,7 @@ let myPersonalDetails: Partial = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { - if (!value || !currentUserAccountID) { + if (!value || currentUserAccountID === -1) { return; } @@ -240,7 +240,6 @@ function deleteContactMethod(contactMethod: string, loginList: Record SequentialQueue.getCurrentRequest().then(() => { // If we don't have the currentUserAccountID (user is logged out) we don't want to update Onyx with data from Pusher - if (!currentUserAccountID) { + if (currentUserAccountID === -1) { return; } @@ -761,7 +760,7 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { successData, failureData, }); - Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS.getRoute()); + Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS.route); } function updateTheme(theme: ValueOf) { From 60be0181c8bf9b372e2a4551ea43ca4432a8a7d7 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Wed, 15 Nov 2023 10:46:35 +0100 Subject: [PATCH 08/28] Changes after review. --- src/libs/actions/User.ts | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index b208c3bb0989..238e73a4bf83 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -57,9 +57,9 @@ function closeAccount(message: string) { // Note: successData does not need to set isLoading to false because if the CloseAccount // command succeeds, a Pusher response will clear all Onyx data. - type CloseAccountParam = {message: string}; + type CloseAccountParams = {message: string}; - const parameters: CloseAccountParam = {message}; + const parameters: CloseAccountParams = {message}; const optimisticData: OnyxUpdate[] = [ { @@ -148,9 +148,9 @@ function requestContactMethodValidateCode(contactMethod: string) { }, ]; - type RequestContactMethodValidateCodeParam = {email: string}; + type RequestContactMethodValidateCodeParams = {email: string}; - const parameters: RequestContactMethodValidateCodeParam = {email: contactMethod}; + const parameters: RequestContactMethodValidateCodeParams = {email: contactMethod}; API.write('RequestContactMethodValidateCode', parameters, {optimisticData, successData, failureData}); } @@ -159,9 +159,9 @@ function requestContactMethodValidateCode(contactMethod: string) { * Sets whether the user is subscribed to Expensify news */ function updateNewsletterSubscription(isSubscribed: boolean) { - type UpdateNewsletterSubscriptionParam = {isSubscribed: boolean}; + type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; - const parameters: UpdateNewsletterSubscriptionParam = {isSubscribed}; + const parameters: UpdateNewsletterSubscriptionParams = {isSubscribed}; const optimisticData: OnyxUpdate[] = [ { @@ -236,9 +236,9 @@ function deleteContactMethod(contactMethod: string, loginList: Record) { }, ]; - type UpdateChatPriorityModeParam = { + type UpdateChatPriorityModeParams = { value: string; }; - const parameters: UpdateChatPriorityModeParam = { + const parameters: UpdateChatPriorityModeParams = { value: mode, }; @@ -747,11 +747,11 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { }, ]; - type SetContactMethodAsDefaultParam = { + type SetContactMethodAsDefaultParams = { partnerUserID: string; }; - const parameters: SetContactMethodAsDefaultParam = { + const parameters: SetContactMethodAsDefaultParams = { partnerUserID: newDefaultContactMethod, }; @@ -772,11 +772,11 @@ function updateTheme(theme: ValueOf) { }, ]; - type UpdateThemeParam = { + type UpdateThemeParams = { value: string; }; - const parameters: UpdateThemeParam = { + const parameters: UpdateThemeParams = { value: theme, }; @@ -801,13 +801,13 @@ function updateCustomStatus(status: CustomStatus) { }, ]; - type UpdateStatusParam = { + type UpdateStatusParams = { text: string; emojiCode: string; clearAfter?: string; }; - const parameters: UpdateStatusParam = {text: status.text, emojiCode: status.emojiCode, clearAfter: status.clearAfter}; + const parameters: UpdateStatusParams = {text: status.text, emojiCode: status.emojiCode, clearAfter: status.clearAfter}; API.write('UpdateStatus', parameters, { optimisticData, From ee33de2fa620b55ac06ba52ba69ae2689b0cf0c3 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Wed, 15 Nov 2023 10:50:37 +0100 Subject: [PATCH 09/28] Changes after review. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 238e73a4bf83..6290275ed3bb 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -36,7 +36,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: Partial = {}; +let myPersonalDetails: OnyxPersonalDetails | Record = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { From 6ce19e4a4aca1d0a1f08d6b5d23c6242aa985cf6 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Wed, 15 Nov 2023 11:33:04 +0100 Subject: [PATCH 10/28] Changes after review. --- src/libs/actions/User.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 6290275ed3bb..4e417192e751 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -16,6 +16,7 @@ import type Login from '@src/types/onyx/Login'; import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; import ReportAction from '@src/types/onyx/ReportAction'; +import {OnyxEntry} from "react-native-onyx/lib/types"; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; @@ -447,7 +448,7 @@ function validateSecondaryLogin(contactMethod: string, validateCode: string) { * and if so whether the expiresAt date of a user's ban is before right now * */ -function isBlockedFromConcierge(blockedFromConciergeNVP: BlockedFromConciergeNVP): boolean { +function isBlockedFromConcierge(blockedFromConciergeNVP: OnyxEntry): boolean { if (!blockedFromConciergeNVP || Object.keys(blockedFromConciergeNVP).length === 0) { return false; } From 4edce16177063d54aab7ce219bc31931ce73cd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=27fvlvte=27=20Fa=C5=82at?= Date: Mon, 27 Nov 2023 10:32:51 +0100 Subject: [PATCH 11/28] Prettier fix. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 4e417192e751..a75975e07ebe 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -1,5 +1,6 @@ import {isBefore} from 'date-fns'; import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; +import {OnyxEntry} from 'react-native-onyx/lib/types'; import {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import * as ErrorUtils from '@libs/ErrorUtils'; @@ -16,7 +17,6 @@ import type Login from '@src/types/onyx/Login'; import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; import ReportAction from '@src/types/onyx/ReportAction'; -import {OnyxEntry} from "react-native-onyx/lib/types"; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; From 5781a6a152c3fb2eb62d5def9fed80ab7f001898 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Tue, 12 Dec 2023 01:22:53 +0100 Subject: [PATCH 12/28] Requested changes + custom status handling fix. --- src/libs/ReportActionsUtils.ts | 2 +- src/libs/SidebarUtils.ts | 2 +- src/libs/actions/User.ts | 78 +++++++++++++++++++------------ src/types/onyx/PersonalDetails.ts | 5 +- 4 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 6ddc2ac99e06..69e9ead46ab5 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -643,7 +643,7 @@ function isReportActionAttachment(reportAction: OnyxEntry): boolea } // eslint-disable-next-line rulesdir/no-negated-variables -function isNotifiableReportAction(reportAction: OnyxEntry): boolean { +function isNotifiableReportAction(reportAction: OnyxEntry): reportAction is ReportAction { if (!reportAction) { return false; } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 9a1db07ca683..17461395e30e 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -438,7 +438,7 @@ function getOptionData( result.displayNamesWithTooltips = displayNamesWithTooltips; if (status) { - result.status = status; + result.status = status.text; } result.type = report.type; diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index a75975e07ebe..5ae26f532499 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -15,8 +15,9 @@ import ROUTES from '@src/ROUTES'; import type {FrequentlyUsedEmoji} from '@src/types/onyx'; import type Login from '@src/types/onyx/Login'; import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; -import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; +import OnyxPersonalDetails, {CustomStatus} from '@src/types/onyx/PersonalDetails'; import ReportAction from '@src/types/onyx/ReportAction'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; @@ -24,7 +25,6 @@ import * as Report from './Report'; import * as Session from './Session'; import redirectToSignIn from './SignInRedirect'; -type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; type BlockedFromConciergeNVP = {expiresAt: number}; let currentUserAccountID = -1; @@ -58,10 +58,6 @@ function closeAccount(message: string) { // Note: successData does not need to set isLoading to false because if the CloseAccount // command succeeds, a Pusher response will clear all Onyx data. - type CloseAccountParams = {message: string}; - - const parameters: CloseAccountParams = {message}; - const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -77,7 +73,9 @@ function closeAccount(message: string) { }, ]; - API.write('CloseAccount', parameters, { + type CloseAccountParams = {message: string}; + + API.write('CloseAccount', {message} as CloseAccountParams, { optimisticData, failureData, }); @@ -160,10 +158,6 @@ function requestContactMethodValidateCode(contactMethod: string) { * Sets whether the user is subscribed to Expensify news */ function updateNewsletterSubscription(isSubscribed: boolean) { - type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; - - const parameters: UpdateNewsletterSubscriptionParams = {isSubscribed}; - const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -179,7 +173,9 @@ function updateNewsletterSubscription(isSubscribed: boolean) { }, ]; - API.write('UpdateNewsletterSubscription', parameters, { + type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; + + API.write('UpdateNewsletterSubscription', {isSubscribed} as UpdateNewsletterSubscriptionParams, { optimisticData, failureData, }); @@ -449,11 +445,11 @@ function validateSecondaryLogin(contactMethod: string, validateCode: string) { * */ function isBlockedFromConcierge(blockedFromConciergeNVP: OnyxEntry): boolean { - if (!blockedFromConciergeNVP || Object.keys(blockedFromConciergeNVP).length === 0) { + if (isEmptyObject(blockedFromConciergeNVP)) { return false; } - if (!blockedFromConciergeNVP.expiresAt) { + if (!blockedFromConciergeNVP?.expiresAt) { return false; } @@ -469,8 +465,7 @@ function triggerNotifications(onyxUpdates: OnyxServerUpdate[]) { const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); const reportActions = Object.values((update.value as OnyxCollection) ?? {}); - const actions = reportActions.filter((action) => ReportActionsUtils.isNotifiableReportAction(action)) as ReportAction[]; - actions.forEach((action) => Report.showReportActionNotification(reportID, action)); + reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action)); }); } @@ -525,8 +520,9 @@ function subscribeToUserEvents() { return; } - const onyxUpdatePromise = Onyx.update(pushJSON); - triggerNotifications(pushJSON); + const onyxUpdatePromise = Onyx.update(pushJSON).then(() => { + triggerNotifications(pushJSON); + }); // Return a promise when Onyx is done updating so that the OnyxUpdatesManager can properly apply all // the onyx updates in order @@ -576,8 +572,11 @@ function updateFrequentlyUsedEmojis(frequentlyUsedEmojis: FrequentlyUsedEmoji[]) /** * Sync user chat priority mode with Onyx and Server + * @param mode + * @param [automatic] if we changed the mode automatically */ -function updateChatPriorityMode(mode: ValueOf) { +function updateChatPriorityMode(mode: ValueOf, automatic = false) { + const autoSwitchedToFocusMode = mode === CONST.PRIORITY_MODE.GSD && automatic; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -586,16 +585,33 @@ function updateChatPriorityMode(mode: ValueOf) { }, ]; + if (autoSwitchedToFocusMode) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_TRY_FOCUS_MODE, + value: true, + }); + } + type UpdateChatPriorityModeParams = { - value: string; + value: ValueOf; + automatic: boolean; }; const parameters: UpdateChatPriorityModeParams = { value: mode, + automatic, }; API.write('UpdateChatPriorityMode', parameters, {optimisticData}); - Navigation.goBack(ROUTES.SETTINGS_PREFERENCES); + + if (!autoSwitchedToFocusMode) { + Navigation.goBack(ROUTES.SETTINGS_PREFERENCES); + } +} + +function clearFocusModeNotification() { + Onyx.set(ONYXKEYS.FOCUS_MODE_NOTIFICATION, false); } function setShouldUseStagingServer(shouldUseStagingServer: boolean) { @@ -655,15 +671,14 @@ function generateStatementPDF(period: string) { }, }, ]; - API.read( - 'GetStatementPDF', - {period}, - { - optimisticData, - successData, - failureData, - }, - ); + + type GetStatementPDFParams = {period: string}; + + API.read('GetStatementPDF', {period} as GetStatementPDFParams, { + optimisticData, + successData, + failureData, + }); } /** @@ -796,7 +811,7 @@ function updateCustomStatus(status: CustomStatus) { key: ONYXKEYS.PERSONAL_DETAILS_LIST, value: { [currentUserAccountID]: { - status: status.text, + status, }, }, }, @@ -854,6 +869,7 @@ function clearDraftCustomStatus() { } export { + clearFocusModeNotification, closeAccount, resendValidateCode, requestContactMethodValidateCode, diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts index 049a32a80874..b6e33358098a 100644 --- a/src/types/onyx/PersonalDetails.ts +++ b/src/types/onyx/PersonalDetails.ts @@ -11,6 +11,7 @@ type Timezone = { /** Whether timezone is automatically set */ automatic?: boolean; }; +type CustomStatus = {text: string; emojiCode: string; clearAfter?: string}; type PersonalDetails = { /** ID of the current user from their personal details */ @@ -70,9 +71,9 @@ type PersonalDetails = { fallbackIcon?: string; /** Status of the current user from their personal details */ - status?: string; + status?: CustomStatus; }; export default PersonalDetails; -export type {Timezone, SelectedTimezone}; +export type {Timezone, SelectedTimezone, CustomStatus}; From 3e5ac80bd1f8f5ecd691505b09fba7ea592f6f81 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Thu, 14 Dec 2023 12:29:16 +0100 Subject: [PATCH 13/28] Solved errors. --- src/libs/actions/Report.ts | 2 +- src/types/onyx/CustomStatusDraft.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index bea4ab8aed77..fd704adcf46a 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -1809,7 +1809,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi // Only show notifications for supported types of report actions if (!ReportActionsUtils.isNotifiableReportAction(action)) { - Log.info(`${tag} No notification because this action type is not supported`, false, {actionName: action?.actionName}); + Log.info(`${tag} No notification because this action type is not supported`, false, {}); return false; } diff --git a/src/types/onyx/CustomStatusDraft.ts b/src/types/onyx/CustomStatusDraft.ts index b2801a1d89e0..4ea685b40cb5 100644 --- a/src/types/onyx/CustomStatusDraft.ts +++ b/src/types/onyx/CustomStatusDraft.ts @@ -7,6 +7,8 @@ type CustomStatusDraft = { /** ISO 8601 format string, which represents the time when the status should be cleared */ clearAfter: string; + + customDateTemporary: string; }; export default CustomStatusDraft; From 7b8f2d02a099531076409c52924403b5bab4acf6 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Fri, 15 Dec 2023 10:21:25 +0100 Subject: [PATCH 14/28] Requested changes. --- src/libs/actions/User.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 2c5871d7d45d..651212a17af9 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -75,7 +75,9 @@ function closeAccount(message: string) { type CloseAccountParams = {message: string}; - API.write('CloseAccount', {message} as CloseAccountParams, { + const parameters: CloseAccountParams = {message}; + + API.write('CloseAccount', parameters, { optimisticData, failureData, }); @@ -175,7 +177,9 @@ function updateNewsletterSubscription(isSubscribed: boolean) { type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; - API.write('UpdateNewsletterSubscription', {isSubscribed} as UpdateNewsletterSubscriptionParams, { + const parameters: UpdateNewsletterSubscriptionParams = {isSubscribed}; + + API.write('UpdateNewsletterSubscription', parameters, { optimisticData, failureData, }); @@ -674,7 +678,9 @@ function generateStatementPDF(period: string) { type GetStatementPDFParams = {period: string}; - API.read('GetStatementPDF', {period} as GetStatementPDFParams, { + const parameters: GetStatementPDFParams = {period}; + + API.read('GetStatementPDF', parameters, { optimisticData, successData, failureData, From ca9c880fdae3c0cf6795eac2d748f1e82f6c5908 Mon Sep 17 00:00:00 2001 From: Kacper Falat Date: Fri, 15 Dec 2023 10:28:49 +0100 Subject: [PATCH 15/28] Migrated changes from main. --- src/libs/actions/User.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 651212a17af9..a12b06152979 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -23,7 +23,6 @@ import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; import * as Report from './Report'; import * as Session from './Session'; -import redirectToSignIn from './SignInRedirect'; type BlockedFromConciergeNVP = {expiresAt: number}; @@ -81,8 +80,6 @@ function closeAccount(message: string) { optimisticData, failureData, }); - // Run cleanup actions to prevent reconnection callbacks from blocking logging in again - redirectToSignIn(); } /** From bb27db19ab118951be25125d29b4d2139f6e13bf Mon Sep 17 00:00:00 2001 From: fvlvte Date: Thu, 28 Dec 2023 12:54:03 +0100 Subject: [PATCH 16/28] Aligned to Onyx types. --- src/libs/actions/User.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 9f67087dba6a..fa106e2f9c37 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -36,7 +36,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: OnyxPersonalDetails | Record = {}; +let myPersonalDetails: OnyxPersonalDetails | Record | null = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { @@ -537,7 +537,7 @@ function subscribeToUserEvents() { /** * Sync preferredSkinTone with Onyx and Server */ -function updatePreferredSkinTone(skinTone: string) { +function updatePreferredSkinTone(skinTone: number) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.SET, @@ -547,7 +547,7 @@ function updatePreferredSkinTone(skinTone: string) { ]; type UpdatePreferredEmojiSkinToneParams = { - value: string; + value: number; }; const parameters: UpdatePreferredEmojiSkinToneParams = {value: skinTone}; From 1fbc2525c54522a8afa940e31979fb972f3fccb1 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Thu, 28 Dec 2023 12:59:05 +0100 Subject: [PATCH 17/28] Requested change. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index fa106e2f9c37..ff3d5d00a6eb 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -36,7 +36,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: OnyxPersonalDetails | Record | null = {}; +let myPersonalDetails: OnyxEntry | Record = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { From dec956168cb23367393c3ce555fb475cbdfa1e76 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 10:22:10 +0100 Subject: [PATCH 18/28] Applied incoming status type changes. --- src/libs/actions/User.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index ff3d5d00a6eb..f467b6864a61 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -15,7 +15,7 @@ import ROUTES from '@src/ROUTES'; import type {FrequentlyUsedEmoji} from '@src/types/onyx'; import type Login from '@src/types/onyx/Login'; import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; -import OnyxPersonalDetails, {CustomStatus} from '@src/types/onyx/PersonalDetails'; +import OnyxPersonalDetails, {Status} from '@src/types/onyx/PersonalDetails'; import ReportAction from '@src/types/onyx/ReportAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; @@ -809,7 +809,7 @@ function updateTheme(theme: ValueOf) { /** * Sets a custom status */ -function updateCustomStatus(status: CustomStatus) { +function updateCustomStatus(status: Status) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -823,7 +823,7 @@ function updateCustomStatus(status: CustomStatus) { ]; type UpdateStatusParams = { - text: string; + text?: string; emojiCode: string; clearAfter?: string; }; @@ -862,7 +862,7 @@ function clearCustomStatus() { * @param status.emojiCode * @param status.clearAfter - ISO 8601 format string, which represents the time when the status should be cleared */ -function updateDraftCustomStatus(status: CustomStatus) { +function updateDraftCustomStatus(status: Status) { Onyx.merge(ONYXKEYS.CUSTOM_STATUS_DRAFT, status); } From 686becc1cce72e995ce8c0a5451900dc25b1bd74 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 10:25:35 +0100 Subject: [PATCH 19/28] Fixed types. --- src/libs/SidebarUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 8bee1f7d9a81..c4fad1a86906 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -447,7 +447,7 @@ function getOptionData( result.displayNamesWithTooltips = displayNamesWithTooltips; if (status) { - result.status = status.text; + result.status = status; } result.type = report.type; From f857350b08e36c5b17ec83f064dde7e148524b45 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 12:11:45 +0100 Subject: [PATCH 20/28] Removed redundant field. --- src/libs/actions/User.ts | 2 +- src/types/onyx/CustomStatusDraft.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index f467b6864a61..2253321a6634 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -870,7 +870,7 @@ function updateDraftCustomStatus(status: Status) { * Clear the custom draft status */ function clearDraftCustomStatus() { - Onyx.merge(ONYXKEYS.CUSTOM_STATUS_DRAFT, {text: '', emojiCode: '', clearAfter: '', customDateTemporary: ''}); + Onyx.merge(ONYXKEYS.CUSTOM_STATUS_DRAFT, {text: '', emojiCode: '', clearAfter: ''}); } export { diff --git a/src/types/onyx/CustomStatusDraft.ts b/src/types/onyx/CustomStatusDraft.ts index 4ea685b40cb5..b2801a1d89e0 100644 --- a/src/types/onyx/CustomStatusDraft.ts +++ b/src/types/onyx/CustomStatusDraft.ts @@ -7,8 +7,6 @@ type CustomStatusDraft = { /** ISO 8601 format string, which represents the time when the status should be cleared */ clearAfter: string; - - customDateTemporary: string; }; export default CustomStatusDraft; From 2edfcca74898549ac419848cf7a9fd7d80ab27cd Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 12:24:16 +0100 Subject: [PATCH 21/28] Rolled back log changes. --- src/libs/ReportActionsUtils.ts | 2 +- src/libs/actions/Report.ts | 2 +- src/libs/actions/User.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 46717cfd816d..4847eee2c8c6 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -663,7 +663,7 @@ function isReportActionAttachment(reportAction: OnyxEntry): boolea } // eslint-disable-next-line rulesdir/no-negated-variables -function isNotifiableReportAction(reportAction: OnyxEntry): reportAction is ReportAction { +function isNotifiableReportAction(reportAction: OnyxEntry): boolean { if (!reportAction) { return false; } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 4b2f86b26aad..ef24b64ce7c7 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -1825,7 +1825,7 @@ function shouldShowReportActionNotification(reportID: string, action: ReportActi // Only show notifications for supported types of report actions if (!ReportActionsUtils.isNotifiableReportAction(action)) { - Log.info(`${tag} No notification because this action type is not supported`, false, {}); + Log.info(`${tag} No notification because this action type is not supported`, false, {actionName: action?.actionName}); return false; } diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 2253321a6634..0c4d78a1cec4 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -468,7 +468,7 @@ function triggerNotifications(onyxUpdates: OnyxServerUpdate[]) { const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); const reportActions = Object.values((update.value as OnyxCollection) ?? {}); - reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action)); + reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action as ReportAction)); }); } From e4371bc54789b97fe673b96d528eace0c25a043e Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 12:30:05 +0100 Subject: [PATCH 22/28] Linter fixed. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 0c4d78a1cec4..10716d98e1e4 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -468,7 +468,7 @@ function triggerNotifications(onyxUpdates: OnyxServerUpdate[]) { const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); const reportActions = Object.values((update.value as OnyxCollection) ?? {}); - reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action as ReportAction)); + reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action!)); }); } From b0ad8357b423a64447b5b8f2dd7290ae68328e51 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 2 Jan 2024 12:34:50 +0100 Subject: [PATCH 23/28] Moved assertion. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 10716d98e1e4..9418ba0a9cb6 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -468,7 +468,7 @@ function triggerNotifications(onyxUpdates: OnyxServerUpdate[]) { const reportID = update.key.replace(ONYXKEYS.COLLECTION.REPORT_ACTIONS, ''); const reportActions = Object.values((update.value as OnyxCollection) ?? {}); - reportActions.forEach((action) => ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action!)); + reportActions.forEach((action) => action && ReportActionsUtils.isNotifiableReportAction(action) && Report.showReportActionNotification(reportID, action)); }); } From a5ba1a369faf3b0f7019bf76d98e745b13294afa Mon Sep 17 00:00:00 2001 From: fvlvte Date: Wed, 3 Jan 2024 10:52:33 +0100 Subject: [PATCH 24/28] Requested changes. --- src/libs/actions/User.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 9418ba0a9cb6..0b340e69add9 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -14,10 +14,11 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {FrequentlyUsedEmoji} from '@src/types/onyx'; import type Login from '@src/types/onyx/Login'; -import {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; -import OnyxPersonalDetails, {Status} from '@src/types/onyx/PersonalDetails'; -import ReportAction from '@src/types/onyx/ReportAction'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import type { OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; +import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; +import type { Status } from '@src/types/onyx/PersonalDetails'; +import type ReportAction from '@src/types/onyx/ReportAction'; +import {EmptyObject, isEmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; @@ -36,7 +37,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: OnyxEntry | Record = {}; +let myPersonalDetails: OnyxEntry | EmptyObject = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { @@ -49,11 +50,9 @@ Onyx.connect({ }); /** - * Attempt to close the user's account - * - * @param message optional reason for closing account + * Attempt to close the user's accountt */ -function closeAccount(message: string) { +function closeAccount(reason: string) { // Note: successData does not need to set isLoading to false because if the CloseAccount // command succeeds, a Pusher response will clear all Onyx data. @@ -74,7 +73,7 @@ function closeAccount(message: string) { type CloseAccountParams = {message: string}; - const parameters: CloseAccountParams = {message}; + const parameters: CloseAccountParams = {message: reason}; API.write('CloseAccount', parameters, { optimisticData, @@ -360,9 +359,6 @@ function validateLogin(accountID: number, validateCode: string) { /** * Validates a secondary login / contact method - * - * @param contactMethod - The contact method the user is trying to verify - * @param validateCode */ function validateSecondaryLogin(contactMethod: string, validateCode: string) { const optimisticData: OnyxUpdate[] = [ From 528f188a9712388e621aa5f8af109b426c682526 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Wed, 3 Jan 2024 10:54:54 +0100 Subject: [PATCH 25/28] Prettier & linter. --- src/libs/actions/User.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 0b340e69add9..98437167a338 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -14,9 +14,9 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {FrequentlyUsedEmoji} from '@src/types/onyx'; import type Login from '@src/types/onyx/Login'; -import type { OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; +import type {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; -import type { Status } from '@src/types/onyx/PersonalDetails'; +import type {Status} from '@src/types/onyx/PersonalDetails'; import type ReportAction from '@src/types/onyx/ReportAction'; import {EmptyObject, isEmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; From 079aa5c01d00bc9c1e6b4d66c48ceab6a65be174 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Wed, 3 Jan 2024 10:58:34 +0100 Subject: [PATCH 26/28] Added type to EmptyObject. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 98437167a338..931b621657c4 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -18,7 +18,7 @@ import type {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; import type {Status} from '@src/types/onyx/PersonalDetails'; import type ReportAction from '@src/types/onyx/ReportAction'; -import {EmptyObject, isEmptyObject} from '@src/types/utils/EmptyObject'; +import {type EmptyObject, isEmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; From e55a34c171d6fc7c1382f4c26ee970375ab7caa6 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Thu, 4 Jan 2024 09:55:02 +0100 Subject: [PATCH 27/28] Linter fixes. --- src/libs/actions/User.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 931b621657c4..896cad2aa51e 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -1,7 +1,8 @@ import {isBefore} from 'date-fns'; -import Onyx, {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; -import {OnyxEntry} from 'react-native-onyx/lib/types'; -import {ValueOf} from 'type-fest'; +import type {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx/lib/types'; +import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -18,7 +19,8 @@ import type {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; import type {Status} from '@src/types/onyx/PersonalDetails'; import type ReportAction from '@src/types/onyx/ReportAction'; -import {type EmptyObject, isEmptyObject} from '@src/types/utils/EmptyObject'; +import { isEmptyObject} from '@src/types/utils/EmptyObject'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; From 59890903c47f69a4513c656faa0d00ac216f6ec2 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Thu, 4 Jan 2024 10:01:40 +0100 Subject: [PATCH 28/28] Applied prettier. --- src/libs/actions/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 896cad2aa51e..8da451f9d64d 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -19,7 +19,7 @@ import type {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer'; import type OnyxPersonalDetails from '@src/types/onyx/PersonalDetails'; import type {Status} from '@src/types/onyx/PersonalDetails'; import type ReportAction from '@src/types/onyx/ReportAction'; -import { isEmptyObject} from '@src/types/utils/EmptyObject'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; import * as OnyxUpdates from './OnyxUpdates';