Files
pi-im/main.go.copy
2025-08-04 10:05:43 +01:00

211 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"image/color"
"log"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
_ "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
_ "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
_ "github.com/mbaklor/fyne-catppuccin"
_ "fyne.io/x/fyne/theme"
"mellium.im/xmpp/jid"
"mellium.im/xmpp/muc"
"mellium.im/xmpp/stanza"
oasisSdk "pain.agency/oasis-sdk"
)
type Message struct {
Author string
Content string
}
var Messages []Message
type myTheme struct{}
func (m myTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color {
return theme.DefaultTheme().Color(name, variant)
}
func (m myTheme) Icon(name fyne.ThemeIconName) fyne.Resource {
return theme.DefaultTheme().Icon(name)
}
func (m myTheme) Font(style fyne.TextStyle) fyne.Resource {
return theme.DefaultTheme().Font(style)
}
func (m myTheme) Size(name fyne.ThemeSizeName) float32 {
if name == theme.SizeNameHeadingText {
return 18
}
return theme.DefaultTheme().Size(name)
}
var scrollDownOnNewMessage bool = true
func addMessageToView() fyne.CanvasObject {
author := widget.NewLabel("")
author.TextStyle.Bold = true
content := widget.NewLabel("")
content.Wrapping = fyne.TextWrapWord
return container.NewVBox(author, content)
}
func main() {
login := oasisSdk.LoginInfo{
Host: "sunglocto.net:5222",
User: "bot2@sunglocto.net",
Password: "iloverobots",
DisplayName: "bot2",
TLSoff: false,
StartTLS: true,
MucsToJoin: []string{"ringen@muc.isekai.rocks"},
}
scroller := widget.NewList(
func() int {
return len(Messages)
}, func() fyne.CanvasObject {
return addMessageToView()
}, func(i widget.ListItemID, co fyne.CanvasObject) {
co.(*fyne.Container).Objects[0].(*widget.Label).SetText(Messages[i].Author)
co.(*fyne.Container).Objects[1].(*widget.Label).SetText(Messages[i].Content)
})
client, err := oasisSdk.CreateClient(
&login,
func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) {
myMessage := Message{}
myMessage.Author = msg.From.Resourcepart()
myMessage.Content = *msg.CleanedBody
Messages = append(Messages, myMessage)
if scrollDownOnNewMessage {
fyne.Do(func() {
scroller.ScrollToBottom()
})
}
},
func(client *oasisSdk.XmppClient, _ *muc.Channel, msg *oasisSdk.XMPPChatMessage) {
myMessage := Message{}
myMessage.Author = msg.From.Resourcepart()
myMessage.Content = *msg.CleanedBody
Messages = append(Messages, myMessage)
if scrollDownOnNewMessage {
fyne.Do(func() {
scroller.ScrollToBottom()
})
}
},
func(_ *oasisSdk.XmppClient, from jid.JID, state oasisSdk.ChatState) {
//fromStr := from.String()
switch state {
case oasisSdk.ChatStateActive:
case oasisSdk.ChatStateComposing:
case oasisSdk.ChatStatePaused:
case oasisSdk.ChatStateInactive:
case oasisSdk.ChatStateGone:
default:
}
},
func(_ *oasisSdk.XmppClient, from jid.JID, id string) {
fmt.Printf("Delivered %s to %s", id, from.String())
},
func(_ *oasisSdk.XmppClient, from jid.JID, id string) {
fmt.Printf("%s has seen %s", from.String(), id)
},
)
if err != nil {
log.Fatalln("Could not create client - " + err.Error())
}
go func() {
err = client.Connect()
if err != nil {
log.Fatalln("Could not connect - " + err.Error())
}
}()
a := app.New()
a.Settings().SetTheme(myTheme{})
w := a.NewWindow("pi")
w.Resize(fyne.NewSize(500, 500))
entry := widget.NewMultiLineEntry()
entry.SetPlaceHolder("Say something, you know you want to.")
sendbtn := widget.NewButton("Send", func() {
text := entry.Text
go func() {
msg := oasisSdk.XMPPChatMessage{ // TODO: Remove hack when oasisSdk adds message sending (hopefully xd)
Message: stanza.Message{
To: jid.MustParse("ringen@muc.isekai.rocks"), //FIXME
Type: stanza.GroupChatMessage, //FIXME
},
ChatMessageBody: oasisSdk.ChatMessageBody{
Body: &text,
},
}
err := client.Session.Encode(client.Ctx, msg)
if err != nil {
dialog.ShowError(err, w)
}
}()
entry.SetText("")
})
mit := fyne.NewMenuItem("About pi", func() {
dialog.ShowInformation("About pi", "the XMPP client from hell\n\npi is an experimental XMPP client\nwritten by Sunglocto in Go.", w)
})
mia := fyne.NewMenuItem("Configure message view", func() {
ch := widget.NewCheck("", func(b bool) {})
ch.Checked = scrollDownOnNewMessage
scrollView := widget.NewFormItem("Scroll to bottom on new message", ch)
items := []*widget.FormItem{
scrollView,
}
dialog.ShowForm("Configure message view", "Apply", "Cancel", items, func(b bool) {
if b {
scrollDownOnNewMessage = ch.Checked
}
}, w)
})
mib := fyne.NewMenuItem("Join a room", func() {
nick := widget.NewEntry()
room := widget.NewEntry()
items := []*widget.FormItem{
widget.NewFormItem("Nick", nick),
widget.NewFormItem("MUC address", room),
}
dialog.ShowForm("Join a MUC", "Join", "Cancel", items, func(b bool) {
if b {
fmt.Println("attempting to join MUC")
fmt.Println(nick)
fmt.Println(room)
go func() {
client.MucClient.Join(client.Ctx, jid.MustParse(room.Text), client.Session, nil)
}()
}
}, w)
})
menu_help := fyne.NewMenu("π", mit)
menu_changeroom := fyne.NewMenu("β", mib)
menu_configureview := fyne.NewMenu("γ", mia)
ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview)
w.SetMainMenu(ma)
tabs := container.NewAppTabs(container.NewTabItem("pi", widget.NewLabel("pi\n\nthe XMPP client from hell")), container.NewTabItem("chat", scroller))
w.SetContent(container.NewVSplit(tabs, container.NewHSplit(entry, sendbtn))) // TODO: Add send message functionality
w.ShowAndRun()
}