diff --git a/.gitignore b/.gitignore index cff268905..61924dfc1 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,7 @@ src/GWallet.Frontend.Maui/WelcomePage.xaml src/GWallet.Frontend.Maui/WelcomePage2.xaml src/GWallet.Frontend.Maui/LoadingPage.xaml src/GWallet.Frontend.Maui/BalancesPage.xaml +src/GWallet.Frontend.Maui/PairingFromPage.xaml +src/GWallet.Frontend.Maui/PairingToPage.xaml +src/GWallet.Frontend.Maui/SendPage.xaml +src/GWallet.Frontend.Maui/ReceivePage.xaml diff --git a/scripts/make.fsx b/scripts/make.fsx index 887508103..e83adcf33 100644 --- a/scripts/make.fsx +++ b/scripts/make.fsx @@ -260,7 +260,17 @@ let BuildSolutionOrProject // TODO: we have to change this function to be the other way around (i.e. copy from Maui to XF) once we // have a finished version of Maui and we consider XF as legacy. let CopyXamlFiles() = - let files = [| "WelcomePage.xaml"; "WelcomePage2.xaml"; "LoadingPage.xaml"; "BalancesPage.xaml" |] + let files = + [| + "WelcomePage.xaml" + "WelcomePage2.xaml" + "LoadingPage.xaml" + "BalancesPage.xaml" + "PairingFromPage.xaml" + "PairingToPage.xaml" + "ReceivePage.xaml" + "SendPage.xaml" + |] for file in files do let sourcePath = Path.Combine("src", "GWallet.Frontend.XF", file) let destPath = Path.Combine("src", "GWallet.Frontend.Maui", file) @@ -271,7 +281,9 @@ let CopyXamlFiles() = destPath, fileText .Replace("http://xamarin.com/schemas/2014/forms","http://schemas.microsoft.com/dotnet/2021/maui") + .Replace("clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms","clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls") .Replace("GWallet.Frontend.XF", "GWallet.Frontend.Maui") + .Replace("ZXingBarcodeImageView", "BarcodeGeneratorView") ) diff --git a/src/GWallet.Frontend.Maui/GWallet.Frontend.Maui.fsproj b/src/GWallet.Frontend.Maui/GWallet.Frontend.Maui.fsproj index c8fb21bad..401bc5ffc 100644 --- a/src/GWallet.Frontend.Maui/GWallet.Frontend.Maui.fsproj +++ b/src/GWallet.Frontend.Maui/GWallet.Frontend.Maui.fsproj @@ -143,6 +143,10 @@ + + + + @@ -150,6 +154,18 @@ + + PairingFromPage.xaml + + + PairingToPage.xaml + + + SendPage.xaml + + + ReceivePage.xaml + BalancesPage.xaml diff --git a/src/GWallet.Frontend.XF/BalancesPage.xaml.fs b/src/GWallet.Frontend.XF/BalancesPage.xaml.fs index 0c7aa03ac..b0834b6f1 100644 --- a/src/GWallet.Frontend.XF/BalancesPage.xaml.fs +++ b/src/GWallet.Frontend.XF/BalancesPage.xaml.fs @@ -35,6 +35,8 @@ open GWallet.Backend open GWallet.Backend.FSharpUtil.UwpHacks +type FiatAmountFrameTapHandler = unit -> unit + // this type allows us to represent the idea that if we have, for example, 3 LTC and an unknown number of ETC (might // be because all ETC servers are unresponsive), then it means we have AT LEAST 3LTC; as opposed to when we know for // sure all balances of all currencies because all servers are responsive @@ -272,14 +274,12 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState, balances |> Seq.iteri (fun balanceIndex balanceState -> let balanceSet = balanceState.BalanceSet let tapGestureRecognizer = TapGestureRecognizer() -#if XAMARIN tapGestureRecognizer.Tapped.Subscribe(fun _ -> let receivePage () = ReceivePage(balanceSet.Account, readOnly, balanceState.UsdRate, self, balanceSet.Widgets) :> Page FrontendHelpers.SwitchToNewPage self receivePage true ) |> ignore -#endif let frame = balanceSet.Widgets.Frame frame.GestureRecognizers.Add tapGestureRecognizer contentLayout.Children.Add frame @@ -423,7 +423,7 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState, cancelSource.Cancel() cancelSource.Dispose() - member private self.ConfigureFiatAmountFrame (readOnly: bool): TapGestureRecognizer = + member private self.ConfigureFiatAmountFrame (readOnly: bool): FiatAmountFrameTapHandler = let totalCurrentFiatAmountFrameName,totalOtherFiatAmountFrameName = if readOnly then "totalReadOnlyFiatAmountFrame","totalFiatAmountFrame" @@ -447,9 +447,8 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState, mainLayout.FindByName otherChartViewName let tapGestureRecognizer = TapGestureRecognizer() -#if XAMARIN - tapGestureRecognizer.Tapped.Add(fun _ -> + let tapHandler () = let shouldNotOpenNewPage = if switchingToReadOnly then readOnlyAccountsBalanceSets.Any() @@ -495,26 +494,22 @@ type BalancesPage(state: FrontendHelpers.IGlobalAppState, PairingFromPage(self, "Copy wallet info to clipboard", walletInfoJson, None) :> Page FrontendHelpers.SwitchToNewPage self page true - - ) -#endif + + tapGestureRecognizer.Tapped.Add(fun _ -> tapHandler()) + totalCurrentFiatAmountFrame.GestureRecognizers.Add tapGestureRecognizer - tapGestureRecognizer + tapHandler member self.PopulateGridInitially () = - let tapper = self.ConfigureFiatAmountFrame false + let tapHandler = self.ConfigureFiatAmountFrame false self.ConfigureFiatAmountFrame true |> ignore self.PopulateBalances false normalBalanceStates RedrawCircleView false normalBalanceStates if startWithReadOnlyAccounts then -#if XAMARIN - tapper.SendTapped null -#else - () // No tapper.SendTapped in MAUI -#endif + tapHandler() member private __.AssignColorLabels (readOnly: bool) = let labels,color = diff --git a/src/GWallet.Frontend.XF/FrontendHelpers.fs b/src/GWallet.Frontend.XF/FrontendHelpers.fs index f88f003a4..0c88300aa 100644 --- a/src/GWallet.Frontend.XF/FrontendHelpers.fs +++ b/src/GWallet.Frontend.XF/FrontendHelpers.fs @@ -24,6 +24,7 @@ open Xamarin.Forms open Xamarin.Essentials open ZXing open ZXing.Mobile +open ZXing.Net.Mobile.Forms #endif open Fsdk open GWallet.Backend @@ -329,7 +330,11 @@ module FrontendHelpers = let SwitchToNewPage (currentPage: Page) (createNewPage: unit -> Page) (navBar: bool): unit = MainThread.BeginInvokeOnMainThread(fun _ -> let newPage = createNewPage () +#if !XAMARIN && GTK + NavigationPage.SetHasNavigationBar(newPage, navBar) +#else NavigationPage.SetHasNavigationBar(newPage, false) +#endif let navPage = NavigationPage newPage NavigationPage.SetHasNavigationBar(navPage, navBar) @@ -482,6 +487,32 @@ module FrontendHelpers = #else BarcodeReaderOptions(TryHarder = true, Formats = BarcodeFormat.QrCode) #endif + + let GetBarcodeScannerPage (onBarcodeDetected: string -> unit) = +#if XAMARIN + let scanPage = ZXingScannerPage BarCodeScanningOptions + scanPage.add_OnScanResult(fun result -> + scanPage.IsScanning <- false + onBarcodeDetected result.Text + ) + scanPage +#else + let scanView = ZXing.Net.Maui.Controls.CameraBarcodeReaderView(Options = BarCodeScanningOptions) + scanView.BarcodesDetected.Add(fun result -> + let barCodeText = result.Results.[0].Value // assume our barcode is first result? + onBarcodeDetected barCodeText + ) + ContentPage(Content = scanView) +#endif + + /// Safer alternative to Navigation.PopModalAsync(): when ModalStack is empty, do nothing. + /// This is used in barcode scanner calbacks because sometimes those would be called more than one time. + let TryPopModalAsync (page: Page) : Task = + if page.Navigation.ModalStack.Count > 0 then + page.Navigation.PopModalAsync() + else + Task.FromResult page + let GetImageSource name = let thisAssembly = typeof.Assembly let thisAssemblyName = thisAssembly.GetName().Name diff --git a/src/GWallet.Frontend.XF/PairingFromPage.xaml.fs b/src/GWallet.Frontend.XF/PairingFromPage.xaml.fs index 4741ce44d..d70204d10 100644 --- a/src/GWallet.Frontend.XF/PairingFromPage.xaml.fs +++ b/src/GWallet.Frontend.XF/PairingFromPage.xaml.fs @@ -1,12 +1,26 @@ -namespace GWallet.Frontend.XF +#if XAMARIN +namespace GWallet.Frontend.XF +#else +namespace GWallet.Frontend.Maui +#endif open System +#if !XAMARIN +open Microsoft.Maui.Controls +open Microsoft.Maui.Controls.Xaml +open Microsoft.Maui.ApplicationModel +open Microsoft.Maui.ApplicationModel.DataTransfer + +open ZXing.Net.Maui +open ZXing.Net.Maui.Controls +#else open Xamarin.Forms open Xamarin.Forms.Xaml open Xamarin.Essentials open ZXing.Net.Mobile.Forms +#endif type PairingFromPage(previousPage: Page, clipBoardButtonCaption: string, @@ -28,13 +42,23 @@ type PairingFromPage(previousPage: Page, let clipBoardButton = mainLayout.FindByName