Skip to content
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

Issue 28059 fix emoji reactions in offline mode #28519

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions src/components/Reactions/ReportActionItemEmojiReactions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {useRef, useContext} from 'react';
import lodashGet from 'lodash/get';
import _ from 'underscore';
import {View} from 'react-native';
import PropTypes from 'prop-types';
Expand All @@ -14,12 +15,14 @@ import Tooltip from '../Tooltip';
import ReactionTooltipContent from './ReactionTooltipContent';
import * as EmojiUtils from '../../libs/EmojiUtils';
import {ReactionListContext} from '../../pages/home/ReportScreenContext';
import OfflineWithFeedback from '../OfflineWithFeedback';
import reportActionPropTypes from '../../pages/home/report/reportActionPropTypes';

const propTypes = {
emojiReactions: EmojiReactionsPropTypes,

/** The ID of the reportAction. It is the string representation of the a 64-bit integer. */
reportActionID: PropTypes.string.isRequired,
/** The report action that these reactions are for */
reportAction: PropTypes.shape(reportActionPropTypes).isRequired,

/**
* Function to call when the user presses on an emoji.
Expand All @@ -46,6 +49,9 @@ function ReportActionItemEmojiReactions(props) {

let totalReactionCount = 0;

const reportAction = props.reportAction;
const reportActionID = reportAction.reportActionID;

// Each emoji is sorted by the oldest timestamp of user reactions so that they will always appear in the same order for everyone
const sortedReactions = _.sortBy(props.emojiReactions, (emojiReaction, emojiName) => {
// Since the emojiName is only stored as the object key, when _.sortBy() runs, the object is converted to an array and the
Expand Down Expand Up @@ -96,7 +102,7 @@ function ReportActionItemEmojiReactions(props) {
};

const onReactionListOpen = (event) => {
reactionListRef.current.showReactionList(event, popoverReactionListAnchors.current[reactionEmojiName], reactionEmojiName, props.reportActionID);
reactionListRef.current.showReactionList(event, popoverReactionListAnchors.current[reactionEmojiName], reactionEmojiName, reportActionID);
};

return {
Expand All @@ -108,6 +114,7 @@ function ReportActionItemEmojiReactions(props) {
reactionCount,
hasUserReacted,
onReactionListOpen,
pendingAction: reaction.pendingAction,
};
});

Expand All @@ -132,24 +139,29 @@ function ReportActionItemEmojiReactions(props) {
key={reaction.reactionEmojiName}
>
<View>
<EmojiReactionBubble
ref={(ref) => (popoverReactionListAnchors.current[reaction.reactionEmojiName] = ref)}
count={reaction.reactionCount}
emojiCodes={reaction.emojiCodes}
onPress={reaction.onPress}
reactionUsers={reaction.reactionUsers}
hasUserReacted={reaction.hasUserReacted}
onReactionListOpen={reaction.onReactionListOpen}
shouldBlockReactions={props.shouldBlockReactions}
/>
<OfflineWithFeedback
pendingAction={reaction.pendingAction}
shouldDisableOpacity={Boolean(lodashGet(reportAction, 'pendingAction'))}
>
<EmojiReactionBubble
ref={(ref) => (popoverReactionListAnchors.current[reaction.reactionEmojiName] = ref)}
count={reaction.reactionCount}
emojiCodes={reaction.emojiCodes}
onPress={reaction.onPress}
reactionUsers={reaction.reactionUsers}
hasUserReacted={reaction.hasUserReacted}
onReactionListOpen={reaction.onReactionListOpen}
shouldBlockReactions={props.shouldBlockReactions}
/>
</OfflineWithFeedback>
</View>
</Tooltip>
);
})}
{!props.shouldBlockReactions && (
<AddReactionBubble
onSelectEmoji={props.toggleReaction}
reportAction={{reportActionID: props.reportActionID}}
reportAction={{reportActionID}}
/>
)}
</View>
Expand Down
27 changes: 26 additions & 1 deletion src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,7 @@ function addEmojiReaction(reportID, reportActionID, emoji, skinTone = preferredS
value: {
[emoji.name]: {
createdAt,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
users: {
[currentUserAccountID]: {
skinTones: {
Expand All @@ -1754,6 +1755,30 @@ function addEmojiReaction(reportID, reportActionID, emoji, skinTone = preferredS
},
];

const failureData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`,
value: {
[emoji.name]: {
pendingAction: null,
},
},
},
];

const successData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`,
value: {
[emoji.name]: {
pendingAction: null,
},
},
},
];

const parameters = {
reportID,
skinTone,
Expand All @@ -1763,7 +1788,7 @@ function addEmojiReaction(reportID, reportActionID, emoji, skinTone = preferredS
// This will be removed as part of https://github.com/Expensify/App/issues/19535
useEmojiReactions: true,
};
API.write('AddEmojiReaction', parameters, {optimisticData});
API.write('AddEmojiReaction', parameters, {optimisticData, successData, failureData});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ function ReportActionItem(props) {
{!ReportActionsUtils.isMessageDeleted(props.action) && (
<View style={draftMessageRightAlign}>
<ReportActionItemEmojiReactions
reportActionID={props.action.reportActionID}
reportAction={props.action}
emojiReactions={props.emojiReactions}
shouldBlockReactions={hasErrors}
toggleReaction={(emoji) => {
Expand Down
Loading