okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
979f217
main
1package terminal 2 3import ( 4"context" 5"fmt" 6"strings" 7 8"albedo/cli/internal/daemon" 9 tea"charm.land/bubbletea/v2" 10) 11 12// ConfirmRestart keeps input cancellation owned by Bubble Tea, rather than 13// leaving a blocked reader behind when the caller stops waiting. 14func (t * Service )ConfirmRestart (ctx context.Context ,running daemon.ConnectionSnapshot ,selected daemon.BuildIdentity ) (bool ,error ) { 15if err := ctx .Err ();err != nil { 16return false ,err 17 } 18if ! t .Capable { 19return false ,nil 20 } 21if _ ,err := fmt .Fprintf (t .Out ,"Albedo is already running (PID %d).\n" ,running .Pid );err != nil { 22return false ,err 23 } 24if daemon .BuildMismatch (daemon.BuildIdentity {Build :running .Build ,Digest :running .Digest },selected ) { 25if _ ,err := fmt .Fprintln (t .Out ,"The running daemon comes from a different build." );err != nil { 26return false ,err 27 } 28 } 29if _ ,err := fmt .Fprintln (t .Out ,"Restarting interrupts active work in all sessions. Keep it running unless you want to restart." );err != nil { 30return false ,err 31 } 32program := tea .NewProgram (restartConfirmation {},tea .WithInput (t .In ),tea .WithOutput (t .Out ),tea .WithoutSignalHandler ()) 33// Graceful quit waits for the canceled input reader before closing it. 34// WithContext kills immediately and can race that reader's shutdown. 35stopCancellation := context .AfterFunc (ctx ,func () {program .Send (tea .Quit ()) }) 36defer stopCancellation () 37final ,err := program .Run () 38if ctx .Err ()!= nil { 39return false ,ctx .Err () 40 } 41if err != nil { 42return false ,err 43 } 44answer := final .(restartConfirmation ) 45return Confirmed (answer .input ),answer .err 46} 47 48type restartConfirmation struct { 49input string 50err error 51} 52 53func (m restartConfirmation )Init () tea.Cmd {return nil } 54 55func (m restartConfirmation )Update (message tea.Msg ) (tea.Model , tea.Cmd ) { 56switch message := message .(type ) { 57case tea.KeyPressMsg : 58switch message .String () { 59case "ctrl+c" ,"ctrl+d" ,"esc" : 60m .err = context .Canceled 61return m ,tea .Quit 62case "enter" : 63return m ,tea .Quit 64case "backspace" : 65characters := []rune (m .input ) 66if len (characters )> 0 { 67m .input = string (characters [:len (characters )- 1 ]) 68 } 69default : 70m .input += message .Text 71 } 72case tea.PasteMsg : 73m .input += strings .ReplaceAll (strings .ReplaceAll (message .Content ,"\r" ,"" ),"\n" ,"" ) 74 } 75return m ,nil 76} 77 78func (m restartConfirmation )View () tea.View { 79return tea .NewView ("Restart Albedo? [y/N] " + m .input ) 80}