mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 01:48:25 +03:00
stub out autofill ciphers listing page
This commit is contained in:
parent
d53bfae529
commit
3e633dc38e
7 changed files with 262 additions and 3 deletions
|
@ -57,6 +57,9 @@
|
|||
<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>
|
||||
|
|
|
@ -180,6 +180,10 @@ namespace Bit.App
|
|||
{
|
||||
Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions));
|
||||
}
|
||||
else if(_appOptions.Uri != null)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.MainPage = new TabsPage();
|
||||
|
|
96
src/App/Pages/Vault/AutofillCiphersPage.xaml
Normal file
96
src/App/Pages/Vault/AutofillCiphersPage.xaml
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?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.AutofillCiphersPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:fab="clr-namespace:Refractored.FabControl;assembly=Refractored.FabControl"
|
||||
x:DataType="pages:AutofillCiphersPageViewModel"
|
||||
Title="{Binding PageTitle}"
|
||||
x:Name="_page">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<pages:AutofillCiphersPageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="" Clicked="Search_Clicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<DataTemplate x:Key="cipherTemplate"
|
||||
x:DataType="pages:GroupingsPageListItem">
|
||||
<controls:CipherViewCell
|
||||
Cipher="{Binding Cipher}"
|
||||
ButtonCommand="{Binding BindingContext.CipherOptionsCommand, Source={x:Reference _page}}" />
|
||||
</DataTemplate>
|
||||
|
||||
<pages:GroupingsPageListItemSelector x:Key="listItemDataTemplateSelector"
|
||||
CipherTemplate="{StaticResource cipherTemplate}" />
|
||||
|
||||
<StackLayout x:Key="mainLayout" x:Name="_mainLayout">
|
||||
<StackLayout
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Padding="20, 0"
|
||||
Spacing="20"
|
||||
IsVisible="{Binding ShowNoData}">
|
||||
<Label
|
||||
Text="TODO: no data"
|
||||
HorizontalTextAlignment="Center"></Label>
|
||||
<Button
|
||||
Text="{u:I18n AddAnItem}"
|
||||
Clicked="AddButton_Clicked"></Button>
|
||||
</StackLayout>
|
||||
|
||||
<controls:ExtendedListView
|
||||
IsVisible="{Binding ShowList}"
|
||||
ItemsSource="{Binding GroupedItems}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
HasUnevenRows="true"
|
||||
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
|
||||
IsGroupingEnabled="True"
|
||||
ItemSelected="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
<x:Arguments>
|
||||
<ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
|
||||
</x:Arguments>
|
||||
|
||||
<ListView.GroupHeaderTemplate>
|
||||
<DataTemplate x:DataType="pages:GroupingsPageListGroup">
|
||||
<ViewCell>
|
||||
<StackLayout StyleClass="list-row-header">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.GroupHeaderTemplate>
|
||||
</controls:ExtendedListView>
|
||||
</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>
|
||||
<fab:FloatingActionButtonView
|
||||
x:Name="_fab"
|
||||
ImageName="plus.png"
|
||||
AbsoluteLayout.LayoutFlags="PositionProportional"
|
||||
AbsoluteLayout.LayoutBounds="1, 1, AutoSize, AutoSize">
|
||||
</fab:FloatingActionButtonView>
|
||||
</AbsoluteLayout>
|
||||
|
||||
</pages:BaseContentPage>
|
53
src/App/Pages/Vault/AutofillCiphersPage.xaml.cs
Normal file
53
src/App/Pages/Vault/AutofillCiphersPage.xaml.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using Bit.App.Models;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class AutofillCiphersPage : BaseContentPage
|
||||
{
|
||||
private AutofillCiphersPageViewModel _vm;
|
||||
private readonly AppOptions _appOptions;
|
||||
|
||||
public AutofillCiphersPage(AppOptions appOptions)
|
||||
{
|
||||
_appOptions = appOptions;
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as AutofillCiphersPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.Init(appOptions);
|
||||
}
|
||||
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
await LoadOnAppearedAsync(_mainLayout, false, async () =>
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}, _mainContent);
|
||||
}
|
||||
|
||||
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
((ListView)sender).SelectedItem = null;
|
||||
if(!DoOnce())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.SelectedItem is GroupingsPageListItem item && item.Cipher != null)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Search_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
105
src/App/Pages/Vault/AutofillCiphersPageViewModel.cs
Normal file
105
src/App/Pages/Vault/AutofillCiphersPageViewModel.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class AutofillCiphersPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly ISearchService _searchService;
|
||||
private CancellationTokenSource _searchCancellationTokenSource;
|
||||
|
||||
private AppOptions _appOptions;
|
||||
private string _name;
|
||||
private string _uri;
|
||||
private bool _showNoData;
|
||||
private bool _showList;
|
||||
|
||||
public AutofillCiphersPageViewModel()
|
||||
{
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
_searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
|
||||
GroupedItems = new ExtendedObservableCollection<GroupingsPageListGroup>();
|
||||
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
||||
}
|
||||
|
||||
public Command CipherOptionsCommand { get; set; }
|
||||
public ExtendedObservableCollection<GroupingsPageListGroup> GroupedItems { get; set; }
|
||||
|
||||
public bool ShowNoData
|
||||
{
|
||||
get => _showNoData;
|
||||
set => SetProperty(ref _showNoData, value);
|
||||
}
|
||||
|
||||
public bool ShowList
|
||||
{
|
||||
get => _showList;
|
||||
set => SetProperty(ref _showList, value);
|
||||
}
|
||||
|
||||
public void Init(AppOptions appOptions)
|
||||
{
|
||||
_appOptions = appOptions;
|
||||
_uri = appOptions.Uri;
|
||||
if(_uri.StartsWith(Constants.AndroidAppProtocol))
|
||||
{
|
||||
_name = _uri.Substring(Constants.AndroidAppProtocol.Length);
|
||||
}
|
||||
else if(!Uri.TryCreate(_uri, UriKind.Absolute, out Uri uri) ||
|
||||
!DomainName.TryParseBaseDomain(uri.Host, out _name))
|
||||
{
|
||||
_name = "--";
|
||||
}
|
||||
PageTitle = string.Format(AppResources.ItemsForUri, _name ?? "--");
|
||||
}
|
||||
|
||||
public async Task LoadAsync()
|
||||
{
|
||||
ShowNoData = false;
|
||||
ShowList = false;
|
||||
|
||||
var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(_uri, null);
|
||||
var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
|
||||
var matchingGroup = new GroupingsPageListGroup(matching, AppResources.MatchingItems, matching.Count, false);
|
||||
var fuzzy = ciphers.Item2?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
|
||||
var fuzzyGroup = new GroupingsPageListGroup(fuzzy, AppResources.PossibleMatchingItems, fuzzy.Count, false);
|
||||
GroupedItems.ResetWithRange(new List<GroupingsPageListGroup> { matchingGroup, fuzzyGroup });
|
||||
|
||||
ShowNoData = !matching.Any() && !fuzzy.Any();
|
||||
ShowList = !ShowNoData;
|
||||
}
|
||||
|
||||
public async Task SelectCipherAsync(CipherView cipher)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
private async void CipherOptionsAsync(CipherView cipher)
|
||||
{
|
||||
if(!(Page as BaseContentPage).DoOnce())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var option = await Page.DisplayActionSheet(cipher.Name, AppResources.Cancel, null, "1", "2");
|
||||
if(option == AppResources.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO: process options
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,7 +64,7 @@
|
|||
HorizontalTextAlignment="Center"></Label>
|
||||
<Button
|
||||
Text="{u:I18n AddAnItem}"
|
||||
Command="{Binding AddCipherCommand}"
|
||||
Clicked="AddButton_Clicked"
|
||||
IsVisible="{Binding ShowAddCipherButton}"></Button>
|
||||
</StackLayout>
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace Bit.App.Pages
|
|||
Refreshing = true;
|
||||
await LoadAsync();
|
||||
});
|
||||
AddCipherCommand = new Command(() => { /* TODO */ });
|
||||
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
||||
}
|
||||
|
||||
|
@ -104,7 +103,6 @@ namespace Bit.App.Pages
|
|||
}
|
||||
public ExtendedObservableCollection<GroupingsPageListGroup> GroupedItems { get; set; }
|
||||
public Command RefreshCommand { get; set; }
|
||||
public Command AddCipherCommand { get; set; }
|
||||
public Command<CipherView> CipherOptionsCommand { get; set; }
|
||||
|
||||
public async Task LoadAsync()
|
||||
|
|
Loading…
Reference in a new issue