Skip to content

Commit

Permalink
Merge branch 'main' into Rory-BumpRuby
Browse files Browse the repository at this point in the history
  • Loading branch information
roryabraham committed Aug 29, 2024
2 parents d9b2a34 + 964e6ad commit 8f5ad67
Show file tree
Hide file tree
Showing 48 changed files with 688 additions and 162 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ GEM
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
apktools (0.7.4)
apktools (0.7.5)
rubyzip (~> 2.0)
artifactory (3.0.17)
atomos (0.1.3)
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009002514
versionName "9.0.25-14"
versionCode 1009002602
versionName "9.0.26-2"
// Supported language variants must be declared here to avoid from being removed during the compilation.
// This also helps us to not include unnecessary language variants in the APK.
resConfigs "en", "es"
Expand Down
17 changes: 17 additions & 0 deletions assets/images/caret-up-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Certificates.p12.gpg
Binary file not shown.
Binary file modified ios/NewApp_AdHoc.mobileprovision.gpg
Binary file not shown.
Binary file modified ios/NewApp_AdHoc_Notification_Service.mobileprovision.gpg
Binary file not shown.
Binary file modified ios/NewApp_AppStore.mobileprovision.gpg
Binary file not shown.
Binary file modified ios/NewApp_AppStore_Notification_Service.mobileprovision.gpg
Binary file not shown.
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>9.0.25</string>
<string>9.0.26</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>9.0.25.14</string>
<string>9.0.26.2</string>
<key>FullStory</key>
<dict>
<key>OrgId</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>9.0.25</string>
<string>9.0.26</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>9.0.25.14</string>
<string>9.0.26.2</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>9.0.25</string>
<string>9.0.26</string>
<key>CFBundleVersion</key>
<string>9.0.25.14</string>
<string>9.0.26.2</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "9.0.25-14",
"version": "9.0.26-2",
"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 Expand Up @@ -168,7 +168,7 @@
"react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#da50d2c5c54e268499047f9cc98b8df4196c1ddf",
"react-native-plaid-link-sdk": "11.11.0",
"react-native-qrcode-svg": "git+https://github.com/Expensify/react-native-qrcode-svg-old",
"react-native-quick-sqlite": "git+https://github.com/margelo/react-native-quick-sqlite#abc91857d4b3efb2020ec43abd2a508563b64316",
"react-native-quick-sqlite": "git+https://github.com/margelo/react-native-quick-sqlite#99f34ebefa91698945f3ed26622e002bd79489e0",
"react-native-reanimated": "3.13.0",
"react-native-release-profiler": "^0.2.1",
"react-native-render-html": "6.3.1",
Expand Down
13 changes: 0 additions & 13 deletions patches/react-native-quick-sqlite+8.0.6.patch

This file was deleted.

12 changes: 12 additions & 0 deletions patches/react-pdf+7.7.3.patch
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
diff --git a/node_modules/react-pdf/dist/cjs/Document.js b/node_modules/react-pdf/dist/cjs/Document.js
index 9bb0398..032d898 100644
--- a/node_modules/react-pdf/dist/cjs/Document.js
+++ b/node_modules/react-pdf/dist/cjs/Document.js
@@ -289,6 +289,7 @@ const Document = (0, react_1.forwardRef)(function Document(_a, ref) {
pdfDispatch({ type: 'REJECT', error });
});
return () => {
+ loadingTask._worker.destroy();
loadingTask.destroy();
};
}
diff --git a/node_modules/react-pdf/dist/esm/Document.js b/node_modules/react-pdf/dist/esm/Document.js
index b1c5a81..569769e 100644
--- a/node_modules/react-pdf/dist/esm/Document.js
Expand Down
5 changes: 5 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ const CONST = {
REPORT_FIELDS_FEATURE: 'reportFieldsFeature',
WORKSPACE_FEEDS: 'workspaceFeeds',
NETSUITE_USA_TAX: 'netsuiteUsaTax',
NEW_DOT_COPILOT: 'newDotCopilot',
WORKSPACE_RULES: 'workspaceRules',
COMBINED_TRACK_SUBMIT: 'combinedTrackSubmit',
},
Expand Down Expand Up @@ -3877,6 +3878,10 @@ const CONST = {
ENABLED: 'ENABLED',
DISABLED: 'DISABLED',
},
DELEGATE_ROLE: {
SUBMITTER: 'submitter',
ALL: 'all',
},
STRIPE_GBP_AUTH_STATUSES: {
SUCCEEDED: 'succeeded',
CARD_AUTHENTICATION_REQUIRED: 'authentication_required',
Expand Down
202 changes: 202 additions & 0 deletions src/components/AccountSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import React, {useRef, useState} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import usePermissions from '@hooks/usePermissions';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {clearDelegatorErrors, connect, disconnect} from '@libs/actions/Delegate';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
import variables from '@styles/variables';
import * as Modal from '@userActions/Modal';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails} from '@src/types/onyx';
import Avatar from './Avatar';
import ConfirmModal from './ConfirmModal';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import type {MenuItemProps} from './MenuItem';
import MenuItemList from './MenuItemList';
import type {MenuItemWithLink} from './MenuItemList';
import Popover from './Popover';
import {PressableWithFeedback} from './Pressable';
import Text from './Text';

function AccountSwitcher() {
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const {canUseNewDotCopilot} = usePermissions();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const buttonRef = useRef<HTMLDivElement>(null);

const [shouldShowDelegatorMenu, setShouldShowDelegatorMenu] = useState(false);
const [shouldShowOfflineModal, setShouldShowOfflineModal] = useState(false);
const delegators = account?.delegatedAccess?.delegators ?? [];

const isActingAsDelegate = !!account?.delegatedAccess?.delegate ?? false;
const canSwitchAccounts = canUseNewDotCopilot && (delegators.length > 0 || isActingAsDelegate);

const createBaseMenuItem = (personalDetails: PersonalDetails | undefined, error?: TranslationPaths, additionalProps: MenuItemWithLink = {}): MenuItemWithLink => {
return {
title: personalDetails?.displayName ?? personalDetails?.login,
description: personalDetails?.login,
avatarID: personalDetails?.accountID ?? -1,
icon: personalDetails?.avatar ?? '',
iconType: CONST.ICON_TYPE_AVATAR,
outerWrapperStyle: shouldUseNarrowLayout ? {} : styles.accountSwitcherPopover,
numberOfLinesDescription: 1,
errorText: error ? translate(error) : '',
shouldShowRedDotIndicator: !!error,
errorTextStyle: styles.mt2,
...additionalProps,
};
};

const menuItems = (): MenuItemProps[] => {
const currentUserMenuItem = createBaseMenuItem(currentUserPersonalDetails, undefined, {
wrapperStyle: [styles.buttonDefaultBG],
focused: true,
shouldShowRightIcon: true,
iconRight: Expensicons.Checkmark,
success: true,
key: `${currentUserPersonalDetails?.login}-current`,
});

if (isActingAsDelegate) {
const delegateEmail = account?.delegatedAccess?.delegate ?? '';

// Avoid duplicating the current user in the list when switching accounts
if (delegateEmail === currentUserPersonalDetails.login) {
return [currentUserMenuItem];
}

const delegatePersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(delegateEmail);
const error = account?.delegatedAccess?.error;

return [
createBaseMenuItem(delegatePersonalDetails, error, {
onPress: () => {
if (isOffline) {
Modal.close(() => setShouldShowOfflineModal(true));
return;
}
disconnect();
},
key: `${delegateEmail}-delegate`,
}),
currentUserMenuItem,
];
}

const delegatorMenuItems: MenuItemProps[] = delegators
.filter(({email}) => email !== currentUserPersonalDetails.login)
.map(({email, role, error}, index) => {
const personalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email);
return createBaseMenuItem(personalDetails, error, {
badgeText: translate('delegate.role', role),
onPress: () => {
if (isOffline) {
Modal.close(() => setShouldShowOfflineModal(true));
return;
}
connect(email);
},
key: `${email}-${index}`,
});
});

return [currentUserMenuItem, ...delegatorMenuItems];
};

return (
<>
<PressableWithFeedback
accessible
accessibilityLabel={translate('common.profile')}
onPress={() => {
setShouldShowDelegatorMenu(!shouldShowDelegatorMenu);
}}
ref={buttonRef}
interactive={canSwitchAccounts}
wrapperStyle={[styles.flexGrow1, styles.flex1, styles.mnw0, styles.justifyContentCenter]}
>
<View style={[styles.flexRow, styles.gap3]}>
<Avatar
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MEDIUM}
avatarID={currentUserPersonalDetails?.accountID}
source={currentUserPersonalDetails?.avatar}
fallbackIcon={currentUserPersonalDetails.fallbackIcon}
/>
<View style={[styles.flex1, styles.flexShrink1, styles.flexBasis0, styles.justifyContentCenter, styles.gap1]}>
<View style={[styles.flexRow, styles.gap1]}>
<Text
numberOfLines={1}
style={[styles.textBold, styles.textLarge]}
>
{currentUserPersonalDetails?.displayName}
</Text>
{canSwitchAccounts && (
<View style={styles.justifyContentCenter}>
<Icon
fill={theme.icon}
src={Expensicons.CaretUpDown}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
/>
</View>
)}
</View>
<Text
numberOfLines={1}
style={[styles.colorMuted, styles.fontSizeLabel]}
>
{currentUserPersonalDetails?.login}
</Text>
</View>
</View>
</PressableWithFeedback>
{canSwitchAccounts && (
<Popover
isVisible={shouldShowDelegatorMenu}
onClose={() => {
setShouldShowDelegatorMenu(false);
clearDelegatorErrors();
}}
anchorRef={buttonRef}
anchorPosition={styles.accountSwitcherAnchorPosition}
>
<View style={styles.pb4}>
<Text style={[styles.createMenuHeaderText, styles.ph5, styles.pb2, styles.pt4]}>{translate('delegate.switchAccount')}</Text>
<MenuItemList
menuItems={menuItems()}
shouldUseSingleExecution
/>
</View>
</Popover>
)}
<ConfirmModal
title={translate('common.youAppearToBeOffline')}
isVisible={shouldShowOfflineModal}
onConfirm={() => setShouldShowOfflineModal(false)}
onCancel={() => setShouldShowOfflineModal(false)}
confirmText={translate('common.buttonConfirm')}
prompt={translate('common.offlinePrompt')}
shouldShowCancelButton={false}
/>
</>
);
}

AccountSwitcher.displayName = 'AccountSwitcher';

export default AccountSwitcher;
Loading

0 comments on commit 8f5ad67

Please sign in to comment.