package prompt import ( "fmt" "io" "strings" "code.severnaya.net/kordophone-mock/v2/server" "github.com/chzyer/readline" "github.com/rs/zerolog/log" ) type Prompt struct { rl *readline.Instance server *server.Server } func (p *Prompt) listConversations() { conversations := p.server.SortedConversations() for _, c := range conversations { fmt.Printf("%s %s \t %s ", c.Guid, c.GetDisplayName(), c.Date.Format("2006-01-02 15:04:05")) if c.UnreadCount > 0 { fmt.Printf("(%d unread)", c.UnreadCount) } fmt.Println() } } func (p *Prompt) listMessages(guid string) { conversation, err := p.server.ConversationForGUID(guid) if err != nil { log.Err(err).Msgf("Error listing messages for conversation %s", guid) return } messages := p.server.MessagesForConversation(conversation) for _, m := range messages { var sender string if m.Sender == nil { sender = "(Me)" } else { sender = *m.Sender } fmt.Printf("%s %s From: %s\n", m.Guid, m.Date.Format("2006-01-02 15:04:05"), sender) fmt.Printf("\t %s\n", m.Text) } } func (p *Prompt) markConversation(guid string, read bool) { conversation, err := p.server.ConversationForGUID(guid) if err != nil { log.Err(err).Msgf("Error marking conversation %s as read", guid) return } if read { conversation.UnreadCount = 0 } else { conversation.UnreadCount = 1 } } func NewPrompt(server *server.Server) *Prompt { completer := readline.NewPrefixCompleter( readline.PcItem("ls"), readline.PcItem("mark", readline.PcItem("-r"), ), readline.PcItem("help"), readline.PcItem("exit"), ) rl, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", InterruptPrompt: "^C", EOFPrompt: "exit", AutoComplete: completer, HistorySearchFold: true, }) if err != nil { panic(err) } return &Prompt{ rl: rl, server: server, } } func (p *Prompt) StartInteractive() error { for { line, err := p.rl.Readline() if err == readline.ErrInterrupt { if len(line) == 0 { break } else { continue } } else if err == io.EOF { break } line = strings.TrimSpace(line) switch { case strings.HasPrefix(line, "ls"): // List args := strings.Split(line, " ") if len(args) == 1 { p.listConversations() } else { p.listMessages(args[1]) } case strings.HasPrefix(line, "mark"): // Mark args := strings.Split(line, " ") if len(args) < 2 { log.Info().Msgf("Usage: mark [-r] ") continue } read := false if args[1] == "-r" { read = true args = args[1:] } p.markConversation(args[1], read) case line == "help": // Help fmt.Println("Commands:") fmt.Println("\tls list conversations") fmt.Println("\tls list messages for conversation") fmt.Println("\tmark [-r] mark conversation as unread/[r]ead") fmt.Println("\texit exits the program") case line == "exit": // Exit return nil default: fmt.Printf("Unknown command: %s\n", line) } } return nil } func (p *Prompt) CleanAndRefreshForLogging() { p.rl.Clean() // xxx: Lazy hack to make sure this runs _after_ the log is written. go p.rl.Refresh() }