Skip to content
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
6 changes: 6 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2650,6 +2650,12 @@ const CONST = {
EVENTS: {
SCROLLING: 'scrolling',
},
HORIZONTAL_SPACER: {
DEFAULT_BORDER_BOTTOM_WIDTH: 1,
DEFAULT_MARGIN_VERTICAL: 8,
HIDDEN_MARGIN_VERTICAL: 0,
HIDDEN_BORDER_BOTTOM_WIDTH: 0,
},
} as const;

export default CONST;
6 changes: 5 additions & 1 deletion src/components/ReportActionItem/MoneyReportView.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import variables from '../../styles/variables';
import * as CurrencyUtils from '../../libs/CurrencyUtils';
import EmptyStateBackgroundImage from '../../../assets/images/empty-state_background-fade.png';
import useLocalize from '../../hooks/useLocalize';
import SpacerView from '../SpacerView';

const propTypes = {
/** The report currently being looked at */
Expand Down Expand Up @@ -66,7 +67,10 @@ function MoneyReportView(props) {
</Text>
</View>
</View>
{props.shouldShowHorizontalRule && <View style={styles.reportHorizontalRule} />}
<SpacerView
shouldShow={props.shouldShowHorizontalRule}
style={[props.shouldShowHorizontalRule ? styles.reportHorizontalRule : {}]}
/>
</View>
);
}
Expand Down
6 changes: 5 additions & 1 deletion src/components/ReportActionItem/MoneyRequestView.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Image from '../Image';
import ReportActionItemImage from './ReportActionItemImage';
import * as TransactionUtils from '../../libs/TransactionUtils';
import OfflineWithFeedback from '../OfflineWithFeedback';
import SpacerView from '../SpacerView';

const propTypes = {
/** The report currently being looked at */
Expand Down Expand Up @@ -169,7 +170,10 @@ function MoneyRequestView({report, parentReport, shouldShowHorizontalRule, trans
subtitleTextStyle={styles.textLabelError}
/>
</OfflineWithFeedback>
{shouldShowHorizontalRule && <View style={styles.reportHorizontalRule} />}
<SpacerView
shouldShow={shouldShowHorizontalRule}
style={[shouldShowHorizontalRule ? styles.reportHorizontalRule : {}]}
/>
</View>
);
}
Expand Down
6 changes: 5 additions & 1 deletion src/components/ReportActionItem/TaskView.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import getButtonState from '../../libs/getButtonState';
import PressableWithSecondaryInteraction from '../PressableWithSecondaryInteraction';
import * as Session from '../../libs/actions/Session';
import * as Expensicons from '../Icon/Expensicons';
import SpacerView from '../SpacerView';

const propTypes = {
/** The report currently being looked at */
Expand Down Expand Up @@ -158,7 +159,10 @@ function TaskView(props) {
/>
)}
</OfflineWithFeedback>
{props.shouldShowHorizontalRule && <View style={styles.reportHorizontalRule} />}
<SpacerView
shouldShow={props.shouldShowHorizontalRule}
style={[props.shouldShowHorizontalRule ? styles.reportHorizontalRule : {}]}
/>
</View>
);
}
Expand Down
49 changes: 49 additions & 0 deletions src/components/SpacerView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import PropTypes from 'prop-types';
import * as StyleUtils from '../styles/StyleUtils';
import stylePropTypes from '../styles/stylePropTypes';
import CONST from '../CONST';

const propTypes = {
/**
* Should we show the spacer
*/
shouldShow: PropTypes.bool.isRequired,

/**
* Array of style objects
* @default []
*/
style: stylePropTypes,
};

const defaultProps = {
style: [],
};

function SpacerView({shouldShow = true, style = []}) {
const marginVertical = useSharedValue(CONST.HORIZONTAL_SPACER.DEFAULT_MARGIN_VERTICAL);
const borderBottomWidth = useSharedValue(CONST.HORIZONTAL_SPACER.DEFAULT_BORDER_BOTTOM_WIDTH);
const animatedStyles = useAnimatedStyle(() => ({
marginVertical: marginVertical.value,
borderBottomWidth: borderBottomWidth.value,
}));

React.useEffect(() => {
const duration = CONST.ANIMATED_TRANSITION;
const values = {
marginVertical: shouldShow ? CONST.HORIZONTAL_SPACER.DEFAULT_MARGIN_VERTICAL : CONST.HORIZONTAL_SPACER.HIDDEN_MARGIN_VERTICAL,
borderBottomWidth: shouldShow ? CONST.HORIZONTAL_SPACER.DEFAULT_BORDER_BOTTOM_WIDTH : CONST.HORIZONTAL_SPACER.HIDDEN_BORDER_BOTTOM_WIDTH,
};
marginVertical.value = withTiming(values.marginVertical, {duration});
borderBottomWidth.value = withTiming(values.borderBottomWidth, {duration});
}, [shouldShow, borderBottomWidth, marginVertical]);

return <Animated.View style={[animatedStyles, ...StyleUtils.parseStyleAsArray(style)]} />;
}

SpacerView.displayName = 'SpacerView';
SpacerView.propTypes = propTypes;
SpacerView.defaultProps = defaultProps;
export default SpacerView;
34 changes: 21 additions & 13 deletions src/pages/home/report/ReportActionsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function ReportActionsList({
const {isOffline} = useNetwork();
const opacity = useSharedValue(0);
const userActiveSince = useRef(null);
const currentUnreadMarker = useRef(null);
const [currentUnreadMarker, setCurrentUnreadMarker] = useState(null);
const scrollingVerticalOffset = useRef(0);
const readActionSkipped = useRef(false);
const reportActionSize = useRef(sortedReportActions.length);
Expand Down Expand Up @@ -158,12 +158,12 @@ function ReportActionsList({
}
}

if (currentUnreadMarker.current || reportActionSize.current === sortedReportActions.length) {
if (currentUnreadMarker || reportActionSize.current === sortedReportActions.length) {
return;
}

reportActionSize.current = sortedReportActions.length;
currentUnreadMarker.current = null;
setCurrentUnreadMarker(null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sortedReportActions.length, report.reportID]);

Expand All @@ -175,7 +175,7 @@ function ReportActionsList({
}

// Clearing the current unread marker so that it can be recalculated
currentUnreadMarker.current = null;
setCurrentUnreadMarker(null);
setMessageManuallyMarked({read: true});

// We only care when a new lastReadTime is set in the report
Expand Down Expand Up @@ -224,7 +224,7 @@ function ReportActionsList({
* Show/hide the new floating message counter when user is scrolling back/forth in the history of messages.
*/
const handleUnreadFloatingButton = () => {
if (scrollingVerticalOffset.current > VERTICAL_OFFSET_THRESHOLD && !isFloatingMessageCounterVisible && !!currentUnreadMarker.current) {
if (scrollingVerticalOffset.current > VERTICAL_OFFSET_THRESHOLD && !isFloatingMessageCounterVisible && !!currentUnreadMarker) {
setIsFloatingMessageCounterVisible(true);
}

Expand Down Expand Up @@ -260,6 +260,15 @@ function ReportActionsList({
return Math.ceil(availableHeight / minimumReportActionHeight);
}, [windowHeight]);

/**
* Thread's divider line should hide when the first chat in the thread is marked as unread.
* This is so that it will not be conflicting with header's separator line.
*/
const shouldHideThreadDividerLine = useMemo(
() => sortedReportActions.length > 1 && sortedReportActions[sortedReportActions.length - 2].reportActionID === currentUnreadMarker,
[sortedReportActions, currentUnreadMarker],
);

/**
* @param {Object} args
* @param {Number} args.index
Expand All @@ -269,7 +278,7 @@ function ReportActionsList({
({item: reportAction, index}) => {
let shouldDisplayNewMarker = false;

if (!currentUnreadMarker.current) {
if (!currentUnreadMarker) {
const nextMessage = sortedReportActions[index + 1];
const isCurrentMessageUnread = isMessageUnread(reportAction, report.lastReadTime);
shouldDisplayNewMarker = isCurrentMessageUnread && !isMessageUnread(nextMessage, report.lastReadTime);
Expand All @@ -279,18 +288,17 @@ function ReportActionsList({
}
const canDisplayMarker = scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD ? reportAction.created < userActiveSince.current : true;

if (!currentUnreadMarker.current && shouldDisplayNewMarker && canDisplayMarker) {
currentUnreadMarker.current = reportAction.reportActionID;
if (!currentUnreadMarker && shouldDisplayNewMarker && canDisplayMarker) {
setCurrentUnreadMarker(reportAction.reportActionID);
}
} else {
shouldDisplayNewMarker = reportAction.reportActionID === currentUnreadMarker.current;
shouldDisplayNewMarker = reportAction.reportActionID === currentUnreadMarker;
}

const shouldDisplayParentAction =
reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED &&
ReportUtils.isChatThread(report) &&
!ReportActionsUtils.isTransactionThread(ReportActionsUtils.getParentReportAction(report));
const shouldHideThreadDividerLine = sortedReportActions.length > 1 && sortedReportActions[sortedReportActions.length - 2].reportActionID === currentUnreadMarker.current;

return shouldDisplayParentAction ? (
<ReportActionItemParentAction
Expand All @@ -316,19 +324,19 @@ function ReportActionsList({
/>
);
},
[report, hasOutstandingIOU, sortedReportActions, mostRecentIOUReportActionID, messageManuallyMarked],
[report, hasOutstandingIOU, sortedReportActions, mostRecentIOUReportActionID, messageManuallyMarked, shouldHideThreadDividerLine, currentUnreadMarker],
);

// Native mobile does not render updates flatlist the changes even though component did update called.
// To notify there something changes we can use extraData prop to flatlist
const extraData = [isSmallScreenWidth ? currentUnreadMarker.current : undefined, ReportUtils.isArchivedRoom(report)];
const extraData = [isSmallScreenWidth ? currentUnreadMarker : undefined, ReportUtils.isArchivedRoom(report)];
const hideComposer = ReportUtils.shouldDisableWriteActions(report);
const shouldShowReportRecipientLocalTime = ReportUtils.canShowReportRecipientLocalTime(personalDetailsList, report, currentUserPersonalDetails.accountID) && !isComposerFullSize;

return (
<>
<FloatingMessageCounter
isActive={isFloatingMessageCounterVisible && !!currentUnreadMarker.current}
isActive={isFloatingMessageCounterVisible && !!currentUnreadMarker}
onClick={scrollToBottomAndMarkReportAsRead}
/>
<Animated.View style={[animatedStyles, styles.flex1, !shouldShowReportRecipientLocalTime && !hideComposer ? styles.pb4 : {}]}>
Expand Down
2 changes: 0 additions & 2 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3614,10 +3614,8 @@ const styles = (theme) => ({
},

reportHorizontalRule: {
borderBottomWidth: 1,
borderColor: theme.border,
...spacing.mh5,
...spacing.mv2,
},

assigneeTextStyle: {
Expand Down