1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-05 18:13:36 +00:00

Dynamic theme switching and visual tweaks (#1556)

* Dynamic theme switching and visual tweaks

* update action runner to use macos-11 for iOS 15 support

* additional tweaks

* refinements

* refinements

* formatting and tweaks
This commit is contained in:
Matt Portune
2021-10-08 08:47:40 -04:00
committed by GitHub
parent 73eb3c2c1e
commit 4aad34cd75
69 changed files with 4193 additions and 5433 deletions

View File

@@ -40,11 +40,12 @@
HorizontalTextAlignment="Center"></Label>
<StackLayout Spacing="5">
<Button Text="{u:I18n LogIn}"
Clicked="LogIn_Clicked"></Button>
StyleClass="btn-primary"
Clicked="LogIn_Clicked" />
<Button Text="{u:I18n CreateAccount}"
Clicked="Register_Clicked"></Button>
Clicked="Register_Clicked" />
<Button Text="{u:I18n LogInSso}"
Clicked="LogInSso_Clicked"></Button>
Clicked="LogInSso_Clicked" />
</StackLayout>
</StackLayout>
</StackLayout>

View File

@@ -13,11 +13,13 @@ namespace Bit.App.Pages
private readonly HomeViewModel _vm;
private readonly AppOptions _appOptions;
private IMessagingService _messagingService;
private IBroadcasterService _broadcasterService;
public HomePage(AppOptions appOptions = null)
{
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_messagingService.Send("showStatusBar", false);
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as HomeViewModel;
@@ -26,7 +28,7 @@ namespace Bit.App.Pages
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
_vm.StartEnvironmentAction = () => Device.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
UpdateLogo();
}
public async Task DismissRegisterPageAndLogInAsync(string email)
@@ -39,6 +41,27 @@ namespace Bit.App.Pages
{
base.OnAppearing();
_messagingService.Send("showStatusBar", false);
_broadcasterService.Subscribe(nameof(HomePage), async (message) =>
{
if (message.Command == "updatedTheme")
{
Device.BeginInvokeOnMainThread(() =>
{
UpdateLogo();
});
}
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
_broadcasterService.Unsubscribe(nameof(HomePage));
}
private void UpdateLogo()
{
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
}
private void Close_Clicked(object sender, EventArgs e)

View File

@@ -120,7 +120,9 @@
IsVisible="{Binding BiometricIntegrityValid, Converter={StaticResource inverseBool}}" />
<Button Text="{Binding BiometricButtonText}" Clicked="Biometric_Clicked"
IsVisible="{Binding BiometricButtonVisible}"></Button>
<Button Text="{u:I18n Unlock}" Clicked="Unlock_Clicked"></Button>
<Button Text="{u:I18n Unlock}"
StyleClass="btn-primary"
Clicked="Unlock_Clicked" />
</StackLayout>
</StackLayout>
</ScrollView>

View File

@@ -82,7 +82,9 @@
</Grid>
</StackLayout>
<StackLayout Padding="10, 0">
<Button Text="{u:I18n LogIn}" Clicked="LogIn_Clicked" />
<Button Text="{u:I18n LogIn}"
StyleClass="btn-primary"
Clicked="LogIn_Clicked" />
</StackLayout>
</StackLayout>
</ScrollView>

View File

@@ -37,7 +37,8 @@
</StackLayout>
<StackLayout Padding="10, 0">
<Button Text="{u:I18n LogIn}"
Clicked="LogIn_Clicked"></Button>
StyleClass="btn-primary"
Clicked="LogIn_Clicked"></Button>
</StackLayout>
</StackLayout>
</ScrollView>

View File

@@ -4,6 +4,7 @@ using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
@@ -52,7 +53,8 @@ namespace Bit.App.Pages
{
IsRunning = true,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.Center
HorizontalOptions = LayoutOptions.Center,
Color = ThemeManager.GetResourceColor("PrimaryColor"),
};
if (targetView != null)
{

View File

@@ -71,6 +71,7 @@
HorizontalOptions="CenterAndExpand"
LineBreakMode="CharacterWrap" />
<Button Text="{u:I18n RegeneratePassword}"
StyleClass="btn-primary"
HorizontalOptions="FillAndExpand"
Clicked="Regenerate_Clicked"></Button>
<Button Text="{u:I18n CopyPassword}"
@@ -108,7 +109,7 @@
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
<controls:ExtendedStepper
Value="{Binding NumWords}"
Maximum="20"
Minimum="3"
@@ -239,7 +240,7 @@
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
<controls:ExtendedStepper
Value="{Binding MinNumber}"
Maximum="5"
Minimum="0"
@@ -259,7 +260,7 @@
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
<controls:ExtendedStepper
Value="{Binding MinSpecial}"
Maximum="5"
Minimum="0"

View File

@@ -1,6 +1,8 @@
using Bit.App.Resources;
using System;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
@@ -9,6 +11,8 @@ namespace Bit.App.Pages
{
public partial class GeneratorPage : BaseContentPage
{
private readonly IBroadcasterService _broadcasterService;
private GeneratorPageViewModel _vm;
private readonly bool _fromTabPage;
private readonly Action<string> _selectAction;
@@ -18,6 +22,7 @@ namespace Bit.App.Pages
{
_tabsPage = tabsPage;
InitializeComponent();
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_vm = BindingContext as GeneratorPageViewModel;
_vm.Page = this;
_fromTabPage = fromTabPage;
@@ -60,6 +65,22 @@ namespace Bit.App.Pages
{
await InitAsync();
}
_broadcasterService.Subscribe(nameof(GeneratorPage), async (message) =>
{
if (message.Command == "updatedTheme")
{
Device.BeginInvokeOnMainThread(() =>
{
_vm.RedrawPassword();
});
}
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
_broadcasterService.Unsubscribe(nameof(GeneratorPage));
}
protected override bool OnBackButtonPressed()

View File

@@ -262,6 +262,14 @@ namespace Bit.App.Pages
await _passwordGenerationService.AddHistoryAsync(Password);
}
public void RedrawPassword()
{
if (!string.IsNullOrEmpty(_password))
{
TriggerPropertyChanged(nameof(ColoredPassword));
}
}
public async Task SaveOptionsAsync(bool regenerate = true)
{
if (!_doneIniting)

View File

@@ -54,26 +54,6 @@
x:Name="_deleteItem"
x:Key="deleteItem" />
<Style x:Key="segmentedButtonBase" TargetType="Button">
<Setter Property="HeightRequest" Value="{Binding SegmentedButtonHeight}" />
<Setter Property="FontSize" Value="{Binding SegmentedButtonFontSize}" />
<Setter Property="CornerRadius" Value="0" />
</Style>
<Style x:Key="segmentedButtonNormal" BaseResourceKey="segmentedButtonBase" TargetType="Button">
<Setter Property="TextColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="FontAttributes" Value="None" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="BorderColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="BorderWidth" Value="1" />
</Style>
<Style x:Key="segmentedButtonDisabled" BaseResourceKey="segmentedButtonBase" TargetType="Button">
<Setter Property="TextColor" Value="{StaticResource TitleTextColor}" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="BorderWidth" Value="0" />
</Style>
<ScrollView x:Key="scrollView" x:Name="_scrollView">
<StackLayout Spacing="20">
<StackLayout StyleClass="box">
@@ -131,51 +111,25 @@
</Grid.ColumnDefinitions>
<Button
Text="{u:I18n TypeFile}"
StyleClass="segmented-button"
IsEnabled="{Binding IsText}"
HeightRequest="{Binding SegmentedButtonHeight}"
FontSize="{Binding SegmentedButtonFontSize}"
Clicked="FileType_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n File}"
Grid.Column="0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource segmentedButtonNormal}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource segmentedButtonDisabled}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
<Button
Text="{u:I18n TypeText}"
StyleClass="segmented-button"
IsEnabled="{Binding IsFile}"
HeightRequest="{Binding SegmentedButtonHeight}"
FontSize="{Binding SegmentedButtonFontSize}"
Clicked="TextType_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Text}"
Grid.Column="1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource segmentedButtonNormal}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource segmentedButtonDisabled}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</Grid>
</StackLayout>
@@ -289,20 +243,20 @@
Text="{u:I18n Options}"
x:Name="_btnOptions"
StyleClass="box-row-button"
TextColor="{StaticResource PrimaryColor}"
TextColor="{DynamicResource PrimaryColor}"
Margin="0" />
<controls:FaButton
x:Name="_btnOptionsUp"
Text="&#xf077;"
StyleClass="box-row-button"
TextColor="{StaticResource PrimaryColor}"
TextColor="{DynamicResource PrimaryColor}"
Clicked="ToggleOptions_Clicked"
IsVisible="False" />
<controls:FaButton
x:Name="_btnOptionsDown"
Text="&#xf078;"
StyleClass="box-row-button"
TextColor="{StaticResource PrimaryColor}"
TextColor="{DynamicResource PrimaryColor}"
Clicked="ToggleOptions_Clicked"
IsVisible="False" />
</StackLayout>
@@ -421,7 +375,7 @@
MaxLength="9"
TextChanged="OnMaxAccessCountTextChanged"
HorizontalOptions="FillAndExpand" />
<Stepper
<controls:ExtendedStepper
x:Name="_maxAccessCountStepper"
Value="{Binding MaxAccessCount}"
Maximum="999999999"

View File

@@ -61,7 +61,6 @@ namespace Bit.App.Pages
protected override async void OnAppearing()
{
base.OnAppearing();
await _vm.InitAsync();
if (_syncService.SyncInProgress)
{
IsBusy = true;

View File

@@ -110,11 +110,6 @@ namespace Bit.App.Pages
public Command<SendView> SendOptionsCommand { get; set; }
public bool LoadedOnce { get; set; }
public async Task InitAsync()
{
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
}
public async Task LoadAsync()
{
if (_doingLoad)
@@ -142,6 +137,7 @@ namespace Bit.App.Pages
ShowNoData = false;
Loading = true;
ShowList = false;
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
var groupedSends = new List<SendGroupingsPageListGroup>();
var page = Page as SendGroupingsPage;

View File

@@ -29,7 +29,7 @@
HorizontalOptions="End" />
<Button
Clicked="ToggleAutofillService"
BackgroundColor="Transparent"
StyleClass="box-overlay"
RelativeLayout.XConstraint="0"
RelativeLayout.YConstraint="0"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AutofillServiceSwitch, Property=Width}"
@@ -58,8 +58,7 @@
HorizontalOptions="End" />
<Button
Clicked="ToggleInlineAutofill"
IsEnabled="{Binding InlineAutofillEnabled}"
BackgroundColor="Transparent"
StyleClass="box-overlay"
RelativeLayout.XConstraint="0"
RelativeLayout.YConstraint="0"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=InlineAutofillSwitch, Property=Width}"
@@ -85,7 +84,7 @@
HorizontalOptions="End" />
<Button
Clicked="ToggleAccessibility"
BackgroundColor="Transparent"
StyleClass="box-overlay"
RelativeLayout.XConstraint="0"
RelativeLayout.YConstraint="0"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AccessibilitySwitch, Property=Width}"
@@ -114,8 +113,7 @@
HorizontalOptions="End" />
<Button
Clicked="ToggleDrawOver"
IsEnabled="{Binding DrawOverEnabled}"
BackgroundColor="Transparent"
StyleClass="box-overlay"
RelativeLayout.XConstraint="0"
RelativeLayout.YConstraint="0"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=DrawOverSwitch, Property=Width}"

View File

@@ -170,6 +170,10 @@ namespace Bit.App.Pages
public void ToggleInlineAutofill()
{
if (!InlineAutofillEnabled)
{
return;
}
InlineAutofillToggled = !InlineAutofillToggled;
}
@@ -180,6 +184,10 @@ namespace Bit.App.Pages
public void ToggleDrawOver()
{
if (!DrawOverEnabled)
{
return;
}
_deviceActionService.OpenAccessibilityOverlayPermissionSettings();
}

View File

@@ -31,8 +31,7 @@
</StackLayout>
<Label
StyleClass="box-footer-label"
Text="{u:I18n ThemeDescription}"
x:Name="_themeDescriptionLabel" />
Text="{u:I18n ThemeDescription}" />
</StackLayout>
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row, box-row-input, box-row-input-options-platform">

View File

@@ -25,8 +25,6 @@ namespace Bit.App.Pages
{
ToolbarItems.RemoveAt(0);
_vm.ShowAndroidAutofillSettings = _deviceActionService.SupportsAutofillService();
_themeDescriptionLabel.Text = string.Concat(_themeDescriptionLabel.Text, " ",
AppResources.RestartIsRequired);
}
else
{

View File

@@ -59,7 +59,7 @@ namespace Bit.App.Pages
}
ThemeOptions = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(null, AppResources.Default),
new KeyValuePair<string, string>(null, AppResources.ThemeDefault),
new KeyValuePair<string, string>("light", AppResources.Light),
new KeyValuePair<string, string>("dark", AppResources.Dark),
new KeyValuePair<string, string>("black", AppResources.Black),
@@ -215,17 +215,8 @@ namespace Bit.App.Pages
{
var theme = ThemeOptions[ThemeSelectedIndex].Key;
await _storageService.SaveAsync(Constants.ThemeKey, theme);
if (Device.RuntimePlatform == Device.Android)
{
await _deviceActionService.ShowLoadingAsync(AppResources.Restarting);
await Task.Delay(1000);
}
_messagingService.Send("updatedTheme", theme);
if (Device.RuntimePlatform == Device.iOS)
{
await Task.Delay(500);
await _platformUtilsService.ShowDialogAsync(AppResources.ThemeAppliedOnRestart);
}
ThemeManager.SetTheme(Device.RuntimePlatform == Device.Android, Application.Current.Resources);
_messagingService.Send("updatedTheme");
}
}

View File

@@ -1,18 +1,24 @@
using Bit.App.Effects;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class TabsPage : TabbedPage
{
private readonly IMessagingService _messagingService;
private NavigationPage _groupingsPage;
private NavigationPage _sendGroupingsPage;
private NavigationPage _generatorPage;
public TabsPage(AppOptions appOptions = null, PreviousPageInfo previousPage = null)
{
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_groupingsPage = new NavigationPage(new GroupingsPage(true, previousPage: previousPage))
{
Title = AppResources.MyVault,
@@ -85,6 +91,7 @@ namespace Bit.App.Pages
{
if (CurrentPage is NavigationPage navPage)
{
_messagingService.Send("updatedTheme");
if (navPage.RootPage is GroupingsPage groupingsPage)
{
// Load something?

View File

@@ -563,7 +563,7 @@
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf29c;"
Command="{Binding PasswordPromptHelpCommand}"
TextColor="{StaticResource MutedColor}"
TextColor="{DynamicResource MutedColor}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
HorizontalOptions="StartAndExpand" />