Browse Source

41 (#107)

* you'll return to view mode instead of list

* Add help view

* update version

* make the help message optional
pull/118/head 0.0.41
Rasmus Lindroth 4 years ago committed by GitHub
parent
commit
05385cf72f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 4
      cmdbar.go
  3. 4
      config.example.ini
  4. 19
      config.go
  5. 87
      help.tmpl
  6. 64
      helpoverlay.go
  7. 12
      linkoverlay.go
  8. 21
      main.go
  9. 7
      messagebox.go
  10. 28
      statusview.go
  11. 22
      ui.go
  12. 18
      voteoverlay.go

2
README.md

@ -35,6 +35,7 @@ You can find Linux binaries under [releases](https://github.com/RasmusLindroth/t
* `:compose` compose a new toot
* `:favorited` lists toots you've favorited
* `:favorites` lists users that favorited the toot
* `:h` `:help` view help
* `:lists` show a list of your lists
* `:muting` lists users that you have muted
* `:profile` go to your profile
@ -50,6 +51,7 @@ Keys without description in tut
* `arrow keys` = navigation. Same as `jk` and `hl`
* `g` or `Home` = go to top
* `G` or `End` = go to bottom
* `?` = view help
* `q` = go back and quit
* `ESC` = go back

4
cmdbar.go

@ -180,5 +180,9 @@ func (c *CmdBar) DoneFunc(key tcell.Key) {
c.app.UI.StatusView.AddFeed(NewListFeed(c.app))
c.app.UI.SetFocus(LeftPaneFocus)
c.app.UI.CmdBar.ClearInput()
case ":help", ":h":
c.app.UI.SetFocus(HelpOverlayFocus)
c.app.UI.CmdBar.ClearInput()
}
}

4
config.example.ini

@ -92,6 +92,10 @@ char-limit=500
# default=true
show-icons=true
# If you want to show a message in the cmdbar how you can view the help message
# default=true
show-help=true
# If you've learnt all the shortcut keys you can remove the help text and
# only show the key in tui. So it gets less cluttered.
# default=false

19
config.go

@ -19,6 +19,9 @@ var tootTemplate string
//go:embed user.tmpl
var userTemplate string
//go:embed help.tmpl
var helpTemplate string
type Config struct {
General GeneralConfig
Style StyleConfig
@ -47,6 +50,7 @@ type GeneralConfig struct {
ListProportion int
ContentProportion int
ShowIcons bool
ShowHelp bool
}
type StyleConfig struct {
@ -156,6 +160,7 @@ type NotificationConfig struct {
type TemplatesConfig struct {
TootTemplate *template.Template
UserTemplate *template.Template
HelpTemplate *template.Template
}
func parseColor(input string, def string, xrdb map[string]string) tcell.Color {
@ -290,6 +295,7 @@ func parseGeneral(cfg *ini.File) GeneralConfig {
general.ShortHints = cfg.Section("general").Key("short-hints").MustBool(false)
general.HideNotificationText = cfg.Section("general").Key("hide-notification-text").MustBool(false)
general.ShowIcons = cfg.Section("general").Key("show-icons").MustBool(true)
general.ShowHelp = cfg.Section("general").Key("show-help").MustBool(true)
lp := cfg.Section("general").Key("list-placement").In("left", []string{"left", "right", "top", "bottom"})
switch lp {
@ -512,9 +518,18 @@ func ParseTemplates(cfg *ini.File) TemplatesConfig {
if err != nil {
log.Fatalf("Couldn't parse user.tmpl. Error: %v", err)
}
var helpTmpl *template.Template
helpTmpl, err = template.New("help.tmpl").Funcs(template.FuncMap{
"Color": ColorMark,
"Flags": TextFlags,
}).Parse(helpTemplate)
if err != nil {
log.Fatalf("Couldn't parse help.tmpl. Error: %v", err)
}
return TemplatesConfig{
TootTemplate: tootTmpl,
UserTemplate: userTmpl,
HelpTemplate: helpTmpl,
}
}
@ -657,6 +672,10 @@ char-limit=500
# default=true
show-icons=true
# If you want to show a message in the cmdbar how you can view the help message
# default=true
show-help=true
# If you've learnt all the shortcut keys you can remove the help text and
# only show the key in tui. So it gets less cluttered.
# default=false

87
help.tmpl

@ -0,0 +1,87 @@
{{ Color .Style.Text }}{{ Flags "b" }}Keys and navigation{{ Flags "-" }}
Below are the keys that doesn't have hints in the TUI. All other keys have hints in the TUI. E.g. you're viewing a toot, down at the bottom you'll see {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}F{{ Flags "-" }}{{ Color .Style.Text }}avorite.
That means that you'll have to press {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}F{{ Flags "-" }}{{ Color .Style.Text }} to favorite a toot.
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}c{{ Flags "-" }}{{ Color .Style.Text }} - Compose a new toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}j{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} Down arrow{{ Flags "-" }}{{ Color .Style.Text }} - Navigate down in feed list or toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}k{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} Up arrow{{ Flags "-" }}{{ Color .Style.Text }} - Navigate up in feed list or toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}h{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} Left arrow{{ Flags "-" }}{{ Color .Style.Text }} - Cycle back between feeds
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}l{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} Right arrow{{ Flags "-" }}{{ Color .Style.Text }} - Cycle forward between feeds
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}g{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} Home{{ Flags "-" }}{{ Color .Style.Text }} - Go to top in feed list or toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}G{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} End{{ Flags "-" }}{{ Color .Style.Text }} - Go to bottom in feed list or toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}?{{ Flags "-" }}{{ Color .Style.Text }} - View help
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}q{{ Flags "-" }}{{ Color .Style.Text }} - Go back or quit
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}ESC{{ Flags "-" }}{{ Color .Style.Text }} - Go back
{{ Color .Style.Text }}{{ Flags "b" }}Commands{{ Flags "-" }}
All commands start with {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:{{ Flags "-" }}{{ Color .Style.Text }}. And you run the command by hitting {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}Enter{{ Flags "-" }}{{ Color .Style.Text }}.
Here's a list of supported commands.
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:q{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} :quit{{ Flags "-" }}{{ Color .Style.Text }}
Exit the program
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:timeline{{ Flags "-" }}{{ Color .Style.Text }} home|local|federated|direct|notifications|favorited
Open selected timeline
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:tl{{ Flags "-" }}{{ Color .Style.Text }} h|l|f|d|n|fav
Shorter form of the former command *:timeline*
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:blocking{{ Flags "-" }}{{ Color .Style.Text }}
Lists users that you have blocked
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:boosts{{ Flags "-" }}{{ Color .Style.Text }}
Lists users that boosted the toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:bookmarks{{ Flags "-" }}{{ Color .Style.Text }}
Lists all your bookmarks
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:compose{{ Flags "-" }}{{ Color .Style.Text }}
Compose a new toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:favorited{{ Flags "-" }}{{ Color .Style.Text }}
Lists toots you've favorited
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:favorites{{ Flags "-" }}{{ Color .Style.Text }}
Lists users that favorited the toot
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:h{{ Flags "-" }}{{ Color .Style.Text }} or
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} :help{{ Flags "-" }}{{ Color .Style.Text }}
View this help message
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:lists{{ Flags "-" }}{{ Color .Style.Text }}
Show a list of your lists
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:muting{{ Flags "-" }}{{ Color .Style.Text }}
lists users that you have muted
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:profile{{ Flags "-" }}{{ Color .Style.Text }}
Go to your own profile
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:saved{{ Flags "-" }}{{ Color .Style.Text }}
Alias for :bookmarks
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:tag{{ Flags "-" }}{{ Color .Style.Text }} tagname
See toots for a tag. E.g. :tag linux
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:user{{ Flags "-" }}{{ Color .Style.Text }} username
Go to profile for <username>. E.g. :user rasmus
To narrow a search include the instance like this :user rasmus@mastodon.acc.sunet.se
{{ Color .Style.Text }}{{ Flags "b" }}Configuration{{ Flags "-" }}
tut searches for a config file in the following locations:
1. $XDG_CONFIG_HOME/tut/config.ini
2. $HOME/.config/tut/config.ini
For information on the config file format go to <https://tut.anv.nu/config>.

64
helpoverlay.go

@ -0,0 +1,64 @@
package main
import (
"bytes"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
func NewHelpOverlay(app *App) *HelpOverlay {
h := &HelpOverlay{
app: app,
Flex: tview.NewFlex(),
TextMain: tview.NewTextView(),
TextBottom: tview.NewTextView(),
}
h.TextMain.SetBackgroundColor(app.Config.Style.Background)
h.TextMain.SetDynamicColors(true)
h.TextBottom.SetBackgroundColor(app.Config.Style.Background)
h.TextBottom.SetDynamicColors(true)
h.TextBottom.SetText(ColorKey(app.Config, "", "Q", "uit"))
h.Flex.SetDrawFunc(app.Config.ClearContent)
hd := HelpData{
Style: app.Config.Style,
}
var output bytes.Buffer
err := app.Config.Templates.HelpTemplate.ExecuteTemplate(&output, "help.tmpl", hd)
if err != nil {
panic(err)
}
h.TextMain.SetText(output.String())
return h
}
type HelpData struct {
Style StyleConfig
}
type HelpOverlay struct {
app *App
Flex *tview.Flex
TextMain *tview.TextView
TextBottom *tview.TextView
}
func (h *HelpOverlay) InputHandler(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyRune {
switch event.Rune() {
case 'q', 'Q':
h.app.UI.StatusView.giveBackFocus()
return nil
}
} else {
switch event.Key() {
case tcell.KeyEsc:
h.app.UI.StatusView.giveBackFocus()
return nil
}
}
return event
}

12
linkoverlay.go

@ -194,11 +194,7 @@ func (l *LinkOverlay) InputHandler(event *tcell.EventKey) {
i, _ := strconv.Atoi(s)
l.OpenCustom(i)
case 'q', 'Q':
if l.app.UI.StatusView.lastList == NotificationPaneFocus {
l.app.UI.SetFocus(NotificationPaneFocus)
} else {
l.app.UI.SetFocus(LeftPaneFocus)
}
l.app.UI.StatusView.giveBackFocus()
}
} else {
switch event.Key() {
@ -209,11 +205,7 @@ func (l *LinkOverlay) InputHandler(event *tcell.EventKey) {
case tcell.KeyDown:
l.Next()
case tcell.KeyEsc:
if l.app.UI.StatusView.lastList == NotificationPaneFocus {
l.app.UI.SetFocus(NotificationPaneFocus)
} else {
l.app.UI.SetFocus(LeftPaneFocus)
}
l.app.UI.StatusView.giveBackFocus()
}
}
}

21
main.go

@ -9,7 +9,7 @@ import (
"github.com/gdamore/tcell/v2"
)
const version string = "0.0.40"
const version string = "0.0.41"
func main() {
newUser := false
@ -165,6 +165,11 @@ func main() {
return nil
}
if app.UI.Focus == HelpOverlayFocus {
ev := app.UI.HelpOverlay.InputHandler(event)
return ev
}
if app.UI.Focus == VoteOverlayFocus {
app.UI.VoteOverlay.InputHandler(event)
return nil
@ -207,21 +212,13 @@ func main() {
app.UI.SetFocus(VisibilityOverlayFocus)
return nil
case 'q', 'Q':
if app.UI.StatusView.lastList == NotificationPaneFocus {
app.UI.SetFocus(NotificationPaneFocus)
} else {
app.UI.SetFocus(LeftPaneFocus)
}
app.UI.StatusView.giveBackFocus()
return nil
}
} else {
switch event.Key() {
case tcell.KeyEsc:
if app.UI.StatusView.lastList == NotificationPaneFocus {
app.UI.SetFocus(NotificationPaneFocus)
} else {
app.UI.SetFocus(LeftPaneFocus)
}
app.UI.StatusView.giveBackFocus()
return nil
}
}
@ -304,7 +301,7 @@ func main() {
)
app.UI.CmdBar.Input.SetAutocompleteFunc(func(currentText string) (entries []string) {
words := strings.Split(":blocking,:boosts,:bookmarks,:compose,:favorites,:favorited,:lists,:muting,:profile,:saved,:tag,:timeline,:tl,:user,:quit,:q", ",")
words := strings.Split(":blocking,:boosts,:bookmarks,:compose,:favorites,:favorited,:help,:h,:lists,:muting,:profile,:saved,:tag,:timeline,:tl,:user,:quit,:q", ",")
if currentText == "" {
return
}

7
messagebox.go

@ -159,12 +159,7 @@ func (m *MessageBox) Post() {
m.app.UI.CmdBar.ShowError(fmt.Sprintf("Couldn't post toot. Error: %v\n", err))
return
}
if m.app.UI.StatusView.lastList == NotificationPaneFocus {
m.app.UI.SetFocus(NotificationPaneFocus)
} else {
m.app.UI.SetFocus(LeftPaneFocus)
}
m.app.UI.SetFocus(LeftPaneFocus)
m.app.UI.StatusView.giveBackFocus()
}
func (m *MessageBox) TootLength() int {

28
statusview.go

@ -263,6 +263,8 @@ func (t *StatusView) inputBoth(event *tcell.EventKey) {
t.home()
case 'G':
t.end()
case '?':
t.app.UI.SetFocus(HelpOverlayFocus)
}
} else {
switch event.Key() {
@ -675,3 +677,29 @@ func (t *StatusView) loadOlder() {
})
}()
}
func (t *StatusView) giveBackFocus() {
if t.focus == RightPaneFocus {
t.app.UI.SetFocus(RightPaneFocus)
t.focus = RightPaneFocus
t.app.UI.StatusBar.Text.SetBackgroundColor(
t.app.Config.Style.StatusBarViewBackground,
)
t.app.UI.StatusBar.Text.SetTextColor(
t.app.Config.Style.StatusBarViewText,
)
return
} else if t.lastList == LeftPaneFocus {
t.app.UI.SetFocus(LeftPaneFocus)
t.focus = LeftPaneFocus
} else if t.lastList == NotificationPaneFocus {
t.app.UI.SetFocus(NotificationPaneFocus)
t.focus = NotificationPaneFocus
}
t.app.UI.StatusBar.Text.SetBackgroundColor(
t.app.Config.Style.StatusBarBackground,
)
t.app.UI.StatusBar.Text.SetTextColor(
t.app.Config.Style.StatusBarText,
)
}

22
ui.go

@ -24,6 +24,7 @@ const (
VoteOverlayFocus
AuthOverlayFocus
UserSelectFocus
HelpOverlayFocus
)
func NewUI(app *App) *UI {
@ -61,6 +62,7 @@ func (ui *UI) Init() {
ui.AuthOverlay = NewAuthOverlay(ui.app)
ui.UserSelectOverlay = NewUserSelectOverlay(ui.app)
ui.MediaOverlay = NewMediaOverlay(ui.app)
ui.HelpOverlay = NewHelpOverlay(ui.app)
ui.Pages.SetBackgroundColor(ui.app.Config.Style.Background)
@ -155,6 +157,14 @@ func (ui *UI) Init() {
AddItem(ui.MediaOverlay.InputField.View, 2, 1, false), 0, 8, false).
AddItem(nil, 0, 1, false), 0, 8, true).
AddItem(nil, 0, 1, false), true, false)
ui.Pages.AddPage("help", tview.NewFlex().AddItem(nil, 0, 1, false).
AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(nil, 0, 1, false).
AddItem(ui.HelpOverlay.Flex.SetDirection(tview.FlexRow).
AddItem(ui.HelpOverlay.TextMain, 0, 10, true).
AddItem(ui.HelpOverlay.TextBottom, 1, 1, true), 0, 8, false).
AddItem(nil, 0, 1, false), 0, 8, true).
AddItem(nil, 0, 1, false), true, false)
ui.Root.SetBeforeDrawFunc(func(screen tcell.Screen) bool {
screen.Clear()
@ -179,6 +189,7 @@ type UI struct {
MediaOverlay *MediaView
Timeline TimelineType
StatusView *StatusView
HelpOverlay *HelpOverlay
}
func (ui *UI) FocusAt(p tview.Primitive, s string) {
@ -196,6 +207,7 @@ func (ui *UI) SetFocus(f FocusAt) {
ui.Focus = f
switch f {
case RightPaneFocus:
ui.Pages.SwitchToPage("main")
ui.FocusAt(ui.StatusView.text, "-- VIEW --")
case CmdBarFocus:
ui.FocusAt(ui.CmdBar.Input, "-- CMD --")
@ -212,6 +224,13 @@ func (ui *UI) SetFocus(f FocusAt) {
ui.Pages.ShowPage("links")
ui.Root.SetFocus(ui.LinkOverlay.List)
ui.FocusAt(ui.LinkOverlay.List, "-- LINK --")
case HelpOverlayFocus:
ui.Pages.ShowPage("help")
if ui.app.Config.General.ShowHelp {
ui.CmdBar.ClearInput()
}
ui.Root.SetFocus(ui.HelpOverlay.TextMain)
ui.FocusAt(ui.HelpOverlay.TextMain, "-- HELP --")
case VoteOverlayFocus:
ui.Pages.ShowPage("vote")
ui.Root.SetFocus(ui.VoteOverlay.List)
@ -362,6 +381,9 @@ func (ui *UI) SetTopText(s string) {
}
func (ui *UI) LoggedIn() {
if ui.app.Config.General.ShowHelp {
ui.CmdBar.ShowMsg("Press ? or :help to learn how tut functions")
}
ui.StatusView = NewStatusView(ui.app, ui.Timeline)
verticalLine := tview.NewBox()

18
voteoverlay.go

@ -141,11 +141,7 @@ func (v *VoteOverlay) Vote() {
return
}
v.app.UI.StatusView.RedrawPoll(p)
if v.app.UI.StatusView.lastList == NotificationPaneFocus {
v.app.UI.SetFocus(NotificationPaneFocus)
} else {
v.app.UI.SetFocus(LeftPaneFocus)
}
v.app.UI.StatusView.giveBackFocus()
}
func (v *VoteOverlay) InputHandler(event *tcell.EventKey) {
@ -160,11 +156,7 @@ func (v *VoteOverlay) InputHandler(event *tcell.EventKey) {
case ' ':
v.ToggleSelect()
case 'q', 'Q':
if v.app.UI.StatusView.lastList == NotificationPaneFocus {
v.app.UI.SetFocus(NotificationPaneFocus)
} else {
v.app.UI.SetFocus(LeftPaneFocus)
}
v.app.UI.StatusView.giveBackFocus()
}
} else {
switch event.Key() {
@ -175,11 +167,7 @@ func (v *VoteOverlay) InputHandler(event *tcell.EventKey) {
case tcell.KeyDown:
v.Next()
case tcell.KeyEsc:
if v.app.UI.StatusView.lastList == NotificationPaneFocus {
v.app.UI.SetFocus(NotificationPaneFocus)
} else {
v.app.UI.SetFocus(LeftPaneFocus)
}
v.app.UI.StatusView.giveBackFocus()
}
}
}

Loading…
Cancel
Save