195 lines
6.0 KiB
C#
195 lines
6.0 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
using Bit.Core.Abstractions;
|
|
using Bit.Core.Utilities;
|
|
using Xamarin.CommunityToolkit.ObjectModel;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Bit.App.Controls
|
|
{
|
|
public partial class AccountSwitchingOverlayView : ContentView
|
|
{
|
|
public static readonly BindableProperty MainPageProperty = BindableProperty.Create(
|
|
nameof(MainPage),
|
|
typeof(ContentPage),
|
|
typeof(AccountSwitchingOverlayView),
|
|
defaultBindingMode: BindingMode.OneWay);
|
|
|
|
public static readonly BindableProperty MainFabProperty = BindableProperty.Create(
|
|
nameof(MainFab),
|
|
typeof(View),
|
|
typeof(AccountSwitchingOverlayView),
|
|
defaultBindingMode: BindingMode.OneWay);
|
|
|
|
public ContentPage MainPage
|
|
{
|
|
get => (ContentPage)GetValue(MainPageProperty);
|
|
set => SetValue(MainPageProperty, value);
|
|
}
|
|
|
|
public View MainFab
|
|
{
|
|
get => (View)GetValue(MainFabProperty);
|
|
set => SetValue(MainFabProperty, value);
|
|
}
|
|
|
|
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
|
|
|
public AccountSwitchingOverlayView()
|
|
{
|
|
InitializeComponent();
|
|
|
|
ToggleVisibililtyCommand = new AsyncCommand(ToggleVisibilityAsync,
|
|
onException: ex => _logger.Value.Exception(ex),
|
|
allowsMultipleExecutions: false);
|
|
|
|
SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
|
onException: ex => _logger.Value.Exception(ex),
|
|
allowsMultipleExecutions: false);
|
|
|
|
LongPressAccountCommand = new AsyncCommand<AccountViewCellViewModel>(LongPressAccountAsync,
|
|
onException: ex => _logger.Value.Exception(ex),
|
|
allowsMultipleExecutions: false);
|
|
}
|
|
|
|
public AccountSwitchingOverlayViewModel ViewModel => BindingContext as AccountSwitchingOverlayViewModel;
|
|
|
|
public ICommand ToggleVisibililtyCommand { get; }
|
|
|
|
public ICommand SelectAccountCommand { get; }
|
|
|
|
public ICommand LongPressAccountCommand { get; }
|
|
|
|
public int AccountListRowHeight => Device.RuntimePlatform == Device.Android ? 74 : 70;
|
|
|
|
public bool LongPressAccountEnabled { get; set; } = true;
|
|
|
|
public Action AfterHide { get; set; }
|
|
|
|
public async Task ToggleVisibilityAsync()
|
|
{
|
|
if (IsVisible)
|
|
{
|
|
await HideAsync();
|
|
}
|
|
else
|
|
{
|
|
await ShowAsync();
|
|
}
|
|
}
|
|
|
|
public async Task ShowAsync()
|
|
{
|
|
if (ViewModel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await ViewModel.RefreshAccountViewsAsync();
|
|
|
|
await Device.InvokeOnMainThreadAsync(async () =>
|
|
{
|
|
// start listView in default (off-screen) position
|
|
await _accountListContainer.TranslateTo(0, _accountListContainer.Height * -1, 0);
|
|
|
|
// re-measure in case accounts have been removed without changing screens
|
|
if (ViewModel.AccountViews != null)
|
|
{
|
|
_accountListView.HeightRequest = AccountListRowHeight * ViewModel.AccountViews.Count;
|
|
}
|
|
|
|
// set overlay opacity to zero before making visible and start fade-in
|
|
Opacity = 0;
|
|
IsVisible = true;
|
|
this.FadeTo(1, 100);
|
|
|
|
if (Device.RuntimePlatform == Device.Android && MainFab != null)
|
|
{
|
|
// start fab fade-out
|
|
MainFab.FadeTo(0, 200);
|
|
}
|
|
|
|
// slide account list into view
|
|
await _accountListContainer.TranslateTo(0, 0, 200, Easing.SinOut);
|
|
});
|
|
}
|
|
|
|
public async Task HideAsync()
|
|
{
|
|
if (!IsVisible)
|
|
{
|
|
// already hidden, don't animate again
|
|
return;
|
|
}
|
|
// Not all animations are awaited. This is intentional to allow multiple simultaneous animations.
|
|
await Device.InvokeOnMainThreadAsync(async () =>
|
|
{
|
|
// start overlay fade-out
|
|
this.FadeTo(0, 200);
|
|
|
|
if (Device.RuntimePlatform == Device.Android && MainFab != null)
|
|
{
|
|
// start fab fade-in
|
|
MainFab.FadeTo(1, 200);
|
|
}
|
|
|
|
// slide account list out of view
|
|
await _accountListContainer.TranslateTo(0, _accountListContainer.Height * -1, 200, Easing.SinIn);
|
|
|
|
// remove overlay
|
|
IsVisible = false;
|
|
|
|
AfterHide?.Invoke();
|
|
});
|
|
}
|
|
|
|
private async void FreeSpaceOverlay_Tapped(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
await HideAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Value.Exception(ex);
|
|
}
|
|
}
|
|
|
|
private async Task SelectAccountAsync(AccountViewCellViewModel item)
|
|
{
|
|
try
|
|
{
|
|
await Task.Delay(100);
|
|
await HideAsync();
|
|
|
|
ViewModel?.SelectAccountCommand?.Execute(item);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Value.Exception(ex);
|
|
}
|
|
}
|
|
|
|
private async Task LongPressAccountAsync(AccountViewCellViewModel item)
|
|
{
|
|
if (!LongPressAccountEnabled || !item.IsAccount)
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
await Task.Delay(100);
|
|
await HideAsync();
|
|
|
|
ViewModel?.LongPressAccountCommand?.Execute(
|
|
new Tuple<ContentPage, AccountViewCellViewModel>(MainPage, item));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Value.Exception(ex);
|
|
}
|
|
}
|
|
}
|
|
}
|