Skip to content

Commit ec59ff2

Browse files
committed
Added login options in MAUI
1 parent 39eb3f5 commit ec59ff2

8 files changed

Lines changed: 105 additions & 69 deletions

File tree

src/Platforms/SecureFolderFS.Maui/Views/Vault/LoginPage.xaml

Lines changed: 83 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
xmlns:mi_cupertino="clr-namespace:MauiIcons.Cupertino;assembly=MauiIcons.Cupertino"
99
xmlns:mi_material="clr-namespace:MauiIcons.Material;assembly=MauiIcons.Material"
1010
xmlns:uc="clr-namespace:SecureFolderFS.Maui.UserControls"
11+
xmlns:uco="clr-namespace:SecureFolderFS.Maui.UserControls.Options"
1112
xmlns:vc="clr-namespace:SecureFolderFS.Maui.ValueConverters"
1213
Title="{Binding ViewModel.VaultViewModel.Title, Mode=OneWay}"
1314
x:DataType="local:LoginPage">
@@ -18,74 +19,92 @@
1819

1920
<Grid>
2021
<ScrollView>
21-
<VerticalStackLayout Padding="20,0" VerticalOptions="CenterAndExpand">
22+
<Grid Padding="20">
23+
<VerticalStackLayout VerticalOptions="Center">
24+
<!-- Lock icon plate + heading -->
25+
<VerticalStackLayout Margin="0,0,0,48" Spacing="16">
26+
<Border
27+
Background="{StaticResource ThemeSecondaryColorBrush}"
28+
HeightRequest="88"
29+
HorizontalOptions="Center"
30+
StrokeThickness="0"
31+
WidthRequest="88">
32+
<Border.StrokeShape>
33+
<RoundRectangle CornerRadius="22" />
34+
</Border.StrokeShape>
35+
<Grid>
36+
<mi:MauiIcon
37+
HorizontalOptions="Center"
38+
Icon="{mi_material:Material Lock}"
39+
IconColor="{AppThemeBinding Light={StaticResource PrimaryLightColor},
40+
Dark={StaticResource PrimaryDarkColor}}"
41+
IconSize="44"
42+
OnPlatforms="Android"
43+
VerticalOptions="Center" />
44+
<mi:MauiIcon
45+
HorizontalOptions="Center"
46+
Icon="{mi_cupertino:Cupertino Lock}"
47+
IconColor="{AppThemeBinding Light={StaticResource PrimaryLightColor},
48+
Dark={StaticResource PrimaryDarkColor}}"
49+
IconSize="44"
50+
OnPlatforms="iOS"
51+
VerticalOptions="Center" />
52+
</Grid>
53+
</Border>
54+
<Label
55+
FontAttributes="Bold"
56+
FontSize="22"
57+
HorizontalOptions="Center"
58+
HorizontalTextAlignment="Center"
59+
Text="{l:ResourceString Rid=VaultLocked}" />
60+
</VerticalStackLayout>
2261

23-
<!-- Lock icon plate + heading -->
24-
<VerticalStackLayout Margin="0,0,0,48" Spacing="16">
25-
<Border
26-
Background="{StaticResource ThemeSecondaryColorBrush}"
27-
HeightRequest="88"
28-
HorizontalOptions="Center"
29-
StrokeThickness="0"
30-
WidthRequest="88">
31-
<Border.StrokeShape>
32-
<RoundRectangle CornerRadius="22" />
33-
</Border.StrokeShape>
34-
<Grid>
35-
<mi:MauiIcon
36-
HorizontalOptions="Center"
37-
Icon="{mi_material:Material Lock}"
38-
IconColor="{AppThemeBinding Light={StaticResource PrimaryLightColor},
39-
Dark={StaticResource PrimaryDarkColor}}"
40-
IconSize="44"
41-
OnPlatforms="Android"
42-
VerticalOptions="Center" />
43-
<mi:MauiIcon
44-
HorizontalOptions="Center"
45-
Icon="{mi_cupertino:Cupertino Lock}"
46-
IconColor="{AppThemeBinding Light={StaticResource PrimaryLightColor},
47-
Dark={StaticResource PrimaryDarkColor}}"
48-
IconSize="44"
49-
OnPlatforms="iOS"
50-
VerticalOptions="Center" />
51-
</Grid>
52-
</Border>
53-
<Label
54-
FontAttributes="Bold"
55-
FontSize="22"
56-
HorizontalOptions="Center"
57-
HorizontalTextAlignment="Center"
58-
Text="{l:ResourceString Rid=VaultLocked}" />
59-
</VerticalStackLayout>
62+
<!-- Remote connection progress indicator -->
63+
<ActivityIndicator
64+
Margin="0,0,0,16"
65+
IsRunning="{Binding ViewModel.IsProgressing, Mode=OneWay}"
66+
IsVisible="{Binding ViewModel.LoginViewModel, Mode=OneWay, Converter={StaticResource NullToBoolConverter}}"
67+
Opacity="{Binding ViewModel.IsProgressing, Mode=OneWay, Converter={StaticResource BoolOpacityConverter}}" />
6068

61-
<!-- Remote connection progress indicator -->
62-
<ActivityIndicator
63-
Margin="0,0,0,16"
64-
IsRunning="{Binding ViewModel.IsProgressing, Mode=OneWay}"
65-
IsVisible="{Binding ViewModel.LoginViewModel, Mode=OneWay, Converter={StaticResource NullToBoolConverter}}"
66-
Opacity="{Binding ViewModel.IsProgressing, Mode=OneWay, Converter={StaticResource BoolOpacityConverter}}" />
69+
<!-- Login -->
70+
<uc:VaultLocatorControl
71+
CancelConnectionCommand="{Binding ViewModel.CancelConnectionCommand, Mode=OneWay}"
72+
ConnectCommand="{Binding ViewModel.ConnectToVaultCommand, Mode=OneWay}"
73+
IsConnected="{Binding ViewModel.LoginViewModel, Mode=OneWay, Converter={StaticResource NullToBoolConverter}}"
74+
IsRunning="{Binding ViewModel.ConnectToVaultCommand.IsRunning, Mode=OneWay}">
75+
<uc:VaultLocatorControl.LoginView>
76+
<VerticalStackLayout IsVisible="{Binding ViewModel.IsProgressing, Mode=OneWay, Converter={StaticResource BoolInvertConverter}}" Spacing="8">
77+
<uc:LoginControl CurrentViewModel="{Binding ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay}" ProvideContinuationButton="True" />
78+
<Button
79+
Command="{Binding ViewModel.LoginViewModel.RecoverAccessCommand}"
80+
HorizontalOptions="{OnPlatform Android={LayoutOptions Alignment=Fill},
81+
iOS={LayoutOptions Alignment=Center}}"
82+
IsVisible="{Binding ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay, Converter={StaticResource TypeNameBoolConverter}, ConverterParameter='MigrationViewModel,ErrorViewModel|invert'}"
83+
Style="{OnPlatform Android={StaticResource TransparentButtonStyle},
84+
iOS={StaticResource NoBackgroundButtonStyle}}"
85+
Text="{l:ResourceString Rid=RecoverAccess}" />
86+
</VerticalStackLayout>
87+
</uc:VaultLocatorControl.LoginView>
88+
</uc:VaultLocatorControl>
89+
</VerticalStackLayout>
6790

68-
<!-- Login -->
69-
<uc:VaultLocatorControl
70-
CancelConnectionCommand="{Binding ViewModel.CancelConnectionCommand, Mode=OneWay}"
71-
ConnectCommand="{Binding ViewModel.ConnectToVaultCommand, Mode=OneWay}"
72-
IsConnected="{Binding ViewModel.LoginViewModel, Mode=OneWay, Converter={StaticResource NullToBoolConverter}}"
73-
IsRunning="{Binding ViewModel.ConnectToVaultCommand.IsRunning, Mode=OneWay}">
74-
<uc:VaultLocatorControl.LoginView>
75-
<VerticalStackLayout IsVisible="{Binding ViewModel.IsProgressing, Mode=OneWay, Converter={StaticResource BoolInvertConverter}}" Spacing="8">
76-
<uc:LoginControl CurrentViewModel="{Binding ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay}" ProvideContinuationButton="True" />
77-
<Button
78-
Command="{Binding ViewModel.LoginViewModel.RecoverAccessCommand}"
79-
HorizontalOptions="{OnPlatform Android={LayoutOptions Alignment=Fill},
80-
iOS={LayoutOptions Alignment=Center}}"
81-
IsVisible="{Binding ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay, Converter={StaticResource TypeNameBoolConverter}, ConverterParameter='MigrationViewModel,ErrorViewModel|invert'}"
82-
Style="{OnPlatform Android={StaticResource TransparentButtonStyle},
83-
iOS={StaticResource NoBackgroundButtonStyle}}"
84-
Text="{l:ResourceString Rid=RecoverAccess}" />
91+
<uco:OptionsContainer VerticalOptions="End">
92+
<uco:OptionsContainer.InnerContent>
93+
<VerticalStackLayout>
94+
<uco:OptionsControl Title="{l:ResourceString Rid=UnlockAsReadOnly}">
95+
<uco:OptionsControl.Slot>
96+
<Switch IsToggled="{Binding ViewModel.IsReadOnly, Mode=TwoWay}" />
97+
</uco:OptionsControl.Slot>
98+
</uco:OptionsControl>
99+
<uco:OptionsControl Title="{l:ResourceString Rid=SaveCredentials}" IsSeparatorVisible="False">
100+
<uco:OptionsControl.Slot>
101+
<Switch IsToggled="{Binding ViewModel.ShouldSaveCredentials, Mode=TwoWay}" />
102+
</uco:OptionsControl.Slot>
103+
</uco:OptionsControl>
85104
</VerticalStackLayout>
86-
</uc:VaultLocatorControl.LoginView>
87-
</uc:VaultLocatorControl>
88-
</VerticalStackLayout>
105+
</uco:OptionsContainer.InnerContent>
106+
</uco:OptionsContainer>
107+
</Grid>
89108
</ScrollView>
90109
</Grid>
91110
</ContentPage>

src/Platforms/SecureFolderFS.UI/Strings/en-US/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,4 +1436,7 @@
14361436
<data name="Vault" xml:space="preserve">
14371437
<value>Vault</value>
14381438
</data>
1439+
<data name="SaveCredentials" xml:space="preserve">
1440+
<value>Save credentials</value>
1441+
</data>
14391442
</root>

src/Platforms/SecureFolderFS.Uno/UserControls/InterfaceRoot/VaultPreviewRootControl.xaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@
5151
<StackPanel VerticalAlignment="Center" Spacing="8">
5252
<uc:LoginControl CurrentViewModel="{x:Bind ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay}" ProvideContinuationButton="True" />
5353
<uc:LoginOptions
54-
IsReadOnly="{x:Bind ViewModel.IsReadOnlyLogin, Mode=TwoWay}"
54+
IsReadOnly="{x:Bind ViewModel.IsReadOnly, Mode=TwoWay}"
5555
RecoverAccessCommand="{x:Bind ViewModel.RecoverAccessCommand, Mode=OneWay}"
5656
RestartLoginCommand="{x:Bind ViewModel.LoginViewModel.RestartLoginProcessCommand, Mode=OneWay}"
57+
ShouldSaveCredentials="{x:Bind ViewModel.ShouldSaveCredentials, Mode=TwoWay}"
5758
Visibility="{x:Bind ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay, Converter={StaticResource TypeNameVisibilityConverter}, ConverterParameter='MigrationViewModel,ErrorViewModel|invert'}" />
5859
</StackPanel>
5960
</StackPanel>

src/Platforms/SecureFolderFS.Uno/UserControls/LoginOptions.xaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:l="using:SecureFolderFS.Uno.Localization"
7-
xmlns:local="using:SecureFolderFS.Uno.UserControls"
87
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
98
mc:Ignorable="d">
109

@@ -18,7 +17,10 @@
1817
<Flyout>
1918
<StackPanel Spacing="4">
2019
<CheckBox Content="{l:ResourceString Rid=UnlockAsReadOnly}" IsChecked="{x:Bind IsReadOnly, Mode=TwoWay}" />
21-
<CheckBox Content="Save credentials" IsEnabled="False" />
20+
<CheckBox
21+
Content="{l:ResourceString Rid=SaveCredentials}"
22+
IsChecked="{x:Bind ShouldSaveCredentials, Mode=TwoWay}"
23+
IsEnabled="False" />
2224

2325
<!-- TODO(uno): #18589 -->
2426
<Button

src/Platforms/SecureFolderFS.Uno/UserControls/LoginOptions.xaml.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ private void LoginOptions_Click(object sender, RoutedEventArgs e)
1919
{
2020
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
2121
}
22+
23+
public bool ShouldSaveCredentials
24+
{
25+
get => (bool)GetValue(ShouldSaveCredentialsProperty);
26+
set => SetValue(ShouldSaveCredentialsProperty, value);
27+
}
28+
public static readonly DependencyProperty ShouldSaveCredentialsProperty =
29+
DependencyProperty.Register(nameof(ShouldSaveCredentials), typeof(bool), typeof(LoginOptions), new PropertyMetadata(false));
2230

2331
public bool IsReadOnly
2432
{

src/Platforms/SecureFolderFS.Uno/Views/Vault/VaultLoginPage.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
IsReadOnly="{x:Bind ViewModel.IsReadOnly, Mode=TwoWay}"
5454
RecoverAccessCommand="{x:Bind ViewModel.LoginViewModel.RecoverAccessCommand, Mode=OneWay}"
5555
RestartLoginCommand="{x:Bind ViewModel.LoginViewModel.RestartLoginProcessCommand, Mode=OneWay}"
56+
ShouldSaveCredentials="{x:Bind ViewModel.ShouldSaveCredentials, Mode=TwoWay}"
5657
Visibility="{x:Bind ViewModel.LoginViewModel.CurrentViewModel, Mode=OneWay, Converter={StaticResource TypeNameVisibilityConverter}, ConverterParameter='MigrationViewModel,ErrorViewModel|invert'}" />
5758
</StackPanel>
5859
</StackPanel>

src/Sdk/SecureFolderFS.Sdk/ViewModels/Views/Root/VaultPreviewViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public sealed partial class VaultPreviewViewModel : ObservableObject, IAsyncInit
3030
[ObservableProperty] private UnlockedVaultViewModel? _UnlockedVaultViewModel;
3131
[ObservableProperty] private LoginViewModel? _LoginViewModel;
3232
[ObservableProperty] private VaultViewModel _VaultViewModel;
33-
[ObservableProperty] private bool _IsReadOnlyLogin;
33+
[ObservableProperty] private bool _ShouldSaveCredentials;
34+
[ObservableProperty] private bool _IsReadOnly;
3435

3536
public VaultPreviewViewModel(VaultViewModel vaultViewModel, INavigationService vaultNavigation)
3637
{
@@ -130,7 +131,7 @@ private async Task UnlockAsync(IDisposable unlockContract)
130131
try
131132
{
132133
// Unlock the vault
133-
UnlockedVaultViewModel = await VaultViewModel.UnlockAsync(unlockContract, IsReadOnlyLogin);
134+
UnlockedVaultViewModel = await VaultViewModel.UnlockAsync(unlockContract, IsReadOnly);
134135

135136
// Setup dashboard
136137
var dashboardNavigation = DI.Service<INavigationService>();

src/Sdk/SecureFolderFS.Sdk/ViewModels/Views/Vault/VaultLoginViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public sealed partial class VaultLoginViewModel : BaseDesignationViewModel, IVau
2828
[ObservableProperty] private bool _IsReadOnly;
2929
[ObservableProperty] private bool _IsConnected;
3030
[ObservableProperty] private bool _IsProgressing;
31+
[ObservableProperty] private bool _ShouldSaveCredentials;
3132
[ObservableProperty] private LoginViewModel? _LoginViewModel;
3233

3334
public INavigationService VaultNavigation { get; }

0 commit comments

Comments
 (0)