diff --git a/daemonclient/service.go b/daemonclient/service.go index bcee087..7062b06 100644 --- a/daemonclient/service.go +++ b/daemonclient/service.go @@ -25,6 +25,7 @@ type Service interface { RefreshFolder(accountID, folder string) error Subscribe(accountID, folder string) error Unsubscribe(accountID, folder string) error + ReloadConfig() error Events() <-chan *daemonrpc.Event IsDaemon() bool Close() error @@ -187,6 +188,10 @@ func (s *daemonService) Unsubscribe(accountID, folder string) error { }, nil) } +func (s *daemonService) ReloadConfig() error { + return s.client.Call(daemonrpc.MethodReloadConfig, nil, nil) +} + func (s *daemonService) Events() <-chan *daemonrpc.Event { return s.client.Events() } @@ -313,6 +318,16 @@ func (s *directService) Unsubscribe(_, _ string) error { return nil } +func (s *directService) ReloadConfig() error { + cfg, err := config.LoadConfig() + if err != nil { + return err + } + s.cfg = cfg + s.initProviders() + return nil +} + func (s *directService) Events() <-chan *daemonrpc.Event { return s.events } diff --git a/main.go b/main.go index ad0d853..5a3b8ec 100644 --- a/main.go +++ b/main.go @@ -982,6 +982,14 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.current, _ = m.current.Update(tea.WindowSizeMsg{Width: m.width, Height: m.height}) return m, m.current.Init() + case tui.ConfigSavedMsg: + if m.service != nil { + if err := m.service.ReloadConfig(); err != nil { + log.Printf("config reload: %v", err) + } + } + return m, nil + case tui.LanguageChangedMsg: // Rebuild all models with new translations // Keep current view type but recreate with fresh i18n diff --git a/tui/messages.go b/tui/messages.go index 1766e2b..227189f 100644 --- a/tui/messages.go +++ b/tui/messages.go @@ -543,6 +543,10 @@ type SendRSVPMsg struct { // RSVPResultMsg signals that RSVP was sent (or failed) type LanguageChangedMsg struct{} +// ConfigSavedMsg signals the config was written to disk and downstream +// consumers (notably the daemon) should reload it. +type ConfigSavedMsg struct{} + type RSVPResultMsg struct { Err error Response string // "ACCEPTED", "DECLINED", "TENTATIVE" diff --git a/tui/settings_general.go b/tui/settings_general.go index 68e29bb..9a06651 100644 --- a/tui/settings_general.go +++ b/tui/settings_general.go @@ -68,19 +68,24 @@ func (m *Settings) updateGeneral(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { return m, nil } + saved := false switch m.generalCursor { case 0: // Image Display m.cfg.DisableImages = !m.cfg.DisableImages _ = config.SaveConfig(m.cfg) + saved = true case 1: // Contextual Tips m.cfg.HideTips = !m.cfg.HideTips _ = config.SaveConfig(m.cfg) + saved = true case 2: // Desktop Notifications m.cfg.DisableNotifications = !m.cfg.DisableNotifications _ = config.SaveConfig(m.cfg) + saved = true case 3: // Split Pane View m.cfg.EnableSplitPane = !m.cfg.EnableSplitPane _ = config.SaveConfig(m.cfg) + saved = true case 4: // Date Format switch m.cfg.DateFormat { case config.DateFormatEU: @@ -91,6 +96,7 @@ func (m *Settings) updateGeneral(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { m.cfg.DateFormat = config.DateFormatEU } _ = config.SaveConfig(m.cfg) + saved = true case 5: // Language // Cycle through available languages langs := i18n.LanguageCodes() @@ -108,12 +114,18 @@ func (m *Settings) updateGeneral(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { // Apply language change immediately i18n.GetManager().SetLanguage(m.cfg.Language) // Trigger full UI rebuild - return m, func() tea.Msg { return LanguageChangedMsg{} } + return m, tea.Batch( + func() tea.Msg { return ConfigSavedMsg{} }, + func() tea.Msg { return LanguageChangedMsg{} }, + ) case 6: // Edit Signature if msg.String() == "enter" || msg.String() == "right" || msg.String() == "l" { return m, func() tea.Msg { return GoToSignatureEditorMsg{} } } } + if saved { + return m, func() tea.Msg { return ConfigSavedMsg{} } + } } } return m, nil