mirror of
https://github.com/bitwarden/android.git
synced 2026-05-09 05:20:24 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07d57ebe8c | ||
|
|
325c88018c | ||
|
|
dcb1102746 | ||
|
|
636d3c02c4 | ||
|
|
5b119ded17 | ||
|
|
f25ae870c5 | ||
|
|
49673262e4 | ||
|
|
3ed814c1f7 |
@@ -8,7 +8,7 @@
|
||||
|
||||
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android.png" alt="" width="300" height="533" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios.png" alt="" width="300" height="533" />
|
||||
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android-myvault.png" alt="" width="300" height="533" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios.png" alt="" width="300" height="533" />
|
||||
|
||||
# Build/Run
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidManagedSymbols>true</AndroidManagedSymbols>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidSupportedAbis />
|
||||
<AndroidSupportedAbis>armeabi-v7a;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
|
||||
<AndroidLinkSkip>Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;Xamarin.Android.Net</AndroidLinkSkip>
|
||||
@@ -59,7 +59,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<DefineConstants>FDROID</DefineConstants>
|
||||
<AndroidSupportedAbis />
|
||||
<AndroidSupportedAbis>armeabi-v7a;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:versionCode="1"
|
||||
android:versionName="2.0.2"
|
||||
android:versionName="2.0.4"
|
||||
package="com.x8bit.bitwarden">
|
||||
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<item name="colorPrimary">@android:color/black</item>
|
||||
<item name="colorPrimaryDark">@android:color/black</item>
|
||||
<item name="colorControlNormal">@color/black_border</item>
|
||||
<item name="android:navigationBarColor">@android:color/black</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<!-- Nord theme -->
|
||||
|
||||
@@ -54,6 +54,11 @@ namespace Bit.Droid.Services
|
||||
netLanguage = "zh-Hans";
|
||||
}
|
||||
}
|
||||
else if(androidLanguage.StartsWith("iw"))
|
||||
{
|
||||
// Uncomment when we support RTL
|
||||
// netLanguage = "he";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Certain languages need to be converted to CultureInfo equivalent
|
||||
|
||||
@@ -46,7 +46,10 @@ namespace Bit.App.Pages
|
||||
if(EditMode)
|
||||
{
|
||||
var folder = await _folderService.GetAsync(FolderId);
|
||||
Folder = await folder.DecryptAsync();
|
||||
if(folder != null)
|
||||
{
|
||||
Folder = await folder.DecryptAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,17 +15,7 @@
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
|
||||
<ToolbarItem Text="{u:I18n Save}" Clicked="Save_Clicked" Order="Primary" />
|
||||
<ToolbarItem Text="{u:I18n Attachments}"
|
||||
Clicked="Attachments_Clicked"
|
||||
Order="Secondary"
|
||||
x:Name="_attachmentsItem" />
|
||||
<ToolbarItem Text="{u:I18n Delete}"
|
||||
Clicked="Delete_Clicked"
|
||||
Order="Secondary"
|
||||
IsDestructive="True"
|
||||
x:Name="_deleteItem" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Resources>
|
||||
@@ -33,16 +23,31 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:StringHasValueConverter x:Key="stringHasValue" />
|
||||
<u:IsNotNullConverter x:Key="notNull" />
|
||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
x:Key="closeItem" x:Name="_closeItem" />
|
||||
<ToolbarItem Text="{u:I18n Collections}"
|
||||
x:Key="collectionsItem"
|
||||
x:Name="_collectionsItem"
|
||||
Clicked="Collections_Clicked"
|
||||
Order="Secondary" />
|
||||
x:Key="collectionsItem"
|
||||
x:Name="_collectionsItem"
|
||||
Clicked="Collections_Clicked"
|
||||
Order="Secondary" />
|
||||
<ToolbarItem Text="{u:I18n Share}"
|
||||
x:Key="shareItem"
|
||||
x:Name="_shareItem"
|
||||
Clicked="Share_Clicked"
|
||||
Order="Secondary" />
|
||||
x:Key="shareItem"
|
||||
x:Name="_shareItem"
|
||||
Clicked="Share_Clicked"
|
||||
Order="Secondary" />
|
||||
<ToolbarItem Icon="more_vert.png" Clicked="More_Clicked" Order="Primary" x:Name="_moreItem"
|
||||
x:Key="moreItem" />
|
||||
<ToolbarItem Text="{u:I18n Attachments}"
|
||||
Clicked="Attachments_Clicked"
|
||||
Order="Secondary"
|
||||
x:Name="_attachmentsItem"
|
||||
x:Key="attachmentsItem" />
|
||||
<ToolbarItem Text="{u:I18n Delete}"
|
||||
Clicked="Delete_Clicked"
|
||||
Order="Secondary"
|
||||
IsDestructive="True"
|
||||
x:Name="_deleteItem"
|
||||
x:Key="deleteItem" />
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
|
||||
@@ -46,14 +46,15 @@ namespace Bit.App.Pages
|
||||
_vm.DefaultUri = uri ?? appOptions?.Uri;
|
||||
_vm.Init();
|
||||
SetActivityIndicator();
|
||||
if(!_vm.EditMode || Device.RuntimePlatform == Device.iOS)
|
||||
if(_vm.EditMode && Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
ToolbarItems.Remove(_attachmentsItem);
|
||||
ToolbarItems.Remove(_deleteItem);
|
||||
ToolbarItems.Add(_attachmentsItem);
|
||||
ToolbarItems.Add(_deleteItem);
|
||||
}
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
ToolbarItems.Add(_closeItem);
|
||||
ToolbarItems.Add(_moreItem);
|
||||
}
|
||||
|
||||
_typePicker.ItemDisplayBinding = new Binding("Key");
|
||||
@@ -237,6 +238,43 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private async void More_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if(!DoOnce())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var options = new List<string> { AppResources.Attachments };
|
||||
if(_vm.EditMode)
|
||||
{
|
||||
options.Add(_vm.Cipher.OrganizationId != null ? AppResources.Share : AppResources.Collections);
|
||||
}
|
||||
var selection = await DisplayActionSheet(AppResources.Options, AppResources.Cancel,
|
||||
_vm.EditMode ? AppResources.Delete : null, options.ToArray());
|
||||
if(selection == AppResources.Delete)
|
||||
{
|
||||
if(await _vm.DeleteAsync())
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
else if(selection == AppResources.Attachments)
|
||||
{
|
||||
var page = new AttachmentsPage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
else if(selection == AppResources.Collections)
|
||||
{
|
||||
var page = new CollectionsPage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
else if(selection == AppResources.Share)
|
||||
{
|
||||
var page = new SharePage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
}
|
||||
|
||||
private async void Close_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if(DoOnce())
|
||||
|
||||
@@ -381,10 +381,10 @@ namespace Bit.App.Pages
|
||||
return false;
|
||||
}
|
||||
|
||||
Cipher.Fields = Fields.Any() ? Fields.Select(f => f.Field).ToList() : null;
|
||||
Cipher.Fields = Fields != null && Fields.Any() ? Fields.Select(f => f.Field).ToList() : null;
|
||||
if(Cipher.Login != null)
|
||||
{
|
||||
Cipher.Login.Uris = Uris.ToList();
|
||||
Cipher.Login.Uris = Uris?.ToList();
|
||||
if(!EditMode && Cipher.Type == CipherType.Login && (Cipher.Login.Uris?.Count ?? 0) == 1 &&
|
||||
string.IsNullOrWhiteSpace(Cipher.Login.Uris.First().Uri))
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@ using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -31,7 +33,15 @@ namespace Bit.App.Pages
|
||||
base.OnAppearing();
|
||||
await LoadOnAppearedAsync(_mainLayout, false, async () =>
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
try
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
catch(Exception e) when(e.Message.Contains("No key."))
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}, _mainContent);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,10 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task SelectCipherAsync(CipherView cipher, bool fuzzy)
|
||||
{
|
||||
if(cipher == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(_deviceActionService.SystemMajorVersion() < 21)
|
||||
{
|
||||
await AppHelpers.CipherListOptions(Page, cipher);
|
||||
|
||||
@@ -16,13 +16,6 @@
|
||||
<pages:ViewPageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
|
||||
<ToolbarItem Text="{u:I18n Edit}" Clicked="EditToolbarItem_Clicked" Order="Primary" />
|
||||
<ToolbarItem Text="{u:I18n Attachments}" Clicked="Attachments_Clicked" Order="Secondary" />
|
||||
<ToolbarItem Text="{u:I18n Delete}" Clicked="Delete_Clicked" Order="Secondary" IsDestructive="True" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
@@ -38,6 +31,16 @@
|
||||
x:Name="_shareItem"
|
||||
Clicked="Share_Clicked"
|
||||
Order="Secondary" />
|
||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
x:Name="_closeItem" x:Key="closeItem" />
|
||||
<ToolbarItem Text="{u:I18n Edit}" Clicked="EditToolbarItem_Clicked" Order="Primary"
|
||||
x:Name="_editItem" x:Key="editItem" />
|
||||
<ToolbarItem Icon="more_vert.png" Clicked="More_Clicked" Order="Primary"
|
||||
x:Name="_moreItem" x:Key="moreItem" />
|
||||
<ToolbarItem Text="{u:I18n Attachments}" Clicked="Attachments_Clicked" Order="Secondary"
|
||||
x:Name="_attachmentsItem" x:Key="attachmentsItem" />
|
||||
<ToolbarItem Text="{u:I18n Delete}" Clicked="Delete_Clicked" Order="Secondary" IsDestructive="True"
|
||||
x:Name="_deleteItem" x:Key="deleteItem" />
|
||||
|
||||
<ScrollView x:Key="scrollView" x:Name="_scrollView">
|
||||
<StackLayout Spacing="20" x:Name="_mainLayout">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
@@ -25,15 +26,16 @@ namespace Bit.App.Pages
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
_absLayout.Children.Remove(_fab);
|
||||
ToolbarItems.RemoveAt(2);
|
||||
ToolbarItems.RemoveAt(2);
|
||||
ToolbarItems.Add(_closeItem);
|
||||
ToolbarItems.Add(_editItem);
|
||||
ToolbarItems.Add(_moreItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
ToolbarItems.RemoveAt(0);
|
||||
_fab.Clicked = EditButton_Clicked;
|
||||
_mainLayout.Padding = new Thickness(0, 0, 0, 75);
|
||||
ToolbarItems.Add(_attachmentsItem);
|
||||
ToolbarItems.Add(_deleteItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +147,40 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private async void More_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if(!DoOnce())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var options = new List<string> { AppResources.Attachments };
|
||||
options.Add(_vm.Cipher.OrganizationId != null ? AppResources.Share : AppResources.Collections);
|
||||
var selection = await DisplayActionSheet(AppResources.Options, AppResources.Cancel,
|
||||
AppResources.Delete, options.ToArray());
|
||||
if(selection == AppResources.Delete)
|
||||
{
|
||||
if(await _vm.DeleteAsync())
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
else if(selection == AppResources.Attachments)
|
||||
{
|
||||
var page = new AttachmentsPage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
else if(selection == AppResources.Collections)
|
||||
{
|
||||
var page = new CollectionsPage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
else if(selection == AppResources.Share)
|
||||
{
|
||||
var page = new SharePage(_vm.CipherId);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
}
|
||||
|
||||
private async void Close_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if(DoOnce())
|
||||
|
||||
@@ -94,7 +94,11 @@ namespace Bit.App.Services
|
||||
if((uri.StartsWith("http://") || uri.StartsWith("https://")) &&
|
||||
Uri.TryCreate(uri, UriKind.Absolute, out var parsedUri))
|
||||
{
|
||||
Browser.OpenAsync(uri, BrowserLaunchMode.External);
|
||||
try
|
||||
{
|
||||
Browser.OpenAsync(uri, BrowserLaunchMode.External);
|
||||
}
|
||||
catch(FeatureNotSupportedException) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.8bit.bitwarden</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.2</string>
|
||||
<string>2.0.4</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>50</string>
|
||||
<key>CFBundleIconName</key>
|
||||
|
||||
BIN
src/iOS/Resources/more.png
Normal file
BIN
src/iOS/Resources/more.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 145 B |
BIN
src/iOS/Resources/more@2x.png
Normal file
BIN
src/iOS/Resources/more@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 348 B |
BIN
src/iOS/Resources/more@3x.png
Normal file
BIN
src/iOS/Resources/more@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 555 B |
BIN
src/iOS/Resources/more_vert.png
Normal file
BIN
src/iOS/Resources/more_vert.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 164 B |
BIN
src/iOS/Resources/more_vert@2x.png
Normal file
BIN
src/iOS/Resources/more_vert@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 242 B |
BIN
src/iOS/Resources/more_vert@3x.png
Normal file
BIN
src/iOS/Resources/more_vert@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 338 B |
@@ -331,4 +331,22 @@
|
||||
<Visible>false</Visible>
|
||||
</ImageAsset>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more%403x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more%402x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more_vert%403x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more_vert.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BundleResource Include="Resources\more_vert%402x.png" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user