diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 113 |
1 files changed, 113 insertions, 0 deletions
@@ -0,0 +1,113 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + + "golang.org/x/net/html" + + "gioui.org/app" + "gioui.org/font/gofont" + "gioui.org/io/system" + "gioui.org/layout" + "gioui.org/op" + "gioui.org/unit" + "gioui.org/widget/material" +) + +// FeedItem represents a single RSS entry +type FeedItem struct { + Title string + Link string +} + +// Simple RSS fetcher (parses only <item><title> and <link>) +func fetchRSS(url string) ([]FeedItem, error) { + resp, err := http.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + doc, err := html.Parse(resp.Body) + if err != nil { + return nil, err + } + + var items []FeedItem + var f func(*html.Node) + f = func(n *html.Node) { + if n.Type == html.ElementNode && n.Data == "item" { + var item FeedItem + for c := n.FirstChild; c != nil; c = c.NextSibling { + if c.Type == html.ElementNode { + switch c.Data { + case "title": + if c.FirstChild != nil { + item.Title = c.FirstChild.Data + } + case "link": + if c.FirstChild != nil { + item.Link = c.FirstChild.Data + } + } + } + } + items = append(items, item) + } + for c := n.FirstChild; c != nil; c = c.NextSibling { + f(c) + } + } + f(doc) + return items, nil +} + +func main() { + go func() { + w := app.NewWindow( + app.Title("MiniRSS"), + app.Size(unit.Dp(400), unit.Dp(600)), + ) + if err := loop(w); err != nil { + log.Fatal(err) + } + os.Exit(0) + }() + app.Main() +} + +func loop(w *app.Window) error { + th := material.NewTheme(gofont.Collection()) + + // Replace with any RSS feed you want to test + feedURL := "https://xkcd.com/atom.xml" + items, err := fetchRSS(feedURL) + if err != nil { + return fmt.Errorf("failed to fetch RSS: %w", err) + } + + list := layout.List{ + Axis: layout.Vertical, + } + + var ops op.Ops + for { + e := <-w.Events() + switch e := e.(type) { + case system.DestroyEvent: + return e.Err + case system.FrameEvent: + gtx := layout.NewContext(&ops, e) + + list.Layout(gtx, len(items), func(gtx layout.Context, i int) layout.Dimensions { + title := material.H6(th, items[i].Title) + return title.Layout(gtx) + }) + + e.Frame(gtx.Ops) + } + } +} |
