Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
dukenv0307 committed Jan 10, 2024
2 parents b1b29b7 + 09e7aa3 commit 654e4ed
Show file tree
Hide file tree
Showing 76 changed files with 1,539 additions and 1,853 deletions.
3 changes: 3 additions & 0 deletions .github/actions/javascript/bumpVersion/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const getBuildVersion = __nccwpck_require__(4016);
const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle';
const PLIST_PATH = './ios/NewExpensify/Info.plist';
const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist';
const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist';

exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH;
exports.PLIST_PATH = PLIST_PATH;
Expand Down Expand Up @@ -90,8 +91,10 @@ exports.updateiOSVersion = function updateiOSVersion(version) {
// Update Plists
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`);

// Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml
return cfVersion;
Expand Down
3 changes: 3 additions & 0 deletions .github/libs/nativeVersionUpdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const getBuildVersion = require('semver/functions/prerelease');
const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle';
const PLIST_PATH = './ios/NewExpensify/Info.plist';
const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist';
const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist';

exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH;
exports.PLIST_PATH = PLIST_PATH;
Expand Down Expand Up @@ -81,8 +82,10 @@ exports.updateiOSVersion = function updateiOSVersion(version) {
// Update Plists
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`);
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`);

// Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml
return cfVersion;
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001042300
versionName "1.4.23-0"
versionCode 1001042302
versionName "1.4.23-2"
}

flavorDimensions "default"
Expand Down
57 changes: 25 additions & 32 deletions docs/articles/expensify-classic/get-paid-back/Referral-Program.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,49 @@
---
title: Expensify Referral Program
description: Send your joining link, submit a receipt or invoice, and we'll pay you if your referral adopts Expensify.
title: Earn money with Expensify referrals
description: Get paid with the Expensify referral program! Share your link, earn $250 per successful sign-up, and enjoy unlimited income potential. It’s that easy.
redirect_from: articles/other/Referral-Program/
---
<!-- The lines above are required by Jekyll to process the .md file -->

# About
# Earn money with Expensify referrals

Expensify has grown thanks to our users who love Expensify so much that they tell their friends, colleagues, managers, and fellow business founders to use it, too.
Picture this: You've found Expensify and it's transformed your approach to expense management and financial organization. You love it so much that you can't help but recommend it to friends, family, and colleagues. Wouldn’t it be nice if you could get rewarded just for spreading the word?

As a thank you, every time you bring a new user into the platform who directly or indirectly leads to the adoption of a paid annual plan on Expensify, you will earn $250.
With Expensify referrals, you can. Every time someone you invite to the platform signs up for a paid annual plan on Expensify, you’ll earn $250. Think of it as a thank-you gift from us to you!

# How to get paid for referring people to Expensify
## How to get paid for Expensify referrals

1. Submit a report or invoice, or share your referral link with anyone you know who is spending too much time on expenses, or works at a company that could benefit from using Expensify.
Here are a few easy ways to get paid for Expensify friend referrals:

2. You will get $250 for any referred business that commits to an annual subscription, has 2 or more active users, and makes two monthly payments.
- Submit an expense report to your boss (even just one receipt!)
- Send an invoice to a client or customer
- Share your referral link with a friend
- To find your referral link, open your Expensify mobile app and go to **Settings > Refer a friend, earn cash! > Share invite link**.

That’s right! You can refer anyone working at any company you know.
**If the person you referred commits to an annual subscription with two or more active users and makes two monthly payments, you’ll get $250. Cha-ching!**

If their company goes on to become an Expensify customer with an annual subscription, and you are the earliest recorded referrer of a user on that company’s paid Expensify Policy, you'll get paid a referral reward.
## Who can you refer?

The best way to start is to submit any receipt to your manager (you'll get paid back and set yourself up for $250 if they start a subscription: win-win!)
You can refer anyone who might benefit from Expensify. Seriously. Anybody.

Referral rewards for the Spring/Summer 2023 campaign will be paid by direct deposit.
Know a small business owner? Refer them! An [accountant](https://use.expensify.com/accountants-program)? Refer them! A best friend from childhood who keeps losing paper receipts? Refer them!

{% include faq-begin.md %}
Plus, you can [refer an unlimited amount of new users](https://use.expensify.com/blog/earn-50000-by-referring-your-friends-to-expensify/) with the Expensify referral program, so your earning potential is truly sky-high.

- **How will I know if I am the first person to refer a company to Expensify?**
## Common questions about Expensify benefits

Successful referrers are notified after their referral pays for 2 months of an annual subscription. We will check for the earliest recorded referrer of a user on the policy, and if that is you, then we will let you know.
Still have questions about the Expensify referral program? We’ve got answers. Check out our FAQ below.

- **How will you pay me if I am successful?**
### How will I know if I am the first person to refer someone to Expensify?

In the Spring 2023 campaign, Expensify will be paying successful referrers via direct deposit to the Deposit-Only account you have on file. Referral payouts will happen once a month for the duration of the campaign. If you do not have a Deposit-Only account at the time of your referral payout, your deposit will be processed in the next batch.
You’ll know if you’re the first person to refer someone to Expensify if we reach out to let you know that they’ve successfully adopted Expensify and have paid for two months of an annual subscription.

Learn how to add a Deposit-Only account [here](https://community.expensify.com/discussion/4641/how-to-add-a-deposit-only-bank-account-both-personal-and-business).
Simply put, we check for the earliest recorded referrer of a member on the workspace, and if that’s you, then we’ll let you know.

- **I’m outside of the US, how do I get paid?**
### My referral wasn’t counted! How can I appeal?

While our referral payouts are in USD, you will be able to get paid via a Wise Borderless account. Learn more [here](https://community.expensify.com/discussion/5940/how-to-get-reimbursed-outside-the-us-with-wise-for-non-us-employees).
If you think your Expensify friend referral wasn’t counted, please send a message to [email protected] with the email of the person you referred. Our team will review the referral and get back to you.

- **My referral wasn’t counted! How can I appeal?**
## Share the Expensify love — and get paid in the process

Expensify reserves the right to modify the terms of the referral program at any time, and pays out referral bonuses for eligible companies at its own discretion.

Please send a message to [email protected] with the billing owner of the company you have referred and our team will review the referral and get back to you.

- **Where can I find my referral link?**

Expensify members who are opted-in for our newsletters will have received an email containing their unique referral link.

On the mobile app, go to **Settings** > **Invite a Friend** > **Share Invite Link** to retrieve your referral link.

{% include faq-end.md %}
Who needs a side hustle when you have Expensify? With Expensify benefits, it’s not just about managing your expenses — it's about expanding your income too. Share your Expensify referral link now or send over an invoice to unlock unlimited earning potential.
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.23.0</string>
<string>1.4.23.2</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.23.0</string>
<string>1.4.23.2</string>
</dict>
</plist>
6 changes: 5 additions & 1 deletion ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
<key>CFBundleVersion</key>
<string>1.4.23.0</string>
<key>CFBundleShortVersionString</key>
<string>1.4.23</string>
</dict>
</plist>
</plist>
17 changes: 15 additions & 2 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.23-0",
"version": "1.4.23-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 @@ -209,6 +209,7 @@
"@testing-library/jest-native": "5.4.1",
"@testing-library/react-native": "11.5.1",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/canvas-size": "^1.2.2",
"@types/concurrently": "^7.0.0",
"@types/jest": "^29.5.2",
"@types/jest-when": "^3.5.2",
Expand Down
1 change: 1 addition & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ type OnyxValues = {
[ONYXKEYS.COLLECTION.REPORT_USER_IS_LEAVING_ROOM]: boolean;
[ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup;
[ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction;
[ONYXKEYS.COLLECTION.TRANSACTION_DRAFT]: OnyxTypes.Transaction;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags;
[ONYXKEYS.COLLECTION.SELECTED_TAB]: string;
[ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string;
Expand Down
1 change: 1 addition & 0 deletions src/components/AvatarWithDisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ function AvatarWithDisplayName({
<ParentNavigationSubtitle
parentNavigationSubtitleData={parentNavigationSubtitleData}
parentReportID={report?.parentReportID}
pressableStyles={[styles.alignSelfStart, styles.mw100]}
/>
)}
{!!subtitle && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,52 @@
import PropTypes from 'prop-types';
import type {ForwardedRef} from 'react';
import React, {forwardRef, useImperativeHandle} from 'react';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useThrottledButtonState from '@hooks/useThrottledButtonState';
import useWindowDimensions from '@hooks/useWindowDimensions';
import getButtonState from '@libs/getButtonState';
import type IconAsset from '@src/types/utils/IconAsset';
import BaseMiniContextMenuItem from './BaseMiniContextMenuItem';
import Icon from './Icon';
import sourcePropTypes from './Image/sourcePropTypes';
import MenuItem from './MenuItem';

const propTypes = {
type ContextMenuItemProps = {
/** Icon Component */
icon: sourcePropTypes.isRequired,
icon: IconAsset;

/** Text to display */
text: PropTypes.string.isRequired,
text: string;

/** Icon to show when interaction was successful */
successIcon: sourcePropTypes,
successIcon?: IconAsset;

/** Text to show when interaction was successful */
successText: PropTypes.string,
successText?: string;

/** Whether to show the mini menu */
isMini: PropTypes.bool,
isMini?: boolean;

/** Callback to fire when the item is pressed */
onPress: PropTypes.func.isRequired,
onPress: () => void;

/** A description text to show under the title */
description: PropTypes.string,
description?: string;

/** The action accept for anonymous user or not */
isAnonymousAction: PropTypes.bool,
isAnonymousAction?: boolean;

/** Whether the menu item is focused or not */
isFocused: PropTypes.bool,

/** Forwarded ref to ContextMenuItem */
innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
isFocused?: boolean;
};

const defaultProps = {
isMini: false,
successIcon: null,
successText: '',
description: '',
isAnonymousAction: false,
isFocused: false,
innerRef: null,
type ContextMenuItemHandle = {
triggerPressAndUpdateSuccess?: () => void;
};

function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini, description, isAnonymousAction, isFocused, innerRef}) {
function ContextMenuItem(
{onPress, successIcon, successText = '', icon, text, isMini = false, description = '', isAnonymousAction = false, isFocused = false}: ContextMenuItemProps,
ref: ForwardedRef<ContextMenuItemHandle>,
) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {windowWidth} = useWindowDimensions();
Expand All @@ -66,12 +60,12 @@ function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini,

// We only set the success state when we have icon or text to represent the success state
// We may want to replace this check by checking the Result from OnPress Callback in future.
if (successIcon || successText) {
if (!!successIcon || successText) {
setThrottledButtonInactive();
}
};

useImperativeHandle(innerRef, () => ({triggerPressAndUpdateSuccess}));
useImperativeHandle(ref, () => ({triggerPressAndUpdateSuccess}));

const itemIcon = !isThrottledButtonActive && successIcon ? successIcon : icon;
const itemText = !isThrottledButtonActive && successText ? successText : text;
Expand Down Expand Up @@ -107,18 +101,6 @@ function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini,
);
}

ContextMenuItem.propTypes = propTypes;
ContextMenuItem.defaultProps = defaultProps;
ContextMenuItem.displayName = 'ContextMenuItem';

const ContextMenuItemWithRef = forwardRef((props, ref) => (
<ContextMenuItem
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
innerRef={ref}
/>
));

ContextMenuItemWithRef.displayName = 'ContextMenuItemWithRef';

export default ContextMenuItemWithRef;
export default forwardRef(ContextMenuItem);
Loading

0 comments on commit 654e4ed

Please sign in to comment.