// Copyright (c) 2024, Přemysl Eric Janouch
// SPDX-License-Identifier: 0BSD package main import ( "bufio" "context" "encoding/binary" "flag" "fmt" "io" "log" "net" "net/url" "os" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" ) var ( debug = flag.Bool("debug", false, "enable debug output") projectName = "xA" projectVersion = "?" addressConnect string ) // ----------------------------------------------------------------------------- func relayReadFrame(r io.Reader) []byte { var length uint32 if err := binary.Read(r, binary.BigEndian, &length); err != nil { log.Println("Event receive failed: " + err.Error()) return nil } b := make([]byte, length) if _, err := io.ReadFull(r, b); err != nil { log.Println("Event receive failed: " + err.Error()) return nil } if *debug { log.Printf(" %v\n", b) var m RelayEventMessage if after, ok := m.ConsumeFrom(b); !ok { log.Println("Event deserialization failed") return nil } else if len(after) != 0 { log.Println("Event deserialization failed: trailing data") return nil } j, err := m.MarshalJSON() if err != nil { log.Println("Event marshalling failed: " + err.Error()) return nil } log.Printf("<- %s\n", j) } return b } func relayMakeReceiver(ctx context.Context, conn net.Conn) <-chan []byte { // The usual event message rarely gets above 1 kilobyte, // thus this is set to buffer up at most 1 megabyte or so. p := make(chan []byte, 1000) r := bufio.NewReaderSize(conn, 65536) go func() { defer close(p) for { j := relayReadFrame(r) if j == nil { return } select { case p <- j: case <-ctx.Done(): return } } }() return p } func main() { flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [OPTION...] CONNECT\n\n", os.Args[0]) flag.PrintDefaults() } flag.Parse() if flag.NArg() < 1 || flag.NArg() > 1 { flag.Usage() os.Exit(1) } addressConnect = flag.Arg(0) a := app.New() w := a.NewWindow(projectName) // TODO(p): There should also be a widget.NewLabel() next to the entry. // - Probably another Border, even though this seems odd. var ( richtext = widget.NewRichText() richscroll = container.NewVScroll(richtext) entry = widget.NewMultiLineEntry() ) w.SetContent(container.NewBorder(nil, entry, nil, nil, richscroll)) testURL, _ := url.Parse("https://x.com") richtext.Segments = []widget.RichTextSegment{ &widget.ParagraphSegment{Texts: []widget.RichTextSegment{ &widget.TextSegment{Text: "Test"}, &widget.HyperlinkSegment{Text: "X", URL: testURL}, &widget.TextSegment{ Text: " is a website, certainly", Style: widget.RichTextStyleInline, }, }}, &widget.TextSegment{Style: widget.RichTextStyleParagraph}, &widget.SeparatorSegment{}, &widget.TextSegment{Text: "Paragraph"}, } richtext.Wrapping = fyne.TextWrapWord richtext.Refresh() w.ShowAndRun() }