Skip to content

Commit

Permalink
reddit: add tui
Browse files Browse the repository at this point in the history
  • Loading branch information
azimut committed Apr 26, 2023
1 parent c16e7cb commit 55b1d3d
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 42 deletions.
22 changes: 14 additions & 8 deletions cmd/redditview/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/azimut/cli-view/internal/reddit"
"github.com/azimut/cli-view/internal/tui"
"github.com/fatih/color"
)

Expand All @@ -19,11 +20,13 @@ type options struct {
timeout time.Duration
useColors bool
userAgent string
useTUI bool
}

var opts options

func init() {
flag.BoolVar(&opts.useTUI, "x", false, "use TUI")
flag.BoolVar(&opts.useColors, "C", true, "use colors")
flag.DurationVar(&opts.timeout, "t", time.Second*5, "timeout in seconds")
flag.StringVar(&opts.userAgent, "A", "Reddit_Cli/0.1", "user agent to send to reddit")
Expand All @@ -44,18 +47,21 @@ func run(args []string, stdout io.Writer) error {
flag.Usage()
return errors.New("missing URL argument")
}

url := flag.Args()[0]
thread, err := reddit.Fetch(
url,
opts.userAgent,
int(opts.maxWidth),
int(opts.leftPadding),
opts.timeout,
)
thread, err := reddit.Fetch(url, opts.userAgent, opts.timeout)
if err != nil {
return err
}
fmt.Println(thread)
thread.Width = opts.maxWidth
thread.LeftPadding = opts.leftPadding

if opts.useTUI {
tui.RenderLoop(reddit.NewProgram(*thread))
} else {
fmt.Println(thread)
}

return nil
}

Expand Down
47 changes: 27 additions & 20 deletions internal/reddit/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/tidwall/gjson"
)

func Fetch(rawUrl, ua string, maxWidth, leftPadding int, timeout time.Duration) (*Thread, error) {
func Fetch(rawUrl, ua string, timeout time.Duration) (*Thread, error) {
url, err := effectiveUrl(rawUrl)
if err != nil {
return nil, err
Expand All @@ -22,12 +22,14 @@ func Fetch(rawUrl, ua string, maxWidth, leftPadding int, timeout time.Duration)
return nil, err
}

thread := toThread(rawJson, rawUrl, leftPadding, maxWidth)
thread := toThread(rawJson, rawUrl)

return thread, nil
}

func toThread(rawJson, rawUrl string, leftPadding, maxWidth int) *Thread {
func toThread(rawJson, rawUrl string) *Thread {
var thread Thread

post := gjson.Get(rawJson, "0.data.children.0.data")
op := Op{
author: post.Get("author").String(),
Expand All @@ -38,19 +40,21 @@ func toThread(rawJson, rawUrl string, leftPadding, maxWidth int) *Thread {
title: post.Get("title").String(),
upvotes: post.Get("ups").Int(),
url: post.Get("url").String(),
printing: Printing{maxWidth: maxWidth, leftPadding: leftPadding},
thread: &thread,
}
thread.op = op

if op.nComments <= 0 {
return &Thread{op: op}
return &thread
}

var comments []Comment
var json_comments []gjson.Result
json_comments := gjson.Get(rawJson, "1.data.children.#.data").Array()

json_comments = gjson.Get(rawJson, "1.data.children.#.data").Array()
for _, json_comment := range json_comments {
comment := toComment(json_comment, &op)

comment := toComment(json_comment)
comment.thread = &thread

// TODO: is probably a "More..." link
if comment.author == "" {
continue
Expand All @@ -59,18 +63,21 @@ func toThread(rawJson, rawUrl string, leftPadding, maxWidth int) *Thread {
if comment.author == "[deleted]" && len(comment.jsonReplies) == 0 {
continue
}
addReplies(&comment, &op)
comments = append(comments, comment)
}
return &Thread{
op: op,
comments: comments,

addReplies(&comment)
thread.comments = append(thread.comments, comment)
}

return &thread
}

func addReplies(parentComment *Comment, op *Op) {
func addReplies(parentComment *Comment) {

for _, jsonReply := range parentComment.jsonReplies {
comment := toComment(jsonReply, op)

comment := toComment(jsonReply)
comment.thread = parentComment.thread

// TODO: is probably a "More..." link
if comment.author == "" {
continue
Expand All @@ -79,20 +86,20 @@ func addReplies(parentComment *Comment, op *Op) {
if comment.author == "[deleted]" && len(comment.jsonReplies) == 0 {
continue
}

parentComment.replies = append(parentComment.replies, &comment)
addReplies(&comment, op)
addReplies(&comment)
}
}

func toComment(jsonComment gjson.Result, op *Op) Comment {
func toComment(jsonComment gjson.Result) Comment {
return Comment{
author: jsonComment.Get("author").String(),
createdUtc: jsonComment.Get("created_utc").Int(),
depth: jsonComment.Get("depth").Int(),
id: jsonComment.Get("id").String(),
jsonReplies: jsonComment.Get("replies.data.children.#.data").Array(),
message: jsonComment.Get("body").String(),
op: op,
score: jsonComment.Get("score").Int(),
}
}
10 changes: 5 additions & 5 deletions internal/reddit/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ var reMarkdownLink = regexp.MustCompile(`\[([^\]]+)\]\(([^\)]+)\)`)
var reHTTPLink = regexp.MustCompile(`[^\[^\(^m]http[s]?://[^\s^\[^\(^\[]+`)

func (op Op) String() (ret string) {
leftPadding := op.printing.leftPadding
maxWidth := op.printing.maxWidth
leftPadding := int(op.thread.LeftPadding)
maxWidth := int(op.thread.Width)
ret += "\n"
ret += fmt.Sprintf("title: %s\n", op.title)
ret += fmt.Sprintf(" self: %s\n", op.self)
Expand All @@ -44,16 +44,16 @@ func (op Op) String() (ret string) {
}

func (comment Comment) String() (ret string) {
leftPadding := comment.op.printing.leftPadding
maxWidth := comment.op.printing.maxWidth
leftPadding := int(comment.thread.LeftPadding)
maxWidth := int(comment.thread.Width)
commentLeftPadding := int(comment.depth)*leftPadding + 1
ret += fixupContent(
comment.message,
maxWidth,
commentLeftPadding,
)
author := comment.author
if comment.author == comment.op.author {
if comment.author == comment.thread.op.author {
author = color.New(AuthorColor).Sprint(comment.author)
}

Expand Down
41 changes: 41 additions & 0 deletions internal/reddit/tui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package reddit

import (
"fmt"

"github.com/azimut/cli-view/internal/tui"
tea "github.com/charmbracelet/bubbletea"
)

const rightPadding = 10

type Model struct {
render tui.Model
Thread
}

func NewProgram(thread Thread) *tea.Program {
return tea.NewProgram(Model{Thread: thread},
tea.WithAltScreen())
}

func (m Model) Init() tea.Cmd {
return nil
}

func (m Model) View() string {
return m.render.View()
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
m.render, cmd = m.render.Update(msg)
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.Width = 200
m.render.RawContent = fmt.Sprint(m)
m.Width = uint(msg.Width) - rightPadding
m.render.Viewport.SetContent(fmt.Sprint(m))
}
return m, cmd
}
15 changes: 6 additions & 9 deletions internal/reddit/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@ package reddit

import "github.com/tidwall/gjson"

type Printing struct {
leftPadding int
maxWidth int
}

type Thread struct {
comments []Comment
op Op
comments []Comment
op Op
Width uint
LeftPadding uint
}

type Op struct {
author string
createdUTC int64
nComments int64
printing Printing
self string
selftext string
thread *Thread
title string
upvotes int64
url string
Expand All @@ -31,7 +28,7 @@ type Comment struct {
id string
jsonReplies []gjson.Result
message string
op *Op
replies []*Comment
score int64
thread *Thread
}

0 comments on commit 55b1d3d

Please sign in to comment.