summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui.go76
-rw-r--r--limox.go99
-rw-r--r--main.go228
-rw-r--r--xmpp.go73
4 files changed, 248 insertions, 228 deletions
diff --git a/gui.go b/gui.go
new file mode 100644
index 0000000..8e1f30d
--- /dev/null
+++ b/gui.go
@@ -0,0 +1,76 @@
+package main
+
+import (
+ "image/color"
+ "log"
+
+ "gioui.org/io/system"
+ "gioui.org/layout"
+ "gioui.org/text"
+ "gioui.org/widget/material"
+)
+
+type GuiEvent uint8
+
+const (
+ Disconnect GuiEvent = iota
+)
+
+func (l *Limox) draw(e system.FrameEvent) {
+ gtx := layout.NewContext(&l.Operations, e)
+
+ flex := layout.Flex{
+ Axis: layout.Vertical,
+ Spacing: layout.SpaceBetween,
+ }
+
+ flex.Layout(gtx,
+ layout.Rigid(
+ func(gtx layout.Context) layout.Dimensions {
+ h2 := material.H2(l.Theme, "LimoX")
+ h2.Color = color.NRGBA{R: 20, G: 20, B: 20, A: 255}
+ h2.Alignment = text.Middle
+ return h2.Layout(gtx)
+ },
+ ),
+ layout.Rigid(
+ func(gtx layout.Context) layout.Dimensions {
+ jid := material.Editor(l.Theme, &l.JidEditor, "user@example.com")
+ jid.Editor.Alignment = text.Middle
+ return jid.Layout(gtx)
+ },
+ ),
+ layout.Rigid(
+ func(gtx layout.Context) layout.Dimensions {
+ pwd := material.Editor(l.Theme, &l.PwdEditor, "mySafePassword")
+ pwd.Editor.Alignment = text.Middle
+ pwd.Editor.Mask = '*'
+ return pwd.Layout(gtx)
+ },
+ ),
+ layout.Rigid(
+ func(gtx layout.Context) layout.Dimensions {
+ btn := material.Button(l.Theme, &l.MainButton,
+ l.buttonLabel())
+ return btn.Layout(gtx)
+ },
+ ),
+ )
+
+ e.Frame(gtx.Ops)
+}
+
+func (l *Limox) buttonLabel() string {
+ var label string
+ switch l.State {
+ case Disconnected:
+ label = "Connect"
+ case Connecting:
+ label = "Abort"
+ case Connected:
+ label = "Disconnect"
+ default:
+ log.Fatalf("Unknown Limox state '%d'\n", l.State)
+ }
+ return label
+}
diff --git a/limox.go b/limox.go
new file mode 100644
index 0000000..3ca21b3
--- /dev/null
+++ b/limox.go
@@ -0,0 +1,99 @@
+package main
+
+import (
+ "log"
+ "reflect"
+
+ "gioui.org/app"
+ "gioui.org/font/gofont"
+ "gioui.org/io/system"
+ "gioui.org/op"
+ "gioui.org/unit"
+ "gioui.org/widget"
+ "gioui.org/widget/material"
+)
+
+type LimoxState uint8
+
+const (
+ Disconnected LimoxState = iota
+ Connecting
+ Connected
+)
+
+type Limox struct {
+ JidEditor widget.Editor
+ PwdEditor widget.Editor
+ MainButton widget.Clickable
+ XmppEvents chan any
+ GuiEvents chan GuiEvent
+ State LimoxState
+ Window *app.Window
+ Operations op.Ops
+ Theme *material.Theme
+}
+
+func NewLimox() Limox {
+ return Limox{
+ Window: app.NewWindow(
+ app.Title("LimoX"),
+ app.Size(unit.Dp(400), unit.Dp(600)),
+ ),
+ Operations: op.Ops{},
+ Theme: material.NewTheme(gofont.Collection()),
+ XmppEvents: make(chan any),
+ GuiEvents: make(chan GuiEvent),
+ State: Disconnected,
+ }
+}
+
+func (l *Limox) run() error {
+ for {
+ select {
+ case e := <-l.Window.Events():
+ switch e := e.(type) {
+ case system.DestroyEvent:
+ return e.Err
+ case system.FrameEvent:
+ if l.MainButton.Clicked() {
+ l.buttonCallback()
+ }
+ l.draw(e)
+ }
+ case ev := <-l.XmppEvents:
+ switch ev.(type) {
+ case error:
+ log.Print(ev)
+ l.State = Disconnected
+ case XmppEvent:
+ switch ev {
+ case XmppDisconnect:
+ l.State = Disconnected
+ case XmppConnect:
+ l.State = Connected
+ default:
+ log.Fatalf("Unknown XmppEvent '%d'\n", ev)
+ }
+ default:
+ log.Fatalf("Unknown event type '%s'.\n", reflect.TypeOf(ev))
+ }
+ l.Window.Invalidate()
+ }
+ }
+}
+
+func (l *Limox) buttonCallback() {
+ switch l.State {
+ case Disconnected:
+ log.Println("Starting connection establishment")
+ go l.xmpp(l.JidEditor.Text(), l.PwdEditor.Text())
+ l.State = Connecting
+ case Connecting:
+ log.Println("Aborted connection establishment")
+ l.State = Disconnected
+ case Connected:
+ log.Println("Disconnected")
+ l.GuiEvents <- Disconnect
+ l.State = Disconnected
+ }
+}
diff --git a/main.go b/main.go
index 6c33ad4..561b7dd 100644
--- a/main.go
+++ b/main.go
@@ -1,56 +1,12 @@
package main
import (
- "image/color"
"log"
- "net"
"os"
- "reflect"
"gioui.org/app"
- "gioui.org/font/gofont"
- "gioui.org/io/system"
- "gioui.org/layout"
- "gioui.org/op"
- "gioui.org/text"
- "gioui.org/unit"
- "gioui.org/widget"
- "gioui.org/widget/material"
)
-type XmppEvent uint8
-
-const (
- XmppDisconnect XmppEvent = iota
- XmppConnect
-)
-
-type GuiEvent uint8
-
-const (
- Disconnect GuiEvent = iota
-)
-
-type LimoxState uint8
-
-const (
- Disconnected LimoxState = iota
- Connecting
- Connected
-)
-
-type Limox struct {
- JidEditor widget.Editor
- PwdEditor widget.Editor
- MainButton widget.Clickable
- XmppEvents chan any
- GuiEvents chan GuiEvent
- State LimoxState
- Window *app.Window
- Operations op.Ops
- Theme *material.Theme
-}
-
func main() {
limox := NewLimox()
@@ -64,187 +20,3 @@ func main() {
app.Main()
}
-
-func NewLimox() Limox {
- return Limox{
- Window: app.NewWindow(
- app.Title("LimoX"),
- app.Size(unit.Dp(400), unit.Dp(600)),
- ),
- Operations: op.Ops{},
- Theme: material.NewTheme(gofont.Collection()),
- XmppEvents: make(chan any),
- GuiEvents: make(chan GuiEvent),
- State: Disconnected,
- }
-}
-
-func (l *Limox) run() error {
- for {
- select {
- case e := <-l.Window.Events():
- switch e := e.(type) {
- case system.DestroyEvent:
- return e.Err
- case system.FrameEvent:
- if l.MainButton.Clicked() {
- l.buttonCallback()
- }
- l.draw(e)
- }
- case ev := <-l.XmppEvents:
- switch ev.(type) {
- case error:
- log.Print(ev)
- l.State = Disconnected
- case XmppEvent:
- switch ev {
- case XmppDisconnect:
- l.State = Disconnected
- case XmppConnect:
- l.State = Connected
- default:
- log.Fatalf("Unknown XmppEvent '%d'\n", ev)
- }
- default:
- log.Fatalf("Unknown event type '%s'.\n", reflect.TypeOf(ev))
- }
- l.Window.Invalidate()
- }
- }
-}
-
-func (l *Limox) buttonCallback() {
- switch l.State {
- case Disconnected:
- log.Println("Starting connection establishment")
- go l.xmpp(l.JidEditor.Text(), l.PwdEditor.Text())
- l.State = Connecting
- case Connecting:
- log.Println("Aborted connection establishment")
- l.State = Disconnected
- case Connected:
- log.Println("Disconnected")
- l.GuiEvents <- Disconnect
- l.State = Disconnected
- }
-}
-
-func (l *Limox) xmpp(jid string, pwd string) {
- log.Printf("JID: '%s' PWD: '%s'\n", jid, pwd)
-
- domain := domainpart(jid)
- log.Printf("Domain: '%s'\n", domain)
-
- tcpServer, err := net.ResolveTCPAddr("tcp", domain+":"+"5222")
- if err != nil {
- l.XmppEvents <- err
- return
- }
- log.Printf("Server: %s\n", tcpServer)
-
- conn, err := net.DialTCP("tcp", nil, tcpServer)
- if err != nil {
- l.XmppEvents <- err
- return
- }
- l.XmppEvents <- XmppConnect
-
- var closing bool = false
- for {
- ev := <-l.GuiEvents
- switch ev {
- case Disconnect:
- closing = true
- default:
- log.Fatalf("Unknown GuiEvent '%d'!\n", ev)
- }
- if closing {
- break
- }
- }
-
- conn.Close()
- l.XmppEvents <- XmppDisconnect
-}
-
-// domainpart extracts the domain name from a JID / XMPP address. See
-// https://datatracker.ietf.org/doc/html/rfc7622#section-3.2 for details.
-func domainpart(jid string) string {
- list := []rune(jid)
-
- for i, v := range list {
- if v == '/' {
- list = list[:i]
- break
- }
- }
-
- for i, v := range list {
- if v == '@' {
- list = list[i+1:]
- break
- }
- }
-
- return string(list)
-}
-
-func (l *Limox) draw(e system.FrameEvent) {
- gtx := layout.NewContext(&l.Operations, e)
-
- flex := layout.Flex{
- Axis: layout.Vertical,
- Spacing: layout.SpaceBetween,
- }
-
- flex.Layout(gtx,
- layout.Rigid(
- func(gtx layout.Context) layout.Dimensions {
- h2 := material.H2(l.Theme, "LimoX")
- h2.Color = color.NRGBA{R: 20, G: 20, B: 20, A: 255}
- h2.Alignment = text.Middle
- return h2.Layout(gtx)
- },
- ),
- layout.Rigid(
- func(gtx layout.Context) layout.Dimensions {
- jid := material.Editor(l.Theme, &l.JidEditor, "user@example.com")
- jid.Editor.Alignment = text.Middle
- return jid.Layout(gtx)
- },
- ),
- layout.Rigid(
- func(gtx layout.Context) layout.Dimensions {
- pwd := material.Editor(l.Theme, &l.PwdEditor, "mySafePassword")
- pwd.Editor.Alignment = text.Middle
- pwd.Editor.Mask = '*'
- return pwd.Layout(gtx)
- },
- ),
- layout.Rigid(
- func(gtx layout.Context) layout.Dimensions {
- btn := material.Button(l.Theme, &l.MainButton,
- l.buttonLabel())
- return btn.Layout(gtx)
- },
- ),
- )
-
- e.Frame(gtx.Ops)
-}
-
-func (l *Limox) buttonLabel() string {
- var label string
- switch l.State {
- case Disconnected:
- label = "Connect"
- case Connecting:
- label = "Abort"
- case Connected:
- label = "Disconnect"
- default:
- log.Fatalf("Unknown Limox state '%d'\n", l.State)
- }
- return label
-}
diff --git a/xmpp.go b/xmpp.go
new file mode 100644
index 0000000..8078c1a
--- /dev/null
+++ b/xmpp.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+ "log"
+ "net"
+)
+
+type XmppEvent uint8
+
+const (
+ XmppDisconnect XmppEvent = iota
+ XmppConnect
+)
+
+func (l *Limox) xmpp(jid string, pwd string) {
+ log.Printf("JID: '%s' PWD: '%s'\n", jid, pwd)
+
+ domain := domainpart(jid)
+ log.Printf("Domain: '%s'\n", domain)
+
+ tcpServer, err := net.ResolveTCPAddr("tcp", domain+":"+"5222")
+ if err != nil {
+ l.XmppEvents <- err
+ return
+ }
+ log.Printf("Server: %s\n", tcpServer)
+
+ conn, err := net.DialTCP("tcp", nil, tcpServer)
+ if err != nil {
+ l.XmppEvents <- err
+ return
+ }
+ l.XmppEvents <- XmppConnect
+
+ var closing bool = false
+ for {
+ ev := <-l.GuiEvents
+ switch ev {
+ case Disconnect:
+ closing = true
+ default:
+ log.Fatalf("Unknown GuiEvent '%d'!\n", ev)
+ }
+ if closing {
+ break
+ }
+ }
+
+ conn.Close()
+ l.XmppEvents <- XmppDisconnect
+}
+
+// domainpart extracts the domain name from a JID / XMPP address. See
+// https://datatracker.ietf.org/doc/html/rfc7622#section-3.2 for details.
+func domainpart(jid string) string {
+ list := []rune(jid)
+
+ for i, v := range list {
+ if v == '/' {
+ list = list[:i]
+ break
+ }
+ }
+
+ for i, v := range list {
+ if v == '@' {
+ list = list[i+1:]
+ break
+ }
+ }
+
+ return string(list)
+}