-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Order by most recent along with report icons #759
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
004d79f
2afde47
4e73d87
35918f7
4a26675
62a157d
2da2772
2cdf9a4
226d702
68b4d76
1746fc8
5f11d83
78d43e8
8dc27d7
a259d7a
6e87007
306d88a
32f5988
10b7c7b
40c04f5
d0daf83
35e5876
decebef
ff11e79
31af299
0e0683e
85a5b8c
fd27e33
0d2a024
9a5cf51
8a7c43c
69bf6ab
f2d9f35
47c8f95
f9a2f9b
dd483ac
ecb15e7
5b1d9a9
d437b3e
f5406fb
a9ebd92
5161b3e
94dcd24
4c52b72
3469012
5bff415
625097f
2f5447d
d1d5329
fdb673e
22104c9
022ca53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ const typingWatchTimers = {}; | |
| const reportMaxSequenceNumbers = {}; | ||
|
|
||
| // Keeps track of the last read for each report | ||
| const lastReadActionIDs = {}; | ||
| const lastReadSequenceNumbers = {}; | ||
|
|
||
| /** | ||
| * Checks the report to see if there are any unread action items | ||
|
|
@@ -62,25 +62,31 @@ const lastReadActionIDs = {}; | |
| * @returns {Boolean} | ||
| */ | ||
| function getUnreadActionCount(report) { | ||
| const usersLastReadActionID = lodashGet(report, [ | ||
| // @todo remove the first check as part of cleanup https://github.com/Expensify/Expensify/issues/145243 | ||
|
chiragsalian marked this conversation as resolved.
|
||
| // since we migrating our data from lastReadActionID_ value to lastRead_ object. | ||
| const lastReadSequenceNumber = lodashGet(report, [ | ||
| 'reportNameValuePairs', | ||
| `lastReadActionID_${currentUserAccountID}`, | ||
| ]) || lodashGet(report, [ | ||
| 'reportNameValuePairs', | ||
| `lastRead_${currentUserAccountID}`, | ||
| 'sequenceNumber', | ||
| ]); | ||
|
|
||
| // Save the lastReadActionID locally so we can access this later | ||
| lastReadActionIDs[report.reportID] = usersLastReadActionID; | ||
| lastReadSequenceNumbers[report.reportID] = lastReadSequenceNumber; | ||
|
|
||
| if (report.reportActionList.length === 0) { | ||
| return 0; | ||
| } | ||
|
|
||
| if (!usersLastReadActionID) { | ||
| if (!lastReadSequenceNumber) { | ||
| return report.reportActionList.length; | ||
| } | ||
|
|
||
| // There are unread items if the last one the user has read is less | ||
| // than the highest sequence number we have | ||
| const unreadActionCount = report.reportActionList.length - usersLastReadActionID; | ||
| const unreadActionCount = report.reportActionList.length - lastReadSequenceNumber; | ||
| return Math.max(0, unreadActionCount); | ||
| } | ||
|
|
||
|
|
@@ -107,11 +113,15 @@ function getSimplifiedReportObject(report) { | |
| return { | ||
| reportID: report.reportID, | ||
| reportName: report.reportName, | ||
| reportNameValuePairs: report.reportNameValuePairs, | ||
|
marcaaron marked this conversation as resolved.
|
||
| unreadActionCount: getUnreadActionCount(report), | ||
| maxSequenceNumber: report.reportActionList.length, | ||
| participants: getParticipantEmailsFromReport(report), | ||
| isPinned: report.isPinned, | ||
| lastVisitedTimestamp: lodashGet(report, [ | ||
| 'reportNameValuePairs', | ||
| `lastRead_${currentUserAccountID}`, | ||
| 'timestamp' | ||
| ], 0) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAB not sure if it's very valuable but a utility that let us do const lastRead = getLastRead(report, accountID);
console.log(lastRead.sequenceNumber);
console.log(lastRead.timestamp);might help us DRY things up a little instead of having to use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah i don't see much value in a utility function like so when it can be directly accessed in lodashGet. Like atm i don't see a point of returning an object than the required value directly. |
||
| }; | ||
| } | ||
|
|
||
|
|
@@ -148,15 +158,14 @@ function fetchChatReportsByIDs(chatList) { | |
| .then(({reports}) => { | ||
| fetchedReports = reports; | ||
|
|
||
| // Build array of all participant emails so we can | ||
| // get the personal details. | ||
| let participantEmails = []; | ||
|
|
||
| // Process the reports and store them in Onyx | ||
| // Process the reports and store them in Onyx. At the same time we'll save the simplified reports in this | ||
| // variable called simplifiedReports which hold the participants (minus the current user) for each report. | ||
| // Using this simplifiedReport we can call PersonalDetails.getFromReportParticipants to get the | ||
| // personal details of all the participants and even link up their avatars to report icons. | ||
| const simplifiedReports = []; | ||
| _.each(fetchedReports, (report) => { | ||
| const newReport = getSimplifiedReportObject(report); | ||
|
|
||
| participantEmails.push(newReport.participants); | ||
| simplifiedReports.push(newReport); | ||
|
chiragsalian marked this conversation as resolved.
|
||
|
|
||
| if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { | ||
| newReport.reportName = getChatReportName(report.sharedReportList); | ||
|
|
@@ -166,31 +175,26 @@ function fetchChatReportsByIDs(chatList) { | |
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, newReport); | ||
| }); | ||
|
|
||
| // Fetch the person details if there are any | ||
| participantEmails = _.unique(participantEmails); | ||
| if (participantEmails && participantEmails.length !== 0) { | ||
| PersonalDetails.getForEmails(participantEmails.join(',')); | ||
| } | ||
| // Fetch the personal details if there are any | ||
| PersonalDetails.getFromReportParticipants(simplifiedReports); | ||
|
|
||
| return _.map(fetchedReports, report => report.reportID); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Update the lastReadActionID in Onyx and local memory. | ||
| * Update the lastRead actionID and timestamp in local memory and Onyx | ||
| * | ||
| * @param {Number} reportID | ||
| * @param {Number} sequenceNumber | ||
| */ | ||
| function setLocalLastReadActionID(reportID, sequenceNumber) { | ||
| lastReadActionIDs[reportID] = sequenceNumber; | ||
| function setLocalLastRead(reportID, sequenceNumber) { | ||
| lastReadSequenceNumbers[reportID] = sequenceNumber; | ||
|
|
||
| // Update the lastReadActionID on the report optimistically | ||
| // Update the report optimistically | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { | ||
| unreadActionCount: 0, | ||
| reportNameValuePairs: { | ||
| [`lastReadActionID_${currentUserAccountID}`]: sequenceNumber, | ||
| } | ||
| lastVisitedTimestamp: Date.now(), | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -208,15 +212,15 @@ function updateReportWithNewAction(reportID, reportAction) { | |
| // last read actionID has been updated in the server but not necessarily reflected | ||
| // locally so we must first update it and then calculate the unread (which should be 0) | ||
| if (isFromCurrentUser) { | ||
| setLocalLastReadActionID(reportID, newMaxSequenceNumber); | ||
| setLocalLastRead(reportID, newMaxSequenceNumber); | ||
| } | ||
|
|
||
| // Always merge the reportID into Onyx | ||
| // If the report doesn't exist in Onyx yet, then all the rest of the data will be filled out | ||
| // by handleReportChanged | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { | ||
| reportID, | ||
| unreadActionCount: newMaxSequenceNumber - (lastReadActionIDs[reportID] || 0), | ||
| unreadActionCount: newMaxSequenceNumber - (lastReadSequenceNumbers[reportID] || 0), | ||
| maxSequenceNumber: reportAction.sequenceNumber, | ||
| }); | ||
|
|
||
|
|
@@ -451,6 +455,10 @@ function fetchOrCreateChatReport(participants) { | |
| const newReport = getSimplifiedReportObject(report); | ||
| newReport.reportName = getChatReportName(report.sharedReportList); | ||
|
|
||
| // Optimistically update the last visited timestamp such that if the user immediately switches to another | ||
| // report the last visited order is still maintained. | ||
| newReport.lastVisitedTimestamp = Date.now(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAB/possible follow up... one thought I'm having is that we could also update the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically we don't even need this code because
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense to me I think. Except this part...
Not sure it will be obvious to anyone scanning this code that this is the reason we are setting this on the report. How much faster does it make things? If we really want to keep it maybe we can add some context here for why it's being updated immediately. |
||
|
|
||
| // Merge the data into Onyx. Don't use set() here or multiSet() because then that would | ||
| // overwrite any existing data (like if they have unread messages) | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, newReport); | ||
|
|
@@ -536,10 +544,10 @@ function updateLastReadActionID(reportID, sequenceNumber) { | |
| return; | ||
| } | ||
|
|
||
| setLocalLastReadActionID(reportID, sequenceNumber); | ||
| setLocalLastRead(reportID, sequenceNumber); | ||
|
|
||
| // Mark the report as not having any unread items | ||
| API.Report_SetLastReadActionID({ | ||
| API.Report_UpdateLastRead({ | ||
| accountID: currentUserAccountID, | ||
| reportID, | ||
| sequenceNumber, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,7 +35,7 @@ const ChatSwitcherList = ({ | |
| keyboardShouldPersistTaps="always" | ||
| showsVerticalScrollIndicator={false} | ||
| data={options} | ||
| keyExtractor={option => (option.type === 'user' ? option.alternateText : String(option.reportID))} | ||
| keyExtractor={option => option.keyForList} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAB
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. went with the suggestion mentioned here |
||
| renderItem={({item, index}) => ( | ||
| <ChatLinkRow | ||
| option={item} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.