diff options
Diffstat (limited to 'tui/ssh.go')
| -rw-r--r-- | tui/ssh.go | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/tui/ssh.go b/tui/ssh.go deleted file mode 100644 index 2309b3f..0000000 --- a/tui/ssh.go +++ /dev/null @@ -1,197 +0,0 @@ -package tui - -// An example Bubble Tea server. This will put an ssh session into alt screen -// and continually print up to date terminal information. - -import ( - "fmt" - "io/fs" - "net" - - "git.sr.ht/~a73x/home" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour" - "github.com/charmbracelet/lipgloss" - "github.com/charmbracelet/log" - "github.com/charmbracelet/ssh" - "github.com/charmbracelet/wish" - "github.com/charmbracelet/wish/activeterm" - "github.com/charmbracelet/wish/bubbletea" - "github.com/charmbracelet/wish/logging" -) - -func New(host, port string) (*ssh.Server, error) { - s, err := wish.NewServer( - wish.WithAddress(net.JoinHostPort(host, port)), - wish.WithHostKeyPath(".ssh/id_ed25519"), - wish.WithMiddleware( - bubbletea.Middleware(teaHandler), - activeterm.Middleware(), // Bubble Tea apps usually require a PTY. - logging.Middleware(), - ), - ) - if err != nil { - log.Error("Could not start server", "error", err) - } - - return s, err -} - -// You can wire any Bubble Tea model up to the middleware with a function that -// handles the incoming ssh.Session. Here we just grab the terminal info and -// pass it to the new model. You can also return tea.ProgramOptions (such as -// tea.WithAltScreen) on a session by session basis. -func teaHandler(s ssh.Session) (tea.Model, []tea.ProgramOption) { - // This should never fail, as we are using the activeterm middleware. - pty, _, _ := s.Pty() - - // When running a Bubble Tea app over SSH, you shouldn't use the default - // lipgloss.NewStyle function. - // That function will use the color profile from the os.Stdin, which is the - // server, not the client. - // We provide a MakeRenderer function in the bubbletea middleware package, - // so you can easily get the correct renderer for the current session, and - // use it to create the styles. - // The recommended way to use these styles is to then pass them down to - // your Bubble Tea model. - renderer := bubbletea.MakeRenderer(s) - txtStyle := renderer.NewStyle().Foreground(lipgloss.Color("10")) - quitStyle := renderer.NewStyle().Foreground(lipgloss.Color("8")) - - bg := "light" - if renderer.HasDarkBackground() { - bg = "dark" - } - - posts, err := home.Content.ReadDir("posts") - if err != nil { - // fk knows - } - - postFiles := make([]string, 0, len(posts)) - for _, post := range posts { - postFiles = append(postFiles, "posts/"+post.Name()) - } - - m := model{ - term: pty.Term, - profile: renderer.ColorProfile().Name(), - width: pty.Window.Width, - height: pty.Window.Height, - bg: bg, - txtStyle: txtStyle, - quitStyle: quitStyle, - posts: postFiles, - } - return m, []tea.ProgramOption{tea.WithAltScreen()} -} - -// Just a generic tea.Model to demo terminal information of ssh. -type model struct { - term string - profile string - width int - height int - bg string - txtStyle lipgloss.Style - quitStyle lipgloss.Style - posts []string - cursor int - viewer *PostModel - err error -} - -func (m model) Init() tea.Cmd { - return nil -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmds []tea.Cmd - - if m.viewer != nil { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "q", "ctrl+c": - m.viewer = nil - return m, nil - case "esc": - return m, nil - } - } - viewer, cmd := m.viewer.Update(msg) - m.viewer = &viewer - return m, cmd - } - - switch msg := msg.(type) { - case tea.WindowSizeMsg: - m.height = msg.Height - m.width = msg.Width - case tea.KeyMsg: - switch msg.String() { - case "q", "ctrl+c": - return m, tea.Quit - case "up", "k": - if m.cursor > 0 { - m.cursor-- - } - case "down", "j": - if m.cursor < len(m.posts)-1 { - m.cursor++ - } - case "enter": - content, err := fs.ReadFile(home.Content, m.posts[m.cursor]) - if err != nil { - m.err = err - return m, nil - } - - out, err := glamour.Render(string(content), "dark") - if err != nil { - m.err = err - return m, nil - } - - m.viewer = &PostModel{ - content: out, - } - fakeWindowMsg := tea.WindowSizeMsg{ - Width: m.width, - Height: m.height - 1, - } - - viewer, cmd := m.viewer.Update(fakeWindowMsg) - m.viewer = &viewer - return m, cmd - } - } - - return m, tea.Batch(cmds...) -} - -func (m model) View() string { - if m.err != nil { - return m.err.Error() - } - - if m.viewer != nil { - return m.viewer.View() + "\n arrow keys to scroll and q to go back" - } - - s := "a73x\n\n" - for i, choice := range m.posts { - // Is the cursor pointing at this choice? - cursor := " " // no cursor - if m.cursor == i { - cursor = ">" // cursor! - } - - // Render the row - s += fmt.Sprintf("%s %s\n", cursor, choice) - } - s += "\narrow keys to select post and enter to select" - s += "\npress q to quit" - - return s -} |
