mirror of
https://github.com/bitwarden/mobile.git
synced 2024-12-27 17:08:00 +01:00
[SSG-416] PR fixes
This commit is contained in:
parent
1b82249d44
commit
2f2b90acee
@ -13,7 +13,7 @@
|
||||
ColumnDefinitions="40,*,40,Auto,40"
|
||||
RowSpacing="0"
|
||||
Padding="0,10,0,0"
|
||||
RowDefinitions="Auto,Auto">
|
||||
RowDefinitions="*,*">
|
||||
|
||||
<Grid.Resources>
|
||||
<u:IconGlyphConverter x:Key="iconGlyphConverter" />
|
||||
@ -48,8 +48,8 @@
|
||||
LineBreakMode="TailTruncation"
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
VerticalTextAlignment="End"
|
||||
VerticalOptions="End"
|
||||
VerticalTextAlignment="Center"
|
||||
VerticalOptions="Fill"
|
||||
StyleClass="list-title, list-title-platform"
|
||||
Text="{Binding Cipher.Name}" />
|
||||
|
||||
@ -57,8 +57,8 @@
|
||||
LineBreakMode="TailTruncation"
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
VerticalTextAlignment="Start"
|
||||
VerticalOptions="Start"
|
||||
VerticalTextAlignment="Center"
|
||||
VerticalOptions="Fill"
|
||||
StyleClass="list-subtitle, list-subtitle-platform"
|
||||
Text="{Binding Cipher.SubTitle}" />
|
||||
|
||||
|
@ -105,7 +105,7 @@ namespace Bit.App.Controls
|
||||
|
||||
private void DrawArc(SKCanvas canvas, Circle circle, Func<float> progress, float strokewidth, SKColor color, SKColor progressEndColor)
|
||||
{
|
||||
var progressValue = progress.Invoke();
|
||||
var progressValue = progress();
|
||||
var angle = progressValue * 3.6f;
|
||||
canvas.DrawArc(circle.Rect, 270, angle, false,
|
||||
new SKPaint()
|
||||
|
@ -93,7 +93,7 @@ namespace Bit.App.Pages
|
||||
UriOptionsCommand = new Command<LoginUriView>(UriOptions);
|
||||
FieldOptionsCommand = new Command<AddEditPageFieldViewModel>(FieldOptions);
|
||||
PasswordPromptHelpCommand = new Command(PasswordPromptHelp);
|
||||
CopyCommand = new AsyncCommand(CopyTotpClipboardAsync);
|
||||
CopyCommand = new AsyncCommand(CopyTotpClipboardAsync, onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
Uris = new ExtendedObservableCollection<LoginUriView>();
|
||||
Fields = new ExtendedObservableCollection<AddEditPageFieldViewModel>();
|
||||
Collections = new ExtendedObservableCollection<CollectionViewModel>();
|
||||
|
@ -193,7 +193,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
base.OnDisappearing();
|
||||
IsBusy = false;
|
||||
await _vm.StopCiphersTotpTick();
|
||||
_vm.StopCiphersTotpTick();
|
||||
_broadcasterService.Unsubscribe(_pageName);
|
||||
_vm.DisableRefreshing();
|
||||
_accountAvatar?.OnDisappearing();
|
||||
@ -206,6 +206,13 @@ namespace Bit.App.Pages
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.CurrentSelection?.FirstOrDefault() is GroupingsPageTOTPListItem totpItem)
|
||||
{
|
||||
await _vm.SelectCipherAsync(totpItem.Cipher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(e.CurrentSelection?.FirstOrDefault() is GroupingsPageListItem item))
|
||||
{
|
||||
return;
|
||||
|
@ -6,6 +6,7 @@ using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@ -111,9 +112,12 @@ namespace Bit.App.Pages
|
||||
public async Task TotpTickAsync()
|
||||
{
|
||||
await _totpTickHelper.GenerateNewTotpValues();
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
Progress = _totpTickHelper.Progress;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
Progress = _totpTickHelper.Progress;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace Bit.App.Pages
|
||||
private Dictionary<string, int> _collectionCounts = new Dictionary<string, int>();
|
||||
private Dictionary<CipherType, int> _typeCounts = new Dictionary<CipherType, int>();
|
||||
private int _deletedCount = 0;
|
||||
private CancellationTokenSource _totpTickCancellationToken;
|
||||
private CancellationTokenSource _totpTickCts;
|
||||
private Task _totpTickTask;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IFolderService _folderService;
|
||||
@ -299,7 +299,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (Ciphers?.Any() ?? false)
|
||||
{
|
||||
CreateCipherGroupedItems(ref groupedItems);
|
||||
CreateCipherGroupedItems(groupedItems);
|
||||
}
|
||||
if (ShowNoFolderCipherGroup)
|
||||
{
|
||||
@ -387,10 +387,10 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateCipherGroupedItems(ref List<GroupingsPageListGroup> groupedItems)
|
||||
private void CreateCipherGroupedItems(List<GroupingsPageListGroup> groupedItems)
|
||||
{
|
||||
var uppercaseGroupNames = _deviceActionService.DeviceType == DeviceType.iOS;
|
||||
_totpTickCancellationToken?.Cancel();
|
||||
_totpTickCts?.Cancel();
|
||||
if (TotpFilterEnable)
|
||||
{
|
||||
var ciphersListItems = Ciphers.Where(c => c.IsDeleted == Deleted && !string.IsNullOrEmpty(c.Login.Totp))
|
||||
@ -411,15 +411,14 @@ namespace Bit.App.Pages
|
||||
|
||||
private void StartCiphersTotpTick(List<GroupingsPageTOTPListItem> ciphersListItems)
|
||||
{
|
||||
_totpTickCancellationToken?.Cancel();
|
||||
_totpTickCancellationToken = new CancellationTokenSource();
|
||||
_totpTickTask = new TimerTask(() => { ciphersListItems.ForEach(i => i.TotpTickAsync()); }, _totpTickCancellationToken).Run();
|
||||
_totpTickCts?.Cancel();
|
||||
_totpTickCts = new CancellationTokenSource();
|
||||
_totpTickTask = new TimerTask(logger, () => ciphersListItems.ForEach(i => i.TotpTickAsync()), _totpTickCts).RunPeriodic();
|
||||
}
|
||||
|
||||
public async Task StopCiphersTotpTick()
|
||||
{
|
||||
TotpFilterEnable = false;
|
||||
_totpTickCancellationToken?.Cancel();
|
||||
_totpTickCts?.Cancel();
|
||||
if (_totpTickTask != null)
|
||||
{
|
||||
await _totpTickTask;
|
||||
|
@ -258,7 +258,6 @@ namespace Bit.App.Pages
|
||||
break;
|
||||
}
|
||||
}
|
||||
_stopwatch.Stop();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -215,7 +215,7 @@
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n CopyTotp}" />
|
||||
<Label
|
||||
Text="{u:I18n UpgradeToPremiumTotpText}"
|
||||
Text="{u:I18n PremiumSubscriptionRequired}"
|
||||
StyleClass="box-footer-label"
|
||||
IsVisible="{Binding ShowUpgradePremiumTotpText}"
|
||||
Margin="0,5,0,2"
|
||||
|
@ -107,12 +107,12 @@ namespace Bit.App.Pages
|
||||
}, _mainContent);
|
||||
}
|
||||
|
||||
protected override async void OnDisappearing()
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
IsBusy = false;
|
||||
_broadcasterService.Unsubscribe(nameof(ViewPage));
|
||||
await _vm.StopCiphersTotpTick();
|
||||
_vm.StopCiphersTotpTick();
|
||||
}
|
||||
|
||||
private async void PasswordHistory_Tapped(object sender, System.EventArgs e)
|
||||
|
@ -271,7 +271,7 @@ namespace Bit.App.Pages
|
||||
_totpTickHelper = new TotpHelper(Cipher);
|
||||
_totpTickCancellationToken?.Cancel();
|
||||
_totpTickCancellationToken = new CancellationTokenSource();
|
||||
_totpTickTask = new TimerTask(StartCiphersTotpTick, _totpTickCancellationToken).Run();
|
||||
_totpTickTask = new TimerTask(_logger, StartCiphersTotpTick, _totpTickCancellationToken).RunPeriodic();
|
||||
}
|
||||
if (_previousCipherId != CipherId)
|
||||
{
|
||||
@ -284,9 +284,16 @@ namespace Bit.App.Pages
|
||||
|
||||
private async void StartCiphersTotpTick()
|
||||
{
|
||||
await _totpTickHelper.GenerateNewTotpValues();
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
try
|
||||
{
|
||||
await _totpTickHelper.GenerateNewTotpValues();
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StopCiphersTotpTick()
|
||||
|
@ -2,53 +2,53 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Utilities
|
||||
{
|
||||
public class TimerTask
|
||||
{
|
||||
private readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
||||
private readonly ILogger _logger;
|
||||
private readonly Action _action;
|
||||
private readonly CancellationTokenSource _cancellationToken;
|
||||
|
||||
public TimerTask(Action action, CancellationTokenSource cancellationToken)
|
||||
public TimerTask(ILogger logger, Action action, CancellationTokenSource cancellationToken)
|
||||
{
|
||||
_action = action;
|
||||
_logger = logger;
|
||||
_action = action ?? throw new ArgumentNullException();
|
||||
_cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
public Task Run()
|
||||
public Task RunPeriodic(TimeSpan? interval = null)
|
||||
{
|
||||
interval = interval ?? TimeSpan.FromSeconds(1);
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!_cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken.Token);
|
||||
await Device.InvokeOnMainThreadAsync(() =>
|
||||
{
|
||||
if (!_cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
_action?.Invoke();
|
||||
_action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.Value?.Exception(ex);
|
||||
_logger?.Exception(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
Console.WriteLine("TESTES TASK RUNNING");
|
||||
await Task.Delay(interval.Value, _cancellationToken.Token);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.Value?.Exception(ex);
|
||||
_logger?.Exception(ex);
|
||||
}
|
||||
}, _cancellationToken.Token);
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ namespace Bit.App.Utilities
|
||||
public class TotpHelper
|
||||
{
|
||||
private ITotpService _totpService;
|
||||
private CipherView _cipher;
|
||||
private int _interval;
|
||||
|
||||
public TotpHelper(CipherView cipher)
|
||||
{
|
||||
_totpService = ServiceContainer.Resolve<ITotpService>("totpService");
|
||||
Cipher = cipher;
|
||||
_cipher = cipher;
|
||||
_interval = _totpService.GetTimeInterval(cipher?.Login?.Totp);
|
||||
}
|
||||
|
||||
public CipherView Cipher { get; private set; }
|
||||
public string TotpSec { get; private set; }
|
||||
public string TotpCodeFormatted { get; private set; }
|
||||
public double Progress { get; private set; }
|
||||
@ -38,24 +38,20 @@ namespace Bit.App.Utilities
|
||||
|
||||
private async Task<string> TotpUpdateCodeAsync()
|
||||
{
|
||||
var totpCode = await _totpService.GetCodeAsync(Cipher?.Login?.Totp);
|
||||
if (totpCode != null)
|
||||
{
|
||||
if (totpCode.Length > 4)
|
||||
{
|
||||
var half = (int)Math.Floor(totpCode.Length / 2M);
|
||||
return string.Format("{0} {1}", totpCode.Substring(0, half),
|
||||
totpCode.Substring(half));
|
||||
}
|
||||
else
|
||||
{
|
||||
return totpCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
var totpCode = await _totpService.GetCodeAsync(_cipher?.Login?.Totp);
|
||||
if (totpCode == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (totpCode.Length <= 4)
|
||||
{
|
||||
return totpCode;
|
||||
}
|
||||
|
||||
var half = (int)Math.Floor(totpCode.Length / 2M);
|
||||
return string.Format("{0} {1}", totpCode.Substring(0, half),
|
||||
totpCode.Substring(half));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user