Add rendering forms to messages, add configuring mucs, add getting muc affiliations, add a bunch of other stuff idk man check the diff
This commit is contained in:
1 parent
7a875f84a5
commit
34b885a770
19 files changed
+706
-101
No files matched your search
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/diamondburned/gotk4/pkg/gio/v2"
|
||||
"github.com/diamondburned/gotk4/pkg/glib/v2"
|
||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||
"github.com/diamondburned/gotk4/pkg/pango"
|
||||
"github.com/gen2brain/beeep"
|
||||
"github.com/go-analyze/charts"
|
||||
"github.com/google/uuid"
|
||||
@@ -83,11 +84,18 @@ var xmlLog *os.File
|
||||
// Basic roster
|
||||
var Roster = make(map[string]bool)
|
||||
|
||||
var config_filename = "lambda.toml"
|
||||
var app_id = "net.sunglocto.lambda"
|
||||
|
||||
func init() {
|
||||
beeep.AppName = loadedLocale["appName"]
|
||||
}
|
||||
|
||||
func main() {
|
||||
if os.Getenv("PROFILE") != "" {
|
||||
config_filename = fmt.Sprintf("lambda_%s.toml", os.Getenv("PROFILE"))
|
||||
app_id = "net.sunglocto.lambda." + os.Getenv("PROFILE")
|
||||
}
|
||||
|
||||
pingTimes = append(pingTimes, []float64{})
|
||||
p, err := ensureConfig()
|
||||
@@ -95,7 +103,7 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(filepath.Join(p, "lambda.toml"))
|
||||
b, err := os.ReadFile(filepath.Join(p, config_filename))
|
||||
if err != nil {
|
||||
dropToSignInPage(err)
|
||||
return
|
||||
@@ -169,6 +177,7 @@ func main() {
|
||||
|
||||
iqResp.Type = "error"
|
||||
iqResp.From = clientroot.Session.BindJid
|
||||
iqResp.Id = iq.Id
|
||||
|
||||
stanza_err := new(stanza.Err)
|
||||
stanza_err.Type = stanza.ErrorTypeCancel
|
||||
@@ -203,6 +212,7 @@ func main() {
|
||||
{Var: "urn:xmpp:ping"},
|
||||
{Var: "jabber:iq:oob"},
|
||||
{Var: "jabber:x:oob"},
|
||||
{Var: "jabber:x:data"},
|
||||
},
|
||||
}
|
||||
iqResp.Payload = &payload
|
||||
@@ -230,6 +240,7 @@ func main() {
|
||||
|
||||
iqResp.Type = "error"
|
||||
iqResp.From = clientroot.Session.BindJid
|
||||
iqResp.Id = iq.Id
|
||||
|
||||
stanza_err := new(stanza.Err)
|
||||
stanza_err.Type = stanza.ErrorTypeCancel
|
||||
@@ -360,8 +371,8 @@ func main() {
|
||||
// Handle read indicators
|
||||
marker := new(Marker)
|
||||
ok = m.Get(marker)
|
||||
if ok {
|
||||
_, ok := typed_tab.msg_refsOSID[marker.ID]
|
||||
if ok && !loadedConfig.CompactMode {
|
||||
_, ok := typed_tab.msg_refsOSID.Load(marker.ID)
|
||||
if ok {
|
||||
im := gtk.NewImage()
|
||||
im.SetPixelSize(20)
|
||||
@@ -381,10 +392,13 @@ func main() {
|
||||
go getAvatar(m.From, vu.Photo, im)
|
||||
}
|
||||
|
||||
ind, ok := typed_tab.msg_refsOSID[marker.ID]
|
||||
if ok {
|
||||
if ind.read_indicator != nil {
|
||||
ind.read_indicator.Append(im)
|
||||
uind, loaded := typed_tab.msg_refsOSID.Load(marker.ID)
|
||||
if loaded {
|
||||
ind, ok := uind.(*abMessage)
|
||||
if ok {
|
||||
if ind.read_indicator != nil {
|
||||
ind.read_indicator.Append(im)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -423,30 +437,21 @@ func main() {
|
||||
tab, ok := tabs.Load(originator)
|
||||
if ok {
|
||||
typed_tab := tab.(*chatTab)
|
||||
/*
|
||||
to_retract := ""
|
||||
refs := typed_tab.msg_refsID
|
||||
|
||||
// If it is a DM, then we use regular message ID. If it is a MUC, we use stanza id
|
||||
to_retract = sid.ID
|
||||
if typed_tab.isMuc && sid != nil {
|
||||
to_retract = sid.ID
|
||||
refs = typed_tab.msg_refsOSID
|
||||
}
|
||||
*/
|
||||
|
||||
msg, ok := typed_tab.msg_refsOSID[retraction.ID]
|
||||
umsg, ok := typed_tab.msg_refsOSID.Load(retraction.ID)
|
||||
if ok {
|
||||
lab := msg.label_ref
|
||||
glib.IdleAdd(func() {
|
||||
GenerateRetraction(lab, *retraction)
|
||||
})
|
||||
return
|
||||
msg, ok := umsg.(*abMessage)
|
||||
if ok {
|
||||
lab := msg.label_ref
|
||||
glib.IdleAdd(func() {
|
||||
GenerateRetraction(lab, *retraction)
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib.IdleAdd(func() {
|
||||
glib.IdleAddPriority(glib.PriorityLow, func() {
|
||||
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||
|
||||
tab, ok := tabs.Load(originator)
|
||||
@@ -472,9 +477,11 @@ func main() {
|
||||
|
||||
if valid && converted_successfully {
|
||||
mStatus.SetText(originator)
|
||||
typed_tab.msgs.Append(b)
|
||||
b.Append(ba)
|
||||
b.Append(gtk.NewSeparator(gtk.OrientationVertical))
|
||||
if typed_tab.msgs != nil {
|
||||
typed_tab.msgs.Append(b)
|
||||
b.Append(ba)
|
||||
b.Append(gtk.NewSeparator(gtk.OrientationVertical))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -496,6 +503,20 @@ func main() {
|
||||
ok = presence.Get(&mu)
|
||||
|
||||
if ok { // This is a presence stanza from a user in a MUC
|
||||
from_self, created := false, false
|
||||
for _, status := range mu.StatusCodes {
|
||||
if status.Code == "110" {
|
||||
from_self = true
|
||||
}
|
||||
|
||||
if status.Code == "201" {
|
||||
created = true
|
||||
}
|
||||
}
|
||||
|
||||
if from_self && created {
|
||||
showDialog("You have created a new MUC. In order for people to be able to join this MUC, you must first configure it. You can configure this MUC by clicking on the MUC button in the top right and then clicking 'Configre MUC'.", &window.Window)
|
||||
}
|
||||
|
||||
presence.Get(&ocu)
|
||||
id := JidMustParse(presence.From).Resource
|
||||
@@ -524,7 +545,7 @@ func main() {
|
||||
if presence.Type != "unavailable" {
|
||||
_, ok := typed_unit.Members.Load(id)
|
||||
if !ok && loadedConfig.ShowPresenceUpdates {
|
||||
glib.IdleAdd(func() {
|
||||
glib.IdleAddPriority(glib.PriorityLow, func() {
|
||||
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
||||
if ok {
|
||||
@@ -548,7 +569,7 @@ func main() {
|
||||
} else {
|
||||
typed_unit.Members.Delete(id)
|
||||
if loadedConfig.ShowPresenceUpdates {
|
||||
glib.IdleAdd(func() {
|
||||
glib.IdleAddPriority(glib.PriorityLow, func() {
|
||||
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
||||
if ok {
|
||||
@@ -604,7 +625,7 @@ func main() {
|
||||
|
||||
cm := xmpp.NewStreamManager(c, func(c xmpp.Sender) {
|
||||
fmt.Println("XMPP client connected")
|
||||
// client = c
|
||||
client = c
|
||||
// clientroot = c
|
||||
|
||||
go func() {
|
||||
@@ -810,7 +831,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
app := gtk.NewApplication("net.sunglocto.lambda", gio.ApplicationDefaultFlags)
|
||||
app := gtk.NewApplication(app_id, gio.ApplicationDefaultFlags)
|
||||
app.ConnectActivate(func() {
|
||||
activate(app)
|
||||
go conc()
|
||||
@@ -834,6 +855,86 @@ func activate(app *gtk.Application) {
|
||||
fileMenu := gio.NewMenu()
|
||||
fileMenu.Append(loadedLocale["joinMUCMenu"], "app.join")
|
||||
fileMenu.Append(loadedLocale["destroyMUCMenu"], "app.destroymuc")
|
||||
fileMenu.Append("MUC Affiliations", "app.mucaffils")
|
||||
fileMenu.Append("Configure MUC", "app.configuremuc")
|
||||
|
||||
viewAffilsMucAction := gio.NewSimpleAction("mucaffils", nil)
|
||||
viewAffilsMucAction.ConnectActivate(func(p *glib.Variant) {
|
||||
go func() {
|
||||
cur, ok := tabs.Load(current)
|
||||
if ok {
|
||||
cur := cur.(*chatTab)
|
||||
if cur.isMuc {
|
||||
affils := []string{"owner", "admin", "member", "outcast"}
|
||||
items := []MucAdminItem{}
|
||||
|
||||
for _, affil := range affils {
|
||||
iq, err := stanza.NewIQ(stanza.Attrs{Type: stanza.IQTypeGet, To: current, Id: uuid.NewString(), From: clientroot.Session.BindJid})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
q := new(MucAdminQuery)
|
||||
q.MucAdminItems = append(q.MucAdminItems, MucAdminItem{Affiliation: affil})
|
||||
iq.Payload = q
|
||||
ctx := context.TODO()
|
||||
mychan, err := client.SendIQ(ctx, iq)
|
||||
|
||||
result := <-mychan
|
||||
res, ok := result.Payload.(*MucAdminQuery)
|
||||
if ok {
|
||||
for _, item := range res.MucAdminItems {
|
||||
items = append(items, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib.IdleAdd(func() {
|
||||
affil_win := gtk.NewWindow()
|
||||
affil_box := gtk.NewBox(gtk.OrientationVertical, 2)
|
||||
affil_box.Append(gtk.NewLabel("Affiliations"))
|
||||
|
||||
scroller := gtk.NewScrolledWindow()
|
||||
scroller_grid := gtk.NewGrid()
|
||||
scroller_grid.SetVExpand(true)
|
||||
scroller.SetChild(scroller_grid)
|
||||
scroller.SetVExpand(true)
|
||||
|
||||
affil_box.Append(scroller)
|
||||
|
||||
affil_win.SetChild(affil_box)
|
||||
scroller_grid.Attach(gtk.NewLabel("Affiliation"), 0, 0, 1, 1)
|
||||
scroller_grid.Attach(gtk.NewLabel("JID"), 1, 0, 1, 1)
|
||||
scroller_grid.Attach(gtk.NewLabel("Nick"), 2, 0, 1, 1)
|
||||
scroller_grid.Attach(gtk.NewLabel("Reason"), 3, 0, 1, 1)
|
||||
|
||||
for i, v := range items {
|
||||
medal_box := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||
medal_box.Append(gtk.NewImageFromPaintable(clientAssetsLoad(v.Affiliation)))
|
||||
medal_box.Append(gtk.NewLabel(v.Affiliation))
|
||||
scroller_grid.Attach(medal_box, 0, i+1, 1, 1)
|
||||
|
||||
jid := gtk.NewLabel(v.JID)
|
||||
jid.AddCSSClass("jid")
|
||||
jid.SetSelectable(true)
|
||||
scroller_grid.Attach(jid, 1, i+1, 1, 1)
|
||||
|
||||
nick := gtk.NewLabel(v.Nick)
|
||||
nick.SetSelectable(true)
|
||||
scroller_grid.Attach(nick, 2, i+1, 1, 1)
|
||||
|
||||
reason := gtk.NewLabel(v.Reason)
|
||||
reason.SetSelectable(true)
|
||||
reason.SetEllipsize(pango.EllipsizeEnd)
|
||||
scroller_grid.Attach(reason, 3, i+1, 1, 1)
|
||||
}
|
||||
|
||||
affil_win.SetVisible(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
}()
|
||||
})
|
||||
|
||||
dmMenu := gio.NewMenu()
|
||||
dmMenu.Append(loadedLocale["startDMMenu"], "app.dm")
|
||||
@@ -890,12 +991,81 @@ func activate(app *gtk.Application) {
|
||||
a.SetAuthors([]string{"Sunglocto", "Hydrogen", "Kuyuhi"})
|
||||
a.SetLicenseType(gtk.LicenseGPL30)
|
||||
a.SetLogo(clientAssetsLoad("logo"))
|
||||
a.SetWebsite("https://forge.sunglocto.net/sunglocto/lambda")
|
||||
a.SetWebsite("https://sunglocto.net/lambda")
|
||||
a.SetWebsiteLabel("Website")
|
||||
|
||||
a.SetVisible(true)
|
||||
})
|
||||
|
||||
configureMucAction := gio.NewSimpleAction("configuremuc", nil)
|
||||
configureMucAction.ConnectActivate(func(p *glib.Variant) {
|
||||
go func() {
|
||||
cur, ok := tabs.Load(current)
|
||||
if ok {
|
||||
cur := cur.(*chatTab)
|
||||
if cur.isMuc {
|
||||
iq, err := stanza.NewIQ(stanza.Attrs{
|
||||
Type: stanza.IQTypeGet,
|
||||
Id: uuid.NewString(),
|
||||
To: current,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
glib.IdleAdd(func() { showErrorDialog(err, &window.Window) })
|
||||
return
|
||||
}
|
||||
|
||||
iq.Payload = &MucOwnerQuery{}
|
||||
|
||||
ctx := context.TODO()
|
||||
mychan, err := client.SendIQ(ctx, iq)
|
||||
if err != nil {
|
||||
glib.IdleAdd(func() { showErrorDialog(err, &window.Window) })
|
||||
return
|
||||
}
|
||||
|
||||
result := <-mychan
|
||||
res, ok := result.Payload.(*MucOwnerQuery)
|
||||
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
glib.IdleAdd(func() {
|
||||
f, win, _ := showFormDialog(res.Form)
|
||||
win.ConnectCloseRequest(func() (ok bool) {
|
||||
go func() {
|
||||
iq, err := stanza.NewIQ(stanza.Attrs{
|
||||
Id: result.Id,
|
||||
To: result.From,
|
||||
Type: stanza.IQTypeSet,
|
||||
})
|
||||
if err != nil {
|
||||
glib.IdleAdd(func() { showErrorDialog(err, &window.Window) })
|
||||
return
|
||||
}
|
||||
|
||||
f.Type = "submit"
|
||||
mo := new(MucOwnerQuery)
|
||||
mo.Form = *f
|
||||
|
||||
iq.Payload = mo
|
||||
|
||||
ctx := context.TODO()
|
||||
_, err = client.SendIQ(ctx, iq)
|
||||
if err != nil {
|
||||
glib.IdleAdd(func() { showErrorDialog(err, &window.Window) })
|
||||
return
|
||||
}
|
||||
}()
|
||||
return false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}()
|
||||
})
|
||||
|
||||
destroymucAction := gio.NewSimpleAction("destroymuc", nil)
|
||||
destroymucAction.ConnectActivate(func(p *glib.Variant) {
|
||||
cur, ok := tabs.Load(current)
|
||||
@@ -919,7 +1089,6 @@ func activate(app *gtk.Application) {
|
||||
|
||||
submit := gtk.NewButtonWithLabel(loadedLocale["destroyMUCActionButton"])
|
||||
submit.ConnectClicked(func() {
|
||||
fmt.Println(en.Text())
|
||||
if en.Text() == loadedLocale["destroyMUCPassword"] {
|
||||
cur, ok := tabs.Load(current)
|
||||
if ok {
|
||||
@@ -1069,7 +1238,6 @@ func activate(app *gtk.Application) {
|
||||
|
||||
var res *stanza.DiscoInfo
|
||||
allowed := true
|
||||
fmt.Println("Attempting to get Disco info")
|
||||
|
||||
myIQ, err := stanza.NewIQ(stanza.Attrs{
|
||||
Type: "get",
|
||||
@@ -1225,7 +1393,9 @@ func activate(app *gtk.Application) {
|
||||
app.AddAction(joinAction)
|
||||
app.AddAction(aboutAction)
|
||||
app.AddAction(destroymucAction)
|
||||
app.AddAction(configureMucAction)
|
||||
app.AddAction(startDmAction)
|
||||
app.AddAction(viewAffilsMucAction)
|
||||
|
||||
the_menu.AppendSubmenu("MUC", fileMenu)
|
||||
the_menu.AppendSubmenu("DM", dmMenu)
|
||||
@@ -1350,16 +1520,13 @@ func activate(app *gtk.Application) {
|
||||
scrollerStatBar.SetChild(statBar)
|
||||
box.Append(scrollerStatBar)
|
||||
|
||||
// scroller.SetChild(empty_dialog)
|
||||
scroller.SetChild(empty_dialog)
|
||||
menu_scroll := gtk.NewScrolledWindow()
|
||||
menu_scroll.SetHExpand(true)
|
||||
|
||||
menu_scroll.SetChild(menu)
|
||||
// box.Append(menu_scroll)
|
||||
|
||||
chatbox := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||
// chatbox.Append(menu_scroll)
|
||||
chat_pane := gtk.NewPaned(gtk.OrientationHorizontal)
|
||||
chat_pane.SetStartChild(scroller)
|
||||
chat_pane.SetEndChild(memberList)
|
||||
|
||||
Reference in new issue
Block a user