Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend.XF: added the settings icon and side menu #203

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added img/settings_80x80.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 64 additions & 5 deletions src/GWallet.Frontend.XF/BalancesPage.xaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
<?xml version="1.0" encoding="utf-8"?>
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:GWallet.Frontend.XF"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this iOS thing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without we wouldn't be able to apply a safe area to the ios version of the app

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is a safe area?

Copy link
Author

@kubaflo kubaflo Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an area where the notch is. Here are the screens how the app would look like without it

Simulator Screen Shot - iPhone 14 Pro Max - 2023-01-31 at 13 16 51 Simulator Screen Shot - iPhone 14 Pro Max - 2023-01-31 at 13 16 55

ios:FlyoutPage.ApplyShadow="True"
xmlns:controls="clr-namespace:GWallet.Frontend.XF.Controls"
x:Class="GWallet.Frontend.XF.BalancesPage">
<StackLayout x:Name="mainLayout"
Padding="0,0,0,0"
VerticalOptions="FillAndExpand">

<!-- Side menu-->
<FlyoutPage.Flyout>
<ContentPage Title="FlyoutMenu"
ios:Page.UseSafeArea="True" >
<StackLayout Spacing="20" Margin="10,10,15,0">

<Image HeightRequest="80"
WidthRequest="80"
Margin="0,0,0,10"
x:Name="sideMenuImg"/>

<StackLayout Spacing="15" Orientation="Horizontal">
<Label VerticalOptions="Center" Text="#"/>
<Label x:Name="inMenuLbl1" Text="Check you still remember your payment password"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Text, Source={x:Reference inMenuLbl1}}" Tapped="OpenSettingsTapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>

<StackLayout Spacing="15" Orientation="Horizontal">
<Label VerticalOptions="Center" Text="#"/>
<Label x:Name="inMenuLbl2" Text="Check you still remember your secret recovery phrase"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Text, Source={x:Reference inMenuLbl2}}" Tapped="OpenSettingsTapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>

<StackLayout Spacing="15" Orientation="Horizontal">
<Label VerticalOptions="Center" Text="#"/>
<Label x:Name="inMenuLbl3" Text="Wipe your current wallet, in order to start from scratch"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding Text, Source={x:Reference inMenuLbl3}}" Tapped="OpenSettingsTapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</StackLayout>
</ContentPage>
</FlyoutPage.Flyout>

<!-- Main page-->
<FlyoutPage.Detail>
<ContentPage ios:Page.UseSafeArea="True"
Title="Balances">
<StackLayout x:Name="mainLayout"
Padding="0,0,0,0"
VerticalOptions="FillAndExpand">

<!-- Settings icon-->
<ImageButton
x:Name="settingsImgBtn"
BackgroundColor="Transparent"
Padding="0"
HeightRequest="30"
WidthRequest="30"
HorizontalOptions="Start"
Margin="10,10,0,0"
Clicked="OpenFlyoutClicked"/>


<StackLayout Orientation="Horizontal"
Padding="15, 10"
Expand Down Expand Up @@ -82,3 +139,5 @@
Margin="0,10,0,10" />
</StackLayout>
</ContentPage>
</FlyoutPage.Detail>
</FlyoutPage>
14 changes: 13 additions & 1 deletion src/GWallet.Frontend.XF/BalancesPage.xaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState,
currencyImages: Map<Currency*bool,Image>,
startWithReadOnlyAccounts: bool)
as this =
inherit ContentPage()
inherit FlyoutPage()

let _ = base.LoadFromXaml(typeof<BalancesPage>)

Expand All @@ -46,6 +46,8 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState,
let contentLayout = base.FindByName<StackLayout> "contentLayout"
let normalChartView = base.FindByName<CircleChartView> "normalChartView"
let readonlyChartView = base.FindByName<CircleChartView> "readonlyChartView"
let sideMenuImg = base.FindByName<Image> "sideMenuImg"
let settingsImgBtn = base.FindByName<ImageButton> "settingsImgBtn"

let standardTimeToRefreshBalances = TimeSpan.FromMinutes 5.0
let standardTimeToRefreshBalancesWhenThereIsImminentIncomingPaymentOrNotEnoughInfoToKnow = TimeSpan.FromMinutes 1.0
Expand Down Expand Up @@ -500,6 +502,8 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState,
member private this.Init () =
normalChartView.DefaultImageSource <- FrontendHelpers.GetSizedImageSource "logo" 512
readonlyChartView.DefaultImageSource <- FrontendHelpers.GetSizedImageSource "logo" 512
sideMenuImg.Source <- FrontendHelpers.GetSizedImageSource "logo" 512
settingsImgBtn.Source <- FrontendHelpers.GetSizedImageSource "settings" 80

let tapGestureRecognizer = TapGestureRecognizer()
tapGestureRecognizer.Tapped.Subscribe(fun _ ->
Expand Down Expand Up @@ -535,3 +539,11 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState,
this.StopTimer()
this.CancelBalanceRefreshJobs()
)

member self.OpenFlyoutClicked(_sender: obj, _evArgs: EventArgs) =
this.IsPresented <- true

member self.OpenSettingsTapped(_sender: obj, evArgs: EventArgs) =
let title = (evArgs :?> TappedEventArgs).Parameter :?> string
let settingsPage () = SettingsPage title :> Page
FrontendHelpers.SwitchToNewPage this settingsPage true
7 changes: 7 additions & 0 deletions src/GWallet.Frontend.XF/GWallet.Frontend.XF.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
<EmbeddedResource Include="..\..\img\eth_grey_120x120.png">
<Link>img\eth_grey_120x120.png</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\..\img\settings_80x80.png">
<Link>img\settings_80x80.png</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\..\img\eth_red_60x60.png">
<Link>img\eth_red_60x60.png</Link>
</EmbeddedResource>
Expand Down Expand Up @@ -103,6 +106,10 @@
<DependentUpon>SendPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="SettingsPage.xaml.fs">
<DependentUpon>SettingsPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="PairingToPage.xaml.fs">
<DependentUpon>PairingToPage.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down
129 changes: 129 additions & 0 deletions src/GWallet.Frontend.XF/SettingsPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="GWallet.Frontend.XF.SettingsPage">

<AbsoluteLayout>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kubaflo question, is there any specific reason of why you used AbsoluteLayout here instead of an non-absolute alternative?

Copy link
Author

@kubaflo kubaflo Feb 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is necessary as I want the 'mainLayout' to occupy 70% of the page's width

<StackLayout x:Name="mainLayout"
                      AbsoluteLayout.LayoutFlags="XProportional,SizeProportional"
                      AbsoluteLayout.LayoutBounds="0.5,50,0.7,1"
                      VerticalOptions="FillAndExpand">

<StackLayout x:Name="mainLayout"
AbsoluteLayout.LayoutFlags="XProportional,SizeProportional"
AbsoluteLayout.LayoutBounds="0.5,50,0.7,1"
VerticalOptions="FillAndExpand">

<Label x:Name="titleLabel" Text="" Margin="0,0,0,10" HorizontalTextAlignment="Center" TextTransform="Uppercase"/>

<!-- Check you still remember your payment password-->
<StackLayout Spacing="10"
IsVisible="false">
<Entry x:Name="passwordEntry"
IsPassword="true"
Focused="ClearResult"
Text=""
Placeholder="Type your password"/>

<Button Text="Check my password"
Clicked="OnCheckPasswordButtonClicked"
HorizontalOptions="FillAndExpand">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding Text.Length, Source={x:Reference passwordEntry}}"
Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Button.Triggers>
</Button>
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding Text, Source={x:Reference titleLabel}}"
Value="Check you still remember your payment password">
<Setter Property="IsVisible" Value="True"/>
</DataTrigger>
</StackLayout.Triggers>
</StackLayout>

<!--Check you still remember your secret recovery phrase-->
<StackLayout IsVisible="false">
<Entry x:Name="phraseEntry"
Focused="ClearResult"
IsPassword="true"
Text=""
Placeholder="Type your recovery phrase"/>

<Grid>
<DatePicker x:Name="dateOfBirthPicker"
Focused="ClearResult"
HorizontalOptions="FillAndExpand"
TextColor="Transparent"
DateSelected="OnDatePickerDateSelected"/>
<Entry x:Name="dateOfBirthLabel"
Placeholder="Choose your date of birth"
BackgroundColor="Transparent"
VerticalOptions="Center"
InputTransparent="True"
IsEnabled="False"/>
</Grid>

<Entry x:Name="emailEntry"
Focused="ClearResult"
Text=""
Placeholder="Type your email"/>

<Button Text="Check my secret recovery phrase"
Clicked="OnCheckPasswordButtonClicked"
HorizontalOptions="FillAndExpand">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding Text.Length, Source={x:Reference emailEntry}}"
Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding Text, Source={x:Reference dateOfBirthLabel}}"
Value="Choose your date of birth">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding Text.Length, Source={x:Reference phraseEntry}}"
Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Button.Triggers>
</Button>
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding Text, Source={x:Reference titleLabel}}"
Value="Check you still remember your secret recovery phrase">
<Setter Property="IsVisible" Value="True"/>
</DataTrigger>
</StackLayout.Triggers>
</StackLayout>

<!-- Wipe your current wallet, in order to start from scratch-->
<StackLayout Spacing="10"
IsVisible="false">

<Label Text="If you want to remove accounts, the recommended way is to archive them, not wipe the whole wallet."
HorizontalTextAlignment="Center"/>

<Button Text="I want to do it anyway"
Clicked="OnWipeWalletButtonClicked"
HorizontalOptions="FillAndExpand">
</Button>
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding Text, Source={x:Reference titleLabel}}"
Value="Wipe your current wallet, in order to start from scratch">
<Setter Property="IsVisible" Value="True"/>
</DataTrigger>
</StackLayout.Triggers>
</StackLayout>

<!-- Loading & Results -->
<Grid Margin="0,30,0,0">
<ActivityIndicator IsVisible="False" x:Name="loadingIndicator" IsRunning="True"/>
<Label x:Name="resultMessage" IsVisible="False" HorizontalTextAlignment="Center" Text="Try again"/>
</Grid>

</StackLayout>
</AbsoluteLayout>
</ContentPage>
70 changes: 70 additions & 0 deletions src/GWallet.Frontend.XF/SettingsPage.xaml.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
namespace GWallet.Frontend.XF

open System
open System.Linq

open Xamarin.Forms
open Xamarin.Forms.Xaml
open Fsdk

open GWallet.Backend

type SettingsPage(option: string) as this =
inherit ContentPage()
let _ = base.LoadFromXaml(typeof<SettingsPage>)
let titleLabel = base.FindByName<Label> "titleLabel"

//check password
let passwordEntry = base.FindByName<Entry> "passwordEntry"

//check passphrase
let phraseEntry = base.FindByName<Entry> "phraseEntry"
let emailEntry = base.FindByName<Entry> "emailEntry"
let dateOfBirthPicker = base.FindByName<DatePicker> "dateOfBirthPicker"
let dateOfBirthLabel = base.FindByName<Entry> "dateOfBirthLabel"

//loading & result
let resultMessage = base.FindByName<Label> "resultMessage"
let loadingIndicator = base.FindByName<ActivityIndicator> "loadingIndicator"

do
this.Init()

member self.Init () =
titleLabel.Text <- option

member self.OnCheckPasswordButtonClicked(_sender: Object, _args: EventArgs) =
this.PerformCheck (Account.CheckValidPassword passwordEntry.Text None)

member self.OnCheckSeedPassphraseClicked(_sender: Object, _args: EventArgs) =
this.PerformCheck (Account.CheckValidSeed phraseEntry.Text dateOfBirthPicker.Date emailEntry.Text)

member self.PerformCheck(checkTask: Async<bool>) =
async {
Device.BeginInvokeOnMainThread(
fun () ->
loadingIndicator.IsVisible <- true
resultMessage.IsVisible <- false)
let! checkResult = checkTask
Device.BeginInvokeOnMainThread(
fun () ->
loadingIndicator.IsVisible <- false
resultMessage.IsVisible <- true
resultMessage.Text <- if checkResult then "Success!" else "Try again" )
} |> FrontendHelpers.DoubleCheckCompletionAsync true

member self.OnWipeWalletButtonClicked (_sender: Object, _args: EventArgs) =
async {
let! result = Application.Current.MainPage.DisplayAlert("Are you sure?", "Are you ABSOLUTELY SURE about this?", "Yes", "No") |> Async.AwaitTask
if result then
Account.WipeAll()
let displayTask = Application.Current.MainPage.DisplayAlert("Success", "You successfully wiped your current wallet", "Ok")
do! Async.AwaitTask displayTask

} |> Async.StartImmediate

member self.OnDatePickerDateSelected (_sender: obj) (evArgs: DateChangedEventArgs) =
dateOfBirthLabel.Text <- evArgs.NewDate.ToString("dd MMMM yyyy")

member self.ClearResult (_sender: Object, _args: EventArgs) =
resultMessage.IsVisible <- false