1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
wtf/modules/twitter/widget.go
Sean Smith 5abd701b40 Decouple modules from global config
Rather than referencing wtc.Config, instead pass the global config
Also, look up config for the module early and pass that in sooner, to deal with fewer long paths and get rid of the
ConfigKey variable
2019-04-27 22:26:23 -04:00

180 lines
4.1 KiB
Go

package twitter
import (
"fmt"
"html"
"regexp"
"github.com/dustin/go-humanize"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf"
)
const HelpText = `
Keyboard commands for Twitter:
/: Show/hide this help window
h: Previous Twitter name
l: Next Twitter name
o: Open the Twitter handle in a browser
arrow left: Previous Twitter name
arrow right: Next Twitter name
`
type Widget struct {
wtf.HelpfulWidget
wtf.MultiSourceWidget
wtf.TextWidget
app *tview.Application
client *Client
idx int
settings *Settings
sources []string
}
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common.Name, "screenName", "screenNames"),
TextWidget: wtf.NewTextWidget(app, settings.common, true),
app: app,
idx: 0,
settings: settings,
}
widget.HelpfulWidget.SetView(widget.View)
widget.LoadSources()
widget.SetDisplayFunction(widget.display)
widget.client = NewClient(settings)
widget.View.SetBorderPadding(1, 1, 1, 1)
widget.View.SetWrap(true)
widget.View.SetWordWrap(true)
widget.View.SetInputCapture(widget.keyboardIntercept)
return &widget
}
/* -------------------- Exported Functions -------------------- */
// Refresh is called on the interval and refreshes the data
func (widget *Widget) Refresh() {
widget.app.QueueUpdateDraw(func() {
widget.display()
})
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) display() {
widget.client.screenName = widget.CurrentSource()
tweets := widget.client.Tweets()
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("Twitter - [green]@%s[white]", widget.CurrentSource())))
if len(tweets) == 0 {
str := fmt.Sprintf("\n\n\n%s", wtf.CenterText("[blue]No Tweets[white]", 50))
widget.View.SetText(str)
return
}
_, _, width, _ := widget.View.GetRect()
str := widget.settings.common.SigilStr(len(widget.Sources), widget.Idx, width-2) + "\n"
for _, tweet := range tweets {
str = str + widget.format(tweet)
}
widget.View.SetText(str)
}
// If the tweet's Username is the same as the account we're watching, no
// need to display the username
func (widget *Widget) displayName(tweet Tweet) string {
if widget.CurrentSource() == tweet.User.ScreenName {
return ""
}
return tweet.User.ScreenName
}
func (widget *Widget) formatText(text string) string {
result := text
// Convert HTML entities
result = html.UnescapeString(result)
// RT indicator
rtRegExp := regexp.MustCompile(`^RT`)
result = rtRegExp.ReplaceAllString(result, "[olive]${0}[white::-]")
// @name mentions
atRegExp := regexp.MustCompile(`@[0-9A-Za-z_]*`)
result = atRegExp.ReplaceAllString(result, "[blue]${0}[white]")
// HTTP(S) links
linkRegExp := regexp.MustCompile(`http[s:\/.0-9A-Za-z]*`)
result = linkRegExp.ReplaceAllString(result, "[lightblue::u]${0}[white::-]")
// Hash tags
hashRegExp := regexp.MustCompile(`#[0-9A-Za-z_]*`)
result = hashRegExp.ReplaceAllString(result, "[yellow]${0}[white]")
return result
}
func (widget *Widget) format(tweet Tweet) string {
body := widget.formatText(tweet.Text)
name := widget.displayName(tweet)
var attribution string
if name == "" {
attribution = humanize.Time(tweet.Created())
} else {
attribution = fmt.Sprintf(
"%s, %s",
name,
humanize.Time(tweet.Created()),
)
}
return fmt.Sprintf("%s\n[grey]%s[white]\n\n", body, attribution)
}
func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
switch string(event.Rune()) {
case "/":
widget.ShowHelp()
return nil
case "h":
widget.Prev()
return nil
case "l":
widget.Next()
return nil
case "o":
wtf.OpenFile(widget.currentSourceURI())
return nil
}
switch event.Key() {
case tcell.KeyLeft:
widget.Prev()
return nil
case tcell.KeyRight:
widget.Next()
return nil
default:
return event
}
}
func (widget *Widget) currentSourceURI() string {
src := "https://twitter.com/" + widget.CurrentSource()
return src
}