X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/40afb444ff58289700baa1eb07f3f92d4731436d..4f60d070052e104758671765e817d715996afa59:/hotline/ui.go diff --git a/hotline/ui.go b/hotline/ui.go index e4dafd5..e3e2fab 100644 --- a/hotline/ui.go +++ b/hotline/ui.go @@ -1,28 +1,23 @@ package hotline import ( - "errors" "fmt" - "github.com/davecgh/go-spew/spew" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" - "gopkg.in/yaml.v2" - "io" - "io/ioutil" + "gopkg.in/yaml.v3" "os" "strconv" "strings" ) type UI struct { - chatBox *tview.TextView - chatInput *tview.InputField - App *tview.Application - Pages *tview.Pages - userList *tview.TextView - agreeModal *tview.Modal - trackerList *tview.List - HLClient *Client + chatBox *tview.TextView + chatInput *tview.InputField + App *tview.Application + Pages *tview.Pages + userList *tview.TextView + trackerList *tview.List + HLClient *Client } // pages @@ -52,8 +47,8 @@ func NewUI(c *Client) *UI { } _ = c.Send( - *NewTransaction(tranChatSend, nil, - NewField(fieldData, []byte(chatInput.GetText())), + *NewTransaction(TranChatSend, nil, + NewField(FieldData, []byte(chatInput.GetText())), ), ) chatInput.SetText("") // clear the input field after chat send @@ -76,7 +71,6 @@ func NewUI(c *Client) *UI { chatInput: chatInput, userList: userList, trackerList: tview.NewList(), - agreeModal: tview.NewModal(), HLClient: c, } } @@ -92,7 +86,7 @@ func (ui *UI) showBookmarks() *tview.List { list.Box.SetBorder(true).SetTitle("| Bookmarks |") shortcut := 97 // rune for "a" - for i, srv := range ui.HLClient.pref.Bookmarks { + for i, srv := range ui.HLClient.Pref.Bookmarks { addr := srv.Addr login := srv.Login pass := srv.Password @@ -108,12 +102,7 @@ func (ui *UI) showBookmarks() *tview.List { return list } -func (ui *UI) getTrackerList() *tview.List { - listing, err := GetListing(ui.HLClient.pref.Tracker) - if err != nil { - spew.Dump(err) - } - +func (ui *UI) getTrackerList(servers []ServerRecord) *tview.List { list := tview.NewList() list.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyEsc { @@ -123,13 +112,12 @@ func (ui *UI) getTrackerList() *tview.List { }) list.Box.SetBorder(true).SetTitle("| Servers |") - shortcut := 97 // rune for "a" - for i, srv := range listing { - addr := srv.Addr() + const shortcut = 97 // rune for "a" + for i, srv := range servers { list.AddItem(string(srv.Name), string(srv.Description), rune(shortcut+i), func() { ui.Pages.RemovePage("joinServer") - newJS := ui.renderJoinServerForm("", addr, GuestAccount, "", trackerListPage, false, true) + newJS := ui.renderJoinServerForm(string(srv.Name), srv.Addr(), GuestAccount, "", trackerListPage, false, true) ui.Pages.AddPage("joinServer", newJS, true, true) ui.Pages.ShowPage("joinServer") @@ -140,30 +128,32 @@ func (ui *UI) getTrackerList() *tview.List { } func (ui *UI) renderSettingsForm() *tview.Flex { - iconStr := strconv.Itoa(ui.HLClient.pref.IconID) + iconStr := strconv.Itoa(ui.HLClient.Pref.IconID) settingsForm := tview.NewForm() - settingsForm.AddInputField("Your Name", ui.HLClient.pref.Username, 0, nil, nil) + settingsForm.AddInputField("Your Name", ui.HLClient.Pref.Username, 0, nil, nil) settingsForm.AddInputField("IconID", iconStr, 0, func(idStr string, _ rune) bool { _, err := strconv.Atoi(idStr) return err == nil }, nil) - settingsForm.AddInputField("Tracker", ui.HLClient.pref.Tracker, 0, nil, nil) + settingsForm.AddInputField("Tracker", ui.HLClient.Pref.Tracker, 0, nil, nil) + settingsForm.AddCheckbox("Enable Terminal Bell", ui.HLClient.Pref.EnableBell, nil) settingsForm.AddButton("Save", func() { usernameInput := settingsForm.GetFormItem(0).(*tview.InputField).GetText() if len(usernameInput) == 0 { usernameInput = "unnamed" } - ui.HLClient.pref.Username = usernameInput + ui.HLClient.Pref.Username = usernameInput iconStr = settingsForm.GetFormItem(1).(*tview.InputField).GetText() - ui.HLClient.pref.IconID, _ = strconv.Atoi(iconStr) - ui.HLClient.pref.Tracker = settingsForm.GetFormItem(2).(*tview.InputField).GetText() + ui.HLClient.Pref.IconID, _ = strconv.Atoi(iconStr) + ui.HLClient.Pref.Tracker = settingsForm.GetFormItem(2).(*tview.InputField).GetText() + ui.HLClient.Pref.EnableBell = settingsForm.GetFormItem(3).(*tview.Checkbox).IsChecked() - out, err := yaml.Marshal(&ui.HLClient.pref) + out, err := yaml.Marshal(&ui.HLClient.Pref) if err != nil { // TODO: handle err } // TODO: handle err - err = ioutil.WriteFile(ui.HLClient.cfgPath, out, 0666) + err = os.WriteFile(ui.HLClient.cfgPath, out, 0666) if err != nil { println(ui.HLClient.cfgPath) panic(err) @@ -195,34 +185,25 @@ func (ui *UI) joinServer(addr, login, password string) error { if len(strings.Split(addr, ":")) == 1 { addr += ":5500" } - if err := ui.HLClient.JoinServer(addr, login, password); err != nil { - return errors.New(fmt.Sprintf("Error joining server: %v\n", err)) + if err := ui.HLClient.Connect(addr, login, password); err != nil { + return fmt.Errorf("Error joining server: %v\n", err) } go func() { - for { - err := ui.HLClient.ReadLoop() - if err != nil { - ui.HLClient.Logger.Errorw("read error", "err", err) - - if err == io.EOF { - loginErrModal := tview.NewModal(). - AddButtons([]string{"Ok"}). - SetText("The server connection has closed."). - SetDoneFunc(func(buttonIndex int, buttonLabel string) { - ui.Pages.SwitchToPage("home") - }) - loginErrModal.Box.SetTitle("Server Connection Error") - - ui.Pages.AddPage("loginErr", loginErrModal, false, true) - ui.App.Draw() - return - } + if err := ui.HLClient.HandleTransactions(); err != nil { + ui.Pages.SwitchToPage("home") + } + + loginErrModal := tview.NewModal(). + AddButtons([]string{"Ok"}). + SetText("The server connection has closed."). + SetDoneFunc(func(buttonIndex int, buttonLabel string) { ui.Pages.SwitchToPage("home") + }) + loginErrModal.Box.SetTitle("Server Connection Error") - return - } - } + ui.Pages.AddPage("loginErr", loginErrModal, false, true) + ui.App.Draw() }() return nil @@ -231,37 +212,43 @@ func (ui *UI) joinServer(addr, login, password string) error { func (ui *UI) renderJoinServerForm(name, server, login, password, backPage string, save, defaultConnect bool) *tview.Flex { joinServerForm := tview.NewForm() joinServerForm. - // AddInputField("Name", server, 0, func(textToCheck string, lastChar rune) bool { - // return false - //}, nil). AddInputField("Server", server, 0, nil, nil). AddInputField("Login", login, 0, nil, nil). AddPasswordField("Password", password, 0, '*', nil). AddCheckbox("Save", save, func(checked bool) { - ui.HLClient.Logger.Infow("saving bookmark") - // TODO: Implement bookmark saving + ui.HLClient.Pref.AddBookmark( + joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), + joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), + joinServerForm.GetFormItem(1).(*tview.InputField).GetText(), + joinServerForm.GetFormItem(2).(*tview.InputField).GetText(), + ) - ui.HLClient.pref.AddBookmark(joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(1).(*tview.InputField).GetText(), joinServerForm.GetFormItem(2).(*tview.InputField).GetText()) - out, err := yaml.Marshal(ui.HLClient.pref) + out, err := yaml.Marshal(ui.HLClient.Pref) if err != nil { panic(err) } - err = ioutil.WriteFile(ui.HLClient.cfgPath, out, 0666) + err = os.WriteFile(ui.HLClient.cfgPath, out, 0666) if err != nil { panic(err) } - // pref := ui.HLClient.pref }). AddButton("Cancel", func() { ui.Pages.SwitchToPage(backPage) }). AddButton("Connect", func() { + srvAddr := joinServerForm.GetFormItem(0).(*tview.InputField).GetText() + loginInput := joinServerForm.GetFormItem(1).(*tview.InputField).GetText() err := ui.joinServer( - joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), - joinServerForm.GetFormItem(1).(*tview.InputField).GetText(), + srvAddr, + loginInput, joinServerForm.GetFormItem(2).(*tview.InputField).GetText(), ) + if name == "" { + name = fmt.Sprintf("%s@%s", loginInput, srvAddr) + } + ui.HLClient.serverName = name + if err != nil { ui.HLClient.Logger.Errorw("login error", "err", err) loginErrModal := tview.NewModal(). @@ -320,6 +307,7 @@ func (ui *UI) renderServerUI() *tview.Flex { if buttonIndex == 1 { _ = ui.HLClient.Disconnect() ui.Pages.RemovePage(pageServerUI) + ui.Pages.SwitchToPage("home") } else { ui.Pages.HidePage("modal") } @@ -332,7 +320,7 @@ func (ui *UI) renderServerUI() *tview.Flex { AddItem(ui.chatBox, 0, 8, false). AddItem(ui.chatInput, 3, 0, true), 0, 1, true). AddItem(ui.userList, 25, 1, false) - serverUI.SetBorder(true).SetTitle("| Mobius - Connected to " + "TODO" + " |").SetTitleAlign(tview.AlignLeft) + serverUI.SetBorder(true).SetTitle("| Mobius - Connected to " + ui.HLClient.serverName + " |").SetTitleAlign(tview.AlignLeft) serverUI.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyEscape { ui.Pages.AddPage("modal", modal, false, true) @@ -340,21 +328,20 @@ func (ui *UI) renderServerUI() *tview.Flex { // List files if event.Key() == tcell.KeyCtrlF { - if err := ui.HLClient.Send(*NewTransaction(tranGetFileNameList, nil)); err != nil { + if err := ui.HLClient.Send(*NewTransaction(TranGetFileNameList, nil)); err != nil { ui.HLClient.Logger.Errorw("err", "err", err) } } // Show News if event.Key() == tcell.KeyCtrlN { - if err := ui.HLClient.Send(*NewTransaction(tranGetMsgs, nil)); err != nil { + if err := ui.HLClient.Send(*NewTransaction(TranGetMsgs, nil)); err != nil { ui.HLClient.Logger.Errorw("err", "err", err) } } // Post news if event.Key() == tcell.KeyCtrlP { - newsFlex := tview.NewFlex() newsFlex.SetBorderPadding(0, 0, 1, 1) newsPostTextArea := tview.NewTextView() @@ -365,7 +352,7 @@ func (ui *UI) renderServerUI() *tview.Flex { newsPostForm := tview.NewForm(). SetButtonsAlign(tview.AlignRight). - //AddButton("Cancel", nil). // TODO: implement cancel button behavior + // AddButton("Cancel", nil). // TODO: implement cancel button behavior AddButton("Send", nil) newsPostForm.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { @@ -379,8 +366,8 @@ func (ui *UI) renderServerUI() *tview.Flex { return event } err := ui.HLClient.Send( - *NewTransaction(tranOldPostNews, nil, - NewField(fieldData, []byte(newsText)), + *NewTransaction(TranOldPostNews, nil, + NewField(FieldData, []byte(newsText)), ), ) if err != nil { @@ -417,7 +404,7 @@ func (ui *UI) renderServerUI() *tview.Flex { newsPostTextArea.SetText(curTxt) } default: - _, _ = fmt.Fprintf(newsPostTextArea, string(event.Rune())) + _, _ = fmt.Fprint(newsPostTextArea, string(event.Rune())) } } @@ -433,7 +420,7 @@ func (ui *UI) renderServerUI() *tview.Flex { SetDirection(tview.FlexRow). AddItem(nil, 0, 1, false). AddItem(newsFlex, 15, 1, true). - //AddItem(newsPostForm, 3, 0, false). + // AddItem(newsPostForm, 3, 0, false). AddItem(nil, 0, 1, false), 40, 1, false). AddItem(nil, 0, 1, false) @@ -474,7 +461,20 @@ func (ui *UI) Start() { ui.Pages.AddAndSwitchToPage("bookmarks", ui.showBookmarks(), true) }). AddItem("Browse Tracker", "", 't', func() { - ui.trackerList = ui.getTrackerList() + listing, err := GetListing(ui.HLClient.Pref.Tracker) + if err != nil { + errMsg := fmt.Sprintf("Error fetching tracker results:\n%v", err) + errModal := tview.NewModal() + errModal.SetText(errMsg) + errModal.AddButtons([]string{"Cancel"}) + errModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { + ui.Pages.RemovePage("errModal") + }) + ui.Pages.RemovePage("joinServer") + ui.Pages.AddPage("errModal", errModal, false, true) + return + } + ui.trackerList = ui.getTrackerList(listing) ui.Pages.AddAndSwitchToPage("trackerList", ui.trackerList, true) }). AddItem("Settings", "", 's', func() {