feat(usage): PowerUse-Zeitfenster + Handoff-Schwellwert als Settings
Drei neue app_settings-Spalten (Migration AddPowerUseWindow): power_use_window_start/end (HH:mm, lokal, nullable) und power_use_handoff_pct (NOT NULL DEFAULT 95, geclampt 50-99). Die Fensterlogik liegt als reine Funktion in PowerUseWindow (Contains/Normalize/IsOpen): beide Grenzen leer oder nur eine gesetzt = rund um die Uhr, Ende vor Start wrappt ueber Mitternacht, Grenzen halboffen. Geprueft wird in ComposeHandlerPromptAsync, also pro Phase zum Zeitpunkt des Prompt-Baus - die Uhr ist per Func<DateTime> injizierbar. Bedienung im Usage-Monitor neben dem PowerUse-Toggle (Commit auf Blur/Enter, ein Write fuer alle vier Felder); in Settings->General unsichtbar, aber load->save durchgereicht. Nebenbefund, gleicher Pfad: AppSettingsRepository.UpdateAsync kopiert Feld fuer Feld und hat ModelPresets, PowerUseEnabled und ListHandlerMaxHandoffs nie geschrieben - jeder Save dieser drei war still wirkungslos. Mit ergaenzt und per Round-trip-Test gepinnt.
This commit is contained in:
@@ -144,6 +144,29 @@
|
||||
Content="{loc:Tr modals.usageMonitor.powerUse}"/>
|
||||
<TextBlock Classes="meta" TextWrapping="Wrap"
|
||||
Text="{loc:Tr modals.usageMonitor.powerUseHint}"/>
|
||||
<!-- Window + handoff threshold. Same commit-on-blur/Enter discipline as the gauge
|
||||
legend boxes: a hub write per keystroke would be one save per typed digit. -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,6,0,0">
|
||||
<TextBlock Classes="meta" VerticalAlignment="Center"
|
||||
Text="{loc:Tr modals.usageMonitor.powerUseWindow}"/>
|
||||
<TextBox Width="70" FontSize="12" Padding="6,2"
|
||||
Watermark="{loc:Tr modals.usageMonitor.powerUseWindowPlaceholder}"
|
||||
Text="{Binding PowerUseWindowStart, Mode=TwoWay}"
|
||||
LostFocus="OnPowerUseBoxCommit" KeyDown="OnPowerUseBoxKeyDown"/>
|
||||
<TextBlock Classes="meta" VerticalAlignment="Center" Text="–"/>
|
||||
<TextBox Width="70" FontSize="12" Padding="6,2"
|
||||
Watermark="{loc:Tr modals.usageMonitor.powerUseWindowPlaceholder}"
|
||||
Text="{Binding PowerUseWindowEnd, Mode=TwoWay}"
|
||||
LostFocus="OnPowerUseBoxCommit" KeyDown="OnPowerUseBoxKeyDown"/>
|
||||
<TextBlock Classes="meta" VerticalAlignment="Center" Margin="12,0,0,0"
|
||||
Text="{loc:Tr modals.usageMonitor.powerUseHandoffPct}"/>
|
||||
<NumericUpDown Width="80" FontSize="12" Padding="6,2" ShowButtonSpinner="False"
|
||||
Minimum="50" Maximum="99" Increment="1" FormatString="0"
|
||||
Value="{Binding PowerUseHandoffPct, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
||||
LostFocus="OnPowerUseBoxCommit" KeyDown="OnPowerUseBoxKeyDown"/>
|
||||
</StackPanel>
|
||||
<TextBlock Classes="meta" TextWrapping="Wrap" Opacity="0.75"
|
||||
Text="{loc:Tr modals.usageMonitor.powerUseWindowHint}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -33,4 +33,19 @@ public partial class UsageMonitorModalView : Window
|
||||
OnStageBoxCommit(sender, e);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>Persists the PowerUse window / handoff threshold on blur — a save per keystroke
|
||||
/// would be one hub round-trip per typed digit.</summary>
|
||||
private void OnPowerUseBoxCommit(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not UsageMonitorModalViewModel vm) return;
|
||||
if (vm.SavePowerUseCommand.CanExecute(null)) vm.SavePowerUseCommand.Execute(null);
|
||||
}
|
||||
|
||||
private void OnPowerUseBoxKeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key != Key.Enter) return;
|
||||
OnPowerUseBoxCommit(sender, e);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user