From e94eaf7700ae7193d4a76bef2ffedaee294078b3 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Fri, 12 Jun 2026 16:06:37 +0200 Subject: [PATCH] refactor(arch): split App into shared library + Desktop + Android heads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Avalonia UI code (App, Views, ViewModels, Localization, Assets) now lives in src/App as a plain library (no OutputType). Two thin heads reference it: - src/App.Desktop/ — WinExe, Avalonia.Desktop, hosts MainView in a MainWindow; carries Program.cs and app.manifest (moved from src/App) - src/App.Android/ — net10.0-android, Avalonia.Android, MainActivity/ MainApplication; targets API 23+, EmbedAssembliesIntoApk=true so the apk is self-contained for sideloading All event handlers and TopLevel-dependent calls (file picker, clipboard, folder picker) moved from MainWindow.axaml.cs into the new shared MainView.axaml.cs (UserControl), using TopLevel.GetTopLevel(this) so they work on both platforms. Esc/Back key handling is also in MainView. MainWindow becomes a thin shell that hosts MainView. Framework bump: all projects move to net10.0; Cli and Tests follow. --- PalladiumWallet.sln | 14 + src/App.Android/MainActivity.cs | 16 + src/App.Android/MainApplication.cs | 32 + .../PalladiumWallet.App.Android.csproj | 31 + .../Properties/AndroidManifest.xml | 8 + src/App.Android/Resources/values/styles.xml | 7 + .../PalladiumWallet.App.Desktop.csproj | 25 + src/{App => App.Desktop}/Program.cs | 0 src/{App => App.Desktop}/app.manifest | 0 src/App/App.axaml.cs | 65 +- src/App/PalladiumWallet.App.csproj | 65 +- src/App/ViewModels/MainWindowViewModel.cs | 5 + src/App/Views/MainView.axaml | 746 ++++++++++++++++++ src/App/Views/MainView.axaml.cs | 156 ++++ src/App/Views/MainWindow.axaml | 733 +---------------- src/App/Views/MainWindow.axaml.cs | 140 +--- src/Cli/PalladiumWallet.Cli.csproj | 2 +- src/Core/PalladiumWallet.Core.csproj | 2 +- .../PalladiumWallet.Tests.csproj | 2 +- 19 files changed, 1110 insertions(+), 939 deletions(-) create mode 100644 src/App.Android/MainActivity.cs create mode 100644 src/App.Android/MainApplication.cs create mode 100644 src/App.Android/PalladiumWallet.App.Android.csproj create mode 100644 src/App.Android/Properties/AndroidManifest.xml create mode 100644 src/App.Android/Resources/values/styles.xml create mode 100644 src/App.Desktop/PalladiumWallet.App.Desktop.csproj rename src/{App => App.Desktop}/Program.cs (100%) rename src/{App => App.Desktop}/app.manifest (100%) create mode 100644 src/App/Views/MainView.axaml create mode 100644 src/App/Views/MainView.axaml.cs diff --git a/PalladiumWallet.sln b/PalladiumWallet.sln index cce949c..700f567 100644 --- a/PalladiumWallet.sln +++ b/PalladiumWallet.sln @@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FDF1822C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PalladiumWallet.Tests", "tests\PalladiumWallet.Tests\PalladiumWallet.Tests.csproj", "{C7E79E8E-B1DE-4053-9FB4-853814766CE0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PalladiumWallet.App.Desktop", "src\App.Desktop\PalladiumWallet.App.Desktop.csproj", "{A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PalladiumWallet.App.Android", "src\App.Android\PalladiumWallet.App.Android.csproj", "{BCC5BE4A-B909-4043-B0FB-B5A839349578}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,11 +44,21 @@ Global {C7E79E8E-B1DE-4053-9FB4-853814766CE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7E79E8E-B1DE-4053-9FB4-853814766CE0}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7E79E8E-B1DE-4053-9FB4-853814766CE0}.Release|Any CPU.Build.0 = Release|Any CPU + {A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7}.Release|Any CPU.Build.0 = Release|Any CPU + {BCC5BE4A-B909-4043-B0FB-B5A839349578}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BCC5BE4A-B909-4043-B0FB-B5A839349578}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BCC5BE4A-B909-4043-B0FB-B5A839349578}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BCC5BE4A-B909-4043-B0FB-B5A839349578}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {A7D0EF95-B206-4646-99DD-1D2BBB7AF978} = {84E60614-5042-48EC-B349-290FB0CA7BA8} {13EE9780-5810-4229-BFCF-6003172534DD} = {84E60614-5042-48EC-B349-290FB0CA7BA8} {D1AE035A-6DAC-46F4-90FB-F1AE2A79D416} = {84E60614-5042-48EC-B349-290FB0CA7BA8} {C7E79E8E-B1DE-4053-9FB4-853814766CE0} = {FDF1822C-58D6-4B35-93EA-6A85E1292933} + {A5D1DD48-7485-43F0-BFE3-2F645EC4D1E7} = {84E60614-5042-48EC-B349-290FB0CA7BA8} + {BCC5BE4A-B909-4043-B0FB-B5A839349578} = {84E60614-5042-48EC-B349-290FB0CA7BA8} EndGlobalSection EndGlobal diff --git a/src/App.Android/MainActivity.cs b/src/App.Android/MainActivity.cs new file mode 100644 index 0000000..f913dae --- /dev/null +++ b/src/App.Android/MainActivity.cs @@ -0,0 +1,16 @@ +using Android.App; +using Android.Content.PM; +using Avalonia.Android; + +namespace PalladiumWallet.Mobile; + +// Activity di avvio. La configurazione dell'app (tipo App, font) è nella +// MainApplication (AvaloniaAndroidApplication). Qui basta il launcher. +[Activity( + Label = "Palladium Wallet", + Theme = "@style/MyTheme.NoActionBar", + MainLauncher = true, + ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] +public class MainActivity : AvaloniaMainActivity +{ +} diff --git a/src/App.Android/MainApplication.cs b/src/App.Android/MainApplication.cs new file mode 100644 index 0000000..b590c33 --- /dev/null +++ b/src/App.Android/MainApplication.cs @@ -0,0 +1,32 @@ +using System; +using Android.App; +using Android.Runtime; +using Avalonia; +using Avalonia.Android; +using PalladiumWallet.Core.Storage; + +namespace PalladiumWallet.Mobile; + +// In Avalonia 12 l'AppBuilder Android si configura nella sottoclasse Application +// (AvaloniaAndroidApplication), non più nell'Activity. allowBackup=false: +// il file wallet cifrato/seed non deve finire nei backup cloud automatici. +[Application(Label = "Palladium Wallet", AllowBackup = false)] +public class MainApplication : AvaloniaAndroidApplication +{ + public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + } + + public override void OnCreate() + { + // Storage sandbox dell'app: wallet, configurazione e certificati vivono + // qui. Impostato prima dell'init Avalonia (che crea il ViewModel e decide + // se mostrare lo step "scegli cartella dati" del wizard). + AppPaths.OverrideDataRoot = FilesDir?.AbsolutePath; + base.OnCreate(); + } + + protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) => + base.CustomizeAppBuilder(builder).WithInterFont(); +} diff --git a/src/App.Android/PalladiumWallet.App.Android.csproj b/src/App.Android/PalladiumWallet.App.Android.csproj new file mode 100644 index 0000000..6e4bf31 --- /dev/null +++ b/src/App.Android/PalladiumWallet.App.Android.csproj @@ -0,0 +1,31 @@ + + + + Exe + net10.0-android + 23 + enable + io.github.davide3011.palladiumwallet + + 1 + 0.9.0 + apk + + true + + android-arm64 + + + + + + + + + + diff --git a/src/App.Android/Properties/AndroidManifest.xml b/src/App.Android/Properties/AndroidManifest.xml new file mode 100644 index 0000000..1c6a4c2 --- /dev/null +++ b/src/App.Android/Properties/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/App.Android/Resources/values/styles.xml b/src/App.Android/Resources/values/styles.xml new file mode 100644 index 0000000..1b66585 --- /dev/null +++ b/src/App.Android/Resources/values/styles.xml @@ -0,0 +1,7 @@ + + + + + + + + + + + + + + + + + + +