Implemented helpers and modal

pull/17/head
マリウス 3 years ago
parent 130bbe0ae3
commit e97a243b55
No known key found for this signature in database
GPG Key ID: 272ED814BF63261F

@ -85,7 +85,7 @@ func main() {
go func() {
time.Sleep(time.Second * 2)
TUI.SetView("mainscreen")
TUI.SetView("mainscreen", true)
TUI.Refresh()
}()
TUI.Launch()

@ -0,0 +1,55 @@
package tui
import (
"io/ioutil"
"log"
"os"
"os/exec"
"github.com/mrusme/superhighway84/models"
"github.com/rivo/tview"
)
func OpenArticle(app *tview.Application, article *models.Article) (models.Article, error) {
tmpFile, err := ioutil.TempFile(os.TempDir(), "article-*.txt")
if err != nil {
return *article, err
}
defer os.Remove(tmpFile.Name())
tmpContent := []byte(article.Body)
if _, err = tmpFile.Write(tmpContent); err != nil {
return *article, err
}
if err := tmpFile.Close(); err != nil {
return *article, err
}
wasSuspended := app.Suspend(func() {
cmd := exec.Command(os.Getenv("EDITOR"), tmpFile.Name())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
log.Println(err)
}
return
})
if wasSuspended == false {
return *article, err
}
tmpContent, err = os.ReadFile(tmpFile.Name())
if err != nil {
return *article, err
}
newArticle := *article
newArticle.Body = string(tmpContent)
return newArticle, nil
}

@ -1,11 +1,10 @@
package tui
import (
"io/ioutil"
"log"
"os"
"os/exec"
"fmt"
"sort"
"strings"
"time"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/models"
@ -135,6 +134,12 @@ func (mainscreen *Mainscreen) HandleInput(event *tcell.EventKey) (*tcell.EventKe
case tcell.KeyCtrlL:
mainscreen.T.App.SetFocus(mainscreen.Articles)
return nil
case tcell.KeyRune:
switch event.Rune() {
case 'r':
mainscreen.replyToArticle(mainscreen.ArticlesList[mainscreen.CurrentArticleSelected])
}
return nil
}
return event
@ -157,38 +162,43 @@ func(mainscreen *Mainscreen) selectHandler(item string)(func(int, string, string
case "group":
mainscreen.Refresh()
case "article":
article := *mainscreen.ArticlesList[index]
tmpFile, err := ioutil.TempFile(os.TempDir(), "article-*.txt")
if err != nil {
// TODO: Show modal with error
return
}
defer os.Remove(tmpFile.Name())
OpenArticle(mainscreen.T.App, mainscreen.ArticlesList[index])
}
}
}
tmpContent := []byte(article.Body)
if _, err = tmpFile.Write(tmpContent); err != nil {
// TODO: Show modal with error
return
}
func(mainscreen *Mainscreen) replyToArticle(article *models.Article) {
newArticle := models.NewArticle()
if err := tmpFile.Close(); err != nil {
// TODO: Show modal with error
return
}
newArticle.Subject = fmt.Sprintf("Re: %s", article.Subject)
newArticle.InReplyToID = article.ID
newArticle.Newsgroup = article.Newsgroup
// TODO: newArticle.From =
// TODO: newArticle.Organisation =
newArticle.Body = fmt.Sprintf("\nOn %s %s wrote:\n> %s", time.Unix(0, article.Date * int64(time.Millisecond)).Format("Mon Jan _2 15:04:05 2006"), article.From, strings.Replace(article.Body, "\n", "\n> ", -1))
mainscreen.T.App.Suspend(func() {
cmd := exec.Command(os.Getenv("EDITOR"), tmpFile.Name())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
log.Println(err)
}
return
})
}
_, err := OpenArticle(mainscreen.T.App, newArticle)
if err != nil {
// TODO: Show modal
return
}
// TODO: Write reply
mainscreen.T.ShowModal(
"Do you want to post this article?",
map[string]ModalButton{
"[Y]es": {
Rune: 'y',
Callback: func() {
return
},
},
"[N]o": {
Rune: 'n',
Callback: func() {
return
},
},
})
}

@ -4,6 +4,7 @@ import (
"embed"
"log"
"time"
"unicode"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/models"
@ -14,6 +15,10 @@ type TUI struct {
App *tview.Application
Views map[string]View
ActiveView string
Modal *tview.Modal
ModalVisible bool
ModalButtons map[string]ModalButton
}
type View interface {
@ -23,6 +28,11 @@ type View interface {
HandleInput(event *tcell.EventKey) (*tcell.EventKey)
}
type ModalButton struct {
Rune rune
Callback func()
}
func Init(embedfs *embed.FS, articlesDatasource *[]models.Article) (*TUI) {
t := new(TUI)
@ -51,6 +61,8 @@ func Init(embedfs *embed.FS, articlesDatasource *[]models.Article) (*TUI) {
t.Views["splashscreen"] = t.NewSplashscreen(&logoBytes)
t.Views["mainscreen"] = t.NewMainscreen(articlesDatasource)
t.ModalVisible = false
t.initInput()
return t
}
@ -65,7 +77,18 @@ func (t *TUI) initInput() {
t.App.Stop()
return nil
default:
return t.Views[t.ActiveView].HandleInput(event)
if t.ModalVisible == true && event.Key() == tcell.KeyRune {
for _, modalButton := range t.ModalButtons {
if unicode.ToLower(modalButton.Rune) == unicode.ToLower(event.Rune()) {
modalButton.Callback()
t.HideModal()
return nil
}
}
return nil
} else {
return t.Views[t.ActiveView].HandleInput(event)
}
}
})
}
@ -73,7 +96,7 @@ func (t *TUI) initInput() {
func (t *TUI) Launch() {
go func() {
time.Sleep(time.Millisecond * 200)
t.SetView("splashscreen")
t.SetView("splashscreen", true)
t.Refresh()
t.App.Draw()
}()
@ -83,13 +106,39 @@ func (t *TUI) Launch() {
}
}
func(t *TUI) SetView(name string) {
func(t *TUI) SetView(name string, redraw bool) {
t.ActiveView = name
t.App.SetRoot(t.Views[t.ActiveView].GetCanvas(), true)
t.App.Draw()
if redraw {
t.App.Draw()
}
}
func (t *TUI) Refresh() {
t.Views[t.ActiveView].Refresh()
}
func(t *TUI) ShowModal(text string, buttons map[string]ModalButton) {
t.Modal = tview.NewModal().
SetText(text)
// SetDoneFunc(func(buttonIndex int, buttonLabel string) {
// modalButton := buttons[buttonLabel]
// modalButton.Callback()
// t.HideModal()
// })
var buttonLabels []string
for buttonLabel := range buttons {
buttonLabels = append(buttonLabels, buttonLabel)
}
t.Modal.AddButtons(buttonLabels)
t.ModalVisible = true
t.ModalButtons = buttons
t.App.SetRoot(t.Modal, false).SetFocus(t.Modal)
}
func(t *TUI) HideModal() {
t.ModalVisible = false
t.SetView(t.ActiveView, false)
}

Loading…
Cancel
Save