Explorar el Código

feat: floating url list (#520)

Ayyan hace 1 año
padre
commit
a2be9c3329
Se han modificado 4 ficheros con 65 adiciones y 65 borrados
  1. 17 7
      cmd/app.go
  2. 36 50
      cmd/messages_text.go
  3. 2 8
      internal/login/form.go
  4. 10 0
      internal/ui/util.go

+ 17 - 7
cmd/app.go

@@ -16,6 +16,7 @@ type App struct {
 
 	cfg *config.Config
 
+	pages        *tview.Pages
 	flex         *tview.Flex
 	guildsTree   *GuildsTree
 	messagesText *MessagesText
@@ -29,6 +30,7 @@ func newApp(cfg *config.Config) *App {
 
 		cfg: cfg,
 
+		pages:        tview.NewPages(),
 		flex:         tview.NewFlex(),
 		guildsTree:   newGuildsTree(app, cfg),
 		messagesText: newMessagesText(app, cfg),
@@ -57,7 +59,7 @@ func (app *App) show(token string) error {
 		}
 
 		app.init()
-		app.SetRoot(app.flex, true)
+		app.SetRoot(app.pages, true)
 	}
 
 	return nil
@@ -71,16 +73,24 @@ func (app *App) run(token string) error {
 	return app.Run()
 }
 
-func (app *App) init() {
-	app.flex.Clear()
+func (a *App) clearPages() {
+	for _, name := range a.pages.GetPageNames(false) {
+		a.pages.RemovePage(name)
+	}
+}
+
+func (a *App) init() {
+	a.clearPages()
+	a.flex.Clear()
 
 	right := tview.NewFlex()
 	right.SetDirection(tview.FlexRow)
-	right.AddItem(app.messagesText, 0, 1, false)
-	right.AddItem(app.messageInput, 3, 1, false)
+	right.AddItem(a.messagesText, 0, 1, false)
+	right.AddItem(a.messageInput, 3, 1, false)
 	// The guilds tree is always focused first at start-up.
-	app.flex.AddItem(app.guildsTree, 0, 1, true)
-	app.flex.AddItem(right, 0, 4, false)
+	a.flex.AddItem(a.guildsTree, 0, 1, true)
+	a.flex.AddItem(right, 0, 4, false)
+	a.pages.AddAndSwitchToPage("flex", a.flex, true)
 }
 
 func (app *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey {

+ 36 - 50
cmd/messages_text.go

@@ -12,6 +12,7 @@ import (
 	"github.com/atotto/clipboard"
 	"github.com/ayn2op/discordo/internal/config"
 	"github.com/ayn2op/discordo/internal/markdown"
+	"github.com/ayn2op/discordo/internal/ui"
 	"github.com/diamondburned/arikawa/v3/discord"
 	"github.com/diamondburned/ningen/v3/discordmd"
 	"github.com/gdamore/tcell/v2"
@@ -330,10 +331,9 @@ func (mt *MessagesText) open() {
 		} else {
 			go openURL(msg.Attachments[0].URL)
 		}
-		return
+	} else {
+		mt.showUrlSelector(urls, msg.Attachments)
 	}
-
-	showSelector(mt, urls, msg.Attachments)
 }
 
 func extractURLs(content string) []string {
@@ -359,17 +359,43 @@ func extractURLs(content string) []string {
 	return urls
 }
 
-func showSelector(mt *MessagesText, urls []string, attachments []discord.Attachment) {
+func (mt *MessagesText) showUrlSelector(urls []string, attachments []discord.Attachment) {
+	done := func() {
+		app.pages.RemovePage("list").SwitchToPage("flex")
+		app.SetFocus(app.messagesText)
+	}
+
 	list := tview.NewList().
 		SetWrapAround(true).
 		SetHighlightFullLine(true).
-		ShowSecondaryText(false)
+		ShowSecondaryText(false).
+		SetDoneFunc(done)
+
+	p := mt.cfg.Theme.BorderPadding
+	list.
+		SetBorder(mt.cfg.Theme.Border).
+		SetBorderColor(tcell.GetColor(mt.cfg.Theme.BorderColor)).
+		SetBorderPadding(p[0], p[1], p[2], p[3]).
+		SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
+			switch event.Name() {
+			case mt.cfg.Keys.MessagesText.SelectPrevious:
+				return tcell.NewEventKey(tcell.KeyUp, 0, tcell.ModNone)
+			case mt.cfg.Keys.MessagesText.SelectNext:
+				return tcell.NewEventKey(tcell.KeyDown, 0, tcell.ModNone)
+			case mt.cfg.Keys.MessagesText.SelectFirst:
+				return tcell.NewEventKey(tcell.KeyHome, 0, tcell.ModNone)
+			case mt.cfg.Keys.MessagesText.SelectLast:
+				return tcell.NewEventKey(tcell.KeyEnd, 0, tcell.ModNone)
+			}
+
+			return event
+		})
 
 	for i, a := range attachments {
 		attachment := a
 		list.AddItem(a.Filename, "", rune('a'+i), func() {
 			go openURL(attachment.URL)
-			app.SetRoot(app.flex, true)
+			done()
 		})
 	}
 
@@ -377,53 +403,13 @@ func showSelector(mt *MessagesText, urls []string, attachments []discord.Attachm
 		urlCopy := url
 		list.AddItem(url, "", rune('1'+i), func() {
 			go openURL(urlCopy)
-			app.SetRoot(app.flex, true)
+			done()
 		})
 	}
 
-	list.AddItem("Cancel", "", 'q', func() {
-		app.SetRoot(app.flex, true)
-	})
-
-	list.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
-		switch event.Name() {
-		case mt.cfg.Keys.MessagesText.SelectPrevious:
-			return tcell.NewEventKey(tcell.KeyUp, 0, tcell.ModNone)
-		case mt.cfg.Keys.MessagesText.SelectNext:
-			return tcell.NewEventKey(tcell.KeyDown, 0, tcell.ModNone)
-		case mt.cfg.Keys.MessagesText.SelectFirst:
-			list.SetCurrentItem(0)
-			return nil
-		case mt.cfg.Keys.MessagesText.SelectLast:
-			list.SetCurrentItem(list.GetItemCount() - 1)
-			return nil
-		case "Escape":
-			app.SetRoot(app.flex, true)
-			return nil
-		}
-		return event
-	})
-
-	height := len(urls) + len(attachments) + 1
-	maxHeight := 20
-	if height > maxHeight {
-		height = maxHeight
-	}
-
-	modal := createCenteredModal(list, height, 60)
-
-	app.SetRoot(modal, true)
-	app.SetFocus(list)
-}
-
-func createCenteredModal(p tview.Primitive, height, width int) tview.Primitive {
-	return tview.NewFlex().
-		AddItem(nil, 0, 1, false).
-		AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
-			AddItem(nil, 0, 1, false).
-			AddItem(p, height, 1, true).
-			AddItem(nil, 0, 1, false), width, 1, true).
-		AddItem(nil, 0, 1, false)
+	app.pages.
+		AddAndSwitchToPage("list", ui.Centered(list, 0, 0), true).
+		ShowPage("flex")
 }
 
 func openURL(url string) {

+ 2 - 8
internal/login/form.go

@@ -7,6 +7,7 @@ import (
 
 	"github.com/ayn2op/discordo/internal/config"
 	"github.com/ayn2op/discordo/internal/consts"
+	"github.com/ayn2op/discordo/internal/ui"
 	"github.com/diamondburned/arikawa/v3/api"
 	"github.com/diamondburned/arikawa/v3/utils/httputil"
 	"github.com/rivo/tview"
@@ -105,13 +106,6 @@ func (f *Form) onError(err error) {
 			f.RemovePage("modal").SwitchToPage("form")
 		})
 	f.
-		AddAndSwitchToPage("modal", centered(modal, 0, 0), true).
+		AddAndSwitchToPage("modal", ui.Centered(modal, 0, 0), true).
 		ShowPage("form")
 }
-
-func centered(p tview.Primitive, width, height int) tview.Primitive {
-	return tview.NewGrid().
-		SetColumns(0, width, 0).
-		SetRows(0, height, 0).
-		AddItem(p, 1, 1, 1, 1, 0, 0, true)
-}

+ 10 - 0
internal/ui/util.go

@@ -0,0 +1,10 @@
+package ui
+
+import "github.com/rivo/tview"
+
+func Centered(p tview.Primitive, width, height int) tview.Primitive {
+	return tview.NewGrid().
+		SetColumns(0, width, 0).
+		SetRows(0, height, 0).
+		AddItem(p, 1, 1, 1, 1, 0, 0, true)
+}