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

Performance: chat input #25758

Merged
merged 101 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
17d4889
Merge branch 'migrate-composer-fc-web' of github.com:margelo/expensif…
hannojg Aug 4, 2023
91b7d91
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 4, 2023
9f1cac2
move reportactioncompose to own folder
hannojg Aug 4, 2023
12405c3
first refactor
hannojg Aug 4, 2023
0cab4a4
temp: hack good performance
hannojg Aug 4, 2023
9a8201b
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 7, 2023
ea26c2c
fix issues after
hannojg Aug 7, 2023
b002f08
enabled suggestions
hannojg Aug 7, 2023
5042b4b
add value prop back
hannojg Aug 7, 2023
1bf0177
use `insertedEmojis` ref correctly
hannojg Aug 7, 2023
3ab1ca4
add selection change back
hannojg Aug 7, 2023
9ec7169
fix issue with menu closing instantly
hannojg Aug 7, 2023
cfc7b25
pass callbacks
hannojg Aug 7, 2023
e7d3a95
call bloc calculations
hannojg Aug 7, 2023
1156d61
wip
hannojg Aug 7, 2023
eb2892c
Merge branch 'migrate-composer-fc-web' of github.com:margelo/expensif…
hannojg Aug 8, 2023
a7a489a
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 8, 2023
e247161
fix split implementations of suggestions
hannojg Aug 8, 2023
9739c08
wip: split out SendButton & AttachmentPickerWithMenu
hannojg Aug 8, 2023
eb9baf8
wip: simplify code
hannojg Aug 8, 2023
6673ba4
Revert "wip: simplify code"
hannojg Aug 9, 2023
730f4c9
Revert "wip: split out SendButton & AttachmentPickerWithMenu"
hannojg Aug 9, 2023
b846cbe
Split out SendButton component
hannojg Aug 9, 2023
33b8e4b
wip: splitting out AttachmentPicker
hannojg Aug 9, 2023
45a8842
wip: splitting out AttachmentPicker
hannojg Aug 9, 2023
ba38175
wip: split out SendButton & AttachmentPickerWithMenu
hannojg Aug 9, 2023
433d616
wip: move menu items calc to separate component
hannojg Aug 9, 2023
3e957a3
Merge branch 'main' of github.com:margelo/expensify-app-fork into ref…
hannojg Aug 10, 2023
74bd410
Merge branch 'migrate-composer-fc-web' of github.com:margelo/expensif…
hannojg Aug 10, 2023
ff18a4f
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 10, 2023
575046d
wip: move composer to its own component
hannojg Aug 10, 2023
cdefcc6
remove unused prop
hannojg Aug 10, 2023
e820194
wip: move composer to its own component
hannojg Aug 10, 2023
dca3df8
wip: Split out composer
hannojg Aug 10, 2023
7f73769
Add UpdateComment component
hannojg Aug 10, 2023
1a5454f
don't make triggerHotkeyActions depend on value
hannojg Aug 10, 2023
0bfc0b7
Suggestions remove unused props
hannojg Aug 10, 2023
3d4403e
add suggestions back
hannojg Aug 11, 2023
ad4b571
moved over updating frequently used emojis
hannojg Aug 11, 2023
3ee30c9
fix show popover menu
hannojg Aug 11, 2023
557c8d0
enable ExceededCommentLength again
hannojg Aug 11, 2023
3f591e2
forward reportActions
hannojg Aug 11, 2023
52fc6e8
cleanup forward ref code according to common pattern
hannojg Aug 11, 2023
040688c
clean
hannojg Aug 11, 2023
ef17bab
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 11, 2023
7edceee
Apply fixes from origin PR
hannojg Aug 11, 2023
0b5f770
fix update component updating too often
hannojg Aug 11, 2023
5b9336d
fix crash
hannojg Aug 11, 2023
b175eae
Merge branch 'main' into refactor-report-action-compose
hannojg Aug 15, 2023
46a252a
Merge branch '@stas-kravchuk/16263-migrate-reportactioncompose-to-fun…
hannojg Aug 15, 2023
5b61e12
reapply https://github.com/Expensify/App/pull/18648/commits/8554863fa…
hannojg Aug 15, 2023
af6d104
reapply https://github.com/Expensify/App/pull/18648/commits/e209754a3…
hannojg Aug 15, 2023
45947dd
reapply https://github.com/Expensify/App/pull/18648/commits/267188322…
hannojg Aug 15, 2023
eaa3440
reapply https://github.com/Expensify/App/pull/18648/commits/479f31714…
hannojg Aug 15, 2023
1641dc0
reapply https://github.com/Expensify/App/pull/18648/commits/cd6d115ea…
hannojg Aug 15, 2023
d76106b
reapply https://github.com/Expensify/App/pull/18648/commits/a96be820f…
hannojg Aug 15, 2023
f174b04
reapply https://github.com/Expensify/App/pull/18648/commits/dc4ceeaa2…
hannojg Aug 15, 2023
066f980
reapply https://github.com/Expensify/App/pull/18648/commits/a6c309e46…
hannojg Aug 15, 2023
8b2c37f
Merge branch 'main' of github.com:margelo/expensify-app-fork into ref…
hannojg Aug 21, 2023
baa5e8b
reapply https://github.com/Expensify/App/commit/6319e59c29bf7304654e4…
hannojg Aug 21, 2023
893b7e2
fix isFullComposerAvailable
hannojg Aug 21, 2023
6870d17
fix initial isFocused state
hannojg Aug 21, 2023
f1398ce
Use tryGetCachedValue for draft comment
hannojg Aug 21, 2023
ea6f00b
remove todo
hannojg Aug 21, 2023
905c9b5
remove unneeded code
hannojg Aug 21, 2023
10c55b3
move `personalDetails` to onyx
hannojg Aug 21, 2023
f4b9079
fix mention suggestion picker size
hannojg Aug 21, 2023
448d358
fix crash opening attachment picker
hannojg Aug 21, 2023
4968fb1
move to existing pattern
hannojg Aug 22, 2023
a3ea498
migrate also the modal state to established pattern
hannojg Aug 22, 2023
7081e15
remove debug log
hannojg Aug 22, 2023
91d210c
fix suggestion height position
hannojg Aug 22, 2023
8596920
fix suggestions not showing on clicking again into composer
hannojg Aug 22, 2023
9d05dab
use hooks instead of HOCs
hannojg Aug 22, 2023
0b987fa
remove debug code
hannojg Aug 22, 2023
8e8d5c4
rename ReportComposerWithSuggestions -> ComposerWithSuggestions
hannojg Aug 22, 2023
6a7b82e
prop types
hannojg Aug 22, 2023
c02fdac
fix tests
hannojg Aug 22, 2023
72e2bbf
Merge branch 'main' of github.com:Expensify/App into refactor-report-…
hannojg Aug 23, 2023
cf5d835
apply changes to ReportActionCompose
hannojg Aug 23, 2023
ebd8e74
perf: don't update lines when we don't have to
hannojg Aug 23, 2023
28426ce
change name
hannojg Aug 23, 2023
95a0193
fix prop type issues
hannojg Aug 23, 2023
3e3c6ed
fix lint
hannojg Aug 23, 2023
cf6cf7a
Update src/pages/home/report/ReportActionCompose/suggestionProps.js
hannojg Aug 24, 2023
6ab1ccf
Update src/pages/home/report/ReportActionCompose/SendButton.js
hannojg Aug 24, 2023
0dd4773
removed todos
hannojg Aug 24, 2023
b4936ec
Merge branch 'main' of github.com:Expensify/App into refactor-report-…
hannojg Aug 24, 2023
f2f397e
fix issues after merge
hannojg Aug 24, 2023
c3792d6
add blur function
hannojg Aug 24, 2023
9826f49
Merge branch 'main' into refactor-report-action-compose
hannojg Aug 24, 2023
9b7c07b
foc focus state
hannojg Aug 24, 2023
893137a
fix IOU options not showing up
hannojg Aug 24, 2023
faf1e15
fix crash
hannojg Aug 24, 2023
ad30918
remove unused import
hannojg Aug 24, 2023
bd22c57
Merge branch 'main' of github.com:Expensify/App into refactor-report-…
hannojg Aug 25, 2023
5e93ecf
reapply changes
hannojg Aug 25, 2023
1e97af0
fix lint + pass measure callback
hannojg Aug 25, 2023
0ccd7ae
move prop types to separate file
hannojg Aug 25, 2023
89b569d
move libs/ComposerUtils/debouncedSaveReportComment
hannojg Aug 25, 2023
e64a5d9
fix marking reports as draft when opening
hannojg Aug 25, 2023
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import PropTypes from 'prop-types';
import refPropType from '../refPropTypes';

const propTypes = {
/** Array of suggestions */
Expand Down Expand Up @@ -29,16 +28,12 @@ const propTypes = {
/** create accessibility label for each item */
accessibilityLabelExtractor: PropTypes.func.isRequired,

/** Ref of the container enclosing the menu.
* This is needed to render the menu in correct position inside a portal
*/
parentContainerRef: refPropType,
/** Meaures the parent container's position and dimensions. */
measureParentContainer: PropTypes.func,
};

const defaultProps = {
parentContainerRef: {
current: null,
},
measureParentContainer: () => {},
};

export {propTypes, defaultProps};
14 changes: 7 additions & 7 deletions src/components/EmojiSuggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as EmojiUtils from '../libs/EmojiUtils';
import Text from './Text';
import getStyledTextArray from '../libs/GetStyledTextArray';
import AutoCompleteSuggestions from './AutoCompleteSuggestions';
import refPropType from './refPropTypes';

const propTypes = {
/** The index of the highlighted emoji */
Expand Down Expand Up @@ -47,13 +46,14 @@ const propTypes = {
/** Stores user's preferred skin tone */
preferredSkinToneIndex: PropTypes.number.isRequired,

/** Ref of the container enclosing the menu.
* This is needed to render the menu in correct position inside a portal
*/
containerRef: refPropType,
/** Meaures the parent container's position and dimensions. */
measureParentContainer: PropTypes.func,
};

const defaultProps = {highlightedEmojiIndex: 0, containerRef: {current: null}};
const defaultProps = {
highlightedEmojiIndex: 0,
measureParentContainer: () => {},
};

/**
* Create unique keys for each emoji item
Expand Down Expand Up @@ -104,7 +104,7 @@ function EmojiSuggestions(props) {
isSuggestionPickerLarge={props.isEmojiPickerLarge}
shouldIncludeReportRecipientLocalTimeHeight={props.shouldIncludeReportRecipientLocalTimeHeight}
accessibilityLabelExtractor={keyExtractor}
parentContainerRef={props.containerRef}
measureParentContainer={props.measureParentContainer}
/>
);
}
Expand Down
22 changes: 19 additions & 3 deletions src/components/ExceededCommentLength.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import React, {useEffect, useState, useMemo} from 'react';
import PropTypes from 'prop-types';
import {debounce} from 'lodash';
import {withOnyx} from 'react-native-onyx';
import CONST from '../CONST';
import * as ReportUtils from '../libs/ReportUtils';
import Text from './Text';
import styles from '../styles/styles';
import ONYXKEYS from '../ONYXKEYS';

const propTypes = {
/** Report ID to get the comment from (used in withOnyx) */
// eslint-disable-next-line react/no-unused-prop-types
reportID: PropTypes.string.isRequired,

/** Text Comment */
comment: PropTypes.string.isRequired,
comment: PropTypes.string,

/** Update UI on parent when comment length is exceeded */
onExceededMaxCommentLength: PropTypes.func.isRequired,
};

const defaultProps = {
comment: '',
};

function ExceededCommentLength(props) {
const [commentLength, setCommentLength] = useState(0);
const updateCommentLength = useMemo(
Expand All @@ -38,5 +48,11 @@ function ExceededCommentLength(props) {
}

ExceededCommentLength.propTypes = propTypes;

export default ExceededCommentLength;
ExceededCommentLength.defaultProps = defaultProps;
ExceededCommentLength.displayName = 'ExceededCommentLength';

export default withOnyx({
comment: {
key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`,
},
})(ExceededCommentLength);
13 changes: 4 additions & 9 deletions src/components/MentionSuggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Avatar from './Avatar';
import AutoCompleteSuggestions from './AutoCompleteSuggestions';
import getStyledTextArray from '../libs/GetStyledTextArray';
import avatarPropTypes from './avatarPropTypes';
import refPropType from './refPropTypes';

const propTypes = {
/** The index of the highlighted mention */
Expand Down Expand Up @@ -44,17 +43,13 @@ const propTypes = {
/** Show that we should include ReportRecipientLocalTime view height */
shouldIncludeReportRecipientLocalTimeHeight: PropTypes.bool.isRequired,

/** Ref of the container enclosing the menu.
* This is needed to render the menu in correct position inside a portal
*/
containerRef: refPropType,
/** Meaures the parent container's position and dimensions. */
measureParentContainer: PropTypes.func,
};

const defaultProps = {
highlightedMentionIndex: 0,
containerRef: {
current: null,
},
measureParentContainer: () => {},
};

/**
Expand Down Expand Up @@ -131,7 +126,7 @@ function MentionSuggestions(props) {
isSuggestionPickerLarge={props.isMentionPickerLarge}
shouldIncludeReportRecipientLocalTimeHeight={props.shouldIncludeReportRecipientLocalTimeHeight}
accessibilityLabelExtractor={keyExtractor}
parentContainerRef={props.containerRef}
measureParentContainer={props.measureParentContainer}
/>
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/libs/ComposerUtils/debouncedSaveReportComment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import _ from 'underscore';
import * as Report from '../actions/Report';

/**
* Save draft report comment. Debounced to happen at most once per second.
* @param {String} reportID
* @param {String} comment
*/
const debouncedSaveReportComment = _.debounce((reportID, comment) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused a regression of showing draft icon - more information here - #27362 (comment)

Report.saveReportComment(reportID, comment || '');
}, 1000);

export default debouncedSaveReportComment;
24 changes: 24 additions & 0 deletions src/libs/ComposerUtils/getDraftComment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '../../ONYXKEYS';

const draftCommentMap = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT,
callback: (value, key) => {
if (!key) return;

const reportID = key.replace(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, '');
draftCommentMap[reportID] = value;
},
});

/**
* Returns a draft comment from the onyx collection.
* Note: You should use the HOCs/hooks to get onyx data, instead of using this directly.
* A valid use case to use this is if the value is only needed once for an initial value.
* @param {String} reportID
* @returns {String|undefined}
*/
export default function getDraftComment(reportID) {
Copy link
Member

@rushatgabhane rushatgabhane Aug 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using onyx connect to get initial draft value? Why not just use the HOC?

Is this some optimization to get all draft comments for all reports on app start?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to explain this in the comment above. The use case here is, that we only need the value for the initial value of a state variable. If we'd use the HOC the component would re-render every time the value (draft comment) changes, which is something we specifically want to avoid for performance reasons.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return draftCommentMap[reportID];
}
29 changes: 29 additions & 0 deletions src/libs/SuggestionUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import CONST from '../CONST';

/**
* Return the max available index for arrow manager.
* @param {Number} numRows
* @param {Boolean} isAutoSuggestionPickerLarge
* @returns {Number}
*/
function getMaxArrowIndex(numRows, isAutoSuggestionPickerLarge) {
// rowCount is number of emoji/mention suggestions. For small screen we can fit 3 items
// and for large we show up to 20 items for mentions/emojis
const rowCount = isAutoSuggestionPickerLarge
? Math.min(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_SUGGESTIONS)
: Math.min(numRows, CONST.AUTO_COMPLETE_SUGGESTER.MIN_AMOUNT_OF_SUGGESTIONS);

// -1 because we start at 0
return rowCount - 1;
}

/**
* Trims first character of the string if it is a space
* @param {String} str
* @returns {String}
*/
function trimLeadingSpace(str) {
return str.slice(0, 1) === ' ' ? str.slice(1) : str;
}

export {getMaxArrowIndex, trimLeadingSpace};
21 changes: 21 additions & 0 deletions src/libs/getModalState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '../ONYXKEYS';

let modalState = {};

Onyx.connect({
key: ONYXKEYS.MODAL,
callback: (val) => {
modalState = val;
},
});

/**
* Returns the modal state from onyx.
* Note: You should use the HOCs/hooks to get onyx data, instead of using this directly.
* A valid use case to use this is if the value is only needed once for an initial value.
* @returns {Object}
*/
export default function getModalState() {
return modalState;
hannojg marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading