1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-22 04:13:19 +00:00

Compare commits

..

67 Commits

Author SHA1 Message Date
Federico Maccaroni
553ac4d027 PM-3349 MAUI - Android - Fix crash on converter 2023-09-05 17:40:12 -03:00
Federico Maccaroni
b9414d6384 PM-3349 MAUI - Android - Fix Add/Edit cipher page 2023-09-04 20:37:30 -03:00
Federico Maccaroni
d8e8747478 PM-3349 MAUI - Android - Fix Options page 2023-09-01 19:44:20 -03:00
Federico Maccaroni
19c89ebb5f PM-3349 MAUI - Android - Fix Send add edit page 2023-09-01 18:48:25 -03:00
Federico Maccaroni
df4672d4cb PM-3349 MAUI - Android - Fix awful buttons background 2023-09-01 18:46:07 -03:00
Federico Maccaroni
2fe8ae0b46 PM-3349 MAUI - Android - Fix Generator page bindings 2023-09-01 16:04:25 -03:00
Federico Maccaroni
19ba70c9a6 PM-3349 MAUI - Android - Fix Account switching view 2023-08-31 13:33:54 -03:00
Federico Maccaroni
16675c2a66 PM-3349 MAUI Migration Single Project - Android - Handlers and some fixes to avoid crashing 2023-08-30 23:37:10 -03:00
Federico Maccaroni
6ff978cef2 MAUI Migration Single Project - Android - Fonts, renderers, effects 2023-07-31 22:15:14 -03:00
Federico Maccaroni
276081f5f7 MAUI single project migration Android comipling 2023-07-31 11:58:19 -03:00
Federico Maccaroni
d7f52a58f0 MAUI Single project migration initial 2023-07-28 19:44:49 -03:00
github-actions[bot]
0271a4db4c Autosync the updated translations (#2650)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-28 08:19:12 +00:00
Federico Maccaroni
375718f945 PM-3227 Avoid clone on discoverable passkeys. (#2648) 2023-07-27 18:35:09 -03:00
Federico Maccaroni
9eda015371 PM-3165 Finish task completion source when cancelling the dialog tapping on the background. (#2647) 2023-07-27 17:49:52 -03:00
Federico Maccaroni
ea81acb3bf [PM-1575] Display Passkeys (#2523)
* PM-1575 Added new models for Fido2Key

* PM-1575 Added discoverable passkeys and WIP non-discoverable ones

* PM-1575 Fix format

* PM-1575 Added non-discoverable passkeys to login UI

* PM-1575 Added copy application icon to Fido2Key UI

* PM-1575 Updated bwi font with the updated passkey icon

* PM-1575 For now just display Available for two-step login on non-discoverable passkey inside of a cipher login

* PM-1575 Fix non-discoverable passkey visibility

* PM-1575 remove Passkeys as a filter in the vault list

* PM-1575 Display error toast if there is a duplicate passkey when moving a cipher to an org

* Revert "PM-1575 Display error toast if there is a duplicate passkey when moving a cipher to an org"

This reverts commit 78e6353602.

* [PM-2378] Display error toast on duplicate Passkey when moving cipher to an organization (#2594)

* PM-2378 Display error toast if there is a duplicate passkey when moving a cipher to an org

* PM-3097 Fix issue when moving cipher with passkey to an org where the uniqueness should be taken into consideration on different passkeys types and also the Username (#2632)

* PM-3096 Fix non-discoverable passkey to be taken into account when encrypting a cipher which was causing the passkey to be removed when moving to an org (#2637)
2023-07-26 17:59:49 -03:00
René Wang
174549e5bc fix image alt text error (#2641) 2023-07-24 18:27:20 +00:00
Federico Maccaroni
87b1d18872 PM-2320 fix duplicated resource (#2638) 2023-07-21 15:58:28 -03:00
github-actions[bot]
ae9ba810ff Autosync the updated translations (#2634)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-21 09:30:20 +00:00
Federico Maccaroni
dd52ff0dcc [PM-2320] Improve Android block Auto-fill URIs (#2616)
* PM-2320 Added new view for block autofill URIs on Android

* PM-2320 Fix formatting

* PM-2320 Improved validations on block autofill uris

* PM-2320 Improved autofill block uris placeholder colors on different themes
2023-07-18 11:25:38 -03:00
github-actions[bot]
c678c17ebc Bumped version to 2023.7.1 (#2625)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-18 14:23:08 +00:00
Federico Maccaroni
cd9e49b13b ac-1425 added main thread invocations when updating the vault properties to fix cases where the screen stays blank and doesn't update (#2604) 2023-07-17 16:53:30 -03:00
Federico Maccaroni
6d7970f767 [AC-762] Configure Crowdin to localize watch app (#2552)
* AC-762 Added localization files to watch project

* AC-762 Added crowdin config for watchOS localizable files
2023-07-17 13:35:54 -03:00
mpbw2
9adc4d3080 Catch additional exception types when validating intents (#2618) 2023-07-17 08:40:35 -04:00
ifernandezdiaz
1f20f70d13 Fixing show value id button (#2620) 2023-07-16 20:13:55 -03:00
Vince Grassia
a25da68437 Fix syntax in Version Auto Bump workflow (#2615) 2023-07-13 11:55:16 -04:00
Vince Grassia
fdc0313d10 Fix Build Workflow (#2613) 2023-07-13 10:05:57 -04:00
github-actions[bot]
f31c87b52e Bumped version to 2023.7.0 (#2612)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-12 17:34:23 +00:00
Cesar Gonzalez
1e79e1182f [PM-1063] Re-prompt for Master Password Can be Bypassed When Using Gboard Inline Autofill (#2593) 2023-07-11 08:15:37 -05:00
github-actions[bot]
11947ce99a Autosync the updated translations (#2603)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-07 05:13:18 +00:00
mpbw2
4abb472998 Revert "reset lock delay when returning from activity result (#2539)" (#2597)
This reverts commit 0288a6659c.
2023-07-03 09:56:10 -04:00
github-actions[bot]
1d541e5b8e Autosync the updated translations (#2595)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-30 07:06:12 +00:00
ifernandezdiaz
175b9936b6 [PM-2798] Fixing Toolbar locators in FolderAddEditPage (#2592)
* Fixing Toolbar locators

* Adding Matt's suggestions
2023-06-29 15:50:01 -03:00
ifernandezdiaz
72e67bd6f2 [PM-2691] Adding AutomationIDs for Vault Page sections (#2580)
* Adding IDs for Vault Page sections

* Removing extra spaces

* Adding Matt's comments

* Fixing Filters Id bug

* Adding Fede's suggestions

* Fixing Settings Ids issues

* Fixing AutomationIds issues with RecyclerViews + implementing AutomationId helper class

* Adding Fede's suggestion

* Adding latest Fede's suggestions
2023-06-29 15:37:08 -03:00
ifernandezdiaz
216c6abcf6 [PM-2737] Adding AutomationIDs for Send page elements (#2583)
* Adding AutomationIDs for Send page elements

* Fixing some spaces

* Adding Matt's suggestion

* Adding Fede's suggestion

* Removing unnecesarry breaks
2023-06-28 14:07:03 -04:00
Federico Maccaroni
1014563c75 [PM-192] Refactor forwarded email providers (#2579)
* PM-192 Refactor Forwarded email providers to use better patterns and code reuse.

* PM-192 fix format
2023-06-27 18:49:38 -03:00
ifernandezdiaz
3506269811 [PM-2688] Adding IDs for Options and Folders pages (#2585)
* Adding IDs for Options and Folders pages

* Fixing extra spaces
2023-06-26 10:31:57 -03:00
ifernandezdiaz
31487a31bb [PM-2748] Refactoring locator strategy for Cipher Details page (#2586)
* Refactoring locator strategy for Cipher Details page

* Fixing extra spaces
2023-06-26 10:30:13 -03:00
ifernandezdiaz
1407aa5655 [PM-2678] Adding IDs for Settings Page elements (#2584)
* Adding IDS for Settings elements

* Adding IDS for Settings elements
2023-06-23 13:31:24 -03:00
github-actions[bot]
16f59e2698 Autosync the updated translations (#2582)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-23 05:40:37 +00:00
ifernandezdiaz
d876b54f45 Adding IDs for AttachmentPage elements (#2577) 2023-06-20 17:49:26 -03:00
ifernandezdiaz
6644e3b449 [PM-2545] Adding Automation IDs for CipherDetailsPage elements (#2576)
* Adding IDs to CipherDetailsPage

* Fixing extra spaces

* Fixing extra space
2023-06-20 16:26:43 -03:00
ifernandezdiaz
8d98d1d5bd [PM-2612] Adding AutomationIDs for LoginPasswordlessPage elements (#2574)
* Adding AutomationIDs for LoginPasswordlessPag elements

* Adding AutomationIDs for LoginPasswordlessRequest page elements

* Fixing missing space
2023-06-20 15:12:15 -03:00
ifernandezdiaz
3e9711f8f2 [PM-2611] Adding IDs for Cipher/Send search results (#2575)
* Adding IDs for Cipher/Send search results

* Adding missing spaces
2023-06-20 11:28:54 -03:00
github-actions[bot]
3af37f01d3 Autosync the updated translations (#2570)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-19 09:05:12 +00:00
ifernandezdiaz
43d2d386b1 [PM-2645] Adding IDs for Account Switching elements (#2572)
* Adding IDs for Account Switching elements

* Fixing Active/Inactive vault icon IDs
2023-06-16 16:20:09 -03:00
ifernandezdiaz
bc5c11b47f Adding AutomationIDs on Generator page elements (#2569)
* Adding AutomationIDs on Generator pages

* Adding missing spaces
2023-06-15 16:11:55 -03:00
ifernandezdiaz
52843b4181 [PM-2544] Adding AutomationIDs for CipherAddEditViewPage elements (#2564)
* Adding AutomationIDs for Add/Edit Items page

* Adding IDs to CustomFields

* Adding Matt's suggestions

* Adding newest suggestions
2023-06-14 09:34:38 -03:00
Federico Maccaroni
98705e443f PM-2575 Fixed extension freeze when using the return button on the keyboard when unlocking the extension. Also added way to prevent multiple executions of checking the password and logging exceptions. (#2568) 2023-06-13 22:38:08 +02:00
mpbw2
1332ef7b43 Enhancement to login field detection for Android autofill (#2561) 2023-06-13 13:54:28 -04:00
mpbw2
04e30c2146 Update F-Droid listing author name (#2501)
Update F-Droid listing author name to `Bitwarden Inc`
2023-06-13 18:46:41 +02:00
Opeyemi
f604da13a1 add more comment to missing actions (#2567) 2023-06-13 15:57:02 +01:00
github-actions[bot]
dcf9acb51c Autosync the updated translations (#2562)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-09 09:19:34 +02:00
Federico Maccaroni
3b087c50ae PM-1076 added warning on unlocking iOS extensions when the kdf type is argon2id and the memory is higher than 48MB, to let the user know that unlocking might crash the extension (#2560) 2023-06-07 16:21:51 +02:00
ifernandezdiaz
1c13ed9895 [PS-2558] Mobile Automation - Starting automationIDs additions to our codebase (#2558)
* Adding locators for Environment, Hope, Login and Register pages

* Adding Locators on LockPage

* Adding Álison's suggestions
2023-06-06 21:00:01 -03:00
Federico Maccaroni
eeb634e698 PM-1798 Added accessibility names on entries on cipher add (#2550) 2023-06-05 18:58:38 +02:00
github-actions[bot]
8bc2df6c8a Autosync the updated translations (#2555)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-04 16:23:34 +02:00
github-actions[bot]
7cd40d4d89 Bumped version to 2023.5.1 (#2554)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-01 12:18:12 -04:00
Federico Maccaroni
bebf23785d PM-2232 Fix api response not being read as string because the content was not being considered json when it was indeed. Now Netacea messages are shown on the UI. (#2541) 2023-06-01 10:35:35 +03:00
github-actions[bot]
e78833cbcb Bumped version to 2023.5.0 (#2553)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-31 09:33:47 -04:00
github-actions[bot]
b7ff636862 Autosync the updated translations (#2540)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-26 08:12:16 +02:00
mpbw2
0288a6659c reset lock delay when returning from activity result (#2539) 2023-05-25 11:43:45 -04:00
André Bispo
c7fd113f26 [PM-2347] Refresh feature flags when environment urls change (#2538) 2023-05-25 14:37:53 +01:00
Michał Chęciński
79241731e7 Add github actions to renovate (#2536)
* Add github actions to renovate

* Add gh actions manager

* Apply whole renovate config

* Add newline
2023-05-24 16:04:39 +02:00
github-actions[bot]
74e9914f5b Autosync the updated translations (#2531)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-22 11:35:15 +02:00
André Bispo
65307f6eab [PM-1351][PM-190] Add a mobile service to retrieve feature flags from API (#2431) 2023-05-19 12:42:41 +01:00
github-actions[bot]
e9f83aee90 Autosync the updated translations (#2524)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-19 08:28:02 +02:00
Federico Maccaroni
fdaf743868 PM-2249 Fix vault timeout action policy check (#2521) 2023-05-15 15:28:18 +02:00
1348 changed files with 278099 additions and 3018 deletions

57
.github/renovate.json vendored
View File

@@ -1,22 +1,37 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
"schedule:monthly",
":maintainLockFilesMonthly",
":preserveSemverRanges",
":rebaseStalePrs",
":disableDependencyDashboard"
],
"enabledManagers": [
"nuget"
],
"packageRules": [
{
"matchManagers": ["nuget"],
"groupName": "Nuget updates",
"groupSlug": "nuget",
"separateMajorMinor": false
}
]
}
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":combinePatchMinorReleases",
":dependencyDashboard",
":maintainLockFilesWeekly",
":pinAllExceptPeerDependencies",
":prConcurrentLimit10",
":rebaseStalePrs",
"schedule:weekends",
":separateMajorReleases"
],
"enabledManagers": ["cargo", "github-actions", "npm", "nuget"],
"packageRules": [
{
"groupName": "cargo minor",
"matchManagers": ["cargo"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "gh minor",
"matchManagers": ["github-actions"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "npm minor",
"matchManagers": ["npm"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "nuget minor",
"matchManagers": ["nuget"],
"matchUpdateTypes": ["minor", "patch"]
},
]
}

View File

@@ -71,6 +71,11 @@ jobs:
with:
nuget-version: 5.9.0
- name: Set up .NET
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '3.1.x'
- name: Set up MSBuild
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
@@ -793,7 +798,7 @@ jobs:
done
- name: Upload Sources
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -30,7 +30,7 @@ jobs:
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Download translations
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Enforce Label
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # v2.2.2
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2
with:
BANNED_LABELS: "hold,needs-qa"
BANNED_LABELS_DESCRIPTION: "PRs with the hold or needs-qa labels cannot be merged"

View File

@@ -1,23 +0,0 @@
# Runs on creation of Pull Requests
# If the PR destination branch is master, add a needs-qa label
---
name: Label Issue Pull Request
on:
pull_request:
types:
- opened # Check when PR is opened
paths-ignore:
- .github/workflows/** # We don't need QA on workflow changes
branches:
- 'master' # We only want to check when PRs target master
jobs:
add-needs-qa-label:
runs-on: ubuntu-latest
steps:
- name: Add label to pull request
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
add-labels: "needs-qa"

View File

@@ -68,7 +68,7 @@ jobs:
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -76,7 +76,7 @@ jobs:
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -130,7 +130,7 @@ jobs:
- name: Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -139,7 +139,7 @@ jobs:
- name: Dry Run - Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success

View File

@@ -32,14 +32,10 @@ jobs:
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
trigger_version_bump:
name: "Version bump"
runs-on: ubuntu-22.04
needs:
- setup
steps:
- name: Bump version to ${{ needs.setup.outputs.version_number }}
uses: ./.github/workflows/version-bump.yml
secrets:
AZURE_PROD_KV_CREDENTIALS: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
with:
version_number: ${{ needs.setup.outputs.version_number }}
name: Bump version to ${{ needs.setup.outputs.version_number }}
needs: setup
uses: ./.github/workflows/version-bump.yml
secrets:
AZURE_PROD_KV_CREDENTIALS: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
with:
version_number: ${{ needs.setup.outputs.version_number }}

View File

@@ -4,7 +4,7 @@
# Bitwarden Mobile Application
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://mobileapp.bitwarden.com/fdroid/" target="_blank"><img alt="Get it on Google Play" src="https://i.imgur.com/HDicnzz.png" width="154" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://mobileapp.bitwarden.com/fdroid/" target="_blank"><img alt="Get it on F-Droid" src="https://i.imgur.com/HDicnzz.png" width="154" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.

View File

@@ -38,3 +38,15 @@ files:
pt-PT: pt-PT
en-GB: en-GB
en-IN: en-IN
- source: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization/en.lproj/Localizable.strings"
dest: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization/en.lproj/%original_file_name%"
translation: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization//%two_letters_code%.lproj/%original_file_name%"
update_option: update_as_unapproved
languages_mapping:
two_letters_code:
zh-CN: zh-Hans
zh-TW: zh-Hant
pt-BR: pt-BR
pt-PT: pt-PT
en-GB: en-GB
en-IN: en-IN

5
global.json Normal file
View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "7.0.306"
}
}

View File

@@ -159,6 +159,7 @@
<Compile Include="Constants.cs" />
<Compile Include="Effects\RemoveFontPaddingEffect.cs" />
<Compile Include="Services\WatchDeviceService.cs" />
<Compile Include="Renderers\CustomLabelRenderer.cs" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="Assets\bwi-font.ttf" />
@@ -232,6 +233,18 @@
<SubType></SubType>
<Generator></Generator>
</AndroidResource>
<AndroidResource Include="Resources\layout\validatable_input_dialog_layout.xml">
<SubType></SubType>
<Generator></Generator>
</AndroidResource>
<AndroidResource Include="Resources\drawable\empty_uris_placeholder.xml">
<SubType></SubType>
<Generator></Generator>
</AndroidResource>
<AndroidResource Include="Resources\drawable\empty_uris_placeholder_dark.xml">
<SubType></SubType>
<Generator></Generator>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\splash_screen.xml" />

Binary file not shown.

View File

@@ -12,7 +12,7 @@ namespace Bit.Droid.Autofill
private List<Field> _passwordFields = null;
private List<Field> _usernameFields = null;
private HashSet<string> _ignoreSearchTerms = new HashSet<string> { "search", "find", "recipient", "edit" };
private HashSet<string> _usernameTerms = new HashSet<string> { "email", "phone", "username"};
private HashSet<string> _usernameTerms = new HashSet<string> { "email", "phone", "username" };
private HashSet<string> _passwordTerms = new HashSet<string> { "password", "pswd" };
public List<AutofillId> AutofillIds { get; private set; } = new List<AutofillId>();
@@ -54,15 +54,14 @@ namespace Bit.Droid.Autofill
if (HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
{
_passwordFields.AddRange(HintToFieldsMap[View.AutofillHintPassword]);
return _passwordFields;
}
}
else
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
return _passwordFields;
}
@@ -87,24 +86,26 @@ namespace Bit.Droid.Autofill
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintUsername]);
}
if (_usernameFields.Any())
{
return _usernameFields;
}
}
else
{
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if (usernameField != null)
{
_usernameFields.Add(usernameField);
}
}
if (!_usernameFields.Any())
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if (usernameField != null)
{
_usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList();
_usernameFields.Add(usernameField);
}
}
if (!_usernameFields.Any())
{
_usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList();
}
return _usernameFields;
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.4.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.7.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />

View File

@@ -0,0 +1,43 @@
using System.ComponentModel;
using Android.Content;
using Android.OS;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
namespace Bit.Droid.Renderers
{
public class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null && e.NewElement is CustomLabel label)
{
if (label.FontWeight.HasValue && Build.VERSION.SdkInt >= BuildVersionCodes.P)
{
Control.Typeface = Android.Graphics.Typeface.Create(null, label.FontWeight.Value, false);
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var label = sender as CustomLabel;
switch (e.PropertyName)
{
case nameof(CustomLabel.AutomationId):
Control.ContentDescription = label.AutomationId;
break;
}
base.OnElementPropertyChanged(sender, e);
}
}
}

View File

@@ -0,0 +1,35 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="129"
android:viewportHeight="124"
android:width="129dp"
android:height="124dp">
<path
android:pathData="M126.8227 61.9441A59.6843 59.6843 0 0 1 7.4541 61.9441A59.6843 59.6843 0 0 1 126.8227 61.9441Z"
android:fillColor="#F0F0F0"
android:strokeColor="#89929F"
android:strokeWidth="3" />
<path
android:pathData="M21.6167 100.851C52.597 103.31 79.6937 80.3264 82.1391 49.5156C83.6205 30.8497 76.0789 14.8844 62.7275 3.63385"
android:strokeColor="#89929F"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M14.5633 34.2845C12.2035 66.7711 38.5225 96.3429 72.6666 98.8232C74.2596 98.9389 78.629 98.9975 80.1951 99C84.6245 98.8232 97.8063 96.593 106.813 91.8485C113.439 88.3581 119.745 84.6984 124.644 79.1121"
android:strokeColor="#89929F"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M124.502 48.5051C106.554 24.3817 68.8237 21.6709 41.4178 42.0617C24.8146 54.4149 14.7327 72.4183 13.9255 90.1427"
android:strokeColor="#89929F"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M83.4034 28.3934A5 5 0 0 1 73.4034 28.3934A5 5 0 0 1 83.4034 28.3934Z"
android:fillColor="#89929F" />
<path
android:pathData="M24.7698 66.5518A5 5 0 0 1 14.7698 66.5518A5 5 0 0 1 24.7698 66.5518Z"
android:fillColor="#89929F" />
<path
android:pathData="M57.344 94.4726A5 5 0 0 1 47.344 94.4726A5 5 0 0 1 57.344 94.4726Z"
android:fillColor="#89929F" />
</vector>

View File

@@ -0,0 +1,35 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="129"
android:viewportHeight="124"
android:width="129dp"
android:height="124dp">
<path
android:pathData="M126.8227 61.9441A59.6843 59.6843 0 0 1 7.4541 61.9441A59.6843 59.6843 0 0 1 126.8227 61.9441Z"
android:fillColor="@android:color/transparent"
android:strokeColor="#A3A3A3"
android:strokeWidth="3" />
<path
android:pathData="M21.6167 100.851C52.597 103.31 79.6937 80.3264 82.1391 49.5156C83.6205 30.8497 76.0789 14.8844 62.7275 3.63385"
android:strokeColor="#A3A3A3"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M14.5633 34.2845C12.2035 66.7711 38.5225 96.3429 72.6666 98.8232C74.2596 98.9389 78.629 98.9975 80.1951 99C84.6245 98.8232 97.8063 96.593 106.813 91.8485C113.439 88.3581 119.745 84.6984 124.644 79.1121"
android:strokeColor="#A3A3A3"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M124.502 48.5051C106.554 24.3817 68.8237 21.6709 41.4178 42.0617C24.8146 54.4149 14.7327 72.4183 13.9255 90.1427"
android:strokeColor="#A3A3A3"
android:strokeWidth="1.5"
android:strokeLineCap="round" />
<path
android:pathData="M83.4034 28.3934A5 5 0 0 1 73.4034 28.3934A5 5 0 0 1 83.4034 28.3934Z"
android:fillColor="#A3A3A3" />
<path
android:pathData="M24.7698 66.5518A5 5 0 0 1 14.7698 66.5518A5 5 0 0 1 24.7698 66.5518Z"
android:fillColor="#A3A3A3" />
<path
android:pathData="M57.344 94.4726A5 5 0 0 1 47.344 94.4726A5 5 0 0 1 57.344 94.4726Z"
android:fillColor="#A3A3A3" />
</vector>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:paddingRight="30dp">
<TextView
android:id="@+id/lblHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/dialog_header_text_size"
android:layout_marginTop="5dp"
android:layout_marginBottom="-3dp"
android:labelFor="@+id/txtValue"/>
<EditText
android:id="@id/txtValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/dialog_input_text_size"/>
<TextView
android:id="@+id/lblValueSubinfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/dialog_sub_value_info_text_size"/>
</LinearLayout>

View File

@@ -2,4 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_bottom_navigation_text_size" tools:override="true">15sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">15sp</dimen>
<dimen name="dialog_input_text_size">16sp</dimen>
<dimen name="dialog_header_text_size">12sp</dimen>
<dimen name="dialog_sub_value_info_text_size">12sp</dimen>
</resources>

View File

@@ -13,12 +13,13 @@ using Android.Views.InputMethods;
using Android.Widget;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.App.Utilities.Prompts;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Bit.Droid.Utilities;
using Plugin.CurrentActivity;
using static Bit.App.Pages.SettingsPageViewModel;
using Xamarin.Forms.Platform.Android;
namespace Bit.Droid.Services
{
@@ -209,10 +210,7 @@ namespace Bit.Droid.Services
}
if (numericKeyboard)
{
input.InputType = InputTypes.ClassNumber | InputTypes.NumberFlagDecimal | InputTypes.NumberFlagSigned;
#pragma warning disable CS0618 // Type or member is obsolete
input.KeyListener = DigitsKeyListener.GetInstance(false, false);
#pragma warning restore CS0618 // Type or member is obsolete
SetNumericKeyboardTo(input);
}
if (password)
{
@@ -248,6 +246,83 @@ namespace Bit.Droid.Services
return result.Task;
}
public Task<ValidatablePromptResponse?> DisplayValidatablePromptAsync(ValidatablePromptConfig config)
{
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
if (activity == null)
{
return Task.FromResult<ValidatablePromptResponse?>(null);
}
var alertBuilder = new AlertDialog.Builder(activity);
alertBuilder.SetTitle(config.Title);
var view = activity.LayoutInflater.Inflate(Resource.Layout.validatable_input_dialog_layout, null);
alertBuilder.SetView(view);
var result = new TaskCompletionSource<ValidatablePromptResponse?>();
alertBuilder.SetOnCancelListener(new BasicDialogWithResultCancelListener(result));
alertBuilder.SetPositiveButton(config.OkButtonText ?? AppResources.Ok, listener: null);
alertBuilder.SetNegativeButton(config.CancelButtonText ?? AppResources.Cancel, (sender, args) => result.TrySetResult(null));
if (!string.IsNullOrEmpty(config.ThirdButtonText))
{
alertBuilder.SetNeutralButton(config.ThirdButtonText, (sender, args) => result.TrySetResult(new ValidatablePromptResponse(null, true)));
}
var alert = alertBuilder.Create();
var input = view.FindViewById<EditText>(Resource.Id.txtValue);
var lblHeader = view.FindViewById<TextView>(Resource.Id.lblHeader);
var lblValueSubinfo = view.FindViewById<TextView>(Resource.Id.lblValueSubinfo);
lblHeader.Text = config.Subtitle;
lblValueSubinfo.Text = config.ValueSubInfo;
var defaultSubInfoColor = lblValueSubinfo.TextColors;
input.InputType = InputTypes.ClassText;
if (config.NumericKeyboard)
{
SetNumericKeyboardTo(input);
}
input.ImeOptions = input.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning | (ImeAction)ImeFlags.NoExtractUi;
input.Text = config.Text ?? string.Empty;
input.SetSelection(config.Text?.Length ?? 0);
input.AfterTextChanged += (sender, args) =>
{
if (lblValueSubinfo.Text != config.ValueSubInfo)
{
lblValueSubinfo.Text = config.ValueSubInfo;
lblHeader.SetTextColor(defaultSubInfoColor);
lblValueSubinfo.SetTextColor(defaultSubInfoColor);
}
};
alert.Window.SetSoftInputMode(SoftInput.StateVisible);
alert.Show();
var positiveButton = alert.GetButton((int)DialogButtonType.Positive);
positiveButton.Click += (sender, args) =>
{
var error = config.ValidateText(input.Text);
if (error != null)
{
lblHeader.SetTextColor(ThemeManager.GetResourceColor("DangerColor").ToAndroid());
lblValueSubinfo.SetTextColor(ThemeManager.GetResourceColor("DangerColor").ToAndroid());
lblValueSubinfo.Text = error;
lblValueSubinfo.SendAccessibilityEvent(Android.Views.Accessibility.EventTypes.ViewFocused);
return;
}
result.TrySetResult(new ValidatablePromptResponse(input.Text, false));
alert.Dismiss();
};
return result.Task;
}
public void RateApp()
{
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
@@ -525,5 +600,29 @@ namespace Bit.Droid.Services
// only used by iOS
throw new NotImplementedException();
}
private void SetNumericKeyboardTo(EditText editText)
{
editText.InputType = InputTypes.ClassNumber | InputTypes.NumberFlagDecimal | InputTypes.NumberFlagSigned;
#pragma warning disable CS0618 // Type or member is obsolete
editText.KeyListener = DigitsKeyListener.GetInstance(false, false);
#pragma warning restore CS0618 // Type or member is obsolete
}
}
class BasicDialogWithResultCancelListener : Java.Lang.Object, IDialogInterfaceOnCancelListener
{
private readonly TaskCompletionSource<ValidatablePromptResponse?> _taskCompletionSource;
public BasicDialogWithResultCancelListener(TaskCompletionSource<ValidatablePromptResponse?> taskCompletionSource)
{
_taskCompletionSource = taskCompletionSource;
}
public void OnCancel(IDialogInterface dialog)
{
_taskCompletionSource?.TrySetResult(null);
dialog?.Dismiss();
}
}
}

View File

@@ -1,5 +1,6 @@
using Android.Content;
using Android.OS;
using Java.Lang;
namespace Bit.Droid.Utilities
{
@@ -13,7 +14,12 @@ namespace Bit.Droid.Utilities
// Note: getting the bundle like this will cause to call unparcel() internally
var b = intent?.Extras?.GetBundle("trashstringwhichhasnousebuttocheckunparcel");
}
catch (BadParcelableException)
catch (Exception ex) when
(
ex is BadParcelableException ||
ex is ClassNotFoundException ||
ex is RuntimeException
)
{
intent.ReplaceExtras((Bundle)null);
}

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Bit.App.Utilities.Prompts;
using Bit.Core.Enums;
using Bit.Core.Models;
@@ -18,6 +19,7 @@ namespace Bit.App.Abstractions
Task<string> DisplayPromptAync(string title = null, string description = null, string text = null,
string okButtonText = null, string cancelButtonText = null, bool numericKeyboard = false,
bool autofocus = true, bool password = false);
Task<ValidatablePromptResponse?> DisplayValidatablePromptAsync(ValidatablePromptConfig config);
Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons);
Task<string> DisplayActionSheetAsync(string title, string cancel, string destruction, params string[] buttons);

View File

@@ -1,33 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>Bit.App</RootNamespace>
<AssemblyName>BitwardenApp</AssemblyName>
<Configurations>Debug;Release;FDroid</Configurations>
<TargetFrameworks>net7.0-android;net7.0-ios</TargetFrameworks>
<UseMaui>True</UseMaui>
<OutputType>Library</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<SingleProject>true</SingleProject>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Plugin.Fingerprint" Version="2.1.5" />
<PackageReference Include="SkiaSharp.Views.Forms" Version="2.88.3" />
<PackageReference Include="Xamarin.CommunityToolkit" Version="2.0.6" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.5" />
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="ZXing.Net.Mobile" Version="2.4.1" />
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.4.1" />
<PackageReference Include="MessagePack" Version="2.4.59" />
<PackageReference Include="SkiaSharp.Views.Maui.Core" Version="2.88.3" />
<PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="2.88.3" />
<PackageReference Include="SkiaSharp.Views.Maui.Controls.Compatibility" Version="2.88.3" />
<PackageReference Include="CommunityToolkit.Maui" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Pages\Accounts\EnvironmentPage.xaml.cs">
<DependentUpon>EnvironmentPage.xaml</DependentUpon>
@@ -130,7 +125,6 @@
<DependentUpon>LoginPasswordlessRequestPage.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
<Folder Include="Behaviors\" />
@@ -145,12 +139,12 @@
<Folder Include="Controls\DateTime\" />
<Folder Include="Controls\IconLabelButton\" />
<Folder Include="Controls\PasswordStrengthProgressBar\" />
<Folder Include="Utilities\Automation\" />
<Folder Include="Utilities\Prompts\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="Pages\Accounts\AccountsPopupPage.xaml" />
</ItemGroup>
<ItemGroup>
<Compile Update="Styles\Black.xaml.cs">
<DependentUpon>Black.xaml</DependentUpon>
@@ -174,7 +168,6 @@
<DependentUpon>Android.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\AppResources.cs.Designer.cs">
<DependentUpon>AppResources.cs.resx</DependentUpon>
@@ -312,7 +305,6 @@
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\AppResources.cs.resx">
<LastGenOutput>AppResources.cs.Designer.cs</LastGenOutput>
@@ -423,7 +415,6 @@
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Remove="Behaviors\" />
<None Remove="Xamarin.CommunityToolkit" />
@@ -440,5 +431,7 @@
<None Remove="MessagePack" />
<None Remove="MessagePack.MSBuild.Tasks" />
<None Remove="Controls\PasswordStrengthProgressBar\" />
<None Remove="Utilities\Automation\" />
<None Remove="Utilities\Prompts\" />
</ItemGroup>
</Project>
</Project>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.App">
<Application.Resources>

View File

@@ -15,8 +15,9 @@ using Bit.Core.Models.Data;
using Bit.Core.Models.Response;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Microsoft.Maui.Controls.Xaml;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Bit.App
@@ -38,6 +39,7 @@ namespace Bit.App
private readonly IFileService _fileService;
private readonly IAccountsManager _accountsManager;
private readonly IPushNotificationService _pushNotificationService;
private readonly IConfigService _configService;
private static bool _isResumed;
// these variables are static because the app is launching new activities on notification click, creating new instances of App.
private static bool _pendingCheckPasswordlessLoginRequests;
@@ -61,6 +63,7 @@ namespace Bit.App
_fileService = ServiceContainer.Resolve<IFileService>();
_accountsManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
_configService = ServiceContainer.Resolve<IConfigService>();
_accountsManager.Init(() => Options, this);
@@ -91,6 +94,7 @@ namespace Bit.App
}
else if (message.Command == "resumed")
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.iOS)
{
ResumedAsync().FireAndForget();
@@ -98,6 +102,7 @@ namespace Bit.App
}
else if (message.Command == "slept")
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.iOS)
{
await SleptAsync();
@@ -119,7 +124,7 @@ namespace Bit.App
Options.OtpData = new OtpData((string)message.Data);
}
await Device.InvokeOnMainThreadAsync(async () =>
Device.InvokeOnMainThreadAsync(async () =>
{
if (Current.MainPage is TabsPage tabsPage)
{
@@ -169,6 +174,10 @@ namespace Bit.App
new NavigationPage(new UpdateTempPasswordPage()));
});
}
else if (message.Command == "syncCompleted")
{
await _configService.GetAsync(true);
}
else if (message.Command == Constants.PasswordlessLoginRequestKey
|| message.Command == "unlocked"
|| message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED)
@@ -287,12 +296,15 @@ namespace Bit.App
{
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
}
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android)
{
await _vaultTimeoutService.CheckVaultTimeoutAsync();
// Reset delay on every start
_vaultTimeoutService.DelayLockAndLogoutMs = null;
}
await _configService.GetAsync();
_messagingService.Send("startEventTimer");
}
@@ -300,6 +312,7 @@ namespace Bit.App
{
System.Diagnostics.Debug.WriteLine("XF App: OnSleep");
_isResumed = false;
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android)
{
var isLocked = await _vaultTimeoutService.IsLockedAsync();
@@ -323,6 +336,7 @@ namespace Bit.App
{
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
}
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android)
{
ResumedAsync().FireAndForget();
@@ -388,6 +402,7 @@ namespace Bit.App
private void ClearAutofillUri()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri))
{
Options.Uri = null;
@@ -396,6 +411,7 @@ namespace Bit.App
private bool SetTabsPageFromAutofill(bool isLocked)
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri) &&
!Options.FromAutofillFramework)
{
@@ -444,7 +460,7 @@ namespace Bit.App
private void SyncIfNeeded()
{
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
if (Microsoft.Maui.Networking.Connectivity.NetworkAccess == Microsoft.Maui.Networking.NetworkAccess.None)
{
return;
}

View File

@@ -1,5 +1,5 @@
using Xamarin.Essentials;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Behaviors
{

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:xct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:effects="clr-namespace:Bit.App.Effects"
xmlns:view="clr-namespace:Bit.Core.Models.View;assembly=BitwardenCore"
@@ -30,13 +30,15 @@
BackgroundColor="{DynamicResource BackgroundColor}"
VerticalOptions="Start"
RowHeight="{Binding AccountListRowHeight, Source={x:Reference _mainOverlay}}"
effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never">
effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never"
AutomationId="AccountListView">
<ListView.ItemTemplate>
<DataTemplate x:DataType="view:AccountView">
<controls:AccountViewCell
Account="{Binding .}"
SelectAccountCommand="{Binding SelectAccountCommand, Source={x:Reference _mainOverlay}}"
LongPressAccountCommand="{Binding LongPressAccountCommand, Source={x:Reference _mainOverlay}}"
AutomationId="AccountViewCell"
/>
</DataTemplate>
</ListView.ItemTemplate>

View File

@@ -4,7 +4,8 @@ using System.Windows.Input;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -61,7 +62,8 @@ namespace Bit.App.Controls
public ICommand LongPressAccountCommand { get; }
public int AccountListRowHeight => Device.RuntimePlatform == Device.Android ? 74 : 70;
public int AccountListRowHeight => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
Device.RuntimePlatform == Device.Android ? 74 : 70;
public bool LongPressAccountEnabled { get; set; } = true;

View File

@@ -7,7 +7,8 @@ using Bit.Core.Abstractions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
<ViewCell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:xct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="Bit.App.Controls.AccountViewCell"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:u="clr-namespace:Bit.App.Utilities"
@@ -60,20 +60,23 @@
Text="{Binding AccountView.Email}"
IsVisible="{Binding IsActive}"
StyleClass="accountlist-title, accountlist-title-platform"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountEmailLabel" />
<Label
Grid.Row="0"
Text="{Binding AccountView.Email}"
IsVisible="{Binding IsActive, Converter={StaticResource inverseBool}}"
StyleClass="accountlist-title, accountlist-title-platform"
TextColor="{DynamicResource MutedColor}"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountEmailLabel" />
<Label
Grid.Row="1"
IsVisible="{Binding ShowHostname}"
Text="{Binding AccountView.Hostname}"
StyleClass="accountlist-sub, accountlist-sub-platform"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountHostUrlLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountUnlocked}"
@@ -81,7 +84,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountLocked}"
@@ -89,7 +93,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountLoggedOut}"
@@ -97,7 +102,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
</Grid>
<controls:IconLabel
@@ -107,7 +113,8 @@
Margin="12,0"
HorizontalOptions="Center"
VerticalOptions="Center"
StyleClass="list-icon, list-icon-platform" />
StyleClass="list-icon, list-icon-platform"
AutomationId="InactiveVaultIcon" />
<controls:IconLabel
Grid.Column="2"
Text="{Binding AuthStatusIconActive}"
@@ -116,7 +123,8 @@
HorizontalOptions="Center"
VerticalOptions="Center"
StyleClass="list-icon, list-icon-platform"
TextColor="{DynamicResource TextColor}"/>
TextColor="{DynamicResource TextColor}"
AutomationId="ActiveVaultIcon" />
</Grid>
<Grid
@@ -147,7 +155,8 @@
StyleClass="accountlist-title, accountlist-title-platform"
LineBreakMode="TailTruncation"
VerticalOptions="Center"
Grid.Column="1" />
Grid.Column="1"
AutomationId="AddAccountButton" />
</Grid>
</Grid>
</ViewCell>

View File

@@ -1,6 +1,7 @@
using System.Windows.Input;
using Bit.Core.Models.View;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<controls:ExtendedGrid xmlns="http://xamarin.com/schemas/2014/forms"
<controls:ExtendedGrid xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Controls.AuthenticatorViewCell"
xmlns:controls="clr-namespace:Bit.App.Controls"

View File

@@ -3,7 +3,8 @@ using Bit.App.Pages;
using Bit.App.Utilities;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -5,7 +5,8 @@ using System.Threading;
using System.Threading.Tasks;
using Bit.Core.Utilities;
using SkiaSharp;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -160,7 +161,7 @@ namespace Bit.App.Controls
{
if (str == null)
{
return Color.FromHex("#33ffffff");
return Color.FromArgb("#33ffffff");
}
var hash = 0;
for (var i = 0; i < str.Length; i++)
@@ -174,7 +175,7 @@ namespace Bit.App.Controls
var base16 = "00" + Convert.ToString(value, 16);
color += base16.Substring(base16.Length - 2);
}
return Color.FromHex(color);
return Color.FromArgb(color);
}
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<controls:ExtendedGrid xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="UTF-8"?>
<controls:ExtendedGrid xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Controls.CipherViewCell"
xmlns:controls="clr-namespace:Bit.App.Controls"
@@ -9,7 +9,8 @@
StyleClass="list-row, list-row-platform"
RowSpacing="0"
ColumnSpacing="0"
x:DataType="controls:CipherViewCellViewModel">
x:DataType="controls:CipherViewCellViewModel"
AutomationId="CipherCell">
<Grid.Resources>
<u:IconGlyphConverter x:Key="iconGlyphConverter"/>
@@ -36,7 +37,8 @@
IsVisible="{Binding ShowIconImage, Converter={StaticResource inverseBool}}"
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
ShouldUpdateFontSizeDynamicallyForAccesibility="True"
AutomationProperties.IsInAccessibleTree="False" />
AutomationProperties.IsInAccessibleTree="False"
AutomationId="CipherTypeIcon" />
<ff:CachedImage
x:Name="_iconImage"
@@ -52,7 +54,8 @@
Aspect="AspectFit"
IsVisible="{Binding ShowIconImage}"
Source="{Binding IconImageSource, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="False" />
AutomationProperties.IsInAccessibleTree="False"
AutomationId="CipherWebsiteIcon" />
<Grid RowSpacing="0" ColumnSpacing="0" Grid.Row="0" Grid.Column="1" VerticalOptions="Center" Padding="0, 7">
<Grid.RowDefinitions>
@@ -71,7 +74,8 @@
Grid.Column="0"
Grid.Row="0"
StyleClass="list-title, list-title-platform"
Text="{Binding Cipher.Name}" />
Text="{Binding Cipher.Name}"
AutomationId="CipherNameLabel" />
<Label
LineBreakMode="TailTruncation"
Grid.Column="0"
@@ -80,7 +84,8 @@
StyleClass="list-subtitle, list-subtitle-platform"
Text="{Binding Cipher.SubTitle}"
IsVisible="{Binding Source={RelativeSource Self}, Path=Text,
Converter={StaticResource stringHasValueConverter}}"/>
Converter={StaticResource stringHasValueConverter}}"
AutomationId="CipherSubTitleLabel" />
<controls:IconLabel
Grid.Column="1"
Grid.Row="0"
@@ -91,7 +96,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Collection}}"
IsVisible="{Binding Cipher.Shared, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Shared}" />
AutomationProperties.Name="{u:I18n Shared}"
AutomationId="CipherInCollectionIcon" />
<controls:IconLabel
Grid.Column="2"
Grid.Row="0"
@@ -102,7 +108,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Paperclip}}"
IsVisible="{Binding Cipher.HasAttachments, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Attachments}" />
AutomationProperties.Name="{u:I18n Attachments}"
AutomationId="CipherWithAttachmentsIcon" />
</Grid>
<controls:MiButton
@@ -114,6 +121,7 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="EndAndExpand"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="CipherOptionsButton" />
</controls:ExtendedGrid>

View File

@@ -3,7 +3,8 @@ using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -31,7 +31,7 @@ namespace Bit.App.Controls
public bool ShowIconImage
{
get => WebsiteIconsEnabled
&& !string.IsNullOrWhiteSpace(Cipher.Login?.Uri)
&& !string.IsNullOrWhiteSpace(Cipher.LaunchUri)
&& IconImageSource != null;
}
@@ -41,7 +41,7 @@ namespace Bit.App.Controls
{
if (_iconImageSource == string.Empty) // default value since icon source can return null
{
_iconImageSource = IconImageHelper.GetLoginIconImage(Cipher);
_iconImageSource = IconImageHelper.GetIconImage(Cipher);
}
return _iconImageSource;
}

View File

@@ -1,9 +1,11 @@
using System;
using System.Runtime.CompilerServices;
using SkiaSharp;
using SkiaSharp.Views.Forms;
using Xamarin.Essentials;
using Xamarin.Forms;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
using SkiaSharp.Views.Maui.Controls;
using SkiaSharp.Views.Maui;
namespace Bit.App.Controls
{
@@ -21,13 +23,13 @@ namespace Bit.App.Controls
nameof(StrokeWidth), typeof(float), typeof(CircularProgressbarView), 3f);
public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create(
nameof(ProgressColor), typeof(Color), typeof(CircularProgressbarView), Color.FromHex("175DDC"));
nameof(ProgressColor), typeof(Color), typeof(CircularProgressbarView), Color.FromArgb("175DDC"));
public static readonly BindableProperty EndingProgressColorProperty = BindableProperty.Create(
nameof(EndingProgressColor), typeof(Color), typeof(CircularProgressbarView), Color.FromHex("dd4b39"));
nameof(EndingProgressColor), typeof(Color), typeof(CircularProgressbarView), Color.FromArgb("dd4b39"));
public static readonly BindableProperty BackgroundProgressColorProperty = BindableProperty.Create(
nameof(BackgroundProgressColor), typeof(Color), typeof(CircularProgressbarView), Color.White);
nameof(BackgroundProgressColor), typeof(Color), typeof(CircularProgressbarView), Colors.White);
public double Progress
{

View File

@@ -0,0 +1,14 @@
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
public class CustomLabel : Label
{
public CustomLabel()
{
}
public int? FontWeight { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<Grid
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:Bit.App.Controls"
x:Class="Bit.App.Controls.DateTimePicker"

View File

@@ -1,6 +1,12 @@
using System.Runtime.CompilerServices;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
using CommunityToolkit.Maui.Converters;
using CommunityToolkit.Maui.ImageSources;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Layouts;
using CommunityToolkit.Maui.Views;
namespace Bit.App.Controls
{

View File

@@ -1,6 +1,7 @@
using System.Linq;
using Xamarin.CommunityToolkit.Converters;
using Xamarin.Forms;
using CommunityToolkit.Maui.Converters;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,7 @@
using Bit.App.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -7,6 +9,7 @@ namespace Bit.App.Controls
{
public ExtendedSearchBar()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.iOS)
{
if (ThemeManager.UsingLightTheme)

View File

@@ -1,11 +1,12 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
public class ExtendedSlider : Slider
{
public static readonly BindableProperty ThumbBorderColorProperty = BindableProperty.Create(
nameof(ThumbBorderColor), typeof(Color), typeof(ExtendedSlider), Color.FromHex("b5b5b5"));
nameof(ThumbBorderColor), typeof(Color), typeof(ExtendedSlider), Color.FromArgb("b5b5b5"));
public Color ThumbBorderColor
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,14 +1,16 @@
using Xamarin.Forms;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
public class ExtendedStepper : Stepper
{
public static readonly BindableProperty StepperBackgroundColorProperty = BindableProperty.Create(
nameof(StepperBackgroundColor), typeof(Color), typeof(ExtendedStepper), Color.White);
nameof(StepperBackgroundColor), typeof(Color), typeof(ExtendedStepper), Colors.White);
public static readonly BindableProperty StepperForegroundColorProperty = BindableProperty.Create(
nameof(StepperForegroundColor), typeof(Color), typeof(ExtendedStepper), Color.Black);
nameof(StepperForegroundColor), typeof(Color), typeof(ExtendedStepper), Colors.Black);
public Color StepperBackgroundColor
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,6 @@
using Bit.App.Effects;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -8,6 +9,7 @@ namespace Bit.App.Controls
public IconButton()
{
Padding = 0;
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,5 +1,6 @@
using Bit.App.Effects;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -9,6 +10,7 @@ namespace Bit.App.Controls
public IconLabel()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Controls.IconLabelButton"
xmlns:controls="clr-namespace:Bit.App.Controls"

View File

@@ -5,8 +5,10 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.Core.Models.Domain;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Microsoft.Maui.Controls.Xaml;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -22,13 +24,13 @@ namespace Bit.App.Controls
nameof(ButtonCommand), typeof(ICommand), typeof(IconLabelButton));
public static readonly BindableProperty IconLabelColorProperty = BindableProperty.Create(
nameof(IconLabelColor), typeof(Color), typeof(IconLabelButton), Color.White);
nameof(IconLabelColor), typeof(Color), typeof(IconLabelButton), Colors.White);
public static readonly BindableProperty IconLabelBackgroundColorProperty = BindableProperty.Create(
nameof(IconLabelBackgroundColor), typeof(Color), typeof(IconLabelButton), Color.White);
nameof(IconLabelBackgroundColor), typeof(Color), typeof(IconLabelButton), Colors.White);
public static readonly BindableProperty IconLabelBorderColorProperty = BindableProperty.Create(
nameof(IconLabelBorderColor), typeof(Color), typeof(IconLabelButton), Color.White);
nameof(IconLabelBorderColor), typeof(Color), typeof(IconLabelButton), Colors.White);
public IconLabelButton()
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -7,6 +8,7 @@ namespace Bit.App.Controls
public MiButton()
{
Padding = 0;
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -6,6 +7,7 @@ namespace Bit.App.Controls
{
public MiLabel()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -6,6 +7,7 @@ namespace Bit.App.Controls
{
public MonoEntry()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -6,6 +7,7 @@ namespace Bit.App.Controls
{
public MonoLabel()
{
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
switch (Device.RuntimePlatform)
{
case Device.iOS:

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<StackLayout
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:u="clr-namespace:Bit.App.Utilities"

View File

@@ -1,5 +1,7 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{
@@ -100,7 +102,7 @@ namespace Bit.App.Controls
case Controls.PasswordStrengthLevel.Strong:
return StrongColor;
default:
return Color.Transparent;
return Colors.Transparent;
}
}
}

View File

@@ -1,7 +1,8 @@
using System.Collections.Generic;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,7 +1,8 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<controls:ExtendedGrid xmlns="http://xamarin.com/schemas/2014/forms"
<controls:ExtendedGrid xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Controls.SendViewCell"
xmlns:controls="clr-namespace:Bit.App.Controls"
@@ -54,14 +54,16 @@
Grid.Column="0"
Grid.Row="0"
StyleClass="list-title, list-title-platform"
Text="{Binding Send.Name}" />
Text="{Binding Send.Name}"
AutomationId="SendNameLabel" />
<Label
LineBreakMode="TailTruncation"
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="6"
StyleClass="list-subtitle, list-subtitle-platform"
Text="{Binding Send.DisplayDate}" />
Text="{Binding Send.DisplayDate}"
AutomationId="SendDateLabel" />
<controls:IconLabel
Grid.Column="1"
Grid.Row="0"
@@ -72,7 +74,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.ExclamationTriangle}}"
IsVisible="{Binding Send.Disabled, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Disabled}" />
AutomationProperties.Name="{u:I18n Disabled}"
AutomationId="DisabledSendLabel" />
<controls:IconLabel
Grid.Column="2"
Grid.Row="0"
@@ -83,7 +86,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Key}}"
IsVisible="{Binding Send.HasPassword, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Password}" />
AutomationProperties.Name="{u:I18n Password}"
AutomationId="PasswordProtectedSendLabel" />
<controls:IconLabel
Grid.Column="3"
Grid.Row="0"
@@ -94,7 +98,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Ban}}"
IsVisible="{Binding Send.MaxAccessCountReached, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n MaxAccessCountReached}" />
AutomationProperties.Name="{u:I18n MaxAccessCountReached}"
AutomationId="SendMaxAccessCountReachedLabel" />
<controls:IconLabel
Grid.Column="4"
Grid.Row="0"
@@ -105,7 +110,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Clock}}"
IsVisible="{Binding Send.Expired, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Expired}" />
AutomationProperties.Name="{u:I18n Expired}"
AutomationId="ExpiredSendLabel" />
<controls:IconLabel
Grid.Column="5"
Grid.Row="0"
@@ -116,7 +122,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
IsVisible="{Binding Send.PendingDelete, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n PendingDelete}" />
AutomationProperties.Name="{u:I18n PendingDelete}"
AutomationId="SendWithPendingDeletionLabel" />
</Grid>
<controls:MiButton
@@ -129,6 +136,7 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="EndAndExpand"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="SendOptionsButton" />
</controls:ExtendedGrid>

View File

@@ -2,7 +2,8 @@
using Bit.App.Abstractions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Controls
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Effects
{

View File

@@ -1,5 +1,6 @@
using Bit.App.Lists.ItemViewModels.CustomFields;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.DataTemplateSelectors
{

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<StackLayout
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Lists.ItemLayouts.CustomFields.BooleanCustomFieldItemLayout"
xmlns:u="clr-namespace:Bit.App.Utilities"
@@ -33,7 +33,8 @@
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="BooleanCustomFieldNameLabel" />
<Label
Text="{Binding Field.Name, Mode=OneWay}"
IsVisible="{Binding IsEditing}"
@@ -49,13 +50,15 @@
Grid.Row="1"
Grid.Column="0"
Margin="0, 5, 0, 0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="BooleanCustomFieldValueLabel" />
<Switch
IsToggled="{Binding BooleanValue}"
IsVisible="{Binding IsEditing}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2" />
Grid.RowSpan="2"
AutomationId="BooleanCustomFieldValueToggle" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Cog}}"

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemLayouts.CustomFields
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Lists.ItemLayouts.CustomFields.HiddenCustomFieldItemLayout"
xmlns:controls="clr-namespace:Bit.App.Controls"
@@ -31,7 +31,8 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="HiddenCustomFieldNameLabel" />
<StackLayout
Grid.Row="1"
Grid.Column="0"
@@ -39,7 +40,8 @@
<controls:MonoLabel
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
IsVisible="{Binding ShowHiddenValue}" />
IsVisible="{Binding ShowHiddenValue}"
AutomationId="HiddenCustomFieldValueLabel" />
<controls:MonoLabel
Text="{Binding Field.MaskedValue, Mode=OneWay}"
StyleClass="box-value"
@@ -54,7 +56,10 @@
IsPassword="{Binding ShowHiddenValue, Converter={StaticResource inverseBool}}"
IsEnabled="{Binding ShowViewHidden}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False">
IsTextPredictionEnabled="False"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{Binding Field.Name}"
AutomationId="HiddenCustomFieldValueEntry">
<Entry.Keyboard>
<Keyboard x:FactoryMethod="Create">
<x:Arguments>
@@ -72,7 +77,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="HiddenCustomFieldShowValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemLayouts.CustomFields
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Lists.ItemLayouts.CustomFields.LinkedCustomFieldItemLayout"
xmlns:controls="clr-namespace:Bit.App.Controls"
@@ -29,13 +29,15 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="LinkedCustomFieldNameLabel" />
<controls:IconLabel
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="LinkedCustomFieldValueLabel" />
<StackLayout
StyleClass="box-row, box-row-input"
IsVisible="{Binding IsEditing}">
@@ -44,7 +46,8 @@
ItemsSource="{Binding LinkedFieldOptions, Mode=OneTime}"
SelectedIndex="{Binding LinkedFieldOptionSelectedIndex}"
ItemDisplayBinding="{Binding Key}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="LinkedCustomFieldValuePicker" />
</StackLayout>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
@@ -55,7 +58,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="LinkedCustomFieldOptionsButton" />
</Grid>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
</StackLayout>

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemLayouts.CustomFields
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Lists.ItemLayouts.CustomFields.TextCustomFieldItemLayout"
xmlns:controls="clr-namespace:Bit.App.Controls"
@@ -29,19 +29,24 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="TextCustomFieldNameLabel" />
<Label
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="TextCustomFieldValueLabel" />
<Entry
Text="{Binding Field.Value}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing}" />
IsVisible="{Binding IsEditing}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{Binding Field.Name}"
AutomationId="TextCustomFieldValueEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -51,7 +56,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Copy}" />
AutomationProperties.Name="{u:I18n Copy}"
AutomationId="TextCustomFieldCopyValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Cog}}"
@@ -61,7 +67,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="TextCustomFieldOptionsButton" />
</Grid>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
</StackLayout>

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemLayouts.CustomFields
{

View File

@@ -1,7 +1,8 @@
using System.Windows.Input;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemViewModels.CustomFields
{

View File

@@ -5,7 +5,8 @@ using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Models.View;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemViewModels.CustomFields
{

View File

@@ -1,6 +1,7 @@
using System.Windows.Input;
using Bit.Core.Models.View;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Lists.ItemViewModels.CustomFields
{

View File

@@ -6,7 +6,6 @@ using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Xamarin.Essentials;
namespace Bit.App.Pages
{

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.Accounts.DeleteAccountPage"
xmlns:pages="clr-namespace:Bit.App.Pages"

View File

@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages.Accounts
{

View File

@@ -27,7 +27,7 @@ namespace Bit.App.Pages
{
try
{
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
if (Microsoft.Maui.Networking.Connectivity.NetworkAccess == Microsoft.Maui.Networking.NetworkAccess.None)
{
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
AppResources.InternetConnectionRequiredTitle, AppResources.Ok);

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.EnvironmentPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
@@ -34,7 +34,8 @@
Placeholder="ex. https://bitwarden.company.com"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="ServerUrlEntry"/>
</StackLayout>
<Label
Text="{u:I18n SelfHostedEnvironmentFooter}"
@@ -53,7 +54,8 @@
x:Name="_webVaultEntry"
Text="{Binding WebVaultUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="WebVaultUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -63,7 +65,8 @@
x:Name="_apiEntry"
Text="{Binding ApiUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ApiUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -73,7 +76,8 @@
x:Name="_identityEntry"
Text="{Binding IdentityUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -85,7 +89,8 @@
Keyboard="Url"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="IconsUrlEntry"/>
</StackLayout>
<Label
Text="{u:I18n CustomEnvironmentFooter}"

View File

@@ -3,7 +3,8 @@ using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages
{
@@ -18,6 +19,7 @@ namespace Bit.App.Pages
InitializeComponent();
_vm = BindingContext as EnvironmentPageViewModel;
_vm.Page = this;
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android)
{
ToolbarItems.RemoveAt(0);

View File

@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
@@ -18,7 +19,8 @@ namespace Bit.App.Pages
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
PageTitle = AppResources.Settings;
BaseUrl = _environmentService.BaseUrl;
BaseUrl = _environmentService.BaseUrl == EnvironmentUrlData.DefaultEU.Base || EnvironmentUrlData.DefaultUS.Base == _environmentService.BaseUrl ?
string.Empty : _environmentService.BaseUrl;
WebVaultUrl = _environmentService.WebVaultUrl;
ApiUrl = _environmentService.ApiUrl;
IdentityUrl = _environmentService.IdentityUrl;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.HintPage"
xmlns:pages="clr-namespace:Bit.App.Pages"

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages
{
@@ -12,6 +13,7 @@ namespace Bit.App.Pages
_vm = BindingContext as HintPageViewModel;
_vm.Page = this;
_vm.Email = email;
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.Android)
{
ToolbarItems.RemoveAt(0);

View File

@@ -44,7 +44,7 @@ namespace Bit.App.Pages
public async Task SubmitAsync()
{
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
if (Microsoft.Maui.Networking.Connectivity.NetworkAccess == Microsoft.Maui.Networking.NetworkAccess.None)
{
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
AppResources.InternetConnectionRequiredTitle);

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.HomePage"
xmlns:pages="clr-namespace:Bit.App.Pages"
@@ -23,12 +23,9 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
<ToolbarItem x:Name="_closeButton" Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"/>
<ToolbarItem
Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -53,7 +50,9 @@
Keyboard="Email"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding ContinueCommand}">
ReturnCommand="{Binding ContinueCommand}"
AutomationId="EmailAddressEntry"
>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
@@ -66,7 +65,28 @@
</Entry>
<StackLayout
Orientation="Horizontal"
Margin="0, 16, 0 ,0">
Margin="0, 6, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ShowEnvironmentPickerCommand}" />
</StackLayout.GestureRecognizers>
<Label
Text="{Binding RegionText}"
FontSize="13"
TextColor="{DynamicResource MutedColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
<controls:IconLabel
Text="{Binding SelectedEnvironmentName}"
FontSize="13"
TextColor="{DynamicResource PrimaryColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"
AutomationId="RegionSelectorDropdown"/>
</StackLayout>
<StackLayout
Orientation="Horizontal"
Margin="0, 20, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding RememberEmailCommand}" />
@@ -76,21 +96,27 @@
StyleClass="text-sm"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
VerticalTextAlignment="Center"
/>
<Switch
Scale="0.8"
IsToggled="{Binding RememberEmail}"
VerticalOptions="Center"/>
VerticalOptions="Center"
AutomationId="RememberMeSwitch"
/>
</StackLayout>
</StackLayout>
<Button Text="{u:I18n Continue}"
StyleClass="btn-primary"
IsEnabled="{Binding CanContinue}"
Command="{Binding ContinueCommand}" />
Command="{Binding ContinueCommand}"
AutomationId="ContinueButton"
/>
<Label FormattedText="{Binding CreateAccountText}"
Margin="0, 10"
StyleClass="box-footer-label">
StyleClass="box-footer-label"
AutomationId="CreateAccountLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CreateAccountCommand}" />
</Label.GestureRecognizers>
@@ -116,5 +142,4 @@
MainPage="{Binding Source={x:Reference _page}}"
BindingContext="{Binding AccountSwitchingOverlayViewModel}"/>
</AbsoluteLayout>
</pages:BaseContentPage>

View File

@@ -4,7 +4,8 @@ using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages
{
@@ -15,6 +16,8 @@ namespace Bit.App.Pages
private readonly AppOptions _appOptions;
private IBroadcasterService _broadcasterService;
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
public HomePage(AppOptions appOptions = null)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
@@ -70,6 +73,14 @@ namespace Bit.App.Pages
});
}
});
try
{
await _vm.UpdateEnvironment();
}
catch (Exception ex)
{
_logger.Value?.Exception(ex);
}
}
protected override bool OnBackButtonPressed()
@@ -128,14 +139,6 @@ namespace Bit.App.Pages
await Navigation.PushModalAsync(new NavigationPage(page));
}
private void Environment_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.StartEnvironmentAction();
}
}
private async Task StartEnvironmentAsync()
{
await _accountListOverlay.HideAsync();

View File

@@ -4,12 +4,15 @@ using Bit.App.Abstractions;
using Bit.App.Controls;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Models.Data;
using Bit.Core.Models.Response;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Essentials;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages
{
@@ -17,16 +20,19 @@ namespace Bit.App.Pages
{
private readonly IStateService _stateService;
private readonly IMessagingService _messagingService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly ILogger _logger;
private readonly IEnvironmentService _environmentService;
private readonly IAccountsManager _accountManager;
private readonly IConfigService _configService;
private bool _showCancelButton;
private bool _rememberEmail;
private string _email;
private string _selectedEnvironmentName;
private bool _isEmailEnabled;
private bool _canLogin;
private IPlatformUtilsService _platformUtilsService;
private ILogger _logger;
private IEnvironmentService _environmentService;
private IAccountsManager _accountManager;
private bool _displayEuEnvironment;
public HomeViewModel()
{
@@ -36,6 +42,7 @@ namespace Bit.App.Pages
_logger = ServiceContainer.Resolve<ILogger>();
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
_configService = ServiceContainer.Resolve<IConfigService>();
PageTitle = AppResources.Bitwarden;
@@ -45,9 +52,11 @@ namespace Bit.App.Pages
};
RememberEmailCommand = new Command(() => RememberEmail = !RememberEmail);
ContinueCommand = new AsyncCommand(ContinueToLoginStepAsync, allowsMultipleExecutions: false);
CreateAccountCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(StartRegisterAction),
CreateAccountCommand = new AsyncCommand(async () => Device.InvokeOnMainThreadAsync(StartRegisterAction),
onException: _logger.Exception, allowsMultipleExecutions: false);
CloseCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(CloseAction),
CloseCommand = new AsyncCommand(async () => Device.InvokeOnMainThreadAsync(CloseAction),
onException: _logger.Exception, allowsMultipleExecutions: false);
ShowEnvironmentPickerCommand = new AsyncCommand(ShowEnvironmentPickerAsync,
onException: _logger.Exception, allowsMultipleExecutions: false);
InitAsync().FireAndForget();
}
@@ -71,6 +80,13 @@ namespace Bit.App.Pages
additionalPropertyNames: new[] { nameof(CanContinue) });
}
public string SelectedEnvironmentName
{
get => $"{_selectedEnvironmentName} {BitwardenIcons.AngleDown}";
set => SetProperty(ref _selectedEnvironmentName, value);
}
public string RegionText => $"{AppResources.Region}:";
public bool CanContinue => !string.IsNullOrEmpty(Email);
public FormattedString CreateAccountText
@@ -101,11 +117,13 @@ namespace Bit.App.Pages
public AsyncCommand ContinueCommand { get; }
public AsyncCommand CloseCommand { get; }
public AsyncCommand CreateAccountCommand { get; }
public AsyncCommand ShowEnvironmentPickerCommand { get; }
public async Task InitAsync()
{
Email = await _stateService.GetRememberedEmailAsync();
RememberEmail = !string.IsNullOrEmpty(Email);
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag, forceRefresh: true);
}
public async Task ContinueToLoginStepAsync()
@@ -144,5 +162,59 @@ namespace Bit.App.Pages
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage, AppResources.AnErrorHasOccurred, AppResources.Ok);
}
}
public async Task ShowEnvironmentPickerAsync()
{
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag);
var options = _displayEuEnvironment
? new string[] { AppResources.US, AppResources.EU, AppResources.SelfHosted }
: new string[] { AppResources.US, AppResources.SelfHosted };
await Device.InvokeOnMainThreadAsync(async () =>
{
var result = await Page.DisplayActionSheet(AppResources.DataRegion, AppResources.Cancel, null, options);
if (result is null || result == AppResources.Cancel)
{
return;
}
if (result == AppResources.SelfHosted)
{
StartEnvironmentAction?.Invoke();
return;
}
await _environmentService.SetUrlsAsync(result == AppResources.EU ? EnvironmentUrlData.DefaultEU : EnvironmentUrlData.DefaultUS);
await _configService.GetAsync(true);
SelectedEnvironmentName = result;
});
}
public async Task UpdateEnvironment()
{
var environmentsSaved = await _stateService.GetPreAuthEnvironmentUrlsAsync();
if (environmentsSaved == null || environmentsSaved.IsEmpty)
{
await _environmentService.SetUrlsAsync(EnvironmentUrlData.DefaultUS);
environmentsSaved = EnvironmentUrlData.DefaultUS;
SelectedEnvironmentName = AppResources.US;
return;
}
if (environmentsSaved.Base == EnvironmentUrlData.DefaultUS.Base)
{
SelectedEnvironmentName = AppResources.US;
}
else if (environmentsSaved.Base == EnvironmentUrlData.DefaultEU.Base)
{
SelectedEnvironmentName = AppResources.EU;
}
else
{
await _configService.GetAsync(true);
SelectedEnvironmentName = AppResources.SelfHosted;
}
}
}
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.LockPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
@@ -24,7 +24,8 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -71,7 +72,8 @@
Grid.Row="1"
Grid.Column="0"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="PinEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -81,7 +83,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="PinVisibilityToggle" />
</Grid>
<Grid
x:Name="_passwordGrid"
@@ -111,7 +114,8 @@
Grid.Row="1"
Grid.Column="0"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="MasterPasswordEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -121,7 +125,9 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}" />
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="PasswordVisibilityToggle"
/>
</Grid>
<StackLayout
StyleClass="box-row"
@@ -147,7 +153,8 @@
x:Name="_unlockButton"
Text="{u:I18n Unlock}"
StyleClass="btn-primary"
Clicked="Unlock_Clicked" />
Clicked="Unlock_Clicked"
AutomationId="UnlockVaultButton" />
</StackLayout>
</StackLayout>
</ScrollView>

View File

@@ -6,7 +6,8 @@ using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Microsoft.Maui.Controls;
using Microsoft.Maui;
namespace Bit.App.Pages
{
@@ -30,6 +31,7 @@ namespace Bit.App.Pages
_vm.Page = this;
_vm.UnlockedAction = () => Device.BeginInvokeOnMainThread(async () => await UnlockedAsync());
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
if (Device.RuntimePlatform == Device.iOS)
{
ToolbarItems.Add(_moreItem);

Some files were not shown because too many files have changed in this diff Show More