X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/5dd573088995edec81ac34eeed20bdb5819d9136..71c56068adca18f76ebee86355f000a3e51d3127:/client.go?ds=sidebyside diff --git a/client.go b/client.go index 79f623a..940e6fe 100644 --- a/client.go +++ b/client.go @@ -220,7 +220,11 @@ func (ui *UI) renderSettingsForm() *tview.Flex { }, nil) settingsForm.AddInputField("Tracker", ui.HLClient.pref.Tracker, 0, nil, nil) settingsForm.AddButton("Save", func() { - ui.HLClient.pref.Username = settingsForm.GetFormItem(0).(*tview.InputField).GetText() + usernameInput := settingsForm.GetFormItem(0).(*tview.InputField).GetText() + if len(usernameInput) == 0 { + usernameInput = "unnamed" + } + 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() @@ -353,7 +357,7 @@ func randomBanner() string { func (ui *UI) renderServerUI() *tview.Flex { commandList := tview.NewTextView().SetDynamicColors(true) commandList. - SetText("[yellow]^n[-::]: Read News\n[yellow]^l[-::]: View Logs\n"). + SetText("[yellow]^n[-::]: Read News [yellow]^p[-::]: Post News\n[yellow]^l[-::]: View Logs\n"). SetBorder(true). SetTitle("Keyboard Shortcuts") @@ -390,6 +394,90 @@ func (ui *UI) renderServerUI() *tview.Flex { } } + // Post news + if event.Key() == tcell.KeyCtrlP { + + newsFlex := tview.NewFlex() + + newsPostTextArea := tview.NewTextView() + newsPostTextArea.SetBackgroundColor(tcell.ColorDimGray) + newsPostTextArea.SetChangedFunc(func() { + ui.App.Draw() // TODO: docs say this is bad but it's the only way to show content during initial render?? + }) + //newsPostTextArea.SetBorderPadding(0, 0, 1, 1) + + newsPostForm := tview.NewForm(). + SetButtonsAlign(tview.AlignRight). + AddButton("Post", nil) + newsPostForm.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + switch event.Key() { + case tcell.KeyTab: + ui.App.SetFocus(newsPostTextArea) + case tcell.KeyEnter: + newsText := strings.ReplaceAll(newsPostTextArea.GetText(true), "\n", "\r") + err := ui.HLClient.Send( + *NewTransaction(tranOldPostNews, nil, + NewField(fieldData, []byte(newsText)), + ), + ) + if err != nil { + ui.HLClient.Logger.Errorw("Error posting news", "err", err) + // TODO: display errModal to user + } + //newsInput.SetText("") // clear the input field after chat send + ui.Pages.RemovePage("newsInput") + } + + return event + }) + + newsFlex. + SetDirection(tview.FlexRow). + SetBorder(true). + SetTitle("News Post") + + newsPostTextArea.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + ui.HLClient.Logger.Infow("key", "key", event.Key(), "rune", event.Rune()) + switch event.Key() { + case tcell.KeyEscape: + ui.Pages.RemovePage("newsInput") + case tcell.KeyTab: + ui.App.SetFocus(newsPostForm) + case tcell.KeyEnter: + fmt.Fprintf(newsPostTextArea, "\n") + default: + switch event.Rune() { + case 127: // backspace + curTxt := newsPostTextArea.GetText(true) + if len(curTxt) > 0 { + curTxt = curTxt[:len(curTxt)-1] + newsPostTextArea.SetText(curTxt) + } + default: + fmt.Fprintf(newsPostTextArea, string(event.Rune())) + } + } + + return event + }) + + newsFlex.AddItem(newsPostTextArea, 10, 0, true) + newsFlex.AddItem(newsPostForm, 3, 0, false) + + newsPostPage := tview.NewFlex(). + AddItem(nil, 0, 1, false). + AddItem(tview.NewFlex(). + SetDirection(tview.FlexRow). + AddItem(nil, 0, 1, false). + AddItem(newsFlex, 15, 1, true). + //AddItem(newsPostForm, 3, 0, false). + AddItem(nil, 0, 1, false), 40, 1, false). + AddItem(nil, 0, 1, false) + + ui.Pages.AddPage("newsInput", newsPostPage, true, true) + ui.App.SetFocus(newsPostTextArea) + } + return event }) return serverUI @@ -407,7 +495,7 @@ func (ui *UI) Start() { home.AddItem( tview.NewFlex().AddItem(bannerItem, 0, 1, false), - 13, 1, false) + 14, 1, false) home.AddItem(tview.NewFlex(). AddItem(nil, 0, 1, false). AddItem(mainMenu, 0, 1, true). @@ -666,15 +754,16 @@ func (c *Client) GetTransactions() error { func handleClientGetUserNameList(c *Client, t *Transaction) (res []Transaction, err error) { var users []User for _, field := range t.Fields { - u, _ := ReadUser(field.Data) - //flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(u.Flags))) - //if flagBitmap.Bit(userFlagAdmin) == 1 { - // fmt.Fprintf(UserList, "[red::b]%s[-:-:-]\n", u.Name) - //} else { - // fmt.Fprintf(UserList, "%s\n", u.Name) - //} - - users = append(users, *u) + // The Hotline protocol docs say that ClientGetUserNameList should only return fieldUsernameWithInfo (300) + // fields, but shxd sneaks in fieldChatSubject (115) so it's important to filter explicitly for the expected + // field type. Probably a good idea to do everywhere. + if bytes.Equal(field.ID, []byte{0x01, 0x2c}) { + u, err := ReadUser(field.Data) + if err != nil { + return res, err + } + users = append(users, *u) + } } c.UserList = users