mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 02:18:27 +03:00
Feature sync on refresh (#937)
* Added new option: Sync on refresh * Removed unused field * Fixed refreshing on disappearing & unnecessary codes removed * Requested changes * Calling storage service instead of a dedicated service function (mobile-specific)
This commit is contained in:
parent
c5a71c4304
commit
3b4ef4d238
9 changed files with 4338 additions and 2786 deletions
|
@ -16,22 +16,35 @@
|
||||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
|
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
|
||||||
</ContentPage.ToolbarItems>
|
</ContentPage.ToolbarItems>
|
||||||
|
|
||||||
<ScrollView>
|
<ScrollView Padding="0, 0, 0, 20">
|
||||||
<StackLayout Spacing="10"
|
<StackLayout Padding="0" Spacing="20">
|
||||||
Padding="10, 5"
|
<StackLayout StyleClass="box">
|
||||||
VerticalOptions="Center"
|
<StackLayout StyleClass="box-row, box-row-switch">
|
||||||
HorizontalOptions="FillAndExpand">
|
<Label
|
||||||
<Button Text="{u:I18n SyncVaultNow}"
|
Text="{u:I18n EnableSyncOnRefresh}"
|
||||||
Clicked="Sync_Clicked"></Button>
|
StyleClass="box-label, box-label-regular"
|
||||||
<Label StyleClass="text-muted, text-sm" HorizontalTextAlignment="Center">
|
HorizontalOptions="StartAndExpand" />
|
||||||
<Label.FormattedText>
|
<Switch
|
||||||
<FormattedString>
|
IsToggled="{Binding EnableSyncOnRefresh}"
|
||||||
<Span Text="{u:I18n LastSync}" />
|
StyleClass="box-value"
|
||||||
<Span Text=" " />
|
HorizontalOptions="End" />
|
||||||
<Span Text="{Binding LastSync}" />
|
</StackLayout>
|
||||||
</FormattedString>
|
<Label
|
||||||
</Label.FormattedText>
|
Text="{u:I18n EnableSyncOnRefreshDescription}"
|
||||||
</Label>
|
StyleClass="box-footer-label, box-footer-label-switch" />
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout StyleClass="box">
|
||||||
|
<Button Text="{u:I18n SyncVaultNow}" Clicked="Sync_Clicked"></Button>
|
||||||
|
<Label StyleClass="text-muted, text-sm" HorizontalTextAlignment="Center">
|
||||||
|
<Label.FormattedText>
|
||||||
|
<FormattedString>
|
||||||
|
<Span Text="{u:I18n LastSync}" />
|
||||||
|
<Span Text=" " />
|
||||||
|
<Span Text="{Binding LastSync}" />
|
||||||
|
</FormattedString>
|
||||||
|
</Label.FormattedText>
|
||||||
|
</Label>
|
||||||
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Bit.App.Pages
|
||||||
protected async override void OnAppearing()
|
protected async override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
await _vm.SetLastSyncAsync();
|
await _vm.InitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Sync_Clicked(object sender, EventArgs e)
|
private async void Sync_Clicked(object sender, EventArgs e)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
|
using Bit.Core;
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
@ -11,25 +12,56 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
private readonly IDeviceActionService _deviceActionService;
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
|
private readonly IStorageService _storageService;
|
||||||
private readonly ISyncService _syncService;
|
private readonly ISyncService _syncService;
|
||||||
|
|
||||||
private string _lastSync = "--";
|
private string _lastSync = "--";
|
||||||
|
private bool _inited;
|
||||||
|
private bool _syncOnRefresh;
|
||||||
|
|
||||||
public SyncPageViewModel()
|
public SyncPageViewModel()
|
||||||
{
|
{
|
||||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
|
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||||
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||||
|
|
||||||
PageTitle = AppResources.Sync;
|
PageTitle = AppResources.Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool EnableSyncOnRefresh
|
||||||
|
{
|
||||||
|
get => _syncOnRefresh;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _syncOnRefresh, value))
|
||||||
|
{
|
||||||
|
var task = UpdateSyncOnRefreshAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string LastSync
|
public string LastSync
|
||||||
{
|
{
|
||||||
get => _lastSync;
|
get => _lastSync;
|
||||||
set => SetProperty(ref _lastSync, value);
|
set => SetProperty(ref _lastSync, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task InitAsync()
|
||||||
|
{
|
||||||
|
await SetLastSyncAsync();
|
||||||
|
EnableSyncOnRefresh = await _storageService.GetAsync<bool>(Constants.SyncOnRefreshKey);
|
||||||
|
_inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateSyncOnRefreshAsync()
|
||||||
|
{
|
||||||
|
if (_inited)
|
||||||
|
{
|
||||||
|
await _storageService.SaveAsync(Constants.SyncOnRefreshKey, _syncOnRefresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SetLastSyncAsync()
|
public async Task SetLastSyncAsync()
|
||||||
{
|
{
|
||||||
var last = await _syncService.GetLastSyncAsync();
|
var last = await _syncService.GetLastSyncAsync();
|
||||||
|
|
|
@ -194,6 +194,7 @@ namespace Bit.App.Pages
|
||||||
base.OnDisappearing();
|
base.OnDisappearing();
|
||||||
IsBusy = false;
|
IsBusy = false;
|
||||||
_broadcasterService.Unsubscribe(_pageName);
|
_broadcasterService.Unsubscribe(_pageName);
|
||||||
|
_vm.DisableRefreshing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
|
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Bit.App.Pages
|
||||||
private bool _showNoData;
|
private bool _showNoData;
|
||||||
private bool _showList;
|
private bool _showList;
|
||||||
private bool _websiteIconsEnabled;
|
private bool _websiteIconsEnabled;
|
||||||
|
private bool _syncRefreshing;
|
||||||
private string _noDataText;
|
private string _noDataText;
|
||||||
private List<CipherView> _allCiphers;
|
private List<CipherView> _allCiphers;
|
||||||
private Dictionary<string, int> _folderCounts = new Dictionary<string, int>();
|
private Dictionary<string, int> _folderCounts = new Dictionary<string, int>();
|
||||||
|
@ -44,6 +45,7 @@ namespace Bit.App.Pages
|
||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
private readonly IMessagingService _messagingService;
|
private readonly IMessagingService _messagingService;
|
||||||
private readonly IStateService _stateService;
|
private readonly IStateService _stateService;
|
||||||
|
private readonly IStorageService _storageService;
|
||||||
|
|
||||||
public GroupingsPageViewModel()
|
public GroupingsPageViewModel()
|
||||||
{
|
{
|
||||||
|
@ -57,6 +59,7 @@ namespace Bit.App.Pages
|
||||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||||
|
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||||
|
|
||||||
Loading = true;
|
Loading = true;
|
||||||
PageTitle = AppResources.MyVault;
|
PageTitle = AppResources.MyVault;
|
||||||
|
@ -94,6 +97,11 @@ namespace Bit.App.Pages
|
||||||
get => _refreshing;
|
get => _refreshing;
|
||||||
set => SetProperty(ref _refreshing, value);
|
set => SetProperty(ref _refreshing, value);
|
||||||
}
|
}
|
||||||
|
public bool SyncRefreshing
|
||||||
|
{
|
||||||
|
get => _syncRefreshing;
|
||||||
|
set => SetProperty(ref _syncRefreshing, value);
|
||||||
|
}
|
||||||
public bool Loading
|
public bool Loading
|
||||||
{
|
{
|
||||||
get => _loading;
|
get => _loading;
|
||||||
|
@ -149,6 +157,13 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (await _storageService.GetAsync<bool>(Constants.SyncOnRefreshKey) && Refreshing && !SyncRefreshing)
|
||||||
|
{
|
||||||
|
SyncRefreshing = true;
|
||||||
|
await _syncService.FullSyncAsync(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_doingLoad = true;
|
_doingLoad = true;
|
||||||
LoadedOnce = true;
|
LoadedOnce = true;
|
||||||
ShowNoData = false;
|
ShowNoData = false;
|
||||||
|
@ -266,12 +281,18 @@ namespace Bit.App.Pages
|
||||||
_doingLoad = false;
|
_doingLoad = false;
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
Loading = false;
|
Loading = false;
|
||||||
Refreshing = false;
|
|
||||||
ShowNoData = (MainPage && !HasCiphers) || !groupedItems.Any();
|
ShowNoData = (MainPage && !HasCiphers) || !groupedItems.Any();
|
||||||
ShowList = !ShowNoData;
|
ShowList = !ShowNoData;
|
||||||
|
DisableRefreshing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisableRefreshing()
|
||||||
|
{
|
||||||
|
Refreshing = false;
|
||||||
|
SyncRefreshing = false;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SelectCipherAsync(CipherView cipher)
|
public async Task SelectCipherAsync(CipherView cipher)
|
||||||
{
|
{
|
||||||
var page = new ViewPage(cipher.Id);
|
var page = new ViewPage(cipher.Id);
|
||||||
|
|
7011
src/App/Resources/AppResources.Designer.cs
generated
7011
src/App/Resources/AppResources.Designer.cs
generated
File diff suppressed because it is too large
Load diff
|
@ -1674,4 +1674,10 @@
|
||||||
<value>Do you really want to send to the trash?</value>
|
<value>Do you really want to send to the trash?</value>
|
||||||
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
|
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||||
|
<value>Enable sync on refresh</value>
|
||||||
|
</data>
|
||||||
|
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||||
|
<value>Syncing vault with pull down gesture.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -7,7 +7,6 @@ namespace Bit.Core.Abstractions
|
||||||
public interface ISyncService
|
public interface ISyncService
|
||||||
{
|
{
|
||||||
bool SyncInProgress { get; set; }
|
bool SyncInProgress { get; set; }
|
||||||
|
|
||||||
Task<bool> FullSyncAsync(bool forceSync, bool allowThrowOnError = false);
|
Task<bool> FullSyncAsync(bool forceSync, bool allowThrowOnError = false);
|
||||||
Task<DateTime?> GetLastSyncAsync();
|
Task<DateTime?> GetLastSyncAsync();
|
||||||
Task SetLastSyncAsync(DateTime date);
|
Task SetLastSyncAsync(DateTime date);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
{
|
{
|
||||||
public const string AndroidAppProtocol = "androidapp://";
|
public const string AndroidAppProtocol = "androidapp://";
|
||||||
public const string iOSAppProtocol = "iosapp://";
|
public const string iOSAppProtocol = "iosapp://";
|
||||||
|
public static string SyncOnRefreshKey = "syncOnRefresh";
|
||||||
public static string VaultTimeoutKey = "lockOption";
|
public static string VaultTimeoutKey = "lockOption";
|
||||||
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
|
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
|
||||||
public static string LastActiveKey = "lastActive";
|
public static string LastActiveKey = "lastActive";
|
||||||
|
|
Loading…
Reference in a new issue