From bdd40ea8df60b6b161da3c1d201e9ec05ef743d1 Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Sun, 8 Dec 2024 14:18:16 +0300 Subject: Feat: export chat to json file; --- models/models.go | 2 +- session.go | 9 +++++++++ tui.go | 23 ++++++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/models/models.go b/models/models.go index 2ac087a..82ff63d 100644 --- a/models/models.go +++ b/models/models.go @@ -69,7 +69,7 @@ func (m RoleMsg) ToText(i int) string { default: icon = fmt.Sprintf("(%d) <%s>: ", i, m.Role) } - textMsg := fmt.Sprintf("%s\n%s\n", icon, m.Content) + textMsg := fmt.Sprintf("[-:-:u]%s[-:-:-]\n%s\n", icon, m.Content) return strings.ReplaceAll(textMsg, "\n\n", "\n") } diff --git a/session.go b/session.go index 88b370c..c3d826f 100644 --- a/session.go +++ b/session.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "os" "os/exec" "strings" "time" @@ -25,6 +26,14 @@ func historyToSJSON(msgs []models.RoleMsg) (string, error) { return string(data), nil } +func exportChat() error { + data, err := json.MarshalIndent(chatBody.Messages, "", " ") + if err != nil { + return err + } + return os.WriteFile(activeChatName+".json", data, 0666) +} + func updateStorageChat(name string, msgs []models.RoleMsg) error { var err error chat, ok := chatMap[name] diff --git a/tui.go b/tui.go index d7fc6e0..69279d7 100644 --- a/tui.go +++ b/tui.go @@ -37,6 +37,7 @@ var ( [yellow]F7[white]: copy last msg to clipboard (linux xclip) [yellow]F8[white]: copy n msg to clipboard (linux xclip) [yellow]Ctrl+s[white]: choose/replace system prompt +[yellow]Ctrl+e[white]: export chat to json file Press Enter to go back ` @@ -168,6 +169,7 @@ func init() { applyCharCard(cc) // replace textview textView.SetText(chatToText(cfg.ShowSys)) + colorText() sysModal.ClearButtons() pages.RemovePage("sys") app.SetFocus(textArea) @@ -319,10 +321,12 @@ func init() { if strings.HasSuffix(text, cfg.AssistantIcon) { logger.Info("deleting assistant icon", "icon", cfg.AssistantIcon) textView.SetText(strings.TrimSuffix(text, cfg.AssistantIcon)) + colorText() return nil } chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1] textView.SetText(chatToText(cfg.ShowSys)) + colorText() return nil } if event.Key() == tcell.KeyF4 { @@ -335,6 +339,7 @@ func init() { // switch cfg.ShowSys cfg.ShowSys = !cfg.ShowSys textView.SetText(chatToText(cfg.ShowSys)) + colorText() } if event.Key() == tcell.KeyF6 { interruptResp = true @@ -370,8 +375,12 @@ func init() { return nil } if event.Key() == tcell.KeyCtrlE { - textArea.SetText("pressed ctrl+e", true) - colorText() + // export loaded chat into json file + if err := exportChat(); err != nil { + logger.Error("failed to export chat;", "error", err, "chat_name", activeChatName) + return nil + } + notifyUser("exported chat", "chat: "+activeChatName+" was exported") return nil } if event.Key() == tcell.KeyCtrlA { @@ -406,8 +415,16 @@ func init() { msgText := textArea.GetText() // TODO: check whose message was latest (user icon / assistant) // in order to decide if assistant new icon is needed + nl := "\n" + prevText := textView.GetText(true) + // strings.LastIndex() + // newline is not needed is prev msg ends with one + if strings.HasSuffix(prevText, nl) { + nl = "" + } if msgText != "" { - fmt.Fprintf(textView, "\n(%d) : \n%s\n", len(chatBody.Messages), msgText) + fmt.Fprintf(textView, "%s[-:-:u](%d) <%s>: [-:-:-]\n%s\n", + nl, len(chatBody.Messages), cfg.UserRole, msgText) textArea.SetText("", true) textView.ScrollToEnd() colorText() -- cgit v1.2.3