a lodda changes my guy
This commit is contained in:
3
cache.go
3
cache.go
@@ -8,11 +8,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/diamondburned/gotk4/pkg/gdk/v4"
|
"github.com/diamondburned/gotk4/pkg/gdk/v4"
|
||||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||||
|
"github.com/kirsle/configdir"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"github.com/kirsle/configdir"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// global or app-level map/cache
|
// global or app-level map/cache
|
||||||
@@ -105,7 +105,6 @@ func newImageFromWeb(url string) *gtk.Image {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fullpath := filepath.Join(pa, sum)
|
fullpath := filepath.Join(pa, sum)
|
||||||
|
|
||||||
// step 3: save it
|
// step 3: save it
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/diamondburned/gotk4/pkg/glib/v2"
|
"github.com/diamondburned/gotk4/pkg/glib/v2"
|
||||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
Jid "mellium.im/xmpp/jid"
|
Jid "mellium.im/xmpp/jid"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
|
func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
|
||||||
@@ -39,8 +39,22 @@ func switchToTab(jid string) {
|
|||||||
gen := gtk.NewBox(gtk.OrientationVertical, 0)
|
gen := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||||
|
|
||||||
mm.Range(func(k, v any) bool {
|
mm.Range(func(k, v any) bool {
|
||||||
|
userbox := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||||
|
|
||||||
u := v.(stanza.Presence)
|
u := v.(stanza.Presence)
|
||||||
gen.Append(gtk.NewLabel(Jid.MustParse(u.From).Resourcepart()))
|
var mu MucUser
|
||||||
|
u.Get(&mu)
|
||||||
|
|
||||||
|
nick_label := gtk.NewLabel(Jid.MustParse(u.From).Resourcepart())
|
||||||
|
affil_label := gtk.NewLabel(mu.MucUserItem.Affiliation)
|
||||||
|
|
||||||
|
// nick_label.SetHAlign(gtk.AlignStart)
|
||||||
|
// affil_label.SetHAlign(gtk.AlignEnd)
|
||||||
|
|
||||||
|
userbox.Append(nick_label)
|
||||||
|
userbox.Append(affil_label)
|
||||||
|
|
||||||
|
gen.Append(userbox)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ package main
|
|||||||
// This file contains the function that generates message widgets depending on message stanza
|
// This file contains the function that generates message widgets depending on message stanza
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jacoblockett/sanitizefilename"
|
||||||
|
"github.com/jasonlovesdoggo/gopen"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
"mellium.im/xmpp/jid"
|
"mellium.im/xmpp/jid"
|
||||||
"github.com/google/uuid"
|
"os"
|
||||||
"github.com/jasonlovesdoggo/gopen"
|
"path/filepath"
|
||||||
"encoding/base64"
|
|
||||||
"github.com/jacoblockett/sanitizefilename"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
||||||
@@ -31,7 +32,7 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
reactions := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
reactions := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||||
reactions.SetVisible(false)
|
reactions.SetVisible(false)
|
||||||
|
|
||||||
reaction := []string{"👍", "👎", "♥️", "🤣", "😭",}
|
reaction := []string{"👍", "👎", "♥️", "🤣", "😭"}
|
||||||
for _, v := range reaction {
|
for _, v := range reaction {
|
||||||
like := gtk.NewButton()
|
like := gtk.NewButton()
|
||||||
like.SetLabel(v)
|
like.SetLabel(v)
|
||||||
@@ -72,7 +73,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
ocu := OccupantID{}
|
ocu := OccupantID{}
|
||||||
m.Get(&ocu)
|
m.Get(&ocu)
|
||||||
|
|
||||||
|
|
||||||
authorBox := gtk.NewBox(gtk.OrientationHorizontal, 10)
|
authorBox := gtk.NewBox(gtk.OrientationHorizontal, 10)
|
||||||
contentBox := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
contentBox := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||||
// im := newImageFromPath("debug.png")
|
// im := newImageFromPath("debug.png")
|
||||||
@@ -80,6 +80,7 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
// authorBox.Append(im)
|
// authorBox.Append(im)
|
||||||
im := getAvatar(m.From, ocu.ID)
|
im := getAvatar(m.From, ocu.ID)
|
||||||
im.SetPixelSize(40)
|
im.SetPixelSize(40)
|
||||||
|
im.AddCSSClass("author_img")
|
||||||
authorBox.Append(im)
|
authorBox.Append(im)
|
||||||
al := gtk.NewLabel(jid.MustParse(m.From).Resourcepart())
|
al := gtk.NewLabel(jid.MustParse(m.From).Resourcepart())
|
||||||
al.AddCSSClass("author")
|
al.AddCSSClass("author")
|
||||||
@@ -101,20 +102,18 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
oob := stanza.OOB{}
|
oob := stanza.OOB{}
|
||||||
ok = m.Get(&oob)
|
ok = m.Get(&oob)
|
||||||
if ok {
|
if ok {
|
||||||
// media := newPictureFromWeb(oob.URL)
|
// media := newPictureFromWeb(oob.URL)
|
||||||
// media.SetCanShrink(false)
|
// media.SetCanShrink(false)
|
||||||
// mainBox.Append(media)
|
// mainBox.Append(media)
|
||||||
// media.AddCSSClass("chat_image")
|
// media.AddCSSClass("chat_image")
|
||||||
mbtn := gtk.NewButtonWithLabel("🖼️")
|
mbtn := gtk.NewButtonWithLabel("🖼️")
|
||||||
// mbtn.SetChild(newImageFromWeb(oob.URL))
|
// mbtn.SetChild(newImageFromWeb(oob.URL))
|
||||||
mbtn.ConnectClicked(func(){
|
mbtn.ConnectClicked(func() {
|
||||||
gopen.Open(oob.URL)
|
gopen.Open(oob.URL)
|
||||||
})
|
})
|
||||||
authorBox.Append(mbtn)
|
authorBox.Append(mbtn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return mainBox
|
return mainBox
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +122,15 @@ func getVAdjustment(scrolledWindow *gtk.ScrolledWindow) *gtk.Adjustment {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAvatar(j, hash string) *gtk.Image {
|
func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shouldn't be here, and should probably be in xmpp-helpers or somewhere similar.
|
||||||
hash = sanitizefilename.Sanitize(hash)
|
p, err := ensureCache()
|
||||||
|
if err != nil {
|
||||||
|
return newImageFromPath("debug.png")
|
||||||
|
}
|
||||||
|
|
||||||
_, err := os.ReadFile(hash)
|
hash = filepath.Join(p, sanitizefilename.Sanitize(hash))
|
||||||
|
|
||||||
|
_, err = os.ReadFile(hash)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return newImageFromPath(hash)
|
return newImageFromPath(hash)
|
||||||
}
|
}
|
||||||
@@ -134,9 +138,9 @@ func getAvatar(j, hash string) *gtk.Image {
|
|||||||
iqResp, err := stanza.NewIQ(stanza.Attrs{
|
iqResp, err := stanza.NewIQ(stanza.Attrs{
|
||||||
Type: "get",
|
Type: "get",
|
||||||
From: clientroot.Session.BindJid,
|
From: clientroot.Session.BindJid,
|
||||||
To: j,
|
To: j,
|
||||||
Id: "vc2",
|
Id: "vc2",
|
||||||
Lang: "e",
|
Lang: "en",
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,7 +154,7 @@ func getAvatar(j, hash string) *gtk.Image {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
result := <- mychan
|
result := <-mychan
|
||||||
card, ok := result.Payload.(*VCard)
|
card, ok := result.Payload.(*VCard)
|
||||||
if !ok {
|
if !ok {
|
||||||
return newImageFromPath("debug.png")
|
return newImageFromPath("debug.png")
|
||||||
@@ -166,12 +170,10 @@ func getAvatar(j, hash string) *gtk.Image {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
err = os.WriteFile(hash, data, 0644)
|
err = os.WriteFile(hash, data, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement caching!
|
|
||||||
return newImageFromPath(hash)
|
return newImageFromPath(hash)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "regexp"
|
_ "regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file implements XEP-0393 partially by providing a function to get a Pango string.
|
// This file implements XEP-0393 partially by providing a function to get a Pango string.
|
||||||
// https://xmpp.org/extensions/xep-0393.html
|
// https://xmpp.org/extensions/xep-0393.html
|
||||||
|
|
||||||
|
func convertXEPToPango(text string) string {
|
||||||
func convertXEPToPango(text string) string {
|
/* FIXME this RegEx causes certain strings to appear invisible
|
||||||
/* FIXME this RegEx causes certain strings to appear invisible
|
text = regexp.MustCompile(`\*([^*]+)\*`).ReplaceAllString(text, "<b>$1</b>")
|
||||||
text = regexp.MustCompile(`\*([^*]+)\*`).ReplaceAllString(text, "<b>$1</b>")
|
text = regexp.MustCompile(`_([^_]+)_`).ReplaceAllString(text, "<i>$1</i>")
|
||||||
text = regexp.MustCompile(`_([^_]+)_`).ReplaceAllString(text, "<i>$1</i>")
|
text = regexp.MustCompile(`~([^~]+)~`).ReplaceAllString(text, "<s>$1</s>")
|
||||||
text = regexp.MustCompile(`~([^~]+)~`).ReplaceAllString(text, "<s>$1</s>")
|
text = regexp.MustCompile("`([^`]+)`").ReplaceAllString(text, "<tt>$1</tt>")
|
||||||
text = regexp.MustCompile("`([^`]+)`").ReplaceAllString(text, "<tt>$1</tt>")
|
*/
|
||||||
*/
|
return text
|
||||||
return text
|
}
|
||||||
}
|
|
||||||
|
|||||||
14
main.go
14
main.go
@@ -19,6 +19,7 @@ import (
|
|||||||
|
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var loadedConfig lambdaConfig
|
var loadedConfig lambdaConfig
|
||||||
@@ -70,10 +71,10 @@ func main() {
|
|||||||
TransportConfiguration: xmpp.TransportConfiguration{
|
TransportConfiguration: xmpp.TransportConfiguration{
|
||||||
Address: loadedConfig.Server,
|
Address: loadedConfig.Server,
|
||||||
},
|
},
|
||||||
Jid: loadedConfig.Username,
|
Jid: loadedConfig.Username,
|
||||||
Credential: xmpp.Password(loadedConfig.Password),
|
Credential: xmpp.Password(loadedConfig.Password),
|
||||||
Insecure: loadedConfig.Insecure,
|
Insecure: loadedConfig.Insecure,
|
||||||
// StreamLogger: os.Stdout,
|
StreamLogger: os.Stdout,
|
||||||
}
|
}
|
||||||
router := xmpp.NewRouter()
|
router := xmpp.NewRouter()
|
||||||
|
|
||||||
@@ -125,13 +126,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v := &stanza.Version{}
|
v := &stanza.Version{}
|
||||||
v = v.SetInfo("Lambda", "1.0", "Windows") // TODO: Allow spoofing and report correct information
|
v = v.SetInfo("Lambda", lambda_version, runtime.GOOS) // TODO: Allow spoofing on user request
|
||||||
|
|
||||||
iqResp.Payload = v
|
iqResp.Payload = v
|
||||||
s.Send(iqResp)
|
s.Send(iqResp)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
router.HandleFunc("message", func(s xmpp.Sender, p stanza.Packet) {
|
router.HandleFunc("message", func(s xmpp.Sender, p stanza.Packet) {
|
||||||
m, ok := p.(stanza.Message)
|
m, ok := p.(stanza.Message)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -155,7 +155,6 @@ func main() {
|
|||||||
_, ok = tabs[originator]
|
_, ok = tabs[originator]
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
fmt.Println("valid")
|
|
||||||
tabs[originator].msgs.Append(b)
|
tabs[originator].msgs.Append(b)
|
||||||
scrollToBottomAfterUpdate(scroller)
|
scrollToBottomAfterUpdate(scroller)
|
||||||
} else {
|
} else {
|
||||||
@@ -253,6 +252,7 @@ func activate(app *gtk.Application) {
|
|||||||
app.SetMenubar(gio.NewMenu())
|
app.SetMenubar(gio.NewMenu())
|
||||||
|
|
||||||
window.SetTitle("Lambda")
|
window.SetTitle("Lambda")
|
||||||
|
window.AddCSSClass("ssd")
|
||||||
menu := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
menu := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||||
/*
|
/*
|
||||||
f_menu := gtk.NewMenuButton()
|
f_menu := gtk.NewMenuButton()
|
||||||
|
|||||||
@@ -6,3 +6,7 @@
|
|||||||
max-width: 50px;
|
max-width: 50px;
|
||||||
max-height: 50px;
|
max-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.author_img {
|
||||||
|
border-radius 100%;
|
||||||
|
}
|
||||||
|
|||||||
51
types.go
51
types.go
@@ -1,26 +1,25 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type chatTab struct {
|
type chatTab struct {
|
||||||
isMuc bool
|
isMuc bool
|
||||||
msgs *gtk.ListBox
|
msgs *gtk.ListBox
|
||||||
}
|
}
|
||||||
|
|
||||||
type lambdaConfig struct {
|
type lambdaConfig struct {
|
||||||
Server string
|
Server string
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
Insecure bool
|
Insecure bool
|
||||||
Nick string
|
Nick string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mucUnit struct {
|
||||||
type mucUnit struct {
|
// key: OccupantID
|
||||||
// key: OccupantID
|
// value: last user presence
|
||||||
// value: last user presence
|
Members sync.Map
|
||||||
Members sync.Map
|
}
|
||||||
}
|
|
||||||
|
|||||||
3
version.go
Normal file
3
version.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
var lambda_version string = "0.1.0"
|
||||||
@@ -27,7 +27,7 @@ func sendMessage(c xmpp.Sender, sendTo string, msgType stanza.StanzaType, body s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Joins a MUC
|
// Joins a MUC
|
||||||
func joinMuc(c xmpp.Sender, jid string, muc string, nick string) error{
|
func joinMuc(c xmpp.Sender, jid string, muc string, nick string) error {
|
||||||
addr := muc + "/" + nick
|
addr := muc + "/" + nick
|
||||||
fmt.Println(addr)
|
fmt.Println(addr)
|
||||||
joinPresence := stanza.Presence{
|
joinPresence := stanza.Presence{
|
||||||
@@ -36,8 +36,7 @@ func joinMuc(c xmpp.Sender, jid string, muc string, nick string) error{
|
|||||||
To: addr,
|
To: addr,
|
||||||
},
|
},
|
||||||
Extensions: []stanza.PresExtension{
|
Extensions: []stanza.PresExtension{
|
||||||
&stanza.MucPresence{
|
&stanza.MucPresence{},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type VCard struct {
|
type VCard struct {
|
||||||
XMLName xml.Name `xml:"vcard-temp vCard"`
|
XMLName xml.Name `xml:"vcard-temp vCard"`
|
||||||
Photo Photo `xml:"PHOTO"`
|
Photo Photo `xml:"PHOTO"`
|
||||||
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user