1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-23 11:45:38 +01:00

floating action button on android

This commit is contained in:
Kyle Spearrin 2017-12-30 14:05:51 -05:00
parent 2235f1f7af
commit fbe1a6d4c5
15 changed files with 2682 additions and 328 deletions

View File

@ -868,5 +868,20 @@
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\drawable\bottom_nav_bg.xml" /> <AndroidResource Include="Resources\drawable\bottom_nav_bg.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\pencil.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project> </Project>

View File

@ -101,6 +101,7 @@ namespace Bit.Android
public static void SetIoc(Application application) public static void SetIoc(Application application)
{ {
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
CachedImageRenderer.Init(); CachedImageRenderer.Init();
ZXing.Net.Mobile.Forms.Android.Platform.Init(); ZXing.Net.Mobile.Forms.Android.Platform.Init();
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity); CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

View File

@ -20,6 +20,7 @@
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" /> <PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="Plugin.Fingerprint" Version="1.4.6-beta4" /> <PackageReference Include="Plugin.Fingerprint" Version="1.4.6-beta4" />
<PackageReference Include="Refractored.FloatingActionButtonForms" Version="2.1.0" />
<PackageReference Include="sqlite-net-pcl" Version="1.5.166-beta" /> <PackageReference Include="sqlite-net-pcl" Version="1.5.166-beta" />
<PackageReference Include="System.Net.Http" Version="4.3.3" /> <PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" /> <PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />

24
src/App/Controls/Fab.cs Normal file
View File

@ -0,0 +1,24 @@
using Refractored.FabControl;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class Fab : FloatingActionButtonView
{
public Fab(FabLayout fabLayout, string icon, Action<object, EventArgs> clickedAction)
{
ImageName = icon;
ColorNormal = Color.FromHex("3c8dbc");
ColorPressed = Color.FromHex("3883af");
ColorRipple = Color.FromHex("3883af");
Clicked = clickedAction;
AbsoluteLayout.SetLayoutFlags(this, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(this, new Rectangle(1, 1, AbsoluteLayout.AutoSize,
AbsoluteLayout.AutoSize));
fabLayout.Children.Add(this);
}
}
}

View File

@ -0,0 +1,16 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FabLayout : AbsoluteLayout
{
public FabLayout(View mainView)
{
VerticalOptions = LayoutOptions.FillAndExpand;
HorizontalOptions = LayoutOptions.FillAndExpand;
SetLayoutFlags(mainView, AbsoluteLayoutFlags.All);
SetLayoutBounds(mainView, new Rectangle(0, 0, 1, 1));
Children.Add(mainView);
}
}
}

View File

@ -25,32 +25,44 @@ namespace Bit.App.Pages
= new ExtendedObservableCollection<SettingsFolderPageModel>(); = new ExtendedObservableCollection<SettingsFolderPageModel>();
public ListView ListView { get; set; } public ListView ListView { get; set; }
private AddFolderToolBarItem AddItem { get; set; } private AddFolderToolBarItem AddItem { get; set; }
public Fab Fab { get; set; }
private void Init() private void Init()
{ {
AddItem = new AddFolderToolBarItem(this);
ToolbarItems.Add(AddItem);
ListView = new ListView ListView = new ListView
{ {
ItemsSource = Folders, ItemsSource = Folders,
ItemTemplate = new DataTemplate(() => new SettingsFolderListViewCell(this)) ItemTemplate = new DataTemplate(() => new SettingsFolderListViewCell(this))
}; };
if(Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.UWP) if(Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.UWP)
{ {
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Close)); ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Close));
} }
var fabLayout = new FabLayout(ListView);
if(Device.RuntimePlatform == Device.Android)
{
Fab = new Fab(fabLayout, "plus.png", async (sender, args) =>
{
await Navigation.PushForDeviceAsync(new SettingsAddFolderPage());
});
}
else
{
AddItem = new AddFolderToolBarItem(this);
ToolbarItems.Add(AddItem);
}
Title = AppResources.Folders; Title = AppResources.Folders;
Content = ListView; Content = fabLayout;
} }
protected override void OnAppearing() protected override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
ListView.ItemSelected += FolderSelected; ListView.ItemSelected += FolderSelected;
AddItem.InitEvents(); AddItem?.InitEvents();
LoadFoldersAsync().Wait(); LoadFoldersAsync().Wait();
} }
@ -58,7 +70,7 @@ namespace Bit.App.Pages
{ {
base.OnDisappearing(); base.OnDisappearing();
ListView.ItemSelected -= FolderSelected; ListView.ItemSelected -= FolderSelected;
AddItem.Dispose(); AddItem?.Dispose();
} }
private async Task LoadFoldersAsync() private async Task LoadFoldersAsync()

View File

@ -65,15 +65,11 @@ namespace Bit.App.Pages
public StackLayout NoDataStackLayout { get; set; } public StackLayout NoDataStackLayout { get; set; }
public StackLayout ResultsStackLayout { get; set; } public StackLayout ResultsStackLayout { get; set; }
private AddCipherToolBarItem AddCipherItem { get; set; } private AddCipherToolBarItem AddCipherItem { get; set; }
public ContentView ContentView { get; set; }
public Fab Fab { get; set; }
private void Init() private void Init()
{ {
if(!string.IsNullOrWhiteSpace(_uri) || _folder || !string.IsNullOrWhiteSpace(_folderId))
{
AddCipherItem = new AddCipherToolBarItem(this, _folderId);
ToolbarItems.Add(AddCipherItem);
}
ListView = new ListView(ListViewCachingStrategy.RecycleElement) ListView = new ListView(ListViewCachingStrategy.RecycleElement)
{ {
IsGroupingEnabled = true, IsGroupingEnabled = true,
@ -173,7 +169,26 @@ namespace Bit.App.Pages
LoadingIndicator.HorizontalOptions = LayoutOptions.Center; LoadingIndicator.HorizontalOptions = LayoutOptions.Center;
} }
Content = LoadingIndicator; ContentView = new ContentView
{
Content = LoadingIndicator
};
var fabLayout = new FabLayout(ContentView);
if(!string.IsNullOrWhiteSpace(_uri) || _folder || !string.IsNullOrWhiteSpace(_folderId))
{
if(Device.RuntimePlatform == Device.Android)
{
Fab = new Fab(fabLayout, "plus.png", (sender, args) => Helpers.AddCipher(this, _folderId));
}
else
{
AddCipherItem = new AddCipherToolBarItem(this, _folderId);
ToolbarItems.Add(AddCipherItem);
}
}
Content = fabLayout;
} }
private void SearchBar_SearchButtonPressed(object sender, EventArgs e) private void SearchBar_SearchButtonPressed(object sender, EventArgs e)
@ -350,7 +365,7 @@ namespace Bit.App.Pages
PresentationSections.ResetWithRange(sections); PresentationSections.ResetWithRange(sections);
if(PresentationSections.Count > 0 || !string.IsNullOrWhiteSpace(Search.Text)) if(PresentationSections.Count > 0 || !string.IsNullOrWhiteSpace(Search.Text))
{ {
Content = ResultsStackLayout; ContentView.Content = ResultsStackLayout;
if(string.IsNullOrWhiteSpace(_uri) && !_folder && string.IsNullOrWhiteSpace(_folderId) && if(string.IsNullOrWhiteSpace(_uri) && !_folder && string.IsNullOrWhiteSpace(_folderId) &&
string.IsNullOrWhiteSpace(_collectionId) && !_favorites) string.IsNullOrWhiteSpace(_collectionId) && !_favorites)
@ -360,11 +375,11 @@ namespace Bit.App.Pages
} }
else if(_syncService.SyncInProgress) else if(_syncService.SyncInProgress)
{ {
Content = LoadingIndicator; ContentView.Content = LoadingIndicator;
} }
else else
{ {
Content = NoDataStackLayout; ContentView.Content = NoDataStackLayout;
} }
}); });
} }

View File

@ -55,13 +55,13 @@ namespace Bit.App.Pages
public ActivityIndicator LoadingIndicator { get; set; } public ActivityIndicator LoadingIndicator { get; set; }
private AddCipherToolBarItem AddCipherItem { get; set; } private AddCipherToolBarItem AddCipherItem { get; set; }
private SearchToolBarItem SearchItem { get; set; } private SearchToolBarItem SearchItem { get; set; }
public ContentView ContentView { get; set; }
public Fab Fab { get; set; }
private void Init() private void Init()
{ {
SearchItem = new SearchToolBarItem(this); SearchItem = new SearchToolBarItem(this);
AddCipherItem = new AddCipherToolBarItem(this, null);
ToolbarItems.Add(SearchItem); ToolbarItems.Add(SearchItem);
ToolbarItems.Add(AddCipherItem);
ListView = new ListView(ListViewCachingStrategy.RecycleElement) ListView = new ListView(ListViewCachingStrategy.RecycleElement)
{ {
@ -112,7 +112,23 @@ namespace Bit.App.Pages
LoadingIndicator.HorizontalOptions = LayoutOptions.Center; LoadingIndicator.HorizontalOptions = LayoutOptions.Center;
} }
Content = LoadingIndicator; ContentView = new ContentView
{
Content = LoadingIndicator
};
var fabLayout = new FabLayout(ContentView);
if(Device.RuntimePlatform == Device.Android)
{
Fab = new Fab(fabLayout, "plus.png", (sender, args) => Helpers.AddCipher(this, null));
}
else
{
AddCipherItem = new AddCipherToolBarItem(this, null);
ToolbarItems.Add(AddCipherItem);
}
Content = fabLayout;
Title = AppResources.MyVault; Title = AppResources.MyVault;
} }
@ -254,15 +270,15 @@ namespace Bit.App.Pages
if(ciphers.Any() || folders.Any()) if(ciphers.Any() || folders.Any())
{ {
Content = ListView; ContentView.Content = ListView;
} }
else if(_syncService.SyncInProgress) else if(_syncService.SyncInProgress)
{ {
Content = LoadingIndicator; ContentView.Content = LoadingIndicator;
} }
else else
{ {
Content = NoDataStackLayout; ContentView.Content = NoDataStackLayout;
} }
}); });
}, cts.Token); }, cts.Token);

View File

@ -34,6 +34,7 @@ namespace Bit.App.Pages
Init(); Init();
} }
public Fab Fab { get; set; }
private VaultViewCipherPageModel Model { get; set; } = new VaultViewCipherPageModel(); private VaultViewCipherPageModel Model { get; set; } = new VaultViewCipherPageModel();
private ExtendedTableView Table { get; set; } private ExtendedTableView Table { get; set; }
private TableSection ItemInformationSection { get; set; } private TableSection ItemInformationSection { get; set; }
@ -71,16 +72,29 @@ namespace Bit.App.Pages
private void Init() private void Init()
{ {
EditItem = new EditCipherToolBarItem(this, _cipherId);
ToolbarItems.Add(EditItem);
if(Device.RuntimePlatform == Device.iOS) if(Device.RuntimePlatform == Device.iOS)
{ {
ToolbarItems.Add(new DismissModalToolBarItem(this)); ToolbarItems.Add(new DismissModalToolBarItem(this));
} }
InitProps(); InitProps();
var fabLayout = new FabLayout(Table);
if(Device.RuntimePlatform == Device.Android)
{
Fab = new Fab(fabLayout, "pencil.png", async (sender, args) =>
{
await Navigation.PushForDeviceAsync(new VaultEditCipherPage(_cipherId));
});
}
else
{
EditItem = new EditCipherToolBarItem(this, _cipherId);
ToolbarItems.Add(EditItem);
}
Content = fabLayout;
Title = AppResources.ViewItem; Title = AppResources.ViewItem;
Content = Table;
BindingContext = Model; BindingContext = Model;
} }
@ -257,7 +271,7 @@ namespace Bit.App.Pages
{ {
_pageDisappeared = false; _pageDisappeared = false;
NotesCell.Tapped += NotesCell_Tapped; NotesCell.Tapped += NotesCell_Tapped;
EditItem.InitEvents(); EditItem?.InitEvents();
var cipher = await _cipherService.GetByIdAsync(_cipherId); var cipher = await _cipherService.GetByIdAsync(_cipherId);
if(cipher == null) if(cipher == null)
@ -275,7 +289,7 @@ namespace Bit.App.Pages
{ {
_pageDisappeared = true; _pageDisappeared = true;
NotesCell.Tapped -= NotesCell_Tapped; NotesCell.Tapped -= NotesCell_Tapped;
EditItem.Dispose(); EditItem?.Dispose();
CleanupAttachmentCells(); CleanupAttachmentCells();
} }