1
0
mirror of https://github.com/bitwarden/mobile.git synced 2025-01-02 18:07:56 +01:00

save last sync in settings

This commit is contained in:
Kyle Spearrin 2016-05-06 18:49:01 -04:00
parent decd3fc24e
commit 71be9f8780
4 changed files with 67 additions and 18 deletions

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Acr.UserDialogs; using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Plugin.Connectivity.Abstractions;
using Xamarin.Forms; using Xamarin.Forms;
using XLabs.Ioc; using XLabs.Ioc;
@ -11,11 +12,13 @@ namespace Bit.App.Pages
{ {
private readonly ISyncService _syncService; private readonly ISyncService _syncService;
private readonly IUserDialogs _userDialogs; private readonly IUserDialogs _userDialogs;
private readonly IConnectivity _connectivity;
public SyncPage() public SyncPage()
{ {
_syncService = Resolver.Resolve<ISyncService>(); _syncService = Resolver.Resolve<ISyncService>();
_userDialogs = Resolver.Resolve<IUserDialogs>(); _userDialogs = Resolver.Resolve<IUserDialogs>();
_connectivity = Resolver.Resolve<IConnectivity>();
Init(); Init();
} }
@ -34,10 +37,21 @@ namespace Bit.App.Pages
Title = "Sync"; Title = "Sync";
Content = stackLayout; Content = stackLayout;
Icon = "fa-refresh"; Icon = "fa-refresh";
if(!_connectivity.IsConnected)
{
AlertNoConnection();
}
} }
public async Task SyncAsync() public async Task SyncAsync()
{ {
if(!_connectivity.IsConnected)
{
AlertNoConnection();
return;
}
_userDialogs.ShowLoading("Syncing...", MaskType.Black); _userDialogs.ShowLoading("Syncing...", MaskType.Black);
var succeeded = await _syncService.SyncAsync(); var succeeded = await _syncService.SyncAsync();
_userDialogs.HideLoading(); _userDialogs.HideLoading();
@ -50,5 +64,10 @@ namespace Bit.App.Pages
_userDialogs.ErrorToast("Syncing failed."); _userDialogs.ErrorToast("Syncing failed.");
} }
} }
public void AlertNoConnection()
{
DisplayAlert("No internet connection", "Adding a new folder required an internet connection. Please connect to the internet before continuing.", "Ok");
}
} }
} }

View File

@ -6,6 +6,7 @@ using System.Text;
using Acr.UserDialogs; using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Models; using Bit.App.Models;
using Plugin.Connectivity.Abstractions;
using Xamarin.Forms; using Xamarin.Forms;
using XLabs.Ioc; using XLabs.Ioc;
@ -19,6 +20,7 @@ namespace Bit.App.Pages
var siteService = Resolver.Resolve<ISiteService>(); var siteService = Resolver.Resolve<ISiteService>();
var folderService = Resolver.Resolve<IFolderService>(); var folderService = Resolver.Resolve<IFolderService>();
var userDialogs = Resolver.Resolve<IUserDialogs>(); var userDialogs = Resolver.Resolve<IUserDialogs>();
var connectivity = Resolver.Resolve<IConnectivity>();
var folders = folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt()); var folders = folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt());
@ -57,6 +59,12 @@ namespace Bit.App.Pages
var saveToolBarItem = new ToolbarItem("Save", null, async () => var saveToolBarItem = new ToolbarItem("Save", null, async () =>
{ {
if(!connectivity.IsConnected)
{
AlertNoConnection();
return;
}
if(string.IsNullOrWhiteSpace(uriEntry.Text)) if(string.IsNullOrWhiteSpace(uriEntry.Text))
{ {
await DisplayAlert("An error has occurred", "The Uri field is required.", "Ok"); await DisplayAlert("An error has occurred", "The Uri field is required.", "Ok");
@ -95,6 +103,17 @@ namespace Bit.App.Pages
Title = "Add Site"; Title = "Add Site";
Content = scrollView; Content = scrollView;
ToolbarItems.Add(saveToolBarItem); ToolbarItems.Add(saveToolBarItem);
if(!connectivity.IsConnected)
{
AlertNoConnection();
}
}
public void AlertNoConnection()
{
DisplayAlert("No internet connection", "Adding a new folder required an internet connection. Please connect to the internet before continuing.", "Ok");
} }
} }
} }

View File

@ -1,10 +1,8 @@
using System; using System;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Models.Api; using Bit.App.Models.Api;
using Newtonsoft.Json;
using Plugin.Settings.Abstractions; using Plugin.Settings.Abstractions;
namespace Bit.App.Services namespace Bit.App.Services

View File

@ -3,43 +3,56 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Models.Data; using Bit.App.Models.Data;
using Plugin.Settings.Abstractions;
namespace Bit.App.Services namespace Bit.App.Services
{ {
public class SyncService : ISyncService public class SyncService : ISyncService
{ {
private const string LastSyncKey = "lastSync";
private readonly IFolderApiRepository _folderApiRepository; private readonly IFolderApiRepository _folderApiRepository;
private readonly ISiteApiRepository _siteApiRepository; private readonly ISiteApiRepository _siteApiRepository;
private readonly IFolderRepository _folderRepository; private readonly IFolderRepository _folderRepository;
private readonly ISiteRepository _siteRepository; private readonly ISiteRepository _siteRepository;
private readonly IAuthService _authService; private readonly IAuthService _authService;
private readonly ISettings _settings;
public SyncService( public SyncService(
IFolderApiRepository folderApiRepository, IFolderApiRepository folderApiRepository,
ISiteApiRepository siteApiRepository, ISiteApiRepository siteApiRepository,
IFolderRepository folderRepository, IFolderRepository folderRepository,
ISiteRepository siteRepository, ISiteRepository siteRepository,
IAuthService authService) IAuthService authService,
ISettings settings)
{ {
_folderApiRepository = folderApiRepository; _folderApiRepository = folderApiRepository;
_siteApiRepository = siteApiRepository; _siteApiRepository = siteApiRepository;
_folderRepository = folderRepository; _folderRepository = folderRepository;
_siteRepository = siteRepository; _siteRepository = siteRepository;
_authService = authService; _authService = authService;
_settings = settings;
} }
public async Task<bool> SyncAsync() public async Task<bool> SyncAsync()
{ {
// TODO: store now in settings and only fetch from last time stored var now = DateTime.UtcNow;
var now = DateTime.UtcNow.AddYears(-100); var lastSync = _settings.GetValueOrDefault(LastSyncKey, now.AddYears(-100));
var siteTask = await SyncSitesAsync(now); var siteTask = SyncSitesAsync(lastSync);
var folderTask = await SyncFoldersAsync(now); var folderTask = SyncFoldersAsync(lastSync);
await Task.WhenAll(siteTask, folderTask);
return siteTask && folderTask; if(await siteTask && await folderTask && folderTask.Exception == null && siteTask.Exception == null)
{
_settings.AddOrUpdateValue(LastSyncKey, now);
return true;
}
return false;
} }
private async Task<bool> SyncFoldersAsync(DateTime now) private async Task<bool> SyncFoldersAsync(DateTime lastSync)
{ {
var folderResponse = await _folderApiRepository.GetAsync(); var folderResponse = await _folderApiRepository.GetAsync();
if(!folderResponse.Succeeded) if(!folderResponse.Succeeded)
@ -48,12 +61,12 @@ namespace Bit.App.Services
} }
var serverFolders = folderResponse.Result.Data; var serverFolders = folderResponse.Result.Data;
var folders = await _folderRepository.GetAllByUserIdAsync(_authService.UserId); var localFolders = await _folderRepository.GetAllByUserIdAsync(_authService.UserId);
foreach(var serverFolder in serverFolders.Where(f => f.RevisionDate >= now)) foreach(var serverFolder in serverFolders.Where(f => f.RevisionDate >= lastSync))
{ {
var data = new FolderData(serverFolder, _authService.UserId); var data = new FolderData(serverFolder, _authService.UserId);
var existingLocalFolder = folders.SingleOrDefault(f => f.Id == serverFolder.Id); var existingLocalFolder = localFolders.SingleOrDefault(f => f.Id == serverFolder.Id);
if(existingLocalFolder == null) if(existingLocalFolder == null)
{ {
await _folderRepository.InsertAsync(data); await _folderRepository.InsertAsync(data);
@ -64,7 +77,7 @@ namespace Bit.App.Services
} }
} }
foreach(var folder in folders.Where(localFolder => !serverFolders.Any(serverFolder => serverFolder.Id == localFolder.Id))) foreach(var folder in localFolders.Where(localFolder => !serverFolders.Any(serverFolder => serverFolder.Id == localFolder.Id)))
{ {
await _folderRepository.DeleteAsync(folder.Id); await _folderRepository.DeleteAsync(folder.Id);
} }
@ -72,7 +85,7 @@ namespace Bit.App.Services
return true; return true;
} }
private async Task<bool> SyncSitesAsync(DateTime now) private async Task<bool> SyncSitesAsync(DateTime lastSync)
{ {
var siteResponse = await _siteApiRepository.GetAsync(); var siteResponse = await _siteApiRepository.GetAsync();
if(!siteResponse.Succeeded) if(!siteResponse.Succeeded)
@ -81,12 +94,12 @@ namespace Bit.App.Services
} }
var serverSites = siteResponse.Result.Data; var serverSites = siteResponse.Result.Data;
var sites = await _siteRepository.GetAllByUserIdAsync(_authService.UserId); var localSites = await _siteRepository.GetAllByUserIdAsync(_authService.UserId);
foreach(var serverSite in serverSites.Where(s => s.RevisionDate >= now)) foreach(var serverSite in serverSites.Where(s => s.RevisionDate >= lastSync))
{ {
var data = new SiteData(serverSite, _authService.UserId); var data = new SiteData(serverSite, _authService.UserId);
var existingLocalSite = sites.SingleOrDefault(s => s.Id == serverSite.Id); var existingLocalSite = localSites.SingleOrDefault(s => s.Id == serverSite.Id);
if(existingLocalSite == null) if(existingLocalSite == null)
{ {
await _siteRepository.InsertAsync(data); await _siteRepository.InsertAsync(data);
@ -97,7 +110,7 @@ namespace Bit.App.Services
} }
} }
foreach(var site in sites.Where(localSite => !serverSites.Any(serverSite => serverSite.Id == localSite.Id))) foreach(var site in localSites.Where(localSite => !serverSites.Any(serverSite => serverSite.Id == localSite.Id)))
{ {
await _siteRepository.DeleteAsync(site.Id); await _siteRepository.DeleteAsync(site.Id);
} }