Skip to content

Commit

Permalink
Refactor report footer and move shouldShowComposeInput out of ReportS…
Browse files Browse the repository at this point in the history
…creen
  • Loading branch information
marcaaron committed Sep 29, 2022
1 parent 60d933e commit 150cad6
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 87 deletions.
3 changes: 3 additions & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,7 @@ export default {
ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
REQUEST_CALL_FORM: 'requestCallForm',
},

// Whether we should show the compose input or not
SHOULD_SHOW_COMPOSE_INPUT: 'shouldShowComposeInput',
};
14 changes: 14 additions & 0 deletions src/libs/actions/Composer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '../../ONYXKEYS';

/**
* @param {Boolean} shouldShowComposeInput
*/
function setShouldShowComposeInput(shouldShowComposeInput) {
Onyx.set(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT, shouldShowComposeInput);
}

export {
// eslint-disable-next-line import/prefer-default-export
setShouldShowComposeInput,
};
10 changes: 1 addition & 9 deletions src/libs/actions/Session/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ Onyx.connect({
function setSuccessfulSignInData(data) {
PushNotification.register(data.accountID);
Onyx.merge(ONYXKEYS.SESSION, {
shouldShowComposeInput: true,
errors: null,
..._.pick(data, 'authToken', 'accountID', 'email', 'encryptedAuthToken'),
});
Onyx.set(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT, true);
}

/**
Expand Down Expand Up @@ -566,13 +566,6 @@ function authenticatePusher(socketID, channelName, callback) {
});
}

/**
* @param {Boolean} shouldShowComposeInput
*/
function setShouldShowComposeInput(shouldShowComposeInput) {
Onyx.merge(ONYXKEYS.SESSION, {shouldShowComposeInput});
}

export {
beginSignIn,
updatePasswordAndSignin,
Expand All @@ -589,7 +582,6 @@ export {
validateEmail,
authenticatePusher,
reauthenticatePusher,
setShouldShowComposeInput,
changePasswordAndSignIn,
invalidateCredentials,
invalidateAuthToken,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/toggleReportActionComposeView/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as Session from '../actions/Session';
import * as Composer from '../actions/Composer';

export default (shouldShowComposeInput, isSmallScreenWidth = true) => {
if (!isSmallScreenWidth) {
return;
}

Session.setShouldShowComposeInput(shouldShowComposeInput);
Composer.setShouldShowComposeInput(shouldShowComposeInput);
};
4 changes: 2 additions & 2 deletions src/libs/toggleReportActionComposeView/index.native.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import * as Session from '../actions/Session';
import * as Composer from '../actions/Composer';

export default shouldShowComposeInput => Session.setShouldShowComposeInput(shouldShowComposeInput);
export default shouldShowComposeInput => Composer.setShouldShowComposeInput(shouldShowComposeInput);
85 changes: 13 additions & 72 deletions src/pages/home/ReportScreen.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import {Keyboard, Platform, View} from 'react-native';
import {Platform, View} from 'react-native';
import lodashGet from 'lodash/get';
import _ from 'underscore';
import lodashFindLast from 'lodash/findLast';
import styles from '../../styles/styles';
import ScreenWrapper from '../../components/ScreenWrapper';
import HeaderView from './HeaderView';
Expand All @@ -15,21 +14,19 @@ import ONYXKEYS from '../../ONYXKEYS';
import Permissions from '../../libs/Permissions';
import * as ReportUtils from '../../libs/ReportUtils';
import ReportActionsView from './report/ReportActionsView';
import ReportActionCompose from './report/ReportActionCompose';
import SwipeableView from '../../components/SwipeableView';
import CONST from '../../CONST';
import ReportActionsSkeletonView from '../../components/ReportActionsSkeletonView';
import reportActionPropTypes from './report/reportActionPropTypes';
import ArchivedReportFooter from '../../components/ArchivedReportFooter';
import toggleReportActionComposeView from '../../libs/toggleReportActionComposeView';
import addViewportResizeListener from '../../libs/VisualViewport';
import {withNetwork} from '../../components/OnyxProvider';
import compose from '../../libs/compose';
import networkPropTypes from '../../components/networkPropTypes';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
import OfflineIndicator from '../../components/OfflineIndicator';
import OfflineWithFeedback from '../../components/OfflineWithFeedback';
import withDrawerState, {withDrawerPropTypes} from '../../components/withDrawerState';
import ReportFooter from './report/ReportFooter';
import reportPropTypes from './report/reportPropTypes';

const propTypes = {
/** Navigation route context info provided by react navigation */
Expand All @@ -44,25 +41,8 @@ const propTypes = {
/** Tells us if the sidebar has rendered */
isSidebarLoaded: PropTypes.bool,

/** Whether or not to show the Compose Input */
session: PropTypes.shape({
shouldShowComposeInput: PropTypes.bool,
}),

/** The report currently being looked at */
report: PropTypes.shape({
/** The largest sequenceNumber on this report */
maxSequenceNumber: PropTypes.number,

/** Whether there is an outstanding amount in IOU */
hasOutstandingIOU: PropTypes.bool,

/** Flag to check if the report actions data are loading */
isLoadingReportActions: PropTypes.bool,

/** ID for the report */
reportID: PropTypes.number,
}),
report: reportPropTypes,

/** Array of report actions for this report */
reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)),
Expand Down Expand Up @@ -91,9 +71,6 @@ const propTypes = {

const defaultProps = {
isSidebarLoaded: false,
session: {
shouldShowComposeInput: true,
},
reportActions: {},
report: {
maxSequenceNumber: 0,
Expand Down Expand Up @@ -154,10 +131,6 @@ class ReportScreen extends React.Component {
Report.addComment(getReportID(this.props.route), text);
}

setChatFooterStyles(isOffline) {
return {...styles.chatFooter, minHeight: !isOffline ? CONST.CHAT_FOOTER_MIN_HEIGHT : 0};
}

/**
* When reports change there's a brief time content is not ready to be displayed
* It Should show the loader if it's the first time we are opening the report
Expand Down Expand Up @@ -223,15 +196,8 @@ class ReportScreen extends React.Component {
}

const reportID = getReportID(this.props.route);

const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report);
let reportClosedAction;
if (isArchivedRoom) {
reportClosedAction = lodashFindLast(this.props.reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED);
}
const addWorkspaceRoomPendingAction = lodashGet(this.props.report, 'pendingFields.addWorkspaceRoom');
const addWorkspaceRoomErrors = lodashGet(this.props.report, 'errorFields.addWorkspaceRoom');
const hideComposer = isArchivedRoom || !_.isEmpty(addWorkspaceRoomErrors);
return (
<ScreenWrapper
style={[styles.appContent, styles.flex1, {marginTop: this.state.viewportOffsetTop}]}
Expand Down Expand Up @@ -267,40 +233,15 @@ class ReportScreen extends React.Component {
isDrawerOpen={this.props.isDrawerOpen}
/>
)}
{(isArchivedRoom || hideComposer) && (
<View style={[styles.chatFooter]}>
{isArchivedRoom && (
<ArchivedReportFooter
reportClosedAction={reportClosedAction}
report={this.props.report}
/>
)}
{!this.props.isSmallScreenWidth && (
<View style={styles.offlineIndicatorRow}>
{hideComposer && (
<OfflineIndicator containerStyles={[styles.chatItemComposeSecondaryRow]} />
)}
</View>
)}
</View>
)}
{(!hideComposer && this.props.session.shouldShowComposeInput) && (
<View style={[this.setChatFooterStyles(this.props.network.isOffline), this.props.isComposerFullSize && styles.chatFooterFullCompose]}>
<SwipeableView onSwipeDown={Keyboard.dismiss}>
<OfflineWithFeedback
pendingAction={addWorkspaceRoomPendingAction}
>
<ReportActionCompose
onSubmit={this.onSubmitComment}
reportID={reportID}
reportActions={this.props.reportActions}
report={this.props.report}
isComposerFullSize={this.props.isComposerFullSize}
/>
</OfflineWithFeedback>
</SwipeableView>
</View>
)}
<ReportFooter
addWorkspaceRoomErrors={addWorkspaceRoomErrors}
addWorkspaceRoomPendingAction={addWorkspaceRoomPendingAction}
isOffline={this.props.network.isOffline}
reportActions={this.props.reportActions}
report={this.props.report}
isComposerFullSize={this.props.isComposerFullSize}
onSubmitComment={this.props.onSubmitComment}
/>
</View>
</ScreenWrapper>
);
Expand Down
114 changes: 114 additions & 0 deletions src/pages/home/report/ReportFooter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React from 'react';
import _ from 'underscore';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import {View, Keyboard} from 'react-native';
import lodashFindLast from 'lodash/findLast';

import CONST from '../../../CONST';
import ReportActionCompose from './ReportActionCompose';
import * as ReportUtils from '../../../libs/ReportUtils';
import SwipeableView from '../../../components/SwipeableView';
import OfflineIndicator from '../../../components/OfflineIndicator';
import OfflineWithFeedback from '../../../components/OfflineWithFeedback';
import ArchivedReportFooter from '../../../components/ArchivedReportFooter';
import compose from '../../../libs/compose';
import ONYXKEYS from '../../../ONYXKEYS';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import styles from '../../../styles/styles';
import reportActionPropTypes from './reportActionPropTypes';
import reportPropTypes from './reportPropTypes';

const propTypes = {
/** Report object for the current report */
report: reportPropTypes.isRequired,

/** Report actions for the current report */
reportActions: reportActionPropTypes.isRequired,

/** Offline status */
isOffline: PropTypes.bool.isRequired,

/** Any errors associated with an attempt to create a workspace room */
// eslint-disable-next-line react/forbid-prop-types
addWorkspaceRoomErrors: PropTypes.object,

/** The pending action when we are adding a workspace room */
addWorkspaceRoomPendingAction: PropTypes.string,

/** Whether the composer input should be shown */
shouldShowComposeInput: PropTypes.bool,

...windowDimensionsPropTypes,
};

const defaultProps = {
shouldShowComposeInput: true,
addWorkspaceRoomErrors: {},
addWorkspaceRoomPendingAction: '',
};

class ReportFooter extends React.Component {
/**
* @returns {Object}
*/
getChatFooterStyles() {
return {...styles.chatFooter, minHeight: !this.props.isOffline ? CONST.CHAT_FOOTER_MIN_HEIGHT : 0};
}

render() {
const isArchivedRoom = ReportUtils.isArchivedRoom(this.props.report);
let reportClosedAction;
if (isArchivedRoom) {
reportClosedAction = lodashFindLast(this.props.reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED);
}
const hideComposer = isArchivedRoom || !_.isEmpty(this.props.addWorkspaceRoomErrors);
return (
<>
{(isArchivedRoom || hideComposer) && (
<View style={[styles.chatFooter]}>
{isArchivedRoom && (
<ArchivedReportFooter
reportClosedAction={reportClosedAction}
report={this.props.report}
/>
)}
{!this.props.isSmallScreenWidth && (
<View style={styles.offlineIndicatorRow}>
{hideComposer && (
<OfflineIndicator containerStyles={[styles.chatItemComposeSecondaryRow]} />
)}
</View>
)}
</View>
)}
{(!hideComposer && this.props.shouldShowComposeInput) && (
<View style={[this.getChatFooterStyles(), this.props.isComposerFullSize && styles.chatFooterFullCompose]}>
<SwipeableView onSwipeDown={Keyboard.dismiss}>
<OfflineWithFeedback
pendingAction={this.props.addWorkspaceRoomPendingAction}
>
<ReportActionCompose
onSubmit={this.props.onSubmitComment}
reportID={this.props.report.reportID}
reportActions={this.props.reportActions}
report={this.props.report}
isComposerFullSize={this.props.isComposerFullSize}
/>
</OfflineWithFeedback>
</SwipeableView>
</View>
)}
</>
);
}
}

ReportFooter.propTypes = propTypes;
ReportFooter.defaultProps = defaultProps;
export default compose(
withWindowDimensions,
withOnyx({
shouldShowComposeInput: {key: ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT},
}),
)(ReportFooter);
15 changes: 15 additions & 0 deletions src/pages/home/report/reportPropTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import PropTypes from 'prop-types';

export default PropTypes.shape({
/** The largest sequenceNumber on this report */
maxSequenceNumber: PropTypes.number,

/** Whether there is an outstanding amount in IOU */
hasOutstandingIOU: PropTypes.bool,

/** Flag to check if the report actions data are loading */
isLoadingReportActions: PropTypes.bool,

/** ID for the report */
reportID: PropTypes.number,
});
3 changes: 2 additions & 1 deletion src/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ export default function () {
initialKeyStates: {

// Clear any loading and error messages so they do not appear on app startup
[ONYXKEYS.SESSION]: {loading: false, shouldShowComposeInput: true},
[ONYXKEYS.SESSION]: {loading: false},
[ONYXKEYS.ACCOUNT]: CONST.DEFAULT_ACCOUNT_DATA,
[ONYXKEYS.NETWORK]: {isOffline: false},
[ONYXKEYS.IOU]: {
loading: false, error: false, creatingIOUTransaction: false, isRetrievingCurrency: false,
},
[ONYXKEYS.IS_SIDEBAR_LOADED]: false,
[ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT]: true,
},
});

Expand Down
1 change: 0 additions & 1 deletion tests/utils/TestHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ function signInWithTestUser(accountID = 1, login = 'test@user.com', password = '
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.SESSION,
value: {
shouldShowComposeInput: true,
authToken,
accountID,
email: login,
Expand Down

0 comments on commit 150cad6

Please sign in to comment.