mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 02:18:27 +03:00
add uri and add buttons of search page
This commit is contained in:
parent
186f839569
commit
f5896be699
6 changed files with 144 additions and 47 deletions
|
@ -67,6 +67,7 @@
|
||||||
<Compile Include="Abstractions\Services\ISecureStorageService.cs" />
|
<Compile Include="Abstractions\Services\ISecureStorageService.cs" />
|
||||||
<Compile Include="Abstractions\Services\ISqlService.cs" />
|
<Compile Include="Abstractions\Services\ISqlService.cs" />
|
||||||
<Compile Include="Constants.cs" />
|
<Compile Include="Constants.cs" />
|
||||||
|
<Compile Include="Controls\AddCipherToolbarItem.cs" />
|
||||||
<Compile Include="Controls\HybridWebView.cs" />
|
<Compile Include="Controls\HybridWebView.cs" />
|
||||||
<Compile Include="Controls\ExtendedToolbarItem.cs" />
|
<Compile Include="Controls\ExtendedToolbarItem.cs" />
|
||||||
<Compile Include="Controls\DismissModalToolBarItem.cs" />
|
<Compile Include="Controls\DismissModalToolBarItem.cs" />
|
||||||
|
|
16
src/App/Controls/AddCipherToolbarItem.cs
Normal file
16
src/App/Controls/AddCipherToolbarItem.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using Bit.App.Resources;
|
||||||
|
using Bit.App.Utilities;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class AddCipherToolbarItem : ExtendedToolbarItem
|
||||||
|
{
|
||||||
|
public AddCipherToolbarItem(Page page, string folderId)
|
||||||
|
: base(() => Helpers.AddCipher(page, folderId))
|
||||||
|
{
|
||||||
|
Text = AppResources.Add;
|
||||||
|
Icon = "plus.png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ namespace Bit.App.Pages
|
||||||
private readonly IAppInfoService _appInfoService;
|
private readonly IAppInfoService _appInfoService;
|
||||||
private readonly IDeviceInfoService _deviceInfo;
|
private readonly IDeviceInfoService _deviceInfo;
|
||||||
private readonly IDeviceActionService _deviceActionService;
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
|
private readonly string _defaultFolderId;
|
||||||
private readonly string _defaultUri;
|
private readonly string _defaultUri;
|
||||||
private readonly string _defaultName;
|
private readonly string _defaultName;
|
||||||
private readonly string _defaultUsername;
|
private readonly string _defaultUsername;
|
||||||
|
@ -60,9 +61,10 @@ namespace Bit.App.Pages
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VaultAddCipherPage(CipherType type, string defaultUri = null,
|
public VaultAddCipherPage(CipherType type, string defaultUri = null, string defaultName = null,
|
||||||
string defaultName = null, bool fromAutofill = false, bool doInit = true)
|
bool fromAutofill = false, bool doInit = true, string defaultFolderId = null)
|
||||||
{
|
{
|
||||||
|
_defaultFolderId = defaultFolderId;
|
||||||
_type = type;
|
_type = type;
|
||||||
_defaultUri = defaultUri;
|
_defaultUri = defaultUri;
|
||||||
_defaultName = defaultName;
|
_defaultName = defaultName;
|
||||||
|
@ -146,11 +148,19 @@ namespace Bit.App.Pages
|
||||||
var folderOptions = new List<string> { AppResources.FolderNone };
|
var folderOptions = new List<string> { AppResources.FolderNone };
|
||||||
Folders = _folderService.GetAllAsync().GetAwaiter().GetResult()
|
Folders = _folderService.GetAllAsync().GetAwaiter().GetResult()
|
||||||
.OrderBy(f => f.Name?.Decrypt()).ToList();
|
.OrderBy(f => f.Name?.Decrypt()).ToList();
|
||||||
|
var selectedIndex = 0;
|
||||||
|
var i = 1;
|
||||||
foreach(var folder in Folders)
|
foreach(var folder in Folders)
|
||||||
{
|
{
|
||||||
|
if(folder.Id == _defaultFolderId)
|
||||||
|
{
|
||||||
|
selectedIndex = i;
|
||||||
|
}
|
||||||
folderOptions.Add(folder.Name.Decrypt());
|
folderOptions.Add(folder.Name.Decrypt());
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
FolderCell = new FormPickerCell(AppResources.Folder, folderOptions.ToArray());
|
FolderCell = new FormPickerCell(AppResources.Folder, folderOptions.ToArray());
|
||||||
|
FolderCell.Picker.SelectedIndex = selectedIndex;
|
||||||
|
|
||||||
// Favorite
|
// Favorite
|
||||||
FavoriteCell = new ExtendedSwitchCell { Text = AppResources.Favorite };
|
FavoriteCell = new ExtendedSwitchCell { Text = AppResources.Favorite };
|
||||||
|
|
|
@ -12,7 +12,6 @@ using Plugin.Settings.Abstractions;
|
||||||
using Plugin.Connectivity.Abstractions;
|
using Plugin.Connectivity.Abstractions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Bit.App.Enums;
|
|
||||||
using static Bit.App.Models.Page.VaultListPageModel;
|
using static Bit.App.Models.Page.VaultListPageModel;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
|
@ -57,13 +56,13 @@ namespace Bit.App.Pages
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public StackLayout NoDataStackLayout { get; set; }
|
public StackLayout NoDataStackLayout { get; set; }
|
||||||
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; }
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
SearchItem = new SearchToolBarItem(this);
|
SearchItem = new SearchToolBarItem(this);
|
||||||
AddCipherItem = new AddCipherToolBarItem(this);
|
AddCipherItem = new AddCipherToolbarItem(this, null);
|
||||||
ToolbarItems.Add(SearchItem);
|
ToolbarItems.Add(SearchItem);
|
||||||
ToolbarItems.Add(AddCipherItem);
|
ToolbarItems.Add(AddCipherItem);
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ namespace Bit.App.Pages
|
||||||
var addCipherButton = new ExtendedButton
|
var addCipherButton = new ExtendedButton
|
||||||
{
|
{
|
||||||
Text = AppResources.AddAnItem,
|
Text = AppResources.AddAnItem,
|
||||||
Command = new Command(() => AddCipher()),
|
Command = new Command(() => Helpers.AddCipher(this, null)),
|
||||||
Style = (Style)Application.Current.Resources["btn-primaryAccent"]
|
Style = (Style)Application.Current.Resources["btn-primaryAccent"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,6 +134,37 @@ namespace Bit.App.Pages
|
||||||
SearchItem?.InitEvents();
|
SearchItem?.InitEvents();
|
||||||
|
|
||||||
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
||||||
|
|
||||||
|
if(_connectivity.IsConnected && Device.RuntimePlatform == Device.iOS)
|
||||||
|
{
|
||||||
|
var pushPromptShow = _settings.GetValueOrDefault(Constants.PushInitialPromptShown, false);
|
||||||
|
Action registerAction = () =>
|
||||||
|
{
|
||||||
|
var lastPushRegistration =
|
||||||
|
_settings.GetValueOrDefault(Constants.PushLastRegistrationDate, DateTime.MinValue);
|
||||||
|
if(!pushPromptShow || DateTime.UtcNow - lastPushRegistration > TimeSpan.FromDays(1))
|
||||||
|
{
|
||||||
|
_pushNotification.Register();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!pushPromptShow)
|
||||||
|
{
|
||||||
|
_settings.AddOrUpdateValue(Constants.PushInitialPromptShown, true);
|
||||||
|
_userDialogs.Alert(new AlertConfig
|
||||||
|
{
|
||||||
|
Message = AppResources.PushNotificationAlert,
|
||||||
|
Title = AppResources.EnableAutomaticSyncing,
|
||||||
|
OnAction = registerAction,
|
||||||
|
OkText = AppResources.OkGotIt
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check push registration once per day
|
||||||
|
registerAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisappearing()
|
protected override void OnDisappearing()
|
||||||
|
@ -236,49 +266,12 @@ namespace Bit.App.Pages
|
||||||
((ListView)sender).SelectedItem = null;
|
((ListView)sender).SelectedItem = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddCipher()
|
|
||||||
{
|
|
||||||
var type = await _userDialogs.ActionSheetAsync(AppResources.SelectTypeAdd, AppResources.Cancel, null, null,
|
|
||||||
AppResources.TypeLogin, AppResources.TypeCard, AppResources.TypeIdentity, AppResources.TypeSecureNote);
|
|
||||||
|
|
||||||
var selectedType = CipherType.SecureNote;
|
|
||||||
if(type == AppResources.Cancel)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(type == AppResources.TypeLogin)
|
|
||||||
{
|
|
||||||
selectedType = CipherType.Login;
|
|
||||||
}
|
|
||||||
else if(type == AppResources.TypeCard)
|
|
||||||
{
|
|
||||||
selectedType = CipherType.Card;
|
|
||||||
}
|
|
||||||
else if(type == AppResources.TypeIdentity)
|
|
||||||
{
|
|
||||||
selectedType = CipherType.Identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
var page = new VaultAddCipherPage(selectedType);
|
|
||||||
await Navigation.PushForDeviceAsync(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Search()
|
private async void Search()
|
||||||
{
|
{
|
||||||
var page = new ExtendedNavigationPage(new VaultSearchCiphersPage());
|
var page = new ExtendedNavigationPage(new VaultSearchCiphersPage());
|
||||||
await Navigation.PushModalAsync(page);
|
await Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AddCipherToolBarItem : ExtendedToolbarItem
|
|
||||||
{
|
|
||||||
public AddCipherToolBarItem(VaultListGroupingsPage page)
|
|
||||||
: base(() => page.AddCipher())
|
|
||||||
{
|
|
||||||
Text = AppResources.Add;
|
|
||||||
Icon = "plus.png";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SearchToolBarItem : ExtendedToolbarItem
|
private class SearchToolBarItem : ExtendedToolbarItem
|
||||||
{
|
{
|
||||||
public SearchToolBarItem(VaultListGroupingsPage page)
|
public SearchToolBarItem(VaultListGroupingsPage page)
|
||||||
|
|
|
@ -24,15 +24,17 @@ namespace Bit.App.Pages
|
||||||
private readonly ISettings _settings;
|
private readonly ISettings _settings;
|
||||||
private readonly IAppSettingsService _appSettingsService;
|
private readonly IAppSettingsService _appSettingsService;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||||
private readonly bool _favorites = false;
|
private readonly bool _favorites = false;
|
||||||
private readonly bool _folder = false;
|
private readonly bool _folder = false;
|
||||||
private readonly string _folderId = null;
|
private readonly string _folderId = null;
|
||||||
private readonly string _collectionId = null;
|
private readonly string _collectionId = null;
|
||||||
private readonly string _groupingName = null;
|
private readonly string _groupingName = null;
|
||||||
|
private readonly string _uri = null;
|
||||||
|
|
||||||
public VaultSearchCiphersPage(bool folder = false, string folderId = null,
|
public VaultSearchCiphersPage(bool folder = false, string folderId = null,
|
||||||
string collectionId = null, string groupingName = null, bool favorites = false)
|
string collectionId = null, string groupingName = null, bool favorites = false, string uri = null)
|
||||||
: base(true)
|
: base(true)
|
||||||
{
|
{
|
||||||
_folder = folder;
|
_folder = folder;
|
||||||
|
@ -40,6 +42,7 @@ namespace Bit.App.Pages
|
||||||
_collectionId = collectionId;
|
_collectionId = collectionId;
|
||||||
_favorites = favorites;
|
_favorites = favorites;
|
||||||
_groupingName = groupingName;
|
_groupingName = groupingName;
|
||||||
|
_uri = uri;
|
||||||
|
|
||||||
_cipherService = Resolver.Resolve<ICipherService>();
|
_cipherService = Resolver.Resolve<ICipherService>();
|
||||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||||
|
@ -48,6 +51,7 @@ namespace Bit.App.Pages
|
||||||
_settings = Resolver.Resolve<ISettings>();
|
_settings = Resolver.Resolve<ISettings>();
|
||||||
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
|
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
|
||||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||||
|
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -58,9 +62,16 @@ namespace Bit.App.Pages
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public SearchBar Search { get; set; }
|
public SearchBar Search { get; set; }
|
||||||
public StackLayout ResultsStackLayout { get; set; }
|
public StackLayout ResultsStackLayout { get; set; }
|
||||||
|
private AddCipherToolbarItem AddCipherItem { 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,
|
||||||
|
@ -70,7 +81,7 @@ namespace Bit.App.Pages
|
||||||
nameof(Section<Cipher>.Count))),
|
nameof(Section<Cipher>.Count))),
|
||||||
GroupShortNameBinding = new Binding(nameof(Section<Cipher>.Name)),
|
GroupShortNameBinding = new Binding(nameof(Section<Cipher>.Name)),
|
||||||
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
||||||
(Cipher c) => Helpers.CipherMoreClickedAsync(this, c, false)))
|
(Cipher c) => Helpers.CipherMoreClickedAsync(this, c, !string.IsNullOrWhiteSpace(_uri))))
|
||||||
};
|
};
|
||||||
|
|
||||||
if(Device.RuntimePlatform == Device.iOS)
|
if(Device.RuntimePlatform == Device.iOS)
|
||||||
|
@ -187,6 +198,18 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool OnBackButtonPressed()
|
||||||
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(_uri))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("BackClosed", _uri.StartsWith("http") ? "Website" : "App");
|
||||||
|
_deviceActionService.CloseAutofill();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnAppearing()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
|
@ -198,6 +221,7 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddCipherItem?.InitEvents();
|
||||||
ListView.ItemSelected += CipherSelected;
|
ListView.ItemSelected += CipherSelected;
|
||||||
Search.TextChanged += SearchBar_TextChanged;
|
Search.TextChanged += SearchBar_TextChanged;
|
||||||
Search.SearchButtonPressed += SearchBar_SearchButtonPressed;
|
Search.SearchButtonPressed += SearchBar_SearchButtonPressed;
|
||||||
|
@ -214,6 +238,7 @@ namespace Bit.App.Pages
|
||||||
base.OnDisappearing();
|
base.OnDisappearing();
|
||||||
MessagingCenter.Unsubscribe<ISyncService, bool>(_syncService, "SyncCompleted");
|
MessagingCenter.Unsubscribe<ISyncService, bool>(_syncService, "SyncCompleted");
|
||||||
|
|
||||||
|
AddCipherItem?.Dispose();
|
||||||
ListView.ItemSelected -= CipherSelected;
|
ListView.ItemSelected -= CipherSelected;
|
||||||
Search.TextChanged -= SearchBar_TextChanged;
|
Search.TextChanged -= SearchBar_TextChanged;
|
||||||
Search.SearchButtonPressed -= SearchBar_SearchButtonPressed;
|
Search.SearchButtonPressed -= SearchBar_SearchButtonPressed;
|
||||||
|
@ -291,8 +316,32 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string selection = null;
|
||||||
|
if(!string.IsNullOrWhiteSpace(_uri))
|
||||||
|
{
|
||||||
|
selection = await DisplayActionSheet(AppResources.AutofillOrView, AppResources.Cancel, null,
|
||||||
|
AppResources.Autofill, AppResources.View);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selection == AppResources.View || string.IsNullOrWhiteSpace(_uri))
|
||||||
|
{
|
||||||
var page = new VaultViewCipherPage(cipher.Type, cipher.Id);
|
var page = new VaultViewCipherPage(cipher.Type, cipher.Id);
|
||||||
await Navigation.PushForDeviceAsync(page);
|
await Navigation.PushForDeviceAsync(page);
|
||||||
|
}
|
||||||
|
else if(selection == AppResources.Autofill)
|
||||||
|
{
|
||||||
|
if(_deviceInfoService.Version < 21)
|
||||||
|
{
|
||||||
|
Helpers.CipherMoreClickedAsync(this, cipher, !string.IsNullOrWhiteSpace(_uri));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("AutoFilled",
|
||||||
|
_uri.StartsWith("http") ? "Website" : "App");
|
||||||
|
_deviceActionService.Autofill(cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
((ListView)sender).SelectedItem = null;
|
((ListView)sender).SelectedItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,5 +144,33 @@ namespace Bit.App.Utilities
|
||||||
Resolver.Resolve<IDeviceActionService>().CopyToClipboard(copyText);
|
Resolver.Resolve<IDeviceActionService>().CopyToClipboard(copyText);
|
||||||
Resolver.Resolve<IUserDialogs>().Toast(string.Format(AppResources.ValueHasBeenCopied, alertLabel));
|
Resolver.Resolve<IUserDialogs>().Toast(string.Format(AppResources.ValueHasBeenCopied, alertLabel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async void AddCipher(Page page, string folderId)
|
||||||
|
{
|
||||||
|
var type = await Resolver.Resolve<IUserDialogs>().ActionSheetAsync(
|
||||||
|
AppResources.SelectTypeAdd, AppResources.Cancel, null, null, AppResources.TypeLogin,
|
||||||
|
AppResources.TypeCard, AppResources.TypeIdentity, AppResources.TypeSecureNote);
|
||||||
|
|
||||||
|
var selectedType = CipherType.SecureNote;
|
||||||
|
if(type == AppResources.Cancel)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(type == AppResources.TypeLogin)
|
||||||
|
{
|
||||||
|
selectedType = CipherType.Login;
|
||||||
|
}
|
||||||
|
else if(type == AppResources.TypeCard)
|
||||||
|
{
|
||||||
|
selectedType = CipherType.Card;
|
||||||
|
}
|
||||||
|
else if(type == AppResources.TypeIdentity)
|
||||||
|
{
|
||||||
|
selectedType = CipherType.Identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addPage = new VaultAddCipherPage(selectedType, defaultFolderId: folderId);
|
||||||
|
await page.Navigation.PushForDeviceAsync(addPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue