diff --git a/src/components/UnreadActionIndicator.js b/src/components/UnreadActionIndicator.js
index 0a3fa8d3d95d..7c6789c0a66a 100644
--- a/src/components/UnreadActionIndicator.js
+++ b/src/components/UnreadActionIndicator.js
@@ -1,29 +1,16 @@
import React from 'react';
-import {Animated, View} from 'react-native';
-import PropTypes from 'prop-types';
-import styles, {getOpacityStyle} from '../styles/styles';
+import {View} from 'react-native';
+import styles from '../styles/styles';
import Text from './Text';
-const propTypes = {
- // Animated opacity
- // eslint-disable-next-line react/forbid-prop-types
- animatedOpacity: PropTypes.object.isRequired,
-};
-
-const UnreadActionIndicator = props => (
-
+const UnreadActionIndicator = () => (
+
NEW
-
+
);
-UnreadActionIndicator.propTypes = propTypes;
UnreadActionIndicator.displayName = 'UnreadActionIndicator';
-
export default UnreadActionIndicator;
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 060f99c8770a..7d0608ce4aa2 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -13,6 +13,7 @@ import PopoverWithMeasuredContent from '../../../components/PopoverWithMeasuredC
import ReportActionItemSingle from './ReportActionItemSingle';
import ReportActionItemGrouped from './ReportActionItemGrouped';
import ReportActionContextMenu from './ReportActionContextMenu';
+import UnreadActionIndicator from '../../../components/UnreadActionIndicator';
const propTypes = {
// The ID of the report this action is on.
@@ -23,6 +24,9 @@ const propTypes = {
// Should the comment have the appearance of being grouped with the previous comment?
displayAsGroup: PropTypes.bool.isRequired,
+
+ // Should we display the new indicator on top of the comment?
+ shouldDisplayNewIndicator: PropTypes.bool.isRequired,
};
class ReportActionItem extends Component {
@@ -46,6 +50,7 @@ class ReportActionItem extends Component {
shouldComponentUpdate(nextProps, nextState) {
return this.state.isPopoverVisible !== nextState.isPopoverVisible
|| this.props.displayAsGroup !== nextProps.displayAsGroup
+ || (this.props.shouldDisplayNewIndicator !== nextProps.shouldDisplayNewIndicator)
|| !_.isEqual(this.props.action, nextProps.action);
}
@@ -85,6 +90,9 @@ class ReportActionItem extends Component {
{hovered => (
+ {!hovered && this.props.shouldDisplayNewIndicator && (
+
+ )}
{!this.props.displayAsGroup
?
diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js
index d41e7a3c0d86..347dd3d5ee48 100644
--- a/src/pages/home/report/ReportActionsView.js
+++ b/src/pages/home/report/ReportActionsView.js
@@ -1,6 +1,5 @@
import React from 'react';
import {
- Animated,
View,
Keyboard,
AppState,
@@ -11,7 +10,6 @@ import _ from 'underscore';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';
import Text from '../../../components/Text';
-import UnreadActionIndicator from '../../../components/UnreadActionIndicator';
import {
fetchActions,
updateLastReadActionID,
@@ -39,6 +37,9 @@ const propTypes = {
report: PropTypes.shape({
// Number of actions unread
unreadActionCount: PropTypes.number,
+
+ // The largest sequenceNumber on this report
+ maxSequenceNumber: PropTypes.number,
}),
// Array of report actions for this report
@@ -54,6 +55,7 @@ const propTypes = {
const defaultProps = {
report: {
unreadActionCount: 0,
+ maxSequenceNumber: 0,
},
reportActions: {},
session: {},
@@ -71,10 +73,10 @@ class ReportActionsView extends React.Component {
this.loadMoreChats = this.loadMoreChats.bind(this);
this.sortedReportActions = [];
this.timers = [];
- this.unreadIndicatorOpacity = new Animated.Value(1);
- // Helper variable that keeps track of the unread action count before it updates to zero
- this.unreadActionCount = 0;
+ this.initialNewMarkerPosition = props.report.unreadActionCount === 0
+ ? 0
+ : (props.report.maxSequenceNumber + 1) - props.report.unreadActionCount;
this.state = {
isLoadingMoreChats: false,
@@ -89,7 +91,6 @@ class ReportActionsView extends React.Component {
this.keyboardEvent = Keyboard.addListener('keyboardDidShow', this.scrollToListBottom);
this.recordMaxAction();
fetchActions(this.props.reportID);
- this.setUpUnreadActionIndicator();
Timing.end(CONST.TIMING.SWITCH_REPORT, CONST.TIMING.COLD);
}
@@ -146,25 +147,6 @@ class ReportActionsView extends React.Component {
}
}
- /**
- * Checks if the unreadActionIndicator should be shown.
- * If it does, starts a timeout for the fading out animation and creates
- * a flag to not show it again if the report is still open
- */
- setUpUnreadActionIndicator() {
- this.unreadActionCount = this.props.report.unreadActionCount;
-
- if (this.unreadActionCount > 0) {
- this.unreadIndicatorOpacity = new Animated.Value(1);
- this.timers.push(setTimeout(() => {
- Animated.timing(this.unreadIndicatorOpacity, {
- toValue: 0,
- useNativeDriver: false,
- }).start();
- }, 3000));
- }
- }
-
/**
* Retrieves the next set of report actions for the chat once we are nearing the end of what we are currently
* displaying.
@@ -232,8 +214,7 @@ class ReportActionsView extends React.Component {
}
/**
- * When the bottom of the list is reached, this is triggered, so it's a little different than recording the max
- * action when scrolled
+ * Recorded when the report first opens and when the list is scrolled to the bottom
*/
recordMaxAction() {
const reportActions = lodashGet(this.props, 'reportActions', {});
@@ -265,8 +246,8 @@ class ReportActionsView extends React.Component {
/**
* This function overrides the CellRendererComponent (defaults to a plain View), giving each ReportActionItem a
- * higher z-index than the one below it. This prevents issues where the ReportActionContextMenu overlapping between
- * rows is hidden beneath other rows.
+ * higher z-index than the one below it. This prevents issues where the ReportActionContextMenu overlapping between
+ * rows is hidden beneath other rows.
*
* @param {Object} index - The ReportAction item in the FlatList.
* @param {Object|Array} style – The default styles of the CellRendererComponent provided by the CellRenderer.
@@ -291,31 +272,21 @@ class ReportActionsView extends React.Component {
* @param {Object} args
* @param {Object} args.item
* @param {Number} args.index
- * @param {Function} args.onLayout
*
* @returns {React.Component}
*/
renderItem({
item,
index,
- onLayout,
}) {
return (
-
- // Using instead of a Fragment because there is a difference between how
- // are implemented on native and web/desktop which leads to
- // the unread indicator on native to render below the message instead of above it.
-
- {this.unreadActionCount > 0 && index === this.unreadActionCount - 1 && (
-
- )}
-
-
+ 0
+ && item.action.sequenceNumber === this.initialNewMarkerPosition}
+ />
);
}
@@ -334,7 +305,6 @@ class ReportActionsView extends React.Component {
);
}
- this.setUpUnreadActionIndicator();
return (
this.actionListElement = el}
diff --git a/src/styles/getReportActionItemStyles.js b/src/styles/getReportActionItemStyles.js
index 20054eb0eef0..7923c085b536 100644
--- a/src/styles/getReportActionItemStyles.js
+++ b/src/styles/getReportActionItemStyles.js
@@ -1,3 +1,4 @@
+import colors from './colors';
import themeColors from './themes/default';
import positioning from './utilities/positioning';
@@ -11,7 +12,11 @@ export function getReportActionItemStyle(isHovered = false) {
return {
display: 'flex',
justifyContent: 'space-between',
- backgroundColor: isHovered ? themeColors.hoverComponentBG : themeColors.componentBG,
+ backgroundColor: isHovered
+ ? themeColors.hoverComponentBG
+
+ // Warning: Setting this to a non-transparent color will cause unread indicator to break on Android
+ : colors.transparent,
cursor: 'default',
};
}
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 0ea54b06c18b..f50e34339a47 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -828,14 +828,6 @@ const styles = {
marginRight: 4,
},
- navigationMenuOpenAbsolute: {
- position: 'absolute',
- left: 0,
- top: 0,
- bottom: 0,
- zIndex: 2,
- },
-
navigationModalOverlay: {
position: 'absolute',
width: '100%',
@@ -1151,6 +1143,7 @@ const styles = {
paddingHorizontal: 20,
flexDirection: 'row',
alignItems: 'center',
+ zIndex: 1,
},
unreadIndicatorLine: {
@@ -1518,14 +1511,6 @@ function getWidthAndHeightStyle(width, height) {
};
}
-/**
- * @param {Number} opacity
- * @returns {Object}
- */
-function getOpacityStyle(opacity) {
- return {opacity};
-}
-
/**
* @param {Object} params
* @returns {Object}
@@ -1564,6 +1549,5 @@ export {
getIconFillColor,
getAnimatedFABStyle,
getWidthAndHeightStyle,
- getOpacityStyle,
getModalPaddingStyles,
};