feat(app): connect to server before wallet open, status in bottom bar
- ConnectAndSync() no longer bails early when no wallet is open: connection is established immediately after the wizard completes (Electrum-style), sync starts only once an account is available - KeepAlive tick no longer requires IsWalletOpen so the connection is maintained and auto-reconnected at all times - WalletSynchronizer is lazily created on first sync (not on connect) to avoid a null-ref guard on _synchronizer - Connection status indicator (dot + text) moved from wallet header to the status bar (always visible); tapping it still opens the server settings overlay - Menu "Rete" removed: Discover and ResetCerts are inside the server settings overlay; redundant top-level menu entry eliminated - "Server" button in settings overlay is no longer gated on IsWalletOpen
This commit is contained in:
@@ -397,7 +397,9 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
|
|
||||||
private async Task KeepAliveTickAsync()
|
private async Task KeepAliveTickAsync()
|
||||||
{
|
{
|
||||||
if (!IsWalletOpen || IsSyncing)
|
// Vale anche senza wallet aperto: se l'utente si è connesso dalle
|
||||||
|
// impostazioni server, la connessione va mantenuta e riconnessa.
|
||||||
|
if (IsSyncing)
|
||||||
return;
|
return;
|
||||||
if (_client is { IsConnected: true })
|
if (_client is { IsConnected: true })
|
||||||
{
|
{
|
||||||
@@ -461,6 +463,9 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
? Loc.Tr("msg.welcome.existing")
|
? Loc.Tr("msg.welcome.existing")
|
||||||
: Loc.Tr("msg.welcome.new");
|
: Loc.Tr("msg.welcome.new");
|
||||||
RefreshServers();
|
RefreshServers();
|
||||||
|
// Come Electrum: ci si connette al server già durante il setup, senza
|
||||||
|
// aspettare l'apertura di un wallet (la sync parte poi all'apertura).
|
||||||
|
_ = ConnectAndSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshServers()
|
private void RefreshServers()
|
||||||
@@ -776,8 +781,6 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task ConnectAndSync()
|
private async Task ConnectAndSync()
|
||||||
{
|
{
|
||||||
if (_account is null || _doc is null)
|
|
||||||
return;
|
|
||||||
if (IsSyncing)
|
if (IsSyncing)
|
||||||
{
|
{
|
||||||
_resyncRequested = true;
|
_resyncRequested = true;
|
||||||
@@ -812,8 +815,18 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
IsConnected = true;
|
IsConnected = true;
|
||||||
_autoReconnect = true;
|
_autoReconnect = true;
|
||||||
ConnectionStatus = $"{Loc.Tr("conn.connectedto")} {host}:{port}{(UseSsl ? " (TLS)" : "")}";
|
ConnectionStatus = $"{Loc.Tr("conn.connectedto")} {host}:{port}{(UseSsl ? " (TLS)" : "")}";
|
||||||
// Synchronizer per connessione: conserva la cache di tx e
|
}
|
||||||
// prove verificate, così le risincronizzazioni sono incrementali.
|
|
||||||
|
// Senza un wallet aperto ci si limita a stabilire/verificare la
|
||||||
|
// connessione: la sincronizzazione richiede un account.
|
||||||
|
if (_account is null || _doc is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Synchronizer legato all'account corrente, creato alla prima sync
|
||||||
|
// dopo la connessione: conserva la cache di tx e prove verificate,
|
||||||
|
// così le risincronizzazioni sono incrementali.
|
||||||
|
if (_synchronizer is null)
|
||||||
|
{
|
||||||
_synchronizer = new WalletSynchronizer(_account, _client, _doc.GapLimit);
|
_synchronizer = new WalletSynchronizer(_account, _client, _doc.GapLimit);
|
||||||
_synchronizer.Progress += msg => Dispatcher.UIThread.Post(() => StatusMessage = msg);
|
_synchronizer.Progress += msg => Dispatcher.UIThread.Post(() => StatusMessage = msg);
|
||||||
}
|
}
|
||||||
@@ -823,7 +836,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
_resyncRequested = false;
|
_resyncRequested = false;
|
||||||
var result = await _synchronizer!.SyncOnceAsync();
|
var result = await _synchronizer.SyncOnceAsync();
|
||||||
_lastTransactions = result.Transactions;
|
_lastTransactions = result.Transactions;
|
||||||
|
|
||||||
_doc.Cache = new SyncCache
|
_doc.Cache = new SyncCache
|
||||||
|
|||||||
@@ -26,10 +26,6 @@
|
|||||||
<MenuItem Header="{Binding Loc[menu.file.close]}" Command="{Binding CloseWalletCommand}"
|
<MenuItem Header="{Binding Loc[menu.file.close]}" Command="{Binding CloseWalletCommand}"
|
||||||
IsEnabled="{Binding IsWalletOpen}"/>
|
IsEnabled="{Binding IsWalletOpen}"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{Binding Loc[menu.net]}">
|
|
||||||
<MenuItem Header="{Binding Loc[menu.net.discover]}" Command="{Binding DiscoverServersCommand}"/>
|
|
||||||
<MenuItem Header="{Binding Loc[menu.net.resetcerts]}" Command="{Binding ResetCertificatesCommand}"/>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{Binding Loc[menu.settings]}"
|
<MenuItem Header="{Binding Loc[menu.settings]}"
|
||||||
Command="{Binding OpenSettingsCommand}"/>
|
Command="{Binding OpenSettingsCommand}"/>
|
||||||
</Menu>
|
</Menu>
|
||||||
@@ -159,29 +155,13 @@
|
|||||||
<!-- ============ PANNELLO WALLET ============ -->
|
<!-- ============ PANNELLO WALLET ============ -->
|
||||||
<Grid Grid.Row="1" RowDefinitions="Auto,*" IsVisible="{Binding IsWalletOpen}" Margin="16">
|
<Grid Grid.Row="1" RowDefinitions="Auto,*" IsVisible="{Binding IsWalletOpen}" Margin="16">
|
||||||
|
|
||||||
<!-- Testata: saldo + rete · stato connessione.
|
<!-- Testata: saldo + rete. Connetti/sincronizza è automatico; chiudi
|
||||||
Connetti/sincronizza è automatico; chiudi wallet è in File.
|
wallet è in File. Lo stato connessione è nella barra in basso. -->
|
||||||
Le impostazioni del server sono in Impostazioni → Server. -->
|
<StackPanel Grid.Row="0" Spacing="2" Margin="0,0,0,12">
|
||||||
<Grid Grid.Row="0" ColumnDefinitions="*,Auto" Margin="0,0,0,12">
|
|
||||||
<StackPanel Grid.Column="0" Spacing="2">
|
|
||||||
<TextBlock Text="{Binding BalanceText}" FontSize="30" FontWeight="Bold"/>
|
<TextBlock Text="{Binding BalanceText}" FontSize="30" FontWeight="Bold"/>
|
||||||
<TextBlock Text="{Binding UnconfirmedText}" Foreground="Orange"/>
|
<TextBlock Text="{Binding UnconfirmedText}" Foreground="Orange"/>
|
||||||
<TextBlock Text="{Binding NetworkInfo}" FontSize="12" Foreground="Gray"/>
|
<TextBlock Text="{Binding NetworkInfo}" FontSize="12" Foreground="Gray"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<!-- Cliccabile: apre le impostazioni del server -->
|
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="6"
|
|
||||||
VerticalAlignment="Top" Cursor="Hand" Background="Transparent"
|
|
||||||
ToolTip.Tip="{Binding Loc[server.title]}"
|
|
||||||
Tapped="OnConnectionStatusTapped">
|
|
||||||
<Ellipse Width="10" Height="10" Fill="LimeGreen" VerticalAlignment="Center"
|
|
||||||
IsVisible="{Binding IsConnected}"/>
|
|
||||||
<Ellipse Width="10" Height="10" Fill="IndianRed" VerticalAlignment="Center"
|
|
||||||
IsVisible="{Binding !IsConnected}"/>
|
|
||||||
<TextBlock Text="{Binding ConnectionStatus}"
|
|
||||||
Foreground="{DynamicResource SystemAccentColor}"
|
|
||||||
VerticalAlignment="Center"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Tab: Storico / Invia / Ricevi / Indirizzi / Contatti -->
|
<!-- Tab: Storico / Invia / Ricevi / Indirizzi / Contatti -->
|
||||||
<TabControl Grid.Row="1">
|
<TabControl Grid.Row="1">
|
||||||
@@ -331,10 +311,27 @@
|
|||||||
</TabControl>
|
</TabControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Barra di stato -->
|
<!-- Barra di stato: messaggio a sinistra, stato connessione a destra.
|
||||||
|
Lo stato connessione è cliccabile e apre le impostazioni del server. -->
|
||||||
<Border Grid.Row="2" Background="{DynamicResource SystemControlBackgroundChromeMediumBrush}"
|
<Border Grid.Row="2" Background="{DynamicResource SystemControlBackgroundChromeMediumBrush}"
|
||||||
Padding="10,6">
|
Padding="10,6">
|
||||||
<TextBlock Text="{Binding StatusMessage}" FontSize="12" TextWrapping="Wrap"/>
|
<Grid ColumnDefinitions="*,Auto">
|
||||||
|
<TextBlock Grid.Column="0" Text="{Binding StatusMessage}" FontSize="12"
|
||||||
|
TextWrapping="Wrap" VerticalAlignment="Center"/>
|
||||||
|
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="6"
|
||||||
|
Margin="12,0,0,0" VerticalAlignment="Center"
|
||||||
|
Cursor="Hand" Background="Transparent"
|
||||||
|
ToolTip.Tip="{Binding Loc[server.title]}"
|
||||||
|
Tapped="OnConnectionStatusTapped">
|
||||||
|
<Ellipse Width="10" Height="10" Fill="LimeGreen" VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding IsConnected}"/>
|
||||||
|
<Ellipse Width="10" Height="10" Fill="IndianRed" VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding !IsConnected}"/>
|
||||||
|
<TextBlock Text="{Binding ConnectionStatus}" FontSize="12"
|
||||||
|
Foreground="{DynamicResource SystemAccentColor}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- ============ OVERLAY DETTAGLIO INDIRIZZO ============ -->
|
<!-- ============ OVERLAY DETTAGLIO INDIRIZZO ============ -->
|
||||||
@@ -540,11 +537,10 @@
|
|||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Server di indicizzazione -->
|
<!-- Server di indicizzazione (configurabile anche prima di aprire un wallet) -->
|
||||||
<Button Content="{Binding Loc[settings.server]}"
|
<Button Content="{Binding Loc[settings.server]}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Command="{Binding OpenServerSettingsCommand}"
|
Command="{Binding OpenServerSettingsCommand}"/>
|
||||||
IsEnabled="{Binding IsWalletOpen}"/>
|
|
||||||
|
|
||||||
<Button Content="{Binding Loc[addr.close]}"
|
<Button Content="{Binding Loc[addr.close]}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
|||||||
Reference in New Issue
Block a user