okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
5e287ce
main
1package tui 2 3import ( 4"albedo/cli/internal/daemon" 5"context" 6"errors" 7"slices" 8 9 tea"charm.land/bubbletea/v2" 10) 11 12func (m * AppModel )handlePreferences (msg tea.Msg ) (tea.Cmd ,bool ) { 13switch msg := msg .(type ) { 14case settingsLoadedMsg : 15if msg .Gen != m .SettingsGen { 16return nil ,true 17 } 18if msg .Err != nil { 19m .Chat .AddError (msg .Err .Error ()) 20m .SessionPicker .notice = msg .Err .Error () 21return nil ,true 22 } 23m .Profiles = msg .Settings .Profiles 24m .SettingsETags = msg .Settings .ETags 25m .ApplyUI (msg .Settings .UI ) 26return nil ,true 27case uiSavedMsg : 28if msg .Open { 29if msg .Err != nil { 30m .Chat .AddError (msg .Err .Error ()) 31if _ ,uncertain := errors.AsType [* daemon.UncertainOutcomeError ](msg .Err );uncertain { 32return nil ,true 33 } 34 } 35if msg .Err == nil { 36m .ApplyUI (msg .Prefs ) 37 } 38return m .refreshSettingsCmd (),true 39 } 40// One save runs at a time, so this answer always ends it. 41m .UISaving ,m .SessionPicker .Saving = false ,false 42if msg .Session == "" && msg .Gen != m .SettingsGen { 43// The settings read an invalidation asked for waited on this save. 44return m .loadSettingsCmd (m .SettingsGen ),true 45 } 46if msg .Err != nil { 47m .Chat .AddError (msg .Err .Error ()) 48m .SessionPicker .notice = msg .Err .Error () 49return nil ,true 50 } 51m .SessionPicker .notice = "" 52m .ApplyUI (msg .Prefs ) 53if msg .Session == "" { 54return nil ,true 55 } 56if ! m .listingSessions { 57return nil ,true 58 } 59// The listing in flight predates the save and would undo it. 60m .SessionGen ++ 61return m .loadSessionsCmd (m .SessionGen ),true 62case SessionPreferenceMsg : 63if m .UISaving { 64m .SessionPicker .Saving = false 65return nil ,true 66 } 67m .UISaving = true 68m .SettingsGen ++ 69m .SessionGen ++ 70patch := daemon.UIPreferencesPatch {ETag :msg .ETag } 71switch msg .Field { 72case "pinned" : 73patch .Pinned = & msg .Value 74case "archived" : 75patch .Archived = & msg .Value 76 } 77return m .patchUICmd (msg .ID ,patch ,m .SettingsGen ),true 78 } 79return nil ,false 80} 81 82// ApplyUI takes acknowledged shared preferences from the daemon. 83func (m * AppModel )ApplyUI (prefs daemon.UIPreferences ) { 84if len (prefs .SessionETags )!= 0 || len (prefs .Opens )!= 0 { 85m .SessionGen ++ // Earlier listings predate these acknowledged session facts. 86 } 87if prefs .ETag != "" { 88m .UI .Thinking ,m .UI .Tools ,m .UI .ETag = prefs .Thinking ,prefs .Tools ,prefs .ETag 89if prefs .DismissedNotices != nil { 90m .UI .DismissedNotices = slices .Clone (prefs .DismissedNotices ) 91 } 92 } 93for i := range m .Sessions { 94m .Sessions [i ]= applySessionPreferences (m .Sessions [i ],prefs ) 95 } 96if m .ActiveSession != nil { 97captured := applySessionPreferences (* m .ActiveSession ,prefs ) 98m .ActiveSession = & captured 99 } 100m .updateSessionPickerItems () 101m .Chat .Flags .Thinking ,m .Chat .Flags .Tools = m .UI .Thinking ,m .UI .Tools 102} 103 104func applySessionPreferences (session daemon.Session ,prefs daemon.UIPreferences ) daemon.Session { 105if etag ,updated := prefs .SessionETags [session .ID ];updated { 106session .ETag = etag 107session .Pinned = slices .Contains (prefs .Pinned ,session .ID ) 108session .Archived = slices .Contains (prefs .Archived ,session .ID ) 109 } 110if opens ,updated := prefs .Opens [session .ID ];updated { 111session .Opens = opens 112 } 113return session 114} 115 116func (m * AppModel )refreshSettingsCmd () tea.Cmd { 117if m .UISaving { 118return nil 119 } 120m .SettingsGen ++ 121return m .loadSettingsCmd (m .SettingsGen ) 122} 123 124func (m * AppModel )loadSettingsCmd (gen int ) tea.Cmd { 125if m .UISaving { 126return nil 127 } 128conn := m .Conn 129return func () tea.Msg { 130settings ,err := daemon .GetSettings (context .Background (),conn ) 131return settingsLoadedMsg {Settings :settings ,Gen :gen ,Err :err } 132 } 133} 134 135func (m * AppModel )patchUICmd (session string ,patch daemon.UIPreferencesPatch ,gen int ) tea.Cmd { 136conn := m .Conn 137if session == "" { 138patch .ETag = m .UI .ETag 139 } 140if patch .Thinking != nil { 141patch .Thinking = new (* patch.Thinking ) 142 } 143if patch .Tools != nil { 144patch .Tools = new (* patch.Tools ) 145 } 146if patch .Pinned != nil { 147patch .Pinned = new (* patch.Pinned ) 148 } 149if patch .Archived != nil { 150patch .Archived = new (* patch.Archived ) 151 } 152return func () tea.Msg { 153var prefs daemon.UIPreferences 154var err error 155if session == "" { 156prefs ,err = daemon .PatchUI (context .Background (),conn ,patch ) 157 }else { 158prefs ,err = daemon .PatchSessionUI (context .Background (),conn ,session ,patch ) 159 } 160return uiSavedMsg {Prefs :prefs ,Gen :gen ,Session :session ,Err :err } 161 } 162} 163 164func (m * AppModel )recordOpenCmd (session string ) tea.Cmd { 165conn := m .Conn 166return func () tea.Msg { 167prefs ,err := daemon .RecordOpen (context .Background (),conn ,session ) 168return uiSavedMsg {Prefs :prefs ,Open :true ,Err :err } 169 } 170}