1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-10 05:13:31 +00:00

account list status enhancements

This commit is contained in:
Matt Portune
2022-01-19 12:06:45 -05:00
parent d52a1bf668
commit e717992b2b
12 changed files with 48 additions and 36 deletions

View File

@@ -283,13 +283,14 @@ namespace Bit.App
{ {
await SetMainPageAsync(); await SetMainPageAsync();
} }
await Task.Delay(50);
UpdateTheme(); UpdateTheme();
}); });
} }
private async Task SetMainPageAsync() private async Task SetMainPageAsync()
{ {
await _stateService.RefreshAccountViews(); await _stateService.RefreshAccountViewsAsync();
var authed = await _stateService.IsAuthenticatedAsync(); var authed = await _stateService.IsAuthenticatedAsync();
if (authed) if (authed)
{ {

View File

@@ -79,7 +79,7 @@
Padding="0"> Padding="0">
<StackLayout <StackLayout
x:Name="_accountListView" x:Name="_accountListContainer"
VerticalOptions="StartAndExpand" VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}" BackgroundColor="{DynamicResource BackgroundColor}"
@@ -87,6 +87,7 @@
xct:ShadowEffect.Radius="10" xct:ShadowEffect.Radius="10"
xct:ShadowEffect.OffsetY="3"> xct:ShadowEffect.OffsetY="3">
<ListView <ListView
x:Name="_accountListView"
ItemsSource="{Binding AccountViews}" ItemsSource="{Binding AccountViews}"
ItemSelected="AccountRow_Selected" ItemSelected="AccountRow_Selected"
BackgroundColor="Transparent" BackgroundColor="Transparent"

View File

@@ -142,17 +142,18 @@ namespace Bit.App.Pages
{ {
if (_accountListOverlay.IsVisible) if (_accountListOverlay.IsVisible)
{ {
await ShowAccountListAsync(false, _accountListView, _accountListOverlay); await ShowAccountListAsync(false, _accountListContainer, _accountListOverlay);
} }
else else
{ {
await ShowAccountListAsync(true, _accountListView, _accountListOverlay); await RefreshAccountViewsAsync(_accountListView);
await ShowAccountListAsync(true, _accountListContainer, _accountListOverlay);
} }
} }
private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e) private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e)
{ {
await AccountRowSelectedAsync(sender, e, _accountListView, _accountListOverlay, null, true); await AccountRowSelectedAsync(sender, e, _accountListContainer, _accountListOverlay, null, true);
} }
} }
} }

View File

@@ -173,7 +173,7 @@
Padding="0"> Padding="0">
<StackLayout <StackLayout
x:Name="_accountListView" x:Name="_accountListContainer"
VerticalOptions="StartAndExpand" VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}" BackgroundColor="{DynamicResource BackgroundColor}"
@@ -181,6 +181,7 @@
xct:ShadowEffect.Radius="10" xct:ShadowEffect.Radius="10"
xct:ShadowEffect.OffsetY="3"> xct:ShadowEffect.OffsetY="3">
<ListView <ListView
x:Name="_accountListView"
ItemsSource="{Binding AccountViews}" ItemsSource="{Binding AccountViews}"
ItemSelected="AccountRow_Selected" ItemSelected="AccountRow_Selected"
BackgroundColor="Transparent" BackgroundColor="Transparent"

View File

@@ -159,17 +159,18 @@ namespace Bit.App.Pages
{ {
if (_accountListOverlay.IsVisible) if (_accountListOverlay.IsVisible)
{ {
await ShowAccountListAsync(false, _accountListView, _accountListOverlay); await ShowAccountListAsync(false, _accountListContainer, _accountListOverlay);
} }
else else
{ {
await ShowAccountListAsync(true, _accountListView, _accountListOverlay); await RefreshAccountViewsAsync(_accountListView);
await ShowAccountListAsync(true, _accountListContainer, _accountListOverlay);
} }
} }
private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e) private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e)
{ {
await AccountRowSelectedAsync(sender, e, _accountListView, _accountListOverlay, null, true); await AccountRowSelectedAsync(sender, e, _accountListContainer, _accountListOverlay, null, true);
} }
} }
} }

View File

@@ -122,7 +122,7 @@
Padding="0"> Padding="0">
<StackLayout <StackLayout
x:Name="_accountListView" x:Name="_accountListContainer"
VerticalOptions="StartAndExpand" VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}" BackgroundColor="{DynamicResource BackgroundColor}"
@@ -130,6 +130,7 @@
xct:ShadowEffect.Radius="10" xct:ShadowEffect.Radius="10"
xct:ShadowEffect.OffsetY="3"> xct:ShadowEffect.OffsetY="3">
<ListView <ListView
x:Name="_accountListView"
ItemsSource="{Binding AccountViews}" ItemsSource="{Binding AccountViews}"
ItemSelected="AccountRow_Selected" ItemSelected="AccountRow_Selected"
BackgroundColor="Transparent" BackgroundColor="Transparent"

View File

@@ -141,17 +141,18 @@ namespace Bit.App.Pages
{ {
if (_accountListOverlay.IsVisible) if (_accountListOverlay.IsVisible)
{ {
await ShowAccountListAsync(false, _accountListView, _accountListOverlay); await ShowAccountListAsync(false, _accountListContainer, _accountListOverlay);
} }
else else
{ {
await ShowAccountListAsync(true, _accountListView, _accountListOverlay); await RefreshAccountViewsAsync(_accountListView);
await ShowAccountListAsync(true, _accountListContainer, _accountListOverlay);
} }
} }
private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e) private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e)
{ {
await AccountRowSelectedAsync(sender, e, _accountListView, _accountListOverlay, null, true); await AccountRowSelectedAsync(sender, e, _accountListContainer, _accountListOverlay, null, true);
} }
} }
} }

View File

@@ -9,7 +9,6 @@ using Bit.Core.Enums;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration; using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific; using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
using Page = Xamarin.Forms.Page;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {
@@ -39,12 +38,6 @@ namespace Bit.App.Pages
await SaveActivity(); await SaveActivity();
} }
public async Task<bool> ShowAccountSwitcherAsync()
{
return await _stateService.HasMultipleAccountsAsync()
|| await _stateService.IsAuthenticatedAsync();
}
public bool DoOnce(Action action = null, int milliseconds = 1000) public bool DoOnce(Action action = null, int milliseconds = 1000)
{ {
if (LastPageAction.HasValue && (DateTime.UtcNow - LastPageAction.Value).TotalMilliseconds < milliseconds) if (LastPageAction.HasValue && (DateTime.UtcNow - LastPageAction.Value).TotalMilliseconds < milliseconds)
@@ -115,23 +108,33 @@ namespace Bit.App.Pages
}); });
} }
protected async Task<bool> ShowAccountSwitcherAsync()
{
return await _stateService.HasMultipleAccountsAsync()
|| await _stateService.IsAuthenticatedAsync();
}
protected async Task RefreshAccountViewsAsync(Xamarin.Forms.ListView accountListView)
{
await _stateService.RefreshAccountViewsAsync();
// Property change trigger on account listview is yielding inconsistent results, using a hammer instead
accountListView.ItemsSource = null;
accountListView.ItemsSource = _stateService.AccountViews;
}
protected async Task<AvatarImageSource> GetAvatarImageSourceAsync(bool useCurrentActiveAccount = true) protected async Task<AvatarImageSource> GetAvatarImageSourceAsync(bool useCurrentActiveAccount = true)
{ {
return new AvatarImageSource(useCurrentActiveAccount ? await _stateService.GetEmailAsync() : null); return new AvatarImageSource(useCurrentActiveAccount ? await _stateService.GetEmailAsync() : null);
} }
protected async Task ShowAccountListAsync(bool isVisible, View listView, View overlay, View fab = null) protected async Task ShowAccountListAsync(bool isVisible, View listContainer, View overlay, View fab = null)
{ {
Device.BeginInvokeOnMainThread(async () => Device.BeginInvokeOnMainThread(async () =>
{ {
// Not all animations are awaited. This is intentional to allow multiple simultaneous animations. // Not all animations are awaited. This is intentional to allow multiple simultaneous animations.
if (isVisible) if (isVisible)
{ {
// Update account views to reflect current state
await _stateService.RefreshAccountViews();
// start listView in default (off-screen) position // start listView in default (off-screen) position
await listView.TranslateTo(0, listView.Height * -1, 0); await listContainer.TranslateTo(0, listContainer.Height * -1, 0);
// set overlay opacity to zero before making visible and start fade-in // set overlay opacity to zero before making visible and start fade-in
overlay.Opacity = 0; overlay.Opacity = 0;
@@ -145,7 +148,7 @@ namespace Bit.App.Pages
} }
// slide account list into view // slide account list into view
await listView.TranslateTo(0, 0, 200, Easing.SinOut); await listContainer.TranslateTo(0, 0, 200, Easing.SinOut);
} }
else else
{ {
@@ -159,7 +162,7 @@ namespace Bit.App.Pages
} }
// slide account list out of view // slide account list out of view
await listView.TranslateTo(0, listView.Height * -1, 200, Easing.SinIn); await listContainer.TranslateTo(0, listContainer.Height * -1, 200, Easing.SinIn);
// remove overlay // remove overlay
overlay.IsVisible = false; overlay.IsVisible = false;
@@ -167,7 +170,7 @@ namespace Bit.App.Pages
}); });
} }
protected async Task AccountRowSelectedAsync(object sender, SelectedItemChangedEventArgs e, View listView, protected async Task AccountRowSelectedAsync(object sender, SelectedItemChangedEventArgs e, View listContainer,
View overlay, View fab = null, bool? allowActiveAccountSelection = false) View overlay, View fab = null, bool? allowActiveAccountSelection = false)
{ {
if (!DoOnce()) if (!DoOnce())
@@ -181,7 +184,7 @@ namespace Bit.App.Pages
((Xamarin.Forms.ListView)sender).SelectedItem = null; ((Xamarin.Forms.ListView)sender).SelectedItem = null;
await Task.Delay(100); await Task.Delay(100);
await ShowAccountListAsync(false, listView, overlay, fab); await ShowAccountListAsync(false, listContainer, overlay, fab);
if (item.AccountView.IsAccount) if (item.AccountView.IsAccount)
{ {

View File

@@ -172,7 +172,7 @@
Padding="0"> Padding="0">
<StackLayout <StackLayout
x:Name="_accountListView" x:Name="_accountListContainer"
VerticalOptions="StartAndExpand" VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}" BackgroundColor="{DynamicResource BackgroundColor}"
@@ -180,6 +180,7 @@
xct:ShadowEffect.Radius="10" xct:ShadowEffect.Radius="10"
xct:ShadowEffect.OffsetY="3"> xct:ShadowEffect.OffsetY="3">
<ListView <ListView
x:Name="_accountListView"
ItemsSource="{Binding AccountViews}" ItemsSource="{Binding AccountViews}"
ItemSelected="AccountRow_Selected" ItemSelected="AccountRow_Selected"
BackgroundColor="Transparent" BackgroundColor="Transparent"

View File

@@ -298,17 +298,18 @@ namespace Bit.App.Pages
if (_accountListOverlay.IsVisible) if (_accountListOverlay.IsVisible)
{ {
await ShowAccountListAsync(false, _accountListView, _accountListOverlay, _fab); await ShowAccountListAsync(false, _accountListContainer, _accountListOverlay, _fab);
} }
else else
{ {
await ShowAccountListAsync(true, _accountListView, _accountListOverlay, _fab); await RefreshAccountViewsAsync(_accountListView);
await ShowAccountListAsync(true, _accountListContainer, _accountListOverlay, _fab);
} }
} }
private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e) private async void AccountRow_Selected(object sender, SelectedItemChangedEventArgs e)
{ {
await AccountRowSelectedAsync(sender, e, _accountListView, _accountListOverlay, _fab); await AccountRowSelectedAsync(sender, e, _accountListContainer, _accountListOverlay, _fab);
} }
} }
} }

View File

@@ -18,7 +18,7 @@ namespace Bit.Core.Abstractions
Task SetActiveUserAsync(string userId); Task SetActiveUserAsync(string userId);
Task<bool> IsAuthenticatedAsync(string userId = null); Task<bool> IsAuthenticatedAsync(string userId = null);
Task<bool> HasMultipleAccountsAsync(); Task<bool> HasMultipleAccountsAsync();
Task RefreshAccountViews(); Task RefreshAccountViewsAsync();
Task AddAccountAsync(Account account); Task AddAccountAsync(Account account);
Task ClearAsync(string userId); Task ClearAsync(string userId);
Task<EnvironmentUrlData> GetPreAuthEnvironmentUrlsAsync(); Task<EnvironmentUrlData> GetPreAuthEnvironmentUrlsAsync();

View File

@@ -85,7 +85,7 @@ namespace Bit.Core.Services
return _state.Accounts?.Count > 1; return _state.Accounts?.Count > 1;
} }
public async Task RefreshAccountViews() public async Task RefreshAccountViewsAsync()
{ {
await CheckStateAsync(); await CheckStateAsync();
@@ -130,7 +130,7 @@ namespace Bit.Core.Services
{ {
await ScaffoldNewAccountAsync(account); await ScaffoldNewAccountAsync(account);
await SetActiveUserAsync(account.Profile.UserId); await SetActiveUserAsync(account.Profile.UserId);
await RefreshAccountViews(); await RefreshAccountViewsAsync();
} }
public async Task ClearAsync(string userId) public async Task ClearAsync(string userId)