From 55d26142fb4176fcfc5df5bb873f0ea714b57052 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Thu, 16 Nov 2023 17:33:45 +0100 Subject: [PATCH 01/17] Fix green line being displayed chaotically in chat --- src/pages/home/report/ReportActionsList.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index dd537959c91f..00da92270455 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -338,8 +338,9 @@ function ReportActionsList({ const nextMessage = sortedReportActions[index + 1]; const isCurrentMessageUnread = isMessageUnread(reportAction, lastReadTimeRef.current); shouldDisplay = isCurrentMessageUnread && (!nextMessage || !isMessageUnread(nextMessage, lastReadTimeRef.current)); - if (!messageManuallyMarkedUnread) { - shouldDisplay = shouldDisplay && reportAction.actorAccountID !== Report.getCurrentUserAccountID(); + if (shouldDisplay && !messageManuallyMarkedUnread) { + const isWithinVisibleThreshold = scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD ? reportAction.created < userActiveSince.current : true; + shouldDisplay = reportAction.actorAccountID !== Report.getCurrentUserAccountID() && isWithinVisibleThreshold; } if (shouldDisplay) { cacheUnreadMarkers.set(report.reportID, reportAction.reportActionID); From 4ec4bc5e1ec4b31296b491250a886a6f83787544 Mon Sep 17 00:00:00 2001 From: OlimpiaZurek Date: Thu, 9 Nov 2023 09:54:38 +0100 Subject: [PATCH 02/17] add perf tests for ReportActionsUtils --- .../perf-test/ReportActionsUtils.perf-test.ts | 175 ++++++++++++++++++ tests/perf-test/ReportScreen.perf-test.js | 4 +- tests/utils/ReportTestUtils.js | 6 +- 3 files changed, 180 insertions(+), 5 deletions(-) create mode 100644 tests/perf-test/ReportActionsUtils.perf-test.ts diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts new file mode 100644 index 000000000000..c9c31f8ad98e --- /dev/null +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -0,0 +1,175 @@ +import Onyx from 'react-native-onyx'; +import {measureFunction} from 'reassure'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ReportAction, {ReportActions} from '@src/types/onyx/ReportAction'; +import * as LHNTestUtils from '../utils/LHNTestUtils'; +import * as ReportTestUtils from '../utils/ReportTestUtils'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; + +jest.setTimeout(60000); + +beforeAll(() => + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + }), +); + +// Clear out Onyx after each test so that each test starts with a clean slate +afterEach(() => { + Onyx.clear(); +}); + +const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = 100) => { + const mockReportActions = Array.from({length: actionsPerReportLength}, (v, i) => { + const reportActionKey = i + 1; + const email = `actor+${reportActionKey}@mail.com`; + const reportAction = LHNTestUtils.getFakeReportAction(email); + + return {[reportActionKey]: reportAction}; + }); + + const reportKeysMap = Array.from({length: reportsLength}, (v, i) => { + const key = i + 1; + + return {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${key}`]: Object.assign({}, ...mockReportActions)}; + }); + + return Object.assign({}, ...reportKeysMap) as Partial; +}; + +const mockedReportActionsMap = getMockedReportActionsMap(2, 10000); +const reportId = '1'; + +/** + * This function will be executed 20 times and the average time will be used on the comparison. + * It will fail based on the CI configuration around Reassure: + * @see /.github/workflows/reassurePerformanceTests.yml + * + * Max deviation on the duration is set to 20% at the time of writing. + * + * More on the measureFunction API: + * @see https://callstack.github.io/reassure/docs/api#measurefunction-function + */ +test('getLastVisibleAction on 10k reportActions', async () => { + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs: 20}); +}); + +test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { + const parentReportActionId = '1'; + const fakeParentAction = ReportTestUtils.getMockedReportActionsMap()[parentReportActionId]; + const actionsToMerge = { + [parentReportActionId]: { + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + previousMessage: fakeParentAction.message, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: '', + text: '', + isEdited: true, + isDeletedParentAction: true, + }, + ], + errors: null, + linkMetaData: [], + }, + } as unknown as ReportActions; + + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs: 20}); +}); + +test('getSortedReportActions on 10k ReportActions', async () => { + const reportActionsArray = ReportTestUtils.getMockedSortedReportActions() as unknown as ReportAction[]; + + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getSortedReportActions(reportActionsArray), {runs: 20}); +}); + +test('getMostRecentIOURequestActionID on 10k ReportActions', async () => { + const reportActionsArray = (length = 100) => Array.from({length}, (__, i) => ReportTestUtils.getFakeReportAction(i, 'IOU')) as unknown as ReportAction[]; + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray()), {runs: 20}); +}); + +test('getLastVisibleMessage on 10k ReportActions', async () => { + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs: 20}); +}); + +test('getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { + const parentReportActionId = '1'; + const fakeParentAction = ReportTestUtils.getMockedReportActionsMap()[parentReportActionId]; + const actionsToMerge = { + [parentReportActionId]: { + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + previousMessage: fakeParentAction.message, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: '', + text: '', + isEdited: true, + isDeletedParentAction: true, + }, + ], + errors: null, + linkMetaData: [], + }, + } as unknown as ReportActions; + + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs: 20}); +}); + +test('getSortedReportActionsForDisplay on 10k ReportActions', async () => { + const reportActions = ReportTestUtils.getMockedReportActionsMap(); + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs: 20}); +}); + +test('getLastClosedReportAction on 10k ReportActions', async () => { + const reportActions = ReportTestUtils.getMockedReportActionsMap(); + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs: 20}); +}); + +test('getMostRecentReportActionLastModified', async () => { + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs: 20}); +}); + diff --git a/tests/perf-test/ReportScreen.perf-test.js b/tests/perf-test/ReportScreen.perf-test.js index 20af5603d177..b901888bba0f 100644 --- a/tests/perf-test/ReportScreen.perf-test.js +++ b/tests/perf-test/ReportScreen.perf-test.js @@ -155,7 +155,7 @@ test('should render ReportScreen with composer interactions', () => { }; const report = LHNTestUtils.getFakeReport(); - const reportActions = ReportTestUtils.getMockedReportsMap(1000); + const reportActions = ReportTestUtils.getMockedReportActionsMap(1000); const mockRoute = {params: {reportID: '1'}}; return waitForBatchedUpdates() @@ -198,7 +198,7 @@ test('should press of the report item', () => { }; const report = LHNTestUtils.getFakeReport(); - const reportActions = ReportTestUtils.getMockedReportsMap(1000); + const reportActions = ReportTestUtils.getMockedReportActionsMap(1000); const mockRoute = {params: {reportID: '2'}}; return waitForBatchedUpdates() diff --git a/tests/utils/ReportTestUtils.js b/tests/utils/ReportTestUtils.js index 48e5ebfaa56d..10edd0ea0576 100644 --- a/tests/utils/ReportTestUtils.js +++ b/tests/utils/ReportTestUtils.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -const actionNames = ['ADDCOMMENT', 'IOU', 'REPORTPREVIEW']; +const actionNames = ['ADDCOMMENT', 'IOU', 'REPORTPREVIEW', "CLOSED"]; const getFakeReportAction = (index, actionName) => ({ actionName, @@ -47,7 +47,7 @@ const getFakeReportAction = (index, actionName) => ({ const getMockedSortedReportActions = (length = 100) => Array.from({length}, (__, i) => getFakeReportAction(i)); -const getMockedReportsMap = (length = 100) => { +const getMockedReportActionsMap = (length = 100) => { const mockReports = Array.from({length}, (__, i) => { const reportID = i + 1; const actionName = i === 0 ? 'CREATED' : actionNames[i % actionNames.length]; @@ -58,4 +58,4 @@ const getMockedReportsMap = (length = 100) => { return _.assign({}, ...mockReports); }; -export {getFakeReportAction, getMockedSortedReportActions, getMockedReportsMap}; +export {getFakeReportAction, getMockedSortedReportActions, getMockedReportActionsMap}; From c6e6e04f1ad3410264d1395a76a710a588e30c66 Mon Sep 17 00:00:00 2001 From: OlimpiaZurek Date: Wed, 15 Nov 2023 10:33:14 +0100 Subject: [PATCH 03/17] add new mocks --- .../perf-test/ReportActionsUtils.perf-test.ts | 34 ++++----- tests/utils/ReportTestUtils.js | 2 +- tests/utils/collections/reportActions.ts | 72 +++++++++++++++++++ 3 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 tests/utils/collections/reportActions.ts diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index c9c31f8ad98e..36b99b789eb0 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -4,8 +4,8 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ReportAction, {ReportActions} from '@src/types/onyx/ReportAction'; -import * as LHNTestUtils from '../utils/LHNTestUtils'; -import * as ReportTestUtils from '../utils/ReportTestUtils'; +import createCollection from '../utils/collections/createCollection'; +import createRandomReportAction from '../utils/collections/reportActions'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; jest.setTimeout(60000); @@ -25,8 +25,7 @@ afterEach(() => { const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = 100) => { const mockReportActions = Array.from({length: actionsPerReportLength}, (v, i) => { const reportActionKey = i + 1; - const email = `actor+${reportActionKey}@mail.com`; - const reportAction = LHNTestUtils.getFakeReportAction(email); + const reportAction = createRandomReportAction(reportActionKey); return {[reportActionKey]: reportAction}; }); @@ -41,6 +40,12 @@ const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = }; const mockedReportActionsMap = getMockedReportActionsMap(2, 10000); + +const reportActions = createCollection( + (item) => `${item.reportActionID}`, + (index) => createRandomReportAction(index), +); + const reportId = '1'; /** @@ -64,7 +69,7 @@ test('getLastVisibleAction on 10k reportActions', async () => { test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { const parentReportActionId = '1'; - const fakeParentAction = ReportTestUtils.getMockedReportActionsMap()[parentReportActionId]; + const fakeParentAction = reportActions[parentReportActionId]; const actionsToMerge = { [parentReportActionId]: { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, @@ -91,23 +96,13 @@ test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () = await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs: 20}); }); -test('getSortedReportActions on 10k ReportActions', async () => { - const reportActionsArray = ReportTestUtils.getMockedSortedReportActions() as unknown as ReportAction[]; - - await Onyx.multiSet({ - ...mockedReportActionsMap, - }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActions(reportActionsArray), {runs: 20}); -}); - test('getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = (length = 100) => Array.from({length}, (__, i) => ReportTestUtils.getFakeReportAction(i, 'IOU')) as unknown as ReportAction[]; + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions); await Onyx.multiSet({ ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray()), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs: 20}); }); test('getLastVisibleMessage on 10k ReportActions', async () => { @@ -120,7 +115,7 @@ test('getLastVisibleMessage on 10k ReportActions', async () => { test('getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { const parentReportActionId = '1'; - const fakeParentAction = ReportTestUtils.getMockedReportActionsMap()[parentReportActionId]; + const fakeParentAction = reportActions[parentReportActionId]; const actionsToMerge = { [parentReportActionId]: { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, @@ -148,7 +143,6 @@ test('getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () }); test('getSortedReportActionsForDisplay on 10k ReportActions', async () => { - const reportActions = ReportTestUtils.getMockedReportActionsMap(); await Onyx.multiSet({ ...mockedReportActionsMap, }); @@ -157,7 +151,6 @@ test('getSortedReportActionsForDisplay on 10k ReportActions', async () => { }); test('getLastClosedReportAction on 10k ReportActions', async () => { - const reportActions = ReportTestUtils.getMockedReportActionsMap(); await Onyx.multiSet({ ...mockedReportActionsMap, }); @@ -172,4 +165,3 @@ test('getMostRecentReportActionLastModified', async () => { await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs: 20}); }); - diff --git a/tests/utils/ReportTestUtils.js b/tests/utils/ReportTestUtils.js index 10edd0ea0576..910f2200876b 100644 --- a/tests/utils/ReportTestUtils.js +++ b/tests/utils/ReportTestUtils.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -const actionNames = ['ADDCOMMENT', 'IOU', 'REPORTPREVIEW', "CLOSED"]; +const actionNames = ['ADDCOMMENT', 'IOU', 'REPORTPREVIEW', 'CLOSED']; const getFakeReportAction = (index, actionName) => ({ actionName, diff --git a/tests/utils/collections/reportActions.ts b/tests/utils/collections/reportActions.ts new file mode 100644 index 000000000000..abc83eb82abe --- /dev/null +++ b/tests/utils/collections/reportActions.ts @@ -0,0 +1,72 @@ +import {rand, randAggregation, randBoolean, randPastDate, randWord} from '@ngneat/falso'; +import CONST from '@src/CONST'; +import {ReportAction} from '@src/types/onyx'; + +type ActionType = keyof typeof CONST.REPORT.ACTIONS.TYPE; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const flattenActionNamesValues = (actionNames: any) => { + let result = [] as ActionType[]; + Object.keys(actionNames).forEach((key) => { + if (typeof actionNames[key] === 'object') { + result = result.concat(flattenActionNamesValues(actionNames[key])); + } else { + result.push(actionNames[key]); + } + }); + return result; +}; + +export default function createRandomReportAction(index: number): ReportAction { + return { + // we need to add any here because of the way we are generating random values + // eslint-disable-next-line @typescript-eslint/no-explicit-any + actionName: rand(flattenActionNamesValues(CONST.REPORT.ACTIONS.TYPE)) as any, + reportActionID: index.toString(), + previousReportActionID: index.toString(), + actorAccountID: index, + person: [ + { + type: randWord(), + style: randWord(), + text: randWord(), + }, + ], + created: randPastDate().toISOString(), + message: [ + { + type: randWord(), + html: randWord(), + style: randWord(), + text: randWord(), + isEdited: randBoolean(), + isDeletedParentAction: randBoolean(), + whisperedTo: randAggregation(), + reactions: [ + { + emoji: randWord(), + users: [ + { + accountID: index, + skinTone: index, + }, + ], + }, + ], + }, + ], + originalMessage: { + html: randWord(), + type: rand(Object.values(CONST.IOU.REPORT_ACTION_TYPE)), + }, + whisperedToAccountIDs: randAggregation(), + avatar: randWord(), + automatic: randBoolean(), + shouldShow: randBoolean(), + lastModified: randPastDate().toISOString(), + pendingAction: rand(Object.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)), + delegateAccountID: index.toString(), + errors: {}, + isAttachment: randBoolean(), + }; +} From 243396af3879522cfd27858741a2a0941f9d47df Mon Sep 17 00:00:00 2001 From: Github Date: Mon, 27 Nov 2023 10:42:29 +0100 Subject: [PATCH 04/17] add timeouts and runs improvements --- .../perf-test/ReportActionsUtils.perf-test.js | 91 ------------------- .../perf-test/ReportActionsUtils.perf-test.ts | 20 ++-- 2 files changed, 10 insertions(+), 101 deletions(-) delete mode 100644 tests/perf-test/ReportActionsUtils.perf-test.js diff --git a/tests/perf-test/ReportActionsUtils.perf-test.js b/tests/perf-test/ReportActionsUtils.perf-test.js deleted file mode 100644 index 8e9f5570d5d8..000000000000 --- a/tests/perf-test/ReportActionsUtils.perf-test.js +++ /dev/null @@ -1,91 +0,0 @@ -import Onyx from 'react-native-onyx'; -import {measureFunction} from 'reassure'; -import _ from 'underscore'; -import CONST from '../../src/CONST'; -import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils'; -import ONYXKEYS from '../../src/ONYXKEYS'; -import * as LHNTestUtils from '../utils/LHNTestUtils'; -import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; - -beforeAll(() => - Onyx.init({ - keys: ONYXKEYS, - safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - registerStorageEventListener: () => {}, - }), -); - -// Clear out Onyx after each test so that each test starts with a clean slate -afterEach(() => { - Onyx.clear(); -}); - -const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = 100) => { - const mockReportActions = Array.from({length: actionsPerReportLength}, (_reportAction, i) => { - const reportActionKey = i + 1; - const email = `actor+${reportActionKey}@mail.com`; - const reportAction = LHNTestUtils.getFakeReportAction(email); - - return {[reportActionKey]: reportAction}; - }); - - const reportKeysMap = Array.from({length: reportsLength}, (_report, i) => { - const key = i + 1; - - return {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${key}`]: _.assign({}, ...mockReportActions)}; - }); - - return _.assign({}, ...reportKeysMap); -}; - -const mockedReportActionsMap = getMockedReportActionsMap(2, 10000); - -/** - * This function will be executed 20 times and the average time will be used on the comparison. - * It will fail based on the CI configuration around Reassure: - * @see /.github/workflows/reassurePerformanceTests.yml - * - * Max deviation on the duration is set to 20% at the time of writing. - * - * More on the measureFunction API: - * @see https://callstack.github.io/reassure/docs/api#measurefunction-function - */ -test('getLastVisibleAction on 10k reportActions', async () => { - const reportId = '1'; - - await Onyx.multiSet({ - ...mockedReportActionsMap, - }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs: 20}); -}); - -test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { - const reportId = '1'; - const parentReportActionId = '1'; - const fakeParentAction = mockedReportActionsMap[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportId}`][parentReportActionId]; - const actionsToMerge = { - [parentReportActionId]: { - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - previousMessage: fakeParentAction.message, - message: [ - { - translationKey: '', - type: 'COMMENT', - html: '', - text: '', - isEdited: true, - isDeletedParentAction: true, - }, - ], - errors: null, - linkMetaData: [], - }, - }; - - await Onyx.multiSet({ - ...mockedReportActionsMap, - }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs: 20}); -}); diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index 36b99b789eb0..a52e75c8b75f 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -8,8 +8,6 @@ import createCollection from '../utils/collections/createCollection'; import createRandomReportAction from '../utils/collections/reportActions'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -jest.setTimeout(60000); - beforeAll(() => Onyx.init({ keys: ONYXKEYS, @@ -48,6 +46,8 @@ const reportActions = createCollection( const reportId = '1'; +const runs = CONST.PERFORMANCE_TESTS.RUNS; + /** * This function will be executed 20 times and the average time will be used on the comparison. * It will fail based on the CI configuration around Reassure: @@ -64,7 +64,7 @@ test('getLastVisibleAction on 10k reportActions', async () => { }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs}); }); test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { @@ -93,7 +93,7 @@ test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () = ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs}); }); test('getMostRecentIOURequestActionID on 10k ReportActions', async () => { @@ -102,7 +102,7 @@ test('getMostRecentIOURequestActionID on 10k ReportActions', async () => { ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs}); }); test('getLastVisibleMessage on 10k ReportActions', async () => { @@ -110,7 +110,7 @@ test('getLastVisibleMessage on 10k ReportActions', async () => { ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs}); }); test('getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { @@ -139,7 +139,7 @@ test('getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs}); }); test('getSortedReportActionsForDisplay on 10k ReportActions', async () => { @@ -147,7 +147,7 @@ test('getSortedReportActionsForDisplay on 10k ReportActions', async () => { ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs}); }); test('getLastClosedReportAction on 10k ReportActions', async () => { @@ -155,7 +155,7 @@ test('getLastClosedReportAction on 10k ReportActions', async () => { ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs}); }); test('getMostRecentReportActionLastModified', async () => { @@ -163,5 +163,5 @@ test('getMostRecentReportActionLastModified', async () => { ...mockedReportActionsMap, }); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs: 20}); + await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs}); }); From 76e50eaa63da9eaf61e79b617fdb83e2639c6c5a Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Wed, 29 Nov 2023 00:56:33 +0530 Subject: [PATCH 05/17] fix: No I cursor on text in keyboard shortcut Signed-off-by: Krishna Gupta --- src/components/FeatureList.js | 1 + src/pages/KeyboardShortcutsPage.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/FeatureList.js b/src/components/FeatureList.js index 85195864cdc3..7b0c70372579 100644 --- a/src/components/FeatureList.js +++ b/src/components/FeatureList.js @@ -42,6 +42,7 @@ function FeatureList({menuItems, headline, description}) { iconHeight={60} iconStyles={[styles.mr3, styles.ml3]} interactive={false} + wrapperStyle={[styles.cursorAuto]} /> ))} diff --git a/src/pages/KeyboardShortcutsPage.js b/src/pages/KeyboardShortcutsPage.js index fde4bf5ff3df..c44c6213d3a5 100644 --- a/src/pages/KeyboardShortcutsPage.js +++ b/src/pages/KeyboardShortcutsPage.js @@ -36,7 +36,7 @@ function KeyboardShortcutsPage() { key={shortcut.displayName} title={shortcut.displayName} description={translate(`keyboardShortcutsPage.shortcuts.${shortcut.descriptionKey}`)} - wrapperStyle={styles.ph0} + wrapperStyle={[styles.ph0, styles.cursorAuto]} interactive={false} /> ); From f85b1bd7bd208488bb4af2c7619b46d948fd83c1 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 29 Nov 2023 12:16:46 +0100 Subject: [PATCH 06/17] [TS migration] Migrate 'overscrollBehaviorContain' style to TypeScript --- .../AppNavigator/ReportScreenWrapper.tsx | 27 +++++++++++++++++++ .../overscrollBehaviorContain/index.js | 3 --- .../overscrollBehaviorContain/index.native.js | 1 - .../overscrollBehaviorContain/index.native.ts | 5 ++++ .../overscrollBehaviorContain/index.ts | 7 +++++ .../overscrollBehaviorContain/types.ts | 5 ++++ 6 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx delete mode 100644 src/styles/utilities/overscrollBehaviorContain/index.js delete mode 100644 src/styles/utilities/overscrollBehaviorContain/index.native.js create mode 100644 src/styles/utilities/overscrollBehaviorContain/index.native.ts create mode 100644 src/styles/utilities/overscrollBehaviorContain/index.ts create mode 100644 src/styles/utilities/overscrollBehaviorContain/types.ts diff --git a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx new file mode 100644 index 000000000000..4fc83ca9fb0b --- /dev/null +++ b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import ReportScreen from '@pages/home/ReportScreen'; +import ReportScreenIDSetter from './ReportScreenIDSetter'; + +type Props = { + route: any; + navigation: any; +}; + +function ReportScreenWrapper({route, navigation}: Props) { + // The ReportScreen without the reportID set will display a skeleton + // until the reportID is loaded and set in the route param + return ( + <> + {/* @ts-expect-error explanation */} + + + + ); +} + +ReportScreenWrapper.displayName = 'ReportScreenWrapper'; + +export default ReportScreenWrapper; diff --git a/src/styles/utilities/overscrollBehaviorContain/index.js b/src/styles/utilities/overscrollBehaviorContain/index.js deleted file mode 100644 index 1377e4b47d28..000000000000 --- a/src/styles/utilities/overscrollBehaviorContain/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - overscrollBehavior: 'contain', -}; diff --git a/src/styles/utilities/overscrollBehaviorContain/index.native.js b/src/styles/utilities/overscrollBehaviorContain/index.native.js deleted file mode 100644 index ff8b4c56321a..000000000000 --- a/src/styles/utilities/overscrollBehaviorContain/index.native.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/src/styles/utilities/overscrollBehaviorContain/index.native.ts b/src/styles/utilities/overscrollBehaviorContain/index.native.ts new file mode 100644 index 000000000000..fd6b2f496912 --- /dev/null +++ b/src/styles/utilities/overscrollBehaviorContain/index.native.ts @@ -0,0 +1,5 @@ +import OverscrollBehaviorStyles from './types'; + +const overscrollBehaviorContain: OverscrollBehaviorStyles = {}; + +export default overscrollBehaviorContain; diff --git a/src/styles/utilities/overscrollBehaviorContain/index.ts b/src/styles/utilities/overscrollBehaviorContain/index.ts new file mode 100644 index 000000000000..18cbe810d336 --- /dev/null +++ b/src/styles/utilities/overscrollBehaviorContain/index.ts @@ -0,0 +1,7 @@ +import OverscrollBehaviorStyles from './types'; + +const overscrollBehaviorContain: OverscrollBehaviorStyles = { + overscrollBehavior: 'contain', +}; + +export default overscrollBehaviorContain; diff --git a/src/styles/utilities/overscrollBehaviorContain/types.ts b/src/styles/utilities/overscrollBehaviorContain/types.ts new file mode 100644 index 000000000000..1e806eb60642 --- /dev/null +++ b/src/styles/utilities/overscrollBehaviorContain/types.ts @@ -0,0 +1,5 @@ +import {ViewStyle} from 'react-native'; + +type OverscrollBehaviorStyles = Pick; + +export default OverscrollBehaviorStyles; From c988129144bb9f3cdb6711c3e594efbee54f86b9 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 29 Nov 2023 12:18:31 +0100 Subject: [PATCH 07/17] Remove ReportScreenWrapper that was added by mistake --- .../AppNavigator/ReportScreenWrapper.tsx | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx diff --git a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx b/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx deleted file mode 100644 index 4fc83ca9fb0b..000000000000 --- a/src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import ReportScreen from '@pages/home/ReportScreen'; -import ReportScreenIDSetter from './ReportScreenIDSetter'; - -type Props = { - route: any; - navigation: any; -}; - -function ReportScreenWrapper({route, navigation}: Props) { - // The ReportScreen without the reportID set will display a skeleton - // until the reportID is loaded and set in the route param - return ( - <> - {/* @ts-expect-error explanation */} - - - - ); -} - -ReportScreenWrapper.displayName = 'ReportScreenWrapper'; - -export default ReportScreenWrapper; From ddba55a59ab987b8b554341448b0e75d61b1327e Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 30 Nov 2023 10:57:25 +0100 Subject: [PATCH 08/17] fix: amend missed imports --- src/components/Button/index.tsx | 7 +++---- src/components/Icon/index.tsx | 14 ++++++++------ src/components/MapView/MapView.tsx | 3 ++- src/components/MapView/MapView.web.tsx | 9 ++++++--- src/components/ShowMoreButton/index.js | 8 +++++--- src/components/withTheme.tsx | 2 +- src/pages/home/report/ReportActionItem.js | 8 +++++--- src/pages/home/report/ReportActionItemSingle.js | 7 ++++--- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 71bce9777174..8d5833a121ca 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -9,7 +9,6 @@ import Text from '@components/Text'; import withNavigationFallback from '@components/withNavigationFallback'; import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import HapticFeedback from '@libs/HapticFeedback'; -import themeColors from '@styles/themes/default'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; @@ -118,7 +117,7 @@ function Button( allowBubble = false, iconRight = Expensicons.ArrowRight, - iconFill = themeColors.textLight, + iconFill, iconStyles = [], iconRightStyles = [], @@ -214,7 +213,7 @@ function Button( @@ -225,7 +224,7 @@ function Button( diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 82a5045b7ad4..1c21d1ae9426 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,8 +1,9 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; import withThemeStyles, {ThemeStylesProps} from '@components/withThemeStyles'; +import withTheme, {ThemeProps} from "@components/withTheme"; +import compose from '@libs/compose'; import * as StyleUtils from '@styles/StyleUtils'; -import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import IconWrapperStyles from './IconWrapperStyles'; @@ -41,7 +42,7 @@ type IconProps = { /** Additional styles to add to the Icon */ additionalStyles?: StyleProp; -} & ThemeStylesProps; +} & ThemeStylesProps & ThemeProps; // We must use a class component to create an animatable component with the Animated API // eslint-disable-next-line react/prefer-stateless-function @@ -50,7 +51,7 @@ class Icon extends PureComponent { public static defaultProps = { width: variables.iconSizeNormal, height: variables.iconSizeNormal, - fill: themeColors.icon, + fill: undefined, small: false, inline: false, additionalStyles: [], @@ -62,6 +63,7 @@ class Icon extends PureComponent { const width = this.props.small ? variables.iconSizeSmall : this.props.width; const height = this.props.small ? variables.iconSizeSmall : this.props.height; const iconStyles = [StyleUtils.getWidthAndHeightStyle(width ?? 0, height), IconWrapperStyles, this.props.themeStyles.pAbsolute, this.props.additionalStyles]; + const fill = this.props.fill ?? this.props.theme.icon; if (this.props.inline) { return ( @@ -73,7 +75,7 @@ class Icon extends PureComponent { @@ -90,7 +92,7 @@ class Icon extends PureComponent { @@ -99,4 +101,4 @@ class Icon extends PureComponent { } } -export default withThemeStyles(Icon); +export default compose(withTheme, withThemeStyles)(Icon); diff --git a/src/components/MapView/MapView.tsx b/src/components/MapView/MapView.tsx index db3e076eacca..eaafd7fc9f7e 100644 --- a/src/components/MapView/MapView.tsx +++ b/src/components/MapView/MapView.tsx @@ -6,11 +6,11 @@ import {withOnyx} from 'react-native-onyx'; import setUserLocation from '@libs/actions/UserLocation'; import compose from '@libs/compose'; import getCurrentPosition from '@libs/getCurrentPosition'; -import styles from '@styles/styles'; import CONST from '@src/CONST'; import useLocalize from '@src/hooks/useLocalize'; import useNetwork from '@src/hooks/useNetwork'; import ONYXKEYS from '@src/ONYXKEYS'; +import useThemeStyles from "@styles/useThemeStyles"; import Direction from './Direction'; import {MapViewHandle} from './MapViewTypes'; import PendingMapView from './PendingMapView'; @@ -23,6 +23,7 @@ const MapView = forwardRef( const navigation = useNavigation(); const {isOffline} = useNetwork(); const {translate} = useLocalize(); + const styles = useThemeStyles(); const cameraRef = useRef(null); const [isIdle, setIsIdle] = useState(false); diff --git a/src/components/MapView/MapView.web.tsx b/src/components/MapView/MapView.web.tsx index 1880049b3542..87ec8a25093e 100644 --- a/src/components/MapView/MapView.web.tsx +++ b/src/components/MapView/MapView.web.tsx @@ -10,14 +10,14 @@ import Map, {MapRef, Marker} from 'react-map-gl'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as StyleUtils from '@styles/StyleUtils'; -import themeColors from '@styles/themes/default'; import setUserLocation from '@userActions/UserLocation'; import CONST from '@src/CONST'; import useLocalize from '@src/hooks/useLocalize'; import useNetwork from '@src/hooks/useNetwork'; import getCurrentPosition from '@src/libs/getCurrentPosition'; import ONYXKEYS from '@src/ONYXKEYS'; -import styles from '@src/styles/styles'; +import useTheme from "@styles/themes/useTheme"; +import useThemeStyles from "@styles/useThemeStyles"; import Direction from './Direction'; import './mapbox.css'; import {MapViewHandle} from './MapViewTypes'; @@ -43,6 +43,9 @@ const MapView = forwardRef( const {isOffline} = useNetwork(); const {translate} = useLocalize(); + const theme = useTheme(); + const styles = useThemeStyles(); + const [mapRef, setMapRef] = useState(null); const [currentPosition, setCurrentPosition] = useState(cachedUserLocation); const [userInteractedWithMap, setUserInteractedWithMap] = useState(false); @@ -179,7 +182,7 @@ const MapView = forwardRef( latitude: currentPosition?.latitude, zoom: initialState.zoom, }} - style={StyleUtils.getTextColorStyle(themeColors.mapAttributionText) as React.CSSProperties} + style={StyleUtils.getTextColorStyle(theme.mapAttributionText) as React.CSSProperties} mapStyle={styleURL} > {waypoints?.map(({coordinate, markerComponent, id}) => { diff --git a/src/components/ShowMoreButton/index.js b/src/components/ShowMoreButton/index.js index f983a468cc1c..b47b8bed1932 100644 --- a/src/components/ShowMoreButton/index.js +++ b/src/components/ShowMoreButton/index.js @@ -7,8 +7,8 @@ import * as Expensicons from '@components/Icon/Expensicons'; import useLocalize from '@hooks/useLocalize'; import * as NumberFormatUtils from '@libs/NumberFormatUtils'; import stylePropTypes from '@styles/stylePropTypes'; -import styles from '@styles/styles'; -import themeColors from '@styles/themes/default'; +import useTheme from "@styles/themes/useTheme"; +import useThemeStyles from "@styles/useThemeStyles"; const propTypes = { /** Additional styles for container */ @@ -32,6 +32,8 @@ const defaultProps = { function ShowMoreButton({containerStyle, currentCount, totalCount, onPress}) { const {translate, preferredLocale} = useLocalize(); + const theme = useTheme(); + const styles = useThemeStyles(); const shouldShowCounter = _.isNumber(currentCount) && _.isNumber(totalCount); @@ -51,7 +53,7 @@ function ShowMoreButton({containerStyle, currentCount, totalCount, onPress}) { style={styles.mh0} small shouldShowRightIcon - iconFill={themeColors.icon} + iconFill={theme.icon} iconRight={Expensicons.DownArrow} text={translate('common.showMore')} accessibilityLabel={translate('common.showMore')} diff --git a/src/components/withTheme.tsx b/src/components/withTheme.tsx index d78742b7036b..451292f1a66f 100644 --- a/src/components/withTheme.tsx +++ b/src/components/withTheme.tsx @@ -29,4 +29,4 @@ export default function withTheme( return forwardRef(WithTheme); } -export {withThemePropTypes}; +export {withThemePropTypes, type ThemeProps}; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 828a793a8565..5ce7683fb6bf 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -45,9 +45,7 @@ import SelectionScraper from '@libs/SelectionScraper'; import userWalletPropTypes from '@pages/EnablePayments/userWalletPropTypes'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import reportPropTypes from '@pages/reportPropTypes'; -import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; -import themeColors from '@styles/themes/default'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as store from '@userActions/ReimbursementAccount/store'; @@ -58,6 +56,8 @@ import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import useThemeStyles from "@styles/useThemeStyles"; +import useTheme from "@styles/themes/useTheme"; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; import * as ContextMenuActions from './ContextMenu/ContextMenuActions'; import MiniReportActionContextMenu from './ContextMenu/MiniReportActionContextMenu'; @@ -142,13 +142,15 @@ function ReportActionItem(props) { const {updateHiddenAttachments} = useContext(ReportAttachmentsContext); const textInputRef = useRef(); const popoverAnchorRef = useRef(); + const styles = useThemeStyles(); + const theme = useTheme(); const downloadedPreviews = useRef([]); const prevDraftMessage = usePrevious(props.draftMessage); const originalReportID = ReportUtils.getOriginalReportID(props.report.reportID, props.action); const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); const isReportActionLinked = props.linkedReportActionID === props.action.reportActionID; - const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [isReportActionLinked]); + const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(theme.highlightBG) : {}), [isReportActionLinked, theme.highlightBG]); const originalMessage = lodashGet(props.action, 'originalMessage', {}); // IOUDetails only exists when we are sending money diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 9c641d879de3..911a5e0aa69a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -21,8 +21,8 @@ import * as UserUtils from '@libs/UserUtils'; import reportPropTypes from '@pages/reportPropTypes'; import stylePropTypes from '@styles/stylePropTypes'; import * as StyleUtils from '@styles/StyleUtils'; -import themeColors from '@styles/themes/default'; import useThemeStyles from '@styles/useThemeStyles'; +import useTheme from "@styles/themes/useTheme"; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import ReportActionItemDate from './ReportActionItemDate'; @@ -80,6 +80,7 @@ const showWorkspaceDetails = (reportID) => { function ReportActionItemSingle(props) { const styles = useThemeStyles(); + const theme = useTheme(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const actorAccountID = props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && props.iouReport ? props.iouReport.managerID : props.action.actorAccountID; let displayName = ReportUtils.getDisplayNameForParticipant(actorAccountID); @@ -167,8 +168,8 @@ function ReportActionItemSingle(props) { isInReportAction shouldShowTooltip secondAvatarStyle={[ - StyleUtils.getBackgroundAndBorderStyle(themeColors.appBG), - props.isHovered ? StyleUtils.getBackgroundAndBorderStyle(themeColors.highlightBG) : undefined, + StyleUtils.getBackgroundAndBorderStyle(theme.appBG), + props.isHovered ? StyleUtils.getBackgroundAndBorderStyle(theme.highlightBG) : undefined, ]} /> ); From 34272607f75358d514611999030161abdc1f3e7e Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 30 Nov 2023 11:05:28 +0100 Subject: [PATCH 09/17] fix: run lint --- src/components/Icon/index.tsx | 5 +++-- src/components/MapView/MapView.tsx | 2 +- src/components/MapView/MapView.web.tsx | 4 ++-- src/components/ShowMoreButton/index.js | 4 ++-- src/pages/home/report/ReportActionItem.js | 4 ++-- src/pages/home/report/ReportActionItemSingle.js | 7 ++----- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 1c21d1ae9426..7b3249798046 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,7 +1,7 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; +import withTheme, {ThemeProps} from '@components/withTheme'; import withThemeStyles, {ThemeStylesProps} from '@components/withThemeStyles'; -import withTheme, {ThemeProps} from "@components/withTheme"; import compose from '@libs/compose'; import * as StyleUtils from '@styles/StyleUtils'; import variables from '@styles/variables'; @@ -42,7 +42,8 @@ type IconProps = { /** Additional styles to add to the Icon */ additionalStyles?: StyleProp; -} & ThemeStylesProps & ThemeProps; +} & ThemeStylesProps & + ThemeProps; // We must use a class component to create an animatable component with the Animated API // eslint-disable-next-line react/prefer-stateless-function diff --git a/src/components/MapView/MapView.tsx b/src/components/MapView/MapView.tsx index eaafd7fc9f7e..91f9d9930079 100644 --- a/src/components/MapView/MapView.tsx +++ b/src/components/MapView/MapView.tsx @@ -6,11 +6,11 @@ import {withOnyx} from 'react-native-onyx'; import setUserLocation from '@libs/actions/UserLocation'; import compose from '@libs/compose'; import getCurrentPosition from '@libs/getCurrentPosition'; +import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import useLocalize from '@src/hooks/useLocalize'; import useNetwork from '@src/hooks/useNetwork'; import ONYXKEYS from '@src/ONYXKEYS'; -import useThemeStyles from "@styles/useThemeStyles"; import Direction from './Direction'; import {MapViewHandle} from './MapViewTypes'; import PendingMapView from './PendingMapView'; diff --git a/src/components/MapView/MapView.web.tsx b/src/components/MapView/MapView.web.tsx index 87ec8a25093e..f32413cbc15d 100644 --- a/src/components/MapView/MapView.web.tsx +++ b/src/components/MapView/MapView.web.tsx @@ -10,14 +10,14 @@ import Map, {MapRef, Marker} from 'react-map-gl'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as StyleUtils from '@styles/StyleUtils'; +import useTheme from '@styles/themes/useTheme'; +import useThemeStyles from '@styles/useThemeStyles'; import setUserLocation from '@userActions/UserLocation'; import CONST from '@src/CONST'; import useLocalize from '@src/hooks/useLocalize'; import useNetwork from '@src/hooks/useNetwork'; import getCurrentPosition from '@src/libs/getCurrentPosition'; import ONYXKEYS from '@src/ONYXKEYS'; -import useTheme from "@styles/themes/useTheme"; -import useThemeStyles from "@styles/useThemeStyles"; import Direction from './Direction'; import './mapbox.css'; import {MapViewHandle} from './MapViewTypes'; diff --git a/src/components/ShowMoreButton/index.js b/src/components/ShowMoreButton/index.js index b47b8bed1932..5f1620ac7c88 100644 --- a/src/components/ShowMoreButton/index.js +++ b/src/components/ShowMoreButton/index.js @@ -7,8 +7,8 @@ import * as Expensicons from '@components/Icon/Expensicons'; import useLocalize from '@hooks/useLocalize'; import * as NumberFormatUtils from '@libs/NumberFormatUtils'; import stylePropTypes from '@styles/stylePropTypes'; -import useTheme from "@styles/themes/useTheme"; -import useThemeStyles from "@styles/useThemeStyles"; +import useTheme from '@styles/themes/useTheme'; +import useThemeStyles from '@styles/useThemeStyles'; const propTypes = { /** Additional styles for container */ diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 5ce7683fb6bf..ae07503b6e9c 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -46,6 +46,8 @@ import userWalletPropTypes from '@pages/EnablePayments/userWalletPropTypes'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import reportPropTypes from '@pages/reportPropTypes'; import * as StyleUtils from '@styles/StyleUtils'; +import useTheme from '@styles/themes/useTheme'; +import useThemeStyles from '@styles/useThemeStyles'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as store from '@userActions/ReimbursementAccount/store'; @@ -56,8 +58,6 @@ import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import useThemeStyles from "@styles/useThemeStyles"; -import useTheme from "@styles/themes/useTheme"; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; import * as ContextMenuActions from './ContextMenu/ContextMenuActions'; import MiniReportActionContextMenu from './ContextMenu/MiniReportActionContextMenu'; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 911a5e0aa69a..c50f868cae99 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -21,8 +21,8 @@ import * as UserUtils from '@libs/UserUtils'; import reportPropTypes from '@pages/reportPropTypes'; import stylePropTypes from '@styles/stylePropTypes'; import * as StyleUtils from '@styles/StyleUtils'; +import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useTheme from "@styles/themes/useTheme"; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import ReportActionItemDate from './ReportActionItemDate'; @@ -167,10 +167,7 @@ function ReportActionItemSingle(props) { icons={[icon, secondaryAvatar]} isInReportAction shouldShowTooltip - secondAvatarStyle={[ - StyleUtils.getBackgroundAndBorderStyle(theme.appBG), - props.isHovered ? StyleUtils.getBackgroundAndBorderStyle(theme.highlightBG) : undefined, - ]} + secondAvatarStyle={[StyleUtils.getBackgroundAndBorderStyle(theme.appBG), props.isHovered ? StyleUtils.getBackgroundAndBorderStyle(theme.highlightBG) : undefined]} /> ); } From 42d3c22bee97bea32d03a2abcc3dac00f70ea163 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 30 Nov 2023 11:37:17 +0100 Subject: [PATCH 10/17] migrate getModalStyles --- src/components/Modal/BaseModal.tsx | 3 ++- src/components/PopoverWithoutOverlay/index.js | 3 +++ src/styles/getModalStyles.ts | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 95a7f3adc279..4945b4b62ad6 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -139,11 +139,12 @@ function BaseModal( windowHeight, isSmallScreenWidth, }, + theme, popoverAnchorPosition, innerContainerStyle, outerStyle, ), - [innerContainerStyle, isSmallScreenWidth, outerStyle, popoverAnchorPosition, type, windowHeight, windowWidth], + [innerContainerStyle, isSmallScreenWidth, outerStyle, popoverAnchorPosition, theme, type, windowHeight, windowWidth], ); const { diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 8b9dd4ac7a61..2a5d9265144a 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -6,10 +6,12 @@ import {PopoverContext} from '@components/PopoverProvider'; import withWindowDimensions from '@components/withWindowDimensions'; import getModalStyles from '@styles/getModalStyles'; import * as StyleUtils from '@styles/StyleUtils'; +import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as Modal from '@userActions/Modal'; function Popover(props) { + const theme = useTheme(); const styles = useThemeStyles(); const {onOpen, close} = React.useContext(PopoverContext); const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( @@ -19,6 +21,7 @@ function Popover(props) { windowHeight: props.windowHeight, isSmallScreenWidth: false, }, + theme, props.anchorPosition, props.innerContainerStyle, props.outerStyle, diff --git a/src/styles/getModalStyles.ts b/src/styles/getModalStyles.ts index c250bdf9498d..6402a16a97eb 100644 --- a/src/styles/getModalStyles.ts +++ b/src/styles/getModalStyles.ts @@ -3,7 +3,7 @@ import {ModalProps} from 'react-native-modal'; import {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import styles from './styles'; -import themeColors from './themes/default'; +import {ThemeColors} from './themes/types'; import variables from './variables'; function getCenteredModalStyles(windowWidth: number, isSmallScreenWidth: boolean, isFullScreenWhenSmall = false): ViewStyle { @@ -39,6 +39,7 @@ type GetModalStyles = { export default function getModalStyles( type: ModalType | undefined, windowDimensions: WindowDimensions, + themeColors: ThemeColors, popoverAnchorPosition: ViewStyle = {}, innerContainerStyle: ViewStyle = {}, outerStyle: ViewStyle = {}, From 10e87911c2b5e3b0047a202a1ea2c27fbc1892fe Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 30 Nov 2023 11:46:04 +0100 Subject: [PATCH 11/17] migrate getReportActionContextMenuStyles --- .../BaseReportActionContextMenu.js | 4 ++- .../getReportActionContextMenuStyles.ts | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js index 18351f86a400..4044ea2396db 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js @@ -13,6 +13,7 @@ import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import useNetwork from '@hooks/useNetwork'; import compose from '@libs/compose'; import getReportActionContextMenuStyles from '@styles/getReportActionContextMenuStyles'; +import useTheme from '@styles/themes/useTheme'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -49,9 +50,10 @@ const defaultProps = { ...GenericReportActionContextMenuDefaultProps, }; function BaseReportActionContextMenu(props) { + const theme = useTheme(); const menuItemRefs = useRef({}); const [shouldKeepOpen, setShouldKeepOpen] = useState(false); - const wrapperStyle = getReportActionContextMenuStyles(props.isMini, props.isSmallScreenWidth); + const wrapperStyle = getReportActionContextMenuStyles(props.isMini, props.isSmallScreenWidth, theme); const {isOffline} = useNetwork(); const reportAction = useMemo(() => { diff --git a/src/styles/getReportActionContextMenuStyles.ts b/src/styles/getReportActionContextMenuStyles.ts index cd3843169a43..e26f8de94919 100644 --- a/src/styles/getReportActionContextMenuStyles.ts +++ b/src/styles/getReportActionContextMenuStyles.ts @@ -1,42 +1,40 @@ import {ViewStyle} from 'react-native'; import styles from './styles'; -import themeColors from './themes/default'; +import {ThemeColors} from './themes/types'; import variables from './variables'; -const defaultWrapperStyle: ViewStyle = { - backgroundColor: themeColors.componentBG, -}; +const getDefaultWrapperStyle = (theme: ThemeColors): ViewStyle => ({ + backgroundColor: theme.componentBG, +}); -const miniWrapperStyle: ViewStyle[] = [ +const getMiniWrapperStyle = (theme: ThemeColors): ViewStyle[] => [ styles.flexRow, - defaultWrapperStyle, + getDefaultWrapperStyle(theme), { borderRadius: variables.buttonBorderRadius, borderWidth: 1, - borderColor: themeColors.border, + borderColor: theme.border, // In Safari, when welcome messages use a code block (triple backticks), they would overlap the context menu below when there is no scrollbar without the transform style. // NOTE: asserting "transform" to a valid type, because it isn't possible to augment "transform". transform: 'translateZ(0)' as unknown as ViewStyle['transform'], }, ]; -const bigWrapperStyle: ViewStyle[] = [styles.flexColumn, defaultWrapperStyle]; - /** * Generate the wrapper styles for the ReportActionContextMenu. * * @param isMini * @param isSmallScreenWidth + * @param theme */ -function getReportActionContextMenuStyles(isMini: boolean, isSmallScreenWidth: boolean): ViewStyle[] { +function getReportActionContextMenuStyles(isMini: boolean, isSmallScreenWidth: boolean, theme: ThemeColors): ViewStyle[] { if (isMini) { - return miniWrapperStyle; + return getMiniWrapperStyle(theme); } - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return return [ - ...bigWrapperStyle, + styles.flexColumn, + getDefaultWrapperStyle(theme), // Small screens use a bottom-docked modal that already has vertical padding. isSmallScreenWidth ? {} : styles.pv3, From 1e0da1d62b82c6926c35cb7ed34f3ae6baa462a9 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 30 Nov 2023 11:46:30 +0100 Subject: [PATCH 12/17] rename argument --- src/styles/getModalStyles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/getModalStyles.ts b/src/styles/getModalStyles.ts index 6402a16a97eb..eb87cc005f8b 100644 --- a/src/styles/getModalStyles.ts +++ b/src/styles/getModalStyles.ts @@ -39,7 +39,7 @@ type GetModalStyles = { export default function getModalStyles( type: ModalType | undefined, windowDimensions: WindowDimensions, - themeColors: ThemeColors, + theme: ThemeColors, popoverAnchorPosition: ViewStyle = {}, innerContainerStyle: ViewStyle = {}, outerStyle: ViewStyle = {}, @@ -197,7 +197,7 @@ export default function getModalStyles( modalContainerStyle = { borderRadius: 12, borderWidth: 1, - borderColor: themeColors.border, + borderColor: theme.border, justifyContent: 'center', overflow: 'hidden', boxShadow: variables.popoverMenuShadow, From c5d677ecf27255103bbcd5c79a7143b30ce4d14b Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 30 Nov 2023 11:54:06 +0100 Subject: [PATCH 13/17] fix: export fix --- src/components/Icon/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 7b3249798046..98449c838b67 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -2,7 +2,6 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; import withTheme, {ThemeProps} from '@components/withTheme'; import withThemeStyles, {ThemeStylesProps} from '@components/withThemeStyles'; -import compose from '@libs/compose'; import * as StyleUtils from '@styles/StyleUtils'; import variables from '@styles/variables'; import IconWrapperStyles from './IconWrapperStyles'; @@ -102,4 +101,4 @@ class Icon extends PureComponent { } } -export default compose(withTheme, withThemeStyles)(Icon); +export default withTheme(withThemeStyles(Icon)); From f1a3095897f934cf54342baf82db4a774576e2f7 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 30 Nov 2023 12:35:55 +0000 Subject: [PATCH 14/17] Update version to 1.4.6-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 549ee7fd79d5..4a32609ce517 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001040507 - versionName "1.4.5-7" + versionCode 1001040600 + versionName "1.4.6-0" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 22c893c828aa..c4105db05e68 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.5 + 1.4.6 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.5.7 + 1.4.6.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 35deae453a67..d53f0db8cde9 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.4.5 + 1.4.6 CFBundleSignature ???? CFBundleVersion - 1.4.5.7 + 1.4.6.0 diff --git a/package-lock.json b/package-lock.json index abd1110e5cce..e4eadbab7afa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.5-7", + "version": "1.4.6-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.5-7", + "version": "1.4.6-0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index b8173bd8ba1b..4cd5d52ae2b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.5-7", + "version": "1.4.6-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 78162d09f3cf2c1ab9bf58087f381b277796bffb Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 30 Nov 2023 12:44:35 +0000 Subject: [PATCH 15/17] Update version to 1.4.6-1 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4a32609ce517..4db8a0836477 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001040600 - versionName "1.4.6-0" + versionCode 1001040601 + versionName "1.4.6-1" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index c4105db05e68..5ce1b7f51147 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.6.0 + 1.4.6.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index d53f0db8cde9..f9675bc7cc27 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.6.0 + 1.4.6.1 diff --git a/package-lock.json b/package-lock.json index e4eadbab7afa..289c13c27e27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.6-0", + "version": "1.4.6-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.6-0", + "version": "1.4.6-1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 4cd5d52ae2b0..de4be2ace0f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.6-0", + "version": "1.4.6-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 23e360e4b601381025ee1ef7b1a1cce3975136db Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 30 Nov 2023 14:24:27 +0100 Subject: [PATCH 16/17] fix: remove invalid param --- src/components/TabSelector/TabSelector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TabSelector/TabSelector.js b/src/components/TabSelector/TabSelector.js index cdec2a7e91e1..83601dbc27d8 100644 --- a/src/components/TabSelector/TabSelector.js +++ b/src/components/TabSelector/TabSelector.js @@ -102,7 +102,7 @@ function TabSelector({state, navigation, onTabPress, position}) { {_.map(state.routes, (route, index) => { const activeOpacity = getOpacity(position, state.routes.length, index, true, affectedAnimatedTabs); const inactiveOpacity = getOpacity(position, state.routes.length, index, false, affectedAnimatedTabs); - const backgroundColor = getBackgroundColor(position, state.routes.length, index, affectedAnimatedTabs); + const backgroundColor = getBackgroundColor(state.routes.length, index, affectedAnimatedTabs); const isFocused = index === state.index; const {icon, title} = getIconAndTitle(route.name, translate); From 310ccf62cd93b498f8c14e0b17aaaf1b99b3bc2d Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 30 Nov 2023 13:45:19 +0000 Subject: [PATCH 17/17] Update version to 1.4.6-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4db8a0836477..28c983297c8b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001040601 - versionName "1.4.6-1" + versionCode 1001040602 + versionName "1.4.6-2" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 5ce1b7f51147..c05fe7fbfeba 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.6.1 + 1.4.6.2 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index f9675bc7cc27..4c875f6d7ba2 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.6.1 + 1.4.6.2 diff --git a/package-lock.json b/package-lock.json index 289c13c27e27..92f3de4e6271 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.6-1", + "version": "1.4.6-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.6-1", + "version": "1.4.6-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index de4be2ace0f4..24fbe3b0995f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.6-1", + "version": "1.4.6-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",