From ddbe9dfa9a998cf733182715a32f0a2262e90751 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 12:43:43 -0700 Subject: [PATCH 01/21] create currentDBTime --- src/libs/DateUtils.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 3582e672306d4..fdde17e2a64b7 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -161,6 +161,16 @@ function getMicroseconds() { return Date.now() * CONST.MICROSECONDS_PER_MS; } +/** + * Returns the current time in milliseconds in the format expected by the database + * @returns {String} + */ +function currentDBTime() { + return new Date().toISOString() + .replace('T', ' ') + .replace('Z', ''); +} + /** * @namespace DateUtils */ @@ -173,6 +183,7 @@ const DateUtils = { canUpdateTimezone, setTimezoneUpdated, getMicroseconds, + currentDBTime, }; export default DateUtils; From 55a89820fb1069b0556231b74b88ceb2af899744 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 13:02:10 -0700 Subject: [PATCH 02/21] update functions to use datetime --- src/components/withLocalize.js | 6 +++--- src/libs/DateUtils.js | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 1fb7c9ca9dc8c..d7480f0c251f0 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -96,14 +96,14 @@ class LocaleContextProvider extends React.Component { } /** - * @param {Number} timestamp + * @param {String} datetime - ISO-formatted datetime string * @param {Boolean} [includeTimezone] * @returns {String} */ - timestampToDateTime(timestamp, includeTimezone) { + timestampToDateTime(datetime, includeTimezone) { return DateUtils.timestampToDateTime( this.props.preferredLocale, - timestamp, + datetime, includeTimezone, ); } diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index fdde17e2a64b7..8138dd66752ef 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -34,26 +34,26 @@ Onyx.connect({ /** * Gets the user's stored time-zone NVP and returns a localized - * Moment object for the given timestamp + * Moment object for the given ISO-formatted datetime string * * @param {String} locale - * @param {Number} timestamp + * @param {String} datetime * @param {String} [currentSelectedTimezone] * * @returns {Moment} * * @private */ -function getLocalMomentFromTimestamp(locale, timestamp, currentSelectedTimezone = timezone.selected) { +function getLocalMomentFromTimestamp(locale, datetime, currentSelectedTimezone = timezone.selected) { moment.locale(locale); - if (!timestamp) { + if (!datetime) { return moment.tz(currentSelectedTimezone); } - return moment.unix(timestamp).tz(currentSelectedTimezone); + return moment.unix(datetime).tz(currentSelectedTimezone); } /** - * Formats a timestamp to local date and time string + * Formats an ISO-formatted datetime string to local date and time string * * e.g. * @@ -61,13 +61,13 @@ function getLocalMomentFromTimestamp(locale, timestamp, currentSelectedTimezone * Jan 20, 2019 at 5:30 PM anything over 1 year ago * * @param {String} locale - * @param {Number} timestamp + * @param {String} datetime * @param {Boolean} includeTimeZone * * @returns {String} */ -function timestampToDateTime(locale, timestamp, includeTimeZone = false) { - const date = getLocalMomentFromTimestamp(locale, timestamp); +function timestampToDateTime(locale, datetime, includeTimeZone = false) { + const date = getLocalMomentFromTimestamp(locale, datetime); const tz = includeTimeZone ? ' [UTC]Z' : ''; const todayAt = Localize.translate(locale, 'common.todayAt'); @@ -86,7 +86,7 @@ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { } /** - * Converts a timestamp into a localized string representation + * Converts an ISO-formatted datetime string into a localized string representation * that's relative to current moment in time. * * e.g. @@ -99,12 +99,12 @@ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { * Jan 20, 2019 anything over 1 year * * @param {String} locale - * @param {Number} timestamp + * @param {String} datetime * * @returns {String} */ -function timestampToRelative(locale, timestamp) { - const date = getLocalMomentFromTimestamp(locale, timestamp); +function timestampToRelative(locale, datetime) { + const date = getLocalMomentFromTimestamp(locale, datetime); return moment(date).fromNow(); } From 8250451d50f855b9297a6a3be3fccf0e469c0b83 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 14:47:02 -0700 Subject: [PATCH 03/21] add broken test --- tests/unit/DateUtilsTest.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/unit/DateUtilsTest.js diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js new file mode 100644 index 0000000000000..24b685932200a --- /dev/null +++ b/tests/unit/DateUtilsTest.js @@ -0,0 +1,13 @@ +import moment from 'moment'; +import DateUtils from '../../src/libs/DateUtils'; + +describe('DateUtils', () => { + it('getLocalMomentFromTimestamp', () => { + const locale = 'en'; + const datetime = '2022-11-07 00:00:00'; + const timezone = 'America/Los_Angeles'; + const localMoment = DateUtils.getLocalMomentFromTimestamp(locale, datetime, timezone); + expect(moment.isMoment(localMoment)).toBe(true); + expect(moment(localMoment).format()).toEqual('2022-11-06T23:00:00-08:00'); + }); +}); From 2d63eafed40533eaacdfe94c9176e54b135fb880 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 14:50:48 -0700 Subject: [PATCH 04/21] more tests --- tests/unit/DateUtilsTest.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 24b685932200a..a03e88071cfb4 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -1,8 +1,8 @@ import moment from 'moment'; import DateUtils from '../../src/libs/DateUtils'; -describe('DateUtils', () => { - it('getLocalMomentFromTimestamp', () => { +describe('DateUtils/getLocalMomentFromTimestamp', () => { + it('should return a moment object with the correct date and time', () => { const locale = 'en'; const datetime = '2022-11-07 00:00:00'; const timezone = 'America/Los_Angeles'; @@ -11,3 +11,7 @@ describe('DateUtils', () => { expect(moment(localMoment).format()).toEqual('2022-11-06T23:00:00-08:00'); }); }); + +describe('DateUtils/timestampToDateTime', () => { + it('should return a moment object with the correct date and time', () => {}); +}); From a0031c8b6b53d4991f652bda53a8b3d13052e0e8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 14:52:52 -0700 Subject: [PATCH 05/21] use created --- src/pages/home/report/ReportActionItemDate.js | 4 ++-- src/pages/home/report/ReportActionItemSingle.js | 2 +- src/pages/home/report/reportActionPropTypes.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionItemDate.js b/src/pages/home/report/ReportActionItemDate.js index 8ee127a721fd9..dd7089016ef92 100644 --- a/src/pages/home/report/ReportActionItemDate.js +++ b/src/pages/home/report/ReportActionItemDate.js @@ -8,13 +8,13 @@ import {withCurrentDate} from '../../../components/OnyxProvider'; const propTypes = { /** UTC timestamp for when the action was created */ - timestamp: PropTypes.number.isRequired, + created: PropTypes.string.isRequired, ...withLocalizePropTypes, }; const ReportActionItemDate = props => ( - {props.timestampToDateTime(props.timestamp)} + {props.timestampToDateTime(props.created)} ); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 12c09b5f934f0..4ca290a8912a5 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -98,7 +98,7 @@ const ReportActionItemSingle = (props) => { /> ))} - + ) : null} {props.children} diff --git a/src/pages/home/report/reportActionPropTypes.js b/src/pages/home/report/reportActionPropTypes.js index d752047cbb970..d3cebe8ba317f 100644 --- a/src/pages/home/report/reportActionPropTypes.js +++ b/src/pages/home/report/reportActionPropTypes.js @@ -12,8 +12,8 @@ export default { /** ID of the report action */ sequenceNumber: PropTypes.number, - /** Unix timestamp */ - timestamp: PropTypes.number, + /** ISO-formatted datetime */ + created: PropTypes.string, /** report action message */ message: PropTypes.arrayOf(reportActionFragmentPropTypes), From 92bcdd1ba5d47e68d25c63bdfb9a7183c0f55550 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 14:56:50 -0700 Subject: [PATCH 06/21] initialize optimistic actions with created date --- src/libs/ReportUtils.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 4f2128063d764..fbcf02fb18591 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -15,6 +15,7 @@ import ROUTES from '../ROUTES'; import * as NumberUtils from './NumberUtils'; import * as NumberFormatUtils from './NumberFormatUtils'; import Permissions from './Permissions'; +import DateUtils from './DateUtils'; let sessionEmail; Onyx.connect({ @@ -643,7 +644,7 @@ function buildOptimisticReportAction(sequenceNumber, text, file) { sequenceNumber, clientID: NumberUtils.generateReportActionClientID(), avatar: lodashGet(allPersonalDetails, [currentUserEmail, 'avatar'], getDefaultAvatar(currentUserEmail)), - timestamp: moment().unix(), + created: DateUtils.currentDBTime(), message: [ { type: CONST.REPORT.MESSAGE.TYPE.COMMENT, @@ -795,7 +796,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, reportActionID: NumberUtils.rand64(), sequenceNumber, shouldShow: true, - timestamp: moment().unix(), + created: DateUtils.currentDBTime(), pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; } @@ -883,7 +884,7 @@ function buildOptimisticCreatedReportAction(ownerEmail) { automatic: false, sequenceNumber: 0, avatar: lodashGet(allPersonalDetails, [currentUserEmail, 'avatar'], getDefaultAvatar(currentUserEmail)), - timestamp: moment().unix(), + created: DateUtils.currentDBTime(), shouldShow: true, }, }; From 518f17987e08c9790e7308995390cff8138b41c7 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 15:02:51 -0700 Subject: [PATCH 07/21] rm moment import and unix --- src/libs/DateUtils.js | 2 +- src/libs/ReportUtils.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 8138dd66752ef..cdb5084d1fc28 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -49,7 +49,7 @@ function getLocalMomentFromTimestamp(locale, datetime, currentSelectedTimezone = if (!datetime) { return moment.tz(currentSelectedTimezone); } - return moment.unix(datetime).tz(currentSelectedTimezone); + return moment(datetime).tz(currentSelectedTimezone); } /** diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index fbcf02fb18591..abb19fd07213d 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -2,7 +2,6 @@ import _ from 'underscore'; import Str from 'expensify-common/lib/str'; import lodashGet from 'lodash/get'; import Onyx from 'react-native-onyx'; -import moment from 'moment'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import ONYXKEYS from '../ONYXKEYS'; import CONST from '../CONST'; From 92bcdb622dd8fec304914b86c432570d3776bc8a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 16:10:54 -0700 Subject: [PATCH 08/21] fix report test --- tests/actions/ReportTest.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/actions/ReportTest.js b/tests/actions/ReportTest.js index cbf04d3adb582..f36c7b5560ae4 100644 --- a/tests/actions/ReportTest.js +++ b/tests/actions/ReportTest.js @@ -1,7 +1,6 @@ import _ from 'underscore'; import Onyx from 'react-native-onyx'; import lodashGet from 'lodash/get'; -import moment from 'moment'; import { beforeEach, beforeAll, afterEach, jest, describe, it, expect, } from '@jest/globals'; @@ -17,6 +16,7 @@ import Log from '../../src/libs/Log'; import * as PersistedRequests from '../../src/libs/actions/PersistedRequests'; import * as User from '../../src/libs/actions/User'; import * as ReportUtils from '../../src/libs/ReportUtils'; +import DateUtils from '../../src/libs/DateUtils'; describe('actions/Report', () => { beforeAll(() => { @@ -260,7 +260,7 @@ describe('actions/Report', () => { person: [{type: 'TEXT', style: 'strong', text: 'Test User'}], sequenceNumber: 1, shouldShow: true, - timestamp: moment().unix(), + created: DateUtils.currentDBTime(), }, }, }, @@ -325,7 +325,7 @@ describe('actions/Report', () => { avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png', person: [{type: 'TEXT', style: 'strong', text: 'Test User'}], shouldShow: true, - timestamp: moment().unix(), + created: DateUtils.currentDBTime(), reportActionID: 'derp', }; From c2999b736939b0014c9e5ad93be9e245cc754741 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 16:21:35 -0700 Subject: [PATCH 09/21] fix unread tests --- tests/ui/UnreadIndicatorsTest.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 56f531da77514..be75e61c98a2f 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -107,6 +107,7 @@ const USER_B_ACCOUNT_ID = 2; const USER_B_EMAIL = 'user_b@test.com'; const USER_C_ACCOUNT_ID = 3; const USER_C_EMAIL = 'user_c@test.com'; +const MOMENT_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS'; /** * Sets up a test with a logged in user that has one unread chat from another user. Returns the test instance. @@ -141,7 +142,7 @@ function signInAndGetAppWithUnreadChat() { actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, automatic: false, sequenceNumber: 0, - timestamp: MOMENT_TEN_MINUTES_AGO.unix(), + created: MOMENT_TEN_MINUTES_AGO.format(MOMENT_FORMAT), reportActionID: NumberUtils.rand64(), }, 1: TestHelper.buildTestReportComment(USER_B_EMAIL, 1, MOMENT_TEN_MINUTES_AGO.add(10, 'seconds').unix(), USER_B_ACCOUNT_ID), @@ -276,7 +277,7 @@ describe('Unread Indicators', () => { actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, automatic: false, sequenceNumber: 0, - timestamp: NEW_REPORT_CREATED_MOMENT.unix(), + created: NEW_REPORT_CREATED_MOMENT.format(MOMENT_FORMAT), reportActionID: NumberUtils.rand64(), }, 1: { @@ -285,7 +286,7 @@ describe('Unread Indicators', () => { actorAccountID: USER_C_ACCOUNT_ID, person: [{type: 'TEXT', style: 'strong', text: 'User C'}], sequenceNumber: 1, - timestamp: NEW_REPORT_CREATED_MOMENT.add(5, 'seconds').unix(), + created: NEW_REPORT_CREATED_MOMENT.add(5, 'seconds').format(MOMENT_FORMAT), message: [{type: 'COMMENT', html: 'Comment 1', text: 'Comment 1'}], reportActionID: NumberUtils.rand64(), }, From 34a561b014fff94e8ceabb5be066bdb8ae448b6e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 16:45:03 -0700 Subject: [PATCH 10/21] fix ReportTest --- src/libs/actions/Report.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index ee240ac8ce671..fe19b3a6f50c9 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1502,12 +1502,12 @@ Onyx.connect({ return; } - if (!action.timestamp) { + if (!action.created) { return; } // If we are past the deadline to notify for this comment don't do it - if (moment.utc(action.timestamp * 1000).isBefore(moment.utc().subtract(10, 'seconds'))) { + if (moment.utc(moment(action.created).unix() * 1000).isBefore(moment.utc().subtract(10, 'seconds'))) { handledReportActions[reportID] = handledReportActions[reportID] || {}; handledReportActions[reportID][action.sequenceNumber] = true; return; From b8fa25921bfdf2723d0709f6086703303754f028 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 16:52:41 -0700 Subject: [PATCH 11/21] update dateutils tests --- tests/unit/DateUtilsTest.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index a03e88071cfb4..2438e97d7fc9c 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -1,10 +1,11 @@ import moment from 'moment'; import DateUtils from '../../src/libs/DateUtils'; +const datetime = '2022-11-07 00:00:00'; +const locale = 'en'; + describe('DateUtils/getLocalMomentFromTimestamp', () => { it('should return a moment object with the correct date and time', () => { - const locale = 'en'; - const datetime = '2022-11-07 00:00:00'; const timezone = 'America/Los_Angeles'; const localMoment = DateUtils.getLocalMomentFromTimestamp(locale, datetime, timezone); expect(moment.isMoment(localMoment)).toBe(true); @@ -13,5 +14,7 @@ describe('DateUtils/getLocalMomentFromTimestamp', () => { }); describe('DateUtils/timestampToDateTime', () => { - it('should return a moment object with the correct date and time', () => {}); + it('should return a moment object with the correct date and time', () => { + expect(DateUtils.timestampToDateTime(locale, datetime)).toBe('Yesterday at 11:00 PM'); + }); }); From 035e95ff31a3cc8e58de4d432e29e2190b85bf90 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 7 Nov 2022 18:07:04 -0700 Subject: [PATCH 12/21] fix test --- tests/unit/DateUtilsTest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 2438e97d7fc9c..17c17a114a7d5 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -9,12 +9,12 @@ describe('DateUtils/getLocalMomentFromTimestamp', () => { const timezone = 'America/Los_Angeles'; const localMoment = DateUtils.getLocalMomentFromTimestamp(locale, datetime, timezone); expect(moment.isMoment(localMoment)).toBe(true); - expect(moment(localMoment).format()).toEqual('2022-11-06T23:00:00-08:00'); + expect(moment(localMoment).format()).toEqual('2022-11-06T16:00:00-08:00'); }); }); describe('DateUtils/timestampToDateTime', () => { it('should return a moment object with the correct date and time', () => { - expect(DateUtils.timestampToDateTime(locale, datetime)).toBe('Yesterday at 11:00 PM'); + expect(DateUtils.timestampToDateTime(locale, datetime)).toBe('Yesterday at 4:00 PM'); }); }); From 64f60b78fe8188b16fbb84c4451a35e4a9478e5d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 10:26:22 -0700 Subject: [PATCH 13/21] rename getLocalMomentFromDatetime --- src/libs/DateUtils.js | 10 +++++----- src/pages/DetailsPage.js | 2 +- src/pages/home/report/ParticipantLocalTime.js | 4 ++-- tests/unit/DateUtilsTest.js | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index cdb5084d1fc28..f935ce0b2afc1 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -33,7 +33,7 @@ Onyx.connect({ }); /** - * Gets the user's stored time-zone NVP and returns a localized + * Gets the user's stored time zone NVP and returns a localized * Moment object for the given ISO-formatted datetime string * * @param {String} locale @@ -44,7 +44,7 @@ Onyx.connect({ * * @private */ -function getLocalMomentFromTimestamp(locale, datetime, currentSelectedTimezone = timezone.selected) { +function getLocalMomentFromDatetime(locale, datetime, currentSelectedTimezone = timezone.selected) { moment.locale(locale); if (!datetime) { return moment.tz(currentSelectedTimezone); @@ -67,7 +67,7 @@ function getLocalMomentFromTimestamp(locale, datetime, currentSelectedTimezone = * @returns {String} */ function timestampToDateTime(locale, datetime, includeTimeZone = false) { - const date = getLocalMomentFromTimestamp(locale, datetime); + const date = getLocalMomentFromDatetime(locale, datetime); const tz = includeTimeZone ? ' [UTC]Z' : ''; const todayAt = Localize.translate(locale, 'common.todayAt'); @@ -104,7 +104,7 @@ function timestampToDateTime(locale, datetime, includeTimeZone = false) { * @returns {String} */ function timestampToRelative(locale, datetime) { - const date = getLocalMomentFromTimestamp(locale, datetime); + const date = getLocalMomentFromDatetime(locale, datetime); return moment(date).fromNow(); } @@ -178,7 +178,7 @@ const DateUtils = { timestampToRelative, timestampToDateTime, startCurrentDateUpdater, - getLocalMomentFromTimestamp, + getLocalMomentFromDatetime, getCurrentTimezone, canUpdateTimezone, setTimezoneUpdated, diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js index e65930c916dd2..45b151a695690 100755 --- a/src/pages/DetailsPage.js +++ b/src/pages/DetailsPage.js @@ -95,7 +95,7 @@ class DetailsPage extends React.PureComponent { // If we have a reportID param this means that we // arrived here via the ParticipantsPage and should be allowed to navigate back to it const shouldShowBackButton = Boolean(this.props.route.params.reportID); - const timezone = details.timezone ? DateUtils.getLocalMomentFromTimestamp(this.props.preferredLocale, null, details.timezone.selected) : null; + const timezone = details.timezone ? DateUtils.getLocalMomentFromDatetime(this.props.preferredLocale, null, details.timezone.selected) : null; const GMTTime = timezone ? `${timezone.toString().split(/[+-]/)[0].slice(-3)} ${timezone.zoneAbbr()}` : ''; const currentTime = (timezone && Number.isNaN(Number(timezone.zoneAbbr()))) ? timezone.zoneAbbr() : GMTTime; const shouldShowLocalTime = !ReportUtils.hasExpensifyEmails([details.login]); diff --git a/src/pages/home/report/ParticipantLocalTime.js b/src/pages/home/report/ParticipantLocalTime.js index b62a7ba5e833e..a93d2e57adcc1 100644 --- a/src/pages/home/report/ParticipantLocalTime.js +++ b/src/pages/home/report/ParticipantLocalTime.js @@ -42,8 +42,8 @@ class ParticipantLocalTime extends PureComponent { getParticipantLocalTime() { const reportRecipientTimezone = lodashGet(this.props.participant, 'timezone', CONST.DEFAULT_TIME_ZONE); - const reportTimezone = DateUtils.getLocalMomentFromTimestamp(this.props.preferredLocale, null, reportRecipientTimezone.selected); - const currentTimezone = DateUtils.getLocalMomentFromTimestamp(this.props.preferredLocale); + const reportTimezone = DateUtils.getLocalMomentFromDatetime(this.props.preferredLocale, null, reportRecipientTimezone.selected); + const currentTimezone = DateUtils.getLocalMomentFromDatetime(this.props.preferredLocale); const reportRecipientDay = reportTimezone.format('dddd'); const currentUserDay = currentTimezone.format('dddd'); diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 17c17a114a7d5..13a5bae206ea2 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -4,10 +4,10 @@ import DateUtils from '../../src/libs/DateUtils'; const datetime = '2022-11-07 00:00:00'; const locale = 'en'; -describe('DateUtils/getLocalMomentFromTimestamp', () => { +describe('DateUtils/getLocalMomentFromDatetime', () => { it('should return a moment object with the correct date and time', () => { const timezone = 'America/Los_Angeles'; - const localMoment = DateUtils.getLocalMomentFromTimestamp(locale, datetime, timezone); + const localMoment = DateUtils.getLocalMomentFromDatetime(locale, datetime, timezone); expect(moment.isMoment(localMoment)).toBe(true); expect(moment(localMoment).format()).toEqual('2022-11-06T16:00:00-08:00'); }); From bd9c5f0a00646d44322fa6e4ac0d9ce1fa990199 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 10:29:28 -0700 Subject: [PATCH 14/21] rename datetimeToCalendarTime --- src/components/withLocalize.js | 8 ++++---- src/libs/DateUtils.js | 4 ++-- src/pages/home/report/ReportActionItemDate.js | 2 +- tests/unit/DateUtilsTest.js | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index d7480f0c251f0..fe70ae4fe7379 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -23,7 +23,7 @@ const withLocalizePropTypes = { timestampToRelative: PropTypes.func.isRequired, /** Formats a timestamp to local date and time string */ - timestampToDateTime: PropTypes.func.isRequired, + datetimeToCalendarTime: PropTypes.func.isRequired, /** Returns a locally converted phone number without the country code */ toLocalPhone: PropTypes.func.isRequired, @@ -60,7 +60,7 @@ class LocaleContextProvider extends React.Component { translate: this.translate.bind(this), numberFormat: this.numberFormat.bind(this), timestampToRelative: this.timestampToRelative.bind(this), - timestampToDateTime: this.timestampToDateTime.bind(this), + datetimeToCalendarTime: this.datetimeToCalendarTime.bind(this), fromLocalPhone: this.fromLocalPhone.bind(this), toLocalPhone: this.toLocalPhone.bind(this), fromLocaleDigit: this.fromLocaleDigit.bind(this), @@ -100,8 +100,8 @@ class LocaleContextProvider extends React.Component { * @param {Boolean} [includeTimezone] * @returns {String} */ - timestampToDateTime(datetime, includeTimezone) { - return DateUtils.timestampToDateTime( + datetimeToCalendarTime(datetime, includeTimezone) { + return DateUtils.datetimeToCalendarTime( this.props.preferredLocale, datetime, includeTimezone, diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index f935ce0b2afc1..f2e49a2f50ddb 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -66,7 +66,7 @@ function getLocalMomentFromDatetime(locale, datetime, currentSelectedTimezone = * * @returns {String} */ -function timestampToDateTime(locale, datetime, includeTimeZone = false) { +function datetimeToCalendarTime(locale, datetime, includeTimeZone = false) { const date = getLocalMomentFromDatetime(locale, datetime); const tz = includeTimeZone ? ' [UTC]Z' : ''; @@ -176,7 +176,7 @@ function currentDBTime() { */ const DateUtils = { timestampToRelative, - timestampToDateTime, + datetimeToCalendarTime, startCurrentDateUpdater, getLocalMomentFromDatetime, getCurrentTimezone, diff --git a/src/pages/home/report/ReportActionItemDate.js b/src/pages/home/report/ReportActionItemDate.js index dd7089016ef92..0cf570132bd9e 100644 --- a/src/pages/home/report/ReportActionItemDate.js +++ b/src/pages/home/report/ReportActionItemDate.js @@ -14,7 +14,7 @@ const propTypes = { const ReportActionItemDate = props => ( - {props.timestampToDateTime(props.created)} + {props.datetimeToCalendarTime(props.created)} ); diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 13a5bae206ea2..98875e66c377f 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -13,8 +13,8 @@ describe('DateUtils/getLocalMomentFromDatetime', () => { }); }); -describe('DateUtils/timestampToDateTime', () => { +describe('DateUtils/datetimeToCalendarTime', () => { it('should return a moment object with the correct date and time', () => { - expect(DateUtils.timestampToDateTime(locale, datetime)).toBe('Yesterday at 4:00 PM'); + expect(DateUtils.datetimeToCalendarTime(locale, datetime)).toBe('Yesterday at 4:00 PM'); }); }); From a94992e23cf399f12bd180a0a2df9cdd7abac520 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 10:30:07 -0700 Subject: [PATCH 15/21] rename datetimeToRelative --- src/components/withLocalize.js | 8 ++++---- src/libs/DateUtils.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index fe70ae4fe7379..61008979b4100 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -20,7 +20,7 @@ const withLocalizePropTypes = { numberFormat: PropTypes.func.isRequired, /** Converts a timestamp into a localized string representation that's relative to current moment in time */ - timestampToRelative: PropTypes.func.isRequired, + datetimeToRelative: PropTypes.func.isRequired, /** Formats a timestamp to local date and time string */ datetimeToCalendarTime: PropTypes.func.isRequired, @@ -59,7 +59,7 @@ class LocaleContextProvider extends React.Component { return { translate: this.translate.bind(this), numberFormat: this.numberFormat.bind(this), - timestampToRelative: this.timestampToRelative.bind(this), + datetimeToRelative: this.datetimeToRelative.bind(this), datetimeToCalendarTime: this.datetimeToCalendarTime.bind(this), fromLocalPhone: this.fromLocalPhone.bind(this), toLocalPhone: this.toLocalPhone.bind(this), @@ -91,8 +91,8 @@ class LocaleContextProvider extends React.Component { * @param {Number} timestamp * @returns {String} */ - timestampToRelative(timestamp) { - return DateUtils.timestampToRelative(this.props.preferredLocale, timestamp); + datetimeToRelative(timestamp) { + return DateUtils.datetimeToRelative(this.props.preferredLocale, timestamp); } /** diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index f2e49a2f50ddb..58bacc5eca0db 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -103,7 +103,7 @@ function datetimeToCalendarTime(locale, datetime, includeTimeZone = false) { * * @returns {String} */ -function timestampToRelative(locale, datetime) { +function datetimeToRelative(locale, datetime) { const date = getLocalMomentFromDatetime(locale, datetime); return moment(date).fromNow(); @@ -175,7 +175,7 @@ function currentDBTime() { * @namespace DateUtils */ const DateUtils = { - timestampToRelative, + datetimeToRelative, datetimeToCalendarTime, startCurrentDateUpdater, getLocalMomentFromDatetime, From bb4c879835293a98a463a51662b6cb0b9fbfa461 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 10:35:48 -0700 Subject: [PATCH 16/21] convert to utc time --- src/libs/DateUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 58bacc5eca0db..b3fbbbd03d8a5 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -49,7 +49,7 @@ function getLocalMomentFromDatetime(locale, datetime, currentSelectedTimezone = if (!datetime) { return moment.tz(currentSelectedTimezone); } - return moment(datetime).tz(currentSelectedTimezone); + return moment.utc(datetime).tz(currentSelectedTimezone); } /** From 546a0701576564b8e4dba2c09669bd3ce2e19e9c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 12:18:35 -0700 Subject: [PATCH 17/21] add more tests --- tests/unit/DateUtilsTest.js | 54 ++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 98875e66c377f..7724162b8288d 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -1,20 +1,54 @@ import moment from 'moment'; +import Onyx from 'react-native-onyx'; import DateUtils from '../../src/libs/DateUtils'; +import ONYXKEYS from '../../src/ONYXKEYS'; +import waitForPromisesToResolve from '../utils/waitForPromisesToResolve'; -const datetime = '2022-11-07 00:00:00'; -const locale = 'en'; +const LOCALE = 'en'; -describe('DateUtils/getLocalMomentFromDatetime', () => { - it('should return a moment object with the correct date and time', () => { - const timezone = 'America/Los_Angeles'; - const localMoment = DateUtils.getLocalMomentFromDatetime(locale, datetime, timezone); +describe('DateUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + initialKeyStates: { + [ONYXKEYS.SESSION]: {email: 'current@user.com'}, + [ONYXKEYS.PERSONAL_DETAILS]: {'current@user.com': {timezone: {selected: 'Etc/UTC'}}}, + }, + }); + return waitForPromisesToResolve(); + }); + + const datetime = '2022-11-07 00:00:00'; + it('should return a moment object with the formatted datetime when calling getLocalMomentFromDatetime', () => { + const localMoment = DateUtils.getLocalMomentFromDatetime(LOCALE, datetime, 'America/Los_Angeles'); expect(moment.isMoment(localMoment)).toBe(true); expect(moment(localMoment).format()).toEqual('2022-11-06T16:00:00-08:00'); }); -}); -describe('DateUtils/datetimeToCalendarTime', () => { - it('should return a moment object with the correct date and time', () => { - expect(DateUtils.datetimeToCalendarTime(locale, datetime)).toBe('Yesterday at 4:00 PM'); + it('should return the date in calendar time when calling datetimeToCalendarTime', () => { + const today = moment.utc().set({hour: 14, minute: 32}); + expect(DateUtils.datetimeToCalendarTime(LOCALE, today)).toBe('Today at 2:32 PM'); + + const yesterday = moment.utc().subtract(1, 'days').set({hour: 7, minute: 43}); + expect(DateUtils.datetimeToCalendarTime(LOCALE, yesterday)).toBe('Yesterday at 7:43 AM'); + + const date = moment.utc('2022-11-05').set({hour: 10, minute: 17}); + expect(DateUtils.datetimeToCalendarTime(LOCALE, date)).toBe('Nov 5 at 10:17 AM'); + }); + + it('should return the date in calendar time when calling datetimeToRelative', () => { + const aFewSecondsAgo = moment().subtract(10, 'seconds'); + expect(DateUtils.datetimeToRelative(LOCALE, aFewSecondsAgo)).toBe('a few seconds ago'); + + const aMinuteAgo = moment().subtract(1, 'minute'); + expect(DateUtils.datetimeToRelative(LOCALE, aMinuteAgo)).toBe('a minute ago'); + + const anHourAgo = moment().subtract(1, 'hour'); + expect(DateUtils.datetimeToRelative(LOCALE, anHourAgo)).toBe('an hour ago'); + }); + + it('should return the date in the format expected by the database when calling currentDBTime', () => { + const currentDBTime = DateUtils.currentDBTime(); + expect(currentDBTime).toBe(moment(currentDBTime).format('YYYY-MM-DD HH:mm:ss.SSS')); }); }); From 4bd99402cebdf4d7394e0d1f260879ea238197eb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 8 Nov 2022 12:37:45 -0700 Subject: [PATCH 18/21] use created in unread tests --- src/components/withLocalize.js | 10 +++++----- src/libs/ReportActionsUtils.js | 3 ++- tests/ui/UnreadIndicatorsTest.js | 18 +++++++++--------- tests/utils/TestHelper.js | 6 +++--- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 61008979b4100..918c055948250 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -19,10 +19,10 @@ const withLocalizePropTypes = { /** Formats number formatted according to locale and options */ numberFormat: PropTypes.func.isRequired, - /** Converts a timestamp into a localized string representation that's relative to current moment in time */ + /** Converts a datetime into a localized string representation that's relative to current moment in time */ datetimeToRelative: PropTypes.func.isRequired, - /** Formats a timestamp to local date and time string */ + /** Formats a datetime to local date and time string */ datetimeToCalendarTime: PropTypes.func.isRequired, /** Returns a locally converted phone number without the country code */ @@ -88,11 +88,11 @@ class LocaleContextProvider extends React.Component { } /** - * @param {Number} timestamp + * @param {String} datetime * @returns {String} */ - datetimeToRelative(timestamp) { - return DateUtils.datetimeToRelative(this.props.preferredLocale, timestamp); + datetimeToRelative(datetime) { + return DateUtils.datetimeToRelative(this.props.preferredLocale, datetime); } /** diff --git a/src/libs/ReportActionsUtils.js b/src/libs/ReportActionsUtils.js index 6616d03511e82..150ce27b12465 100644 --- a/src/libs/ReportActionsUtils.js +++ b/src/libs/ReportActionsUtils.js @@ -3,6 +3,7 @@ import _ from 'underscore'; import lodashMerge from 'lodash/merge'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import Onyx from 'react-native-onyx'; +import moment from 'moment'; import * as CollectionUtils from './CollectionUtils'; import CONST from '../CONST'; import ONYXKEYS from '../ONYXKEYS'; @@ -84,7 +85,7 @@ function isConsecutiveActionMadeByPreviousActor(reportActions, actionIndex) { } // Comments are only grouped if they happen within 5 minutes of each other - if (currentAction.action.timestamp - previousAction.action.timestamp > 300) { + if (moment(currentAction.action.created).unix() - moment(previousAction.action.created).unix() > 300) { return false; } diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index be75e61c98a2f..ac061383f0c07 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -145,15 +145,15 @@ function signInAndGetAppWithUnreadChat() { created: MOMENT_TEN_MINUTES_AGO.format(MOMENT_FORMAT), reportActionID: NumberUtils.rand64(), }, - 1: TestHelper.buildTestReportComment(USER_B_EMAIL, 1, MOMENT_TEN_MINUTES_AGO.add(10, 'seconds').unix(), USER_B_ACCOUNT_ID), - 2: TestHelper.buildTestReportComment(USER_B_EMAIL, 2, MOMENT_TEN_MINUTES_AGO.add(20, 'seconds').unix(), USER_B_ACCOUNT_ID), - 3: TestHelper.buildTestReportComment(USER_B_EMAIL, 3, MOMENT_TEN_MINUTES_AGO.add(30, 'seconds').unix(), USER_B_ACCOUNT_ID), - 4: TestHelper.buildTestReportComment(USER_B_EMAIL, 4, MOMENT_TEN_MINUTES_AGO.add(40, 'seconds').unix(), USER_B_ACCOUNT_ID), - 5: TestHelper.buildTestReportComment(USER_B_EMAIL, 5, MOMENT_TEN_MINUTES_AGO.add(50, 'seconds').unix(), USER_B_ACCOUNT_ID), - 6: TestHelper.buildTestReportComment(USER_B_EMAIL, 6, MOMENT_TEN_MINUTES_AGO.add(60, 'seconds').unix(), USER_B_ACCOUNT_ID), - 7: TestHelper.buildTestReportComment(USER_B_EMAIL, 7, MOMENT_TEN_MINUTES_AGO.add(70, 'seconds').unix(), USER_B_ACCOUNT_ID), - 8: TestHelper.buildTestReportComment(USER_B_EMAIL, 8, MOMENT_TEN_MINUTES_AGO.add(80, 'seconds').unix(), USER_B_ACCOUNT_ID), - 9: TestHelper.buildTestReportComment(USER_B_EMAIL, 9, MOMENT_TEN_MINUTES_AGO.add(90, 'seconds').unix(), USER_B_ACCOUNT_ID), + 1: TestHelper.buildTestReportComment(USER_B_EMAIL, 1, MOMENT_TEN_MINUTES_AGO.add(10, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 2: TestHelper.buildTestReportComment(USER_B_EMAIL, 2, MOMENT_TEN_MINUTES_AGO.add(20, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 3: TestHelper.buildTestReportComment(USER_B_EMAIL, 3, MOMENT_TEN_MINUTES_AGO.add(30, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 4: TestHelper.buildTestReportComment(USER_B_EMAIL, 4, MOMENT_TEN_MINUTES_AGO.add(40, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 5: TestHelper.buildTestReportComment(USER_B_EMAIL, 5, MOMENT_TEN_MINUTES_AGO.add(50, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 6: TestHelper.buildTestReportComment(USER_B_EMAIL, 6, MOMENT_TEN_MINUTES_AGO.add(60, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 7: TestHelper.buildTestReportComment(USER_B_EMAIL, 7, MOMENT_TEN_MINUTES_AGO.add(70, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 8: TestHelper.buildTestReportComment(USER_B_EMAIL, 8, MOMENT_TEN_MINUTES_AGO.add(80, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), + 9: TestHelper.buildTestReportComment(USER_B_EMAIL, 9, MOMENT_TEN_MINUTES_AGO.add(90, 'seconds').format(MOMENT_FORMAT), USER_B_ACCOUNT_ID), }); Onyx.merge(ONYXKEYS.PERSONAL_DETAILS, { [USER_B_EMAIL]: TestHelper.buildPersonalDetails(USER_B_EMAIL, USER_B_ACCOUNT_ID, 'B'), diff --git a/tests/utils/TestHelper.js b/tests/utils/TestHelper.js index 0025ff9040bdc..7b4f05c16e34e 100644 --- a/tests/utils/TestHelper.js +++ b/tests/utils/TestHelper.js @@ -157,17 +157,17 @@ function setPersonalDetails(login, accountID) { /** * @param {String} actorEmail * @param {Number} sequenceNumber - * @param {Number} timestamp + * @param {String} created * @param {Number} actorAccountID * @returns {Object} */ -function buildTestReportComment(actorEmail, sequenceNumber, timestamp, actorAccountID) { +function buildTestReportComment(actorEmail, sequenceNumber, created, actorAccountID) { return { actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT, actorEmail, person: [{type: 'TEXT', style: 'strong', text: 'User B'}], sequenceNumber, - timestamp, + created, message: [{type: 'COMMENT', html: `Comment ${sequenceNumber}`, text: `Comment ${sequenceNumber}`}], reportActionID: NumberUtils.rand64(), actorAccountID, From 374912a4d7dee82b5d69eb05261611f1e6c20392 Mon Sep 17 00:00:00 2001 From: rory Date: Thu, 10 Nov 2022 16:05:55 -0800 Subject: [PATCH 19/21] Make customairshipextender its own package --- android/app/src/main/AndroidManifest.xml | 2 +- .../com/expensify/chat/MainApplication.java | 24 ++++++++----------- .../CustomAirshipExtender.java | 4 ++-- .../CustomNotificationListener.java | 2 +- .../CustomNotificationProvider.java | 2 +- 5 files changed, 15 insertions(+), 19 deletions(-) rename android/app/src/main/java/com/expensify/chat/{ => customairshipextender}/CustomAirshipExtender.java (94%) rename android/app/src/main/java/com/expensify/chat/{ => customairshipextender}/CustomNotificationListener.java (97%) rename android/app/src/main/java/com/expensify/chat/{ => customairshipextender}/CustomNotificationProvider.java (99%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index eb109cc8a30e6..71c3dc6c9af35 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -78,6 +78,6 @@ + android:value="com.expensify.chat.customairshipextender.CustomAirshipExtender" /> diff --git a/android/app/src/main/java/com/expensify/chat/MainApplication.java b/android/app/src/main/java/com/expensify/chat/MainApplication.java index 7156979a6c684..ed90283b05937 100644 --- a/android/app/src/main/java/com/expensify/chat/MainApplication.java +++ b/android/app/src/main/java/com/expensify/chat/MainApplication.java @@ -2,24 +2,23 @@ import android.content.Context; import android.database.CursorWindow; + import androidx.multidex.MultiDexApplication; + import com.expensify.chat.bootsplash.BootSplashPackage; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.existfragger.rnimagesize.RNImageSizePackage; -import com.google.firebase.crashlytics.FirebaseCrashlytics; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.config.ReactFeatureFlags; +import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.soloader.SoLoader; -import java.lang.reflect.InvocationTargetException; +import com.google.firebase.crashlytics.FirebaseCrashlytics; + import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.util.List; -import com.facebook.react.modules.i18nmanager.I18nUtil; public class MainApplication extends MultiDexApplication implements ReactApplication { @@ -111,13 +110,10 @@ private static void initializeFlipper( aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { + } catch (ClassNotFoundException + | NoSuchMethodException + | IllegalAccessException + | InvocationTargetException e) { e.printStackTrace(); } } diff --git a/android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java similarity index 94% rename from android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java index dd09a934fc790..0cae0bd2de6d8 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import android.content.Context; import androidx.annotation.NonNull; @@ -18,4 +18,4 @@ public void onAirshipReady(@NonNull Context context, @NonNull UAirship airship) NotificationListener notificationListener = airship.getPushManager().getNotificationListener(); pushManager.setNotificationListener(new CustomNotificationListener(notificationListener, notificationProvider)); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java similarity index 97% rename from android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java index d6fc1f9e1a350..514e5aca14a05 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import androidx.annotation.NonNull; import com.urbanairship.push.NotificationActionButtonInfo; diff --git a/android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java similarity index 99% rename from android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java index 8e9f5082ef67b..f05f9ceb2b85d 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import android.content.Context; import android.graphics.Bitmap; From ca7bc2d718053522ff5695ae46ef99c373685e12 Mon Sep 17 00:00:00 2001 From: rory Date: Thu, 10 Nov 2022 16:37:45 -0800 Subject: [PATCH 20/21] Dont use reportAction timestamp field in custom notification provider --- .../app/src/main/java/com/expensify/chat/StartupTimer.java | 1 + .../customairshipextender/CustomNotificationProvider.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/com/expensify/chat/StartupTimer.java b/android/app/src/main/java/com/expensify/chat/StartupTimer.java index de43519fcb153..972e1dd95a0e1 100644 --- a/android/app/src/main/java/com/expensify/chat/StartupTimer.java +++ b/android/app/src/main/java/com/expensify/chat/StartupTimer.java @@ -1,4 +1,5 @@ package com.expensify.chat; + import android.util.Log; import com.facebook.react.bridge.ReactApplicationContext; diff --git a/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java index f05f9ceb2b85d..deeff81bf76dc 100644 --- a/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java @@ -26,6 +26,8 @@ import com.urbanairship.util.ImageUtils; import java.net.MalformedURLException; import java.net.URL; +import java.sql.Timestamp; +import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -126,7 +128,7 @@ private void applyMessageStyle(@NonNull Context context, NotificationCompat.Buil String avatar = reportAction.get("avatar").getString(); String accountID = Integer.toString(reportAction.get("actorAccountID").getInt(-1)); String message = reportAction.get("message").getList().get(0).getMap().get("text").getString(); - long time = reportAction.get("timestamp").getLong(0); + long time = Timestamp.valueOf(reportAction.get("created").getString(Instant.now().toString())).getTime(); String roomName = payload.get("roomName") == null ? "" : payload.get("roomName").getString(""); String conversationTitle = "Chat with " + name; if (!roomName.isEmpty()) { From 68f290a87fd736d9ec688a56dc66f57675c708ca Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 11 Nov 2022 07:57:42 -0800 Subject: [PATCH 21/21] Simplify catch --- .../src/main/java/com/expensify/chat/MainApplication.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/android/app/src/main/java/com/expensify/chat/MainApplication.java b/android/app/src/main/java/com/expensify/chat/MainApplication.java index ed90283b05937..fd203ecc675d6 100644 --- a/android/app/src/main/java/com/expensify/chat/MainApplication.java +++ b/android/app/src/main/java/com/expensify/chat/MainApplication.java @@ -110,10 +110,7 @@ private static void initializeFlipper( aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException - | NoSuchMethodException - | IllegalAccessException - | InvocationTargetException e) { + } catch (Exception e) { e.printStackTrace(); } }