Skip to content

Commit

Permalink
Merge branch 'Expensify:main' into fix/38277
Browse files Browse the repository at this point in the history
  • Loading branch information
ishpaul777 authored Mar 15, 2024
2 parents 8388946 + 2abedcd commit 11a1261
Show file tree
Hide file tree
Showing 55 changed files with 502 additions and 165 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deployExpensifyHelp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ jobs:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: helpdot
directory: ./docs/_site
# Add the conditional on this step to prevent execution for pull requests from forks
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository

- name: Setup Cloudflare CLI
run: pip3 install cloudflare==2.19.0
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001045200
versionName "1.4.52-0"
versionCode 1001045301
versionName "1.4.53-1"
}

flavorDimensions "default"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Act as a Copilot
description: How to access another account after being granted Copilot permissions
---
<div id="expensify-classic" markdown="1">

After being assigned as a Copilot, you can access the account you’ve been given Copilot permissions to via the Expensify website or the mobile app.

{% include selector.html values="desktop, mobile" %}

{% include option.html value="desktop" %}
To switch to Copilot mode,
1. Click your profile icon in the upper left side of the page.
2. In the “Copilot Access” section of the dropdown, choose the account you wish to access.

The Expensify header will change to blue, and an airplane icon will appear to show that you are in copilot mode. You can return to your own account any time by clicking your profile icon and selecting **Return to your account**.

{% include end-option.html %}

{% include option.html value="mobile" %}
To switch to Copilot mode,
1. Tap the menu icon in the top left.
2. Tap your profile icon.
3. Tap **Switch to Copilot Mode** and choose the account.

An airplane icon will appear to show that you are in copilot mode. To return to your own account, follow the same steps above and select **Return to your account**.

{% include end-option.html %}

{% include end-selector.html %}

# FAQs

**Can a Copilot’s secondary login be used to forward receipts?**

Yes, a Copilot can use any of the email addresses tied to their account to forward receipts into the account they are copiloting. To ensure a receipt is routed to the Expensify account you are copiloting instead of your own account, email the receipt to receipts@expensify.com with the email address of the account you are copiloting as the subject line of the email.

**Can I add another copilot to an account that I’m copiloting?**

No, only the original account holder can add another Copilot to their account.

</div>
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.52</string>
<string>1.4.53</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.52.0</string>
<string>1.4.53.1</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.52</string>
<string>1.4.53</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.52.0</string>
<string>1.4.53.1</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleShortVersionString</key>
<string>1.4.52</string>
<string>1.4.53</string>
<key>CFBundleVersion</key>
<string>1.4.52.0</string>
<string>1.4.53.1</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.52-0",
"version": "1.4.53-1",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
6 changes: 3 additions & 3 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ const ONYXKEYS = {
ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
ADD_DEBIT_CARD_FORM_DRAFT: 'addDebitCardFormDraft',
WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
WORKSPACE_CATEGORY_CREATE_FORM: 'workspaceCategoryCreate',
WORKSPACE_CATEGORY_CREATE_FORM_DRAFT: 'workspaceCategoryCreateDraft',
WORKSPACE_CATEGORY_FORM: 'workspaceCategoryForm',
WORKSPACE_CATEGORY_FORM_DRAFT: 'workspaceCategoryFormDraft',
WORKSPACE_TAG_CREATE_FORM: 'workspaceTagCreate',
WORKSPACE_TAG_CREATE_FORM_DRAFT: 'workspaceTagCreateDraft',
WORKSPACE_SETTINGS_FORM_DRAFT: 'workspaceSettingsFormDraft',
Expand Down Expand Up @@ -417,7 +417,7 @@ type AllOnyxKeys = DeepValueOf<typeof ONYXKEYS>;
type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: FormTypes.AddDebitCardForm;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: FormTypes.WorkspaceSettingsForm;
[ONYXKEYS.FORMS.WORKSPACE_CATEGORY_CREATE_FORM]: FormTypes.WorkspaceCategoryCreateForm;
[ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM]: FormTypes.WorkspaceCategoryForm;
[ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM]: FormTypes.WorkspaceTagCreateForm;
[ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: FormTypes.WorkspaceRateAndUnitForm;
[ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: FormTypes.CloseAccountForm;
Expand Down
6 changes: 5 additions & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ const ROUTES = {
},
WORKSPACE_CATEGORY_SETTINGS: {
route: 'settings/workspaces/:policyID/categories/:categoryName',
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURI(categoryName)}` as const,
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURIComponent(categoryName)}` as const,
},
WORKSPACE_CATEGORIES_SETTINGS: {
route: 'settings/workspaces/:policyID/categories/settings',
Expand All @@ -569,6 +569,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/categories/new',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/categories/new` as const,
},
WORKSPACE_CATEGORY_EDIT: {
route: 'workspace/:policyID/categories/:categoryName/edit',
getRoute: (policyID: string, categoryName: string) => `workspace/${policyID}/categories/${encodeURI(categoryName)}/edit` as const,
},
WORKSPACE_TAGS: {
route: 'settings/workspaces/:policyID/tags',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/tags` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ const SCREENS = {
SHARE: 'Workspace_Profile_Share',
NAME: 'Workspace_Profile_Name',
CATEGORY_CREATE: 'Category_Create',
CATEGORY_EDIT: 'Category_Edit',
CATEGORY_SETTINGS: 'Category_Settings',
CATEGORIES_SETTINGS: 'Categories_Settings',
MORE_FEATURES: 'Workspace_More_Features',
Expand Down
3 changes: 1 addition & 2 deletions src/components/AvatarCropModal/AvatarCropModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,8 @@ function AvatarCropModal({imageUri = '', imageName = '', imageType = '', onClose
>
<View>
<Button
medium
icon={Expensicons.Rotate}
iconFill={theme.inverse}
iconFill={theme.icon}
onPress={rotateImage}
/>
</View>
Expand Down
1 change: 1 addition & 0 deletions src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ function Button(
<View style={[large ? styles.mr2 : styles.mr1, !text && styles.mr0, iconStyles]}>
<Icon
src={icon}
hasText={!!text}
fill={iconFill ?? (success || danger ? theme.textLight : theme.icon)}
small={small}
medium={medium}
Expand Down
2 changes: 1 addition & 1 deletion src/components/DistanceRequest/DistanceRequestFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig
onPress={() => navigateToWaypointEditPage(Object.keys(transaction?.comment?.waypoints ?? {}).length)}
text={translate('distance.addStop')}
isDisabled={numberOfWaypoints === MAX_WAYPOINTS}
innerStyles={[styles.ph10]}
innerStyles={[styles.pl10, styles.pr10]}
/>
</View>
)}
Expand Down
1 change: 1 addition & 0 deletions src/components/EmojiPicker/EmojiPickerMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ function EmojiPickerMenu({forwardedRef, onEmojiSelected, activeEmoji}) {
disableHorizontalKeys: isFocused,
// We pass true without checking visibility of the component because if the popover is not visible this picker won't be mounted
isActive: true,
allowNegativeIndexes: true,
});

const filterEmojis = _.throttle((searchTerm) => {
Expand Down
6 changes: 5 additions & 1 deletion src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type IconProps = {
/** Is icon pressed */
pressed?: boolean;

/** Is icon will be used with text */
hasText?: boolean;

/** Additional styles to add to the Icon */
additionalStyles?: StyleProp<ViewStyle>;

Expand All @@ -56,6 +59,7 @@ function Icon({
height = variables.iconSizeNormal,
fill = undefined,
small = false,
hasText = false,
large = false,
medium = false,
inline = false,
Expand All @@ -67,7 +71,7 @@ function Icon({
}: IconProps) {
const StyleUtils = useStyleUtils();
const styles = useThemeStyles();
const {width: iconWidth, height: iconHeight} = StyleUtils.getIconWidthAndHeightStyle(small, medium, large, width, height);
const {width: iconWidth, height: iconHeight} = StyleUtils.getIconWidthAndHeightStyle(small, medium, large, width, height, hasText);
const iconStyles = [StyleUtils.getWidthAndHeightStyle(width ?? 0, height), IconWrapperStyles, styles.pAbsolute, additionalStyles];

if (inline) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ type MenuItemBaseProps = {
onSecondaryInteraction?: (event: GestureResponderEvent | MouseEvent) => void;

/** Array of objects that map display names to their corresponding tooltip */
titleWithTooltips?: DisplayNameWithTooltip[];
titleWithTooltips?: DisplayNameWithTooltip[] | undefined;

/** Icon should be displayed in its own color */
displayInDefaultIconColor?: boolean;
Expand Down
10 changes: 5 additions & 5 deletions src/components/VideoPlayerContexts/PlaybackContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ function PlaybackContextProvider({children}: ChildrenProps) {
const {currentReportID} = useCurrentReportID() ?? {};

const pauseVideo = useCallback(() => {
currentVideoPlayerRef.current?.setStatusAsync({shouldPlay: false});
currentVideoPlayerRef.current?.setStatusAsync?.({shouldPlay: false});
}, [currentVideoPlayerRef]);

const stopVideo = useCallback(() => {
currentVideoPlayerRef.current?.stopAsync();
currentVideoPlayerRef.current?.stopAsync?.();
}, [currentVideoPlayerRef]);

const playVideo = useCallback(() => {
currentVideoPlayerRef.current?.getStatusAsync().then((status) => {
currentVideoPlayerRef.current?.getStatusAsync?.().then((status) => {
const newStatus: AVPlaybackStatusToSet = {shouldPlay: true};
if ('durationMillis' in status && status.durationMillis === status.positionMillis) {
newStatus.positionMillis = 0;
Expand All @@ -33,7 +33,7 @@ function PlaybackContextProvider({children}: ChildrenProps) {
}, [currentVideoPlayerRef]);

const unloadVideo = useCallback(() => {
currentVideoPlayerRef.current?.unloadAsync();
currentVideoPlayerRef.current?.unloadAsync?.();
}, [currentVideoPlayerRef]);

const updateCurrentlyPlayingURL = useCallback(
Expand Down Expand Up @@ -61,7 +61,7 @@ function PlaybackContextProvider({children}: ChildrenProps) {

const checkVideoPlaying = useCallback(
(statusCallback: StatusCallback) => {
currentVideoPlayerRef.current?.getStatusAsync().then((status) => {
currentVideoPlayerRef.current?.getStatusAsync?.().then((status) => {
statusCallback('isPlaying' in status && status.isPlaying);
});
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function VideoPopoverMenuContextProvider({children}: ChildrenProps) {
const updatePlaybackSpeed = useCallback(
(speed: PlaybackSpeed) => {
setCurrentPlaybackSpeed(speed);
currentVideoPlayerRef.current?.setStatusAsync({rate: speed});
currentVideoPlayerRef.current?.setStatusAsync?.({rate: speed});
},
[currentVideoPlayerRef],
);
Expand Down
19 changes: 15 additions & 4 deletions src/hooks/useArrowKeyFocusManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Config = {
itemsPerRow?: number;
disableCyclicTraversal?: boolean;
disableHorizontalKeys?: boolean;
allowNegativeIndexes?: boolean;
};

type UseArrowKeyFocusManager = [number, (index: number) => void];
Expand Down Expand Up @@ -44,6 +45,7 @@ export default function useArrowKeyFocusManager({
itemsPerRow,
disableCyclicTraversal = false,
disableHorizontalKeys = false,
allowNegativeIndexes = false,
}: Config): UseArrowKeyFocusManager {
const allowHorizontalArrowKeys = !!itemsPerRow;
const [focusedIndex, setFocusedIndex] = useState(initialFocusedIndex);
Expand Down Expand Up @@ -84,7 +86,13 @@ export default function useArrowKeyFocusManager({
while (disabledIndexes.includes(newFocusedIndex)) {
newFocusedIndex -= allowHorizontalArrowKeys ? itemsPerRow : 1;
if (newFocusedIndex < 0) {
break;
if (disableCyclicTraversal) {
if (!allowNegativeIndexes) {
return actualIndex;
}
break;
}
newFocusedIndex = maxIndex;
}
if (newFocusedIndex === currentFocusedIndex) {
// all indexes are disabled
Expand All @@ -93,7 +101,7 @@ export default function useArrowKeyFocusManager({
}
return newFocusedIndex;
});
}, [allowHorizontalArrowKeys, disableCyclicTraversal, disabledIndexes, itemsPerRow, maxIndex]);
}, [allowHorizontalArrowKeys, disableCyclicTraversal, disabledIndexes, itemsPerRow, maxIndex, allowNegativeIndexes]);

useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ARROW_UP, arrowUpCallback, arrowConfig);

Expand Down Expand Up @@ -127,8 +135,11 @@ export default function useArrowKeyFocusManager({
newFocusedIndex += allowHorizontalArrowKeys ? itemsPerRow : 1;
}

if (newFocusedIndex < 0) {
break;
if (newFocusedIndex > maxIndex) {
if (disableCyclicTraversal) {
return actualIndex;
}
newFocusedIndex = 0;
}
if (newFocusedIndex === currentFocusedIndex) {
// all indexes are disabled
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,7 @@ export default {
},
genericFailureMessage: 'An error occurred while updating the category, please try again.',
addCategory: 'Add category',
editCategory: 'Edit category',
categoryRequiredError: 'Category name is required.',
existingCategoryError: 'A category with this name already exists.',
invalidCategoryName: 'Invalid category name.',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,7 @@ export default {
},
genericFailureMessage: 'Se ha producido un error al intentar eliminar la categoría. Por favor, inténtalo más tarde.',
addCategory: 'Añadir categoría',
editCategory: 'Editar categoría',
categoryRequiredError: 'Lo nombre de la categoría es obligatorio.',
existingCategoryError: 'Ya existe una categoría con este nombre.',
invalidCategoryName: 'Lo nombre de la categoría es invalido.',
Expand Down
10 changes: 10 additions & 0 deletions src/libs/API/parameters/RenameWorkspaceCategoriesParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type RenameWorkspaceCategoriesParams = {
policyID: string;
/**
* Stringified JSON object with type of following structure:
* {[oldName: string]: string;} where value is new category name
*/
categories: string;
};

export default RenameWorkspaceCategoriesParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export type {default as UpdateWorkspaceDescriptionParams} from './UpdateWorkspac
export type {default as UpdateWorkspaceMembersRoleParams} from './UpdateWorkspaceMembersRoleParams';
export type {default as SetWorkspaceCategoriesEnabledParams} from './SetWorkspaceCategoriesEnabledParams';
export type {default as CreateWorkspaceCategoriesParams} from './CreateWorkspaceCategoriesParams';
export type {default as RenameWorkspaceCategoriesParams} from './RenameWorkspaceCategoriesParams';
export type {default as SetWorkspaceRequiresCategoryParams} from './SetWorkspaceRequiresCategoryParams';
export type {default as DeleteWorkspaceCategoriesParams} from './DeleteWorkspaceCategoriesParams';
export type {default as SetWorkspaceAutoReportingParams} from './SetWorkspaceAutoReportingParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const WRITE_COMMANDS = {
CREATE_WORKSPACE_FROM_IOU_PAYMENT: 'CreateWorkspaceFromIOUPayment',
SET_WORKSPACE_CATEGORIES_ENABLED: 'SetWorkspaceCategoriesEnabled',
CREATE_WORKSPACE_CATEGORIES: 'CreateWorkspaceCategories',
RENAME_WORKSPACE_CATEGORY: 'RenameWorkspaceCategory',
CREATE_POLICY_TAG: 'CreatePolicyTag',
SET_WORKSPACE_REQUIRES_CATEGORY: 'SetWorkspaceRequiresCategory',
DELETE_WORKSPACE_CATEGORIES: 'DeleteWorkspaceCategories',
Expand Down Expand Up @@ -282,6 +283,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.CREATE_WORKSPACE_FROM_IOU_PAYMENT]: Parameters.CreateWorkspaceFromIOUPaymentParams;
[WRITE_COMMANDS.SET_WORKSPACE_CATEGORIES_ENABLED]: Parameters.SetWorkspaceCategoriesEnabledParams;
[WRITE_COMMANDS.CREATE_WORKSPACE_CATEGORIES]: Parameters.CreateWorkspaceCategoriesParams;
[WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY]: Parameters.RenameWorkspaceCategoriesParams;
[WRITE_COMMANDS.SET_WORKSPACE_REQUIRES_CATEGORY]: Parameters.SetWorkspaceRequiresCategoryParams;
[WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES]: Parameters.DeleteWorkspaceCategoriesParams;
[WRITE_COMMANDS.SET_POLICY_REQUIRES_TAG]: Parameters.SetPolicyRequiresTag;
Expand Down
Loading

0 comments on commit 11a1261

Please sign in to comment.