Skip to content

Commit

Permalink
Merge branch 'main' into fix-auto-focus-on-reply-in-thread
Browse files Browse the repository at this point in the history
  • Loading branch information
FitseTLT committed Mar 21, 2024
2 parents 4c34830 + 96716fb commit 31db23e
Show file tree
Hide file tree
Showing 81 changed files with 3,493 additions and 571 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deployExpensifyHelp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca
id: deploy
if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork)
with:
apiToken: ${{ secrets.CLOUDFLARE_PAGES_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/platformDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ jobs:
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GCP_GEOLOCATION_API_KEY: $${{ secrets.GCP_GEOLOCATION_API_KEY_PRODUCTION }}


- name: Build staging desktop app
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
Expand All @@ -168,6 +170,7 @@ jobs:
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GCP_GEOLOCATION_API_KEY: $${{ secrets.GCP_GEOLOCATION_API_KEY_STAGING }}

iOS:
name: Build and deploy iOS
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/testBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ jobs:
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GCP_GEOLOCATION_API_KEY: $${{ secrets.GCP_GEOLOCATION_API_KEY_STAGING }}

web:
name: Build and deploy Web
Expand Down
5 changes: 5 additions & 0 deletions assets/images/document-plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion desktop/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const {DESKTOP_SHORTCUT_ACCELERATOR, LOCALES} = CONST;
// Setup google api key in process environment, we are setting it this way intentionally. It is required by the
// geolocation api (window.navigator.geolocation.getCurrentPosition) to work on desktop.
// Source: https://github.com/electron/electron/blob/98cd16d336f512406eee3565be1cead86514db7b/docs/api/environment-variables.md#google_api_key
process.env.GOOGLE_API_KEY = CONFIG.GOOGLE_GEOLOCATION_API_KEY;
process.env.GOOGLE_API_KEY = CONFIG.GCP_GEOLOCATION_API_KEY;

app.setName('New Expensify');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ For a quick snapshot of how Expensify Chat works, and New Expensify in general,

# What’s Expensify Chat?

Expensify Chat is an instant messaging and payment platform. You can manage all your payments, wether for business or personal, and discuss the transactions themselves.
Expensify Chat is an instant messaging and payment platform. You can manage all your payments, whether for business or personal, and discuss the transactions themselves.

With Expensify Chat, you can start a conversation about that missing receipt your employee forgot to submit or chat about splitting that electric bill with your roommates. Expensify makes sending and receiving money as easy as sending and receiving messages. Chat with anyone directly, in groups, or in rooms.

Expand Down
4 changes: 2 additions & 2 deletions src/CONFIG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const secureExpensifyUrl = Url.addTrailingForwardSlash(get(Config, 'SECURE_EXPEN
const useNgrok = get(Config, 'USE_NGROK', 'false') === 'true';
const useWebProxy = get(Config, 'USE_WEB_PROXY', 'true') === 'true';
const expensifyComWithProxy = getPlatform() === 'web' && useWebProxy ? '/' : expensifyURL;
const googleGeolocationAPIKey = get(Config, 'GOOGLE_GEOLOCATION_API_KEY', 'AIzaSyBqg6bMvQU7cPWDKhhzpYqJrTEnSorpiLI');
const googleGeolocationAPIKey = get(Config, 'GCP_GEOLOCATION_API_KEY', '');

// Throw errors on dev if config variables are not set correctly
if (ENVIRONMENT === CONST.ENVIRONMENT.DEV) {
Expand Down Expand Up @@ -94,5 +94,5 @@ export default {
WEB_CLIENT_ID: '921154746561-gpsoaqgqfuqrfsjdf8l7vohfkfj7b9up.apps.googleusercontent.com',
IOS_CLIENT_ID: '921154746561-s3uqn2oe4m85tufi6mqflbfbuajrm2i3.apps.googleusercontent.com',
},
GOOGLE_GEOLOCATION_API_KEY: googleGeolocationAPIKey,
GCP_GEOLOCATION_API_KEY: googleGeolocationAPIKey,
} as const;
7 changes: 7 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ const CONST = {
BETA_COMMENT_LINKING: 'commentLinking',
VIOLATIONS: 'violations',
REPORT_FIELDS: 'reportFields',
TRACK_EXPENSE: 'trackExpense',
P2P_DISTANCE_REQUESTS: 'p2pDistanceRequests',
WORKFLOWS_DELAYED_SUBMISSION: 'workflowsDelayedSubmission',
},
Expand All @@ -358,6 +359,7 @@ const CONST = {
NOT_INSTALLED: 'not-installed',
},
TAX_RATES: {
CUSTOM_NAME_MAX_LENGTH: 8,
NAME_MAX_LENGTH: 50,
},
PLATFORM: {
Expand Down Expand Up @@ -1344,6 +1346,7 @@ const CONST = {
SEND: 'send',
SPLIT: 'split',
REQUEST: 'request',
TRACK_EXPENSE: 'track-expense',
},
REQUEST_TYPE: {
DISTANCE: 'distance',
Expand All @@ -1358,6 +1361,7 @@ const CONST = {
CANCEL: 'cancel',
DELETE: 'delete',
APPROVE: 'approve',
TRACK: 'track',
},
AMOUNT_MAX_LENGTH: 10,
RECEIPT_STATE: {
Expand Down Expand Up @@ -3414,6 +3418,9 @@ const CONST = {

REPORT_FIELD_TITLE_FIELD_ID: 'text_title',

MOBILE_PAGINATION_SIZE: 15,
WEB_PAGINATION_SIZE: 50,

/** Dimensions for illustration shown in Confirmation Modal */
CONFIRM_CONTENT_SVG_SIZE: {
HEIGHT: 220,
Expand Down
2 changes: 0 additions & 2 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ const ONYXKEYS = {
POLICY_TAGS: 'policyTags_',
POLICY_RECENTLY_USED_TAGS: 'nvp_recentlyUsedTags_',
OLD_POLICY_RECENTLY_USED_TAGS: 'policyRecentlyUsedTags_',
POLICY_REPORT_FIELDS: 'policyReportFields_',
WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_',
WORKSPACE_INVITE_MESSAGE_DRAFT: 'workspaceInviteMessageDraft_',
REPORT: 'report_',
Expand Down Expand Up @@ -500,7 +499,6 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMembers;
[ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS]: OnyxTypes.PolicyMember;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories;
[ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS]: OnyxTypes.PolicyReportFields;
[ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMembers;
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: OnyxTypes.InvitedEmailsToAccountIDs;
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MESSAGE_DRAFT]: string;
Expand Down
12 changes: 6 additions & 6 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,9 @@ const ROUTES = {
getUrlWithBackToParam(`create/${iouType}/taxAmount/${transactionID}/${reportID}`, backTo),
},
MONEY_REQUEST_STEP_CATEGORY: {
route: ':action/:iouType/category/:transactionID/:reportID',
getRoute: (action: ValueOf<typeof CONST.IOU.ACTION>, iouType: ValueOf<typeof CONST.IOU.TYPE>, transactionID: string, reportID: string, backTo = '') =>
getUrlWithBackToParam(`${action}/${iouType}/category/${transactionID}/${reportID}`, backTo),
route: ':action/:iouType/category/:transactionID/:reportID/:reportActionID?',
getRoute: (action: ValueOf<typeof CONST.IOU.ACTION>, iouType: ValueOf<typeof CONST.IOU.TYPE>, transactionID: string, reportID: string, backTo = '', reportActionID?: string) =>
getUrlWithBackToParam(`${action}/${iouType}/category/${transactionID}/${reportID}${reportActionID ? `/${reportActionID}` : ''}`, backTo),
},
MONEY_REQUEST_STEP_CURRENCY: {
route: 'create/:iouType/currency/:transactionID/:reportID/:pageIndex?',
Expand All @@ -347,9 +347,9 @@ const ROUTES = {
getUrlWithBackToParam(`${action}/${iouType}/date/${transactionID}/${reportID}`, backTo),
},
MONEY_REQUEST_STEP_DESCRIPTION: {
route: ':action/:iouType/description/:transactionID/:reportID',
getRoute: (action: ValueOf<typeof CONST.IOU.ACTION>, iouType: ValueOf<typeof CONST.IOU.TYPE>, transactionID: string, reportID: string, backTo = '') =>
getUrlWithBackToParam(`${action}/${iouType}/description/${transactionID}/${reportID}`, backTo),
route: ':action/:iouType/description/:transactionID/:reportID/:reportActionID?',
getRoute: (action: ValueOf<typeof CONST.IOU.ACTION>, iouType: ValueOf<typeof CONST.IOU.TYPE>, transactionID: string, reportID: string, backTo = '', reportActionID?: string) =>
getUrlWithBackToParam(`${action}/${iouType}/description/${transactionID}/${reportID}${reportActionID ? `/${reportActionID}` : ''}`, backTo),
},
MONEY_REQUEST_STEP_DISTANCE: {
route: 'create/:iouType/distance/:transactionID/:reportID',
Expand Down
2 changes: 1 addition & 1 deletion src/components/AvatarWithDisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function AvatarWithDisplayName({
const title = ReportUtils.getReportName(report);
const subtitle = ReportUtils.getChatRoomSubtitle(report);
const parentNavigationSubtitleData = ReportUtils.getParentNavigationSubtitle(report);
const isMoneyRequestOrReport = ReportUtils.isMoneyRequestReport(report) || ReportUtils.isMoneyRequest(report);
const isMoneyRequestOrReport = ReportUtils.isMoneyRequestReport(report) || ReportUtils.isMoneyRequest(report) || ReportUtils.isTrackExpenseReport(report);
const icons = ReportUtils.getIcons(report, personalDetails, null, '', -1, policy);
const ownerPersonalDetails = OptionsListUtils.getPersonalDetailsForAccountIDs(report?.ownerAccountID ? [report.ownerAccountID] : [], personalDetails);
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails) as PersonalDetails[], false);
Expand Down
16 changes: 8 additions & 8 deletions src/components/FlatList/MVCPFlatList.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ const MVCPFlatList = React.forwardRef(({maintainVisibleContentPosition, horizont
if (scrollRef.current == null) {
return 0;
}
return horizontal ? scrollRef.current.getScrollableNode().scrollLeft : scrollRef.current.getScrollableNode().scrollTop;
return horizontal ? scrollRef.current?.getScrollableNode()?.scrollLeft : scrollRef.current?.getScrollableNode()?.scrollTop;
}, [horizontal]);

const getContentView = React.useCallback(() => scrollRef.current?.getScrollableNode().childNodes[0], []);
const getContentView = React.useCallback(() => scrollRef.current?.getScrollableNode()?.childNodes[0], []);

const scrollToOffset = React.useCallback(
(offset, animated) => {
const behavior = animated ? 'smooth' : 'instant';
scrollRef.current?.getScrollableNode().scroll(horizontal ? {left: offset, behavior} : {top: offset, behavior});
scrollRef.current?.getScrollableNode()?.scroll(horizontal ? {left: offset, behavior} : {top: offset, behavior});
},
[horizontal],
);
Expand All @@ -68,12 +68,13 @@ const MVCPFlatList = React.forwardRef(({maintainVisibleContentPosition, horizont
}

const scrollOffset = getScrollOffset();
lastScrollOffsetRef.current = scrollOffset;

const contentViewLength = contentView.childNodes.length;
for (let i = mvcpMinIndexForVisible; i < contentViewLength; i++) {
const subview = contentView.childNodes[i];
const subviewOffset = horizontal ? subview.offsetLeft : subview.offsetTop;
if (subviewOffset > scrollOffset || i === contentViewLength - 1) {
if (subviewOffset > scrollOffset) {
prevFirstVisibleOffsetRef.current = subviewOffset;
firstVisibleViewRef.current = subview;
break;
Expand Down Expand Up @@ -126,6 +127,7 @@ const MVCPFlatList = React.forwardRef(({maintainVisibleContentPosition, horizont
}

adjustForMaintainVisibleContentPosition();
prepareForMaintainVisibleContentPosition();
});
});
mutationObserver.observe(contentView, {
Expand All @@ -135,7 +137,7 @@ const MVCPFlatList = React.forwardRef(({maintainVisibleContentPosition, horizont
});

mutationObserverRef.current = mutationObserver;
}, [adjustForMaintainVisibleContentPosition, getContentView, getScrollOffset, scrollToOffset]);
}, [adjustForMaintainVisibleContentPosition, prepareForMaintainVisibleContentPosition, getContentView, getScrollOffset, scrollToOffset]);

React.useEffect(() => {
if (!isListRenderedRef.current) {
Expand Down Expand Up @@ -172,13 +174,11 @@ const MVCPFlatList = React.forwardRef(({maintainVisibleContentPosition, horizont

const onScrollInternal = React.useCallback(
(ev) => {
lastScrollOffsetRef.current = getScrollOffset();

prepareForMaintainVisibleContentPosition();

onScroll?.(ev);
},
[getScrollOffset, prepareForMaintainVisibleContentPosition, onScroll],
[prepareForMaintainVisibleContentPosition, onScroll],
);

return (
Expand Down
7 changes: 1 addition & 6 deletions src/components/HoldMenuSectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,7 @@ function HoldMenuSectionList() {
/>
<View style={[styles.flex1, styles.justifyContentCenter]}>
<Text style={[styles.textStrong, styles.mb1]}>{translate(section.titleTranslationKey)}</Text>
<Text
style={[styles.textNormal]}
numberOfLines={3}
>
{translate(section.descriptionTranslationKey)}
</Text>
<Text style={[styles.textNormal]}>{translate(section.descriptionTranslationKey)}</Text>
</View>
</View>
))}
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import Concierge from '@assets/images/concierge.svg';
import Connect from '@assets/images/connect.svg';
import Copy from '@assets/images/copy.svg';
import CreditCard from '@assets/images/creditcard.svg';
import DocumentPlus from '@assets/images/document-plus.svg';
import DocumentSlash from '@assets/images/document-slash.svg';
import Document from '@assets/images/document.svg';
import DotIndicatorUnfilled from '@assets/images/dot-indicator-unfilled.svg';
Expand Down Expand Up @@ -314,4 +315,5 @@ export {
ChatBubbleUnread,
ChatBubbleReply,
Lightbulb,
DocumentPlus,
};
34 changes: 24 additions & 10 deletions src/components/InvertedFlatList/BaseInvertedFlatList.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import type {ForwardedRef} from 'react';
import React, {forwardRef} from 'react';
import type {FlatListProps} from 'react-native';
import React, {forwardRef, useMemo} from 'react';
import type {FlatListProps, ScrollViewProps} from 'react-native';
import FlatList from '@components/FlatList';

const WINDOW_SIZE = 15;
type BaseInvertedFlatListProps<T> = FlatListProps<T> & {
shouldEnableAutoScrollToTopThreshold?: boolean;
};

const AUTOSCROLL_TO_TOP_THRESHOLD = 128;

const maintainVisibleContentPosition = {
minIndexForVisible: 0,
autoscrollToTopThreshold: AUTOSCROLL_TO_TOP_THRESHOLD,
};
function BaseInvertedFlatList<T>(props: BaseInvertedFlatListProps<T>, ref: ForwardedRef<FlatList>) {
const {shouldEnableAutoScrollToTopThreshold, ...rest} = props;

const maintainVisibleContentPosition = useMemo(() => {
const config: ScrollViewProps['maintainVisibleContentPosition'] = {
// This needs to be 1 to avoid using loading views as anchors.
minIndexForVisible: 1,
};

if (shouldEnableAutoScrollToTopThreshold) {
config.autoscrollToTopThreshold = AUTOSCROLL_TO_TOP_THRESHOLD;
}

return config;
}, [shouldEnableAutoScrollToTopThreshold]);

function BaseInvertedFlatList<T>(props: FlatListProps<T>, ref: ForwardedRef<FlatList>) {
return (
<FlatList
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
{...rest}
ref={ref}
windowSize={WINDOW_SIZE}
maintainVisibleContentPosition={maintainVisibleContentPosition}
inverted
/>
Expand All @@ -27,3 +39,5 @@ function BaseInvertedFlatList<T>(props: FlatListProps<T>, ref: ForwardedRef<Flat
BaseInvertedFlatList.displayName = 'BaseInvertedFlatList';

export default forwardRef(BaseInvertedFlatList);

export {AUTOSCROLL_TO_TOP_THRESHOLD};
6 changes: 5 additions & 1 deletion src/components/InvertedFlatList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import CONST from '@src/CONST';
import BaseInvertedFlatList from './BaseInvertedFlatList';
import CellRendererComponent from './CellRendererComponent';

type InvertedFlatListProps<T> = FlatListProps<T> & {
shouldEnableAutoScrollToTopThreshold?: boolean;
};

// This is adapted from https://codesandbox.io/s/react-native-dsyse
// It's a HACK alert since FlatList has inverted scrolling on web
function InvertedFlatList<T>({onScroll: onScrollProp = () => {}, ...props}: FlatListProps<T>, ref: ForwardedRef<FlatList>) {
function InvertedFlatList<T>({onScroll: onScrollProp = () => {}, ...props}: InvertedFlatListProps<T>, ref: ForwardedRef<FlatList>) {
const lastScrollEvent = useRef<number | null>(null);
const scrollEndTimeout = useRef<NodeJS.Timeout | null>(null);
const updateInProgress = useRef<boolean>(false);
Expand Down
10 changes: 9 additions & 1 deletion src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,14 @@ function MoneyRequestConfirmationList({
description={translate('common.description')}
onPress={() => {
Navigation.navigate(
ROUTES.MONEY_REQUEST_STEP_DESCRIPTION.getRoute(CONST.IOU.ACTION.EDIT, iouType, transaction?.transactionID ?? '', reportID, Navigation.getActiveRouteWithoutParams()),
ROUTES.MONEY_REQUEST_STEP_DESCRIPTION.getRoute(
CONST.IOU.ACTION.EDIT,
iouType,
transaction?.transactionID ?? '',
reportID,
Navigation.getActiveRouteWithoutParams(),
reportActionID,
),
);
}}
style={styles.moneyRequestMenuItem}
Expand Down Expand Up @@ -757,6 +764,7 @@ function MoneyRequestConfirmationList({
transaction?.transactionID ?? '',
reportID,
Navigation.getActiveRouteWithoutParams(),
reportActionID,
),
);
}}
Expand Down
Loading

0 comments on commit 31db23e

Please sign in to comment.