feat(app): QR code for receive address
Adds QRCoder 1.8.0 and generates a PNG QR code in-memory each time the receive address changes (OnReceiveAddressChanged). The bitmap is displayed in the Receive tab inside a white-background border with pixel-perfect scaling (BitmapInterpolationMode=None). Previous bitmap is disposed to avoid memory leaks.
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
|
||||||
|
<PackageReference Include="QRCoder" Version="1.8.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
@@ -15,6 +16,7 @@ using PalladiumWallet.Core.Net;
|
|||||||
using PalladiumWallet.Core.Spv;
|
using PalladiumWallet.Core.Spv;
|
||||||
using PalladiumWallet.Core.Storage;
|
using PalladiumWallet.Core.Storage;
|
||||||
using PalladiumWallet.Core.Wallet;
|
using PalladiumWallet.Core.Wallet;
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
namespace PalladiumWallet.App.ViewModels;
|
namespace PalladiumWallet.App.ViewModels;
|
||||||
|
|
||||||
@@ -240,6 +242,33 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string receiveAddress = "";
|
private string receiveAddress = "";
|
||||||
|
|
||||||
|
/// <summary>QR code dell'indirizzo di ricezione corrente (PNG in-memory).</summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private Bitmap? receiveQr;
|
||||||
|
|
||||||
|
// Rigenera il QR ogni volta che l'indirizzo di ricezione cambia.
|
||||||
|
partial void OnReceiveAddressChanged(string value)
|
||||||
|
{
|
||||||
|
var previous = ReceiveQr;
|
||||||
|
ReceiveQr = string.IsNullOrEmpty(value) ? null : GenerateQr(value);
|
||||||
|
previous?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Bitmap? GenerateQr(string text)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var generator = new QRCodeGenerator();
|
||||||
|
using var data = generator.CreateQrCode(text, QRCodeGenerator.ECCLevel.M);
|
||||||
|
var png = new PngByteQRCode(data).GetGraphic(8);
|
||||||
|
return new Bitmap(new MemoryStream(png));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string serverHost = "";
|
private string serverHost = "";
|
||||||
|
|
||||||
|
|||||||
@@ -255,6 +255,12 @@
|
|||||||
<TextBlock Text="{Binding Loc[receive.next]}"/>
|
<TextBlock Text="{Binding Loc[receive.next]}"/>
|
||||||
<SelectableTextBlock Text="{Binding ReceiveAddress}"
|
<SelectableTextBlock Text="{Binding ReceiveAddress}"
|
||||||
FontFamily="monospace" FontSize="16"/>
|
FontFamily="monospace" FontSize="16"/>
|
||||||
|
<Border Background="White" Padding="12" CornerRadius="6"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
IsVisible="{Binding ReceiveQr, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||||
|
<Image Source="{Binding ReceiveQr}" Width="220" Height="220"
|
||||||
|
RenderOptions.BitmapInterpolationMode="None"/>
|
||||||
|
</Border>
|
||||||
<TextBlock Text="{Binding Loc[receive.hint]}"
|
<TextBlock Text="{Binding Loc[receive.hint]}"
|
||||||
Foreground="Gray" FontSize="12" TextWrapping="Wrap"/>
|
Foreground="Gray" FontSize="12" TextWrapping="Wrap"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
Reference in New Issue
Block a user