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:
1
go.mod
1
go.mod
@@ -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
2
go.sum
@@ -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
63
main.go
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user