mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
Compare commits
340 Commits
vault/pm-5
...
temp-passk
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3568a5bb7 | ||
|
|
25f63ec4e0 | ||
|
|
c11df272be | ||
|
|
a4adcdcfd4 | ||
|
|
c801b2fc3a | ||
|
|
41161864db | ||
|
|
a1c9ebf01f | ||
|
|
7381d5278a | ||
|
|
8b5a7b257d | ||
|
|
62e0626648 | ||
|
|
d339514d9a | ||
|
|
75ec96f282 | ||
|
|
96a9978ef8 | ||
|
|
1ae388cb03 | ||
|
|
c6aaf5002f | ||
|
|
75be6504e1 | ||
|
|
cae1825e3f | ||
|
|
c23100d281 | ||
|
|
c9c0d0b4d6 | ||
|
|
fec0743e4d | ||
|
|
118dcf164c | ||
|
|
bd03b6b5aa | ||
|
|
333917c00d | ||
|
|
450101d9e4 | ||
|
|
3c848a3dcc | ||
|
|
18beb4e5f4 | ||
|
|
4e50f1697d | ||
|
|
3c96ae2220 | ||
|
|
fdbd16a6fd | ||
|
|
39a34bd8c4 | ||
|
|
e9d1792dd7 | ||
|
|
8f8a5795d3 | ||
|
|
4631a9e62c | ||
|
|
51ee6a84b5 | ||
|
|
b8c5ef501a | ||
|
|
2075f8168c | ||
|
|
0f5df0f6b0 | ||
|
|
ad8faec200 | ||
|
|
3223ceb9a8 | ||
|
|
f30158adf5 | ||
|
|
8d5006c0bd | ||
|
|
37208571fe | ||
|
|
7469dad35a | ||
|
|
759627b3c7 | ||
|
|
eae84ded42 | ||
|
|
563210a74e | ||
|
|
08fac4752f | ||
|
|
70db27b750 | ||
|
|
00cff182b4 | ||
|
|
dc5e90436b | ||
|
|
9307e7e0d8 | ||
|
|
b1a0801f9b | ||
|
|
04cc53b934 | ||
|
|
c138658a31 | ||
|
|
c6a086fe62 | ||
|
|
b217451ea9 | ||
|
|
8cb7d5e1a3 | ||
|
|
82b837ef33 | ||
|
|
f1854f2c04 | ||
|
|
e4056d9ee6 | ||
|
|
eb95a54db2 | ||
|
|
7ddea4c70b | ||
|
|
3804e86995 | ||
|
|
b787a6c840 | ||
|
|
a6c4bc9273 | ||
|
|
b23bed182f | ||
|
|
f8e421871b | ||
|
|
4988dbea72 | ||
|
|
ca250c53ad | ||
|
|
ebb2a288a1 | ||
|
|
6bb724ff06 | ||
|
|
f3c64a89eb | ||
|
|
aa71ebc634 | ||
|
|
d0bb7f0a54 | ||
|
|
de7ae27a77 | ||
|
|
d0103496b9 | ||
|
|
cd8952221e | ||
|
|
155c7539bd | ||
|
|
d3dd2e9342 | ||
|
|
5f43681fb1 | ||
|
|
d2965e6e10 | ||
|
|
ec1ade7761 | ||
|
|
f35bef0d7b | ||
|
|
a5878d3341 | ||
|
|
1dc55f78e7 | ||
|
|
37b62b317f | ||
|
|
528e412458 | ||
|
|
5d5d113369 | ||
|
|
7ca9e61e93 | ||
|
|
0f22f2750e | ||
|
|
da7326b0cc | ||
|
|
7bbb711175 | ||
|
|
138d37cf5e | ||
|
|
c87728027e | ||
|
|
fc2fed079f | ||
|
|
9c441a98f4 | ||
|
|
fd80a9ce7c | ||
|
|
e1908d8eef | ||
|
|
8be604feac | ||
|
|
c90ed74faa | ||
|
|
1491872b62 | ||
|
|
c74636ffa5 | ||
|
|
05677f93c5 | ||
|
|
0aef241df6 | ||
|
|
32c43afae2 | ||
|
|
44b2443554 | ||
|
|
3f10a6be24 | ||
|
|
f3537b1a74 | ||
|
|
849a0c24b0 | ||
|
|
e0b58461b5 | ||
|
|
cd33c7f608 | ||
|
|
f0dde7eb82 | ||
|
|
f6a58e469f | ||
|
|
19639b61c3 | ||
|
|
9d29af36e5 | ||
|
|
4472d7f9a8 | ||
|
|
999579915c | ||
|
|
63904fd303 | ||
|
|
983937c9eb | ||
|
|
ce550fee74 | ||
|
|
f0841eb8b2 | ||
|
|
b23d58c0b1 | ||
|
|
2cb6872e4e | ||
|
|
f539bf051d | ||
|
|
14f845d623 | ||
|
|
b2f93d3d4b | ||
|
|
133a80acef | ||
|
|
e8f6c37c06 | ||
|
|
b43790de9a | ||
|
|
d0e0f0ecdb | ||
|
|
64c694e593 | ||
|
|
56b9e3f615 | ||
|
|
7558f60a44 | ||
|
|
0bdd63df06 | ||
|
|
c6544b49e9 | ||
|
|
8e1a8b5f0e | ||
|
|
4717f5e230 | ||
|
|
ad80defa40 | ||
|
|
0dc281edc1 | ||
|
|
378551e2d5 | ||
|
|
dbe4110027 | ||
|
|
a08466d220 | ||
|
|
e66ac9dd44 | ||
|
|
66a01e30d3 | ||
|
|
01ee1ff845 | ||
|
|
75b4655f38 | ||
|
|
9b2f596d15 | ||
|
|
cc89b6a5d5 | ||
|
|
32c2f2aac4 | ||
|
|
f9b4e30b0b | ||
|
|
55fb71744d | ||
|
|
ee252be634 | ||
|
|
66f0471f2e | ||
|
|
6b9eeba88d | ||
|
|
0a1fbfafb5 | ||
|
|
d6c139cb8a | ||
|
|
0a5d772886 | ||
|
|
6b7c6eac71 | ||
|
|
70c8a264d2 | ||
|
|
b5fbb2cade | ||
|
|
9027755b71 | ||
|
|
6d625f285b | ||
|
|
822ad7564e | ||
|
|
1949a450fd | ||
|
|
27fa79e0bd | ||
|
|
9e1d6c7b03 | ||
|
|
1e29eacc61 | ||
|
|
b81d26d589 | ||
|
|
cd107b6161 | ||
|
|
7ac3646fb0 | ||
|
|
d1e4e8645a | ||
|
|
e107b893ea | ||
|
|
5de02c863f | ||
|
|
0e95d4d4ca | ||
|
|
36a648e53e | ||
|
|
6c04ac67b1 | ||
|
|
a42b88b666 | ||
|
|
dfb7a0621f | ||
|
|
1eb9e5f8ea | ||
|
|
b149e7549c | ||
|
|
e3877cc589 | ||
|
|
275ae76761 | ||
|
|
a1e4f0aaa2 | ||
|
|
adaef0d15b | ||
|
|
af6866cee1 | ||
|
|
0cec49f121 | ||
|
|
d091922017 | ||
|
|
fa4a2247e3 | ||
|
|
5d2fc4530f | ||
|
|
9b64af3423 | ||
|
|
b6ff6e34f6 | ||
|
|
6d4c706026 | ||
|
|
14fd026ea0 | ||
|
|
a4392a8730 | ||
|
|
1b885ea438 | ||
|
|
fa022a1a4f | ||
|
|
6011b63958 | ||
|
|
7d79b98bf2 | ||
|
|
d4e75e9de8 | ||
|
|
c3370b58ec | ||
|
|
3de13325c9 | ||
|
|
c253c110c1 | ||
|
|
bf35d1f2dc | ||
|
|
05b6aa90b6 | ||
|
|
e39898bba6 | ||
|
|
da0866cc85 | ||
|
|
b3140381ab | ||
|
|
c01a8f8d93 | ||
|
|
8484b4af30 | ||
|
|
6b9faed45f | ||
|
|
770a1c5dfe | ||
|
|
3c87d4db1c | ||
|
|
8b3c6ab35f | ||
|
|
90912977c4 | ||
|
|
740b368b8c | ||
|
|
3a40a4cda8 | ||
|
|
9bcd2e51f7 | ||
|
|
741214a1cc | ||
|
|
aad87dfdce | ||
|
|
8fc1e9a3b9 | ||
|
|
2a8e15146e | ||
|
|
8559d5908e | ||
|
|
f60c4d94fe | ||
|
|
05858bea48 | ||
|
|
5cbef47fd4 | ||
|
|
4bf695d18c | ||
|
|
c24e0dfa28 | ||
|
|
9ccd0834ff | ||
|
|
a806f17d3b | ||
|
|
436a162df2 | ||
|
|
f2c298607e | ||
|
|
b5dbb9ae5e | ||
|
|
7a5f7c0274 | ||
|
|
17acb57732 | ||
|
|
5803635f44 | ||
|
|
19c393842f | ||
|
|
15a306490d | ||
|
|
a4a3d31c19 | ||
|
|
922dc683af | ||
|
|
bae1b3e891 | ||
|
|
a5888827c9 | ||
|
|
0348940a12 | ||
|
|
4c2998337d | ||
|
|
7ea86380f4 | ||
|
|
406f4425c8 | ||
|
|
95ca911444 | ||
|
|
fa62510e09 | ||
|
|
65dc73495d | ||
|
|
02a2e41118 | ||
|
|
bd6f8295e7 | ||
|
|
0a0cb7093b | ||
|
|
465e5eff76 | ||
|
|
5b756aaf7a | ||
|
|
d168a7b750 | ||
|
|
7f4bbafe3c | ||
|
|
a5804df6a3 | ||
|
|
bfa2a51608 | ||
|
|
32be08daae | ||
|
|
0a628cc8a8 | ||
|
|
80c424ed03 | ||
|
|
99fb5463cf | ||
|
|
c5d941e1df | ||
|
|
3edfef6169 | ||
|
|
1c8742511a | ||
|
|
8e424d6c05 | ||
|
|
390c303b90 | ||
|
|
443f7282b8 | ||
|
|
50109ee70b | ||
|
|
9ffdfd51cc | ||
|
|
04e409f3c6 | ||
|
|
6c143bad57 | ||
|
|
286e18059a | ||
|
|
553bf9ed0a | ||
|
|
ddb27b52d3 | ||
|
|
6c504aa710 | ||
|
|
62254aef8d | ||
|
|
06a0195a6d | ||
|
|
df2b0b21d5 | ||
|
|
e6b1bab860 | ||
|
|
ce41eb0578 | ||
|
|
1a0b52d644 | ||
|
|
16ada4993c | ||
|
|
3795f3aa17 | ||
|
|
eceb506c77 | ||
|
|
2c7870d660 | ||
|
|
f02b3415a3 | ||
|
|
beda4e9ff8 | ||
|
|
df4d89cd52 | ||
|
|
5f12bb9747 | ||
|
|
5712639492 | ||
|
|
e0a3c301fb | ||
|
|
27306fe353 | ||
|
|
a31f15559f | ||
|
|
0e75f3f5c8 | ||
|
|
363da063fa | ||
|
|
974a571455 | ||
|
|
e0c721098c | ||
|
|
a86f6e3034 | ||
|
|
fe17288b99 | ||
|
|
7324da9d47 | ||
|
|
69aa6fc044 | ||
|
|
e840dc2e30 | ||
|
|
eb25ee5d1b | ||
|
|
840f24dbe5 | ||
|
|
c6309173ba | ||
|
|
946c465f0c | ||
|
|
e90409d842 | ||
|
|
484b5a5160 | ||
|
|
2688209752 | ||
|
|
53e0e55915 | ||
|
|
ca57948d9f | ||
|
|
aaf082faba | ||
|
|
e7aeb08cae | ||
|
|
f177968958 | ||
|
|
f1d59210f9 | ||
|
|
62213c0aaf | ||
|
|
8be8abb8fe | ||
|
|
174acbc558 | ||
|
|
4bcc7c0d71 | ||
|
|
14b2960f30 | ||
|
|
455c3a257c | ||
|
|
8c623a2067 | ||
|
|
3cdf1c2f0e | ||
|
|
ce9503fa0c | ||
|
|
2e4da1b87d | ||
|
|
d63a219272 | ||
|
|
c92cd90a97 | ||
|
|
1dcd3a3daa | ||
|
|
efb8763d3c | ||
|
|
90649d1c8b | ||
|
|
828055791f | ||
|
|
87eebda55f | ||
|
|
7542d1ae1c | ||
|
|
990de4ea4e | ||
|
|
0dbc23f734 | ||
|
|
9f6c8601d3 | ||
|
|
8b7f9b9fb3 | ||
|
|
d17789d5ee | ||
|
|
b8f0747dd4 | ||
|
|
8ef9443b1e |
19
.github/CODEOWNERS
vendored
19
.github/CODEOWNERS
vendored
@@ -1,12 +1,21 @@
|
||||
# Please sort lines alphabetically, this will ensure we don't accidentally add duplicates.
|
||||
# Please sort into logical groups with comment headers. Sort groups in order of specificity.
|
||||
# For example, default owners should always be the first group.
|
||||
# Sort lines alphabetically within these groups to avoid accidentally adding duplicates.
|
||||
#
|
||||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
|
||||
# The following owners will be the default owners for everything in the repo.
|
||||
# Unless a later match takes precedence
|
||||
# @bitwarden/tech-leads
|
||||
# Default file owners
|
||||
* @bitwarden/dept-development-mobile
|
||||
|
||||
@bitwarden/dept-development-mobile
|
||||
# DevOps for Actions and other workflow changes
|
||||
.github/workflows @bitwarden/dept-devops
|
||||
|
||||
# DevOps for Version Bumping
|
||||
src/App/Platforms/Android/AndroidManifest.xml
|
||||
src/iOS.Autofill/Info.plist
|
||||
src/iOS.Extension/Info.plist
|
||||
src/iOS.ShareExtension/Info.plist
|
||||
src/App/Platforms/iOS/Info.plist
|
||||
|
||||
## Auth team files ##
|
||||
|
||||
|
||||
17
.github/renovate.json
vendored
17
.github/renovate.json
vendored
@@ -2,22 +2,21 @@
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base",
|
||||
"github>bitwarden/renovate-config:pin-actions",
|
||||
":combinePatchMinorReleases",
|
||||
":dependencyDashboard",
|
||||
":maintainLockFilesWeekly",
|
||||
":pinAllExceptPeerDependencies",
|
||||
":prConcurrentLimit10",
|
||||
":rebaseStalePrs",
|
||||
"schedule:weekends",
|
||||
":separateMajorReleases"
|
||||
":separateMajorReleases",
|
||||
"group:monorepos",
|
||||
"schedule:weekends"
|
||||
],
|
||||
"enabledManagers": ["cargo", "github-actions", "npm", "nuget"],
|
||||
"enabledManagers": ["github-actions", "npm", "nuget"],
|
||||
"commitMessagePrefix": "[deps]:",
|
||||
"commitMessageTopic": "{{depName}}",
|
||||
"packageRules": [
|
||||
{
|
||||
"groupName": "cargo minor",
|
||||
"matchManagers": ["cargo"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
},
|
||||
{
|
||||
"groupName": "gh minor",
|
||||
"matchManagers": ["github-actions"],
|
||||
@@ -32,6 +31,6 @@
|
||||
"groupName": "nuget minor",
|
||||
"matchManagers": ["nuget"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
268
.github/workflows/build.yml
vendored
268
.github/workflows/build.yml
vendored
@@ -10,6 +10,11 @@ on:
|
||||
- ".github/workflows/**"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
main_app_folder_path: src/App
|
||||
main_app_project_path: src/App/App.csproj
|
||||
target-net-version: net8.0
|
||||
|
||||
jobs:
|
||||
cloc:
|
||||
name: CLOC
|
||||
@@ -26,7 +31,6 @@ jobs:
|
||||
- name: Print lines of code
|
||||
run: cloc --vcs git --exclude-dir Resources,store,test,Properties --include-lang C#,XAML
|
||||
|
||||
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -54,7 +58,6 @@ jobs:
|
||||
echo "hotfix_branch_exists=0" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
|
||||
android:
|
||||
name: Android
|
||||
runs-on: windows-2022
|
||||
@@ -63,19 +66,26 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant: ["prod", "qa"]
|
||||
env:
|
||||
android_folder_path: src/App/Platforms/Android
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
nuget-version: 6.4.0
|
||||
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
|
||||
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
|
||||
with:
|
||||
dotnet-version: '3.1.x'
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
|
||||
uses: microsoft/setup-msbuild@ede762b26a2de8d110bb5a3db4d7e0e080c0e917 # v1.3.3
|
||||
|
||||
# This step might be obsolete at some point as .NET MAUI workloads
|
||||
# are starting to come pre-installed on the GH Actions build agents.
|
||||
- name: Install MAUI Workload
|
||||
run: dotnet workload install maui --ignore-failed-sources
|
||||
|
||||
- name: Setup Windows builder
|
||||
run: choco install checksum --no-progress
|
||||
@@ -106,9 +116,9 @@ jobs:
|
||||
mkdir -p ~/secrets
|
||||
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
|
||||
--output ./${{ env.main_app_folder_path }}/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
|
||||
--output ./${{ env.main_app_folder_path }}/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
|
||||
shell: bash
|
||||
@@ -119,7 +129,7 @@ jobs:
|
||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||
run: |
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
|
||||
--output ./${{ env.android_folder_path }}/google-services.json ./.github/secrets/google-services.json.gpg
|
||||
shell: bash
|
||||
|
||||
- name: Increment version
|
||||
@@ -129,9 +139,9 @@ jobs:
|
||||
echo "########################################"
|
||||
echo "##### Setting Version Code $BUILD_NUMBER"
|
||||
echo "########################################"
|
||||
|
||||
|
||||
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
||||
./src/Android/Properties/AndroidManifest.xml
|
||||
./${{ env.android_folder_path }}/AndroidManifest.xml
|
||||
shell: bash
|
||||
|
||||
- name: Restore packages
|
||||
@@ -140,14 +150,14 @@ jobs:
|
||||
- name: Restore tools
|
||||
run: dotnet tool restore
|
||||
|
||||
- name: Verify Format
|
||||
run: dotnet tool run dotnet-format --check
|
||||
# - name: Verify Format
|
||||
# run: dotnet tool run dotnet-format --check
|
||||
|
||||
- name: Run Core tests
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx"
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" /p:CustomConstants=UT
|
||||
|
||||
- name: Report test results
|
||||
uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226 # v1.6.0
|
||||
uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
|
||||
if: always()
|
||||
with:
|
||||
name: Test Results
|
||||
@@ -165,18 +175,20 @@ jobs:
|
||||
- name: Build Android
|
||||
run: |
|
||||
$configuration = "Release";
|
||||
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Build $configuration Configuration"
|
||||
Write-Output "########################################"
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
|
||||
|
||||
dotnet build $projToBuild -c $configuration -f ${{ env.target-net-version }}-android
|
||||
|
||||
- name: Sign Android Build
|
||||
env:
|
||||
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
|
||||
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
|
||||
$packageName = "com.x8bit.bitwarden";
|
||||
|
||||
if ("${{ matrix.variant }}" -ne "prod")
|
||||
@@ -187,16 +199,13 @@ jobs:
|
||||
Write-Output "##### Sign Google Play Bundle Release Configuration"
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" `
|
||||
"/p:AndroidSigningKeyAlias=upload" "/p:AndroidSigningKeyPass=$($env:UPLOAD_KEYSTORE_PASSWORD)" `
|
||||
"/p:AndroidSigningKeyStore=$("app_upload-keystore.jks")" `
|
||||
"/p:AndroidSigningStorePass=$($env:UPLOAD_KEYSTORE_PASSWORD)" "/p:AndroidPackageFormat=aab" "/v:quiet"
|
||||
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidPackageFormats=aab /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_upload-keystore.jks") /p:AndroidSigningKeyAlias=upload /p:AndroidSigningKeyPass="$($env:UPLOAD_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:UPLOAD_KEYSTORE_PASSWORD)" --no-restore
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Copy Google Play Bundle to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.aab");
|
||||
$signedAabPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.aab");
|
||||
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).aab");
|
||||
Copy-Item $signedAabPath $signedAabDestPath
|
||||
|
||||
@@ -204,23 +213,20 @@ jobs:
|
||||
Write-Output "##### Sign APK Release Configuration"
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" `
|
||||
"/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:PLAY_KEYSTORE_PASSWORD)" `
|
||||
"/p:AndroidSigningKeyStore=$("app_play-keystore.jks")" `
|
||||
"/p:AndroidSigningStorePass=$($env:PLAY_KEYSTORE_PASSWORD)" "/v:quiet"
|
||||
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_play-keystore.jks") /p:AndroidSigningKeyAlias=bitwarden /p:AndroidSigningKeyPass="$($env:PLAY_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:PLAY_KEYSTORE_PASSWORD)" --no-restore
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Copy Release APK to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.apk");
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
|
||||
- name: Upload Prod .aab artifact
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: com.x8bit.bitwarden.aab
|
||||
path: ./com.x8bit.bitwarden.aab
|
||||
@@ -228,7 +234,7 @@ jobs:
|
||||
|
||||
- name: Upload Prod .apk artifact
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: com.x8bit.bitwarden.apk
|
||||
path: ./com.x8bit.bitwarden.apk
|
||||
@@ -236,7 +242,7 @@ jobs:
|
||||
|
||||
- name: Upload Other .apk artifact
|
||||
if: ${{ matrix.variant != 'prod' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
@@ -256,7 +262,7 @@ jobs:
|
||||
|
||||
- name: Upload .apk sha file for prod
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: bw-android-apk-sha256.txt
|
||||
path: ./bw-android-apk-sha256.txt
|
||||
@@ -264,7 +270,7 @@ jobs:
|
||||
|
||||
- name: Upload .apk sha file for other
|
||||
if: ${{ matrix.variant != 'prod' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
|
||||
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
|
||||
@@ -277,7 +283,7 @@ jobs:
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc' ) }}
|
||||
run: |
|
||||
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
|
||||
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/net7.0/Publisher.dll"
|
||||
CREDS_PATH="$HOME/secrets/play_creds.json"
|
||||
AAB_PATH="$GITHUB_WORKSPACE/com.x8bit.bitwarden.aab"
|
||||
TRACK="internal"
|
||||
@@ -289,14 +295,27 @@ jobs:
|
||||
f-droid:
|
||||
name: F-Droid Build
|
||||
runs-on: windows-2022
|
||||
env:
|
||||
android_folder_path: src/App/Platforms/Android
|
||||
android_manifest_path: src/App/Platforms/Android/AndroidManifest.xml
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
nuget-version: 6.4.0
|
||||
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
|
||||
uses: microsoft/setup-msbuild@ede762b26a2de8d110bb5a3db4d7e0e080c0e917 # v1.3.3
|
||||
|
||||
# This step might be obsolete at some point as .NET MAUI workloads
|
||||
# are starting to come pre-installed on the GH Actions build agents.
|
||||
- name: Install MAUI Workload
|
||||
run: dotnet workload install maui --ignore-failed-sources
|
||||
|
||||
- name: Setup Windows builder
|
||||
run: choco install checksum --no-progress
|
||||
@@ -325,7 +344,7 @@ jobs:
|
||||
mkdir -p ~/secrets
|
||||
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/app_fdroid-keystore.jks ./.github/secrets/app_fdroid-keystore.jks.gpg
|
||||
--output ./${{ env.main_app_folder_path }}/app_fdroid-keystore.jks ./.github/secrets/app_fdroid-keystore.jks.gpg
|
||||
shell: bash
|
||||
|
||||
- name: Increment version
|
||||
@@ -337,30 +356,21 @@ jobs:
|
||||
echo "########################################"
|
||||
|
||||
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
||||
./src/Android/Properties/AndroidManifest.xml
|
||||
./${{ env.android_manifest_path }}
|
||||
shell: bash
|
||||
|
||||
- name: Clean for F-Droid
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
$appPath = $($env:GITHUB_WORKSPACE + "/src/App/App.csproj");
|
||||
$appPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
|
||||
$corePath = $($env:GITHUB_WORKSPACE + "/src/Core/Core.csproj");
|
||||
|
||||
$androidManifest = $($env:GITHUB_WORKSPACE + "/src/Android/Properties/AndroidManifest.xml");
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Clean Android and App"
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($androidPath)" "/t:Clean" "/p:Configuration=FDroid"
|
||||
msbuild "$($appPath)" "/t:Clean" "/p:Configuration=FDroid"
|
||||
$androidManifest = $($env:GITHUB_WORKSPACE + "/${{ env.android_manifest_path }}");
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Backup project files"
|
||||
Write-Output "########################################"
|
||||
|
||||
Copy-Item $androidManifest $($androidManifest + ".original");
|
||||
Copy-Item $androidPath $($androidPath + ".original");
|
||||
Copy-Item $appPath $($appPath + ".original");
|
||||
|
||||
Write-Output "########################################"
|
||||
@@ -375,80 +385,44 @@ jobs:
|
||||
|
||||
$xml.Save($androidManifest);
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Uninstall from Android.csproj"
|
||||
Write-Output "########################################"
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($androidPath);
|
||||
|
||||
$ns=New-Object System.Xml.XmlNamespaceManager($xml.NameTable);
|
||||
$ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI);
|
||||
|
||||
$firebaseNode=$xml.SelectSingleNode(`
|
||||
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Firebase.Messaging']", $ns);
|
||||
$firebaseNode.ParentNode.RemoveChild($firebaseNode);
|
||||
|
||||
$daggerNode=$xml.SelectSingleNode(`
|
||||
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Google.Dagger']", $ns);
|
||||
$daggerNode.ParentNode.RemoveChild($daggerNode);
|
||||
|
||||
$safetyNetNode=$xml.SelectSingleNode(`
|
||||
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.GooglePlayServices.SafetyNet']", $ns);
|
||||
$safetyNetNode.ParentNode.RemoveChild($safetyNetNode);
|
||||
|
||||
$xml.Save($androidPath);
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Uninstall from Core.csproj"
|
||||
Write-Output "########################################"
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($corePath);
|
||||
|
||||
$appCenterNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='Microsoft.AppCenter.Crashes']");
|
||||
$appCenterNode.ParentNode.RemoveChild($appCenterNode);
|
||||
|
||||
$xml.Save($corePath);
|
||||
|
||||
- name: Restore packages
|
||||
run: nuget restore
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build for F-Droid
|
||||
run: |
|
||||
$configuration = "FDroid";
|
||||
$configuration = "Release";
|
||||
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Build $configuration Configuration"
|
||||
Write-Output "##### Build $configuration FDROID
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
|
||||
|
||||
dotnet build $projToBuild -c $configuration -f ${{ env.target-net-version }}-android /p:CustomConstants="FDROID"
|
||||
|
||||
- name: Sign for F-Droid
|
||||
env:
|
||||
FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
|
||||
$packageName = "com.x8bit.bitwarden";
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Sign FDroid Configuration"
|
||||
Write-Output "##### Sign FDroid"
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" `
|
||||
"/t:SignAndroidPackage" "/p:Configuration=FDroid" "/p:AndroidKeyStore=true" `
|
||||
"/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:FDROID_KEYSTORE_PASSWORD)" `
|
||||
"/p:AndroidSigningKeyStore=$("app_fdroid-keystore.jks")" `
|
||||
"/p:AndroidSigningStorePass=$($env:FDROID_KEYSTORE_PASSWORD)" "/v:quiet"
|
||||
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_fdroid-keystore.jks") /p:AndroidSigningKeyAlias=bitwarden /p:AndroidSigningKeyPass="$($env:FDROID_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:FDROID_KEYSTORE_PASSWORD)" /p:CustomConstants="FDROID" --no-restore
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Copy FDroid apk to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/FDroid/com.x8bit.bitwarden-Signed.apk");
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden-fdroid.apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
|
||||
- name: Upload F-Droid .apk artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
path: ./com.x8bit.bitwarden-fdroid.apk
|
||||
@@ -460,27 +434,44 @@ jobs:
|
||||
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt
|
||||
|
||||
- name: Upload F-Droid sha file
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: bw-fdroid-apk-sha256.txt
|
||||
path: ./bw-fdroid-apk-sha256.txt
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
ios:
|
||||
name: Apple iOS
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
needs: setup
|
||||
env:
|
||||
ios_folder_path: src/App/Platforms/iOS
|
||||
app_output_name: App
|
||||
app_ci_output_filename: App_x64_Debug
|
||||
steps:
|
||||
- name: Set XCode version
|
||||
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
|
||||
with:
|
||||
xcode-version: 15.1
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
nuget-version: 6.4.0
|
||||
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
# This step might be obsolete at some point as .NET MAUI workloads
|
||||
# are starting to come pre-installed on the GH Actions build agents.
|
||||
- name: Install MAUI Workload
|
||||
run: dotnet workload install maui --ignore-failed-sources
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
nuget help | grep Version
|
||||
msbuild -version
|
||||
dotnet --info
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
@@ -491,7 +482,7 @@ jobs:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
@@ -538,7 +529,9 @@ jobs:
|
||||
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
|
||||
echo "########################################"
|
||||
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS/Info.plist
|
||||
echo "### CFBundleVersion $BUILD_NUMBER" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./${{ env.ios_folder_path }}/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Extension/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.ShareExtension/Info.plist
|
||||
@@ -551,8 +544,8 @@ jobs:
|
||||
echo "##### Updating Entitlements"
|
||||
echo "########################################"
|
||||
|
||||
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./src/iOS/Entitlements.plist
|
||||
|
||||
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./${{ env.ios_folder_path }}/Entitlements.plist
|
||||
|
||||
- name: Set up Keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
|
||||
@@ -599,6 +592,9 @@ jobs:
|
||||
WATCH_APP_EXTENSION_UUID=$(grep UUID -A1 -a $WATCH_APP_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $WATCH_APP_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$WATCH_APP_EXTENSION_UUID.mobileprovision"
|
||||
|
||||
- name: Restore packages
|
||||
run: dotnet restore
|
||||
|
||||
- name: Bulid WatchApp
|
||||
run: |
|
||||
echo "########################################"
|
||||
@@ -611,19 +607,13 @@ jobs:
|
||||
echo "##### Done"
|
||||
echo "########################################"
|
||||
|
||||
- name: Restore packages
|
||||
run: nuget restore
|
||||
|
||||
- name: Archive Build for App Store
|
||||
run: |
|
||||
$configuration = "AppStore";
|
||||
$platform = "iPhone";
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Archive for Release ios-arm64
|
||||
Write-Output "########################################"
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Archive $configuration Configuration for $platform Platform"
|
||||
Write-Output "########################################"
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/iOS/iOS.csproj")" "/p:Platform=$platform" `
|
||||
"/p:Configuration=$configuration" "/p:ArchiveOnBuild=true" "/t:`"Build`""
|
||||
dotnet publish ${{ env.main_app_project_path }} -c Release -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=ios-arm64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Done"
|
||||
@@ -632,14 +622,11 @@ jobs:
|
||||
|
||||
- name: Archive Build for Mobile Automation
|
||||
run: |
|
||||
$configuration = "Release";
|
||||
$platform = "iPhoneSimulator";
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Archive Debug for iossimulator-x64
|
||||
Write-Output "########################################"
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Archive $configuration Configuration for $platform Platform"
|
||||
Write-Output "########################################"
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/iOS/iOS.csproj")" "/p:Platform=$platform" `
|
||||
"/p:Configuration=$configuration" "/p:ArchiveOnBuild=true" "/t:`"Build`""
|
||||
dotnet build ${{ env.main_app_project_path }} -c Debug -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=iossimulator-x64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Done"
|
||||
@@ -658,11 +645,11 @@ jobs:
|
||||
|
||||
- name: Export .app for Automation CI
|
||||
run: |
|
||||
ARCHIVE_PATH="./src/iOS/bin/iPhoneSimulator/Release/BitwardeniOS.app"
|
||||
ARCHIVE_PATH="./${{ env.main_app_folder_path }}/bin/Debug/${{ env.target-net-version }}-ios/iossimulator-x64"
|
||||
EXPORT_PATH="./bitwarden-export"
|
||||
|
||||
zip -r -q BitwardeniOS.app.zip $ARCHIVE_PATH
|
||||
mv BitwardeniOS.app.zip $EXPORT_PATH
|
||||
zip -r -q ${{ env.app_ci_output_filename }}.app.zip $ARCHIVE_PATH
|
||||
mv ${{ env.app_ci_output_filename }}.app.zip $EXPORT_PATH
|
||||
|
||||
- name: Copy all dSYMs files to upload
|
||||
run: |
|
||||
@@ -677,7 +664,7 @@ jobs:
|
||||
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
|
||||
|
||||
- name: Upload App Store .ipa & dSYMs artifacts
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: Bitwarden iOS
|
||||
path: |
|
||||
@@ -686,10 +673,10 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload .app file for Automation CI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: BitwardeniOS.app.zip
|
||||
path: ./bitwarden-export/BitwardeniOS.app.zip
|
||||
name: ${{ env.app_ci_output_filename }}.app.zip
|
||||
path: ./bitwarden-export/${{ env.app_ci_output_filename }}.app.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Install AppCenter CLI
|
||||
@@ -726,6 +713,21 @@ jobs:
|
||||
|
||||
find "$HOME/Library/Developer/XCode/DerivedData" -name "upload-symbols" -exec chmod +x {} \; -exec {} -gsp "./src/watchOS/bitwarden/GoogleService-Info.plist" -p ios "./bitwarden-export/Watch_dSYMs" \;
|
||||
|
||||
- name: Validate app in App Store
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
run: |
|
||||
xcrun altool --validate-app --type ios --file "./bitwarden-export/Bitwarden.ipa" \
|
||||
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD"
|
||||
shell: bash
|
||||
|
||||
- name: Deploy to App Store
|
||||
if: |
|
||||
(github.ref == 'refs/heads/main'
|
||||
@@ -756,7 +758,7 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
@@ -768,7 +770,7 @@ jobs:
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
|
||||
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
@@ -815,7 +817,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
if: failure()
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
6
.github/workflows/crowdin-pull.yml
vendored
6
.github/workflows/crowdin-pull.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
||||
_CROWDIN_PROJECT_ID: "269690"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
@@ -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@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
|
||||
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
|
||||
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Check Release Version
|
||||
id: version
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
|
||||
- name: Create GitHub deployment
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
|
||||
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
|
||||
- name: Download all artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
|
||||
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.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@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
|
||||
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||
with:
|
||||
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
||||
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
|
||||
@@ -126,11 +126,11 @@ jobs:
|
||||
if: inputs.fdroid_publish
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Download F-Droid .apk artifact
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
|
||||
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.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@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
|
||||
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
|
||||
|
||||
2
.github/workflows/stale-bot.yml
vendored
2
.github/workflows/stale-bot.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: 'Run stale action'
|
||||
uses: actions/stale@f7176fd3007623b69d27091f9b9d4ab7995f0a06 # v5.2.1
|
||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
with:
|
||||
stale-issue-label: 'needs-reply'
|
||||
stale-pr-label: 'needs-changes'
|
||||
|
||||
37
.github/workflows/version-auto-bump.yml
vendored
37
.github/workflows/version-auto-bump.yml
vendored
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: Version Auto Bump
|
||||
name: Auto Bump Mobile Version
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,14 +7,12 @@ on:
|
||||
- v**
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: "Setup"
|
||||
bump-version:
|
||||
name: Bump Mobile Version
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version_number: ${{ steps.version.outputs.new-version }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Calculate bumped version
|
||||
id: version
|
||||
@@ -29,12 +27,23 @@ jobs:
|
||||
NEW_PATCH=$((CURR_PATCH+1))
|
||||
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
||||
echo "New Version: $NEW_VER"
|
||||
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
|
||||
echo "new_version=$NEW_VER" >> $GITHUB_OUTPUT
|
||||
|
||||
trigger_version_bump:
|
||||
name: Bump version to ${{ needs.setup.outputs.version_number }}
|
||||
needs: setup
|
||||
uses: ./.github/workflows/version-bump.yml
|
||||
with:
|
||||
version_number: ${{ needs.setup.outputs.version_number }}
|
||||
secrets: inherit
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve bot secrets
|
||||
id: retrieve-bot-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: bitwarden-ci
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: "Bump version to ${{ steps.version.outputs.new_version }}"
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
run: |
|
||||
echo '{"cut_rc_branch": "false", "version_number": "${{ steps.version.outputs.new_version }}"}' | \
|
||||
gh workflow run version-bump.yml --json --repo bitwarden/mobile
|
||||
49
.github/workflows/version-bump.yml
vendored
49
.github/workflows/version-bump.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
@@ -33,13 +33,22 @@ jobs:
|
||||
github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: main
|
||||
repository: bitwarden/mobile
|
||||
|
||||
- name: Check if RC branch exists
|
||||
if: ${{ inputs.cut_rc_branch == true }}
|
||||
run: |
|
||||
remote_rc_branch_check=$(git ls-remote --heads origin rc | wc -l)
|
||||
if [[ "${remote_rc_branch_check}" -gt 0 ]]; then
|
||||
echo "Remote RC branch exists."
|
||||
echo "Please delete current RC branch before running again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@d6f3f49f3345e29369fe57596a3ca8f94c4d2ca7 # v5.4.0
|
||||
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
|
||||
with:
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
@@ -63,7 +72,7 @@ jobs:
|
||||
CURRENT_VERSION=$(xmllint --xpath '
|
||||
string(/manifest/@*[local-name()="versionName"
|
||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||
' src/Android/Properties/AndroidManifest.xml)
|
||||
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||
|
||||
# Error if version has not changed.
|
||||
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
|
||||
@@ -84,7 +93,7 @@ jobs:
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ inputs.version_number }}
|
||||
file_path: "src/Android/Properties/AndroidManifest.xml"
|
||||
file_path: "src/App/Platforms/Android/AndroidManifest.xml"
|
||||
|
||||
- name: Bump Version - iOS.Autofill
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
@@ -108,7 +117,7 @@ jobs:
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ inputs.version_number }}
|
||||
file_path: "src/iOS/Info.plist"
|
||||
file_path: "src/App/Platforms/iOS/Info.plist"
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
@@ -182,15 +191,27 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- name: Install xmllint
|
||||
run: sudo apt install -y libxml2-utils
|
||||
|
||||
- name: Check if RC branch exists
|
||||
- name: Verify version has been updated
|
||||
env:
|
||||
NEW_VERSION: ${{ inputs.version_number }}
|
||||
run: |
|
||||
remote_rc_branch_check=$(git ls-remote --heads origin rc | wc -l)
|
||||
if [[ "${remote_rc_branch_check}" -gt 0 ]]; then
|
||||
echo "Remote RC branch exists."
|
||||
echo "Please delete current RC branch before running again."
|
||||
exit 1
|
||||
fi
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(xmllint --xpath '
|
||||
string(/manifest/@*[local-name()="versionName"
|
||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: Cut RC branch
|
||||
run: |
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -31,6 +31,7 @@ Components/
|
||||
x64/
|
||||
x86/
|
||||
!src/lib/x86/
|
||||
!src/App/Platforms/Android/lib/x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
@@ -147,6 +148,7 @@ publish/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
!**/Xamarin.AndroidX.Credentials.1.0.0.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
|
||||
13
Directory.Build.props
Normal file
13
Directory.Build.props
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<MauiVersion>8.0.7-nightly.*</MauiVersion>
|
||||
<ReleaseCodesignProvision>Automatic:AppStore</ReleaseCodesignProvision>
|
||||
<ReleaseCodesignKey>iPhone Distribution</ReleaseCodesignKey>
|
||||
<IncludeBitwardeniOSExtensions>True</IncludeBitwardeniOSExtensions>
|
||||
<IncludeBitwardenWatchOSApp>True</IncludeBitwardenWatchOSApp>
|
||||
<Argon2IdLoadMtouchExtraArgs>-gcc_flags "-L$(ProjectDir)../../lib/ios -largon2 -force_load $(ProjectDir)../../lib/ios/libargon2.a"</Argon2IdLoadMtouchExtraArgs>
|
||||
|
||||
<!-- Uncomment this when Unit Testing-->
|
||||
<!-- <CustomConstants>UT</CustomConstants> -->
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
[](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:master)
|
||||
[](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:main)
|
||||
[](https://crowdin.com/project/bitwarden-mobile)
|
||||
[](https://gitter.im/bitwarden/Lobby)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<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.
|
||||
The Bitwarden mobile application is written in C# using .NET MAUI.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android-myvault.png" alt="" width="325" height="650" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios-myvault.png" alt="" width="300" height="650" />
|
||||
|
||||
@@ -20,6 +20,6 @@ Interested in contributing in a big way? Consider joining our team! We're hiring
|
||||
|
||||
# Contribute
|
||||
|
||||
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
|
||||
Code contributions are welcome! Please commit any pull requests against the `main` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
|
||||
|
||||
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
|
||||
|
||||
@@ -1,471 +1,233 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29009.5
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34112.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App", "src\App\App.csproj", "{971FDF07-E288-4239-B47A-E9E7E912193B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\Core\Core.csproj", "{4B8A8C41-9820-4341-974C-41E65B7F4366}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Playground", "test\Playground\Playground.csproj", "{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D10CA4A9-F866-40E1-B658-F69051236C71}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8904C536-C67D-420F-9971-51B26574C3AA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "store", "store", "{92470CBD-9047-4C3C-8EA3-D972D6622D84}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E399654-26A2-46F6-B9CA-1B496A3F370A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{76690DFB-B7F4-4781-83E4-113FDC450AFE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
.github\workflows\build.yml = .github\workflows\build.yml
|
||||
CONTRIBUTING.md = CONTRIBUTING.md
|
||||
crowdin.yml = crowdin.yml
|
||||
README.md = README.md
|
||||
SECURITY.md = SECURITY.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{599E0201-420A-4C3E-A7BA-5349F72E0B15}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Extension\iOS.Extension.csproj", "{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\iOS.ShareExtension\iOS.ShareExtension.csproj", "{F8C3F648-EA5A-4719-8005-85D1690B1655}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{83449CC4-1F76-4CFE-92B1-D2E13A62506F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||
AppStore|Any CPU = AppStore|Any CPU
|
||||
AppStore|iPhone = AppStore|iPhone
|
||||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|iPhone = Debug|iPhone
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
FDroid|Any CPU = FDroid|Any CPU
|
||||
FDroid|iPhone = FDroid|iPhone
|
||||
FDroid|iPhoneSimulator = FDroid|iPhoneSimulator
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|iPhone = Release|iPhone
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||
Debug|iPhone = Debug|iPhone
|
||||
Release|iPhone = Release|iPhone
|
||||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||
AppStore|iPhone = AppStore|iPhone
|
||||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||
FDroid|Any CPU = FDroid|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = AppStore|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = AppStore|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|Any CPU.ActiveCfg = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.ActiveCfg = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.Build.0 = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.Build.0 = FDroid|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.Build.0 = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.Build.0 = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{2E399654-26A2-46F6-B9CA-1B496A3F370A} = {92470CBD-9047-4C3C-8EA3-D972D6622D84}
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}
|
||||
SolutionGuid = {3B3A9B6C-D325-4BB3-97D3-8070630C5D3B}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$1.DirectoryNamespaceAssociation = PrefixedHierarchical
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6} = {BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44} = {BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
44
build.cake
44
build.cake
@@ -67,7 +67,7 @@ Task("UpdateAndroidManifest")
|
||||
.Does(()=>
|
||||
{
|
||||
var buildVariant = GetVariant();
|
||||
var manifestPath = Path.Combine(_slnPath, "src", "Android", "Properties", "AndroidManifest.xml");
|
||||
var manifestPath = Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "AndroidManifest.xml");
|
||||
|
||||
// Cake.AndroidAppManifest doesn't currently enable us to access nested items so, quick (not ideal) fix:
|
||||
var manifestText = FileReadText(manifestPath);
|
||||
@@ -119,26 +119,26 @@ Task("UpdateAndroidCodeFiles")
|
||||
//We're not using _androidPackageName here because the codefile is currently slightly different string than the one in AndroidManifest.xml
|
||||
var keyName = "com.8bit.bitwarden";
|
||||
var fixedPackageName = buildVariant.AndroidPackageName.Replace("x8bit", "8bit");
|
||||
var filePath = Path.Combine(_slnPath, "src", "Android", "Services", "BiometricService.cs");
|
||||
var filePath = Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "BiometricService.cs");
|
||||
ReplaceInFile(filePath, keyName, fixedPackageName);
|
||||
|
||||
var packageFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "MainActivity.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "MainApplication.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Constants.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Services", "DeviceActionService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Services", "FileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "AutofillTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "google-services.json"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "MainActivity.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "MainApplication.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Constants.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "DeviceActionService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "FileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "AutofillTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "google-services.json"),
|
||||
Path.Combine(_slnPath, "store", "google", "Publisher", "Program.cs"),
|
||||
};
|
||||
|
||||
@@ -148,7 +148,7 @@ Task("UpdateAndroidCodeFiles")
|
||||
}
|
||||
|
||||
var labelFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillService.cs"),
|
||||
};
|
||||
|
||||
foreach(string path in labelFileList)
|
||||
@@ -315,7 +315,7 @@ private void UpdateAppleIcons(string target, string appiconsetTarget)
|
||||
|
||||
Task("UpdateiOSIcons")
|
||||
.Does(()=>{
|
||||
UpdateAppleIcons("ios", Path.Combine(_slnPath, "src", "iOS", "Resources", "Assets.xcassets", "AppIcons.appiconset"));
|
||||
UpdateAppleIcons("ios", Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Resources", "Assets.xcassets", "AppIcons.appiconset"));
|
||||
UpdateAppleIcons("watch", Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden WatchKit App", "Assets.xcassets", "AppIcon.appiconset"));
|
||||
// TODO: Update complication icons when they start working
|
||||
});
|
||||
@@ -324,8 +324,8 @@ Task("UpdateiOSPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS", "Entitlements.plist");
|
||||
var infoPath = Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.MainApp);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@ project_id_env: _CROWDIN_PROJECT_ID
|
||||
api_token_env: CROWDIN_API_TOKEN
|
||||
preserve_hierarchy: true
|
||||
files:
|
||||
- source: /src/App/Resources/AppResources.resx
|
||||
dest: /src/App/Resources/%original_file_name%
|
||||
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
|
||||
- source: /src/Core/Resources/Localization/AppResources.resx
|
||||
dest: /src/Core/Resources/Localization/%original_file_name%
|
||||
translation: /src/Core/Resources/Localization/AppResources.%two_letters_code%.resx
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.400",
|
||||
"rollForward": "latestPatch",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Xamarin.AndroidX.Credentials</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
Binary file not shown.
7
nuget.config
Normal file
7
nuget.config
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="MAUI Nightly builds" value="https://pkgs.dev.azure.com/xamarin/public/_packaging/maui-nightly/nuget/v3/index.json" />
|
||||
<add key="Local AndroidX Credentials" value="lib/android/Xamarin.AndroidX.Credentials" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -8,7 +8,7 @@
|
||||
"name": "bitwarden-mobile",
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"gh-pages": "^3.2.3"
|
||||
"gh-pages": "3.2.3"
|
||||
}
|
||||
},
|
||||
"node_modules/array-union": {
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"clean:l10n": "git push origin --delete l10n_master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gh-pages": "^3.2.3"
|
||||
"gh-pages": "3.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TemplateGuid>{c9e5eea5-ca05-42a1-839b-61506e0a37df}</TemplateGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Bit.Droid</RootNamespace>
|
||||
<AssemblyName>BitwardenAndroid</AssemblyName>
|
||||
<AndroidApplication>True</AndroidApplication>
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<AndroidSupportedAbis />
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidManagedSymbols>true</AndroidManagedSymbols>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FDroid|AnyCPU'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<OutputPath>bin\FDroid\</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<DefineConstants>FDROID</DefineConstants>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="Mono.Android.Export" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Net.Http" Condition="'$(Configuration)'=='FDroid'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Plugin.CurrentActivity">
|
||||
<Version>2.1.0.4</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Portable.BouncyCastle">
|
||||
<Version>1.9.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.6.1.3" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.18" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.21" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.10.1.2" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.4.0.2" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.8.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>123.1.2.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.9.0.2" />
|
||||
<PackageReference Include="Xamarin.Google.Dagger" Version="2.46.1.2" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
|
||||
<Version>118.0.1.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Accessibility\AccessibilityActivity.cs" />
|
||||
<Compile Include="Accessibility\AccessibilityHelpers.cs" />
|
||||
<Compile Include="Accessibility\Credentials.cs" />
|
||||
<Compile Include="Accessibility\AccessibilityService.cs" />
|
||||
<Compile Include="Accessibility\Browser.cs" />
|
||||
<Compile Include="Accessibility\NodeList.cs" />
|
||||
<Compile Include="Accessibility\KnownUsernameField.cs" />
|
||||
<Compile Include="Autofill\AutofillConstants.cs" />
|
||||
<Compile Include="Autofill\AutofillHelpers.cs" />
|
||||
<Compile Include="Autofill\AutofillService.cs" />
|
||||
<Compile Include="Autofill\AutofillExternalSelectionActivity.cs" />
|
||||
<Compile Include="Autofill\Field.cs" />
|
||||
<Compile Include="Autofill\FieldCollection.cs" />
|
||||
<Compile Include="Autofill\FilledItem.cs" />
|
||||
<Compile Include="Autofill\Parser.cs" />
|
||||
<Compile Include="Autofill\SavedItem.cs" />
|
||||
<Compile Include="Effects\FabShadowEffect.cs" />
|
||||
<Compile Include="Effects\FixedSizeEffect.cs" />
|
||||
<Compile Include="Effects\TabBarEffect.cs" />
|
||||
<Compile Include="Push\FirebaseMessagingService.cs" />
|
||||
<Compile Include="Receivers\ClearClipboardAlarmReceiver.cs" />
|
||||
<Compile Include="Receivers\RestrictionsChangedReceiver.cs" />
|
||||
<Compile Include="Receivers\EventUploadReceiver.cs" />
|
||||
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
||||
<Compile Include="Renderers\ExtendedGridRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedDatePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStackLayoutRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStepperRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSwitchRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedTimePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEditorRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomPickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEntryRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
|
||||
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||
<Compile Include="Services\AndroidPushNotificationService.cs" />
|
||||
<Compile Include="Services\AndroidLogService.cs" />
|
||||
<Compile Include="MainApplication.cs" />
|
||||
<Compile Include="MainActivity.cs" />
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\BiometricService.cs" />
|
||||
<Compile Include="Services\CryptoPrimitiveService.cs" />
|
||||
<Compile Include="Services\DeviceActionService.cs" />
|
||||
<Compile Include="Services\LocalizeService.cs" />
|
||||
<Compile Include="Tiles\AutofillTileService.cs" />
|
||||
<Compile Include="Tiles\GeneratorTileService.cs" />
|
||||
<Compile Include="Tiles\MyVaultTileService.cs" />
|
||||
<Compile Include="Utilities\AndroidHelpers.cs" />
|
||||
<Compile Include="Utilities\ThemeHelpers.cs" />
|
||||
<Compile Include="WebAuthCallbackActivity.cs" />
|
||||
<Compile Include="Renderers\SelectableLabelRenderer.cs" />
|
||||
<Compile Include="Services\ClipboardService.cs" />
|
||||
<Compile Include="Utilities\IntentExtensions.cs" />
|
||||
<Compile Include="Renderers\CustomPageRenderer.cs" />
|
||||
<Compile Include="Effects\NoEmojiKeyboardEffect.cs" />
|
||||
<Compile Include="Receivers\NotificationDismissReceiver.cs" />
|
||||
<Compile Include="Services\FileService.cs" />
|
||||
<Compile Include="Services\AutofillHandler.cs" />
|
||||
<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" />
|
||||
<AndroidAsset Include="Assets\RobotoMono_Regular.ttf" />
|
||||
<AndroidAsset Include="Assets\MaterialIcons_Regular.ttf" />
|
||||
<None Include="8bit.keystore.enc" />
|
||||
<GoogleServicesJson Include="google-services.json" />
|
||||
<GoogleServicesJson Include="google-services.json.enc" />
|
||||
<None Include="fdroid-keystore.jks.enc" />
|
||||
<AndroidNativeLibrary Include="lib\arm64-v8a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\armeabi-v7a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\x86\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\x86_64\libargon2.so" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
<None Include="upload-keystore.jks.enc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable\card.xml" />
|
||||
<AndroidResource Include="Resources\drawable\cog_environment.xml" />
|
||||
<AndroidResource Include="Resources\drawable\cog_settings.xml" />
|
||||
<AndroidResource Include="Resources\drawable\icon.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_foreground.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_monochrome.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_warning.xml" />
|
||||
<AndroidResource Include="Resources\drawable\id.xml" />
|
||||
<AndroidResource Include="Resources\drawable\info.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg.xml" />
|
||||
<AndroidResource Include="Resources\drawable\lock.xml" />
|
||||
<AndroidResource Include="Resources\drawable\login.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_white.xml" />
|
||||
<AndroidResource Include="Resources\drawable\send.xml" />
|
||||
<AndroidResource Include="Resources\drawable\pencil.xml" />
|
||||
<AndroidResource Include="Resources\drawable\plus.xml" />
|
||||
<AndroidResource Include="Resources\drawable\generate.xml" />
|
||||
<AndroidResource Include="Resources\drawable\search.xml" />
|
||||
<AndroidResource Include="Resources\drawable\shield.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
|
||||
<AndroidResource Include="Resources\drawable\switch_thumb.xml" />
|
||||
<AndroidResource Include="Resources\layout\progress_dialog_layout.xml" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher_round.xml" />
|
||||
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\values-night\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\colors.xml" />
|
||||
<AndroidResource Include="Resources\values\manifest.xml" />
|
||||
<AndroidResource Include="Resources\values-v30\manifest.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_rounded.xml" />
|
||||
<AndroidResource Include="Resources\drawable-night-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_notification.xml">
|
||||
<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>
|
||||
<AndroidResource Include="Resources\drawable\empty_login_requests.xml">
|
||||
<SubType></SubType>
|
||||
<Generator></Generator>
|
||||
</AndroidResource>
|
||||
<AndroidResource Include="Resources\drawable\empty_login_requests_dark.xml">
|
||||
<SubType></SubType>
|
||||
<Generator></Generator>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\App\App.csproj">
|
||||
<Project>{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}</Project>
|
||||
<Name>App</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{4b8a8c41-9820-4341-974c-41e65b7f4366}</Project>
|
||||
<Name>Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\accessibilityservice.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\autofillservice.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\filepaths.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\network_security_config.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\strings.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\ic_launcher_background.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\autofill_listitem.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\slider_thumb.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\splash_screen_dark.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\dimens.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\app_restrictions.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\values-v30\" />
|
||||
<Folder Include="Resources\drawable-v26\" />
|
||||
<Folder Include="Resources\drawable-night-v26\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,30 +0,0 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using Bit.Droid.Effects;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(FabShadowEffect), "FabShadowEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class FabShadowEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached ()
|
||||
{
|
||||
if (Control is Android.Widget.Button button)
|
||||
{
|
||||
var gd = new GradientDrawable();
|
||||
gd.SetColor(ThemeHelpers.FabColor);
|
||||
gd.SetCornerRadius(100);
|
||||
|
||||
button.SetBackground(gd);
|
||||
button.Elevation = 6;
|
||||
button.TranslationZ = 20;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Effects;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(FixedSizeEffect), "FixedSizeEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class FixedSizeEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (Element is Label label && Control is TextView textView)
|
||||
{
|
||||
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Effects;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class RemoveFontPaddingEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (Control is TextView textView)
|
||||
{
|
||||
textView.SetIncludeFontPadding(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Android.Views;
|
||||
using Bit.Droid.Effects;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ResolutionGroupName("Bitwarden")]
|
||||
[assembly: ExportEffect(typeof(TabBarEffect), "TabBarEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class TabBarEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (!(Container.GetChildAt(0) is ViewGroup layout))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("BitwardenAndroid")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Bitwarden Inc.")]
|
||||
[assembly: AssemblyProduct("Bitwarden")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,69 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Editor), typeof(CustomEditorRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomEditorRenderer : EditorRenderer
|
||||
{
|
||||
public CustomEditorRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
// Workaround for issue described here:
|
||||
// https://github.com/xamarin/Xamarin.Forms/issues/8291#issuecomment-617456651
|
||||
protected override void OnAttachedToWindow()
|
||||
{
|
||||
base.OnAttachedToWindow();
|
||||
EditText.Enabled = false;
|
||||
EditText.Enabled = true;
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Text;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Entry), typeof(CustomEntryRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomEntryRenderer : EntryRenderer
|
||||
{
|
||||
public CustomEntryRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for bug preventing long-press -> copy/paste on Android 11
|
||||
// See https://issuetracker.google.com/issues/37095917
|
||||
protected override void OnAttachedToWindow()
|
||||
{
|
||||
base.OnAttachedToWindow();
|
||||
Control.Enabled = false;
|
||||
Control.Enabled = true;
|
||||
}
|
||||
|
||||
// Workaround for failure to disable text prediction on non-password fields
|
||||
// see https://github.com/xamarin/Xamarin.Forms/issues/10857
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
// Check if changed property is "IsPassword", otherwise ignore
|
||||
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
|
||||
{
|
||||
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
|
||||
EditText.InputType = Element.Keyboard.ToInputType();
|
||||
bool isText = (EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText,
|
||||
isNumber = (EditText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
|
||||
if (isText || isNumber)
|
||||
{
|
||||
if (Element.IsPassword)
|
||||
{
|
||||
// Element is a password field, set inputType to TextVariationPassword which disables
|
||||
// predictive text by default
|
||||
EditText.InputType = EditText.InputType |
|
||||
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Element is not a password field, set inputType to TextVariationVisiblePassword to
|
||||
// disable predictive text while still displaying the content.
|
||||
EditText.InputType = EditText.InputType |
|
||||
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
|
||||
}
|
||||
|
||||
// The workaround above forces a reset of the style properties, so we need to re-apply the font.
|
||||
// see https://xamarin.github.io/bugzilla-archives/33/33666/bug.html
|
||||
var typeface = Typeface.CreateFromAsset(Context.Assets, "RobotoMono_Regular.ttf");
|
||||
if (Control is TextView label)
|
||||
{
|
||||
label.Typeface = typeface;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomPageRenderer : PageRenderer
|
||||
{
|
||||
public CustomPageRenderer(Context context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
Activity context = (Activity)this.Context;
|
||||
var toolbar = context.FindViewById<Toolbar>(Resource.Id.toolbar);
|
||||
if(toolbar != null)
|
||||
{
|
||||
toolbar.NavigationContentDescription = AppResources.TapToGoBack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomPickerRenderer : PickerRenderer
|
||||
{
|
||||
public CustomPickerRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Picker.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Android.Content;
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SearchBar), typeof(CustomSearchBarRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomSearchBarRenderer : SearchBarRenderer
|
||||
{
|
||||
public CustomSearchBarRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var magId = Resources.GetIdentifier("android:id/search_mag_icon", null, null);
|
||||
var magImage = (Android.Widget.ImageView)Control.FindViewById(magId);
|
||||
magImage.LayoutParameters = new Android.Widget.LinearLayout.LayoutParams(0, 0);
|
||||
}
|
||||
catch { }
|
||||
Control.SetImeOptions(Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using AndroidX.Core.Content.Resources;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomSwitchRenderer : SwitchRenderer
|
||||
{
|
||||
public CustomSwitchRenderer(Context context)
|
||||
: base(context)
|
||||
{}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateColors();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Switch.OnColorProperty.PropertyName)
|
||||
{
|
||||
UpdateColors();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateColors()
|
||||
{
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
|
||||
{
|
||||
// Android 5.x doesn't support ThumbTintList, and using SwitchCompat on every version after 5.x
|
||||
// doesn't apply tinting the way we want. Let 5.x to do its own thing here.
|
||||
return;
|
||||
}
|
||||
if (Control != null)
|
||||
{
|
||||
Control.SetHintTextColor(ThemeHelpers.MutedColor);
|
||||
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.switch_thumb, null);
|
||||
if (t is GradientDrawable thumb)
|
||||
{
|
||||
Control.ThumbDrawable = thumb;
|
||||
}
|
||||
var thumbStates = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateChecked }, // checked
|
||||
new[] { -Android.Resource.Attribute.StateChecked }, // unchecked
|
||||
};
|
||||
var thumbColors = new int[]
|
||||
{
|
||||
ThemeHelpers.SwitchOnColor,
|
||||
ThemeHelpers.SwitchThumbColor
|
||||
};
|
||||
Control.ThumbTintList = new ColorStateList(thumbStates, thumbColors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Pages;
|
||||
using Bit.Droid.Renderers;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Google.Android.Material.Navigation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
using Xamarin.Forms.Platform.Android.AppCompat;
|
||||
|
||||
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
|
||||
{
|
||||
private TabbedPage _page;
|
||||
|
||||
public CustomTabbedRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
_page = e.NewElement;
|
||||
GetBottomNavigationView()?.SetOnItemReselectedListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page = e.OldElement;
|
||||
}
|
||||
}
|
||||
|
||||
private BottomNavigationView GetBottomNavigationView()
|
||||
{
|
||||
for (var i = 0; i < ViewGroup.ChildCount; i++)
|
||||
{
|
||||
var childView = ViewGroup.GetChildAt(i);
|
||||
if (childView is ViewGroup viewGroup)
|
||||
{
|
||||
for (var j = 0; j < viewGroup.ChildCount; j++)
|
||||
{
|
||||
var childRelativeLayoutView = viewGroup.GetChildAt(j);
|
||||
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
|
||||
{
|
||||
return bottomNavigationView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OnNavigationItemReselected(IMenuItem item)
|
||||
{
|
||||
if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
|
||||
{
|
||||
if (_page is TabsPage tabsPage)
|
||||
{
|
||||
tabsPage.OnPageReselected();
|
||||
}
|
||||
Device.BeginInvokeOnMainThread(async () => await _page.CurrentPage.Navigation.PopToRootAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedDatePickerRenderer : DatePickerRenderer
|
||||
{
|
||||
public ExtendedDatePickerRenderer(Context context)
|
||||
: base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && Element is ExtendedDatePicker element)
|
||||
{
|
||||
// center text
|
||||
Control.Gravity = GravityFlags.CenterHorizontal;
|
||||
|
||||
// use placeholder until NullableDate set
|
||||
if (!element.NullableDate.HasValue)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == DatePicker.DateProperty.PropertyName ||
|
||||
e.PropertyName == DatePicker.FormatProperty.PropertyName)
|
||||
{
|
||||
if (Control != null && Element is ExtendedDatePicker element)
|
||||
{
|
||||
if (Element.Format == element.PlaceHolder)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedGrid), typeof(ExtendedGridRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedGridRenderer : ViewRenderer
|
||||
{
|
||||
public ExtendedGridRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
{
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using AndroidX.Core.Content.Resources;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedSlider), typeof(ExtendedSliderRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedSliderRenderer : SliderRenderer
|
||||
{
|
||||
public ExtendedSliderRenderer(Context context)
|
||||
: base(context)
|
||||
{}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == ExtendedSlider.ThumbBorderColorProperty.PropertyName)
|
||||
{
|
||||
UpdateColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateColor()
|
||||
{
|
||||
if (Control != null && Element is ExtendedSlider view)
|
||||
{
|
||||
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.slider_thumb, null);
|
||||
if (t is GradientDrawable thumb)
|
||||
{
|
||||
if (view.ThumbColor == Color.Default)
|
||||
{
|
||||
thumb.SetColor(Color.White.ToAndroid());
|
||||
}
|
||||
else
|
||||
{
|
||||
thumb.SetColor(view.ThumbColor.ToAndroid());
|
||||
}
|
||||
thumb.SetStroke(3, view.ThumbBorderColor.ToAndroid());
|
||||
Control.SetThumb(thumb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedStackLayout), typeof(ExtendedStackLayoutRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedStackLayoutRenderer : ViewRenderer
|
||||
{
|
||||
public ExtendedStackLayoutRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
{
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.OS;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedStepper), typeof(ExtendedStepperRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedStepperRenderer : StepperRenderer
|
||||
{
|
||||
public ExtendedStepperRenderer(Context context)
|
||||
: base(context)
|
||||
{}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBgColor();
|
||||
UpdateFgColor();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == ExtendedStepper.StepperBackgroundColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBgColor();
|
||||
}
|
||||
else if (e.PropertyName == ExtendedStepper.StepperForegroundColorProperty.PropertyName)
|
||||
{
|
||||
UpdateFgColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBgColor()
|
||||
{
|
||||
if (Control != null && Element is ExtendedStepper view)
|
||||
{
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
|
||||
{
|
||||
Control.GetChildAt(0)?.Background?.SetColorFilter(
|
||||
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), BlendMode.Multiply));
|
||||
Control.GetChildAt(1)?.Background?.SetColorFilter(
|
||||
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), BlendMode.Multiply));
|
||||
}
|
||||
else
|
||||
{
|
||||
Control.GetChildAt(0)?.Background?.SetColorFilter(
|
||||
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
|
||||
Control.GetChildAt(1)?.Background?.SetColorFilter(
|
||||
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFgColor()
|
||||
{
|
||||
if (Control != null && Element is ExtendedStepper view)
|
||||
{
|
||||
var btn0 = Control.GetChildAt(0) as Android.Widget.Button;
|
||||
btn0?.SetTextColor(view.StepperForegroundColor.ToAndroid());
|
||||
var btn1 = Control.GetChildAt(1) as Android.Widget.Button;
|
||||
btn1?.SetTextColor(view.StepperForegroundColor.ToAndroid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedTimePicker), typeof(ExtendedTimePickerRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedTimePickerRenderer : TimePickerRenderer
|
||||
{
|
||||
public ExtendedTimePickerRenderer(Context context)
|
||||
: base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && Element is ExtendedTimePicker element)
|
||||
{
|
||||
// center text
|
||||
Control.Gravity = GravityFlags.CenterHorizontal;
|
||||
|
||||
// use placeholder until NullableTime set
|
||||
if (!element.NullableTime.HasValue)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == TimePicker.TimeProperty.PropertyName ||
|
||||
e.PropertyName == TimePicker.FormatProperty.PropertyName)
|
||||
{
|
||||
if (Control != null && Element is ExtendedTimePicker element)
|
||||
{
|
||||
if (Element.Format == element.PlaceHolder)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using Bit.App.Controls;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
using Android.Webkit;
|
||||
using AWebkit = Android.Webkit;
|
||||
using Java.Interop;
|
||||
using Android.Content;
|
||||
using Bit.Droid.Renderers;
|
||||
using System.ComponentModel;
|
||||
|
||||
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, AWebkit.WebView>
|
||||
{
|
||||
private const string JSFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
|
||||
|
||||
private readonly Context _context;
|
||||
|
||||
public HybridWebViewRenderer(Context context)
|
||||
: base(context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (Control == null)
|
||||
{
|
||||
var webView = new AWebkit.WebView(_context);
|
||||
webView.Settings.JavaScriptEnabled = true;
|
||||
webView.SetWebViewClient(new JSWebViewClient(string.Format("javascript: {0}", JSFunction)));
|
||||
SetNativeControl(webView);
|
||||
}
|
||||
if (e.OldElement != null)
|
||||
{
|
||||
Control.RemoveJavascriptInterface("jsBridge");
|
||||
var hybridWebView = e.OldElement as HybridWebView;
|
||||
hybridWebView.Cleanup();
|
||||
}
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
|
||||
Control.LoadUrl(Element.Uri);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
if (e.PropertyName == HybridWebView.UriProperty.PropertyName)
|
||||
{
|
||||
Control.LoadUrl(Element.Uri);
|
||||
}
|
||||
}
|
||||
|
||||
public class JSBridge : Java.Lang.Object
|
||||
{
|
||||
private readonly WeakReference<HybridWebViewRenderer> _hybridWebViewRenderer;
|
||||
|
||||
public JSBridge(HybridWebViewRenderer hybridRenderer)
|
||||
{
|
||||
_hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
|
||||
}
|
||||
|
||||
[JavascriptInterface]
|
||||
[Export("invokeAction")]
|
||||
public void InvokeAction(string data)
|
||||
{
|
||||
if (_hybridWebViewRenderer != null &&
|
||||
_hybridWebViewRenderer.TryGetTarget(out HybridWebViewRenderer hybridRenderer))
|
||||
{
|
||||
hybridRenderer.Element.InvokeAction(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class JSWebViewClient : WebViewClient
|
||||
{
|
||||
private readonly string _javascript;
|
||||
|
||||
public JSWebViewClient(string javascript)
|
||||
{
|
||||
_javascript = javascript;
|
||||
|
||||
}
|
||||
|
||||
public override void OnPageFinished(AWebkit.WebView view, string url)
|
||||
{
|
||||
base.OnPageFinished(view, url);
|
||||
view.EvaluateJavascript(_javascript, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SelectableLabel), typeof(SelectableLabelRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class SelectableLabelRenderer : LabelRenderer
|
||||
{
|
||||
public SelectableLabelRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (Control != null)
|
||||
{
|
||||
Control.SetTextIsSelectable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,441 +1,261 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<RootNamespace>Bit.App</RootNamespace>
|
||||
<AssemblyName>BitwardenApp</AssemblyName>
|
||||
<Configurations>Debug;Release;FDroid</Configurations>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0-android;net8.0-ios</TargetFrameworks>
|
||||
|
||||
<!-- Uncomment to also build for Windows platform.-->
|
||||
<!--<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>-->
|
||||
|
||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
|
||||
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Bit.App</RootNamespace>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<!-- Display name -->
|
||||
<ApplicationTitle>Bitwarden</ApplicationTitle>
|
||||
|
||||
<!-- App Identifier -->
|
||||
<ApplicationId Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">com.8bit.bitwarden</ApplicationId>
|
||||
<ApplicationId Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">com.x8bit.bitwarden</ApplicationId>
|
||||
<ApplicationIdGuid>ccf4766c-a36c-4647-900c-0ea7d323ccc6</ApplicationIdGuid>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
|
||||
<ForceSimulatorX64ArchitectureInIDE>true</ForceSimulatorX64ArchitectureInIDE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DefineConstants Condition=" '$(CustomConstants)' != '' ">$(DefineConstants);$(CustomConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-android|AnyCPU'">
|
||||
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
|
||||
<UseInterpreter>False</UseInterpreter>
|
||||
<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.8.0" />
|
||||
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2612" />
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Pages\Accounts\EnvironmentPage.xaml.cs">
|
||||
<DependentUpon>EnvironmentPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\HintPage.xaml.cs">
|
||||
<DependentUpon>HintPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LockPage.xaml.cs">
|
||||
<DependentUpon>LockPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\TwoFactorPage.xaml.cs">
|
||||
<DependentUpon>TwoFactorPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\RegisterPage.xaml.cs">
|
||||
<DependentUpon>RegisterPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LoginPage.xaml.cs">
|
||||
<DependentUpon>LoginPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Generator\GeneratorPage.xaml.cs">
|
||||
<DependentUpon>GeneratorPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Generator\GeneratorHistoryPage.xaml.cs">
|
||||
<DependentUpon>GeneratorHistoryPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\AutofillPage.xaml.cs">
|
||||
<DependentUpon>AutofillPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\ExtensionPage.xaml.cs">
|
||||
<DependentUpon>ExtensionPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\FolderAddEditPage.xaml.cs">
|
||||
<DependentUpon>FolderAddEditPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\FoldersPage.xaml.cs">
|
||||
<DependentUpon>FoldersPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\ExportVaultPage.xaml.cs">
|
||||
<DependentUpon>ExportVaultPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\AttachmentsPage.xaml.cs">
|
||||
<DependentUpon>AttachmentsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\AutofillCiphersPage.xaml.cs">
|
||||
<DependentUpon>AutofillCiphersPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\CollectionsPage.xaml.cs">
|
||||
<DependentUpon>CollectionsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\ScanPage.xaml.cs">
|
||||
<DependentUpon>ScanPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\SharePage.xaml.cs">
|
||||
<DependentUpon>SharePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\CiphersPage.xaml.cs">
|
||||
<DependentUpon>CiphersPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\PasswordHistoryPage.xaml.cs">
|
||||
<DependentUpon>PasswordHistoryPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\CipherDetailsPage.xaml.cs">
|
||||
<DependentUpon>CipherDetailsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\CipherAddEditPage.xaml.cs">
|
||||
<DependentUpon>CipherAddEditPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\SettingsPage\SettingsPage.xaml.cs">
|
||||
<DependentUpon>SettingsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Vault\GroupingsPage\GroupingsPage.xaml.cs">
|
||||
<DependentUpon>GroupingsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LoginSsoPage.xaml.cs">
|
||||
<DependentUpon>LoginSsoPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\SetPasswordPage.xaml.cs">
|
||||
<DependentUpon>ResetMasterPasswordPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Send\SendGroupingsPage\SendGroupingsPage.xaml.cs">
|
||||
<DependentUpon>SendGroupingsPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Remove="Pages\Accounts\AccountsPopupPage.xaml.cs" />
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessRequestPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessRequestPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
<Folder Include="Behaviors\" />
|
||||
<Folder Include="Lists\" />
|
||||
<Folder Include="Lists\ItemLayouts\" />
|
||||
<Folder Include="Lists\DataTemplateSelectors\" />
|
||||
<Folder Include="Lists\ItemLayouts\CustomFields\" />
|
||||
<Folder Include="Lists\ItemViewModels\" />
|
||||
<Folder Include="Lists\ItemViewModels\CustomFields\" />
|
||||
<Folder Include="Controls\AccountSwitchingOverlay\" />
|
||||
<Folder Include="Utilities\AccountManagement\" />
|
||||
<Folder Include="Controls\DateTime\" />
|
||||
<Folder Include="Controls\IconLabelButton\" />
|
||||
<Folder Include="Controls\PasswordStrengthProgressBar\" />
|
||||
<Folder Include="Utilities\Automation\" />
|
||||
<Folder Include="Utilities\Prompts\" />
|
||||
<Folder Include="Controls\Settings\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="Pages\Accounts\AccountsPopupPage.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Styles\Black.xaml.cs">
|
||||
<DependentUpon>Black.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\Nord.xaml.cs">
|
||||
<DependentUpon>Nord.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\Variables.xaml.cs">
|
||||
<DependentUpon>Variables.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\Light.xaml.cs">
|
||||
<DependentUpon>Light.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\Dark.xaml.cs">
|
||||
<DependentUpon>Dark.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\iOS.xaml.cs">
|
||||
<DependentUpon>iOS.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Styles\Android.xaml.cs">
|
||||
<DependentUpon>Android.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Resources\AppResources.cs.Designer.cs">
|
||||
<DependentUpon>AppResources.cs.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.da.Designer.cs">
|
||||
<DependentUpon>AppResources.da.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.de.Designer.cs">
|
||||
<DependentUpon>AppResources.de.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>AppResources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.es.Designer.cs">
|
||||
<DependentUpon>AppResources.es.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.fi.Designer.cs">
|
||||
<DependentUpon>AppResources.fi.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.fr.Designer.cs">
|
||||
<DependentUpon>AppResources.fr.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.hi.Designer.cs">
|
||||
<DependentUpon>AppResources.hi.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.hr.Designer.cs">
|
||||
<DependentUpon>AppResources.hr.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.hu.Designer.cs">
|
||||
<DependentUpon>AppResources.hu.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.id.Designer.cs">
|
||||
<DependentUpon>AppResources.id.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.it.Designer.cs">
|
||||
<DependentUpon>AppResources.it.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.ja.Designer.cs">
|
||||
<DependentUpon>AppResources.ja.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.nl.Designer.cs">
|
||||
<DependentUpon>AppResources.nl.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.pl.Designer.cs">
|
||||
<DependentUpon>AppResources.pl.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.pt-BR.Designer.cs">
|
||||
<DependentUpon>AppResources.pt-BR.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.pt-PT.Designer.cs">
|
||||
<DependentUpon>AppResources.pt-PT.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.ro.Designer.cs">
|
||||
<DependentUpon>AppResources.ro.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.ru.Designer.cs">
|
||||
<DependentUpon>AppResources.ru.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.sk.Designer.cs">
|
||||
<DependentUpon>AppResources.sk.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.sv.Designer.cs">
|
||||
<DependentUpon>AppResources.sv.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.th.Designer.cs">
|
||||
<DependentUpon>AppResources.th.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.tr.Designer.cs">
|
||||
<DependentUpon>AppResources.tr.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.uk.Designer.cs">
|
||||
<DependentUpon>AppResources.uk.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.vi.Designer.cs">
|
||||
<DependentUpon>AppResources.vi.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.zh-Hans.Designer.cs">
|
||||
<DependentUpon>AppResources.zh-Hans.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="Resources\AppResources.zh-Hant.Designer.cs">
|
||||
<DependentUpon>AppResources.zh-Hant.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\AppResources.cs.resx">
|
||||
<LastGenOutput>AppResources.cs.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.da.resx">
|
||||
<LastGenOutput>AppResources.da.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.de.resx">
|
||||
<LastGenOutput>AppResources.de.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.es.resx">
|
||||
<LastGenOutput>AppResources.es.Designer.cs</LastGenOutput>
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.fi.resx">
|
||||
<LastGenOutput>AppResources.fi.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.fr.resx">
|
||||
<LastGenOutput>AppResources.fr.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.hi.resx">
|
||||
<LastGenOutput>AppResources.hi.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.hr.resx">
|
||||
<LastGenOutput>AppResources.hr.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.hu.resx">
|
||||
<LastGenOutput>AppResources.hu.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.id.resx">
|
||||
<LastGenOutput>AppResources.id.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.it.resx">
|
||||
<LastGenOutput>AppResources.it.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.ja.resx">
|
||||
<LastGenOutput>AppResources.ja.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.nl.resx">
|
||||
<LastGenOutput>AppResources.nl.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.pl.resx">
|
||||
<LastGenOutput>AppResources.pl.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.pt-BR.resx">
|
||||
<LastGenOutput>AppResources.pt-BR.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.pt-PT.resx">
|
||||
<LastGenOutput>AppResources.pt-PT.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AppResources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.ro.resx">
|
||||
<LastGenOutput>AppResources.ro.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.ru.resx">
|
||||
<LastGenOutput>AppResources.ru.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.sk.resx">
|
||||
<LastGenOutput>AppResources.sk.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.sv.resx">
|
||||
<LastGenOutput>AppResources.sv.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.th.resx">
|
||||
<LastGenOutput>AppResources.th.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.tr.resx">
|
||||
<LastGenOutput>AppResources.tr.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.uk.resx">
|
||||
<LastGenOutput>AppResources.uk.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.vi.resx">
|
||||
<LastGenOutput>AppResources.vi.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.zh-Hans.resx">
|
||||
<LastGenOutput>AppResources.zh-Hans.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\AppResources.zh-Hant.resx">
|
||||
<LastGenOutput>AppResources.zh-Hant.Designer.cs</LastGenOutput>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Behaviors\" />
|
||||
<None Remove="Xamarin.CommunityToolkit" />
|
||||
<None Remove="Lists\" />
|
||||
<None Remove="Lists\DataTemplates\" />
|
||||
<None Remove="Lists\DataTemplateSelectors\" />
|
||||
<None Remove="Lists\DataTemplates\CustomFields\" />
|
||||
<None Remove="Lists\ItemViewModels\" />
|
||||
<None Remove="Lists\ItemViewModels\CustomFields\" />
|
||||
<None Remove="Controls\AccountSwitchingOverlay\" />
|
||||
<None Remove="Utilities\AccountManagement\" />
|
||||
<None Remove="Controls\DateTime\" />
|
||||
<None Remove="Controls\IconLabelButton\" />
|
||||
<None Remove="MessagePack" />
|
||||
<None Remove="MessagePack.MSBuild.Tasks" />
|
||||
<None Remove="Controls\PasswordStrengthProgressBar\" />
|
||||
<None Remove="Utilities\Automation\" />
|
||||
<None Remove="Utilities\Prompts\" />
|
||||
<None Remove="Controls\Settings\" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-android|AnyCPU'">
|
||||
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
|
||||
<UseInterpreter>False</UseInterpreter>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<RunAOTCompilation>False</RunAOTCompilation>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-ios|AnyCPU'">
|
||||
<CreatePackage>false</CreatePackage>
|
||||
<CodesignProvision>Automatic</CodesignProvision>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
|
||||
<UseInterpreter>true</UseInterpreter>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(RuntimeIdentifier)'=='Debug|net8.0-ios|iossimulator-x64'">
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(RuntimeIdentifier)'=='Debug|net8.0-ios|ios-arm64'">
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-ios|AnyCPU'">
|
||||
<CreatePackage>false</CreatePackage>
|
||||
<CodesignProvision>$(ReleaseCodesignProvision)</CodesignProvision>
|
||||
<CodesignKey>$(ReleaseCodesignKey)</CodesignKey>
|
||||
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
|
||||
<UseInterpreter>true</UseInterpreter>
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
|
||||
<!--This is needed for PCLCrypto to work correctly-->
|
||||
<TrimmerRootAssembly Include="System.Security.Cryptography" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidNativeLibrary Include="Platforms\Android\lib\arm64-v8a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="Platforms\Android\lib\armeabi-v7a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="Platforms\Android\lib\x86\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="Platforms\Android\lib\x86_64\libargon2.so" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Camera.MAUI" Version="1.4.4" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
|
||||
<PackageReference Include="CsvHelper" Version="30.0.1" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.17" />
|
||||
<PackageReference Include="MessagePack" Version="2.5.124" />
|
||||
<PackageReference Include="MessagePack.MSBuild.Tasks" Version="2.5.124">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="zxcvbn-core" Version="7.0.92" />
|
||||
<PackageReference Include="CommunityToolkit.Maui" Version="5.2.0" />
|
||||
<PackageReference Include="Plugin.Fingerprint" Version="3.0.0-beta.1" />
|
||||
<PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="2.88.4-preview.84" />
|
||||
<PackageReference Include="SkiaSharp.Views.Maui.Controls.Compatibility" Version="2.88.4-preview.84" />
|
||||
<PackageReference Include="FFImageLoadingCompat.Maui" Version="0.1.1" />
|
||||
<PackageReference Include="AsyncAwaitBestPractices.MVVM" Version="6.0.6" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<PackageReference Include="PCLCrypto" Version="2.1.40-alpha" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Effects\" />
|
||||
<Folder Include="Resources\" />
|
||||
<Folder Include="Resources\AppIcon\" />
|
||||
<Folder Include="Resources\Splash\" />
|
||||
<Folder Include="Platforms\Android\Accessibility\" />
|
||||
<Folder Include="Platforms\Android\Autofill\" />
|
||||
<Folder Include="Platforms\Android\Push\" />
|
||||
<Folder Include="Platforms\Android\Receivers\" />
|
||||
<Folder Include="Platforms\Android\Services\" />
|
||||
<Folder Include="Platforms\Android\Tiles\" />
|
||||
<Folder Include="Platforms\Android\Utilities\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.18" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Activity.Ktx" Version="1.7.2.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Credentials" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android' AND !$(DefineConstants.Contains(FDROID))">
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet" Version="118.0.1.5" />
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging" Version="123.1.2.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="!$(DefineConstants.Contains(FDROID))">
|
||||
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-mdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-mdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxhdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxhdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxxhdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-hdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-hdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-mdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-mdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-hdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-hdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxxhdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxhdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xxhdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xhdpi\logo_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xhdpi\yubikey.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xhdpi\logo_white_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xxhdpi\logo_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xxhdpi\yubikey.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-xxhdpi\logo_white_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-hdpi\logo_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-hdpi\yubikey.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\drawable-hdpi\logo_white_legacy.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher.png" />
|
||||
<BundleResource Include="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher_round.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo_white%402x.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\more_vert%402x.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo_white%403x.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo%403x.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\more_vert%403x.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\more_vert.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo_white.png" />
|
||||
<BundleResource Include="Platforms\iOS\Resources\logo%402x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\iOS.Core\iOS.Core.csproj" Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'" />
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- App Icon -->
|
||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MauiImage Include="Resources\cog_settings.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\ext_act.png" />
|
||||
<MauiImage Include="Resources\ext_more.png" />
|
||||
<MauiImage Include="Resources\ext_use.png" />
|
||||
<MauiImage Include="Resources\generate.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\info.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\lock.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\login.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\logo_white.png" />
|
||||
<MauiImage Include="Resources\logo.png" />
|
||||
<MauiImage Include="Resources\more_vert.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\more.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\plus.svg" TintColor="#FFFFFFFF">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\send.svg">
|
||||
<BaseSize>24,24</BaseSize>
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' AND '$(IncludeBitwardeniOSExtensions)' == 'True'">
|
||||
<ProjectReference Include="..\iOS.Autofill\iOS.Autofill.csproj">
|
||||
<IsAppExtension>true</IsAppExtension>
|
||||
<IsWatchApp>false</IsWatchApp>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\iOS.Extension\iOS.Extension.csproj">
|
||||
<IsAppExtension>true</IsAppExtension>
|
||||
<IsWatchApp>false</IsWatchApp>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\iOS.ShareExtension\iOS.ShareExtension.csproj">
|
||||
<IsAppExtension>true</IsAppExtension>
|
||||
<IsWatchApp>false</IsWatchApp>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)'=='net8.0-ios' AND '$(IncludeBitwardenWatchOSApp)' == 'True'">
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' == 'Debug' ">$(Home)/Library/Developer/Xcode/DerivedData/bitwarden-acgkbpwvmebfiofokotvoerzkqcl/Build/Products</WatchAppBuildPath>
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' != 'Debug' ">$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..'))/watchOS/bitwarden.xcarchive/Products/Applications/bitwarden.app/Watch</WatchAppBuildPath>
|
||||
<WatchAppBundle>Bitwarden.app</WatchAppBundle>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'!='ios-arm64'">watchsimulator</WatchAppConfiguration>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'=='ios-arm64'">watchos</WatchAppConfiguration>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' == 'Debug' ">$(WatchAppBuildPath)/$(Configuration)-$(WatchAppConfiguration)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' != 'Debug' ">$(WatchAppBuildPath)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net8.0-ios' AND Exists('$(WatchAppBundleFullPath)') ">
|
||||
<_ResolvedWatchAppReferences Include="$(WatchAppBundleFullPath)" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)'=='net8.0-ios' AND Exists('$(WatchAppBundleFullPath)') ">
|
||||
<CreateAppBundleDependsOn>
|
||||
_CopyWatchOS2AppsToBundle;
|
||||
$(CreateAppBundleDependsOn);
|
||||
</CreateAppBundleDependsOn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<GoogleServicesJson Include="Platforms\Android\google-services.json" />
|
||||
<GoogleServicesJson Include="Platforms\Android\google-services.json.enc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Platforms\iOS\Resources\logo.png" />
|
||||
<None Remove="Platforms\iOS\Resources\logo_white%402x.png" />
|
||||
<None Remove="Platforms\iOS\Resources\more_vert%402x.png" />
|
||||
<None Remove="Platforms\iOS\Resources\logo_white%403x.png" />
|
||||
<None Remove="Platforms\iOS\Resources\logo%403x.png" />
|
||||
<None Remove="Platforms\iOS\Resources\more_vert%403x.png" />
|
||||
<None Remove="Platforms\iOS\Resources\more_vert.png" />
|
||||
<None Remove="Platforms\iOS\Resources\logo_white.png" />
|
||||
<None Remove="Platforms\iOS\Resources\logo%402x.png" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
using System;
|
||||
using Bit.App.Pages;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class AuthenticatorViewCell : ExtendedGrid
|
||||
{
|
||||
public static readonly BindableProperty CipherProperty = BindableProperty.Create(
|
||||
nameof(Cipher), typeof(CipherView), typeof(AuthenticatorViewCell), default(CipherView), BindingMode.TwoWay);
|
||||
|
||||
public static readonly BindableProperty WebsiteIconsEnabledProperty = BindableProperty.Create(
|
||||
nameof(WebsiteIconsEnabled), typeof(bool?), typeof(AuthenticatorViewCell));
|
||||
|
||||
public static readonly BindableProperty TotpSecProperty = BindableProperty.Create(
|
||||
nameof(TotpSec), typeof(long), typeof(AuthenticatorViewCell));
|
||||
|
||||
public AuthenticatorViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Command CopyCommand { get; set; }
|
||||
|
||||
public CipherView Cipher
|
||||
{
|
||||
get => GetValue(CipherProperty) as CipherView;
|
||||
set => SetValue(CipherProperty, value);
|
||||
}
|
||||
|
||||
public bool? WebsiteIconsEnabled
|
||||
{
|
||||
get => (bool)GetValue(WebsiteIconsEnabledProperty);
|
||||
set => SetValue(WebsiteIconsEnabledProperty, value);
|
||||
}
|
||||
|
||||
public long TotpSec
|
||||
{
|
||||
get => (long)GetValue(TotpSecProperty);
|
||||
set => SetValue(TotpSecProperty, value);
|
||||
}
|
||||
|
||||
public bool ShowIconImage
|
||||
{
|
||||
get => WebsiteIconsEnabled ?? false
|
||||
&& !string.IsNullOrWhiteSpace(Cipher.Login?.Uri)
|
||||
&& IconImageSource != null;
|
||||
}
|
||||
|
||||
private string _iconImageSource = string.Empty;
|
||||
public string IconImageSource
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconImageSource == string.Empty) // default value since icon source can return null
|
||||
{
|
||||
_iconImageSource = IconImageHelper.GetLoginIconImage(Cipher);
|
||||
}
|
||||
return _iconImageSource;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Utilities;
|
||||
using SkiaSharp;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class AvatarImageSource : StreamImageSource
|
||||
{
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
private readonly string _color;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._id == _id && avatar._text == _text && avatar._color == _color;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null, string color = null)
|
||||
{
|
||||
_id = userId;
|
||||
_text = name;
|
||||
if (string.IsNullOrWhiteSpace(_text))
|
||||
{
|
||||
_text = email;
|
||||
}
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public override Func<CancellationToken, Task<Stream>> Stream => GetStreamAsync;
|
||||
|
||||
private Task<Stream> GetStreamAsync(CancellationToken userToken = new CancellationToken())
|
||||
{
|
||||
OnLoadingStarted();
|
||||
userToken.Register(CancellationTokenSource.Cancel);
|
||||
var result = Draw();
|
||||
OnLoadingCompleted(CancellationTokenSource.IsCancellationRequested);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
private Stream Draw()
|
||||
{
|
||||
string chars;
|
||||
string upperCaseText = null;
|
||||
|
||||
if (string.IsNullOrEmpty(_text))
|
||||
{
|
||||
chars = "..";
|
||||
}
|
||||
else if (_text?.Length > 1)
|
||||
{
|
||||
upperCaseText = _text.ToUpper();
|
||||
chars = GetFirstLetters(upperCaseText, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
chars = upperCaseText = _text.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = _color ?? CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var textColor = CoreHelpers.TextColorFromBgColor(bgColor);
|
||||
var size = 50;
|
||||
|
||||
using (var bitmap = new SKBitmap(size * 2,
|
||||
size * 2,
|
||||
SKImageInfo.PlatformColorType,
|
||||
SKAlphaType.Premul))
|
||||
{
|
||||
using (var canvas = new SKCanvas(bitmap))
|
||||
{
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
using (var paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
var midX = canvas.LocalClipBounds.Size.ToSizeI().Width / 2;
|
||||
var midY = canvas.LocalClipBounds.Size.ToSizeI().Height / 2;
|
||||
var radius = midX - midX / 5;
|
||||
|
||||
using (var circlePaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
canvas.DrawCircle(midX, midY, radius, circlePaint);
|
||||
|
||||
var typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Normal);
|
||||
var textSize = midX / 1.3f;
|
||||
using (var textPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
Color = SKColor.Parse(textColor),
|
||||
TextSize = textSize,
|
||||
TextAlign = SKTextAlign.Center,
|
||||
Typeface = typeface
|
||||
})
|
||||
{
|
||||
var rect = new SKRect();
|
||||
textPaint.MeasureText(chars, ref rect);
|
||||
canvas.DrawText(chars, midX, midY + rect.Height / 2, textPaint);
|
||||
|
||||
using (var img = SKImage.FromBitmap(bitmap))
|
||||
{
|
||||
var data = img.Encode(SKEncodedImageFormat.Png, 100);
|
||||
return data?.AsStream(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFirstLetters(string data, int charCount)
|
||||
{
|
||||
var sanitizedData = data.Trim();
|
||||
var parts = sanitizedData.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parts.Length > 1 && charCount <= 2)
|
||||
{
|
||||
var text = string.Empty;
|
||||
for (var i = 0; i < charCount; i++)
|
||||
{
|
||||
text += parts[i][0];
|
||||
}
|
||||
return text;
|
||||
}
|
||||
if (sanitizedData.Length > 2)
|
||||
{
|
||||
return sanitizedData.Substring(0, 2);
|
||||
}
|
||||
return sanitizedData;
|
||||
}
|
||||
|
||||
private Color StringToColor(string str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return Color.FromHex("#33ffffff");
|
||||
}
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
hash = str[i] + ((hash << 5) - hash);
|
||||
}
|
||||
var color = "#FF";
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var value = (hash >> (i * 8)) & 0xff;
|
||||
var base16 = "00" + Convert.ToString(value, 16);
|
||||
color += base16.Substring(base16.Length - 2);
|
||||
}
|
||||
return Color.FromHex(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class CipherViewCell : ExtendedGrid
|
||||
{
|
||||
private const int ICON_COLUMN_DEFAULT_WIDTH = 40;
|
||||
private const int ICON_IMAGE_DEFAULT_WIDTH = 22;
|
||||
|
||||
public static readonly BindableProperty CipherProperty = BindableProperty.Create(
|
||||
nameof(Cipher), typeof(CipherView), typeof(CipherViewCell), default(CipherView), BindingMode.OneWay);
|
||||
|
||||
public static readonly BindableProperty WebsiteIconsEnabledProperty = BindableProperty.Create(
|
||||
nameof(WebsiteIconsEnabled), typeof(bool?), typeof(CipherViewCell));
|
||||
|
||||
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
|
||||
nameof(ButtonCommand), typeof(ICommand), typeof(CipherViewCell));
|
||||
|
||||
public CipherViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var fontScale = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService").GetSystemFontSizeScale();
|
||||
_iconColumn.Width = new GridLength(ICON_COLUMN_DEFAULT_WIDTH * fontScale, GridUnitType.Absolute);
|
||||
_iconImage.WidthRequest = ICON_IMAGE_DEFAULT_WIDTH * fontScale;
|
||||
_iconImage.HeightRequest = ICON_IMAGE_DEFAULT_WIDTH * fontScale;
|
||||
}
|
||||
|
||||
public bool? WebsiteIconsEnabled
|
||||
{
|
||||
get => (bool)GetValue(WebsiteIconsEnabledProperty);
|
||||
set => SetValue(WebsiteIconsEnabledProperty, value);
|
||||
}
|
||||
|
||||
public CipherView Cipher
|
||||
{
|
||||
get => GetValue(CipherProperty) as CipherView;
|
||||
set => SetValue(CipherProperty, value);
|
||||
}
|
||||
|
||||
public ICommand ButtonCommand
|
||||
{
|
||||
get => GetValue(ButtonCommandProperty) as ICommand;
|
||||
set => SetValue(ButtonCommandProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (propertyName == CipherProperty.PropertyName)
|
||||
{
|
||||
if (Cipher == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
BindingContext = new CipherViewCellViewModel(Cipher, WebsiteIconsEnabled ?? false);
|
||||
}
|
||||
else if (propertyName == WebsiteIconsEnabledProperty.PropertyName)
|
||||
{
|
||||
if (Cipher == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
((CipherViewCellViewModel)BindingContext).WebsiteIconsEnabled = WebsiteIconsEnabled ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoreButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var cipher = ((sender as MiButton)?.BindingContext as CipherViewCellViewModel)?.Cipher;
|
||||
if (cipher != null)
|
||||
{
|
||||
ButtonCommand?.Execute(cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class CipherViewCellViewModel : ExtendedViewModel
|
||||
{
|
||||
private CipherView _cipher;
|
||||
private bool _websiteIconsEnabled;
|
||||
private string _iconImageSource = string.Empty;
|
||||
|
||||
public CipherViewCellViewModel(CipherView cipherView, bool websiteIconsEnabled)
|
||||
{
|
||||
Cipher = cipherView;
|
||||
WebsiteIconsEnabled = websiteIconsEnabled;
|
||||
}
|
||||
|
||||
public CipherView Cipher
|
||||
{
|
||||
get => _cipher;
|
||||
set => SetProperty(ref _cipher, value);
|
||||
}
|
||||
|
||||
public bool WebsiteIconsEnabled
|
||||
{
|
||||
get => _websiteIconsEnabled;
|
||||
set => SetProperty(ref _websiteIconsEnabled, value);
|
||||
}
|
||||
|
||||
public bool ShowIconImage
|
||||
{
|
||||
get => WebsiteIconsEnabled
|
||||
&& !string.IsNullOrWhiteSpace(Cipher.LaunchUri)
|
||||
&& IconImageSource != null;
|
||||
}
|
||||
|
||||
public string IconImageSource
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconImageSource == string.Empty) // default value since icon source can return null
|
||||
{
|
||||
_iconImageSource = IconImageHelper.GetIconImage(Cipher);
|
||||
}
|
||||
return _iconImageSource;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System.Linq;
|
||||
using Xamarin.CommunityToolkit.Converters;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedCollectionView : CollectionView
|
||||
{
|
||||
public string ExtraDataForLogging { get; set; }
|
||||
}
|
||||
|
||||
public class SelectionChangedEventArgsConverter : BaseNullableConverterOneWay<SelectionChangedEventArgs, object>
|
||||
{
|
||||
public override object? ConvertFrom(SelectionChangedEventArgs? value)
|
||||
{
|
||||
return value?.CurrentSelection.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedGrid : Grid
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedSearchBar : SearchBar
|
||||
{
|
||||
public ExtendedSearchBar()
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
if (ThemeManager.UsingLightTheme)
|
||||
{
|
||||
TextColor = Color.Black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedStackLayout : StackLayout
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Controls.IconLabelButton"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
x:Name="_iconLabelButton"
|
||||
HeightRequest="45"
|
||||
Padding="1"
|
||||
StyleClass="btn-icon-secondary"
|
||||
BackgroundColor="{Binding IconLabelBorderColor, Source={x:Reference _iconLabelButton}}"
|
||||
BorderColor="Transparent"
|
||||
HasShadow="False">
|
||||
<Frame.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding ButtonCommand, Source={x:Reference _iconLabelButton}}" />
|
||||
</Frame.GestureRecognizers>
|
||||
<Frame
|
||||
Margin="0"
|
||||
Padding="0"
|
||||
CornerRadius="{Binding CornerRadius, Source={x:Reference _iconLabelButton}}"
|
||||
BackgroundColor="{Binding IconLabelBackgroundColor, Source={x:Reference _iconLabelButton}}"
|
||||
BorderColor="Transparent"
|
||||
IsClippedToBounds="True"
|
||||
HasShadow="False">
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
HorizontalOptions="Center">
|
||||
<controls:IconLabel
|
||||
VerticalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
FontSize="Large"
|
||||
TextColor="{Binding IconLabelColor, Source={x:Reference _iconLabelButton}}"
|
||||
Text="{Binding Icon, Source={x:Reference _iconLabelButton}}">
|
||||
</controls:IconLabel>
|
||||
<Label
|
||||
VerticalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
TextColor="{Binding IconLabelColor, Source={x:Reference _iconLabelButton}}"
|
||||
FontSize="Medium"
|
||||
Text="{Binding Label, Source={x:Reference _iconLabelButton}}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</Frame>
|
||||
@@ -1,20 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class MonoEntry : Entry
|
||||
{
|
||||
public MonoEntry()
|
||||
{
|
||||
switch (Device.RuntimePlatform)
|
||||
{
|
||||
case Device.iOS:
|
||||
FontFamily = "Menlo-Regular";
|
||||
break;
|
||||
case Device.Android:
|
||||
FontFamily = "RobotoMono_Regular.ttf#Roboto Mono";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class MonoLabel : Label
|
||||
{
|
||||
public MonoLabel()
|
||||
{
|
||||
switch (Device.RuntimePlatform)
|
||||
{
|
||||
case Device.iOS:
|
||||
FontFamily = "Menlo-Regular";
|
||||
break;
|
||||
case Device.Android:
|
||||
FontFamily = "RobotoMono_Regular.ttf#Roboto Mono";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class SendViewCell : ExtendedGrid
|
||||
{
|
||||
public static readonly BindableProperty SendProperty = BindableProperty.Create(
|
||||
nameof(Send), typeof(SendView), typeof(SendViewCell), default(SendView), BindingMode.OneWay);
|
||||
|
||||
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
|
||||
nameof(ButtonCommand), typeof(Command<SendView>), typeof(SendViewCell));
|
||||
|
||||
public static readonly BindableProperty ShowOptionsProperty = BindableProperty.Create(
|
||||
nameof(ShowOptions), typeof(bool), typeof(SendViewCell), true, BindingMode.OneWay);
|
||||
|
||||
public SendViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_iconColumn.Width = new GridLength(40 * deviceActionService.GetSystemFontSizeScale(), GridUnitType.Absolute);
|
||||
}
|
||||
|
||||
public SendView Send
|
||||
{
|
||||
get => GetValue(SendProperty) as SendView;
|
||||
set => SetValue(SendProperty, value);
|
||||
}
|
||||
|
||||
public Command<SendView> ButtonCommand
|
||||
{
|
||||
get => GetValue(ButtonCommandProperty) as Command<SendView>;
|
||||
set => SetValue(ButtonCommandProperty, value);
|
||||
}
|
||||
|
||||
public bool ShowOptions
|
||||
{
|
||||
get => (bool)GetValue(ShowOptionsProperty);
|
||||
set => SetValue(ShowOptionsProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (propertyName == SendProperty.PropertyName)
|
||||
{
|
||||
if (Send == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
BindingContext = new SendViewCellViewModel(Send, ShowOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private void MoreButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var send = ((sender as MiButton)?.BindingContext as SendViewCellViewModel)?.Send;
|
||||
if (send != null)
|
||||
{
|
||||
ButtonCommand?.Execute(send);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class FabShadowEffect : RoutingEffect
|
||||
{
|
||||
public FabShadowEffect()
|
||||
: base("Bitwarden.FabShadowEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class FixedSizeEffect : RoutingEffect
|
||||
{
|
||||
public FixedSizeEffect()
|
||||
: base("Bitwarden.FixedSizeEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class NoEmojiKeyboardEffect : RoutingEffect
|
||||
{
|
||||
public NoEmojiKeyboardEffect()
|
||||
: base("Bitwarden.NoEmojiKeyboardEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class RemoveFontPaddingEffect : RoutingEffect
|
||||
{
|
||||
public RemoveFontPaddingEffect()
|
||||
: base("Bitwarden.RemoveFontPaddingEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public enum ScrollContentInsetAdjustmentBehavior
|
||||
{
|
||||
Automatic,
|
||||
ScrollableAxes,
|
||||
Never,
|
||||
Always
|
||||
}
|
||||
|
||||
public class ScrollViewContentInsetAdjustmentBehaviorEffect : RoutingEffect
|
||||
{
|
||||
public static readonly BindableProperty ContentInsetAdjustmentBehaviorProperty =
|
||||
BindableProperty.CreateAttached("ContentInsetAdjustmentBehavior", typeof(ScrollContentInsetAdjustmentBehavior), typeof(ScrollViewContentInsetAdjustmentBehaviorEffect), ScrollContentInsetAdjustmentBehavior.Automatic);
|
||||
|
||||
public static ScrollContentInsetAdjustmentBehavior GetContentInsetAdjustmentBehavior(BindableObject view)
|
||||
{
|
||||
return (ScrollContentInsetAdjustmentBehavior)view.GetValue(ContentInsetAdjustmentBehaviorProperty);
|
||||
}
|
||||
|
||||
public static void SetContentInsetAdjustmentBehavior(BindableObject view, ScrollContentInsetAdjustmentBehavior value)
|
||||
{
|
||||
view.SetValue(ContentInsetAdjustmentBehaviorProperty, value);
|
||||
}
|
||||
|
||||
public ScrollViewContentInsetAdjustmentBehaviorEffect()
|
||||
: base($"Bitwarden.{nameof(ScrollViewContentInsetAdjustmentBehaviorEffect)}")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class TabBarEffect : RoutingEffect
|
||||
{
|
||||
public TabBarEffect()
|
||||
: base("Bitwarden.TabBarEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
41
src/App/MauiProgram.cs
Normal file
41
src/App/MauiProgram.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace Bit.App
|
||||
{
|
||||
public class MauiProgram
|
||||
{
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
return Core.MauiProgram.ConfigureMauiAppBuilder(
|
||||
effects =>
|
||||
{
|
||||
#if IOS
|
||||
iOS.Core.Utilities.iOSCoreHelpers.ConfigureMAUIEffects(effects);
|
||||
#endif
|
||||
},
|
||||
handlers =>
|
||||
{
|
||||
#if ANDROID
|
||||
Bit.App.Handlers.EntryHandlerMappings.Setup();
|
||||
Bit.App.Handlers.EditorHandlerMappings.Setup();
|
||||
Bit.App.Handlers.LabelHandlerMappings.Setup();
|
||||
Bit.App.Handlers.PickerHandlerMappings.Setup();
|
||||
Bit.App.Handlers.SearchBarHandlerMappings.Setup();
|
||||
Bit.App.Handlers.SwitchHandlerMappings.Setup();
|
||||
Bit.App.Handlers.DatePickerHandlerMappings.Setup();
|
||||
Bit.App.Handlers.SliderHandlerMappings.Setup();
|
||||
Bit.App.Handlers.StepperHandlerMappings.Setup();
|
||||
Bit.App.Handlers.TimePickerHandlerMappings.Setup();
|
||||
Bit.App.Handlers.ButtonHandlerMappings.Setup();
|
||||
Bit.App.Handlers.ToolbarHandlerMappings.Setup();
|
||||
|
||||
handlers.AddHandler(typeof(Bit.App.Controls.HybridWebView), typeof(Bit.App.Handlers.HybridWebViewHandler));
|
||||
handlers.AddHandler(typeof(Bit.App.Pages.TabsPage), typeof(Bit.App.Handlers.CustomTabbedPageHandler));
|
||||
handlers.AddHandler(typeof(Bit.App.Controls.ExtendedDatePicker), typeof(Bit.App.Handlers.ExtendedDatePickerHandler));
|
||||
#else
|
||||
iOS.Core.Utilities.iOSCoreHelpers.ConfigureMAUIHandlers(handlers);
|
||||
#endif
|
||||
},
|
||||
initUseMauiApp: true
|
||||
).Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.HomePage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:HomeViewModel"
|
||||
x:Name="_page"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
<pages:HomeViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<controls:ExtendedToolbarItem
|
||||
x:Name="_accountAvatar"
|
||||
x:Key="accountAvatar"
|
||||
IconImageSource="{Binding AvatarImageSource}"
|
||||
Command="{Binding Source={x:Reference _accountListOverlay}, Path=ToggleVisibililtyCommand}"
|
||||
Order="Primary"
|
||||
Priority="-1"
|
||||
UseOriginalImage="True"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n Account}"
|
||||
AutomationId="AccountIconButton" />
|
||||
<ToolbarItem x:Name="_closeButton" Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<StackLayout x:Name="_mainLayout" x:Key="mainLayout" Spacing="30" Padding="20, 50, 20, 0">
|
||||
<Image
|
||||
x:Name="_logo"
|
||||
Source="logo.png"
|
||||
VerticalOptions="Center" />
|
||||
<Label Text="{u:I18n LoginOrCreateNewAccount}"
|
||||
StyleClass="text-lg"
|
||||
HorizontalTextAlignment="Center"/>
|
||||
<StackLayout
|
||||
StyleClass="box-row">
|
||||
<Label
|
||||
Text="{u:I18n EmailAddress}"
|
||||
StyleClass="box-label" />
|
||||
<Entry
|
||||
x:Name="_email"
|
||||
Text="{Binding Email}"
|
||||
Keyboard="Email"
|
||||
StyleClass="box-value"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding ContinueCommand}"
|
||||
AutomationId="EmailAddressEntry"
|
||||
>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{DynamicResource MutedColor}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Entry>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
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}" />
|
||||
</StackLayout.GestureRecognizers>
|
||||
<Label
|
||||
Text="{u:I18n RememberMe}"
|
||||
StyleClass="text-sm"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="Center"
|
||||
VerticalTextAlignment="Center"
|
||||
/>
|
||||
<Switch
|
||||
Scale="0.8"
|
||||
IsToggled="{Binding RememberEmail}"
|
||||
VerticalOptions="Center"
|
||||
AutomationId="RememberMeSwitch"
|
||||
/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<Button Text="{u:I18n Continue}"
|
||||
StyleClass="btn-primary"
|
||||
IsEnabled="{Binding CanContinue}"
|
||||
Command="{Binding ContinueCommand}"
|
||||
AutomationId="ContinueButton"
|
||||
/>
|
||||
|
||||
<Label FormattedText="{Binding CreateAccountText}"
|
||||
Margin="0, 10"
|
||||
StyleClass="box-footer-label"
|
||||
AutomationId="CreateAccountLabel">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CreateAccountCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<AbsoluteLayout
|
||||
x:Name="_absLayout"
|
||||
VerticalOptions="FillAndExpand"
|
||||
HorizontalOptions="FillAndExpand">
|
||||
<ContentView
|
||||
x:Name="_mainContent"
|
||||
AbsoluteLayout.LayoutFlags="All"
|
||||
AbsoluteLayout.LayoutBounds="0, 0, 1, 1">
|
||||
</ContentView>
|
||||
|
||||
<controls:AccountSwitchingOverlayView
|
||||
x:Name="_accountListOverlay"
|
||||
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
|
||||
AbsoluteLayout.LayoutFlags="All"
|
||||
MainPage="{Binding Source={x:Reference _page}}"
|
||||
BindingContext="{Binding AccountSwitchingOverlayViewModel}"/>
|
||||
</AbsoluteLayout>
|
||||
</pages:BaseContentPage>
|
||||
@@ -1,162 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.PlatformConfiguration;
|
||||
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class BaseContentPage : ContentPage
|
||||
{
|
||||
private IStateService _stateService;
|
||||
private IDeviceActionService _deviceActionService;
|
||||
|
||||
protected int ShowModalAnimationDelay = 400;
|
||||
protected int ShowPageAnimationDelay = 100;
|
||||
|
||||
public BaseContentPage()
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
On<iOS>().SetUseSafeArea(true);
|
||||
On<iOS>().SetModalPresentationStyle(UIModalPresentationStyle.FullScreen);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? LastPageAction { get; set; }
|
||||
|
||||
public bool IsThemeDirty { get; set; }
|
||||
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
if (IsThemeDirty)
|
||||
{
|
||||
UpdateOnThemeChanged();
|
||||
}
|
||||
|
||||
await SaveActivityAsync();
|
||||
}
|
||||
|
||||
public bool DoOnce(Action action = null, int milliseconds = 1000)
|
||||
{
|
||||
if (LastPageAction.HasValue && (DateTime.UtcNow - LastPageAction.Value).TotalMilliseconds < milliseconds)
|
||||
{
|
||||
// Last action occurred recently.
|
||||
return false;
|
||||
}
|
||||
LastPageAction = DateTime.UtcNow;
|
||||
action?.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual Task UpdateOnThemeChanged()
|
||||
{
|
||||
IsThemeDirty = false;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected void SetActivityIndicator(ContentView targetView = null)
|
||||
{
|
||||
var indicator = new ActivityIndicator
|
||||
{
|
||||
IsRunning = true,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
Color = ThemeManager.GetResourceColor("PrimaryColor"),
|
||||
};
|
||||
if (targetView != null)
|
||||
{
|
||||
targetView.Content = indicator;
|
||||
}
|
||||
else
|
||||
{
|
||||
Content = indicator;
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task LoadOnAppearedAsync(View sourceView, bool fromModal, Func<Task> workFunction,
|
||||
ContentView targetView = null)
|
||||
{
|
||||
async Task DoWorkAsync()
|
||||
{
|
||||
await workFunction.Invoke();
|
||||
if (sourceView != null)
|
||||
{
|
||||
if (targetView != null)
|
||||
{
|
||||
targetView.Content = sourceView;
|
||||
}
|
||||
else
|
||||
{
|
||||
Content = sourceView;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
await DoWorkAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(fromModal ? ShowModalAnimationDelay : ShowPageAnimationDelay);
|
||||
Device.BeginInvokeOnMainThread(async () => await DoWorkAsync());
|
||||
});
|
||||
}
|
||||
|
||||
protected void RequestFocus(InputView input)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(ShowModalAnimationDelay);
|
||||
Device.BeginInvokeOnMainThread(() => input.Focus());
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task<bool> ShowAccountSwitcherAsync()
|
||||
{
|
||||
return await _stateService.GetActiveUserIdAsync() != null;
|
||||
}
|
||||
|
||||
protected async Task<AvatarImageSource> GetAvatarImageSourceAsync(bool useCurrentActiveAccount = true)
|
||||
{
|
||||
if (useCurrentActiveAccount)
|
||||
{
|
||||
var user = await _stateService.GetActiveUserCustomDataAsync(a => (a?.Profile?.UserId, a?.Profile?.Name, a?.Profile?.Email, a?.Profile?.AvatarColor));
|
||||
return new AvatarImageSource(user.UserId, user.Name, user.Email, user.AvatarColor);
|
||||
}
|
||||
return new AvatarImageSource();
|
||||
}
|
||||
|
||||
private void SetServices()
|
||||
{
|
||||
if (_stateService == null)
|
||||
{
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
}
|
||||
if (_deviceActionService == null)
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveActivityAsync()
|
||||
{
|
||||
SetServices();
|
||||
if (await _stateService.GetActiveUserIdAsync() == null)
|
||||
{
|
||||
// Fresh install and/or all users logged out won't have an active user, skip saving last active time
|
||||
return;
|
||||
}
|
||||
|
||||
await _stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public abstract class BaseViewModel : ExtendedViewModel
|
||||
{
|
||||
private string _pageTitle = string.Empty;
|
||||
private AvatarImageSource _avatar;
|
||||
private LazyResolve<IDeviceActionService> _deviceActionService = new LazyResolve<IDeviceActionService>();
|
||||
private LazyResolve<IPlatformUtilsService> _platformUtilsService = new LazyResolve<IPlatformUtilsService>();
|
||||
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
|
||||
|
||||
public string PageTitle
|
||||
{
|
||||
get => _pageTitle;
|
||||
set => SetProperty(ref _pageTitle, value);
|
||||
}
|
||||
|
||||
public AvatarImageSource AvatarImageSource
|
||||
{
|
||||
get => _avatar ?? new AvatarImageSource();
|
||||
set => SetProperty(ref _avatar, value);
|
||||
}
|
||||
|
||||
public ContentPage Page { get; set; }
|
||||
|
||||
protected void HandleException(Exception ex, string message = null)
|
||||
{
|
||||
if (ex is ApiException apiException && apiException.Error != null)
|
||||
{
|
||||
message = apiException.Error.GetSingleMessage();
|
||||
}
|
||||
|
||||
Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _deviceActionService.Value.HideLoadingAsync();
|
||||
await _platformUtilsService.Value.ShowDialogAsync(message ?? AppResources.GenericErrorMessage);
|
||||
}).FireAndForget();
|
||||
_logger.Value.Exception(ex);
|
||||
}
|
||||
|
||||
protected AsyncCommand CreateDefaultAsyncCommnad(Func<Task> execute, Func<object, bool> canExecute = null)
|
||||
{
|
||||
return new AsyncCommand(execute,
|
||||
canExecute,
|
||||
ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
protected async Task<bool> HasConnectivityAsync()
|
||||
{
|
||||
if (Connectivity.NetworkAccess == NetworkAccess.None)
|
||||
{
|
||||
await _platformUtilsService.Value.ShowDialogAsync(
|
||||
AppResources.InternetConnectionRequiredMessage,
|
||||
AppResources.InternetConnectionRequiredTitle);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class AutofillSettingsPageViewModel
|
||||
{
|
||||
public bool SupportsiOSAutofill => Device.RuntimePlatform == Device.iOS && _deviceActionService.SupportsAutofillServices();
|
||||
|
||||
public ICommand GoToPasswordAutofillCommand { get; private set; }
|
||||
public ICommand GoToAppExtensionCommand { get; private set; }
|
||||
|
||||
private void InitIOSCommands()
|
||||
{
|
||||
GoToPasswordAutofillCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new AutofillPage())));
|
||||
GoToAppExtensionCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new ExtensionPage())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class GroupingsPageTOTPListItem : ExtendedViewModel, IGroupingsPageListItem
|
||||
{
|
||||
private readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
||||
private readonly ITotpService _totpService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private CipherView _cipher;
|
||||
|
||||
private bool _websiteIconsEnabled;
|
||||
private string _iconImageSource = string.Empty;
|
||||
|
||||
private double _progress;
|
||||
private string _totpSec;
|
||||
private string _totpCodeFormatted;
|
||||
private TotpHelper _totpTickHelper;
|
||||
|
||||
|
||||
public GroupingsPageTOTPListItem(CipherView cipherView, bool websiteIconsEnabled)
|
||||
{
|
||||
_totpService = ServiceContainer.Resolve<ITotpService>("totpService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
|
||||
Cipher = cipherView;
|
||||
WebsiteIconsEnabled = websiteIconsEnabled;
|
||||
CopyCommand = new AsyncCommand(CopyToClipboardAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
_totpTickHelper = new TotpHelper(cipherView);
|
||||
}
|
||||
|
||||
public AsyncCommand CopyCommand { get; set; }
|
||||
|
||||
public CipherView Cipher
|
||||
{
|
||||
get => _cipher;
|
||||
set => SetProperty(ref _cipher, value);
|
||||
}
|
||||
|
||||
public string TotpCodeFormatted
|
||||
{
|
||||
get => _totpCodeFormatted;
|
||||
set => SetProperty(ref _totpCodeFormatted, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(TotpCodeFormattedStart),
|
||||
nameof(TotpCodeFormattedEnd),
|
||||
});
|
||||
}
|
||||
|
||||
public string TotpSec
|
||||
{
|
||||
get => _totpSec;
|
||||
set => SetProperty(ref _totpSec, value);
|
||||
}
|
||||
public double Progress
|
||||
{
|
||||
get => _progress;
|
||||
set => SetProperty(ref _progress, value);
|
||||
}
|
||||
public bool WebsiteIconsEnabled
|
||||
{
|
||||
get => _websiteIconsEnabled;
|
||||
set => SetProperty(ref _websiteIconsEnabled, value);
|
||||
}
|
||||
|
||||
public bool ShowIconImage
|
||||
{
|
||||
get => WebsiteIconsEnabled
|
||||
&& !string.IsNullOrWhiteSpace(Cipher.Login?.Uri)
|
||||
&& IconImageSource != null;
|
||||
}
|
||||
|
||||
public string IconImageSource
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconImageSource == string.Empty) // default value since icon source can return null
|
||||
{
|
||||
_iconImageSource = IconImageHelper.GetLoginIconImage(Cipher);
|
||||
}
|
||||
return _iconImageSource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string TotpCodeFormattedStart => TotpCodeFormatted?.Split(' ')[0];
|
||||
|
||||
public string TotpCodeFormattedEnd => TotpCodeFormatted?.Split(' ')[1];
|
||||
|
||||
public async Task CopyToClipboardAsync()
|
||||
{
|
||||
await _clipboardService.CopyTextAsync(TotpCodeFormatted?.Replace(" ", string.Empty));
|
||||
_platformUtilsService.ShowToast("info", null, string.Format(AppResources.ValueHasBeenCopied, AppResources.VerificationCodeTotp));
|
||||
}
|
||||
|
||||
public async Task TotpTickAsync()
|
||||
{
|
||||
await _totpTickHelper.GenerateNewTotpValues();
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
Progress = _totpTickHelper.Progress;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using Android.Views;
|
||||
using System;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Utilities;
|
||||
using Bit.App.Droid.Utilities;
|
||||
|
||||
namespace Bit.Droid.Accessibility
|
||||
{
|
||||
@@ -10,8 +10,13 @@ using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Views.Accessibility;
|
||||
using Android.Widget;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core;
|
||||
using Application = Android.App.Application;
|
||||
using View = Android.Views.View;
|
||||
using Resource = Bit.Core.Resource;
|
||||
using Point = Android.Graphics.Point;
|
||||
using Rect = Android.Graphics.Rect;
|
||||
|
||||
namespace Bit.Droid.Accessibility
|
||||
{
|
||||
@@ -705,7 +710,7 @@ namespace Bit.Droid.Accessibility
|
||||
public static LinearLayout GetOverlayView(Context context)
|
||||
{
|
||||
var inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
|
||||
var view = (LinearLayout)inflater.Inflate(Resource.Layout.autofill_listitem, null);
|
||||
var view = (LinearLayout)inflater.Inflate(Bit.Core.Resource.Layout.autofill_listitem, null);
|
||||
var text1 = (TextView)view.FindViewById(Resource.Id.text1);
|
||||
var text2 = (TextView)view.FindViewById(Resource.Id.text2);
|
||||
var icon = (ImageView)view.FindViewById(Resource.Id.icon);
|
||||
@@ -9,9 +9,10 @@ using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Views.Accessibility;
|
||||
using Android.Widget;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using View = Android.Views.View;
|
||||
|
||||
namespace Bit.Droid.Accessibility
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
<?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.12.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2024.2.2" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
@@ -4,14 +4,14 @@ using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Utilities;
|
||||
using Bit.App.Droid.Utilities;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
[Activity(
|
||||
NoHistory = true,
|
||||
LaunchMode = LaunchMode.SingleTop)]
|
||||
public class AutofillExternalSelectionActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
public class AutofillExternalSelectionActivity : MauiAppCompatActivity
|
||||
{
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
@@ -12,15 +12,17 @@ using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Widget.Inline;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Enums;
|
||||
using Android.Views.Autofill;
|
||||
using AndroidX.AutoFill.Inline;
|
||||
using AndroidX.AutoFill.Inline.V1;
|
||||
using Bit.Core.Abstractions;
|
||||
using SaveFlags = Android.Service.Autofill.SaveFlags;
|
||||
using Bit.Droid.Utilities;
|
||||
using Bit.App.Droid.Utilities;
|
||||
using Bit.Core.Services;
|
||||
using Resource = Bit.Core.Resource;
|
||||
using BlendMode = Android.Graphics.BlendMode;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
public class CredentialProviderConstants
|
||||
{
|
||||
public const string CredentialProviderCipherId = "credentialProviderCipherId";
|
||||
public const string CredentialDataIntentExtra = "CREDENTIAL_DATA";
|
||||
public const string CredentialIdIntentExtra = "credId";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using AndroidX.Credentials.Provider;
|
||||
using AndroidX.Credentials.WebAuthn;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.App.Droid.Utilities;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
[Activity(
|
||||
NoHistory = true,
|
||||
LaunchMode = LaunchMode.SingleTop)]
|
||||
public class CredentialProviderSelectionActivity : MauiAppCompatActivity
|
||||
{
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
Intent?.Validate();
|
||||
base.OnCreate(bundle);
|
||||
|
||||
var cipherId = Intent?.GetStringExtra(CredentialProviderConstants.CredentialProviderCipherId);
|
||||
if (string.IsNullOrEmpty(cipherId))
|
||||
{
|
||||
SetResult(Result.Canceled);
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
GetCipherAndPerformPasskeyAuthAsync(cipherId).FireAndForget();
|
||||
}
|
||||
|
||||
private async Task GetCipherAndPerformPasskeyAuthAsync(string cipherId)
|
||||
{
|
||||
// TODO this is a work in progress
|
||||
// https://developer.android.com/training/sign-in/credential-provider#passkeys-implement
|
||||
|
||||
var getRequest = PendingIntentHandler.RetrieveProviderGetCredentialRequest(Intent);
|
||||
// var publicKeyRequest = getRequest?.CredentialOptions as PublicKeyCredentialRequestOptions;
|
||||
|
||||
var requestInfo = Intent.GetBundleExtra(CredentialProviderConstants.CredentialDataIntentExtra);
|
||||
var credIdEnc = requestInfo?.GetString(CredentialProviderConstants.CredentialIdIntentExtra);
|
||||
|
||||
var cipherService = ServiceContainer.Resolve<ICipherService>();
|
||||
var cipher = await cipherService.GetAsync(cipherId);
|
||||
var decCipher = await cipher.DecryptAsync();
|
||||
|
||||
var passkey = decCipher.Login.Fido2Credentials.Find(f => f.CredentialId == credIdEnc);
|
||||
|
||||
var credId = Convert.FromBase64String(credIdEnc);
|
||||
// var privateKey = Convert.FromBase64String(passkey.PrivateKey);
|
||||
// var uid = Convert.FromBase64String(passkey.uid);
|
||||
|
||||
var origin = getRequest?.CallingAppInfo.Origin;
|
||||
var packageName = getRequest?.CallingAppInfo.PackageName;
|
||||
|
||||
// --- continue WIP here (save TOTP copy as last step) ---
|
||||
|
||||
// Copy TOTP if needed
|
||||
var autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
autofillHandler.Autofill(decCipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
147
src/App/Platforms/Android/Autofill/CredentialProviderService.cs
Normal file
147
src/App/Platforms/Android/Autofill/CredentialProviderService.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using AndroidX.Credentials.Provider;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using AndroidX.Credentials.Exceptions;
|
||||
using AndroidX.Credentials.WebAuthn;
|
||||
using Bit.Core.Models.View;
|
||||
using Resource = Microsoft.Maui.Resource;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
[Service(Permission = Manifest.Permission.BindCredentialProviderService, Label = "Bitwarden", Exported = true)]
|
||||
[IntentFilter(new string[] { "android.service.credentials.CredentialProviderService" })]
|
||||
[MetaData("android.credentials.provider", Resource = "@xml/provider")]
|
||||
[Register("com.x8bit.bitwarden.Autofill.CredentialProviderService")]
|
||||
public class CredentialProviderService : AndroidX.Credentials.Provider.CredentialProviderService
|
||||
{
|
||||
private const string GetPasskeyIntentAction = "PACKAGE_NAME.GET_PASSKEY";
|
||||
private const int UniqueRequestCode = 94556023;
|
||||
|
||||
private ICipherService _cipherService;
|
||||
private IUserVerificationService _userVerificationService;
|
||||
private IVaultTimeoutService _vaultTimeoutService;
|
||||
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
||||
|
||||
public override async void OnBeginCreateCredentialRequest(BeginCreateCredentialRequest request,
|
||||
CancellationSignal cancellationSignal, IOutcomeReceiver callback) => throw new NotImplementedException();
|
||||
|
||||
public override async void OnBeginGetCredentialRequest(BeginGetCredentialRequest request,
|
||||
CancellationSignal cancellationSignal, IOutcomeReceiver callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
_vaultTimeoutService ??= ServiceContainer.Resolve<IVaultTimeoutService>();
|
||||
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
var locked = await _vaultTimeoutService.IsLockedAsync();
|
||||
if (!locked)
|
||||
{
|
||||
var response = await ProcessGetCredentialsRequestAsync(request);
|
||||
callback.OnResult(response);
|
||||
}
|
||||
// TODO handle auth/unlock account flow
|
||||
}
|
||||
catch (GetCredentialException e)
|
||||
{
|
||||
_logger.Value.Exception(e);
|
||||
callback.OnError(e.ErrorMessage ?? "Error getting credentials");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Value.Exception(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<BeginGetCredentialResponse> ProcessGetCredentialsRequestAsync(
|
||||
BeginGetCredentialRequest request)
|
||||
{
|
||||
IList<CredentialEntry> credentialEntries = null;
|
||||
|
||||
foreach (var option in request.BeginGetCredentialOptions)
|
||||
{
|
||||
var credentialOption = option as BeginGetPublicKeyCredentialOption;
|
||||
if (credentialOption != null)
|
||||
{
|
||||
credentialEntries ??= new List<CredentialEntry>();
|
||||
((List<CredentialEntry>)credentialEntries).AddRange(
|
||||
await PopulatePasskeyDataAsync(request.CallingAppInfo, credentialOption));
|
||||
}
|
||||
}
|
||||
|
||||
if (credentialEntries == null)
|
||||
{
|
||||
return new BeginGetCredentialResponse();
|
||||
}
|
||||
|
||||
return new BeginGetCredentialResponse.Builder()
|
||||
.SetCredentialEntries(credentialEntries)
|
||||
.Build();
|
||||
}
|
||||
|
||||
private async Task<List<CredentialEntry>> PopulatePasskeyDataAsync(CallingAppInfo callingAppInfo,
|
||||
BeginGetPublicKeyCredentialOption option)
|
||||
{
|
||||
var packageName = callingAppInfo.PackageName;
|
||||
var origin = callingAppInfo.Origin;
|
||||
var signingInfo = callingAppInfo.SigningInfo;
|
||||
|
||||
var request = new PublicKeyCredentialRequestOptions(option.RequestJson);
|
||||
|
||||
var passkeyEntries = new List<CredentialEntry>();
|
||||
|
||||
_cipherService ??= ServiceContainer.Resolve<ICipherService>();
|
||||
var ciphers = await _cipherService.GetAllDecryptedForUrlAsync(origin);
|
||||
if (ciphers == null)
|
||||
{
|
||||
return passkeyEntries;
|
||||
}
|
||||
|
||||
var passkeyCiphers = ciphers.Where(cipher => cipher.HasFido2Credential).ToList();
|
||||
if (!passkeyCiphers.Any())
|
||||
{
|
||||
return passkeyEntries;
|
||||
}
|
||||
|
||||
foreach (var cipher in passkeyCiphers)
|
||||
{
|
||||
var passkeyEntry = GetPasskey(cipher, option);
|
||||
passkeyEntries.Add(passkeyEntry);
|
||||
}
|
||||
|
||||
return passkeyEntries;
|
||||
}
|
||||
|
||||
private PublicKeyCredentialEntry GetPasskey(CipherView cipher, BeginGetPublicKeyCredentialOption option)
|
||||
{
|
||||
var credDataBundle = new Bundle();
|
||||
credDataBundle.PutString(CredentialProviderConstants.CredentialIdIntentExtra,
|
||||
cipher.Login.MainFido2Credential.CredentialId);
|
||||
|
||||
var intent = new Intent(ApplicationContext, typeof(CredentialProviderSelectionActivity))
|
||||
.SetAction(GetPasskeyIntentAction).SetPackage(Constants.PACKAGE_NAME);
|
||||
intent.PutExtra(CredentialProviderConstants.CredentialDataIntentExtra, credDataBundle);
|
||||
intent.PutExtra(CredentialProviderConstants.CredentialProviderCipherId, cipher.Id);
|
||||
var pendingIntent = PendingIntent.GetActivity(ApplicationContext, UniqueRequestCode, intent,
|
||||
PendingIntentFlags.Mutable | PendingIntentFlags.UpdateCurrent);
|
||||
|
||||
return new PublicKeyCredentialEntry.Builder(
|
||||
ApplicationContext,
|
||||
cipher.Login.Username ?? "No username",
|
||||
pendingIntent,
|
||||
option)
|
||||
.SetDisplayName(cipher.Name)
|
||||
.SetIcon(Icon.CreateWithResource(ApplicationContext, Resource.Drawable.icon))
|
||||
.Build();
|
||||
}
|
||||
|
||||
public override void OnClearCredentialStateRequest(ProviderClearCredentialStateRequest request,
|
||||
CancellationSignal cancellationSignal, IOutcomeReceiver callback) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Android.Views.Autofill;
|
||||
using static Android.App.Assist.AssistStructure;
|
||||
using Android.Text;
|
||||
using static Android.Views.ViewStructure;
|
||||
using View = Android.Views.View;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
@@ -4,6 +4,7 @@ using Android.Views.Autofill;
|
||||
using System.Linq;
|
||||
using Android.Text;
|
||||
using Android.Views;
|
||||
using View = Android.Views.View;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Bit.Core.Enums;
|
||||
using Android.Views;
|
||||
using Bit.Core.Models.View;
|
||||
using Resource = Bit.Core.Resource;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
14
src/App/Platforms/Android/Handlers/ButtonHandlerMappings.cs
Normal file
14
src/App/Platforms/Android/Handlers/ButtonHandlerMappings.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
public class ButtonHandlerMappings
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
Microsoft.Maui.Handlers.ButtonHandler.Mapper.AppendToMapping("CustomButtonHandler", (handler, button) =>
|
||||
{
|
||||
// WORKAROUND applied from https://github.com/dotnet/maui/issues/2918
|
||||
handler.PlatformView.StateListAnimator = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
134
src/App/Platforms/Android/Handlers/CustomTabbedPageHandler.cs
Normal file
134
src/App/Platforms/Android/Handlers/CustomTabbedPageHandler.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using AndroidX.AppCompat.View.Menu;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Microsoft.Maui.Handlers;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
public partial class CustomTabbedPageHandler : TabbedViewHandler
|
||||
{
|
||||
private TabbedPage _tabbedPage;
|
||||
private BottomNavigationView _bottomNavigationView;
|
||||
private Android.Views.ViewGroup _bottomNavigationViewGroup;
|
||||
private ILogger _logger;
|
||||
|
||||
protected override void ConnectHandler(global::Android.Views.View platformView)
|
||||
{
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
if(VirtualView is TabbedPage tabbedPage)
|
||||
{
|
||||
_tabbedPage = tabbedPage;
|
||||
_tabbedPage.Loaded += TabbedPage_Loaded;
|
||||
}
|
||||
|
||||
base.ConnectHandler(platformView);
|
||||
}
|
||||
|
||||
private void TabbedPage_Loaded(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
//This layout should always be the same/fixed and therefore this should run with no issues. Nevertheless it's wrapped in try catch to avoid crashing in edge-case scenarios.
|
||||
_bottomNavigationViewGroup = (((sender as VisualElement).Handler as IPlatformViewHandler)
|
||||
.PlatformView
|
||||
.Parent
|
||||
.Parent as Android.Views.View)
|
||||
.FindViewById(Microsoft.Maui.Controls.Resource.Id.navigationlayout_bottomtabs) as Android.Views.ViewGroup;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
|
||||
if(_bottomNavigationViewGroup == null) { return; }
|
||||
|
||||
//If TabbedPage still doesn't have items we set an event to wait for them
|
||||
if (_bottomNavigationViewGroup.ChildCount == 0)
|
||||
{
|
||||
_bottomNavigationViewGroup.ChildViewAdded += View_ChildViewAdded;
|
||||
}
|
||||
else
|
||||
{ //If we already have items we can start listening immediately
|
||||
var bottomTabs = _bottomNavigationViewGroup.GetChildAt(0);
|
||||
ListenToItemReselected(bottomTabs);
|
||||
}
|
||||
}
|
||||
|
||||
private void ListenToItemReselected(Android.Views.View bottomTabs)
|
||||
{
|
||||
if(bottomTabs is BottomNavigationView bottomNavigationView)
|
||||
{
|
||||
//If there was an older _bottomNavigationView for some reason we want to make sure to unregister
|
||||
if(_bottomNavigationView != null)
|
||||
{
|
||||
_bottomNavigationView.ItemReselected -= BottomNavigationView_ItemReselected;
|
||||
_bottomNavigationView = null;
|
||||
}
|
||||
|
||||
_bottomNavigationView = bottomNavigationView;
|
||||
_bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
|
||||
_bottomNavigationView.ItemReselected += BottomNavigationView_ItemReselected;
|
||||
}
|
||||
}
|
||||
|
||||
private void View_ChildViewAdded(object sender, Android.Views.ViewGroup.ChildViewAddedEventArgs e)
|
||||
{
|
||||
//We shouldn't need this to be called anymore times so we can unregister to the events now
|
||||
if(_bottomNavigationViewGroup != null)
|
||||
{
|
||||
_bottomNavigationViewGroup.ChildViewAdded -= View_ChildViewAdded;
|
||||
}
|
||||
|
||||
var bottomTabs = e.Child;
|
||||
ListenToItemReselected(bottomTabs);
|
||||
}
|
||||
|
||||
private void BottomNavigationView_ItemReselected(object sender, Google.Android.Material.Navigation.NavigationBarView.ItemReselectedEventArgs e)
|
||||
{
|
||||
if(e.Item is MenuItemImpl item)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Tab '{item.Title}' was reselected so we'll PopToRoot.");
|
||||
MainThread.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tabbedPage.CurrentPage.Navigation.PopToRootAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//Currently the Disconnect Handler needs to be manually called from the App: https://github.com/dotnet/maui/issues/3604
|
||||
protected override void DisconnectHandler(global::Android.Views.View platformView)
|
||||
{
|
||||
if(_bottomNavigationViewGroup != null)
|
||||
{
|
||||
_bottomNavigationViewGroup.ChildViewAdded -= View_ChildViewAdded;
|
||||
_bottomNavigationViewGroup = null;
|
||||
}
|
||||
|
||||
if(_bottomNavigationView != null)
|
||||
{
|
||||
_bottomNavigationView.ItemReselected -= BottomNavigationView_ItemReselected;
|
||||
_bottomNavigationView = null;
|
||||
}
|
||||
|
||||
if(_tabbedPage != null)
|
||||
{
|
||||
_tabbedPage.Loaded -= TabbedPage_Loaded;
|
||||
_tabbedPage = null;
|
||||
}
|
||||
|
||||
_logger = null;
|
||||
|
||||
base.DisconnectHandler(platformView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Android.Views;
|
||||
using Bit.App.Controls;
|
||||
using Microsoft.Maui.Handlers;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
public class DatePickerHandlerMappings
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
DatePickerHandler.Mapper.AppendToMapping("CustomDatePickerHandler", (handler, datePicker) =>
|
||||
{
|
||||
if (datePicker is ExtendedDatePicker extDatePicker)
|
||||
{
|
||||
// center text
|
||||
handler.PlatformView.Gravity = GravityFlags.CenterHorizontal;
|
||||
|
||||
// use placeholder until NullableDate set
|
||||
if (!extDatePicker.NullableDate.HasValue)
|
||||
{
|
||||
handler.PlatformView.Text = extDatePicker.PlaceHolder;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Date), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Format), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
}
|
||||
|
||||
private static void UpdateTextPlaceholderOnFormatLikePlaceholder(IDatePickerHandler handler, IDatePicker datePicker)
|
||||
{
|
||||
if (datePicker is ExtendedDatePicker extDatePicker && extDatePicker.Format == extDatePicker.PlaceHolder)
|
||||
{
|
||||
handler.PlatformView.Text = extDatePicker.PlaceHolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/App/Platforms/Android/Handlers/EditorHandlerMappings.cs
Normal file
24
src/App/Platforms/Android/Handlers/EditorHandlerMappings.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.App.Droid.Utilities;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
public class EditorHandlerMappings
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
Microsoft.Maui.Handlers.EditorHandler.Mapper.AppendToMapping("CustomEditorHandler", (handler, editor) =>
|
||||
{
|
||||
handler.PlatformView.SetPadding(handler.PlatformView.PaddingLeft, handler.PlatformView.PaddingTop - 10, handler.PlatformView.PaddingRight,
|
||||
handler.PlatformView.PaddingBottom + 20);
|
||||
handler.PlatformView.ImeOptions = handler.PlatformView.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
});
|
||||
|
||||
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(IEditor.TextColor), (handler, editor) =>
|
||||
{
|
||||
handler.PlatformView.BackgroundTintList = ThemeHelpers.GetStateFocusedColors();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/App/Platforms/Android/Handlers/EntryHandlerMappings.cs
Normal file
63
src/App/Platforms/Android/Handlers/EntryHandlerMappings.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using Android.Graphics;
|
||||
using Android.Text;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Bit.App.Droid.Utilities;
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
public class EntryHandlerMappings
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("CustomEntryHandler", (handler, entry) =>
|
||||
{
|
||||
handler.PlatformView.SetPadding(handler.PlatformView.PaddingLeft, handler.PlatformView.PaddingTop - 10, handler.PlatformView.PaddingRight,
|
||||
handler.PlatformView.PaddingBottom + 20);
|
||||
handler.PlatformView.ImeOptions = handler.PlatformView.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
});
|
||||
|
||||
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(IEntry.TextColor), (handler, entry) =>
|
||||
{
|
||||
handler.PlatformView.BackgroundTintList = ThemeHelpers.GetStateFocusedColors();
|
||||
});
|
||||
|
||||
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(IEntry.IsPassword), (handler, entry) =>
|
||||
{
|
||||
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
|
||||
handler.PlatformView.InputType = entry.Keyboard.ToInputType();
|
||||
bool isText = (handler.PlatformView.InputType & InputTypes.ClassText) == InputTypes.ClassText,
|
||||
isNumber = (handler.PlatformView.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
|
||||
if (!isText && !isNumber)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.IsPassword)
|
||||
{
|
||||
// Element is a password field, set inputType to TextVariationPassword which disables
|
||||
// predictive text by default
|
||||
handler.PlatformView.InputType = handler.PlatformView.InputType |
|
||||
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Element is not a password field, set inputType to TextVariationVisiblePassword to
|
||||
// disable predictive text while still displaying the content.
|
||||
handler.PlatformView.InputType = handler.PlatformView.InputType |
|
||||
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
|
||||
}
|
||||
|
||||
// The workaround above forces a reset of the style properties, so we need to re-apply the font.
|
||||
// see https://xamarin.github.io/bugzilla-archives/33/33666/bug.html
|
||||
var typeface = Typeface.CreateFromAsset(handler.PlatformView.Context.Assets, "RobotoMono_Regular.ttf");
|
||||
if (handler.PlatformView is TextView label)
|
||||
{
|
||||
label.Typeface = typeface;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using Android.App;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
// Note: This Handler exists only to allow the ExtendedDatePicker to receive IsFocused events on Android. iOS Already does this with this fix: https://github.com/dotnet/maui/pull/13321
|
||||
// If MAUI eventually implements this behavior we can remove this handler completely. There is another Handler (DatePickerHandlerMappings) for the other DatePicker customizations.
|
||||
public partial class ExtendedDatePickerHandler : DatePickerHandler
|
||||
{
|
||||
|
||||
public static PropertyMapper<IDatePicker, ExtendedDatePickerHandler> PropertyMapper = new (DatePickerHandler.Mapper)
|
||||
{
|
||||
[nameof(IDatePicker.IsFocused)] = MapIsFocused
|
||||
};
|
||||
|
||||
public ExtendedDatePickerHandler() : base(PropertyMapper)
|
||||
{
|
||||
}
|
||||
|
||||
public static void MapIsFocused(ExtendedDatePickerHandler handler, IDatePicker datePicker)
|
||||
{
|
||||
if (handler.PlatformView.IsFocused == datePicker.IsFocused) return;
|
||||
|
||||
if (datePicker.IsFocused)
|
||||
{
|
||||
handler.PlatformView.RequestFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.PlatformView.ClearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private DatePickerDialog? _dialog;
|
||||
|
||||
protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
|
||||
{
|
||||
_dialog = base.CreateDatePickerDialog(year, month, day);
|
||||
return _dialog;
|
||||
}
|
||||
|
||||
protected override void ConnectHandler(MauiDatePicker platformView)
|
||||
{
|
||||
base.ConnectHandler(platformView);
|
||||
if (_dialog != null)
|
||||
{
|
||||
_dialog.ShowEvent += OnDialogShown;
|
||||
_dialog.DismissEvent += OnDialogDismissed;
|
||||
}
|
||||
}
|
||||
|
||||
//Currently the Disconnect Handler needs to be manually called from the App: https://github.com/dotnet/maui/issues/3604
|
||||
protected override void DisconnectHandler(MauiDatePicker platformView)
|
||||
{
|
||||
if (_dialog != null)
|
||||
{
|
||||
_dialog.ShowEvent -= OnDialogShown;
|
||||
_dialog.DismissEvent -= OnDialogDismissed;
|
||||
}
|
||||
base.DisconnectHandler(platformView);
|
||||
|
||||
_dialog = null;
|
||||
}
|
||||
|
||||
private void OnDialogShown(object sender, EventArgs e)
|
||||
{
|
||||
this.VirtualView.IsFocused = true;
|
||||
}
|
||||
|
||||
private void OnDialogDismissed(object sender, EventArgs e)
|
||||
{
|
||||
this.VirtualView.IsFocused = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user