diff --git a/.env.temp b/.env.temp deleted file mode 100644 index 193575ed4718..000000000000 --- a/.env.temp +++ /dev/null @@ -1 +0,0 @@ -PUSHER_DEV_SUFFIX=-14fec3ac47964662914a7b6a69ba5e41 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0dd10af71747..5d1d2c8f5417 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -68,7 +68,6 @@ This is a checklist for PR authors. Please make sure to complete all tasks and c - [ ] I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct) - [ ] I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline) - [ ] I tested this PR with a [High Traffic account](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#high-traffic-accounts) against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability). - - [ ] I included screenshots or videos for tests on [all platforms](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#make-sure-you-can-test-on-all-platforms) - [ ] I ran the tests on **all platforms** & verified they passed on: - [ ] iOS / native @@ -109,81 +108,45 @@ This is a checklist for PR authors. Please make sure to complete all tasks and c - [ ] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected. - [ ] I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR. +### Screenshots/Videos
-

PR Reviewer Checklist

- -The reviewer will copy/paste it into a new comment and complete it after the author checklist is completed -
- -- [ ] I have verified the author checklist is complete (all boxes are checked off). -- [ ] I verified the correct issue is linked in the `### Fixed Issues` section above -- [ ] I verified testing steps are clear and they cover the changes made in this PR - - [ ] I verified the steps for local testing are in the `Tests` section - - [ ] I verified the steps for expected offline behavior are in the `Offline steps` section - - [ ] I verified the steps for Staging and/or Production testing are in the `QA steps` section - - [ ] I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct) - - [ ] I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline) - - [ ] I tested this PR with a [High Traffic account](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#high-traffic-accounts) against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability). -- [ ] I checked that screenshots or videos are included for tests on [all platforms](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#make-sure-you-can-test-on-all-platforms) -- [ ] I included screenshots or videos for tests on [all platforms](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#make-sure-you-can-test-on-all-platforms) -- [ ] I verified tests pass on **all platforms** & I tested again on: - - [ ] iOS / native - - [ ] Android / native - - [ ] iOS / Safari - - [ ] Android / Chrome - - [ ] MacOS / Chrome - - [ ] MacOS / Desktop -- [ ] If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack -- [ ] I verified proper code patterns were followed (see [Reviewing the code](https://github.com/Expensify/App/blob/main/contributingGuides/PR_REVIEW_GUIDELINES.md#reviewing-the-code)) - - [ ] I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. `toggleReport` and not `onIconClick`). - - [ ] I verified that comments were added to code that is not self explanatory - - [ ] I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing. - - [ ] I verified any copy / text shown in the product was added in all `src/languages/*` files - - [ ] I verified any copy / text that was added to the app is correct English and approved by marketing by adding the `Waiting for Copy` label for a copy review on the original GH to get the correct copy. - - [ ] I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README. - - [ ] I verified the JSDocs style guidelines (in [`STYLE.md`](https://github.com/Expensify/App/blob/main/contributingGuides/STYLE.md#jsdocs)) were followed -- [ ] If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers -- [ ] I verified that this PR follows the guidelines as stated in the [Review Guidelines](https://github.com/Expensify/App/blob/main/contributingGuides/PR_REVIEW_GUIDELINES.md) -- [ ] I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like `Avatar`, I verified the components using `Avatar` have been tested & I retested again) -- [ ] I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests) -- [ ] I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such -- [ ] I verified that if a function's arguments changed that all usages have also been updated correctly -- [ ] If a new component is created I verified that: - - [ ] A similar component doesn't exist in the codebase - - [ ] All props are defined accurately and each prop has a `/** comment above it */` - - [ ] The file is named correctly - - [ ] The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone - - [ ] The only data being stored in the state is data necessary for rendering and nothing else - - [ ] For Class Components, any internal methods passed to components event handlers are bound to `this` properly so there are no scoping issues (i.e. for `onClick={this.submit}` the method `this.submit` should be bound to `this` in the constructor) - - [ ] Any internal methods bound to `this` are necessary to be bound (i.e. avoid `this.submit = this.submit.bind(this);` if `this.submit` is never passed to a component event handler like `onClick`) - - [ ] All JSX used for rendering exists in the render method - - [ ] The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions -- [ ] If a new CSS style is added I verified that: - - [ ] A similar style doesn't already exist - - [ ] The style can't be created with an existing [StyleUtils](https://github.com/Expensify/App/blob/main/src/styles/StyleUtils.js) function (i.e. `StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG`) -- [ ] If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like `Avatar` is modified, I verified that `Avatar` is working as expected in all cases) -- [ ] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected. -- [ ] I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR. +Web + +
-### Screenshots - +
+Mobile Web - Chrome -#### Web - + -#### Mobile Web - Chrome - +
-#### Mobile Web - Safari - +
+Mobile Web - Safari -#### Desktop - + -#### iOS - +
-#### Android - +
+Desktop + + + +
+ +
+iOS + + + +
+ +
+Android + + + +
diff --git a/.github/actions/composite/announceFailedWorkflowInSlack/action.yml b/.github/actions/composite/announceFailedWorkflowInSlack/action.yml index f6057d33f875..91b2a899f775 100644 --- a/.github/actions/composite/announceFailedWorkflowInSlack/action.yml +++ b/.github/actions/composite/announceFailedWorkflowInSlack/action.yml @@ -9,7 +9,7 @@ inputs: runs: using: composite steps: - - uses: 8398a7/action-slack@v3 + - uses: 8398a7/action-slack@2780b654eb23ee546e54052f0d2b0ed66ea30eaa name: Job failed Slack notification with: status: custom @@ -20,7 +20,7 @@ runs: attachments: [{ color: "#DB4545", pretext: ``, - text: `💥 ${process.env.AS_REPO} failed on ${process.env.AS_WORKFLOW} workflow 💥`, + text: `💥 ${process.env.AS_REPO} failed on ${process.env.AS_WORKFLOW_RUN} workflow 💥`, }] } env: diff --git a/.github/actions/composite/configureAwsCredentials/action.yml b/.github/actions/composite/configureAwsCredentials/action.yml new file mode 100644 index 000000000000..aec147b8cc77 --- /dev/null +++ b/.github/actions/composite/configureAwsCredentials/action.yml @@ -0,0 +1,21 @@ +name: 'Configure AWS Credentials' +description: 'Configures AWS credentials for the workflow' + +inputs: + AWS_ACCESS_KEY_ID: + description: 'Access Key to AWS' + required: true + AWS_SECRET_ACCESS_KEY: + description: 'Secret Access Key to AWS' + required: true + +runs: + using: composite + steps: + - name: Configure AWS Credentials + # Version: 1.5.5 + uses: aws-actions/configure-aws-credentials@e97d7fbc8e0e5af69631c13daa0f4b5a8d88165b + with: + aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 diff --git a/.github/actions/composite/setupNode/action.yml b/.github/actions/composite/setupNode/action.yml index 95e187ff4d3a..d475acf5380f 100644 --- a/.github/actions/composite/setupNode/action.yml +++ b/.github/actions/composite/setupNode/action.yml @@ -4,10 +4,6 @@ description: Set up Node runs: using: composite steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - with: - fetch-depth: 0 - - uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 with: node-version-file: '.nvmrc' diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index a594fa69d1a1..968159ce7184 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -14,7 +14,7 @@ const https = __nccwpck_require__(7211); const GitHubUtils = __nccwpck_require__(7999); const pathToReviewerChecklist = 'https://raw.githubusercontent.com/Expensify/App/main/contributingGuides/REVIEWER_CHECKLIST.md'; -const reviewerChecklistStartsWith = '## Reviewer Checklist'; +const reviewerChecklistContains = '# Reviewer Checklist'; const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedComments = []; @@ -66,7 +66,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { for (let i = 0; i < combinedComments.length; i++) { // Skip all other comments if we already found the reviewer checklist if (foundReviewerChecklist) { - return; + break; } const whitespace = /([\n\r])/gm; @@ -75,7 +75,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { console.log(`Comment ${i} starts with: ${comment.slice(0, 20)}...`); // Found the reviewer checklist, so count how many completed checklist items there are - if (comment.startsWith(reviewerChecklistStartsWith)) { + if (comment.indexOf(reviewerChecklistContains) !== -1) { console.log('Found the reviewer checklist!'); foundReviewerChecklist = true; numberOfFinishedChecklistItems = (comment.match(/- \[x\]/gi) || []).length; diff --git a/.github/actions/javascript/reviewerChecklist/reviewerChecklist.js b/.github/actions/javascript/reviewerChecklist/reviewerChecklist.js index 7fb27e5b5a5a..92fa27675473 100644 --- a/.github/actions/javascript/reviewerChecklist/reviewerChecklist.js +++ b/.github/actions/javascript/reviewerChecklist/reviewerChecklist.js @@ -4,7 +4,7 @@ const https = require('https'); const GitHubUtils = require('../../../libs/GithubUtils'); const pathToReviewerChecklist = 'https://raw.githubusercontent.com/Expensify/App/main/contributingGuides/REVIEWER_CHECKLIST.md'; -const reviewerChecklistStartsWith = '## Reviewer Checklist'; +const reviewerChecklistContains = '# Reviewer Checklist'; const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedComments = []; @@ -56,7 +56,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { for (let i = 0; i < combinedComments.length; i++) { // Skip all other comments if we already found the reviewer checklist if (foundReviewerChecklist) { - return; + break; } const whitespace = /([\n\r])/gm; @@ -65,7 +65,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { console.log(`Comment ${i} starts with: ${comment.slice(0, 20)}...`); // Found the reviewer checklist, so count how many completed checklist items there are - if (comment.startsWith(reviewerChecklistStartsWith)) { + if (comment.indexOf(reviewerChecklistContains) !== -1) { console.log('Found the reviewer checklist!'); foundReviewerChecklist = true; numberOfFinishedChecklistItems = (comment.match(/- \[x\]/gi) || []).length; diff --git a/.github/workflows/README.md b/.github/workflows/README.md index eb963877fc7f..c6695f5cbf30 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -3,6 +3,8 @@ ## Important tip for creating GitHub Workflows All inputs and outputs to GitHub Actions and any data passed between jobs or workflows is JSON-encoded (AKA, strings). Keep this in mind whenever writing GitHub workflows – you may need to JSON-decode variables to access them accurately. Here's an example of a common way to misuse GitHub Actions data: + + ```yaml name: CI on: pull_request diff --git a/.github/workflows/createNewVersion.yml b/.github/workflows/createNewVersion.yml index 31184425795a..b8bcd71d0f08 100644 --- a/.github/workflows/createNewVersion.yml +++ b/.github/workflows/createNewVersion.yml @@ -55,8 +55,7 @@ jobs: with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} - # TODO: Point back at upstream when https://github.com/softprops/turnstyle/pull/46 is merged - - uses: roryabraham/turnstyle@d50d3ffc3f2c8d280dec4cd802c1c735fcda77c8 + - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 with: poll-interval-seconds: 10 env: diff --git a/.github/workflows/e2ePerformanceRegressionTests.yml b/.github/workflows/e2ePerformanceRegressionTests.yml index a59eb8c0dbff..ad6425d4ec90 100644 --- a/.github/workflows/e2ePerformanceRegressionTests.yml +++ b/.github/workflows/e2ePerformanceRegressionTests.yml @@ -7,10 +7,15 @@ on: jobs: e2e-tests: if: ${{ github.event.label.name == 'e2e' }} - name: "Run e2e performance regression tests" + name: Run e2e performance regression tests # Although the tests will run on an android emulator, using macOS as its more performant runs-on: macos-12 steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 @@ -43,7 +48,7 @@ jobs: disable-animations: false script: echo "Generated AVD snapshot for caching." -# Note: if the android build fails the logs can be incomplete. It can help to run the build once manually to get a full log + # Note: if the android build fails the logs can be incomplete. It can help to run the build once manually to get a full log - name: Preheat build system env: JAVA_HOME: ${{ env.JAVA_HOME_11_X64 }} @@ -76,4 +81,3 @@ jobs: name: test-failure-logs path: e2e/.results retention-days: 5 - diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0af8907b085d..f0bcf63b6955 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,6 +11,11 @@ jobs: if: ${{ github.actor != 'OSBotify' || github.event_name == 'workflow_call' }} runs-on: ubuntu-latest steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - run: npm run lint diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index 6aa397758ea2..a2ed81064b46 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -31,6 +31,11 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: ubuntu-latest steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 @@ -100,6 +105,11 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: macos-12 steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - name: Decrypt Developer ID Certificate @@ -135,6 +145,11 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: macos-12 steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 @@ -219,18 +234,21 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: ubuntu-latest steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - name: Setup Cloudflare CLI run: pip3 install cloudflare - name: Configure AWS Credentials - # Version: 1.5.5 - uses: aws-actions/configure-aws-credentials@e97d7fbc8e0e5af69631c13daa0f4b5a8d88165b + uses: Expensify/App/.github/actions/composite/configureAwsCredentials@main with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Build web for production if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} @@ -340,6 +358,11 @@ jobs: if: ${{ always() }} needs: [android, desktop, iOS, web] steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - name: Set version diff --git a/.github/workflows/preDeploy.yml b/.github/workflows/preDeploy.yml index 045187c396e1..8c15408eaea1 100644 --- a/.github/workflows/preDeploy.yml +++ b/.github/workflows/preDeploy.yml @@ -82,8 +82,7 @@ jobs: needs: [chooseDeployActions, createNewVersion] runs-on: ubuntu-latest steps: - # TODO: Point back at upstream when https://github.com/softprops/turnstyle/pull/46 is merged - - uses: roryabraham/turnstyle@d50d3ffc3f2c8d280dec4cd802c1c735fcda77c8 + - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 with: poll-interval-seconds: 10 env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90e6e06e75d2..72dde5fe38cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,6 +39,11 @@ jobs: chunk: ${{fromJson(needs.config.outputs.MATRIX)}} steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main # If automatic signing is enabled, iOS builds will fail, so ensure we always have the proper profile specified diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml new file mode 100644 index 000000000000..839df9e758b4 --- /dev/null +++ b/.github/workflows/testBuild.yml @@ -0,0 +1,199 @@ +name: Build and deploy apps for testing + +on: + workflow_dispatch: + pull_request_target: + types: [opened, synchronize] + branches: ['*ci-test/**'] + +env: + DEVELOPER_DIR: /Applications/Xcode_14.0.1.app/Contents/Developer + +jobs: + validateActor: + runs-on: ubuntu-latest + outputs: + IS_TEAM_MEMBER: ${{ fromJSON(steps.isUserDeployer.outputs.isTeamMember) }} + steps: + - id: isUserDeployer + uses: tspascoal/get-user-teams-membership@baf2e6adf4c3b897bd65a7e3184305c165aec872 + with: + GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} + username: ${{ github.actor }} + team: mobile-deployers + + android: + name: Build and deploy Android for testing + needs: validateActor + if: ${{ fromJSON(needs.validateActor.outputs.IS_TEAM_MEMBER) }} + runs-on: ubuntu-latest + steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - uses: Expensify/App/.github/actions/composite/setupNode@main + + - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + with: + ruby-version: '2.7' + bundler-cache: true + + - name: Decrypt keystore + run: cd android/app && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output my-upload-key.keystore my-upload-key.keystore.gpg + env: + LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} + + - name: Decrypt json key + run: cd android/app && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output android-fastlane-json-key.json android-fastlane-json-key.json.gpg + env: + LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} + + - name: Configure AWS Credentials + uses: Expensify/App/.github/actions/composite/configureAwsCredentials@main + with: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Run Fastlane beta test + id: runFastlaneBetaTest + run: bundle exec fastlane android build_internal + env: + S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }} + S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + S3_BUCKET: ad-hoc-expensify-cash + S3_REGION: us-east-1 + PULL_REQUEST_NUMBER: ${{ github.event.number }} + + - uses: actions/upload-artifact@v3 + with: + name: android + path: ./android_paths.json + + iOS: + name: Build and deploy iOS for testing + needs: validateActor + if: ${{ fromJSON(needs.validateActor.outputs.IS_TEAM_MEMBER) }} + runs-on: macos-12 + steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - uses: Expensify/App/.github/actions/composite/setupNode@main + + - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + with: + ruby-version: '2.7' + bundler-cache: true + + - name: Install cocoapods + uses: nick-invision/retry@0711ba3d7808574133d713a0d92d2941be03a350 + with: + timeout_minutes: 10 + max_attempts: 5 + command: cd ios && pod install + + - name: Decrypt profile + run: cd ios && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output chat_expensify_adhoc.mobileprovision chat_expensify_adhoc.mobileprovision.gpg + env: + LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} + + - name: Decrypt certificate + run: cd ios && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output Certificates.p12 Certificates.p12.gpg + env: + LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} + + - name: Configure AWS Credentials + uses: Expensify/App/.github/actions/composite/configureAwsCredentials@main + with: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Run Fastlane + run: bundle exec fastlane ios build_internal + env: + S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }} + S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + S3_BUCKET: ad-hoc-expensify-cash + S3_REGION: us-east-1 + PULL_REQUEST_NUMBER: ${{ github.event.number }} + + - uses: actions/upload-artifact@v3 + with: + name: ios + path: ./ios_paths.json + + desktop: + name: Build and deploy Desktop for testing + needs: validateActor + if: ${{ fromJSON(needs.validateActor.outputs.IS_TEAM_MEMBER) }} + runs-on: macos-12 + steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + + - uses: Expensify/App/.github/actions/composite/setupNode@main + + - name: Decrypt Developer ID Certificate + run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg + env: + DEVELOPER_ID_SECRET_PASSPHRASE: ${{ secrets.DEVELOPER_ID_SECRET_PASSPHRASE }} + + - name: Configure AWS Credentials + uses: Expensify/App/.github/actions/composite/configureAwsCredentials@main + with: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Build desktop app for testing + run: npm run desktop-build-internal -- --publish always + env: + CSC_LINK: ${{ secrets.CSC_LINK }} + CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + PULL_REQUEST_NUMBER: ${{ github.event.number }} + + postGithubComment: + runs-on: ubuntu-latest + name: Post a GitHub comment with app download links for testing + needs: [android, ios, desktop] + steps: + - name: Checkout + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - uses: actions/download-artifact@v3 + + - name: Read JSONs with paths + id: set_var + run: | + content_android="$(cat ./android/android_paths.json)" + content_android="${content_android//'%'/'%25'}" + content_android="${content_android//$'\n'/'%0A'}" + content_android="${content_android//$'\r'/'%0D'}" + echo "android_paths=$content_android" >> "$GITHUB_OUTPUT" + content_ios="$(cat ./ios/ios_paths.json)" + content_ios="${content_ios//'%'/'%25'}" + content_ios="${content_ios//$'\n'/'%0A'}" + content_ios="${content_ios//$'\r'/'%0D'}" + echo "ios_paths=$content_ios" >> "$GITHUB_OUTPUT" + + - name: Publish links to apps for download + run: | + gh pr comment --body \ + ":test_tube::test_tube: Use the links below to test this build in android and iOS. Happy testing! :test_tube::test_tube: + | android :robot: | iOS :apple: | desktop :computer: | + | ------------- | ------------- | ------------- | + | ${{fromJson(steps.set_var.outputs.android_paths).html_path}} | ${{fromJson(steps.set_var.outputs.ios_paths).html_path}} | https://ad-hoc-expensify-cash.us-east-1.amazonaws.com/desktop/${{github.event.number}}/NewExpensify.dmg + | ![Android](https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${{fromJson(steps.set_var.outputs.android_paths).html_path}}) | ![iOS](https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${{fromJson(steps.set_var.outputs.ios_paths).html_path}}) | ![desktop](https://ad-hoc-expensify-cash.us-east-1.amazonaws.com/desktop/${{github.event.number}}/NewExpensify.dmg)" + env: + GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} diff --git a/.github/workflows/validateGithubActions.yml b/.github/workflows/validateGithubActions.yml index 4e51d785d6b0..b583ba31f2bc 100644 --- a/.github/workflows/validateGithubActions.yml +++ b/.github/workflows/validateGithubActions.yml @@ -10,6 +10,11 @@ jobs: if: github.actor != 'OSBotify' runs-on: ubuntu-latest steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main # Rebuild all the actions on this branch and check for a diff. Fail if there is one, diff --git a/.github/workflows/verifyPodfile.yml b/.github/workflows/verifyPodfile.yml index 17d80ca7e055..84f52d09997a 100644 --- a/.github/workflows/verifyPodfile.yml +++ b/.github/workflows/verifyPodfile.yml @@ -10,6 +10,11 @@ jobs: if: github.actor != 'OSBotify' runs-on: ubuntu-latest steps: + # This action checks-out the repository, so the workflow can access it. + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + with: + fetch-depth: 0 + - uses: Expensify/App/.github/actions/composite/setupNode@main - run: ./.github/scripts/verifyPodfile.sh diff --git a/.github/workflows/warnCPLabel.yml b/.github/workflows/warnCPLabel.yml index 1d57ae38f718..c488bb1836d6 100644 --- a/.github/workflows/warnCPLabel.yml +++ b/.github/workflows/warnCPLabel.yml @@ -16,9 +16,9 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} body: | - :warning: :warning: **Heads up! This pull request has the `CP Staging` label.** :warning: :warning: - Merging it will cause it to be immediately deployed to staging, _even if the [open `StagingDeployCash` deploy checklist](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3AStagingDeployCash) is locked._ - + :warning: :warning: **Heads up! This pull request has the `CP Staging` label** :warning: :warning: + If you applied the `CP Staging` label before the PR was merged, the PR will be be immediately deployed to staging even if the [open `StagingDeployCash` deploy checklist](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3AStagingDeployCash) is locked. + However if you applied the `CP Staging` after the PR was merged it's possible it won't be CP'ed automatically. If you need it to be CP'ed to staging, tag a member of @Expensify/mobile-deployers to CP it manually, otherwise you can wait for it to go out with the next deploy. - if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: diff --git a/.storybook/theme.js b/.storybook/theme.js index 641198d20f07..e33243058453 100644 --- a/.storybook/theme.js +++ b/.storybook/theme.js @@ -9,7 +9,7 @@ export default create({ brandImage: 'logomark.svg', colorPrimary: colors.dark, colorSecondary: colors.orange, - fontBase: 'GTAmericaExp-Regular', + fontBase: 'ExpensifyNeue-Regular', fontCode: 'monospace', textInverseColor: colors.black, }); diff --git a/Gemfile b/Gemfile index c41a21c6604f..d8b9c135680d 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ source "https://rubygems.org" gem "cocoapods", "~> 1.11.3" gem "fastlane", "~> 2" gem "xcpretty", "~> 0" + + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/Gemfile.lock b/Gemfile.lock index 5ac763189187..95a2611d953c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,6 +14,8 @@ GEM algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) + apktools (0.7.4) + rubyzip (~> 2.0) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) @@ -155,6 +157,10 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) + fastlane-plugin-aws_s3 (2.1.0) + apktools (~> 0.7) + aws-sdk-s3 (~> 1) + mime-types (~> 3.3) ffi (1.15.5) fourflusher (2.3.1) fuzzy_match (2.0.4) @@ -207,6 +213,9 @@ GEM json (2.6.2) jwt (2.5.0) memoist (0.16.2) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2022.0105) mini_magick (4.11.0) mini_mime (1.1.2) minitest (5.16.2) @@ -283,6 +292,7 @@ PLATFORMS DEPENDENCIES cocoapods (~> 1.11.3) fastlane (~> 2) + fastlane-plugin-aws_s3 xcpretty (~> 0) BUNDLED WITH diff --git a/README.md b/README.md index d456c5e52af4..61734c2417ed 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ export default withOnyx({ This application is built with the following principles. 1. **Data Flow** - Ideally, this is how data flows through the app: 1. Server pushes data to the disk of any client (Server -> Pusher event -> Action listening to pusher event -> Onyx). - >**Note:** Currently the code only does this with report comments. Until we make more server changes, this steps is actually done by the client requesting data from the server via XHR and then storing the response in Onyx. + >**Note:** Currently the code only does this with report comments. Until we make more server changes, this step is actually done by the client requesting data from the server via XHR and then storing the response in Onyx. 2. Disk pushes data to the UI (Onyx -> withOnyx() -> React component). 3. UI pushes data to people's brains (React component -> device screen). 4. Brain pushes data into UI inputs (Device input -> React component). diff --git a/android/app/build.gradle b/android/app/build.gradle index a0f77597cb4e..62303fef6a80 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -156,8 +156,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001022906 - versionName "1.2.29-6" + versionCode 1001023601 + versionName "1.2.36-1" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { @@ -258,6 +258,11 @@ android { matchingFallbacks = ['release'] signingConfig signingConfigs.debug } + internalRelease { + initWith release + matchingFallbacks = ['release'] + signingConfig signingConfigs.debug + } } // applicationVariants are e.g. debug, release @@ -284,6 +289,10 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + def lifecycle_version = "2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' } diff --git a/android/app/src/debug/assets/airshipconfig.properties b/android/app/src/debug/assets/airshipconfig.properties new file mode 100644 index 000000000000..490f74552f11 --- /dev/null +++ b/android/app/src/debug/assets/airshipconfig.properties @@ -0,0 +1,8 @@ +appKey = uulSSfTDQJ2r0PMpjRrhmQ +appSecret = D4Bhf0HrQEehrPua74Tyiw +inProduction = false +developmentLogLevel = VERBOSE + +# Notification Customization +notificationIcon = ic_notification +notificationAccentColor = #2EAAE2 \ No newline at end of file diff --git a/android/app/src/e2eRelease/assets/airshipconfig.properties b/android/app/src/e2eRelease/assets/airshipconfig.properties new file mode 100644 index 000000000000..194c4577de8b --- /dev/null +++ b/android/app/src/e2eRelease/assets/airshipconfig.properties @@ -0,0 +1,7 @@ +appKey = 55vypj0ARc6cN09MX7ogtQ +appSecret = EsSaqbdLSvmyC6kSBFJCtQ +inProduction = true + +# Notification Customization +notificationIcon = ic_notification +notificationAccentColor = #2EAAE2 \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index eb109cc8a30e..71c3dc6c9af3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -78,6 +78,6 @@ + android:value="com.expensify.chat.customairshipextender.CustomAirshipExtender" /> diff --git a/android/app/src/main/assets/airshipconfig.properties b/android/app/src/main/assets/airshipconfig.properties deleted file mode 100644 index 6e37dfb7465e..000000000000 --- a/android/app/src/main/assets/airshipconfig.properties +++ /dev/null @@ -1,9 +0,0 @@ -developmentAppKey = uulSSfTDQJ2r0PMpjRrhmQ -developmentAppSecret = D4Bhf0HrQEehrPua74Tyiw - -productionAppKey = 55vypj0ARc6cN09MX7ogtQ -productionAppSecret = EsSaqbdLSvmyC6kSBFJCtQ - -# Notification Customization -notificationIcon = ic_notification -notificationAccentColor = #2EAAE2 diff --git a/android/app/src/main/assets/fonts/ExpensifyMono-Bold.otf b/android/app/src/main/assets/fonts/Expensify-Mono-Bold.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyMono-Bold.otf rename to android/app/src/main/assets/fonts/Expensify-Mono-Bold.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyMono-Regular.otf b/android/app/src/main/assets/fonts/Expensify-Mono-Regular.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyMono-Regular.otf rename to android/app/src/main/assets/fonts/Expensify-Mono-Regular.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNeue-Bold.otf b/android/app/src/main/assets/fonts/Expensify-Neue-Bold.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNeue-Bold.otf rename to android/app/src/main/assets/fonts/Expensify-Neue-Bold.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNeue-BoldItalic.otf b/android/app/src/main/assets/fonts/Expensify-Neue-BoldItalic.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNeue-BoldItalic.otf rename to android/app/src/main/assets/fonts/Expensify-Neue-BoldItalic.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNeue-Italic.otf b/android/app/src/main/assets/fonts/Expensify-Neue-Italic.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNeue-Italic.otf rename to android/app/src/main/assets/fonts/Expensify-Neue-Italic.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNeue-Regular.otf b/android/app/src/main/assets/fonts/Expensify-Neue-Regular.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNeue-Regular.otf rename to android/app/src/main/assets/fonts/Expensify-Neue-Regular.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNewKansas-Medium.otf b/android/app/src/main/assets/fonts/Expensify-New-Kansas-Medium.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNewKansas-Medium.otf rename to android/app/src/main/assets/fonts/Expensify-New-Kansas-Medium.otf diff --git a/android/app/src/main/assets/fonts/ExpensifyNewKansas-MediumItalic.otf b/android/app/src/main/assets/fonts/Expensify-New-Kansas-MediumItalic.otf similarity index 100% rename from android/app/src/main/assets/fonts/ExpensifyNewKansas-MediumItalic.otf rename to android/app/src/main/assets/fonts/Expensify-New-Kansas-MediumItalic.otf diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-BdIt.otf b/android/app/src/main/assets/fonts/GTAmericaExp-BdIt.otf deleted file mode 100755 index b0b9e28e6786..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-BdIt.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-Bold.otf b/android/app/src/main/assets/fonts/GTAmericaExp-Bold.otf deleted file mode 100644 index 58d3be114e47..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-Bold.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-Light.otf b/android/app/src/main/assets/fonts/GTAmericaExp-Light.otf deleted file mode 100644 index 512b53fa37b3..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-Light.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-MdIt.otf b/android/app/src/main/assets/fonts/GTAmericaExp-MdIt.otf deleted file mode 100755 index 05aee02bbf80..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-MdIt.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-Medium.otf b/android/app/src/main/assets/fonts/GTAmericaExp-Medium.otf deleted file mode 100644 index 0e9d3629ce23..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-Medium.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-Regular.otf b/android/app/src/main/assets/fonts/GTAmericaExp-Regular.otf deleted file mode 100644 index 02f39bc35445..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-Regular.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-RgIt.otf b/android/app/src/main/assets/fonts/GTAmericaExp-RgIt.otf deleted file mode 100755 index 9cb4f78ff57e..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-RgIt.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExp-Thin.otf b/android/app/src/main/assets/fonts/GTAmericaExp-Thin.otf deleted file mode 100644 index 0557381f1353..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExp-Thin.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExpMono-Bd.otf b/android/app/src/main/assets/fonts/GTAmericaExpMono-Bd.otf deleted file mode 100755 index ba733848f1d9..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExpMono-Bd.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExpMono-BdIt.otf b/android/app/src/main/assets/fonts/GTAmericaExpMono-BdIt.otf deleted file mode 100755 index 063e653c8b52..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExpMono-BdIt.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExpMono-Rg.otf b/android/app/src/main/assets/fonts/GTAmericaExpMono-Rg.otf deleted file mode 100644 index 2786ecdc0cf5..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExpMono-Rg.otf and /dev/null differ diff --git a/android/app/src/main/assets/fonts/GTAmericaExpMono-RgIt.otf b/android/app/src/main/assets/fonts/GTAmericaExpMono-RgIt.otf deleted file mode 100755 index 6852a3391dae..000000000000 Binary files a/android/app/src/main/assets/fonts/GTAmericaExpMono-RgIt.otf and /dev/null differ diff --git a/android/app/src/main/java/com/expensify/chat/MainApplication.java b/android/app/src/main/java/com/expensify/chat/MainApplication.java index 7156979a6c68..fd203ecc675d 100644 --- a/android/app/src/main/java/com/expensify/chat/MainApplication.java +++ b/android/app/src/main/java/com/expensify/chat/MainApplication.java @@ -2,24 +2,23 @@ import android.content.Context; import android.database.CursorWindow; + import androidx.multidex.MultiDexApplication; + import com.expensify.chat.bootsplash.BootSplashPackage; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.existfragger.rnimagesize.RNImageSizePackage; -import com.google.firebase.crashlytics.FirebaseCrashlytics; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.config.ReactFeatureFlags; +import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.soloader.SoLoader; -import java.lang.reflect.InvocationTargetException; +import com.google.firebase.crashlytics.FirebaseCrashlytics; + import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.util.List; -import com.facebook.react.modules.i18nmanager.I18nUtil; public class MainApplication extends MultiDexApplication implements ReactApplication { @@ -111,13 +110,7 @@ private static void initializeFlipper( aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/android/app/src/main/java/com/expensify/chat/StartupTimer.java b/android/app/src/main/java/com/expensify/chat/StartupTimer.java index de43519fcb15..972e1dd95a0e 100644 --- a/android/app/src/main/java/com/expensify/chat/StartupTimer.java +++ b/android/app/src/main/java/com/expensify/chat/StartupTimer.java @@ -1,4 +1,5 @@ package com.expensify.chat; + import android.util.Log; import com.facebook.react.bridge.ReactApplicationContext; diff --git a/android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java similarity index 94% rename from android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java index dd09a934fc79..0cae0bd2de6d 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomAirshipExtender.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomAirshipExtender.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import android.content.Context; import androidx.annotation.NonNull; @@ -18,4 +18,4 @@ public void onAirshipReady(@NonNull Context context, @NonNull UAirship airship) NotificationListener notificationListener = airship.getPushManager().getNotificationListener(); pushManager.setNotificationListener(new CustomNotificationListener(notificationListener, notificationProvider)); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java similarity index 97% rename from android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java index d6fc1f9e1a35..514e5aca14a0 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomNotificationListener.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationListener.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import androidx.annotation.NonNull; import com.urbanairship.push.NotificationActionButtonInfo; diff --git a/android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java similarity index 98% rename from android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java rename to android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java index 8e9f5082ef67..deeff81bf76d 100644 --- a/android/app/src/main/java/com/expensify/chat/CustomNotificationProvider.java +++ b/android/app/src/main/java/com/expensify/chat/customairshipextender/CustomNotificationProvider.java @@ -1,4 +1,4 @@ -package com.expensify.chat; +package com.expensify.chat.customairshipextender; import android.content.Context; import android.graphics.Bitmap; @@ -26,6 +26,8 @@ import com.urbanairship.util.ImageUtils; import java.net.MalformedURLException; import java.net.URL; +import java.sql.Timestamp; +import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -126,7 +128,7 @@ private void applyMessageStyle(@NonNull Context context, NotificationCompat.Buil String avatar = reportAction.get("avatar").getString(); String accountID = Integer.toString(reportAction.get("actorAccountID").getInt(-1)); String message = reportAction.get("message").getList().get(0).getMap().get("text").getString(); - long time = reportAction.get("timestamp").getLong(0); + long time = Timestamp.valueOf(reportAction.get("created").getString(Instant.now().toString())).getTime(); String roomName = payload.get("roomName") == null ? "" : payload.get("roomName").getString(""); String conversationTitle = "Chat with " + name; if (!roomName.isEmpty()) { diff --git a/android/app/src/main/res/drawable-hdpi/ic_notification.png b/android/app/src/main/res/drawable-hdpi/ic_notification.png index eb4a29a5eb31..7612112d1bc5 100644 Binary files a/android/app/src/main/res/drawable-hdpi/ic_notification.png and b/android/app/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_notification.png b/android/app/src/main/res/drawable-mdpi/ic_notification.png index 6bd66d53e897..89accf5424f8 100644 Binary files a/android/app/src/main/res/drawable-mdpi/ic_notification.png and b/android/app/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/android/app/src/main/res/drawable-xhdpi/ic_notification.png index 35220f20eb97..a01f2c5e0dc9 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png index 344a154d7fe5..3bb969329c79 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png index 53d01824530d..697922b1e689 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png b/android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png index 418344ef64a5..2dd985e8eeea 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png and b/android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png b/android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png index 88c82f6938cf..7d0644eed692 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png and b/android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png b/android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png index aad0a60610c8..f2dd3df6e1ad 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png and b/android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png b/android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png index 855115119d1e..59538b46ded4 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png and b/android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png b/android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png index 783b32cea53b..9a8a1bbf2640 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png and b/android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 89436352feb8..35d8a1c3cef2 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 807ac49eb556..9a5989a435aa 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 21e97a75c38a..1b925f61ae28 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -1,5 +1,5 @@ - #FFFFFF + #061B09 #FFFFFF #0185ff #0b1b34 diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 0cad8b818b02..9057ea9c1cc2 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -7,15 +7,16 @@ diff --git a/android/app/src/release/assets/airshipconfig.properties b/android/app/src/release/assets/airshipconfig.properties new file mode 100644 index 000000000000..194c4577de8b --- /dev/null +++ b/android/app/src/release/assets/airshipconfig.properties @@ -0,0 +1,7 @@ +appKey = 55vypj0ARc6cN09MX7ogtQ +appSecret = EsSaqbdLSvmyC6kSBFJCtQ +inProduction = true + +# Notification Customization +notificationIcon = ic_notification +notificationAccentColor = #2EAAE2 \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index a35d82861347..ad1efd01ff98 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -3,8 +3,8 @@ buildscript { ext { minSdkVersion = 21 - compileSdkVersion = 31 - targetSdkVersion = 31 + compileSdkVersion = 32 + targetSdkVersion = 32 if (System.properties['os.arch'] == "aarch64") { // For M1 Users we need to use the NDK 24 which added support for aarch64 diff --git a/assets/css/fonts.css b/assets/css/fonts.css index a58f45bb3b0f..03f4d019b731 100644 --- a/assets/css/fonts.css +++ b/assets/css/fonts.css @@ -1,92 +1,43 @@ @font-face { - font-family: GTAmericaExp-Regular; - font-weight: 100; - font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Light.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Light.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Light.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExp-Regular; - font-weight: 200; - font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Thin.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Thin.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Thin.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExp-Regular; + font-family: ExpensifyNeue-Regular; font-weight: 400; font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Regular.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Regular.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Regular.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExp-Regular; - font-weight: 500; - font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Medium.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Medium.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Medium.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExp-Regular; - font-weight: 600; - font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Medium.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Medium.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Medium.woff2") format("woff2"); + src: url('/fonts/ExpensifyNeue-Regular.woff2') format('woff2'), url('/fonts/ExpensifyNeue-Regular.woff') format('woff'); } @font-face { - font-family: GTAmericaExp-Regular; + font-family: ExpensifyNeue-Bold; font-weight: 700; font-style: normal; - src: url("https://www.expensify.com/font/GT-America-Standard-Bold.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Bold.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Bold.woff2") format("woff2"); + src: url('/fonts/ExpensifyNeue-Bold.woff2') format('woff2'), url('/fonts/ExpensifyNeue-Bold.woff') format('woff'); } @font-face { - font-family: GTAmericaExp-RgIt; + font-family: ExpensifyNeue-Italic; font-weight: 400; - font-style: italic; - src: url("https://www.expensify.com/font/GT-America-Standard-Regular-Italic.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Regular-Italic.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Regular-Italic.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExp-MdIt; - font-weight: 500; - font-style: italic; - src: url("https://www.expensify.com/font/GT-America-Standard-Medium-Italic.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Medium-Italic.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Medium-Italic.woff2") format("woff2"); + font-style: normal; + src: url('/fonts/ExpensifyNeue-Italic.woff2') format('woff2'), url('/fonts/ExpensifyNeue-Italic.woff') format('woff'); } @font-face { - font-family: GTAmericaExp-BdIt; + font-family: ExpensifyNeue-BoldItalic; font-weight: 700; - font-style: italic; - src: url("https://www.expensify.com/font/GT-America-Standard-Bold-Italic.eot") format("embedded-opentype"), url("https://www.expensify.com/font/GT-America-Standard-Bold-Italic.woff") format("woff"), url("https://www.expensify.com/font/GT-America-Standard-Bold-Italic.woff2") format("woff2"); -} - -@font-face { - font-family: GTAmericaExpMono-Rg; - font-weight: 400; font-style: normal; - src: url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular.eot') format('embedded-opentype'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular.woff') format('woff'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular.woff2') format('woff2'); + src: url('/fonts/ExpensifyNeue-BoldItalic.woff2') format('woff2'), url('/fonts/ExpensifyNeue-BoldItalic.woff') format('woff'); } @font-face { - font-family: GTAmericaExpMono-RgIt; + font-family: ExpensifyMono-Regular; font-weight: 400; - font-style: italic; - src: url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular-Italic.eot') format('embedded-opentype'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular-Italic.woff') format('woff'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Regular-Italic.woff2') format('woff2'); -} - -@font-face { - font-family: GTAmericaExpMono-Bd; - font-weight: 700; font-style: normal; - src: url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold.eot') format('embedded-opentype'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold.woff') format('woff'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold.woff2') format('woff2'); + src: url('/fonts/ExpensifyMono-Regular.woff2') format('woff2'), url('/fonts/ExpensifyMono-Regular.woff') format('woff'); } @font-face { - font-family: GTAmericaExpMono-BdIt; + font-family: ExpensifyMono-Bold; font-weight: 700; - font-style: italic; - src: url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold-Italic.eot') format('embedded-opentype'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold-Italic.woff') format('woff'), url('https://www.expensify.com/font/GT-America-Exp-Mono-Bold-Italic.woff2') format('woff2'); + font-style: normal; + src: url('/fonts/ExpensifyMono-Bold.woff2') format('woff2'), url('/fonts/ExpensifyMono-Bold.woff') format('woff'); } * { diff --git a/assets/fonts/ExpensifyMono-Bold.woff b/assets/fonts/ExpensifyMono-Bold.woff new file mode 100755 index 000000000000..6cbe62241ccb Binary files /dev/null and b/assets/fonts/ExpensifyMono-Bold.woff differ diff --git a/assets/fonts/ExpensifyMono-Bold.woff2 b/assets/fonts/ExpensifyMono-Bold.woff2 new file mode 100755 index 000000000000..73a872d7612c Binary files /dev/null and b/assets/fonts/ExpensifyMono-Bold.woff2 differ diff --git a/assets/fonts/ExpensifyMono-Regular.woff b/assets/fonts/ExpensifyMono-Regular.woff new file mode 100755 index 000000000000..094b25062760 Binary files /dev/null and b/assets/fonts/ExpensifyMono-Regular.woff differ diff --git a/assets/fonts/ExpensifyMono-Regular.woff2 b/assets/fonts/ExpensifyMono-Regular.woff2 new file mode 100755 index 000000000000..497eed2191c0 Binary files /dev/null and b/assets/fonts/ExpensifyMono-Regular.woff2 differ diff --git a/assets/fonts/ExpensifyNeue-Bold.woff b/assets/fonts/ExpensifyNeue-Bold.woff new file mode 100755 index 000000000000..387c232dffcc Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Bold.woff differ diff --git a/assets/fonts/ExpensifyNeue-Bold.woff2 b/assets/fonts/ExpensifyNeue-Bold.woff2 new file mode 100755 index 000000000000..36ba41100e56 Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Bold.woff2 differ diff --git a/assets/fonts/ExpensifyNeue-BoldItalic.woff b/assets/fonts/ExpensifyNeue-BoldItalic.woff new file mode 100755 index 000000000000..fae33b057ef9 Binary files /dev/null and b/assets/fonts/ExpensifyNeue-BoldItalic.woff differ diff --git a/assets/fonts/ExpensifyNeue-BoldItalic.woff2 b/assets/fonts/ExpensifyNeue-BoldItalic.woff2 new file mode 100755 index 000000000000..40829f25d10b Binary files /dev/null and b/assets/fonts/ExpensifyNeue-BoldItalic.woff2 differ diff --git a/assets/fonts/ExpensifyNeue-Italic.woff b/assets/fonts/ExpensifyNeue-Italic.woff new file mode 100755 index 000000000000..6592e735e982 Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Italic.woff differ diff --git a/assets/fonts/ExpensifyNeue-Italic.woff2 b/assets/fonts/ExpensifyNeue-Italic.woff2 new file mode 100755 index 000000000000..1085e342cd14 Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Italic.woff2 differ diff --git a/assets/fonts/ExpensifyNeue-Regular.woff b/assets/fonts/ExpensifyNeue-Regular.woff new file mode 100755 index 000000000000..a8a311d59e77 Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Regular.woff differ diff --git a/assets/fonts/ExpensifyNeue-Regular.woff2 b/assets/fonts/ExpensifyNeue-Regular.woff2 new file mode 100755 index 000000000000..cdec638e361b Binary files /dev/null and b/assets/fonts/ExpensifyNeue-Regular.woff2 differ diff --git a/assets/fonts/GTAmericaExp-BdIt.otf b/assets/fonts/GTAmericaExp-BdIt.otf deleted file mode 100755 index b0b9e28e6786..000000000000 Binary files a/assets/fonts/GTAmericaExp-BdIt.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-Bold.otf b/assets/fonts/GTAmericaExp-Bold.otf deleted file mode 100644 index 58d3be114e47..000000000000 Binary files a/assets/fonts/GTAmericaExp-Bold.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-Light.otf b/assets/fonts/GTAmericaExp-Light.otf deleted file mode 100644 index 512b53fa37b3..000000000000 Binary files a/assets/fonts/GTAmericaExp-Light.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-MdIt.otf b/assets/fonts/GTAmericaExp-MdIt.otf deleted file mode 100755 index 05aee02bbf80..000000000000 Binary files a/assets/fonts/GTAmericaExp-MdIt.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-Medium.otf b/assets/fonts/GTAmericaExp-Medium.otf deleted file mode 100644 index 0e9d3629ce23..000000000000 Binary files a/assets/fonts/GTAmericaExp-Medium.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-Regular.otf b/assets/fonts/GTAmericaExp-Regular.otf deleted file mode 100644 index 02f39bc35445..000000000000 Binary files a/assets/fonts/GTAmericaExp-Regular.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-RgIt.otf b/assets/fonts/GTAmericaExp-RgIt.otf deleted file mode 100755 index 9cb4f78ff57e..000000000000 Binary files a/assets/fonts/GTAmericaExp-RgIt.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExp-Thin.otf b/assets/fonts/GTAmericaExp-Thin.otf deleted file mode 100644 index 0557381f1353..000000000000 Binary files a/assets/fonts/GTAmericaExp-Thin.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExpMono-Bd.otf b/assets/fonts/GTAmericaExpMono-Bd.otf deleted file mode 100755 index ba733848f1d9..000000000000 Binary files a/assets/fonts/GTAmericaExpMono-Bd.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExpMono-BdIt.otf b/assets/fonts/GTAmericaExpMono-BdIt.otf deleted file mode 100755 index 063e653c8b52..000000000000 Binary files a/assets/fonts/GTAmericaExpMono-BdIt.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExpMono-Rg.otf b/assets/fonts/GTAmericaExpMono-Rg.otf deleted file mode 100644 index 2786ecdc0cf5..000000000000 Binary files a/assets/fonts/GTAmericaExpMono-Rg.otf and /dev/null differ diff --git a/assets/fonts/GTAmericaExpMono-RgIt.otf b/assets/fonts/GTAmericaExpMono-RgIt.otf deleted file mode 100755 index 6852a3391dae..000000000000 Binary files a/assets/fonts/GTAmericaExpMono-RgIt.otf and /dev/null differ diff --git a/assets/images/arrow-right-long.svg b/assets/images/arrow-right-long.svg new file mode 100644 index 000000000000..99be81fa9b36 --- /dev/null +++ b/assets/images/arrow-right-long.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/assets/images/arrow-right.svg b/assets/images/arrow-right.svg index e1fa6e5962eb..c3bb5345d3f9 100644 --- a/assets/images/arrow-right.svg +++ b/assets/images/arrow-right.svg @@ -1,7 +1,10 @@ - + - + + diff --git a/assets/images/arrow-up.svg b/assets/images/arrow-up.svg index f8c4b75ac35c..60d03289d446 100644 --- a/assets/images/arrow-up.svg +++ b/assets/images/arrow-up.svg @@ -1,7 +1,10 @@ - + - + + diff --git a/assets/images/arrows-updown.svg b/assets/images/arrows-updown.svg new file mode 100644 index 000000000000..a1aa2c92ef87 --- /dev/null +++ b/assets/images/arrows-updown.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/assets/images/avatars/admin-room.svg b/assets/images/avatars/admin-room.svg index b358608ed994..aa25fe5bbb1d 100644 --- a/assets/images/avatars/admin-room.svg +++ b/assets/images/avatars/admin-room.svg @@ -1,15 +1,17 @@ - + - - + + diff --git a/assets/images/avatars/announce-room.svg b/assets/images/avatars/announce-room.svg index d29ff8c76976..772a113fbc33 100644 --- a/assets/images/avatars/announce-room.svg +++ b/assets/images/avatars/announce-room.svg @@ -1,19 +1,17 @@ - + - - - - - + + + + diff --git a/assets/images/avatars/deleted-room.svg b/assets/images/avatars/deleted-room.svg index c68c13a23fef..a39c55d0e2b5 100644 --- a/assets/images/avatars/deleted-room.svg +++ b/assets/images/avatars/deleted-room.svg @@ -1,13 +1,15 @@ - + - + + diff --git a/assets/images/avatars/domain-room.svg b/assets/images/avatars/domain-room.svg index 6dcc6407d880..1f9903539049 100644 --- a/assets/images/avatars/domain-room.svg +++ b/assets/images/avatars/domain-room.svg @@ -1,16 +1,15 @@ - + - + diff --git a/assets/images/avatars/fallback-avatar.svg b/assets/images/avatars/fallback-avatar.svg index dc1a1497cfe5..f509ba03b1a5 100644 --- a/assets/images/avatars/fallback-avatar.svg +++ b/assets/images/avatars/fallback-avatar.svg @@ -1,25 +1,12 @@ - + - - - - - - - - - - - - - + + + diff --git a/assets/images/avatars/fallback-workspace-avatar.svg b/assets/images/avatars/fallback-workspace-avatar.svg index ac2f58122a0f..518627fafc19 100644 --- a/assets/images/avatars/fallback-workspace-avatar.svg +++ b/assets/images/avatars/fallback-workspace-avatar.svg @@ -1,15 +1,14 @@ - + - + diff --git a/assets/images/avatars/room.svg b/assets/images/avatars/room.svg index bb677bac3714..0db866ad9160 100644 --- a/assets/images/avatars/room.svg +++ b/assets/images/avatars/room.svg @@ -1,14 +1,14 @@ - + - - + + diff --git a/assets/images/back-left.svg b/assets/images/back-left.svg index 5dac74426cc4..c6730b492228 100644 --- a/assets/images/back-left.svg +++ b/assets/images/back-left.svg @@ -1,7 +1,10 @@ - + - + + diff --git a/assets/images/bank.svg b/assets/images/bank.svg index 3c03e528d731..87a75b644a3a 100644 --- a/assets/images/bank.svg +++ b/assets/images/bank.svg @@ -1,8 +1,11 @@ - + - + + diff --git a/assets/images/bill.svg b/assets/images/bill.svg index b27e6776b0fd..6d9e7bd74ee6 100644 --- a/assets/images/bill.svg +++ b/assets/images/bill.svg @@ -1,11 +1,11 @@ - + - - + + + diff --git a/assets/images/bolt.svg b/assets/images/bolt.svg index 2290fbd7ded7..c54c044a898e 100644 --- a/assets/images/bolt.svg +++ b/assets/images/bolt.svg @@ -1,7 +1,7 @@ - - - + + + diff --git a/assets/images/briefcase.svg b/assets/images/briefcase.svg index f73854bbb36a..c73734c6b124 100644 --- a/assets/images/briefcase.svg +++ b/assets/images/briefcase.svg @@ -1,8 +1,11 @@ - + - - - + + + + diff --git a/assets/images/bug.svg b/assets/images/bug.svg index b7145d19c241..8a33c1c17437 100644 --- a/assets/images/bug.svg +++ b/assets/images/bug.svg @@ -1,17 +1,12 @@ - + - - + viewBox="0 0 21 20" style="enable-background:new 0 0 21 20;" xml:space="preserve"> + + + diff --git a/assets/images/building.svg b/assets/images/building.svg index 1cb4dd7f09c1..27efe759f4e4 100644 --- a/assets/images/building.svg +++ b/assets/images/building.svg @@ -1 +1,12 @@ -building \ No newline at end of file + + + + + + diff --git a/assets/images/camera.svg b/assets/images/camera.svg index 65c5e9301417..966a185ae5d9 100644 --- a/assets/images/camera.svg +++ b/assets/images/camera.svg @@ -1,8 +1,11 @@ - + - + + diff --git a/assets/images/cascading-cards-mobile.svg b/assets/images/cascading-cards-mobile.svg deleted file mode 100644 index 71b8e711183b..000000000000 --- a/assets/images/cascading-cards-mobile.svg +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/cascading-cards-web.svg b/assets/images/cascading-cards-web.svg deleted file mode 100644 index 266f98a88ebe..000000000000 --- a/assets/images/cascading-cards-web.svg +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/cash.svg b/assets/images/cash.svg index 4691242574c4..7780e9be9eec 100644 --- a/assets/images/cash.svg +++ b/assets/images/cash.svg @@ -1,27 +1,10 @@ - + - - - - - - - - - - - - - - + + diff --git a/assets/images/chair.svg b/assets/images/chair.svg new file mode 100644 index 000000000000..d8864d205b33 --- /dev/null +++ b/assets/images/chair.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/assets/images/chatbubble.svg b/assets/images/chatbubble.svg index 24f1bc1d3c2a..23bc4b429ea0 100644 --- a/assets/images/chatbubble.svg +++ b/assets/images/chatbubble.svg @@ -1,7 +1,7 @@ - + - + diff --git a/assets/images/checkmark.svg b/assets/images/checkmark.svg index d472d1894d63..7ac28068ff56 100644 --- a/assets/images/checkmark.svg +++ b/assets/images/checkmark.svg @@ -1,7 +1,10 @@ - + - + + diff --git a/assets/images/circle-hourglass.svg b/assets/images/circle-hourglass.svg deleted file mode 100644 index 1bba8b474101..000000000000 --- a/assets/images/circle-hourglass.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/assets/images/clipboard.svg b/assets/images/clipboard.svg index 34735f1977ff..5ac0c503f19b 100644 --- a/assets/images/clipboard.svg +++ b/assets/images/clipboard.svg @@ -1,11 +1,8 @@ - + - - - - + viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve"> + + diff --git a/assets/images/close.svg b/assets/images/close.svg index de1a4693afb6..f36b0714385a 100644 --- a/assets/images/close.svg +++ b/assets/images/close.svg @@ -1,8 +1,7 @@ - + - + diff --git a/assets/images/closed-sign.svg b/assets/images/closed-sign.svg index b3b3482c688c..6454e31cd35e 100644 --- a/assets/images/closed-sign.svg +++ b/assets/images/closed-sign.svg @@ -1,10 +1,12 @@ - + - + + diff --git a/assets/images/collapse.svg b/assets/images/collapse.svg index 92b9619924f0..9b254182dbe2 100644 --- a/assets/images/collapse.svg +++ b/assets/images/collapse.svg @@ -1,12 +1,8 @@ - + - - - + diff --git a/assets/images/concierge.svg b/assets/images/concierge.svg index 4b22f626a0e9..2ed0becb61da 100644 --- a/assets/images/concierge.svg +++ b/assets/images/concierge.svg @@ -1,8 +1,12 @@ - + - - + + + diff --git a/assets/images/connect.svg b/assets/images/connect.svg index 6d4e9eb21d97..e30231e46840 100644 --- a/assets/images/connect.svg +++ b/assets/images/connect.svg @@ -1,12 +1,12 @@ - + - - + + diff --git a/assets/images/creditcard.svg b/assets/images/creditcard.svg index 9d701f73e2bf..f174472a63c4 100644 --- a/assets/images/creditcard.svg +++ b/assets/images/creditcard.svg @@ -1,9 +1,7 @@ - + - - - - + + diff --git a/assets/images/document.svg b/assets/images/document.svg new file mode 100644 index 000000000000..8ef6c5ec10ce --- /dev/null +++ b/assets/images/document.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/assets/images/dot-indicator.svg b/assets/images/dot-indicator.svg index 49be497b35c1..9d808d91babe 100644 --- a/assets/images/dot-indicator.svg +++ b/assets/images/dot-indicator.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/images/down.svg b/assets/images/down.svg index 8e988eae2980..e4bb5bea9b4d 100644 --- a/assets/images/down.svg +++ b/assets/images/down.svg @@ -1,6 +1,10 @@ - + - + + diff --git a/assets/images/download.svg b/assets/images/download.svg index 1a84187992dc..96bbd4198574 100644 --- a/assets/images/download.svg +++ b/assets/images/download.svg @@ -1,9 +1,12 @@ - + - - + + + diff --git a/assets/images/emoji.svg b/assets/images/emoji.svg index f414143bace3..431f46962bd7 100644 --- a/assets/images/emoji.svg +++ b/assets/images/emoji.svg @@ -1,13 +1,11 @@ - + - + diff --git a/assets/images/example-check-image-en.png b/assets/images/example-check-image-en.png index c6ef809ed983..2a4f32ade69a 100644 Binary files a/assets/images/example-check-image-en.png and b/assets/images/example-check-image-en.png differ diff --git a/assets/images/example-check-image-es.png b/assets/images/example-check-image-es.png index ed757c7f7d8a..435151525a7e 100644 Binary files a/assets/images/example-check-image-es.png and b/assets/images/example-check-image-es.png differ diff --git a/assets/images/exclamation.svg b/assets/images/exclamation.svg index 0d2e32a463d9..ab70c6f3ca8f 100644 --- a/assets/images/exclamation.svg +++ b/assets/images/exclamation.svg @@ -1,8 +1,10 @@ - + - + + diff --git a/assets/images/exit.svg b/assets/images/exit.svg index d97b7535ddf1..07792548c8a5 100644 --- a/assets/images/exit.svg +++ b/assets/images/exit.svg @@ -1,11 +1,13 @@ - + - - - - + + + diff --git a/assets/images/expand.svg b/assets/images/expand.svg index cdd1d712fd6a..0d5d520e444a 100644 --- a/assets/images/expand.svg +++ b/assets/images/expand.svg @@ -1,12 +1,9 @@ - + - - - + + diff --git a/assets/images/expensify-logo-round-clearspace.png b/assets/images/expensify-logo-round-clearspace.png index 154e1cbfec1c..da0f19dda770 100644 Binary files a/assets/images/expensify-logo-round-clearspace.png and b/assets/images/expensify-logo-round-clearspace.png differ diff --git a/assets/images/expensify-logo-round.png b/assets/images/expensify-logo-round.png index 8904b9d80403..59d29ed09530 100644 Binary files a/assets/images/expensify-logo-round.png and b/assets/images/expensify-logo-round.png differ diff --git a/assets/images/expensify-wordmark.svg b/assets/images/expensify-wordmark.svg index 68f4231501c2..09fdaf2b4c83 100644 --- a/assets/images/expensify-wordmark.svg +++ b/assets/images/expensify-wordmark.svg @@ -1,9 +1,9 @@ - + - + - + diff --git a/assets/images/eye-disabled.svg b/assets/images/eye-disabled.svg index 804a36c63777..4055ba7e78a0 100644 --- a/assets/images/eye-disabled.svg +++ b/assets/images/eye-disabled.svg @@ -1,15 +1,13 @@ - + - - - - + + + diff --git a/assets/images/eye.svg b/assets/images/eye.svg index 7957890c3180..dd0a4fd532b8 100644 --- a/assets/images/eye.svg +++ b/assets/images/eye.svg @@ -1,9 +1,12 @@ - + - + + diff --git a/assets/images/gallery.svg b/assets/images/gallery.svg index b79d2010c02f..21eb78059329 100644 --- a/assets/images/gallery.svg +++ b/assets/images/gallery.svg @@ -1,8 +1,11 @@ - + - + + diff --git a/assets/images/gear.svg b/assets/images/gear.svg index eb58b5196e02..f7090075e0a4 100644 --- a/assets/images/gear.svg +++ b/assets/images/gear.svg @@ -1,12 +1,18 @@ - + - + + diff --git a/assets/images/globe.svg b/assets/images/globe.svg new file mode 100644 index 000000000000..f057bd36379b --- /dev/null +++ b/assets/images/globe.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/assets/images/hashtag.svg b/assets/images/hashtag.svg index a9d4286599b1..86324ffcdba8 100644 --- a/assets/images/hashtag.svg +++ b/assets/images/hashtag.svg @@ -1,7 +1,16 @@ - + - + + diff --git a/assets/images/history.svg b/assets/images/history.svg new file mode 100644 index 000000000000..5eefb04b480d --- /dev/null +++ b/assets/images/history.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/assets/images/hourglass.svg b/assets/images/hourglass.svg new file mode 100644 index 000000000000..b04dc3589d73 --- /dev/null +++ b/assets/images/hourglass.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/assets/images/info.svg b/assets/images/info.svg index 391a10af69db..7446622ab044 100644 --- a/assets/images/info.svg +++ b/assets/images/info.svg @@ -1,9 +1,12 @@ - + - - - + + + + diff --git a/assets/images/invoice.svg b/assets/images/invoice.svg index 91391b0f9bcb..618aba9be614 100644 --- a/assets/images/invoice.svg +++ b/assets/images/invoice.svg @@ -1,11 +1,11 @@ - + - - + + + diff --git a/assets/images/key.svg b/assets/images/key.svg index a1817f791261..595a1541ce5e 100644 --- a/assets/images/key.svg +++ b/assets/images/key.svg @@ -1,8 +1,11 @@ - + - + + diff --git a/assets/images/keyboard.svg b/assets/images/keyboard.svg index 65ac8642ee70..16df73f0026b 100644 --- a/assets/images/keyboard.svg +++ b/assets/images/keyboard.svg @@ -1,22 +1,20 @@ - + - + diff --git a/assets/images/lets-chat.svg b/assets/images/lets-chat.svg deleted file mode 100644 index b083891413a9..000000000000 --- a/assets/images/lets-chat.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/images/link-copy.svg b/assets/images/link-copy.svg index 9b883ade5067..e153fbc49795 100644 --- a/assets/images/link-copy.svg +++ b/assets/images/link-copy.svg @@ -1 +1,13 @@ -link-copy \ No newline at end of file + + + + + + diff --git a/assets/images/link.svg b/assets/images/link.svg index 25c8296daa72..a284470a5c79 100644 --- a/assets/images/link.svg +++ b/assets/images/link.svg @@ -1,11 +1,9 @@ - + - - + + diff --git a/assets/images/lock.svg b/assets/images/lock.svg index f7d145372828..ab4bafc4724d 100644 --- a/assets/images/lock.svg +++ b/assets/images/lock.svg @@ -1,9 +1,10 @@ - + - + + diff --git a/assets/images/luggage.svg b/assets/images/luggage.svg index b7f8dc7fe93c..65edc1f31fb3 100644 --- a/assets/images/luggage.svg +++ b/assets/images/luggage.svg @@ -1,16 +1,13 @@ - + - - - - - - + + + diff --git a/assets/images/magnifying-glass.svg b/assets/images/magnifying-glass.svg new file mode 100644 index 000000000000..c0e2465f0308 --- /dev/null +++ b/assets/images/magnifying-glass.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/assets/images/magnifyingglass.svg b/assets/images/magnifyingglass.svg deleted file mode 100644 index b32a165ee972..000000000000 --- a/assets/images/magnifyingglass.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/assets/images/mail.svg b/assets/images/mail.svg index facbceb9661d..1a3d788288b9 100644 --- a/assets/images/mail.svg +++ b/assets/images/mail.svg @@ -1,8 +1,8 @@ - + - - + + diff --git a/assets/images/megaphone.svg b/assets/images/megaphone.svg new file mode 100644 index 000000000000..a10a6d838558 --- /dev/null +++ b/assets/images/megaphone.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/assets/images/menu.svg b/assets/images/menu.svg new file mode 100644 index 000000000000..9995bb6d521b --- /dev/null +++ b/assets/images/menu.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/assets/images/money-bag.svg b/assets/images/money-bag.svg index 7c9d54262151..e691635f9544 100644 --- a/assets/images/money-bag.svg +++ b/assets/images/money-bag.svg @@ -1,8 +1,11 @@ - + - + + diff --git a/assets/images/money-circle.svg b/assets/images/money-circle.svg index eb1bf4488874..f6c66e0a6dfb 100644 --- a/assets/images/money-circle.svg +++ b/assets/images/money-circle.svg @@ -1,12 +1,13 @@ - + - - - + + + + diff --git a/assets/images/monitor.svg b/assets/images/monitor.svg index 5e134ee9af4a..a8b99721a9cc 100644 --- a/assets/images/monitor.svg +++ b/assets/images/monitor.svg @@ -1,7 +1,11 @@ - + - + + + diff --git a/assets/images/new-expensify-dev.svg b/assets/images/new-expensify-dev.svg index 4346bdbaeef5..5e36ffebe0d3 100644 --- a/assets/images/new-expensify-dev.svg +++ b/assets/images/new-expensify-dev.svg @@ -1,12 +1,46 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-expensify-stg.svg b/assets/images/new-expensify-stg.svg index 26aff3d44293..61852bbb1932 100644 --- a/assets/images/new-expensify-stg.svg +++ b/assets/images/new-expensify-stg.svg @@ -1,12 +1,48 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-expensify.svg b/assets/images/new-expensify.svg index cc9c02021485..dc8273e6aa99 100644 --- a/assets/images/new-expensify.svg +++ b/assets/images/new-expensify.svg @@ -1,10 +1,29 @@ - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-window.svg b/assets/images/new-window.svg index 394000048d14..c1b9991558b7 100644 --- a/assets/images/new-window.svg +++ b/assets/images/new-window.svg @@ -1,9 +1,9 @@ - + - - + + diff --git a/assets/images/new-workspace.svg b/assets/images/new-workspace.svg index 67208e1e31b6..62f4717108e9 100644 --- a/assets/images/new-workspace.svg +++ b/assets/images/new-workspace.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + diff --git a/assets/images/offline-cloud.svg b/assets/images/offline-cloud.svg index 38cf2892e9c2..ae8305e52934 100644 --- a/assets/images/offline-cloud.svg +++ b/assets/images/offline-cloud.svg @@ -1,8 +1,8 @@ - + - - - + + + diff --git a/assets/images/offline.svg b/assets/images/offline.svg index f3b58e11221f..21cb29d382c0 100644 --- a/assets/images/offline.svg +++ b/assets/images/offline.svg @@ -1,5 +1,10 @@ - - - - + + + + + + diff --git a/assets/images/paperclip.svg b/assets/images/paperclip.svg index b5331b7b4585..29760284c687 100644 --- a/assets/images/paperclip.svg +++ b/assets/images/paperclip.svg @@ -1,4 +1,11 @@ - - paper-clip - + + + + + diff --git a/assets/images/paycheck.svg b/assets/images/paycheck.svg index f81a5a9a86a9..d54602d8b11b 100644 --- a/assets/images/paycheck.svg +++ b/assets/images/paycheck.svg @@ -1,17 +1,15 @@ - + - - - + + + diff --git a/assets/images/pencil.svg b/assets/images/pencil.svg index 9c27bd52986d..8673005d818a 100644 --- a/assets/images/pencil.svg +++ b/assets/images/pencil.svg @@ -1,8 +1,9 @@ - + - - + + + diff --git a/assets/images/phone.svg b/assets/images/phone.svg index a8fcf348b331..38cc8c1319dc 100644 --- a/assets/images/phone.svg +++ b/assets/images/phone.svg @@ -1,8 +1,8 @@ - + - + diff --git a/assets/images/pin-circle.svg b/assets/images/pin-circle.svg deleted file mode 100644 index 3a43ccd3ec5a..000000000000 --- a/assets/images/pin-circle.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/assets/images/pin.svg b/assets/images/pin.svg index 74fadfa4f1c8..048f95cbc929 100644 --- a/assets/images/pin.svg +++ b/assets/images/pin.svg @@ -1,7 +1,9 @@ - + - + diff --git a/assets/images/plus.svg b/assets/images/plus.svg index ef02c077357b..59a0b803dde4 100644 --- a/assets/images/plus.svg +++ b/assets/images/plus.svg @@ -1,8 +1,7 @@ - + - + diff --git a/assets/images/printer.svg b/assets/images/printer.svg index cd62ce79744d..ce0d725d4251 100644 --- a/assets/images/printer.svg +++ b/assets/images/printer.svg @@ -1,13 +1,12 @@ - + - - - - - + + + + diff --git a/assets/images/profile.svg b/assets/images/profile.svg index ee451f70c775..9f41da0e141f 100644 --- a/assets/images/profile.svg +++ b/assets/images/profile.svg @@ -1,8 +1,10 @@ - + - - + + + + diff --git a/assets/images/question-mark-circle.svg b/assets/images/question-mark-circle.svg index 8bd33591355e..ae318f655750 100644 --- a/assets/images/question-mark-circle.svg +++ b/assets/images/question-mark-circle.svg @@ -1,12 +1,12 @@ - + - + + diff --git a/assets/images/receipt-search.svg b/assets/images/receipt-search.svg index 6272cfea3212..a8aa5f51f581 100644 --- a/assets/images/receipt-search.svg +++ b/assets/images/receipt-search.svg @@ -1,15 +1,16 @@ - + - - - + + + diff --git a/assets/images/receipt.svg b/assets/images/receipt.svg index 90b88db8c62a..5ad963dab8ad 100644 --- a/assets/images/receipt.svg +++ b/assets/images/receipt.svg @@ -1,9 +1,15 @@ - + - + + diff --git a/assets/images/rotate-image.svg b/assets/images/rotate-image.svg new file mode 100644 index 000000000000..b1c4f02cbb8d --- /dev/null +++ b/assets/images/rotate-image.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/assets/images/rotate-left.svg b/assets/images/rotate-left.svg index 7c48a7284ef3..47447cf91cf9 100644 --- a/assets/images/rotate-left.svg +++ b/assets/images/rotate-left.svg @@ -1,9 +1,8 @@ - + - + diff --git a/assets/images/send.svg b/assets/images/send.svg index c5a0f52a01bf..53bb81676042 100644 --- a/assets/images/send.svg +++ b/assets/images/send.svg @@ -1,7 +1,7 @@ - + - + diff --git a/assets/images/shield.svg b/assets/images/shield.svg new file mode 100644 index 000000000000..cb46f32fdfa0 --- /dev/null +++ b/assets/images/shield.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__bank-arrow.svg b/assets/images/simple-illustrations/simple-illustration__bank-arrow.svg new file mode 100644 index 000000000000..7e5b4dae1ccc --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__bank-arrow.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__bill.svg b/assets/images/simple-illustrations/simple-illustration__bill.svg new file mode 100644 index 000000000000..7fb76fb8c09b --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__bill.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__concierge-bubble.svg b/assets/images/simple-illustrations/simple-illustration__concierge-bubble.svg new file mode 100644 index 000000000000..eeabc78b1881 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__concierge-bubble.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__concierge.svg b/assets/images/simple-illustrations/simple-illustration__concierge.svg new file mode 100644 index 000000000000..8275671c3486 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__concierge.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__credit-cards.svg b/assets/images/simple-illustrations/simple-illustration__credit-cards.svg new file mode 100644 index 000000000000..8e070f074ef3 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__credit-cards.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__invoice.svg b/assets/images/simple-illustrations/simple-illustration__invoice.svg new file mode 100644 index 000000000000..0a10b70a7bfe --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__invoice.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__lockopen.svg b/assets/images/simple-illustrations/simple-illustration__lockopen.svg new file mode 100644 index 000000000000..fb07d7a8628b --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__lockopen.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__luggage.svg b/assets/images/simple-illustrations/simple-illustration__luggage.svg new file mode 100644 index 000000000000..9a01eee56662 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__luggage.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__money-receipts.svg b/assets/images/simple-illustrations/simple-illustration__money-receipts.svg new file mode 100644 index 000000000000..3d81f5dba653 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__money-receipts.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__moneybadge.svg b/assets/images/simple-illustrations/simple-illustration__moneybadge.svg new file mode 100644 index 000000000000..1f673aa20a90 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__moneybadge.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__moneyintowallet.svg b/assets/images/simple-illustrations/simple-illustration__moneyintowallet.svg new file mode 100644 index 000000000000..3f89e6b14836 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__moneyintowallet.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__moneywings.svg b/assets/images/simple-illustrations/simple-illustration__moneywings.svg new file mode 100644 index 000000000000..b13abdf448af --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__moneywings.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__opensafe.svg b/assets/images/simple-illustrations/simple-illustration__opensafe.svg new file mode 100644 index 000000000000..273d68b62723 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__opensafe.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__shield.svg b/assets/images/simple-illustrations/simple-illustration__shield.svg new file mode 100644 index 000000000000..5d56b9c3acb2 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__shield.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__thumbsupstars.svg b/assets/images/simple-illustrations/simple-illustration__thumbsupstars.svg new file mode 100644 index 000000000000..623874d2d3eb --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__thumbsupstars.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__track-shoe.svg b/assets/images/simple-illustrations/simple-illustration__track-shoe.svg new file mode 100644 index 000000000000..5d45f2f9df67 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__track-shoe.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/simple-illustrations/simple-illustration__treasurechest.svg b/assets/images/simple-illustrations/simple-illustration__treasurechest.svg new file mode 100644 index 000000000000..edb868db11d2 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__treasurechest.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/sync.svg b/assets/images/sync.svg index e4486116b970..65d8df356901 100644 --- a/assets/images/sync.svg +++ b/assets/images/sync.svg @@ -1,4 +1,10 @@ - - - + + + + + diff --git a/assets/images/three-dots.svg b/assets/images/three-dots.svg index 4d9b5384986a..1ff11c8448a1 100644 --- a/assets/images/three-dots.svg +++ b/assets/images/three-dots.svg @@ -1,7 +1,8 @@ - - - - - + + + + + diff --git a/assets/images/transfer.svg b/assets/images/transfer.svg index 03cb3c5f72b2..76288f8227b4 100644 --- a/assets/images/transfer.svg +++ b/assets/images/transfer.svg @@ -1,11 +1,9 @@ - + - - - - + + diff --git a/assets/images/trashcan.svg b/assets/images/trashcan.svg index a0e4110580a9..6158a705bd35 100644 --- a/assets/images/trashcan.svg +++ b/assets/images/trashcan.svg @@ -1 +1,11 @@ -trashcan \ No newline at end of file + + + + + + + diff --git a/assets/images/unlock.svg b/assets/images/unlock.svg new file mode 100644 index 000000000000..0cf22e8d1813 --- /dev/null +++ b/assets/images/unlock.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/images/upload-alt.svg b/assets/images/upload-alt.svg new file mode 100644 index 000000000000..260e93510373 --- /dev/null +++ b/assets/images/upload-alt.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/assets/images/upload.svg b/assets/images/upload.svg index 7760794acddf..dbb90377dfad 100644 --- a/assets/images/upload.svg +++ b/assets/images/upload.svg @@ -1,11 +1,8 @@ - + - - - - + + diff --git a/assets/images/user.svg b/assets/images/user.svg new file mode 100644 index 000000000000..96f403e2ce4a --- /dev/null +++ b/assets/images/user.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/assets/images/users.svg b/assets/images/users.svg index 948998d2c359..8af469328821 100644 --- a/assets/images/users.svg +++ b/assets/images/users.svg @@ -1,25 +1,10 @@ - + - - - - - - - - - - - - - - - + + + + diff --git a/assets/images/wallet.svg b/assets/images/wallet.svg index 5cd109ee053f..1c6d606683b8 100644 --- a/assets/images/wallet.svg +++ b/assets/images/wallet.svg @@ -1,11 +1,10 @@ - + - + diff --git a/assets/images/welcome-screenshot.png b/assets/images/welcome-screenshot.png deleted file mode 100644 index 4b6cc9a29cb4..000000000000 Binary files a/assets/images/welcome-screenshot.png and /dev/null differ diff --git a/assets/images/workspace-default-avatar.svg b/assets/images/workspace-default-avatar.svg index 96fd0832bfc5..63d0a47f6806 100644 --- a/assets/images/workspace-default-avatar.svg +++ b/assets/images/workspace-default-avatar.svg @@ -1 +1,13 @@ - + + + + + + + diff --git a/assets/images/zoom.svg b/assets/images/zoom.svg index 2984bb4b1a65..25e82c2903eb 100644 --- a/assets/images/zoom.svg +++ b/assets/images/zoom.svg @@ -1,13 +1,13 @@ - + - + + diff --git a/config/electronBuilder.config.js b/config/electronBuilder.config.js index 2c076e894032..db642e00008e 100644 --- a/config/electronBuilder.config.js +++ b/config/electronBuilder.config.js @@ -1,7 +1,27 @@ const {version} = require('../package.json'); -const isStaging = process.env.ELECTRON_ENV === 'staging'; const isPublishing = process.argv.includes('--publish'); +const pullRequestNumber = process.env.PULL_REQUEST_NUMBER; + +const s3Bucket = { + production: 'expensify-cash', + staging: 'staging-expensify-cash', + internal: 'ad-hoc-expensify-cash', +}; + +const s3Path = { + production: '/', + staging: '/', + internal: process.env.PULL_REQUEST_NUMBER + ? `/desktop/${pullRequestNumber}/` + : '/', +}; + +const macIcon = { + production: './desktop/icon.png', + staging: './desktop/icon-stg.png', + internal: './desktop/icon-stg.png', +}; /** * The configuration for the production and staging Electron builds. @@ -15,7 +35,7 @@ module.exports = { }, mac: { category: 'public.app-category.finance', - icon: isStaging ? './desktop/icon-stg.png' : './desktop/icon.png', + icon: macIcon[process.env.ELECTRON_ENV], hardenedRuntime: true, entitlements: 'desktop/entitlements.mac.plist', entitlementsInherit: 'desktop/entitlements.mac.plist', @@ -26,16 +46,16 @@ module.exports = { artifactName: 'NewExpensify.dmg', internetEnabled: true, }, - publish: [{ - provider: 's3', - bucket: isStaging ? 'staging-expensify-cash' : 'expensify-cash', - channel: 'latest', - }], - afterSign: isPublishing ? './desktop/notarize.js' : undefined, - files: [ - 'dist', - '!dist/www/{.well-known,favicon*}', + publish: [ + { + provider: 's3', + bucket: s3Bucket[process.env.ELECTRON_ENV], + channel: 'latest', + path: s3Path[process.env.ELECTRON_ENV], + }, ], + afterSign: isPublishing ? './desktop/notarize.js' : undefined, + files: ['dist', '!dist/www/{.well-known,favicon*}'], directories: { app: 'desktop', output: 'desktop-build', diff --git a/config/webpack/webpack.common.js b/config/webpack/webpack.common.js index 0b555105300a..fa8f4c049104 100644 --- a/config/webpack/webpack.common.js +++ b/config/webpack/webpack.common.js @@ -90,6 +90,7 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ {from: 'web/favicon-unread.png'}, {from: 'web/og-preview-image.png'}, {from: 'assets/css', to: 'css'}, + {from: 'assets/fonts', to: 'fonts'}, {from: 'node_modules/react-pdf/dist/esm/Page/AnnotationLayer.css', to: 'css/AnnotationLayer.css'}, {from: 'assets/images/shadow.png', to: 'images/shadow.png'}, {from: '.well-known/apple-app-site-association', to: '.well-known/apple-app-site-association', toType: 'file'}, @@ -187,6 +188,10 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ test: /\.css$/i, use: ['style-loader', 'css-loader'], }, + { + test: /\.(woff|woff2)$/i, + type: 'asset', + }, { resourceQuery: /raw/, type: 'asset/source', diff --git a/contributingGuides/CONTRIBUTING.md b/contributingGuides/CONTRIBUTING.md index 87a309fc567c..ea4504d07f6a 100644 --- a/contributingGuides/CONTRIBUTING.md +++ b/contributingGuides/CONTRIBUTING.md @@ -69,6 +69,7 @@ This is the most common scenario for contributors. The Expensify team posts new It’s possible that you found a new bug or new feature that we haven’t posted as a job to the [GitHub repository](https://github.com/Expensify/App/issues?q=is%3Aissue). This is an opportunity to propose a job, and (optionally) a solution for that job. If it's a valid job proposal that we choose to implement by deploying it to production — either internally or via an external contributor — then we will compensate you $250 for identifying and proposing the bug or feature. If the bug or feature is fixed by a PR that is not associated with your proposal, then you will not be eligible for the corresponding compensation unless you can find the PR that fixed it and prove your proposal came first. - Note: If you get assigned the job you proposed **and** you complete the job, this $250 for identifying the improvement is *in addition to* the reward you will be paid for completing the job. - Note about proposed bugs or features: Expensify has the right not to pay the $250 reward if the suggested bug or feature is already planned. Currently, Expensify plans to implement all features of the old Expensify app in New Expensify. +- Note: whilst you may optionally propose a solution for that job on Slack, solutions are ultimately reviewed in GitHub. The onus is on you to propose the solution on GitHub, and/or ensure the issue creator will include a link to your proposal. Please follow these steps to propose a job: diff --git a/contributingGuides/FORMS.md b/contributingGuides/FORMS.md index 78eae93b696c..a6562e237c9a 100644 --- a/contributingGuides/FORMS.md +++ b/contributingGuides/FORMS.md @@ -88,7 +88,7 @@ To give a slightly more detailed example of how this would work with phone numbe ### Form Drafts -Form inputs will NOT store draft values by default. This is to avoid accidentely storing any sensitive information like passwords, SSN or bank account information. We need to explicitly tell each form input to save draft values by passing the shouldSaveDraft prop to the input. Saving draft values is highly desireable and we should always try to save draft values. This way when a user continues a given flow they can easily pick up right where they left off if they accidentally exited a flow. Inputs with saved draft values [will be cleared when a user logs out](https://github.com/Expensify/App/blob/aa1f0f34eeba5d761657168255a1ae9aebdbd95e/src/libs/actions/SignInRedirect.js#L52) (like most data). Additionally we should clear draft data once the form is successfully submitted by calling `Onyx.set(ONYXKEY.FORM_ID, null)` in the onSubmit callback passed to Form. +Form inputs will NOT store draft values by default. This is to avoid accidentally storing any sensitive information like passwords, SSN or bank account information. We need to explicitly tell each form input to save draft values by passing the shouldSaveDraft prop to the input. Saving draft values is highly desirable and we should always try to save draft values. This way when a user continues a given flow they can easily pick up right where they left off if they accidentally exited a flow. Inputs with saved draft values [will be cleared when a user logs out](https://github.com/Expensify/App/blob/aa1f0f34eeba5d761657168255a1ae9aebdbd95e/src/libs/actions/SignInRedirect.js#L52) (like most data). Additionally, we should clear draft data once the form is successfully submitted by calling `Onyx.set(ONYXKEY.FORM_ID, null)` in the onSubmit callback passed to Form. ```jsx + com.apple.security.cs.allow-jit + com.apple.security.cs.allow-unsigned-executable-memory diff --git a/desktop/icon-dev.png b/desktop/icon-dev.png index bd8e57dfbe23..4589faa80d41 100644 Binary files a/desktop/icon-dev.png and b/desktop/icon-dev.png differ diff --git a/desktop/icon-stg.png b/desktop/icon-stg.png index 2a45484acb67..c605f8aea6ad 100644 Binary files a/desktop/icon-stg.png and b/desktop/icon-stg.png differ diff --git a/desktop/icon.png b/desktop/icon.png index f0a50e5aaeae..f837c238d19d 100644 Binary files a/desktop/icon.png and b/desktop/icon.png differ diff --git a/desktop/main.js b/desktop/main.js index 78c13e4d448c..da5e13e91e22 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -1,5 +1,6 @@ const { app, + dialog, BrowserWindow, Menu, MenuItem, @@ -80,6 +81,55 @@ const quitAndInstallWithUpdate = () => { autoUpdater.quitAndInstall(); }; +/** + * Menu Item callback to triggers an update check + * @param {MenuItem} menuItem + * @param {BrowserWindow} browserWindow + */ +const manuallyCheckForUpdates = (menuItem, browserWindow) => { + // Disable item until the check (and download) is complete + // eslint: menu item flags like enabled or visible can be dynamically toggled by mutating the object + // eslint-disable-next-line no-param-reassign + menuItem.enabled = false; + + autoUpdater.checkForUpdates() + .catch(error => ({error})) + .then((result) => { + const downloadPromise = result && result.downloadPromise; + + if (downloadPromise) { + dialog.showMessageBox(browserWindow, { + type: 'info', + message: 'Update Available', + detail: 'The new version will be available shortly. We’ll notify you when we’re ready to update.', + buttons: ['Sounds good'], + }); + } else if (result && result.error) { + dialog.showMessageBox(browserWindow, { + type: 'error', + message: 'Update Check Failed', + detail: 'We couldn’t look for an update. Please check again in a bit!', + buttons: ['Okay'], + }); + } else { + dialog.showMessageBox(browserWindow, { + type: 'info', + message: 'Update Not Available', + detail: 'There is no update available as of now! Check again at a later time.', + buttons: ['Okay'], + cancelId: 2, + }); + } + + // By returning the `downloadPromise` we keep "check for updates" disabled if any updates are being downloaded + return downloadPromise; + }) + .finally(() => { + // eslint-disable-next-line no-param-reassign + menuItem.enabled = true; + }); +}; + /** * Trigger event to show keyboard shortcuts * @param {BrowserWindow} browserWindow @@ -91,13 +141,21 @@ const showKeyboardShortcutsModal = (browserWindow) => { browserWindow.webContents.send(ELECTRON_EVENTS.SHOW_KEYBOARD_SHORTCUTS_MODAL); }; -// Defines the system-level menu item for manually triggering an update after +// Defines the system-level menu item to manually apply an update +// This menu item should become visible after an update is downloaded and ready to be applied const updateAppMenuItem = new MenuItem({ label: 'Update New Expensify', - enabled: false, + visible: false, click: quitAndInstallWithUpdate, }); +// System-level menu item to manually check for App updates +const checkForUpdateMenuItem = new MenuItem({ + label: 'Check For Updates', + visible: true, + click: manuallyCheckForUpdates, +}); + // Defines the system-level menu item for opening keyboard shortcuts modal const keyboardShortcutsMenu = new MenuItem({ label: 'View Keyboard Shortcuts', @@ -109,7 +167,8 @@ const electronUpdater = browserWindow => ({ init: () => { autoUpdater.on(ELECTRON_EVENTS.UPDATE_DOWNLOADED, (info) => { downloadedVersion = info.version; - updateAppMenuItem.enabled = true; + updateAppMenuItem.visible = true; + checkForUpdateMenuItem.visible = false; if (browserWindow.isVisible()) { browserWindow.webContents.send(ELECTRON_EVENTS.UPDATE_DOWNLOADED, info.version); } else { @@ -137,6 +196,12 @@ const mainWindow = (() => { app.setName('New Expensify'); } + /* + * Starting from Electron 20, it shall be required to set sandbox option to false explicitly. + * Running a preload script contextBridge.js require access to nodeJS modules from the javascript code. + * This was not a concern earlier as sandbox used to be false by default for Electron <= 20. + * Refer https://www.electronjs.org/docs/latest/tutorial/sandbox#disabling-the-sandbox-for-a-single-process + * */ return app.whenReady() .then(() => { const browserWindow = new BrowserWindow({ @@ -146,6 +211,7 @@ const mainWindow = (() => { webPreferences: { preload: `${__dirname}/contextBridge.js`, contextIsolation: true, + sandbox: false, }, titleBarStyle: 'hidden', }); @@ -221,7 +287,8 @@ const mainWindow = (() => { const appMenu = _.find(systemMenu.items, item => item.role === 'appmenu'); appMenu.submenu.insert(1, updateAppMenuItem); - appMenu.submenu.insert(2, keyboardShortcutsMenu); + appMenu.submenu.insert(2, checkForUpdateMenuItem); + appMenu.submenu.insert(3, keyboardShortcutsMenu); // On mac, pressing cmd++ actually sends a cmd+=. cmd++ is generally the zoom in shortcut, but this is // not properly listened for by electron. Adding in an invisible cmd+= listener fixes this. diff --git a/docs/404.html b/docs/404.html index 6440e4efb47f..1773388c6923 100644 --- a/docs/404.html +++ b/docs/404.html @@ -2,7 +2,7 @@ permalink: /404.html ---
- + Hmm it's not here...
That page is nowhere to be found.
diff --git a/docs/assets/images/concierge-avatar.svg b/docs/assets/images/concierge-avatar.svg index 2372f3ea9183..d2a7cf31ac98 100644 --- a/docs/assets/images/concierge-avatar.svg +++ b/docs/assets/images/concierge-avatar.svg @@ -1,5 +1,39 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 74060ccb501c..959810eee87c 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -36,6 +36,29 @@ platform :android do ) end + desc "Build app for testing" + lane :build_internal do + ENV["ENVFILE"]=".env.staging" + + gradle( + project_dir: './android', + task: 'assemble', + build_type: 'InternalRelease', + ) + + aws_s3( + access_key: ENV['S3_ACCESS_KEY'], + secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], + bucket: ENV['S3_BUCKET'], + region: ENV['S3_REGION'], + + apk: lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], + app_directory: "android/#{ENV['PULL_REQUEST_NUMBER']}", + ) + + sh("echo '{\"apk_path\": \"#{lane_context[SharedValues::S3_APK_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../android_paths.json") + end + desc "Build and upload app to Google Play" lane :beta do ENV["ENVFILE"]=".env.production" @@ -91,6 +114,59 @@ platform :ios do ) end + desc "Build app for testing" + lane :build_internal do + require 'securerandom' + ENV["ENVFILE"]=".env.staging" + + keychain_password = SecureRandom.uuid + + create_keychain( + name: "ios-build.keychain", + password: keychain_password, + default_keychain: "true", + unlock: "true", + timeout: "3600", + add_to_search_list: "true" + ) + + import_certificate( + certificate_path: "./ios/Certificates.p12", + keychain_name: "ios-build.keychain", + keychain_password: keychain_password + ) + + install_provisioning_profile( + path: "./ios/chat_expensify_adhoc.mobileprovision" + ) + + build_app( + workspace: "./ios/NewExpensify.xcworkspace", + skip_profile_detection: true, + scheme: "NewExpensify", + export_method: "ad-hoc", + export_options: { + method: "ad-hoc", + provisioningProfiles: { + "com.chat.expensify.chat" => "chat_expensify_adhoc", + }, + manageAppVersionAndBuildNumber: false + } + ) + + aws_s3( + access_key: ENV['S3_ACCESS_KEY'], + secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], + bucket: ENV['S3_BUCKET'], + region: ENV['S3_REGION'], + + ipa: lane_context[SharedValues::IPA_OUTPUT_PATH], + app_directory: "android/#{ENV['PULL_REQUEST_NUMBER']}", + ) + + sh("echo '{\"ipa_path\": \"#{lane_context[SharedValues::S3_IPA_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../ios_paths.json") + end + desc "Build and upload app to TestFlight" lane :beta do require 'securerandom' diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile new file mode 100644 index 000000000000..c6ab0dfb46a4 --- /dev/null +++ b/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-aws_s3' diff --git a/ios/AirshipConfig.plist b/ios/AirshipConfig.plist index 3502dc33584f..32926a3c6bcf 100644 --- a/ios/AirshipConfig.plist +++ b/ios/AirshipConfig.plist @@ -4,13 +4,13 @@ detectProvisioningMode - developmentAppKey + appKey uulSSfTDQJ2r0PMpjRrhmQ - developmentAppSecret + appSecret D4Bhf0HrQEehrPua74Tyiw - productionAppKey + appKey 55vypj0ARc6cN09MX7ogtQ - productionAppSecret + appSecret EsSaqbdLSvmyC6kSBFJCtQ diff --git a/ios/ExpensifyMono-Bold.otf b/ios/ExpensifyMono-Bold.otf deleted file mode 100755 index 4198f46f6d79..000000000000 Binary files a/ios/ExpensifyMono-Bold.otf and /dev/null differ diff --git a/ios/ExpensifyMono-Regular.otf b/ios/ExpensifyMono-Regular.otf deleted file mode 100755 index 1c6242a717f9..000000000000 Binary files a/ios/ExpensifyMono-Regular.otf and /dev/null differ diff --git a/ios/ExpensifyNeue-Bold.otf b/ios/ExpensifyNeue-Bold.otf deleted file mode 100755 index 7534aecda322..000000000000 Binary files a/ios/ExpensifyNeue-Bold.otf and /dev/null differ diff --git a/ios/ExpensifyNeue-BoldItalic.otf b/ios/ExpensifyNeue-BoldItalic.otf deleted file mode 100755 index 4c28031fedd6..000000000000 Binary files a/ios/ExpensifyNeue-BoldItalic.otf and /dev/null differ diff --git a/ios/ExpensifyNeue-Italic.otf b/ios/ExpensifyNeue-Italic.otf deleted file mode 100755 index a5d19502dbfe..000000000000 Binary files a/ios/ExpensifyNeue-Italic.otf and /dev/null differ diff --git a/ios/ExpensifyNeue-Regular.otf b/ios/ExpensifyNeue-Regular.otf deleted file mode 100755 index d4d8cbe63b44..000000000000 Binary files a/ios/ExpensifyNeue-Regular.otf and /dev/null differ diff --git a/ios/ExpensifyNewKansas-Medium.otf b/ios/ExpensifyNewKansas-Medium.otf deleted file mode 100755 index a7277555fad9..000000000000 Binary files a/ios/ExpensifyNewKansas-Medium.otf and /dev/null differ diff --git a/ios/ExpensifyNewKansas-MediumItalic.otf b/ios/ExpensifyNewKansas-MediumItalic.otf deleted file mode 100755 index 984ef4bfa2d4..000000000000 Binary files a/ios/ExpensifyNewKansas-MediumItalic.otf and /dev/null differ diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index 953179f1e1f8..708956b75d26 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -15,28 +15,24 @@ 0F5BE0CE252686330097D869 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0F5BE0CD252686320097D869 /* GoogleService-Info.plist */; }; 0F5E5350263B73FD004CA14F /* EnvironmentChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F5E534F263B73FD004CA14F /* EnvironmentChecker.m */; }; 0F5E5351263B73FD004CA14F /* EnvironmentChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F5E534F263B73FD004CA14F /* EnvironmentChecker.m */; }; - 12DD1878FCB9487C9F031C86 /* GTAmericaExpMono-Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 18D050E0262400AF000D658B /* BridgingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D050DF262400AF000D658B /* BridgingFile.swift */; }; - 1E76D5212522316A005A268F /* GTAmericaExp-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */; }; - 1E76D5222522316A005A268F /* GTAmericaExp-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */; }; - 1E76D5232522316A005A268F /* GTAmericaExp-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */; }; - 1E76D5242522316A005A268F /* GTAmericaExp-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */; }; - 1E76D5252522316A005A268F /* GTAmericaExp-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */; }; 374FB8D728A133FE000D84EF /* OriginImageRequestHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 374FB8D628A133FE000D84EF /* OriginImageRequestHandler.mm */; }; - 425866037F4C482AAB46CB8B /* GTAmericaExp-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */; }; - 52477A09739546F4814EA25F /* GTAmericaExpMono-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */; }; + 597489DE2936B81100AE6F8B /* ExpensifyNeue-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541512915C8CF001E81A5 /* ExpensifyNeue-Bold.otf */; }; + 597489DF2936B81400AE6F8B /* ExpensifyMono-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541522915C8DF001E81A5 /* ExpensifyMono-Bold.otf */; }; + 597489E02936B81600AE6F8B /* ExpensifyMono-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541532915C8DF001E81A5 /* ExpensifyMono-Regular.otf */; }; + 597489E12936B81900AE6F8B /* ExpensifyNewKansas-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541542915C8ED001E81A5 /* ExpensifyNewKansas-Medium.otf */; }; + 597489E22936B81C00AE6F8B /* ExpensifyNewKansas-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541552915C8ED001E81A5 /* ExpensifyNewKansas-MediumItalic.otf */; }; + 597489E32936B81E00AE6F8B /* ExpensifyNeue-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5935414F2915C8CF001E81A5 /* ExpensifyNeue-BoldItalic.otf */; }; + 597489E42936B82000AE6F8B /* ExpensifyNeue-Italic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 593541502915C8CF001E81A5 /* ExpensifyNeue-Italic.otf */; }; + 597489E52936B82200AE6F8B /* ExpensifyNeue-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5935414E2915C8CF001E81A5 /* ExpensifyNeue-Regular.otf */; }; 5E2EE3856BE7BC98F354B110 /* libPods-NewExpensify.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EDF186626B8D2CBA203E08D /* libPods-NewExpensify.a */; }; - 6856B78873B64C44A92E51DB /* GTAmericaExp-MdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */; }; 7041848526A8E47D00E09F4D /* RCTStartupTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7041848426A8E47D00E09F4D /* RCTStartupTimer.m */; }; 7041848626A8E47D00E09F4D /* RCTStartupTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7041848426A8E47D00E09F4D /* RCTStartupTimer.m */; }; 70CF6E82262E297300711ADC /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 70CF6E81262E297300711ADC /* BootSplash.storyboard */; }; - 8821A238A081483FA947BC4E /* GTAmericaExp-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */; }; - DB77016704074197AB6633BB /* GTAmericaExpMono-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */; }; DD79042B2792E76D004484B4 /* RCTBootSplash.m in Sources */ = {isa = PBXBuildFile; fileRef = DD79042A2792E76D004484B4 /* RCTBootSplash.m */; }; E3B48DC1ED4CC64F660388A8 /* libPods-NewExpensify-NewExpensifyTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A2695CF895D81C31AFB4A074 /* libPods-NewExpensify-NewExpensifyTests.a */; }; E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; }; - ED814D34526B415CAFA0451E /* GTAmericaExpMono-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */; }; F0C450EA2705020500FD2970 /* colors.json in Resources */ = {isa = PBXBuildFile; fileRef = F0C450E92705020500FD2970 /* colors.json */; }; /* End PBXBuildFile section */ @@ -60,7 +56,6 @@ 02BB59C8C4E7D63E4192F2FA /* Pods-NewExpensify-NewExpensifyTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug.xcconfig"; sourceTree = ""; }; 0CDA8E33287DD650004ECBEC /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = NewExpensify/AppDelegate.mm; sourceTree = ""; }; 0CDA8E36287DD6A0004ECBEC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = NewExpensify/Images.xcassets; sourceTree = ""; }; - 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Bd.otf"; path = "../assets/fonts/GTAmericaExpMono-Bd.otf"; sourceTree = ""; }; 0F5BE0CD252686320097D869 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 0F5E534E263B73D5004CA14F /* EnvironmentChecker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EnvironmentChecker.h; sourceTree = ""; }; 0F5E534F263B73FD004CA14F /* EnvironmentChecker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EnvironmentChecker.m; sourceTree = ""; }; @@ -71,31 +66,20 @@ 18D050DF262400AF000D658B /* BridgingFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BridgingFile.swift; sourceTree = ""; }; 374FB8D528A133A7000D84EF /* OriginImageRequestHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OriginImageRequestHandler.h; path = NewExpensify/OriginImageRequestHandler.h; sourceTree = ""; }; 374FB8D628A133FE000D84EF /* OriginImageRequestHandler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = OriginImageRequestHandler.mm; path = NewExpensify/OriginImageRequestHandler.mm; sourceTree = ""; }; - 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-BdIt.otf"; path = "../assets/fonts/GTAmericaExpMono-BdIt.otf"; sourceTree = ""; }; 3EDF186626B8D2CBA203E08D /* libPods-NewExpensify.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NewExpensify.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-RgIt.otf"; path = "../assets/fonts/GTAmericaExpMono-RgIt.otf"; sourceTree = ""; }; - 5935414E2915C8CF001E81A5 /* ExpensifyNeue-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNeue-Regular.otf"; sourceTree = ""; }; - 5935414F2915C8CF001E81A5 /* ExpensifyNeue-BoldItalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNeue-BoldItalic.otf"; sourceTree = ""; }; - 593541502915C8CF001E81A5 /* ExpensifyNeue-Italic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNeue-Italic.otf"; sourceTree = ""; }; - 593541512915C8CF001E81A5 /* ExpensifyNeue-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNeue-Bold.otf"; sourceTree = ""; }; - 593541522915C8DF001E81A5 /* ExpensifyMono-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyMono-Bold.otf"; sourceTree = ""; }; - 593541532915C8DF001E81A5 /* ExpensifyMono-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyMono-Regular.otf"; sourceTree = ""; }; - 593541542915C8ED001E81A5 /* ExpensifyNewKansas-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNewKansas-Medium.otf"; sourceTree = ""; }; - 593541552915C8ED001E81A5 /* ExpensifyNewKansas-MediumItalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ExpensifyNewKansas-MediumItalic.otf"; sourceTree = ""; }; - 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Light.otf"; path = "../assets/fonts/GTAmericaExp-Light.otf"; sourceTree = ""; }; + 5935414E2915C8CF001E81A5 /* ExpensifyNeue-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNeue-Regular.otf"; path = "../assets/fonts/ExpensifyNeue-Regular.otf"; sourceTree = ""; }; + 5935414F2915C8CF001E81A5 /* ExpensifyNeue-BoldItalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNeue-BoldItalic.otf"; path = "../assets/fonts/ExpensifyNeue-BoldItalic.otf"; sourceTree = ""; }; + 593541502915C8CF001E81A5 /* ExpensifyNeue-Italic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNeue-Italic.otf"; path = "../assets/fonts/ExpensifyNeue-Italic.otf"; sourceTree = ""; }; + 593541512915C8CF001E81A5 /* ExpensifyNeue-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNeue-Bold.otf"; path = "../assets/fonts/ExpensifyNeue-Bold.otf"; sourceTree = ""; }; + 593541522915C8DF001E81A5 /* ExpensifyMono-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyMono-Bold.otf"; path = "../assets/fonts/ExpensifyMono-Bold.otf"; sourceTree = ""; }; + 593541532915C8DF001E81A5 /* ExpensifyMono-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyMono-Regular.otf"; path = "../assets/fonts/ExpensifyMono-Regular.otf"; sourceTree = ""; }; + 593541542915C8ED001E81A5 /* ExpensifyNewKansas-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNewKansas-Medium.otf"; path = "../assets/fonts/ExpensifyNewKansas-Medium.otf"; sourceTree = ""; }; + 593541552915C8ED001E81A5 /* ExpensifyNewKansas-MediumItalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ExpensifyNewKansas-MediumItalic.otf"; path = "../assets/fonts/ExpensifyNewKansas-MediumItalic.otf"; sourceTree = ""; }; 7041848326A8E40900E09F4D /* RCTStartupTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RCTStartupTimer.h; path = NewExpensify/RCTStartupTimer.h; sourceTree = ""; }; 7041848426A8E47D00E09F4D /* RCTStartupTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RCTStartupTimer.m; path = NewExpensify/RCTStartupTimer.m; sourceTree = ""; }; 70CF6E81262E297300711ADC /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = NewExpensify/BootSplash.storyboard; sourceTree = ""; }; - 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Rg.otf"; path = "../assets/fonts/GTAmericaExpMono-Rg.otf"; sourceTree = ""; }; - 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Regular.otf"; path = "../assets/fonts/GTAmericaExp-Regular.otf"; sourceTree = ""; }; - 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-RgIt.otf"; path = "../assets/fonts/GTAmericaExp-RgIt.otf"; sourceTree = ""; }; A2695CF895D81C31AFB4A074 /* libPods-NewExpensify-NewExpensifyTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NewExpensify-NewExpensifyTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Thin.otf"; path = "../assets/fonts/GTAmericaExp-Thin.otf"; sourceTree = ""; }; - A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Bold.otf"; path = "../assets/fonts/GTAmericaExp-Bold.otf"; sourceTree = ""; }; - A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-BdIt.otf"; path = "../assets/fonts/GTAmericaExp-BdIt.otf"; sourceTree = ""; }; - AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Medium.otf"; path = "../assets/fonts/GTAmericaExp-Medium.otf"; sourceTree = ""; }; B66D52EC75F78B8A06F1E035 /* Pods-NewExpensify.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debug.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debug.xcconfig"; sourceTree = ""; }; - DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; sourceTree = ""; }; DD7904292792E76D004484B4 /* RCTBootSplash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTBootSplash.h; path = NewExpensify/RCTBootSplash.h; sourceTree = ""; }; DD79042A2792E76D004484B4 /* RCTBootSplash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTBootSplash.m; path = NewExpensify/RCTBootSplash.m; sourceTree = ""; }; E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; }; @@ -213,7 +197,6 @@ A9EA265D209D4558995C9BD4 /* Resources */ = { isa = PBXGroup; children = ( - A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */, 593541512915C8CF001E81A5 /* ExpensifyNeue-Bold.otf */, 593541522915C8DF001E81A5 /* ExpensifyMono-Bold.otf */, 593541532915C8DF001E81A5 /* ExpensifyMono-Regular.otf */, @@ -222,17 +205,6 @@ 5935414F2915C8CF001E81A5 /* ExpensifyNeue-BoldItalic.otf */, 593541502915C8CF001E81A5 /* ExpensifyNeue-Italic.otf */, 5935414E2915C8CF001E81A5 /* ExpensifyNeue-Regular.otf */, - 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */, - AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */, - 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */, - A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */, - 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */, - A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */, - DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */, - 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */, - 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */, - 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */, - 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */, ); name = Resources; sourceTree = ""; @@ -348,23 +320,19 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 597489E52936B82200AE6F8B /* ExpensifyNeue-Regular.otf in Resources */, + 597489E22936B81C00AE6F8B /* ExpensifyNewKansas-MediumItalic.otf in Resources */, 0F5BE0CE252686330097D869 /* GoogleService-Info.plist in Resources */, + 597489E02936B81600AE6F8B /* ExpensifyMono-Regular.otf in Resources */, E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */, - 12DD1878FCB9487C9F031C86 /* GTAmericaExpMono-Rg.otf in Resources */, - 1E76D5212522316A005A268F /* GTAmericaExp-Bold.otf in Resources */, - 1E76D5222522316A005A268F /* GTAmericaExp-Light.otf in Resources */, - 1E76D5232522316A005A268F /* GTAmericaExp-Medium.otf in Resources */, - 1E76D5242522316A005A268F /* GTAmericaExp-Regular.otf in Resources */, F0C450EA2705020500FD2970 /* colors.json in Resources */, - 1E76D5252522316A005A268F /* GTAmericaExp-Thin.otf in Resources */, - 425866037F4C482AAB46CB8B /* GTAmericaExp-BdIt.otf in Resources */, - 6856B78873B64C44A92E51DB /* GTAmericaExp-MdIt.otf in Resources */, + 597489E32936B81E00AE6F8B /* ExpensifyNeue-BoldItalic.otf in Resources */, + 597489DF2936B81400AE6F8B /* ExpensifyMono-Bold.otf in Resources */, + 597489E12936B81900AE6F8B /* ExpensifyNewKansas-Medium.otf in Resources */, + 597489E42936B82000AE6F8B /* ExpensifyNeue-Italic.otf in Resources */, + 597489DE2936B81100AE6F8B /* ExpensifyNeue-Bold.otf in Resources */, 0CDA8E37287DD6A0004ECBEC /* Images.xcassets in Resources */, - 8821A238A081483FA947BC4E /* GTAmericaExp-RgIt.otf in Resources */, 70CF6E82262E297300711ADC /* BootSplash.storyboard in Resources */, - 52477A09739546F4814EA25F /* GTAmericaExpMono-Bd.otf in Resources */, - ED814D34526B415CAFA0451E /* GTAmericaExpMono-BdIt.otf in Resources */, - DB77016704074197AB6633BB /* GTAmericaExpMono-RgIt.otf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -766,7 +734,7 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -791,6 +759,7 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; name = Debug; @@ -827,7 +796,7 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -844,6 +813,7 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/ios/NewExpensify.xcworkspace/contents.xcworkspacedata b/ios/NewExpensify.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..bf66f1bed435 --- /dev/null +++ b/ios/NewExpensify.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/NewExpensify/BootSplash.storyboard b/ios/NewExpensify/BootSplash.storyboard index 8ee04cf74b3b..00b73194f144 100644 --- a/ios/NewExpensify/BootSplash.storyboard +++ b/ios/NewExpensify/BootSplash.storyboard @@ -24,7 +24,7 @@ - + diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/Store.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/Store.png index f9cb090957f4..35d8a1c3cef2 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/Store.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/Store.png differ diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@2x.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@2x.png index 4f10387caf28..2f88e782bfd9 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@2x.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@2x.png differ diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@3x.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@3x.png index 95054fc13d36..cae156c0409f 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@3x.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iOS@3x.png differ diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad.png index 040a3fff300b..c4f9c3c467d0 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad.png differ diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad@2x.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad@2x.png index 7b0abef8d05c..f36fe1698c60 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad@2x.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPad@2x.png differ diff --git a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPadPro.png b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPadPro.png index eedfcdb2e04a..389e9bf64676 100644 Binary files a/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPadPro.png and b/ios/NewExpensify/Images.xcassets/AppIcon.appiconset/iPadPro.png differ diff --git a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png index 0aa07e4792b1..7d0644eed692 100644 Binary files a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png and b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png differ diff --git a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png index b9fc4eb21a78..90bb9b0c4eed 100644 Binary files a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png and b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png differ diff --git a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png index 59e4967cf66f..295d9fed4b29 100644 Binary files a/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png and b/ios/NewExpensify/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png differ diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 9924d88e457c..ba2aefa9279f 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.2.29 + 1.2.36 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.2.29.6 + 1.2.36.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes @@ -83,18 +83,6 @@ ExpensifyNeue-Bold.otf ExpensifyMono-Regular.otf ExpensifyMono-Bold.otf - GTAmericaExp-Bold.otf - GTAmericaExp-Light.otf - GTAmericaExp-Medium.otf - GTAmericaExp-Regular.otf - GTAmericaExp-Thin.otf - GTAmericaExpMono-Rg.otf - GTAmericaExp-BdIt.otf - GTAmericaExp-MdIt.otf - GTAmericaExp-RgIt.otf - GTAmericaExpMono-Bd.otf - GTAmericaExpMono-BdIt.otf - GTAmericaExpMono-RgIt.otf UIBackgroundModes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 5a1b5459afcb..1fb5af250556 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.2.29 + 1.2.36 CFBundleSignature ???? CFBundleVersion - 1.2.29.6 + 1.2.36.1 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e8c0a53362e1..c696014a9b31 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -17,14 +17,14 @@ PODS: - boost (1.76.0) - CocoaAsyncSocket (7.6.5) - DoubleConversion (1.1.6) - - FBLazyVector (0.70.4-alpha.1) - - FBReactNativeSpec (0.70.4-alpha.1): + - FBLazyVector (0.70.4-alpha.2) + - FBReactNativeSpec (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 0.70.4-alpha.1) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Core (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) + - RCTRequired (= 0.70.4-alpha.2) + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Core (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) - Firebase/Analytics (8.8.0): - Firebase/Core - Firebase/Core (8.8.0): @@ -181,45 +181,45 @@ PODS: - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/AppDelegateSwizzler (7.7.0): + - GoogleUtilities/AppDelegateSwizzler (7.10.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (7.7.0): + - GoogleUtilities/Environment (7.10.0): - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/ISASwizzler (7.7.0) - - GoogleUtilities/Logger (7.7.0): + - GoogleUtilities/ISASwizzler (7.10.0) + - GoogleUtilities/Logger (7.10.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (7.7.0): + - GoogleUtilities/MethodSwizzler (7.10.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (7.7.0): + - GoogleUtilities/Network (7.10.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.7.0)" - - GoogleUtilities/Reachability (7.7.0): + - "GoogleUtilities/NSData+zlib (7.10.0)" + - GoogleUtilities/Reachability (7.10.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (7.7.0): + - GoogleUtilities/UserDefaults (7.10.0): - GoogleUtilities/Logger - hermes-engine (0.70.4) - libevent (2.1.12) - - libwebp (1.2.3): - - libwebp/demux (= 1.2.3) - - libwebp/mux (= 1.2.3) - - libwebp/webp (= 1.2.3) - - libwebp/demux (1.2.3): + - libwebp (1.2.4): + - libwebp/demux (= 1.2.4) + - libwebp/mux (= 1.2.4) + - libwebp/webp (= 1.2.4) + - libwebp/demux (1.2.4): - libwebp/webp - - libwebp/mux (1.2.3): + - libwebp/mux (1.2.4): - libwebp/demux - - libwebp/webp (1.2.3) + - libwebp/webp (1.2.4) - nanopb (2.30908.0): - nanopb/decode (= 2.30908.0) - nanopb/encode (= 2.30908.0) - nanopb/decode (2.30908.0) - nanopb/encode (2.30908.0) - - Onfido (26.0.1) - - onfido-react-native-sdk (6.0.0): - - Onfido (= 26.0.1) + - Onfido (27.0.0) + - onfido-react-native-sdk (7.0.1): + - Onfido (= 27.0.0) - React - OpenSSL-Universal (1.1.1100) - Permission-Camera (3.6.1): @@ -249,214 +249,214 @@ PODS: - fmt (~> 6.2.1) - glog - libevent - - RCTRequired (0.70.4-alpha.1) - - RCTTypeSafety (0.70.4-alpha.1): - - FBLazyVector (= 0.70.4-alpha.1) - - RCTRequired (= 0.70.4-alpha.1) - - React-Core (= 0.70.4-alpha.1) - - React (0.70.4-alpha.1): - - React-Core (= 0.70.4-alpha.1) - - React-Core/DevSupport (= 0.70.4-alpha.1) - - React-Core/RCTWebSocket (= 0.70.4-alpha.1) - - React-RCTActionSheet (= 0.70.4-alpha.1) - - React-RCTAnimation (= 0.70.4-alpha.1) - - React-RCTBlob (= 0.70.4-alpha.1) - - React-RCTImage (= 0.70.4-alpha.1) - - React-RCTLinking (= 0.70.4-alpha.1) - - React-RCTNetwork (= 0.70.4-alpha.1) - - React-RCTSettings (= 0.70.4-alpha.1) - - React-RCTText (= 0.70.4-alpha.1) - - React-RCTVibration (= 0.70.4-alpha.1) - - React-bridging (0.70.4-alpha.1): + - RCTRequired (0.70.4-alpha.2) + - RCTTypeSafety (0.70.4-alpha.2): + - FBLazyVector (= 0.70.4-alpha.2) + - RCTRequired (= 0.70.4-alpha.2) + - React-Core (= 0.70.4-alpha.2) + - React (0.70.4-alpha.2): + - React-Core (= 0.70.4-alpha.2) + - React-Core/DevSupport (= 0.70.4-alpha.2) + - React-Core/RCTWebSocket (= 0.70.4-alpha.2) + - React-RCTActionSheet (= 0.70.4-alpha.2) + - React-RCTAnimation (= 0.70.4-alpha.2) + - React-RCTBlob (= 0.70.4-alpha.2) + - React-RCTImage (= 0.70.4-alpha.2) + - React-RCTLinking (= 0.70.4-alpha.2) + - React-RCTNetwork (= 0.70.4-alpha.2) + - React-RCTSettings (= 0.70.4-alpha.2) + - React-RCTText (= 0.70.4-alpha.2) + - React-RCTVibration (= 0.70.4-alpha.2) + - React-bridging (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - React-jsi (= 0.70.4-alpha.1) - - React-callinvoker (0.70.4-alpha.1) - - React-Codegen (0.70.4-alpha.1): - - FBReactNativeSpec (= 0.70.4-alpha.1) + - React-jsi (= 0.70.4-alpha.2) + - React-callinvoker (0.70.4-alpha.2) + - React-Codegen (0.70.4-alpha.2): + - FBReactNativeSpec (= 0.70.4-alpha.2) - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 0.70.4-alpha.1) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Core (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-Core (0.70.4-alpha.1): + - RCTRequired (= 0.70.4-alpha.2) + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Core (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-Core (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.70.4-alpha.1) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-Core/Default (= 0.70.4-alpha.2) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/CoreModulesHeaders (0.70.4-alpha.1): + - React-Core/CoreModulesHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/Default (0.70.4-alpha.1): + - React-Core/Default (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/DevSupport (0.70.4-alpha.1): + - React-Core/DevSupport (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.70.4-alpha.1) - - React-Core/RCTWebSocket (= 0.70.4-alpha.1) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-jsinspector (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-Core/Default (= 0.70.4-alpha.2) + - React-Core/RCTWebSocket (= 0.70.4-alpha.2) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-jsinspector (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTActionSheetHeaders (0.70.4-alpha.1): + - React-Core/RCTActionSheetHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTAnimationHeaders (0.70.4-alpha.1): + - React-Core/RCTAnimationHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTBlobHeaders (0.70.4-alpha.1): + - React-Core/RCTBlobHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTImageHeaders (0.70.4-alpha.1): + - React-Core/RCTImageHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTLinkingHeaders (0.70.4-alpha.1): + - React-Core/RCTLinkingHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTNetworkHeaders (0.70.4-alpha.1): + - React-Core/RCTNetworkHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTSettingsHeaders (0.70.4-alpha.1): + - React-Core/RCTSettingsHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTTextHeaders (0.70.4-alpha.1): + - React-Core/RCTTextHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTVibrationHeaders (0.70.4-alpha.1): + - React-Core/RCTVibrationHeaders (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-Core/RCTWebSocket (0.70.4-alpha.1): + - React-Core/RCTWebSocket (0.70.4-alpha.2): - glog - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.70.4-alpha.1) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-Core/Default (= 0.70.4-alpha.2) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - Yoga - - React-CoreModules (0.70.4-alpha.1): + - React-CoreModules (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/CoreModulesHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-RCTImage (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-cxxreact (0.70.4-alpha.1): + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/CoreModulesHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-RCTImage (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-cxxreact (0.70.4-alpha.2): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsinspector (= 0.70.4-alpha.1) - - React-logger (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) - - React-runtimeexecutor (= 0.70.4-alpha.1) - - React-hermes (0.70.4-alpha.1): + - React-callinvoker (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsinspector (= 0.70.4-alpha.2) + - React-logger (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) + - React-runtimeexecutor (= 0.70.4-alpha.2) + - React-hermes (0.70.4-alpha.2): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - RCT-Folly/Futures (= 2021.07.22.00) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-jsiexecutor (= 0.70.4-alpha.1) - - React-jsinspector (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) - - React-jsi (0.70.4-alpha.1): + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-jsiexecutor (= 0.70.4-alpha.2) + - React-jsinspector (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) + - React-jsi (0.70.4-alpha.2): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.07.22.00) - - React-jsi/Default (= 0.70.4-alpha.1) - - React-jsi/Default (0.70.4-alpha.1): + - React-jsi/Default (= 0.70.4-alpha.2) + - React-jsi/Default (0.70.4-alpha.2): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.07.22.00) - - React-jsiexecutor (0.70.4-alpha.1): + - React-jsiexecutor (0.70.4-alpha.2): - DoubleConversion - glog - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) - - React-jsinspector (0.70.4-alpha.1) - - React-logger (0.70.4-alpha.1): + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) + - React-jsinspector (0.70.4-alpha.2) + - React-logger (0.70.4-alpha.2): - glog - react-native-blob-util (0.16.2): - React-Core @@ -472,7 +472,7 @@ PODS: - React-Core - react-native-image-manipulator (1.0.5): - React - - react-native-image-picker (4.8.5): + - react-native-image-picker (4.10.1): - React-Core - react-native-netinfo (8.3.1): - React-Core @@ -495,72 +495,72 @@ PODS: - ReactCommon/turbomodule/core - react-native-webview (11.23.0): - React-Core - - React-perflogger (0.70.4-alpha.1) - - React-RCTActionSheet (0.70.4-alpha.1): - - React-Core/RCTActionSheetHeaders (= 0.70.4-alpha.1) - - React-RCTAnimation (0.70.4-alpha.1): + - React-perflogger (0.70.4-alpha.2) + - React-RCTActionSheet (0.70.4-alpha.2): + - React-Core/RCTActionSheetHeaders (= 0.70.4-alpha.2) + - React-RCTAnimation (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTAnimationHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTBlob (0.70.4-alpha.1): + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTAnimationHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTBlob (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTBlobHeaders (= 0.70.4-alpha.1) - - React-Core/RCTWebSocket (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-RCTNetwork (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTImage (0.70.4-alpha.1): + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTBlobHeaders (= 0.70.4-alpha.2) + - React-Core/RCTWebSocket (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-RCTNetwork (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTImage (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTImageHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-RCTNetwork (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTLinking (0.70.4-alpha.1): - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTLinkingHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTNetwork (0.70.4-alpha.1): + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTImageHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-RCTNetwork (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTLinking (0.70.4-alpha.2): + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTLinkingHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTNetwork (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTNetworkHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTSettings (0.70.4-alpha.1): + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTNetworkHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTSettings (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.70.4-alpha.1) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTSettingsHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-RCTText (0.70.4-alpha.1): - - React-Core/RCTTextHeaders (= 0.70.4-alpha.1) - - React-RCTVibration (0.70.4-alpha.1): + - RCTTypeSafety (= 0.70.4-alpha.2) + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTSettingsHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-RCTText (0.70.4-alpha.2): + - React-Core/RCTTextHeaders (= 0.70.4-alpha.2) + - React-RCTVibration (0.70.4-alpha.2): - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.70.4-alpha.1) - - React-Core/RCTVibrationHeaders (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (= 0.70.4-alpha.1) - - React-runtimeexecutor (0.70.4-alpha.1): - - React-jsi (= 0.70.4-alpha.1) - - ReactCommon/turbomodule/core (0.70.4-alpha.1): + - React-Codegen (= 0.70.4-alpha.2) + - React-Core/RCTVibrationHeaders (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (= 0.70.4-alpha.2) + - React-runtimeexecutor (0.70.4-alpha.2): + - React-jsi (= 0.70.4-alpha.2) + - ReactCommon/turbomodule/core (0.70.4-alpha.2): - DoubleConversion - glog - RCT-Folly (= 2021.07.22.00) - - React-bridging (= 0.70.4-alpha.1) - - React-callinvoker (= 0.70.4-alpha.1) - - React-Core (= 0.70.4-alpha.1) - - React-cxxreact (= 0.70.4-alpha.1) - - React-jsi (= 0.70.4-alpha.1) - - React-logger (= 0.70.4-alpha.1) - - React-perflogger (= 0.70.4-alpha.1) + - React-bridging (= 0.70.4-alpha.2) + - React-callinvoker (= 0.70.4-alpha.2) + - React-Core (= 0.70.4-alpha.2) + - React-cxxreact (= 0.70.4-alpha.2) + - React-jsi (= 0.70.4-alpha.2) + - React-logger (= 0.70.4-alpha.2) + - React-perflogger (= 0.70.4-alpha.2) - RNCAsyncStorage (1.17.10): - React-Core - RNCClipboard (1.5.1): @@ -594,7 +594,7 @@ PODS: - React-Core - RNReactNativeHapticFeedback (1.14.0): - React-Core - - RNReanimated (3.0.0-rc.3): + - RNReanimated (3.0.0-rc.6): - DoubleConversion - FBLazyVector - FBReactNativeSpec @@ -921,8 +921,8 @@ SPEC CHECKSUMS: boost: a7c83b31436843459a1961bfd74b96033dc77234 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 - FBLazyVector: 674d5b03473bdbc879c79c6ad770d17aef384b03 - FBReactNativeSpec: 3d8684f3599fef61928f5226eb41376945a5bc97 + FBLazyVector: 4c04f10d8958a7be74dc063bc0584ff223b89d4a + FBReactNativeSpec: b6ac4163edc4db460a21e2de83c8a9f3acd5c6cc Firebase: 629510f1a9ddb235f3a7c5c8ceb23ba887f0f814 FirebaseABTesting: 10cbce8db9985ae2e3847ea44e9947dd18f94e10 FirebaseAnalytics: 5506ea8b867d8423485a84b4cd612d279f7b0b8a @@ -945,13 +945,13 @@ SPEC CHECKSUMS: glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f - GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1 + GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95 hermes-engine: 3623325e0d0676a45fbc544d72c57dd79fce7446 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c + libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 - Onfido: 91935f0dcee9a6647fdb386fa87cb4af9d9a3c70 - onfido-react-native-sdk: bc72114ac430a2636cd2f02972ddf5b8b3b397c6 + Onfido: bdbc3ed45598aa106ab2ea021d94e2e28c6b5be3 + onfido-react-native-sdk: 5856e76fbfc0eb7b70b0f76fa1059830932a5c88 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6 Permission-LocationAccuracy: 76df17de5c6b8bc2eee34e61ee92cdd7a864c73d @@ -960,27 +960,27 @@ SPEC CHECKSUMS: Plaid: 6beadc0828cfd5396c5905931b9503493bbc139a PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda - RCTRequired: 9171c759923bb34cebba3142a996ff0055a26558 - RCTTypeSafety: b6e02adf80bbbb3df7ff287959df499dab9d66b0 - React: a75e21ae0e5409626c31321359785e7e3d2fa4ab - React-bridging: 99c78cffc6d53177130c27c309ffd3ca4a008add - React-callinvoker: 470766a4e2f49490da6e25923e9bd7f19a449cda - React-Codegen: 6f97b1b03090f65582ddccb0b75ea1662f34b54b - React-Core: f780c93e3b8248ca22f08149b1f4f94f85ab24c7 - React-CoreModules: 87351a3490e6bbc8bec65cd5c5c2f5a16a18e01f - React-cxxreact: 1eb773153ae7609bd7ee42c708951742d8cac3c8 - React-hermes: 0f83c702505261ab33e1938ca4a6def638a003e2 - React-jsi: 3fe2db643751becdf3511b77dcb84b68a04b52c4 - React-jsiexecutor: f7a04e9374dbfa320089064f4e6f2c9e10d0740a - React-jsinspector: 0f08037401626246e5c760871a023769b9815619 - React-logger: 0a8e62c840f534936c2cb2c96d0e6d507010e862 + RCTRequired: 329ead02b8edd20fb186d17745a9cadd5ce2922d + RCTTypeSafety: 698418021f8b47d82c058f3115c0026d1874a3ef + React: efefef133cf808a2d6edd1feedf2163d4d7a2922 + React-bridging: c12b25793db0e04c377055b4ddc9db6641be0536 + React-callinvoker: fbb9bbfe86f48efb712149d6c83ec74533e45095 + React-Codegen: 3398733e53c4106cc6fc7602c159669b5fbc1b14 + React-Core: 750c6a39b95c0b427b7624ff48cf1482f05ecf3f + React-CoreModules: 64bec7f728f87706c6512c2e8ca8cdb4f6f41ee3 + React-cxxreact: b515bc7e8b44b4c76ec7f030b00cb11c95692fa0 + React-hermes: 2c7c36834cdbd32b959333fbc17794209f18ecb0 + React-jsi: 9ae06bc7d17e61cee886e985e69f8fa3ef39334a + React-jsiexecutor: 523e742f144a346f7df32dea4fe1944d39b02473 + React-jsinspector: 7b02a02b9b9bf830102394039c80b3bf2e0200b0 + React-logger: b2c47bb0829c3c45ba3a04add9a2b4aea3f3dd4e react-native-blob-util: c3b0faecd2919db568e9d552084396f3e50b57c7 react-native-cameraroll: 2957f2bce63ae896a848fbe0d5352c1bd4d20866 react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e react-native-document-picker: f68191637788994baed5f57d12994aa32cf8bf88 react-native-flipper: dc5290261fbeeb2faec1bdc57ae6dd8d562e1de4 react-native-image-manipulator: c48f64221cfcd46e9eec53619c4c0374f3328a56 - react-native-image-picker: cd420f97f6ed6ff74fc4686d27dbcfdbd051db91 + react-native-image-picker: f2ab1215d17bcfe27b0eb6417cc236fd1f4775e7 react-native-netinfo: 1a6035d3b9780221d407c277ebfb5722ace00658 react-native-pdf: 33c622cbdf776a649929e8b9d1ce2d313347c4fa react-native-plaid-link-sdk: 77052f329310ff5a36ddda276793f40d27c02bc4 @@ -989,18 +989,18 @@ SPEC CHECKSUMS: react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 - React-perflogger: d4c9c4cfcc30a0d6cca35ddbd40a85ad4d3e4db1 - React-RCTActionSheet: fe551971745a6b04447a2c04f3d2b26fa5e3728f - React-RCTAnimation: 3a02fced1ff92012a71d4304769c2d430c7a9866 - React-RCTBlob: 9269e1c1fd754d7e8bb8c8a1d0178dc678a9f32f - React-RCTImage: 80c98b6b77063ebe851692000f54fbb9448d8e27 - React-RCTLinking: 7209ca06d58b04ad68148eeaa704f179e05f114b - React-RCTNetwork: 3ef476f0a3d43b7db36217a6f1e197517e6b750b - React-RCTSettings: 9e3dc3833f246062e91a70fed535ccb8c9f6d8c9 - React-RCTText: 89a452bfdb56e0aec4428d083626582a20d07910 - React-RCTVibration: b49dd0970d37e18c716228fce87936b578b7390c - React-runtimeexecutor: a0bd76a1162262d2945d467f6b978116e740904f - ReactCommon: cf8ef38ad293cc8a30b02f858bd16719b64a985b + React-perflogger: b231fb9993c1b5f74e32f0a3473225f9ebaf73d3 + React-RCTActionSheet: 9064b3b78118a253f2d6a63153f6dfff0b38f19f + React-RCTAnimation: d93c521d4ad6457fc8c1d9830ffb0495286ea036 + React-RCTBlob: 3121c9d4416d1d4c8d05a600f7a27da85458a277 + React-RCTImage: fac3e6e809d2e79669cc9deec9e4802dde9d73cd + React-RCTLinking: 23718d841e65fe258dd64e9cc0681d6767f89196 + React-RCTNetwork: 1bf07637ebb27f8241557e85871f7af990238130 + React-RCTSettings: 02f399b023b23a853eeda24879f4703755ffc996 + React-RCTText: c916d8da274c9823aaed9f53c007ecfa6e802764 + React-RCTVibration: eb5fb0bb3d78e31dcaeae5f127c75a7caf4b6af9 + React-runtimeexecutor: a8cee6fe3fb7994f07b735c7024a08a4fa5f8446 + ReactCommon: 1ebf2df5c764ebb52048e7a1cf42c75a6246171a RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 RNCPicker: 0b65be85fe7954fbb2062ef079e3d1cde252d888 @@ -1013,14 +1013,14 @@ SPEC CHECKSUMS: RNGestureHandler: 920eb17f5b1e15dae6e5ed1904045f8f90e0b11e RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c - RNReanimated: 6c980139eb3b043569a08b8cb3d92cdf46bd54fa + RNReanimated: 069f3aff5df4cbefaf81589c0622370073a89f1d RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9 RNSVG: 38ca962c970dbce1ca38991a5aebf26d163f9efb SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 urbanairship-react-native: 7e2e9a84c541b1d04798e51f7f390a2d5806eac0 - Yoga: affc5393470ecec3069bd7bf05d5877afffff995 + Yoga: f77f6497bccebdcbc8efb03dbf83eadfdec6d104 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: 48093a300788c218e76f70cf6d102915cd993f34 diff --git a/package-lock.json b/package-lock.json index 063c8d203796..9c3cafee7368 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.2.29-6", + "version": "1.2.36-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.2.29-6", + "version": "1.2.36-1", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -16,7 +16,7 @@ "@formatjs/intl-numberformat": "^6.2.5", "@formatjs/intl-pluralrules": "^4.0.13", "@oguzhnatly/react-native-image-manipulator": "github:Expensify/react-native-image-manipulator#c5f654fc9d0ad7cc5b89d50b34ecf8b0e3f4d050", - "@onfido/react-native-sdk": "6.0.0", + "@onfido/react-native-sdk": "7.0.1", "@pieter-pot/react-native-fast-image": "8.5.11", "@react-native-async-storage/async-storage": "^1.17.10", "@react-native-community/cameraroll": "git+https://github.com/react-native-cameraroll/react-native-cameraroll.git#3f0aed96db68e134f199171c7b06c1b4d6cb382b", @@ -38,7 +38,7 @@ "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", "dotenv": "^8.2.0", - "expensify-common": "git+https://github.com/Expensify/expensify-common.git#490d695c8ceb54bcff736785b54f06057c32fc9b", + "expensify-common": "git+https://github.com/Expensify/expensify-common.git#6bd112f1e7ebbd6679042fa04060104b68beace2", "fbjs": "^3.0.2", "file-loader": "^6.0.0", "html-entities": "^1.3.1", @@ -56,7 +56,7 @@ "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", "react-dom": "18.1.0", - "react-native": "npm:@expensify/react-native@0.70.4-alpha.1", + "react-native": "npm:@expensify/react-native@0.70.4-alpha.2", "react-native-blob-util": "^0.16.2", "react-native-collapsible": "^1.6.0", "react-native-config": "^1.4.5", @@ -74,7 +74,7 @@ "react-native-permissions": "^3.0.1", "react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#7f09b2c15ffae320d769788f75bdf8948714bb10", "react-native-plaid-link-sdk": "^7.2.0", - "react-native-reanimated": "3.0.0-rc.3", + "react-native-reanimated": "3.0.0-rc.6", "react-native-render-html": "6.3.1", "react-native-safe-area-context": "4.4.1", "react-native-screens": "3.17.0", @@ -4157,12 +4157,12 @@ } }, "node_modules/@onfido/react-native-sdk": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-6.0.0.tgz", - "integrity": "sha512-TJWeiEh0Vil37/Xm9H+uiOpiuYD2NhOhixdvaAkohTzLI3uUNiG7bph66jCUa+SpqFURQdCZMYWFwHwj2nXs2Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-7.0.1.tgz", + "integrity": "sha512-nhjByw/YyTACvkDWX2QtCzYmqkrDtSBJxYYgJjPuKvPRVIJhrny3bIm0DzAi1hWyIM2ZsKW/MSQxerGhR9FQaw==", "peerDependencies": { - "react": ">=16.8.1", - "react-native": ">=0.60.0-rc.0 <1.0.x" + "react": ">=17.0.0", + "react-native": ">=0.68.2 <1.0.x" } }, "node_modules/@pieter-pot/react-native-fast-image": { @@ -23861,8 +23861,8 @@ }, "node_modules/expensify-common": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#490d695c8ceb54bcff736785b54f06057c32fc9b", - "integrity": "sha512-jfAYoUkH8I3MRb9vBMRX4X84npyahCGMP704dDLHd78P4loY7kZoCYqiklQwOYDqVQXZQUY9hN96eAnAG7LJrw==", + "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#6bd112f1e7ebbd6679042fa04060104b68beace2", + "integrity": "sha512-9KDdGIiV9aSZloy+lWtaBrZrrEwS+Fp9T8+KoWa6E+nrS+Y9kx55vRHGIPpDeMqFk8hMfaBiYwQ7/wQmc2ijeg==", "license": "MIT", "dependencies": { "classnames": "2.3.1", @@ -35213,9 +35213,9 @@ }, "node_modules/react-native": { "name": "@expensify/react-native", - "version": "0.70.4-alpha.1", - "resolved": "https://registry.npmjs.org/@expensify/react-native/-/react-native-0.70.4-alpha.1.tgz", - "integrity": "sha512-kXVxU+ni4SnJgCAENaS8ri/CwO2lt1Yqu0y0Y9SjCgayk2ZsSXsp13ajYfICOpPfrOLRvMjQE8cAMQuuzDqovg==", + "version": "0.70.4-alpha.2", + "resolved": "https://registry.npmjs.org/@expensify/react-native/-/react-native-0.70.4-alpha.2.tgz", + "integrity": "sha512-JpB56JP1YXrhuV4TQTVGJNppWcrCcfCvkk5hZhOieArfmi7iJsoCF3urLEj88EZmAHrnf7DrQgOYki++hVwg7A==", "dependencies": { "@jest/create-cache-key-function": "^29.0.3", "@react-native-community/cli": "9.2.1", @@ -35539,9 +35539,9 @@ } }, "node_modules/react-native-reanimated": { - "version": "3.0.0-rc.3", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.0.0-rc.3.tgz", - "integrity": "sha512-kFkbazXfhq/zb3sQyLIFegLqxzPMJAd36pbz7jtOphZ1mEXDadX0ODp6eD7/PJHnLqYGHtsqSI8WMMLLN6rdjw==", + "version": "3.0.0-rc.6", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.0.0-rc.6.tgz", + "integrity": "sha512-XdJP4yESxU5kyxZtExwa4uEBF3fUJ7jQTzptMg/KBANZazKnNUW+UwgpW6MQ0xyLSqcHY/essYcGadCU6wHu3A==", "dependencies": { "@babel/plugin-transform-object-assign": "^7.16.7", "@babel/preset-typescript": "^7.16.7", @@ -45696,9 +45696,9 @@ } }, "@onfido/react-native-sdk": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-6.0.0.tgz", - "integrity": "sha512-TJWeiEh0Vil37/Xm9H+uiOpiuYD2NhOhixdvaAkohTzLI3uUNiG7bph66jCUa+SpqFURQdCZMYWFwHwj2nXs2Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-7.0.1.tgz", + "integrity": "sha512-nhjByw/YyTACvkDWX2QtCzYmqkrDtSBJxYYgJjPuKvPRVIJhrny3bIm0DzAi1hWyIM2ZsKW/MSQxerGhR9FQaw==", "requires": {} }, "@pieter-pot/react-native-fast-image": { @@ -60824,9 +60824,9 @@ } }, "expensify-common": { - "version": "git+ssh://git@github.com/Expensify/expensify-common.git#490d695c8ceb54bcff736785b54f06057c32fc9b", - "integrity": "sha512-jfAYoUkH8I3MRb9vBMRX4X84npyahCGMP704dDLHd78P4loY7kZoCYqiklQwOYDqVQXZQUY9hN96eAnAG7LJrw==", - "from": "expensify-common@git+https://github.com/Expensify/expensify-common.git#490d695c8ceb54bcff736785b54f06057c32fc9b", + "version": "git+ssh://git@github.com/Expensify/expensify-common.git#6bd112f1e7ebbd6679042fa04060104b68beace2", + "integrity": "sha512-9KDdGIiV9aSZloy+lWtaBrZrrEwS+Fp9T8+KoWa6E+nrS+Y9kx55vRHGIPpDeMqFk8hMfaBiYwQ7/wQmc2ijeg==", + "from": "expensify-common@git+https://github.com/Expensify/expensify-common.git#6bd112f1e7ebbd6679042fa04060104b68beace2", "requires": { "classnames": "2.3.1", "clipboard": "2.0.4", @@ -69510,9 +69510,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-native": { - "version": "npm:@expensify/react-native@0.70.4-alpha.1", - "resolved": "https://registry.npmjs.org/@expensify/react-native/-/react-native-0.70.4-alpha.1.tgz", - "integrity": "sha512-kXVxU+ni4SnJgCAENaS8ri/CwO2lt1Yqu0y0Y9SjCgayk2ZsSXsp13ajYfICOpPfrOLRvMjQE8cAMQuuzDqovg==", + "version": "npm:@expensify/react-native@0.70.4-alpha.2", + "resolved": "https://registry.npmjs.org/@expensify/react-native/-/react-native-0.70.4-alpha.2.tgz", + "integrity": "sha512-JpB56JP1YXrhuV4TQTVGJNppWcrCcfCvkk5hZhOieArfmi7iJsoCF3urLEj88EZmAHrnf7DrQgOYki++hVwg7A==", "requires": { "@jest/create-cache-key-function": "^29.0.3", "@react-native-community/cli": "9.2.1", @@ -69853,9 +69853,9 @@ "requires": {} }, "react-native-reanimated": { - "version": "3.0.0-rc.3", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.0.0-rc.3.tgz", - "integrity": "sha512-kFkbazXfhq/zb3sQyLIFegLqxzPMJAd36pbz7jtOphZ1mEXDadX0ODp6eD7/PJHnLqYGHtsqSI8WMMLLN6rdjw==", + "version": "3.0.0-rc.6", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.0.0-rc.6.tgz", + "integrity": "sha512-XdJP4yESxU5kyxZtExwa4uEBF3fUJ7jQTzptMg/KBANZazKnNUW+UwgpW6MQ0xyLSqcHY/essYcGadCU6wHu3A==", "requires": { "@babel/plugin-transform-object-assign": "^7.16.7", "@babel/preset-typescript": "^7.16.7", diff --git a/package.json b/package.json index 60d17b15381b..368118f97925 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.2.29-6", + "version": "1.2.36-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.", @@ -22,6 +22,7 @@ "desktop": "scripts/set-pusher-suffix.sh && node desktop/start.js", "desktop-build": "scripts/build-desktop.sh production", "desktop-build-staging": "scripts/build-desktop.sh staging", + "desktop-build-internal": "scripts/build-desktop.sh internal", "ios-build": "fastlane ios build", "android-build": "fastlane android build", "android-build-e2e": "bundle exec fastlane android build_e2e", @@ -45,7 +46,7 @@ "@formatjs/intl-numberformat": "^6.2.5", "@formatjs/intl-pluralrules": "^4.0.13", "@oguzhnatly/react-native-image-manipulator": "github:Expensify/react-native-image-manipulator#c5f654fc9d0ad7cc5b89d50b34ecf8b0e3f4d050", - "@onfido/react-native-sdk": "6.0.0", + "@onfido/react-native-sdk": "7.0.1", "@pieter-pot/react-native-fast-image": "8.5.11", "@react-native-async-storage/async-storage": "^1.17.10", "@react-native-community/cameraroll": "git+https://github.com/react-native-cameraroll/react-native-cameraroll.git#3f0aed96db68e134f199171c7b06c1b4d6cb382b", @@ -67,7 +68,7 @@ "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", "dotenv": "^8.2.0", - "expensify-common": "git+https://github.com/Expensify/expensify-common.git#490d695c8ceb54bcff736785b54f06057c32fc9b", + "expensify-common": "git+https://github.com/Expensify/expensify-common.git#6bd112f1e7ebbd6679042fa04060104b68beace2", "fbjs": "^3.0.2", "file-loader": "^6.0.0", "html-entities": "^1.3.1", @@ -85,7 +86,7 @@ "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", "react-dom": "18.1.0", - "react-native": "npm:@expensify/react-native@0.70.4-alpha.1", + "react-native": "npm:@expensify/react-native@0.70.4-alpha.2", "react-native-blob-util": "^0.16.2", "react-native-collapsible": "^1.6.0", "react-native-config": "^1.4.5", @@ -103,7 +104,7 @@ "react-native-permissions": "^3.0.1", "react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#7f09b2c15ffae320d769788f75bdf8948714bb10", "react-native-plaid-link-sdk": "^7.2.0", - "react-native-reanimated": "3.0.0-rc.3", + "react-native-reanimated": "3.0.0-rc.6", "react-native-render-html": "6.3.1", "react-native-safe-area-context": "4.4.1", "react-native-screens": "3.17.0", diff --git a/patches/react-native-modal+13.0.1.patch b/patches/react-native-modal+13.0.1.patch new file mode 100644 index 000000000000..576858f1f5f7 --- /dev/null +++ b/patches/react-native-modal+13.0.1.patch @@ -0,0 +1,46 @@ +diff --git a/node_modules/react-native-modal/dist/modal.d.ts b/node_modules/react-native-modal/dist/modal.d.ts +index b63bcfc..bd6419e 100644 +--- a/node_modules/react-native-modal/dist/modal.d.ts ++++ b/node_modules/react-native-modal/dist/modal.d.ts +@@ -161,6 +161,7 @@ export declare class ReactNativeModal extends React.Component + getDeviceHeight: () => number; + getDeviceWidth: () => number; + onBackButtonPress: () => boolean; ++ handleEscape: (e: KeyboardEvent) => void; + shouldPropagateSwipe: (evt: GestureResponderEvent, gestureState: PanResponderGestureState) => boolean; + buildPanResponder: () => void; + getAccDistancePerDirection: (gestureState: PanResponderGestureState) => number; +diff --git a/node_modules/react-native-modal/dist/modal.js b/node_modules/react-native-modal/dist/modal.js +index 80f4e75..fe028ab 100644 +--- a/node_modules/react-native-modal/dist/modal.js ++++ b/node_modules/react-native-modal/dist/modal.js +@@ -75,6 +75,13 @@ export class ReactNativeModal extends React.Component { + } + return false; + }; ++ this.handleEscape = (e) => { ++ if (e.key === 'Escape') { ++ if (this.onBackButtonPress() === true) { ++ e.stopImmediatePropagation(); ++ } ++ } ++ }; + this.shouldPropagateSwipe = (evt, gestureState) => { + return typeof this.props.propagateSwipe === 'function' + ? this.props.propagateSwipe(evt, gestureState) +@@ -454,9 +461,15 @@ export class ReactNativeModal extends React.Component { + this.open(); + } + BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPress); ++ if (Platform.OS === 'web') { ++ document?.body?.addEventListener?.('keyup', this.handleEscape, true); ++ } + } + componentWillUnmount() { + BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPress); ++ if (Platform.OS === 'web') { ++ document?.body?.removeEventListener?.('keyup', this.handleEscape, true); ++ } + if (this.didUpdateDimensionsEmitter) { + this.didUpdateDimensionsEmitter.remove(); + } diff --git a/patches/react-native-reanimated+3.0.0-rc.3.patch b/patches/react-native-reanimated+3.0.0-rc.3.patch deleted file mode 100644 index 321bcc07419f..000000000000 --- a/patches/react-native-reanimated+3.0.0-rc.3.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff --git a/node_modules/react-native-reanimated/RNReanimated.podspec b/node_modules/react-native-reanimated/RNReanimated.podspec -index 3205c93..c7f2821 100644 ---- a/node_modules/react-native-reanimated/RNReanimated.podspec -+++ b/node_modules/react-native-reanimated/RNReanimated.podspec -@@ -49,7 +49,12 @@ rescue - end - end - --reactCommonDir = File.join(nodeModulesDir, "react-native", "ReactCommon") -+ -+# From: https://github.com/software-mansion/react-native-reanimated/pull/3701/files -+pods_root = Pod::Config.instance.project_pods_root -+react_native_common_dir_absolute = File.join(nodeModulesDir, 'react-native', 'ReactCommon') -+react_native_common_dir_relative = Pathname.new(react_native_common_dir_absolute).relative_path_from(pods_root).to_s -+reactCommonDir = react_native_common_dir_relative - - if isUserApp - libInstances = %x[find ../../ -name "package.json" | grep "/react-native-reanimated/package.json" | grep -v "/.yarn/"] -@@ -111,9 +116,10 @@ Pod::Spec.new do |s| - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", - } - s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags + ' -DHERMES_ENABLE_DEBUGGER' -- s.xcconfig = { -- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/glog\" \"$(PODS_ROOT)/#{folly_prefix}Folly\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"#{reactCommonDir}\"", -- "OTHER_CFLAGS" => "$(inherited)" + " " + folly_flags + " " + fabric_flags } -+ s.xcconfig = { -+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/glog\" \"$(PODS_ROOT)/#{folly_prefix}Folly\" \"$(PODS_ROOT)/Headers/Public/React-hermes\" \"$(PODS_ROOT)/Headers/Public/hermes-engine\" \"$(PODS_ROOT)/#{reactCommonDir}\"", -+ "OTHER_CFLAGS" => "$(inherited)" + " " + folly_flags + " " + fabric_flags -+ } - - s.requires_arc = true - -diff --git a/node_modules/react-native-reanimated/ios/REAModule.mm b/node_modules/react-native-reanimated/ios/REAModule.mm -index e1cd2f4..8ba248d 100644 ---- a/node_modules/react-native-reanimated/ios/REAModule.mm -+++ b/node_modules/react-native-reanimated/ios/REAModule.mm -@@ -52,6 +52,7 @@ @implementation REAModule { - #ifdef DEBUG - SingleInstanceChecker singleInstanceChecker_; - #endif -+ bool hasListeners; - } - - RCT_EXPORT_MODULE(ReanimatedModule); -@@ -291,4 +292,19 @@ - (void)eventDispatcherWillDispatchEvent:(id)event - [_nodesManager dispatchEvent:event]; - } - -+- (void)startObserving { -+ hasListeners = YES; -+} -+ -+- (void)stopObserving { -+ hasListeners = NO; -+} -+ -+- (void)sendEventWithName:(NSString *)eventName body:(id)body -+{ -+ if (hasListeners) { -+ [super sendEventWithName:eventName body:body]; -+ } -+} -+ - @end diff --git a/scripts/build-desktop.sh b/scripts/build-desktop.sh index 3e5024fc758c..ce8737ee1b18 100755 --- a/scripts/build-desktop.sh +++ b/scripts/build-desktop.sh @@ -5,6 +5,8 @@ export ELECTRON_ENV=${1:-development} if [[ "$ELECTRON_ENV" == "staging" ]]; then ENV_FILE=".env.staging" +elif [[ "$ELECTRON_ENV" == "internal" ]]; then + ENV_FILE=".env.staging" elif [[ "$ELECTRON_ENV" == "production" ]]; then ENV_FILE=".env.production" else diff --git a/src/CONFIG.js b/src/CONFIG.js index 57260b676e79..9b7648916da0 100644 --- a/src/CONFIG.js +++ b/src/CONFIG.js @@ -1,10 +1,14 @@ -import lodashGet from 'lodash/get'; +import get from 'lodash/get'; import {Platform} from 'react-native'; import Config from 'react-native-config'; import getPlatform from './libs/getPlatform/index'; import * as Url from './libs/Url'; import CONST from './CONST'; +// react-native-config doesn't trim whitespace on iOS for some reason so we +// add a trim() call to lodashGet here to prevent headaches +const lodashGet = (config, key, defaultValue) => get(config, key, defaultValue).trim(); + // Set default values to contributor friendly values to make development work out of the box without an .env file const ENVIRONMENT = lodashGet(Config, 'ENVIRONMENT', CONST.ENVIRONMENT.DEV); const newExpensifyURL = Url.addTrailingForwardSlash(lodashGet(Config, 'NEW_EXPENSIFY_URL', 'https://new.expensify.com/')); diff --git a/src/CONST.js b/src/CONST.js index 6dc16734ba7c..01fce37adca1 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -40,6 +40,7 @@ const CONST = { }, DATE: { MOMENT_FORMAT_STRING: 'YYYY-MM-DD', + UNIX_EPOCH: '1970-01-01 00:00:00.000', }, SMS: { DOMAIN: '@expensify.sms', @@ -104,7 +105,11 @@ const CONST = { }, MAX_LENGTH: { SSN: 4, - ZIP_CODE: 5, + ZIP_CODE: 10, + }, + TYPE: { + BUSINESS: 'BUSINESS', + PERSONAL: 'PERSONAL', }, }, INCORPORATION_TYPES: { @@ -226,6 +231,7 @@ const CONST = { DEEPLINK_BASE_URL: 'new-expensify://', PDF_VIEWER_URL: '/pdf/web/viewer.html', EXPENSIFY_ICON_URL: `${CLOUDFRONT_URL}/images/favicon-2019.png`, + CONCIERGE_ICON_URL: `${CLOUDFRONT_URL}/images/icons/concierge_2022.png`, UPWORK_URL: 'https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22', GITHUB_URL: 'https://github.com/Expensify/App', TERMS_URL: `${USE_EXPENSIFY_URL}/terms`, @@ -685,6 +691,8 @@ const CONST = { }, ROLE: { ADMIN: 'admin', + AUDITOR: 'auditor', + USER: 'user', }, ROOM_PREFIX: '#', CUSTOM_UNIT_RATE_BASE_OFFSET: 100, @@ -753,6 +761,7 @@ const CONST = { EMOJI_NAME: /:[\w+-]+:/g, EMOJI_SUGGESTIONS: /:[a-zA-Z]{1,20}(\s[a-zA-Z]{0,20})?$/, + AFTER_FIRST_LINE_BREAK: /\n.*/g, }, PRONOUNS: { diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 5eac06ad1f28..60a686195dcd 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -92,7 +92,6 @@ export default { REPORT_DRAFT_COMMENT: 'reportDraftComment_', REPORT_ACTIONS_DRAFTS: 'reportActionsDrafts_', REPORT_USER_IS_TYPING: 'reportUserIsTyping_', - REPORT_IOUS: 'reportIOUs_', POLICY: 'policy_', REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_', POLICY_MEMBER_LIST: 'policyMemberList_', diff --git a/src/ROUTES.js b/src/ROUTES.js index 6ec7f4cf229c..470ea9d99eb7 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -23,6 +23,8 @@ export default { SETTINGS: 'settings', SETTINGS_PROFILE: 'settings/profile', SETTINGS_DISPLAY_NAME: 'settings/profile/display-name', + SETTINGS_TIMEZONE: 'settings/profile/timezone', + SETTINGS_TIMEZONE_SELECT: 'settings/profile/timezone/select', SETTINGS_PRONOUNS: 'settings/profile/pronouns', SETTINGS_PREFERENCES: 'settings/preferences', SETTINGS_WORKSPACES: 'settings/workspaces', diff --git a/src/SCREENS.js b/src/SCREENS.js index c3a9414d5c05..24ea27fe9689 100644 --- a/src/SCREENS.js +++ b/src/SCREENS.js @@ -6,5 +6,6 @@ export default { HOME: 'Home', LOADING: 'Loading', REPORT: 'Report', + NOT_FOUND: 'not-found', TRANSITION_FROM_OLD_DOT: 'TransitionFromOldDot', }; diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js index 66b21c7e5d13..b3006bcc6b80 100755 --- a/src/components/AttachmentModal.js +++ b/src/components/AttachmentModal.js @@ -297,7 +297,7 @@ class AttachmentModal extends PureComponent {
tags - // we replace them with line breaks and render it as text, not as html. + // we render it as text, not as html. // This is done to render emojis with line breaks between them as text. - const differByLineBreaksOnly = Str.replaceAll(props.fragment.html, '
', ' ') === props.fragment.text; - if (differByLineBreaksOnly) { - const textWithLineBreaks = Str.replaceAll(props.fragment.html, '
', '\n'); - html = textWithLineBreaks; - text = textWithLineBreaks; - } + const differByLineBreaksOnly = Str.replaceAll(html, '
', '\n') === text; // Only render HTML if we have html in the fragment - if (html !== text) { + if (!differByLineBreaksOnly) { const editedTag = props.fragment.isEdited ? '' : ''; const htmlContent = html + editedTag; return ( @@ -144,7 +139,6 @@ const ReportActionItemFragment = (props) => { return ( diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 8362d315ab54..9e2886761429 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -98,7 +98,7 @@ const ReportActionItemSingle = (props) => { /> ))} - + ) : null} {props.children} diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index 002185fba351..15bb034251eb 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -30,13 +30,7 @@ const propTypes = { report: reportPropTypes.isRequired, /** Sorted actions prepared for display */ - sortedReportActions: PropTypes.arrayOf(PropTypes.shape({ - /** Index of the action in the array */ - index: PropTypes.number, - - /** The action itself */ - action: PropTypes.shape(reportActionPropTypes), - })).isRequired, + sortedReportActions: PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes)).isRequired, /** The ID of the most recent IOU report action connected with the shown report */ mostRecentIOUReportActionID: PropTypes.string, @@ -108,7 +102,7 @@ class ReportActionsList extends React.Component { * @return {String} */ keyExtractor(item) { - return `${item.action.clientID}${item.action.reportActionID}`; + return item.reportActionID; } /** @@ -118,27 +112,26 @@ class ReportActionsList extends React.Component { * See: https://reactnative.dev/docs/optimizing-flatlist-configuration#avoid-anonymous-function-on-renderitem * * @param {Object} args - * @param {Object} args.item * @param {Number} args.index * * @returns {React.Component} */ renderItem({ - item, + item: reportAction, index, }) { // When the new indicator should not be displayed we explicitly set it to 0. The marker should never be shown above the // created action (which will have sequenceNumber of 0) so we use 0 to indicate "hidden". const shouldDisplayNewIndicator = this.props.newMarkerSequenceNumber > 0 - && item.action.sequenceNumber === this.props.newMarkerSequenceNumber - && !ReportActionsUtils.isDeletedAction(item.action); + && reportAction.sequenceNumber === this.props.newMarkerSequenceNumber + && !ReportActionsUtils.isDeletedAction(reportAction); return ( diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index a705ff2afed9..6898f74ea977 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -1,7 +1,4 @@ import React from 'react'; -import { - Keyboard, -} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; import lodashGet from 'lodash/get'; @@ -15,7 +12,6 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../../componen import {withDrawerPropTypes} from '../../../components/withDrawerState'; import * as ReportScrollManager from '../../../libs/ReportScrollManager'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import ReportActionComposeFocusManager from '../../../libs/ReportActionComposeFocusManager'; import * as ReportActionContextMenu from './ContextMenu/ReportActionContextMenu'; import PopoverReportActionContextMenu from './ContextMenu/PopoverReportActionContextMenu'; import Performance from '../../../libs/Performance'; @@ -78,7 +74,7 @@ class ReportActionsView extends React.Component { }; this.currentScrollOffset = 0; - this.sortedReportActions = ReportActionsUtils.getSortedReportActions(props.reportActions); + this.sortedReportActions = this.getSortedReportActionsForDisplay(props.reportActions); this.mostRecentIOUReportActionID = ReportActionsUtils.getMostRecentIOUReportActionID(props.reportActions); this.trackScroll = this.trackScroll.bind(this); this.toggleFloatingMessageCounter = this.toggleFloatingMessageCounter.bind(this); @@ -100,13 +96,6 @@ class ReportActionsView extends React.Component { this.setState({newMarkerSequenceNumber: 0}); }); - this.keyboardEvent = Keyboard.addListener('keyboardDidShow', () => { - if (!ReportActionComposeFocusManager.isFocused()) { - return; - } - ReportScrollManager.scrollToBottom(); - }); - if (this.getIsReportFullyVisible()) { this.openReportIfNecessary(); } @@ -141,7 +130,7 @@ class ReportActionsView extends React.Component { shouldComponentUpdate(nextProps, nextState) { if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { - this.sortedReportActions = ReportActionsUtils.getSortedReportActions(nextProps.reportActions); + this.sortedReportActions = this.getSortedReportActionsForDisplay(nextProps.reportActions); this.mostRecentIOUReportActionID = ReportActionsUtils.getMostRecentIOUReportActionID(nextProps.reportActions); return true; } @@ -258,6 +247,15 @@ class ReportActionsView extends React.Component { Report.unsubscribeFromReportChannel(this.props.report.reportID); } + /** + * @param {Object} reportActions + * @returns {Array} + */ + getSortedReportActionsForDisplay(reportActions) { + const sortedReportActions = ReportActionsUtils.getSortedReportActions(_.values(reportActions), true); + return ReportActionsUtils.filterReportActionsForDisplay(sortedReportActions); + } + /** * @returns {Boolean} */ diff --git a/src/pages/home/report/reportActionPropTypes.js b/src/pages/home/report/reportActionPropTypes.js index d752047cbb97..d3cebe8ba317 100644 --- a/src/pages/home/report/reportActionPropTypes.js +++ b/src/pages/home/report/reportActionPropTypes.js @@ -12,8 +12,8 @@ export default { /** ID of the report action */ sequenceNumber: PropTypes.number, - /** Unix timestamp */ - timestamp: PropTypes.number, + /** ISO-formatted datetime */ + created: PropTypes.string, /** report action message */ message: PropTypes.arrayOf(reportActionFragmentPropTypes), diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index f2a8ed496220..12a09d5e189a 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -38,11 +38,11 @@ const propTypes = { /* Onyx Props */ /** List of reports */ // eslint-disable-next-line react/no-unused-prop-types - reports: PropTypes.objectOf(reportPropTypes), + chatReports: PropTypes.objectOf(reportPropTypes), /** All report actions for all reports */ // eslint-disable-next-line react/no-unused-prop-types - reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), + reportActions: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.shape(reportActionPropTypes))), /** List of users' personal details */ personalDetails: PropTypes.objectOf(participantPropTypes), @@ -69,7 +69,7 @@ const propTypes = { }; const defaultProps = { - reports: {}, + chatReports: {}, reportActions: {}, personalDetails: {}, currentUserPersonalDetails: { @@ -202,25 +202,30 @@ SidebarLinks.defaultProps = defaultProps; * @param {Object} [report] * @returns {Object|undefined} */ -const reportSelector = report => report && ({ - reportID: report.reportID, - participants: report.participants, - hasDraft: report.hasDraft, - isPinned: report.isPinned, - errorFields: { - addWorkspaceRoom: report.errorFields && report.errorFields.addWorkspaceRoom, - }, - maxSequenceNumber: report.maxSequenceNumber, - lastReadSequenceNumber: report.lastReadSequenceNumber, - lastMessageText: report.lastMessageText, - lastMessageTimestamp: report.lastMessageTimestamp, - iouReportID: report.iouReportID, - hasOutstandingIOU: report.hasOutstandingIOU, - statusNum: report.statusNum, - stateNum: report.stateNum, - chatType: report.chatType, - policyID: report.policyID, -}); +const chatReportSelector = (report) => { + if (ReportUtils.isIOUReport(report)) { + return null; + } + return report && ({ + reportID: report.reportID, + participants: report.participants, + hasDraft: report.hasDraft, + isPinned: report.isPinned, + errorFields: { + addWorkspaceRoom: report.errorFields && report.errorFields.addWorkspaceRoom, + }, + maxSequenceNumber: report.maxSequenceNumber, + lastReadSequenceNumber: report.lastReadSequenceNumber, + lastMessageText: report.lastMessageText, + lastActionCreated: report.lastActionCreated, + iouReportID: report.iouReportID, + hasOutstandingIOU: report.hasOutstandingIOU, + statusNum: report.statusNum, + stateNum: report.stateNum, + chatType: report.chatType, + policyID: report.policyID, + }); +}; /** * @param {Object} [personalDetails] @@ -265,9 +270,9 @@ export default compose( // for that key, then there would be no re-render and the options wouldn't reflect the new data because SidebarUtils.getOrderedReportIDs() wouldn't be triggered. // This could be changed if each OptionRowLHN used withOnyx() to connect to the Onyx keys, but if you had 10,000 reports // with 10,000 withOnyx() connections, it would have unknown performance implications. - reports: { + chatReports: { key: ONYXKEYS.COLLECTION.REPORT, - selector: reportSelector, + selector: chatReportSelector, }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index 9f200ec9356d..14ca7bc531e5 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -1,145 +1,42 @@ -import lodashGet from 'lodash/get'; -import _ from 'underscore'; import React, {Component} from 'react'; import {View} from 'react-native'; -import PropTypes from 'prop-types'; import styles from '../../../../styles/styles'; import SidebarLinks from '../SidebarLinks'; -import PopoverMenu from '../../../../components/PopoverMenu'; -import FloatingActionButton from '../../../../components/FloatingActionButton'; import ScreenWrapper from '../../../../components/ScreenWrapper'; -import compose from '../../../../libs/compose'; import Navigation from '../../../../libs/Navigation/Navigation'; import ROUTES from '../../../../ROUTES'; import Timing from '../../../../libs/actions/Timing'; import CONST from '../../../../CONST'; -import * as Expensicons from '../../../../components/Icon/Expensicons'; -import Permissions from '../../../../libs/Permissions'; -import * as Policy from '../../../../libs/actions/Policy'; import Performance from '../../../../libs/Performance'; -import * as Welcome from '../../../../libs/actions/Welcome'; -import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; import withDrawerState from '../../../../components/withDrawerState'; -import withNavigationFocus from '../../../../components/withNavigationFocus'; import KeyboardShortcutsModal from '../../../../components/KeyboardShortcutsModal'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions'; +import compose from '../../../../libs/compose'; +import sidebarPropTypes from './sidebarPropTypes'; const propTypes = { - - /** Callback function when the menu is shown */ - onShowCreateMenu: PropTypes.func, - - /** Callback function before the menu is hidden */ - onHideCreateMenu: PropTypes.func, - - /** reportID in the current navigation state */ - reportIDFromRoute: PropTypes.string, - ...sidebarPropTypes, -}; -const defaultProps = { - onHideCreateMenu: () => {}, - onShowCreateMenu: () => {}, - ...sidebarDefaultProps, + ...windowDimensionsPropTypes, }; class BaseSidebarScreen extends Component { constructor(props) { super(props); - this.hideCreateMenu = this.hideCreateMenu.bind(this); this.startTimer = this.startTimer.bind(this); - this.showCreateMenu = this.showCreateMenu.bind(this); - - this.state = { - isCreateMenuActive: false, - }; + this.navigateToSettings = this.navigateToSettings.bind(this); } componentDidMount() { Performance.markStart(CONST.TIMING.SIDEBAR_LOADED); Timing.start(CONST.TIMING.SIDEBAR_LOADED, true); - - const routes = lodashGet(this.props.navigation.getState(), 'routes', []); - Welcome.show({routes, showCreateMenu: this.showCreateMenu}); - } - - componentDidUpdate(prevProps) { - if (!this.didScreenBecomeInactive(prevProps)) { - return; - } - - // Hide menu manually when other pages are opened using shortcut key - this.hideCreateMenu(); } /** - * Check if LHN status changed from active to inactive. - * Used to close already opened FAB menu when open any other pages (i.e. Press Command + K on web). - * - * @param {Object} prevProps - * @return {Boolean} + * Method called when avatar is clicked */ - didScreenBecomeInactive(prevProps) { - // When the Drawer gets closed and ReportScreen is shown - if (!this.props.isDrawerOpen && prevProps.isDrawerOpen) { - return true; - } - - // When any other page is opened over LHN - if (!this.props.isFocused && prevProps.isFocused) { - return true; - } - - return false; - } - - /** - * Check if LHN is inactive. - * Used to prevent FAB menu showing after opening any other pages. - * - * @return {Boolean} - */ - isScreenInactive() { - // When drawer is closed and Report page is open - if (this.props.isSmallScreenWidth && !this.props.isDrawerOpen) { - return true; - } - - // When any other page is open - if (!this.props.isFocused) { - return true; - } - - return false; - } - - /** - * Method called when we click the floating action button - */ - showCreateMenu() { - if (this.isScreenInactive()) { - // Prevent showing menu when click FAB icon quickly after opening other pages - return; - } - this.setState({ - isCreateMenuActive: true, - }); - this.props.onShowCreateMenu(); - } - - /** - * Method called either when: - * Pressing the floating action button to open the CreateMenu modal - * Selecting an item on CreateMenu or closing it by clicking outside of the modal component - */ - hideCreateMenu() { - if (!this.state.isCreateMenuActive) { - return; - } - this.props.onHideCreateMenu(); - this.setState({ - isCreateMenuActive: false, - }); + navigateToSettings() { + Navigation.navigate(ROUTES.SETTINGS); } /** @@ -151,8 +48,6 @@ class BaseSidebarScreen extends Component { } render() { - // Workspaces are policies with type === 'free' - const workspaces = _.filter(this.props.allPolicies, policy => policy && policy.type === CONST.POLICY.TYPE.FREE); return ( - - Navigation.navigate(ROUTES.NEW_CHAT), - }, - { - icon: Expensicons.Users, - text: this.props.translate('sidebarScreen.newGroup'), - onSelected: () => Navigation.navigate(ROUTES.NEW_GROUP), - }, - ...(Permissions.canUsePolicyRooms(this.props.betas) && workspaces.length ? [ - { - icon: Expensicons.Hashtag, - text: this.props.translate('sidebarScreen.newRoom'), - onSelected: () => Navigation.navigate(ROUTES.WORKSPACE_NEW_ROOM), - }, - ] : []), - ...(Permissions.canUseIOUSend(this.props.betas) ? [ - { - icon: Expensicons.Send, - text: this.props.translate('iou.sendMoney'), - onSelected: () => Navigation.navigate(ROUTES.IOU_SEND), - }, - ] : []), - ...(Permissions.canUseIOU(this.props.betas) ? [ - { - icon: Expensicons.MoneyCircle, - text: this.props.translate('iou.requestMoney'), - onSelected: () => Navigation.navigate(ROUTES.IOU_REQUEST), - }, - ] : []), - ...(Permissions.canUseIOU(this.props.betas) ? [ - { - icon: Expensicons.Receipt, - text: this.props.translate('iou.splitBill'), - onSelected: () => Navigation.navigate(ROUTES.IOU_BILL), - }, - ] : []), - ...(!Policy.hasActiveFreePolicy(this.props.allPolicies) ? [ - { - icon: Expensicons.NewWorkspace, - iconWidth: 46, - iconHeight: 40, - text: this.props.translate('workspace.new.newWorkspace'), - description: this.props.translate('workspace.new.getTheExpensifyCardAndMore'), - onSelected: () => Policy.createWorkspace(), - }, - ] : []), - ]} - /> + {this.props.children} )} @@ -242,9 +75,8 @@ class BaseSidebarScreen extends Component { } BaseSidebarScreen.propTypes = propTypes; -BaseSidebarScreen.defaultProps = defaultProps; export default compose( + withWindowDimensions, withDrawerState, - withNavigationFocus, )(BaseSidebarScreen); diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js new file mode 100644 index 000000000000..465902df23d0 --- /dev/null +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js @@ -0,0 +1,252 @@ +import React from 'react'; +import _ from 'underscore'; +import {withOnyx} from 'react-native-onyx'; +import PropTypes from 'prop-types'; +import lodashGet from 'lodash/get'; +import {View} from 'react-native'; +import styles from '../../../../styles/styles'; +import * as Expensicons from '../../../../components/Icon/Expensicons'; +import Navigation from '../../../../libs/Navigation/Navigation'; +import ROUTES from '../../../../ROUTES'; +import Permissions from '../../../../libs/Permissions'; +import * as Policy from '../../../../libs/actions/Policy'; +import PopoverMenu from '../../../../components/PopoverMenu'; +import CONST from '../../../../CONST'; +import FloatingActionButton from '../../../../components/FloatingActionButton'; +import compose from '../../../../libs/compose'; +import withLocalize, {withLocalizePropTypes} from '../../../../components/withLocalize'; +import withWindowDimensions from '../../../../components/withWindowDimensions'; +import ONYXKEYS from '../../../../ONYXKEYS'; +import withNavigation from '../../../../components/withNavigation'; +import * as Welcome from '../../../../libs/actions/Welcome'; +import withNavigationFocus from '../../../../components/withNavigationFocus'; +import withDrawerState from '../../../../components/withDrawerState'; + +/** + * @param {Object} [policy] + * @returns {Object|undefined} + */ +const policySelector = policy => policy && ({ + type: policy.type, + role: policy.role, +}); + +const propTypes = { + /* Callback function when the menu is shown */ + onShowCreateMenu: PropTypes.func, + + /* Callback function before the menu is hidden */ + onHideCreateMenu: PropTypes.func, + + /** The list of policies the user has access to. */ + allPolicies: PropTypes.shape({ + /** The policy name */ + name: PropTypes.string, + }), + + /* Beta features list */ + betas: PropTypes.arrayOf(PropTypes.string), + + ...withLocalizePropTypes, +}; +const defaultProps = { + onHideCreateMenu: () => {}, + onShowCreateMenu: () => {}, + allPolicies: {}, + betas: [], +}; + +/** + * Responsible for rendering the {@link PopoverMenu}, and the accompanying + * FAB that can open or close the menu. + */ +class FloatingActionButtonAndPopover extends React.Component { + constructor(props) { + super(props); + + this.showCreateMenu = this.showCreateMenu.bind(this); + this.hideCreateMenu = this.hideCreateMenu.bind(this); + + this.state = { + isCreateMenuActive: false, + }; + } + + componentDidMount() { + const routes = lodashGet(this.props.navigation.getState(), 'routes', []); + Welcome.show({routes, showCreateMenu: this.showCreateMenu}); + } + + componentDidUpdate(prevProps) { + if (!this.didScreenBecomeInactive(prevProps)) { + return; + } + + // Hide menu manually when other pages are opened using shortcut key + this.hideCreateMenu(); + } + + /** + * Check if LHN status changed from active to inactive. + * Used to close already opened FAB menu when open any other pages (i.e. Press Command + K on web). + * + * @param {Object} prevProps + * @return {Boolean} + */ + didScreenBecomeInactive(prevProps) { + // When the Drawer gets closed and ReportScreen is shown + if (!this.props.isDrawerOpen && prevProps.isDrawerOpen) { + return true; + } + + // When any other page is opened over LHN + if (!this.props.isFocused && prevProps.isFocused) { + return true; + } + + return false; + } + + /** + * Check if LHN is inactive. + * Used to prevent FAB menu showing after opening any other pages. + * + * @return {Boolean} + */ + isScreenInactive() { + // When drawer is closed and Report page is open + if (this.props.isSmallScreenWidth && !this.props.isDrawerOpen) { + return true; + } + + // When any other page is open + if (!this.props.isFocused) { + return true; + } + + return false; + } + + /** + * Method called when we click the floating action button + */ + showCreateMenu() { + if (this.isScreenInactive()) { + // Prevent showing menu when click FAB icon quickly after opening other pages + return; + } + this.setState({ + isCreateMenuActive: true, + }); + this.props.onShowCreateMenu(); + } + + /** + * Method called either when: + * - Pressing the floating action button to open the CreateMenu modal + * - Selecting an item on CreateMenu or closing it by clicking outside of the modal component + */ + hideCreateMenu() { + if (this.isScreenInactive()) { + // Prevent showing menu when click FAB icon quickly after opening other pages + return; + } + this.props.onHideCreateMenu(); + this.setState({ + isCreateMenuActive: false, + }); + } + + render() { + // Workspaces are policies with type === 'free' + const workspaces = _.filter(this.props.allPolicies, policy => policy && policy.type === CONST.POLICY.TYPE.FREE); + + return ( + + Navigation.navigate(ROUTES.NEW_CHAT), + }, + { + icon: Expensicons.Users, + text: this.props.translate('sidebarScreen.newGroup'), + onSelected: () => Navigation.navigate(ROUTES.NEW_GROUP), + }, + ...(Permissions.canUsePolicyRooms(this.props.betas) && workspaces.length ? [ + { + icon: Expensicons.Hashtag, + text: this.props.translate('sidebarScreen.newRoom'), + onSelected: () => Navigation.navigate(ROUTES.WORKSPACE_NEW_ROOM), + }, + ] : []), + ...(Permissions.canUseIOUSend(this.props.betas) ? [ + { + icon: Expensicons.Send, + text: this.props.translate('iou.sendMoney'), + onSelected: () => Navigation.navigate(ROUTES.IOU_SEND), + }, + ] : []), + ...(Permissions.canUseIOU(this.props.betas) ? [ + { + icon: Expensicons.MoneyCircle, + text: this.props.translate('iou.requestMoney'), + onSelected: () => Navigation.navigate(ROUTES.IOU_REQUEST), + }, + ] : []), + ...(Permissions.canUseIOU(this.props.betas) ? [ + { + icon: Expensicons.Receipt, + text: this.props.translate('iou.splitBill'), + onSelected: () => Navigation.navigate(ROUTES.IOU_BILL), + }, + ] : []), + ...(!Policy.hasActiveFreePolicy(this.props.allPolicies) ? [ + { + icon: Expensicons.NewWorkspace, + iconWidth: 46, + iconHeight: 40, + text: this.props.translate('workspace.new.newWorkspace'), + description: this.props.translate('workspace.new.getTheExpensifyCardAndMore'), + onSelected: () => Policy.createWorkspace(), + }, + ] : []), + ]} + /> + + + ); + } +} + +FloatingActionButtonAndPopover.propTypes = propTypes; +FloatingActionButtonAndPopover.defaultProps = defaultProps; + +export default compose( + withLocalize, + withNavigation, + withNavigationFocus, + withDrawerState, + withWindowDimensions, + withOnyx({ + allPolicies: { + key: ONYXKEYS.COLLECTION.POLICY, + selector: policySelector, + }, + betas: { + key: ONYXKEYS.BETAS, + }, + }), +)(FloatingActionButtonAndPopover); diff --git a/src/pages/home/sidebar/SidebarScreen/PopoverModal.js b/src/pages/home/sidebar/SidebarScreen/PopoverModal.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/src/pages/home/sidebar/SidebarScreen/index.js b/src/pages/home/sidebar/SidebarScreen/index.js index 584bcc49f8e4..552b0e2dc180 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.js +++ b/src/pages/home/sidebar/SidebarScreen/index.js @@ -1,52 +1,40 @@ -import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import compose from '../../../../libs/compose'; -import withWindowDimensions from '../../../../components/withWindowDimensions'; -import withLocalize from '../../../../components/withLocalize'; -import ONYXKEYS from '../../../../ONYXKEYS'; -import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; +import React, {useRef} from 'react'; +import sidebarPropTypes from './sidebarPropTypes'; import BaseSidebarScreen from './BaseSidebarScreen'; +import FloatingActionButtonAndPopover from './FloatingActionButtonAndPopover'; const SidebarScreen = (props) => { - let baseSidebarScreen = null; + const popoverModal = useRef(null); /** * Method create event listener */ const createDragoverListener = () => { - document.addEventListener('dragover', baseSidebarScreen.hideCreateMenu); + document.addEventListener('dragover', popoverModal.current.hideCreateMenu); }; /** * Method remove event listener. */ const removeDragoverListener = () => { - document.removeEventListener('dragover', baseSidebarScreen.hideCreateMenu); + document.removeEventListener('dragover', popoverModal.current.hideCreateMenu); }; + return ( baseSidebarScreen = el} - onShowCreateMenu={createDragoverListener} - onHideCreateMenu={removeDragoverListener} // eslint-disable-next-line react/jsx-props-no-spreading {...props} - /> + > + + ); }; SidebarScreen.propTypes = sidebarPropTypes; -SidebarScreen.defaultProps = sidebarDefaultProps; SidebarScreen.displayName = 'SidebarScreen'; -export default compose( - withLocalize, - withWindowDimensions, - withOnyx({ - allPolicies: { - key: ONYXKEYS.COLLECTION.POLICY, - }, - betas: { - key: ONYXKEYS.BETAS, - }, - }), -)(SidebarScreen); +export default SidebarScreen; diff --git a/src/pages/home/sidebar/SidebarScreen/index.native.js b/src/pages/home/sidebar/SidebarScreen/index.native.js index e2cb2838efe8..145c841b1d2f 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.native.js +++ b/src/pages/home/sidebar/SidebarScreen/index.native.js @@ -1,28 +1,18 @@ import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import compose from '../../../../libs/compose'; -import withWindowDimensions from '../../../../components/withWindowDimensions'; -import withLocalize from '../../../../components/withLocalize'; -import ONYXKEYS from '../../../../ONYXKEYS'; -import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; +import sidebarPropTypes from './sidebarPropTypes'; import BaseSidebarScreen from './BaseSidebarScreen'; +import FloatingActionButtonAndPopover from './FloatingActionButtonAndPopover'; -// eslint-disable-next-line react/jsx-props-no-spreading -const SidebarScreen = props => ; +const SidebarScreen = props => ( + + + +); SidebarScreen.propTypes = sidebarPropTypes; -SidebarScreen.defaultProps = sidebarDefaultProps; SidebarScreen.displayName = 'SidebarScreen'; -export default compose( - withLocalize, - withWindowDimensions, - withOnyx({ - allPolicies: { - key: ONYXKEYS.COLLECTION.POLICY, - }, - betas: { - key: ONYXKEYS.BETAS, - }, - }), -)(SidebarScreen); +export default SidebarScreen; diff --git a/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js b/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js index 996bba9d676b..3affaa2d00be 100644 --- a/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js +++ b/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js @@ -1,26 +1,8 @@ import PropTypes from 'prop-types'; -import {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions'; -import {withLocalizePropTypes} from '../../../../components/withLocalize'; const sidebarPropTypes = { - /** The list of policies the user has access to. */ - allPolicies: PropTypes.shape({ - /** The policy name */ - name: PropTypes.string, - }), - - /* Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), - - ...windowDimensionsPropTypes, - - ...withLocalizePropTypes, + /** reportID in the current navigation state */ + reportIDFromRoute: PropTypes.string, }; - -const sidebarDefaultProps = { - allPolicies: {}, - betas: [], -}; - -export {sidebarPropTypes, sidebarDefaultProps}; +export default sidebarPropTypes; diff --git a/src/pages/iou/IOUDetailsModal.js b/src/pages/iou/IOUDetailsModal.js index 17369e94891e..d90b83f4b8b5 100644 --- a/src/pages/iou/IOUDetailsModal.js +++ b/src/pages/iou/IOUDetailsModal.js @@ -167,7 +167,7 @@ export default compose( key: ONYXKEYS.IOU, }, iouReport: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${route.params.iouReportID}`, + key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.iouReportID}`, }, session: { key: ONYXKEYS.SESSION, diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index cb6905b3bc1f..67b5ab23f2a7 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -350,6 +350,47 @@ class IOUModal extends Component { this.state.comment); } + renderHeader() { + return ( + + + {this.state.currentStepIndex > 0 + && ( + + + + + + )} +
+ + + Navigation.dismissModal()} + style={[styles.touchableButtonImage, styles.mr0]} + accessibilityRole="button" + accessibilityLabel={this.props.translate('common.close')} + > + + + + + + + ); + } + render() { const currentStep = this.steps[this.state.currentStepIndex]; const reportID = lodashGet(this.props, 'route.params.reportID', ''); @@ -357,42 +398,6 @@ class IOUModal extends Component { {({didScreenTransitionEnd}) => ( <> - - - {this.state.currentStepIndex > 0 - && ( - - - - - - )} -
- - - Navigation.dismissModal()} - style={[styles.touchableButtonImage, styles.mr0]} - accessibilityRole="button" - accessibilityLabel={this.props.translate('common.close')} - > - - - - - - {!didScreenTransitionEnd && } {didScreenTransitionEnd && ( @@ -400,8 +405,9 @@ class IOUModal extends Component { {currentStep === Steps.IOUAmount && ( + {this.renderHeader()} { this.setState({amount}); @@ -420,6 +426,7 @@ class IOUModal extends Component { style={[styles.flex1]} direction={this.getDirection()} > + {this.renderHeader()} + {this.renderHeader()} - + {canUseTouchScreen() ? ( prev + data.length, 0), + indexOffset, }); + indexOffset += this.state.personalDetails.length; if (this.state.userToInvite && !OptionsListUtils.isCurrentUser(this.state.userToInvite)) { sections.push({ undefined, data: [this.state.userToInvite], shouldShow: true, - indexOffset: _.reduce(sections, (prev, {data}) => prev + data.length, 0), + indexOffset, }); } diff --git a/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js b/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js index f1a1f2a3f5c5..76a694b664ae 100755 --- a/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js +++ b/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js @@ -87,12 +87,15 @@ class IOUParticipantsSplit extends Component { */ getSections(maxParticipantsReached) { const sections = []; + let indexOffset = 0; + sections.push({ title: undefined, data: this.props.participants, shouldShow: true, - indexOffset: 0, + indexOffset, }); + indexOffset += this.props.participants.length; if (maxParticipantsReached) { return sections; @@ -102,28 +105,24 @@ class IOUParticipantsSplit extends Component { title: this.props.translate('common.recents'), data: this.state.recentReports, shouldShow: !_.isEmpty(this.state.recentReports), - - // takes the sum off the length of all data - // (this.state.selectedOptions) in previous sections - indexOffset: _.reduce(sections, (prev, {data}) => prev + data.length, 0), + indexOffset, }); + indexOffset += this.state.recentReports.length; sections.push({ title: this.props.translate('common.contacts'), data: this.state.personalDetails, shouldShow: !_.isEmpty(this.state.personalDetails), - - // takes the sum off the length of all data - // (this.state.selectedOptions, this.state.recentReports) in previous sections - indexOffset: _.reduce(sections, (prev, {data}) => prev + data.length, 0), + indexOffset, }); + indexOffset += this.state.personalDetails.length; if (this.state.userToInvite && !OptionsListUtils.isCurrentUser(this.state.userToInvite)) { sections.push(({ undefined, data: [this.state.userToInvite], shouldShow: true, - indexOffset: _.reduce(sections, (prev, {data}) => prev + data.length, 0), + indexOffset, })); } diff --git a/src/pages/reportPropTypes.js b/src/pages/reportPropTypes.js index 5c26bb2905a1..bc233b305676 100644 --- a/src/pages/reportPropTypes.js +++ b/src/pages/reportPropTypes.js @@ -32,7 +32,7 @@ export default PropTypes.shape({ lastMessageText: PropTypes.string, /** The time of the last message on the report */ - lastMessageTimestamp: PropTypes.number, + lastActionCreated: PropTypes.string, /** The sequence number of the last action read by the user */ lastReadSequenceNumber: PropTypes.number, diff --git a/src/pages/settings/AddSecondaryLoginPage.js b/src/pages/settings/AddSecondaryLoginPage.js index 01e60852a578..892a75153d55 100755 --- a/src/pages/settings/AddSecondaryLoginPage.js +++ b/src/pages/settings/AddSecondaryLoginPage.js @@ -107,7 +107,8 @@ class AddSecondaryLoginPage extends Component { onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PROFILE)} onCloseButtonPress={() => Navigation.dismissModal()} /> - + {/* We use keyboardShouldPersistTaps="handled" to prevent the keyboard from being hidden when switching focus on input fields */} + {this.props.translate(this.formType === CONST.LOGIN_TYPE.PHONE ? 'addSecondaryLoginPage.enterPreferredPhoneNumberToSendValidationLink' diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 994ed5e099c7..c2bf6b384b87 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; +import {withNetwork} from '../../components/OnyxProvider'; import styles from '../../styles/styles'; import Text from '../../components/Text'; import * as Session from '../../libs/actions/Session'; @@ -28,6 +29,7 @@ import cardPropTypes from '../../components/cardPropTypes'; import * as Wallet from '../../libs/actions/Wallet'; import walletTermsPropTypes from '../EnablePayments/walletTermsPropTypes'; import * as PolicyUtils from '../../libs/PolicyUtils'; +import ConfirmModal from '../../components/ConfirmModal'; const propTypes = { /* Onyx Props */ @@ -96,6 +98,12 @@ class InitialSettingsPage extends React.Component { this.getWalletBalance = this.getWalletBalance.bind(this); this.getDefaultMenuItems = this.getDefaultMenuItems.bind(this); this.getMenuItem = this.getMenuItem.bind(this); + this.toggleSignoutConfirmModal = this.toggleSignoutConfirmModal.bind(this); + this.signout = this.signOut.bind(this); + + this.state = { + shouldShowSignoutConfirmModal: false, + }; } componentDidMount() { @@ -171,7 +179,7 @@ class InitialSettingsPage extends React.Component { { translationKey: 'initialSettingsPage.signOut', icon: Expensicons.Exit, - action: Session.signOutAndRedirectToSignIn, + action: () => { this.signout(false); }, }, ]); } @@ -199,6 +207,20 @@ class InitialSettingsPage extends React.Component { ); } + toggleSignoutConfirmModal(value) { + this.setState({shouldShowSignoutConfirmModal: value}); + } + + signOut(shouldForceSignout = false) { + if (!this.props.network.isOffline || shouldForceSignout) { + Session.signOutAndRedirectToSignIn(); + return; + } + + // When offline, warn the user that any actions they took while offline will be lost if they sign out + this.toggleSignoutConfirmModal(true); + } + openProfileSettings() { Navigation.navigate(ROUTES.SETTINGS_PROFILE); } @@ -247,6 +269,17 @@ class InitialSettingsPage extends React.Component { )} {_.map(this.getDefaultMenuItems(), (item, index) => this.getMenuItem(item, index))} + + this.signOut(true)} + onCancel={() => this.toggleSignoutConfirmModal(false)} + /> @@ -286,4 +319,5 @@ export default compose( key: ONYXKEYS.WALLET_TERMS, }, }), + withNetwork(), )(InitialSettingsPage); diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index 11986e260909..6de7b44bf259 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -164,6 +164,7 @@ class DebitCardPage extends Component { label={this.props.translate('common.zip')} keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD} maxLength={CONST.BANK_ACCOUNT.MAX_LENGTH.ZIP_CODE} + hint={this.props.translate('common.zipCodeExample')} /> diff --git a/src/pages/settings/Payments/PaymentMethodList.js b/src/pages/settings/Payments/PaymentMethodList.js index 7691b02e9f43..b1be756e2a17 100644 --- a/src/pages/settings/Payments/PaymentMethodList.js +++ b/src/pages/settings/Payments/PaymentMethodList.js @@ -60,6 +60,9 @@ const propTypes = { /** ID of selected payment method */ selectedMethodID: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + /** Content for the FlatList header component */ + listHeaderComponent: PropTypes.func, + ...withLocalizePropTypes, }; @@ -76,6 +79,7 @@ const defaultProps = { actionPaymentMethodType: '', activePaymentMethodID: '', selectedMethodID: '', + listHeaderComponent: null, }; class PaymentMethodList extends Component { @@ -215,6 +219,7 @@ class PaymentMethodList extends Component { renderItem={this.renderItem} keyExtractor={item => item.key} ListEmptyComponent={this.renderListEmptyComponent()} + ListHeaderComponent={this.props.listHeaderComponent} /> { this.props.shouldShowAddPaymentMethodButton diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index f9c36bd873fe..b308898e4662 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -23,7 +23,6 @@ import withWindowDimensions from '../../../../components/withWindowDimensions'; import CurrentWalletBalance from '../../../../components/CurrentWalletBalance'; import ONYXKEYS from '../../../../ONYXKEYS'; import Permissions from '../../../../libs/Permissions'; -import ConfirmPopover from '../../../../components/ConfirmPopover'; import AddPaymentMethodMenu from '../../../../components/AddPaymentMethodMenu'; import CONST from '../../../../CONST'; import * as Expensicons from '../../../../components/Icon/Expensicons'; @@ -32,6 +31,7 @@ import {propTypes, defaultProps} from './paymentsPagePropTypes'; import {withNetwork} from '../../../../components/OnyxProvider'; import * as PaymentUtils from '../../../../libs/PaymentUtils'; import OfflineWithFeedback from '../../../../components/OfflineWithFeedback'; +import ConfirmContent from '../../../../components/ConfirmContent'; class BasePaymentsPage extends React.Component { constructor(props) { @@ -41,7 +41,6 @@ class BasePaymentsPage extends React.Component { shouldShowAddPaymentMenu: false, shouldShowDefaultDeleteMenu: false, shouldShowPasswordPrompt: false, - shouldShowConfirmPopover: false, isSelectedPaymentMethodDefault: false, selectedPaymentMethod: {}, formattedSelectedPaymentMethod: { @@ -52,6 +51,7 @@ class BasePaymentsPage extends React.Component { anchorPositionRight: 0, addPaymentMethodButton: null, methodID: null, + showConfirmDeleteContent: false, }; this.paymentMethodPressed = this.paymentMethodPressed.bind(this); @@ -63,6 +63,7 @@ class BasePaymentsPage extends React.Component { this.hidePasswordPrompt = this.hidePasswordPrompt.bind(this); this.navigateToTransferBalancePage = this.navigateToTransferBalancePage.bind(this); this.setMenuPosition = this.setMenuPosition.bind(this); + this.listHeaderComponent = this.listHeaderComponent.bind(this); } componentDidMount() { @@ -215,6 +216,11 @@ class BasePaymentsPage extends React.Component { */ hideDefaultDeleteMenu() { this.setState({shouldShowDefaultDeleteMenu: false}); + InteractionManager.runAfterInteractions(() => { + this.setState({ + showConfirmDeleteContent: false, + }); + }); } hidePasswordPrompt() { @@ -255,9 +261,57 @@ class BasePaymentsPage extends React.Component { Navigation.navigate(ROUTES.SETTINGS_PAYMENTS_TRANSFER_BALANCE); } + listHeaderComponent() { + return ( + <> + {Permissions.canUseWallet(this.props.betas) && ( + <> + + + + + + {this.props.userWallet.currentBalance > 0 && ( + + {triggerKYCFlow => ( + + )} + + )} + + )} + + {this.props.translate('paymentsPage.paymentMethodsTitle')} + + + ); + } + render() { const isPayPalMeSelected = this.state.formattedSelectedPaymentMethod.type === CONST.PAYMENT_METHODS.PAYPAL; - const shouldShowMakeDefaultButton = !this.state.isSelectedPaymentMethodDefault && Permissions.canUseWallet(this.props.betas) && !isPayPalMeSelected; + const shouldShowMakeDefaultButton = !this.state.isSelectedPaymentMethodDefault + && Permissions.canUseWallet(this.props.betas) + && !isPayPalMeSelected + && !(this.state.formattedSelectedPaymentMethod.type === CONST.PAYMENT_METHODS.BANK_ACCOUNT && this.state.selectedPaymentMethod.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS); // Determines whether or not the modal popup is mounted from the bottom of the screen instead of the side mount on Web or Desktop screens const isPopoverBottomMount = this.state.anchorPositionTop === 0 || this.props.isSmallScreenWidth; @@ -270,44 +324,6 @@ class BasePaymentsPage extends React.Component { onCloseButtonPress={() => Navigation.dismissModal(true)} /> - {Permissions.canUseWallet(this.props.betas) && ( - <> - - - - - - {this.props.userWallet.currentBalance > 0 && ( - - {triggerKYCFlow => ( - - )} - - )} - - )} - - {this.props.translate('paymentsPage.paymentMethodsTitle')} - @@ -345,13 +362,14 @@ class BasePaymentsPage extends React.Component { right: this.state.anchorPositionRight, }} > - - {isPopoverBottomMount && ( + {!this.state.showConfirmDeleteContent ? ( + + {isPopoverBottomMount && ( - )} - {shouldShowMakeDefaultButton && ( + )} + {shouldShowMakeDefaultButton && ( { this.setState({ @@ -384,31 +402,66 @@ class BasePaymentsPage extends React.Component { {this.props.translate('paymentsPage.setDefaultConfirmation')} - )} - { + )} + { + this.setState({ + showConfirmDeleteContent: true, + }); + }} + style={[ + styles.button, + styles.buttonDanger, + shouldShowMakeDefaultButton && styles.mt4, + styles.alignSelfCenter, + styles.w100, + ]} + > + + {this.props.translate('common.delete')} + + + + ) : ( + { this.setState({ shouldShowDefaultDeleteMenu: false, }); InteractionManager.runAfterInteractions(() => { this.setState({ - shouldShowConfirmPopover: true, + showConfirmDeleteContent: false, }); }); + this.deletePaymentMethod(); }} - style={[ - styles.button, - styles.buttonDanger, - shouldShowMakeDefaultButton && styles.mt4, - styles.alignSelfCenter, - styles.w100, - ]} - > - - {this.props.translate('common.delete')} - - - + onCancel={() => { + this.setState({ + shouldShowDefaultDeleteMenu: false, + }); + InteractionManager.runAfterInteractions( + () => { + this.setState( + { + showConfirmDeleteContent: false, + }, + ); + }, + ); + }} + contentStyles={!this.props.isSmallScreenWidth ? [styles.sidebarPopover] : undefined} + title={this.props.translate('paymentsPage.deleteAccount')} + prompt={this.props.translate('paymentsPage.deleteConfirmation')} + confirmText={this.props.translate('common.delete')} + cancelText={this.props.translate('common.cancel')} + anchorPosition={{ + top: this.state.anchorPositionTop, + right: this.state.anchorPositionRight, + }} + shouldShowCancelButton + danger + /> + )} - { - this.setState({ - shouldShowConfirmPopover: false, - }); - this.deletePaymentMethod(); - }} - onCancel={() => { - this.setState({shouldShowConfirmPopover: false}); - }} - shouldShowCancelButton - danger - /> ); } diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js index 84cc1db5df1d..6c805ade9b17 100755 --- a/src/pages/settings/Profile/ProfilePage.js +++ b/src/pages/settings/Profile/ProfilePage.js @@ -28,30 +28,22 @@ import * as ValidationUtils from '../../../libs/ValidationUtils'; import * as ReportUtils from '../../../libs/ReportUtils'; import Form from '../../../components/Form'; import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; -import * as LoginUtils from '../../../libs/LoginUtils'; - -const loginPropTypes = PropTypes.shape({ - /** Value of partner name */ - partnerName: PropTypes.string, - - /** Phone/Email associated with user */ - partnerUserID: PropTypes.string, - - /** Date of when login was validated */ - validatedDate: PropTypes.string, -}); const propTypes = { /* Onyx Props */ /** Login list for the user that is signed in */ - loginList: PropTypes.oneOfType([ - PropTypes.objectOf(loginPropTypes), + loginList: PropTypes.shape({ + /** Value of partner name */ + partnerName: PropTypes.string, + + /** Phone/Email associated with user */ + partnerUserID: PropTypes.string, + + /** Date of when login was validated */ + validatedDate: PropTypes.string, + }), - // TODO: remove this once this closes: - // https://github.com/Expensify/App/issues/10960 - PropTypes.arrayOf(loginPropTypes), - ]), ...withLocalizePropTypes, ...withCurrentUserPersonalDetailsPropTypes, }; @@ -77,7 +69,7 @@ class ProfilePage extends Component { this.avatar = {uri: lodashGet(this.props.currentUserPersonalDetails, 'avatar') || this.defaultAvatar}; this.pronouns = props.currentUserPersonalDetails.pronouns; this.state = { - logins: this.getLogins(LoginUtils.convertLoginListToObject(props.loginList)), + logins: this.getLogins(), selectedTimezone: lodashGet(props.currentUserPersonalDetails.timezone, 'selected', CONST.DEFAULT_TIME_ZONE.selected), isAutomaticTimezone: lodashGet(props.currentUserPersonalDetails.timezone, 'automatic', CONST.DEFAULT_TIME_ZONE.automatic), hasSelfSelectedPronouns: !_.isEmpty(props.currentUserPersonalDetails.pronouns) && !props.currentUserPersonalDetails.pronouns.startsWith(CONST.PRONOUNS.PREFIX), @@ -94,10 +86,8 @@ class ProfilePage extends Component { let stateToUpdate = {}; // Recalculate logins if loginList has changed - const currentLoginList = LoginUtils.convertLoginListToObject(this.props.loginList); - const prevLoginList = LoginUtils.convertLoginListToObject(prevProps.loginList); - if (_.keys(currentLoginList).length !== _.keys(prevLoginList).length) { - stateToUpdate = {...stateToUpdate, logins: this.getLogins(currentLoginList)}; + if (_.keys(this.props.loginList).length !== _.keys(prevProps.loginList).length) { + stateToUpdate = {...stateToUpdate, logins: this.getLogins()}; } if (_.isEmpty(stateToUpdate)) { @@ -141,11 +131,10 @@ class ProfilePage extends Component { /** * Get the most validated login of each type * - * @param {Object} loginList * @returns {Object} */ - getLogins(loginList) { - return _.reduce(_.values(loginList), (logins, currentLogin) => { + getLogins() { + return _.reduce(_.values(this.props.loginList), (logins, currentLogin) => { const type = Str.isSMSLogin(currentLogin.partnerUserID) ? CONST.LOGIN_TYPE.PHONE : CONST.LOGIN_TYPE.EMAIL; const login = Str.removeSMSDomain(currentLogin.partnerUserID); diff --git a/src/pages/settings/Profile/TimezoneInitialPage.js b/src/pages/settings/Profile/TimezoneInitialPage.js new file mode 100644 index 000000000000..260820710cd8 --- /dev/null +++ b/src/pages/settings/Profile/TimezoneInitialPage.js @@ -0,0 +1,85 @@ +import lodashGet from 'lodash/get'; +import React from 'react'; +import {View} from 'react-native'; +import moment from 'moment-timezone'; +import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../../components/ScreenWrapper'; +import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import ROUTES from '../../../ROUTES'; +import CONST from '../../../CONST'; +import Text from '../../../components/Text'; +import styles from '../../../styles/styles'; +import Navigation from '../../../libs/Navigation/Navigation'; +import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; +import compose from '../../../libs/compose'; +import Switch from '../../../components/Switch'; +import MenuItemWithTopDescription from '../../../components/MenuItemWithTopDescription'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +const TimezoneInitialPage = (props) => { + const timezone = lodashGet(props.currentUserPersonalDetails, 'timezone', CONST.DEFAULT_TIME_ZONE); + + /** + * Updates setting for automatic timezone selection. + * Note: If we are updating automatically, we'll immediately calculate the user's timezone. + * + * @param {Boolean} isAutomatic + */ + const updateAutomaticTimezone = (isAutomatic) => { + PersonalDetails.updateAutomaticTimezone({ + automatic: isAutomatic, + selected: isAutomatic ? moment.tz.guess() : timezone.selected, + }); + }; + + return ( + + Navigation.navigate(ROUTES.SETTINGS_PROFILE)} + onCloseButtonPress={() => Navigation.dismissModal(true)} + /> + + + {props.translate('timezonePage.isShownOnProfile')} + + + + {props.translate('timezonePage.getLocationAutomatically')} + + + + + Navigation.navigate(ROUTES.SETTINGS_TIMEZONE_SELECT)} + /> + + ); +}; + +TimezoneInitialPage.propTypes = propTypes; +TimezoneInitialPage.defaultProps = defaultProps; +TimezoneInitialPage.displayName = 'TimezoneInitialPage'; + +export default compose( + withLocalize, + withCurrentUserPersonalDetails, +)(TimezoneInitialPage); diff --git a/src/pages/settings/Profile/TimezoneSelectPage.js b/src/pages/settings/Profile/TimezoneSelectPage.js new file mode 100644 index 000000000000..62cb212d60a4 --- /dev/null +++ b/src/pages/settings/Profile/TimezoneSelectPage.js @@ -0,0 +1,103 @@ +import lodashGet from 'lodash/get'; +import React, {Component} from 'react'; +import _ from 'underscore'; +import moment from 'moment-timezone'; +import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../../components/ScreenWrapper'; +import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import ROUTES from '../../../ROUTES'; +import CONST from '../../../CONST'; +import styles from '../../../styles/styles'; +import Navigation from '../../../libs/Navigation/Navigation'; +import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; +import compose from '../../../libs/compose'; +import OptionsSelector from '../../../components/OptionsSelector'; +import themeColors from '../../../styles/themes/default'; +import * as Expensicons from '../../../components/Icon/Expensicons'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +class TimezoneSelectPage extends Component { + constructor(props) { + super(props); + + this.saveSelectedTimezone = this.saveSelectedTimezone.bind(this); + this.filterShownTimezones = this.filterShownTimezones.bind(this); + + this.currentSelectedTimezone = lodashGet(props.currentUserPersonalDetails, 'timezone.selected', CONST.DEFAULT_TIME_ZONE.selected); + this.allTimezones = _.chain(moment.tz.names()) + .filter(timezone => !timezone.startsWith('Etc/GMT')) + .map(timezone => ({ + text: timezone, + keyForList: timezone, + + // Add green checkmark icon & bold the timezone text + customIcon: timezone === this.currentSelectedTimezone + ? {src: Expensicons.Checkmark, color: themeColors.success} + : null, + isUnread: timezone === this.currentSelectedTimezone, + })) + .value(); + + this.state = { + timezoneInputText: this.currentSelectedTimezone, + timezoneOptions: this.allTimezones, + }; + } + + /** + * @param {Object} timezone + * @param {String} timezone.text + */ + saveSelectedTimezone({text}) { + PersonalDetails.updateSelectedTimezone(text); + } + + /** + * @param {String} searchText + */ + filterShownTimezones(searchText) { + this.setState({ + timezoneInputText: searchText, + timezoneOptions: _.filter(this.allTimezones, (tz => tz.text.toLowerCase().includes(searchText.toLowerCase()))), + }); + } + + render() { + return ( + + Navigation.navigate(ROUTES.SETTINGS_TIMEZONE)} + onCloseButtonPress={() => Navigation.dismissModal(true)} + /> + + + ); + } +} + +TimezoneSelectPage.propTypes = propTypes; +TimezoneSelectPage.defaultProps = defaultProps; + +export default compose( + withLocalize, + withCurrentUserPersonalDetails, +)(TimezoneSelectPage); diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 2e47f6b39b14..e9813c3bfb1f 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -12,7 +12,6 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/ import compose from '../../libs/compose'; import canFocusInputOnScreenFocus from '../../libs/canFocusInputOnScreenFocus'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; -import getEmailKeyboardType from '../../libs/getEmailKeyboardType'; import TextInput from '../../components/TextInput'; import * as ValidationUtils from '../../libs/ValidationUtils'; import * as LoginUtils from '../../libs/LoginUtils'; @@ -24,6 +23,7 @@ import networkPropTypes from '../../components/networkPropTypes'; import * as ErrorUtils from '../../libs/ErrorUtils'; import DotIndicatorMessage from '../../components/DotIndicatorMessage'; import * as CloseAccount from '../../libs/actions/CloseAccount'; +import CONST from '../../CONST'; const propTypes = { /** Should we dismiss the keyboard when transitioning away from the page? */ @@ -177,7 +177,7 @@ class LoginForm extends React.Component { onSubmitEditing={this.validateAndSubmitForm} autoCapitalize="none" autoCorrect={false} - keyboardType={getEmailKeyboardType()} + keyboardType={CONST.KEYBOARD_TYPE.EMAIL_ADDRESS} /> {!_.isEmpty(this.props.account.success) && ( diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index f90778d203d8..35c51c259b24 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -1,9 +1,10 @@ import React from 'react'; -import {ScrollView, View, KeyboardAvoidingView} from 'react-native'; +import {ScrollView, View} from 'react-native'; import PropTypes from 'prop-types'; import {withSafeAreaInsets} from 'react-native-safe-area-context'; import styles from '../../../styles/styles'; import variables from '../../../styles/variables'; +import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView'; import ExpensifyCashLogo from '../../../components/ExpensifyCashLogo'; import Text from '../../../components/Text'; import TermsAndLicenses from '../TermsAndLicenses'; diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 1c016c601aae..7ed41d0e2b83 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -79,7 +79,7 @@ class WorkspaceInitialPage extends React.Component { const policyReports = _.filter(this.props.reports, report => report && report.policyID === this.props.policy.id); Policy.deleteWorkspace(this.props.policy.id, policyReports); this.toggleDeleteModal(false); - Navigation.navigate(ROUTES.SETTINGS); + Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); } /** diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 395707142f7a..fbabe111ac26 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -132,12 +132,15 @@ class WorkspaceInvitePage extends React.Component { */ getSections() { const sections = []; + let indexOffset = 0; + sections.push({ title: undefined, data: this.state.selectedOptions, shouldShow: true, - indexOffset: 0, + indexOffset, }); + indexOffset += this.state.selectedOptions.length; // Filtering out selected users from the search results const filterText = _.reduce(this.state.selectedOptions, (str, {login}) => `${str} ${login}`, ''); @@ -148,15 +151,16 @@ class WorkspaceInvitePage extends React.Component { title: this.props.translate('common.contacts'), data: personalDetailsWithoutSelected, shouldShow: !_.isEmpty(personalDetailsWithoutSelected), - indexOffset: _.reduce(sections, (prev, {data}) => prev + data.length, 0), + indexOffset, }); + indexOffset += personalDetailsWithoutSelected.length; if (hasUnselectedUserToInvite) { sections.push(({ title: undefined, data: [this.state.userToInvite], shouldShow: true, - indexOffset: 0, + indexOffset, })); } diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 67091d53c92c..6ff197f4f55e 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -152,9 +152,11 @@ class WorkspaceMembersPage extends React.Component { * Toggle user from the selectedEmployees list * * @param {String} login + * @param {String} pendingAction + * */ - toggleUser(login) { - if (this.willTooltipShowForLogin(login)) { + toggleUser(login, pendingAction) { + if (this.willTooltipShowForLogin(login) || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { return; } @@ -250,26 +252,26 @@ class WorkspaceMembersPage extends React.Component { renderItem({ item, }) { - const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login; + const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> this.willTooltipShowForLogin(item.login, true)} onHoverOut={() => this.setState({showTooltipForLogin: ''})}> this.toggleUser(item.login)} + onPress={() => this.toggleUser(item.login, item.pendingAction)} activeOpacity={0.7} > this.toggleUser(item.login)} + onPress={() => this.toggleUser(item.login, item.pendingAction)} toggleTooltip={this.state.showTooltipForLogin === item.login} text={this.props.translate('workspace.people.error.cannotRemove')} /> this.toggleUser(item.login)} + onSelectRow={() => this.toggleUser(item.login, item.pendingAction)} forceTextUnreadStyle isDisabled={!canBeRemoved} option={{ @@ -301,8 +303,7 @@ class WorkspaceMembersPage extends React.Component { const removableMembers = []; let data = []; _.each(policyMemberList, (policyMember, email) => { - if (policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { return; } - if (email !== this.props.session.email && email !== this.props.policy.owner) { + if (email !== this.props.session.email && email !== this.props.policy.owner && policyMember.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { removableMembers.push(email); } const details = lodashGet(this.props.personalDetails, email, {displayName: email, login: email, avatar: Expensicons.FallbackAvatar}); diff --git a/src/pages/workspace/WorkspacesListPage.js b/src/pages/workspace/WorkspacesListPage.js index e75bfe2dead8..41c6b3babed3 100755 --- a/src/pages/workspace/WorkspacesListPage.js +++ b/src/pages/workspace/WorkspacesListPage.js @@ -122,7 +122,7 @@ class WorkspacesListPage extends Component { iconType: policy.avatar ? CONST.ICON_TYPE_AVATAR : CONST.ICON_TYPE_ICON, action: () => Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policy.id)), iconStyles: policy.avatar ? [] : [styles.popoverMenuIconEmphasized], - iconFill: themeColors.iconReversed, + iconFill: themeColors.textLight, fallbackIcon: Expensicons.FallbackWorkspaceAvatar, brickRoadIndicator: PolicyUtils.getPolicyBrickRoadIndicatorStatus(policy, this.props.policyMembers), pendingAction: policy.pendingAction, diff --git a/src/pages/workspace/bills/WorkspaceBillsFirstSection.js b/src/pages/workspace/bills/WorkspaceBillsFirstSection.js index 85f1ecac7565..f283ec9d8469 100644 --- a/src/pages/workspace/bills/WorkspaceBillsFirstSection.js +++ b/src/pages/workspace/bills/WorkspaceBillsFirstSection.js @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; import Text from '../../../components/Text'; import styles from '../../../styles/styles'; +import themeColors from '../../../styles/themes/default'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import * as Expensicons from '../../../components/Icon/Expensicons'; import * as Illustrations from '../../../components/Icon/Illustrations'; @@ -38,7 +39,7 @@ const WorkspaceBillsFirstSection = (props) => { return (
{ icon: Expensicons.Bill, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, ]} + containerStyles={[styles.cardSection]} > - + {props.translate('workspace.bills.askYourVendorsBeforeEmail')} {props.user.isFromPublicDomain ? ( diff --git a/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js b/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js index 001ecf0273ba..3e5449d92921 100644 --- a/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js +++ b/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js @@ -24,9 +24,10 @@ const WorkspaceBillsNoVBAView = props => (
- + {props.translate('workspace.bills.unlockNoVBACopy')}
{props.user.isCheckingDomain && ( diff --git a/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js b/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js index ca6ab2578ba4..6f19096c97cc 100644 --- a/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js +++ b/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js @@ -2,6 +2,7 @@ import React from 'react'; import {View} from 'react-native'; import Text from '../../../components/Text'; import styles from '../../../styles/styles'; +import themeColors from '../../../styles/themes/default'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import * as Expensicons from '../../../components/Icon/Expensicons'; import * as Illustrations from '../../../components/Icon/Illustrations'; @@ -21,6 +22,8 @@ const WorkspaceCardVBAWithECardView = (props) => { icon: Expensicons.ExpensifyCard, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, { title: props.translate('workspace.common.reconcileCards'), @@ -28,6 +31,8 @@ const WorkspaceCardVBAWithECardView = (props) => { icon: Expensicons.ReceiptSearch, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, { title: props.translate('workspace.common.settlementFrequency'), @@ -35,27 +40,31 @@ const WorkspaceCardVBAWithECardView = (props) => { icon: Expensicons.Gear, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, ]; return (
- + {props.translate('workspace.card.VBAWithECardCopy')} - + + +
); }; diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js b/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js index 8529f4a62cb8..ef0e2512f426 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js @@ -3,6 +3,7 @@ import {View} from 'react-native'; import PropTypes from 'prop-types'; import Text from '../../../components/Text'; import styles from '../../../styles/styles'; +import themeColors from '../../../styles/themes/default'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import * as Expensicons from '../../../components/Icon/Expensicons'; import * as Illustrations from '../../../components/Icon/Illustrations'; @@ -19,7 +20,7 @@ const propTypes = { const WorkspaceInvoicesFirstSection = props => (
( icon: Expensicons.Send, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, { title: props.translate('workspace.invoices.viewAllInvoices'), @@ -36,10 +39,13 @@ const WorkspaceInvoicesFirstSection = props => ( icon: Expensicons.Invoice, shouldShowRightIcon: true, iconRight: Expensicons.NewWindow, + iconFill: themeColors.success, + wrapperStyle: [styles.cardMenuItem], }, ]} + containerStyles={[styles.cardSection]} > - + {props.translate('workspace.invoices.invoiceFirstSectionCopy')} diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js b/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js index 0136079d86d6..9418ff0e1535 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js @@ -24,9 +24,10 @@ const WorkspaceInvoicesNoVBAView = props => (
- + {props.translate('workspace.invoices.unlockNoVBACopy')}