detached 10db773

feat(config): add notify_on_new_settings option to control migration toast

commit
10db773cb4d22bcccda6c3592adbaa68620c85a5
author
bnema · · 2025-12-27 19:05 UTC
parent
3fc796d
signature
GPG Unverified2B82207D370127A0 The key is unknown
7 files · +51 -8
M CHANGELOG.md +4 -0
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55 ## [Unreleased]
66
77 ### Added
8+- **Config migration system**: Detects missing config keys when new settings are added in updates and provides tools to add them.
9+ - `dumber config status`: Shows config file path and number of new settings available.
10+ - `dumber config migrate`: Lists missing keys with types/defaults and adds them to config file.
11+ - GUI toast notification on startup when new settings are available (configurable via `update.notify_on_new_settings`).
812 - **CLI self-update command**: New `dumber update` command to check for and install updates from the command line.
913 - Interactive spinner animation during check and download phases.
1014 - `--force` / `-f` flag to skip version check and reinstall the current version.
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
5 ## [Unreleased]5 ## [Unreleased]
6 6
7 ### Added7 ### Added
8+- **Config migration system**: Detects missing config keys when new settings are added in updates and provides tools to add them.
9+ - `dumber config status`: Shows config file path and number of new settings available.
10+ - `dumber config migrate`: Lists missing keys with types/defaults and adds them to config file.
11+ - GUI toast notification on startup when new settings are available (configurable via `update.notify_on_new_settings`).
8 - **CLI self-update command**: New `dumber update` command to check for and install updates from the command line.12 - **CLI self-update command**: New `dumber update` command to check for and install updates from the command line.
9 - Interactive spinner animation during check and download phases.13 - Interactive spinner animation during check and download phases.
10 - `--force` / `-f` flag to skip version check and reinstall the current version.14 - `--force` / `-f` flag to skip version check and reinstall the current version.
M README.md +4 -0
@@ -261,6 +261,10 @@ sudo apt install va-driver-all
261261 - Clean up data:
262262 - `dumber purge` # interactive selection (TUI)
263263 - `dumber purge --force` # remove everything (no prompts)
264+- Manage configuration:
265+ - `dumber config status` # show config path and migration availability
266+ - `dumber config migrate` # add missing default settings to config
267+ - `dumber config migrate --yes` # skip confirmation prompt
264268 - Manage sessions:
265269 - `dumber sessions` # interactive session browser (TUI)
266270 - `dumber sessions list` # list saved sessions
@@ -261,6 +261,10 @@ sudo apt install va-driver-all
261 - Clean up data:261 - Clean up data:
262 - `dumber purge` # interactive selection (TUI)262 - `dumber purge` # interactive selection (TUI)
263 - `dumber purge --force` # remove everything (no prompts)263 - `dumber purge --force` # remove everything (no prompts)
264+- Manage configuration:
265+ - `dumber config status` # show config path and migration availability
266+ - `dumber config migrate` # add missing default settings to config
267+ - `dumber config migrate --yes` # skip confirmation prompt
264 - Manage sessions:268 - Manage sessions:
265 - `dumber sessions` # interactive session browser (TUI)269 - `dumber sessions` # interactive session browser (TUI)
266 - `dumber sessions list` # list saved sessions270 - `dumber sessions list` # list saved sessions
M docs/CONFIG.md +28 -0
@@ -451,6 +451,34 @@ Notes:
451451 - Filter data is downloaded from `bnema/ublock-webkit-filters` GitHub releases.
452452 - Domain whitelist is managed via the database (`content_whitelist` table), not the config file.
453453
454+## Update
455+
456+| Key | Type | Default | Description |
457+|-----|------|---------|-------------|
458+| `update.enable_on_startup` | bool | `true` | Check for updates when browser starts |
459+| `update.auto_download` | bool | `false` | Automatically download updates in background |
460+| `update.notify_on_new_settings` | bool | `true` | Show toast notification when new config settings are available |
461+
462+**Example:**
463+```toml
464+[update]
465+enable_on_startup = true # Check for updates on startup
466+auto_download = false # Don't auto-download (prompt instead)
467+notify_on_new_settings = true # Show toast when config migration available
468+```
469+
470+**CLI Commands:**
471+```bash
472+# Check config status and available migrations
473+dumber config status
474+
475+# Add missing settings with default values
476+dumber config migrate
477+
478+# Skip confirmation prompt
479+dumber config migrate --yes
480+```
481+
454482 ## Environment Variables
455483
456484 All config values can be overridden via environment variables with the prefix `DUMBER_`:
@@ -451,6 +451,34 @@ Notes:
451 - Filter data is downloaded from `bnema/ublock-webkit-filters` GitHub releases.451 - Filter data is downloaded from `bnema/ublock-webkit-filters` GitHub releases.
452 - Domain whitelist is managed via the database (`content_whitelist` table), not the config file.452 - Domain whitelist is managed via the database (`content_whitelist` table), not the config file.
453 453
454+## Update
455+
456+| Key | Type | Default | Description |
457+|-----|------|---------|-------------|
458+| `update.enable_on_startup` | bool | `true` | Check for updates when browser starts |
459+| `update.auto_download` | bool | `false` | Automatically download updates in background |
460+| `update.notify_on_new_settings` | bool | `true` | Show toast notification when new config settings are available |
461+
462+**Example:**
463+```toml
464+[update]
465+enable_on_startup = true # Check for updates on startup
466+auto_download = false # Don't auto-download (prompt instead)
467+notify_on_new_settings = true # Show toast when config migration available
468+```
469+
470+**CLI Commands:**
471+```bash
472+# Check config status and available migrations
473+dumber config status
474+
475+# Add missing settings with default values
476+dumber config migrate
477+
478+# Skip confirmation prompt
479+dumber config migrate --yes
480+```
481+
454 ## Environment Variables482 ## Environment Variables
455 483
456 All config values can be overridden via environment variables with the prefix `DUMBER_`:484 All config values can be overridden via environment variables with the prefix `DUMBER_`:
M internal/infrastructure/config/defaults.go +3 -2
@@ -292,8 +292,9 @@ func DefaultConfig() *Config {
292292 WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,
293293 },
294294 Update: UpdateConfig{
295- EnableOnStartup: true, // Check for updates on startup by default
296- AutoDownload: false, // Conservative: don't auto-download by default
295+ EnableOnStartup: true, // Check for updates on startup by default
296+ AutoDownload: false, // Conservative: don't auto-download by default
297+ NotifyOnNewSettings: true, // Show toast when new config settings available
297298 },
298299 }
299300 }
@@ -292,8 +292,9 @@ func DefaultConfig() *Config {
292 WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,292 WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,
293 },293 },
294 Update: UpdateConfig{294 Update: UpdateConfig{
295- EnableOnStartup: true, // Check for updates on startup by default295+ EnableOnStartup: true, // Check for updates on startup by default
296- AutoDownload: false, // Conservative: don't auto-download by default296+ AutoDownload: false, // Conservative: don't auto-download by default
297+ NotifyOnNewSettings: true, // Show toast when new config settings available
297 },298 },
298 }299 }
299 }300 }
M internal/infrastructure/config/loader.go +1 -0
@@ -460,6 +460,7 @@ func (m *Manager) setSessionDefaults(defaults *Config) {
460460 func (m *Manager) setUpdateDefaults(defaults *Config) {
461461 m.viper.SetDefault("update.enable_on_startup", defaults.Update.EnableOnStartup)
462462 m.viper.SetDefault("update.auto_download", defaults.Update.AutoDownload)
463+ m.viper.SetDefault("update.notify_on_new_settings", defaults.Update.NotifyOnNewSettings)
463464 }
464465
465466 // New returns a new default configuration instance.
@@ -460,6 +460,7 @@ func (m *Manager) setSessionDefaults(defaults *Config) {
460 func (m *Manager) setUpdateDefaults(defaults *Config) {460 func (m *Manager) setUpdateDefaults(defaults *Config) {
461 m.viper.SetDefault("update.enable_on_startup", defaults.Update.EnableOnStartup)461 m.viper.SetDefault("update.enable_on_startup", defaults.Update.EnableOnStartup)
462 m.viper.SetDefault("update.auto_download", defaults.Update.AutoDownload)462 m.viper.SetDefault("update.auto_download", defaults.Update.AutoDownload)
463+ m.viper.SetDefault("update.notify_on_new_settings", defaults.Update.NotifyOnNewSettings)
463 }464 }
464 465
465 // New returns a new default configuration instance.466 // New returns a new default configuration instance.
M internal/infrastructure/config/schema.go +3 -0
@@ -294,6 +294,9 @@ type UpdateConfig struct {
294294 // When enabled, updates are applied on browser exit.
295295 // Default: false
296296 AutoDownload bool `mapstructure:"auto_download" yaml:"auto_download" toml:"auto_download"`
297+ // NotifyOnNewSettings shows a toast notification on startup when new config settings are available.
298+ // Default: true
299+ NotifyOnNewSettings bool `mapstructure:"notify_on_new_settings" yaml:"notify_on_new_settings" toml:"notify_on_new_settings"`
297300 }
298301
299302 // WorkspaceConfig captures layout, pane, and tab behavior preferences.
@@ -294,6 +294,9 @@ type UpdateConfig struct {
294 // When enabled, updates are applied on browser exit.294 // When enabled, updates are applied on browser exit.
295 // Default: false295 // Default: false
296 AutoDownload bool `mapstructure:"auto_download" yaml:"auto_download" toml:"auto_download"`296 AutoDownload bool `mapstructure:"auto_download" yaml:"auto_download" toml:"auto_download"`
297+ // NotifyOnNewSettings shows a toast notification on startup when new config settings are available.
298+ // Default: true
299+ NotifyOnNewSettings bool `mapstructure:"notify_on_new_settings" yaml:"notify_on_new_settings" toml:"notify_on_new_settings"`
297 }300 }
298 301
299 // WorkspaceConfig captures layout, pane, and tab behavior preferences.302 // WorkspaceConfig captures layout, pane, and tab behavior preferences.
M internal/ui/config_migration.go +8 -6
@@ -12,6 +12,7 @@ import (
1212 // checkConfigMigration checks if user config needs migration and shows a toast.
1313 func (a *App) checkConfigMigration(ctx context.Context) {
1414 log := logging.FromContext(ctx)
15+ cfg := config.Get()
1516
1617 migrator := config.NewMigrator()
1718 result, err := migrator.CheckMigration()
@@ -24,13 +25,14 @@ func (a *App) checkConfigMigration(ctx context.Context) {
2425 return // No migration needed
2526 }
2627
27- // Show toast notification
28- if a.appToaster != nil {
29- msg := fmt.Sprintf("Config has %d new settings. Run 'dumber config migrate'", len(result.MissingKeys))
30- a.appToaster.Show(ctx, msg, component.ToastInfo)
31- }
32-
28+ // Log is always shown for debugging purposes
3329 log.Info().
3430 Int("missing_keys", len(result.MissingKeys)).
3531 Msg("config migration available")
32+
33+ // Show toast notification if enabled
34+ if cfg.Update.NotifyOnNewSettings && a.appToaster != nil {
35+ msg := fmt.Sprintf("Config has %d new settings. Run 'dumber config migrate'", len(result.MissingKeys))
36+ a.appToaster.Show(ctx, msg, component.ToastInfo)
37+ }
3638 }
@@ -12,6 +12,7 @@ import (
12 // checkConfigMigration checks if user config needs migration and shows a toast.12 // checkConfigMigration checks if user config needs migration and shows a toast.
13 func (a *App) checkConfigMigration(ctx context.Context) {13 func (a *App) checkConfigMigration(ctx context.Context) {
14 log := logging.FromContext(ctx)14 log := logging.FromContext(ctx)
15+ cfg := config.Get()
15 16
16 migrator := config.NewMigrator()17 migrator := config.NewMigrator()
17 result, err := migrator.CheckMigration()18 result, err := migrator.CheckMigration()
@@ -24,13 +25,14 @@ func (a *App) checkConfigMigration(ctx context.Context) {
24 return // No migration needed25 return // No migration needed
25 }26 }
26 27
27- // Show toast notification28+ // Log is always shown for debugging purposes
28- if a.appToaster != nil {
29- msg := fmt.Sprintf("Config has %d new settings. Run 'dumber config migrate'", len(result.MissingKeys))
30- a.appToaster.Show(ctx, msg, component.ToastInfo)
31- }
32-
33 log.Info().29 log.Info().
34 Int("missing_keys", len(result.MissingKeys)).30 Int("missing_keys", len(result.MissingKeys)).
35 Msg("config migration available")31 Msg("config migration available")
32+
33+ // Show toast notification if enabled
34+ if cfg.Update.NotifyOnNewSettings && a.appToaster != nil {
35+ msg := fmt.Sprintf("Config has %d new settings. Run 'dumber config migrate'", len(result.MissingKeys))
36+ a.appToaster.Show(ctx, msg, component.ToastInfo)
37+ }
36 }38 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close