okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
1package tui 2 3import ( 4"strings" 5 6"albedo/cli/internal/daemon" 7 8"charm.land/bubbles/v2/textinput" 9 tea"charm.land/bubbletea/v2" 10) 11 12// SessionRenameMsg asks the app to save a session's name. A blank name hands 13// the title back to the daemon, which takes it from the latest message. 14type SessionRenameMsg struct {ID ,Name ,ETag string } 15 16// sessionRenamedMsg is the daemon's answer to a SessionRenameMsg: the 17// session as it is now listed. 18type sessionRenamedMsg struct { 19Err error 20Session daemon.Session 21SessionRenameMsg 22} 23 24// renameField edits one session's name in place. While it is open its owner 25// hands it every key, so typing never reaches search or navigation. 26type renameField struct { 27id ,was ,etag string 28input textinput.Model 29// selected holds until the first key: typing replaces the opening 30// draft, which a message title can fill to the limit; other keys edit it. 31selected bool 32} 33 34// renameLimit matches the daemon, which keeps 80 characters of a name. 35const renameLimit = 80 36 37// open starts a draft of current, prompting with placeholder once emptied. 38func (f * renameField )open (id ,current ,placeholder string ) { 39in := newField () 40in .CharLimit = renameLimit 41in .Placeholder = placeholder 42st := in .Styles () 43st .Focused .Text = DefaultStyles .Bold 44st .Focused .Placeholder = DefaultStyles .Faint 45in .SetStyles (st ) 46in .SetValue (current ) 47in .CursorEnd () 48in .Focus () 49f .id ,f .was ,f .input ,f .selected = id ,current ,in ,current != "" 50} 51 52func (f renameField )active ()bool {return f .id != "" } 53 54// key edits the draft. Enter saves a changed name and esc drops it; both 55// close the field. 56func (f * renameField )key (msg tea.KeyPressMsg ) tea.Cmd { 57switch msg .String () { 58case "esc" ,"ctrl+c" : 59f .id = "" 60return nil 61case "enter" : 62id ,name := f .id ,strings .TrimSpace (f .input .Value ()) 63f .id = "" 64if name == strings .TrimSpace (f .was ) { 65return nil 66 } 67return func () tea.Msg {return SessionRenameMsg {ID :id ,Name :name ,ETag :f .etag } } 68 } 69if f .selected && msg .Text != "" { 70f .input .SetValue ("" ) 71 } 72f .selected = false 73var cmd tea.Cmd 74f .input ,cmd = f .input .Update (msg ) 75return cmd 76} 77 78// view is the draft in exactly width cells. 79func (f renameField )view (width int )string { 80f .input .SetWidth (max (1 ,width - 1 )) 81if f .selected { 82st := f .input .Styles () 83st .Focused .Text = DefaultStyles .Cursor 84f .input .SetStyles (st ) 85 } 86return svFit (f .input .View (),width ) 87} 88 89// renameHints stand in for a screen's key hints while a name is being edited. 90func renameHints (blank string )string { 91return keyHints (hint {"enter" ,"save" },hint {"esc" ,"cancel" },hint {"" ,"empty " + blank }) 92}