Attempt to add YouTube embed handling, revise .webp support, support corrections in 1:1 DMs, and a whole load of other changes. Also bump version number to 3i and begin Indev phase

This commit is contained in:
2025-08-12 10:55:00 +01:00
parent e5f391edfd
commit 6ab9dd8ff8
3 changed files with 58 additions and 8 deletions

1
go.mod
View File

@@ -6,6 +6,7 @@ require (
fyne.io/fyne/v2 v2.6.2 fyne.io/fyne/v2 v2.6.2
fyne.io/x/fyne v0.0.0-20250418202416-58a230ad1acb fyne.io/x/fyne v0.0.0-20250418202416-58a230ad1acb
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6
mellium.im/xmpp v0.22.0 mellium.im/xmpp v0.22.0
pain.agency/oasis-sdk v0.0.0-20250809192709-a3e5dff1aa61 pain.agency/oasis-sdk v0.0.0-20250809192709-a3e5dff1aa61
) )

2
go.sum
View File

@@ -68,6 +68,8 @@ github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqd
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6 h1:VQpB2SpK88C6B5lPHTuSZKb2Qee1QWwiFlC5CKY4AW0=
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6/go.mod h1:yE65LFCeWf4kyWD5re+h4XNvOHJEXOCOuJZ4v8l5sgk=
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=

63
main.go
View File

@@ -10,6 +10,7 @@ import (
"math/rand/v2" "math/rand/v2"
"net/url" "net/url"
"os" "os"
"regexp"
"strings" "strings"
"time" "time"
@@ -22,15 +23,17 @@ import (
"fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/rrivera/identicon"
extraWidgets "fyne.io/x/fyne/widget" extraWidgets "fyne.io/x/fyne/widget"
"github.com/rrivera/identicon"
// xmpp - required // xmpp - required
"mellium.im/xmpp/disco" "mellium.im/xmpp/disco"
"mellium.im/xmpp/jid" "mellium.im/xmpp/jid"
"mellium.im/xmpp/muc" "mellium.im/xmpp/muc"
oasisSdk "pain.agency/oasis-sdk" oasisSdk "pain.agency/oasis-sdk"
// gui - optional // gui - optional
webview "github.com/webview/webview_go"
// catppuccin "github.com/mbaklor/fyne-catppuccin" // catppuccin "github.com/mbaklor/fyne-catppuccin"
// TODO: integrated theme switcher // TODO: integrated theme switcher
) )
@@ -41,6 +44,7 @@ var chatInfo fyne.Container
var chatSidebar fyne.Container var chatSidebar fyne.Container
var agreesToSendingHotFuckIntoChannel bool = false var agreesToSendingHotFuckIntoChannel bool = false
var agreesToLoadingYouTube bool = false
// by sunglocto // by sunglocto
// license AGPL // license AGPL
@@ -199,7 +203,26 @@ func CreateUITab(chatJidStr string) ChatTabUI {
}) })
return return
} }
if strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp4") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp3") {
if strings.HasPrefix(chatTabs[chatJidStr].Messages[i].ImageURL, "https://youtube.com") {
fyne.Do(func() {
go func() {
e := regexp.MustCompile(`(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/|v\/|)(?P<video_id>[a-zA-Z0-9_-]{11})`)
f := e.ReplaceAllString(chatTabs[chatJidStr].Messages[i].ImageURL, "https://youtube.com/watch?v=${video_id}")
fmt.Println(f)
w := webview.New(false)
w.SetTitle("YouTube window")
w.SetSize(480, 320, webview.HintNone)
w.Navigate(f)
w.Run()
w.Destroy()
}()
})
return
}
if strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp4") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp3") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "gif") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "webp") { // FIXME: This code is fucking terrible // TODO: Could check mime?
url, err := url.Parse(chatTabs[chatJidStr].Messages[i].ImageURL) url, err := url.Parse(chatTabs[chatJidStr].Messages[i].ImageURL)
if err != nil { if err != nil {
fyne.Do(func() { fyne.Do(func() {
@@ -287,7 +310,7 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
var icon fyne.Resource var icon fyne.Resource
if isMuc { if isMuc {
icon = theme.HomeIcon() icon = theme.HomeIcon()
} else{ } else {
icon = theme.AccountIcon() icon = theme.AccountIcon()
} }
@@ -393,15 +416,22 @@ func main() {
client, err := oasisSdk.CreateClient( client, err := oasisSdk.CreateClient(
&login, &login,
func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) { func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) {
fmt.Println(msg) correction := false
userJidStr := msg.From.Bare().String() userJidStr := msg.From.Bare().String()
tab, ok := chatTabs[userJidStr] tab, ok := chatTabs[userJidStr]
fmt.Println(msg.From.String())
if ok { if ok {
str := *msg.CleanedBody str := *msg.CleanedBody
if notifications { if notifications {
a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str)) a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str))
} }
for _, v := range msg.Unknown {
if v.XMLName.Local == "replace" {
correction = true
break // dont need to look at more fields
}
}
var img string = "" var img string = ""
if strings.Contains(str, "https://") { if strings.Contains(str, "https://") {
lines := strings.Split(str, "\n") lines := strings.Split(str, "\n")
@@ -410,7 +440,7 @@ func main() {
for _, v := range s { for _, v := range s {
_, err := url.Parse(v) _, err := url.Parse(v)
if err == nil && strings.HasPrefix(v, "https://") { if err == nil && strings.HasPrefix(v, "https://") {
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") { if strings.HasPrefix(v, "https://youtube.com") || strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".gif") {
img = v img = v
} }
} }
@@ -425,6 +455,19 @@ func main() {
} else { } else {
replyID = msg.Reply.ID replyID = msg.Reply.ID
} }
if correction {
for i := len(tab.Messages) - 1; i > 0; i-- {
if tab.Messages[i].Raw.From.String() == msg.From.String() {
tab.Messages[i].Content = *msg.CleanedBody + " (edited)"
fyne.Do(func() {
UITabs[userJidStr].Scroller.Refresh()
})
return
}
}
}
myMessage := Message{ myMessage := Message{
Author: msg.From.Resourcepart(), Author: msg.From.Resourcepart(),
Content: str, Content: str,
@@ -448,8 +491,10 @@ func main() {
ignore := false ignore := false
correction := false correction := false
important := false important := false
donotnotify := false
for _, v := range msg.Unknown { for _, v := range msg.Unknown {
if v.XMLName.Local == "delay" { // Classic history message if v.XMLName.Local == "delay" { // Classic history message
donotnotify = true
//ignore = true //ignore = true
//fmt.Println("ignoring!") //fmt.Println("ignoring!")
//return //what is blud doing //return //what is blud doing
@@ -472,7 +517,7 @@ func main() {
fmt.Println(str) fmt.Println(str)
important = true important = true
} }
if !ignore && notifications { if !donotnotify && !ignore && notifications {
if !correction && msg.From.String() != client.JID.String() && strings.Contains(str, login.DisplayName) || (msg.Reply != nil && strings.Contains(msg.Reply.To, login.DisplayName)) { if !correction && msg.From.String() != client.JID.String() && strings.Contains(str, login.DisplayName) || (msg.Reply != nil && strings.Contains(msg.Reply.To, login.DisplayName)) {
a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str)) a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str))
} }
@@ -484,7 +529,7 @@ func main() {
for _, v := range s { for _, v := range s {
_, err := url.Parse(v) _, err := url.Parse(v)
if err == nil && strings.HasPrefix(v, "https://") { if err == nil && strings.HasPrefix(v, "https://") {
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".mp3") { if strings.HasPrefix(v, "https://youtube.com") || strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".mp3") || strings.HasSuffix(v, ".gif") {
ImageID = v ImageID = v
} }
} }
@@ -735,6 +780,7 @@ func main() {
return return
} }
selectedScroller.ScrollToBottom() selectedScroller.ScrollToBottom()
selectedScroller.Refresh()
}) })
jtt := fyne.NewMenuItem("jump to top", func() { jtt := fyne.NewMenuItem("jump to top", func() {
@@ -743,6 +789,7 @@ func main() {
return return
} }
selectedScroller.ScrollToTop() selectedScroller.ScrollToTop()
selectedScroller.Refresh()
}) })
w.SetOnDropped(func(p fyne.Position, u []fyne.URI) { w.SetOnDropped(func(p fyne.Position, u []fyne.URI) {