Continue last commit

This commit is contained in:
2025-08-07 22:29:40 +01:00
parent 150f42bc58
commit 4015107de0

170
main.go
View File

@@ -56,12 +56,15 @@ type ChatTab struct {
Jid jid.JID Jid jid.JID
Nick string Nick string
Messages []Message Messages []Message
Scroller *widget.List `xml:"-"`
isMuc bool isMuc bool
Muc *muc.Channel `xml:"-"` Muc muc.Channel
Sidebar *fyne.Container `xml:"-"`
UpdateSidebar bool UpdateSidebar bool
SidebarUpdateMethod func(client oasisSdk.XmppClient) `xml:"-"` }
type ChatTabUI struct {
Internal *ChatTab
Scroller *widget.List `xml:"-"`
Sidebar *fyne.Container `xml:"-"`
} }
type piConfig struct { type piConfig struct {
@@ -75,7 +78,9 @@ var login oasisSdk.LoginInfo
var DMs []string var DMs []string
var chatTabs = make(map[string]*ChatTab) var chatTabs = make(map[string]*ChatTab)
var tabs *container.AppTabs var UITabs = make(map[string]*ChatTabUI)
var AppTabs *container.AppTabs
var selectedId widget.ListItemID var selectedId widget.ListItemID
var replying bool = false var replying bool = false
var notifications bool var notifications bool
@@ -106,41 +111,11 @@ var scrollDownOnNewMessage bool = true
var w fyne.Window var w fyne.Window
var a fyne.App var a fyne.App
func addChatTab(isMuc bool, chatJid jid.JID, nick string) { func CreateUITab(chatJidStr string) ChatTabUI {
mucJidStr := chatJid.String()
if _, ok := chatTabs[mucJidStr]; ok {
// Tab already exists
return
}
tabData := &ChatTab{
Jid: chatJid,
Nick: nick,
Messages: []Message{},
isMuc: isMuc,
Sidebar: container.NewVBox(widget.NewRichTextFromMarkdown("# "+chatJid.Localpart()), widget.NewLabel("please wait for more information...")),
UpdateSidebar: true,
}
if isMuc {
tabData.SidebarUpdateMethod = func(client oasisSdk.XmppClient) {
fyne.Do(func() {
if chatTabs[mucJidStr].UpdateSidebar {
i, _ := disco.GetInfo(client.Ctx, "identity", tabData.Jid, client.Session)
name := i.XMLName
chatTabs[mucJidStr].Sidebar = container.NewVBox(widget.NewRichTextFromMarkdown("# "+chatJid.Localpart()), widget.NewLabel(fmt.Sprintf("%d messages loaded", len(tabData.Messages))), widget.NewLabel(name.Space))
chatTabs[mucJidStr].UpdateSidebar = false
chatSidebar = *chatTabs[mucJidStr].Sidebar
chatSidebar.Refresh()
}
})
}
}
var scroller *widget.List var scroller *widget.List
scroller = widget.NewList( scroller = widget.NewList(
func() int { func() int {
return len(tabData.Messages) return len(chatTabs[chatJidStr].Messages)
}, },
func() fyne.CanvasObject { func() fyne.CanvasObject {
author := widget.NewLabel("author") author := widget.NewLabel("author")
@@ -159,22 +134,22 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
author := vbox.Objects[0].(*widget.Label) author := vbox.Objects[0].(*widget.Label)
content := vbox.Objects[1].(*widget.Label) content := vbox.Objects[1].(*widget.Label)
btn := vbox.Objects[2].(*widget.Button) btn := vbox.Objects[2].(*widget.Button)
if tabData.Messages[i].Important { if chatTabs[chatJidStr].Messages[i].Important {
//content.Importance = widget.DangerImportance TODO: Fix highlighting messages with mentions, it's currently broken //content.Importance = widget.DangerImportance TODO: Fix highlighting messages with mentions, it's currently broken
} }
btn.Hidden = true // Hide by default btn.Hidden = true // Hide by default
msgContent := tabData.Messages[i].Content msgContent := chatTabs[chatJidStr].Messages[i].Content
if tabData.Messages[i].ImageURL != "" { if chatTabs[chatJidStr].Messages[i].ImageURL != "" {
btn.Hidden = false btn.Hidden = false
btn.OnTapped = func() { btn.OnTapped = func() {
fyne.Do(func() { fyne.Do(func() {
u, err := storage.ParseURI(tabData.Messages[i].ImageURL) u, err := storage.ParseURI(chatTabs[chatJidStr].Messages[i].ImageURL)
if err != nil { if err != nil {
dialog.ShowError(err, w) dialog.ShowError(err, w)
return return
} }
if strings.HasSuffix(tabData.Messages[i].ImageURL, "mp4") { if strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp4") {
url, err := url.Parse(tabData.Messages[i].ImageURL) url, err := url.Parse(chatTabs[chatJidStr].Messages[i].ImageURL)
if err != nil { if err != nil {
dialog.ShowError(err, w) dialog.ShowError(err, w)
return return
@@ -199,25 +174,53 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
//content.ParseMarkdown(msgContent) //content.ParseMarkdown(msgContent)
content.SetText(msgContent) content.SetText(msgContent)
if tabData.Messages[i].ReplyID != "PICLIENT:UNAVAILABLE" { if chatTabs[chatJidStr].Messages[i].ReplyID != "PICLIENT:UNAVAILABLE" {
author.SetText(fmt.Sprintf("%s > %s", tabData.Messages[i].Author, jid.MustParse(tabData.Messages[i].Raw.Reply.To).Resourcepart())) author.SetText(fmt.Sprintf("%s > %s", chatTabs[chatJidStr].Messages[i].Author, jid.MustParse(chatTabs[chatJidStr].Messages[i].Raw.Reply.To).Resourcepart()))
} else { } else {
author.SetText(tabData.Messages[i].Author) author.SetText(chatTabs[chatJidStr].Messages[i].Author)
} }
scroller.SetItemHeight(i, vbox.MinSize().Height) scroller.SetItemHeight(i, vbox.MinSize().Height)
}, },
) )
scroller.OnSelected = func(id widget.ListItemID) { scroller.OnSelected = func(id widget.ListItemID) {
selectedId = id selectedId = id
} }
myUITab := ChatTabUI{}
scroller.CreateItem() scroller.CreateItem()
tabData.Scroller = scroller myUITab.Scroller = scroller
myUITab.Sidebar = container.NewVBox(widget.NewLabel("Data goes here"))
chatTabs[mucJidStr] = tabData return myUITab
}
func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
tabItem := container.NewTabItem(chatJid.Localpart(), scroller) chatJidStr := chatJid.String()
tabs.Append(tabItem) if _, ok := chatTabs[chatJidStr]; ok {
// Tab already exists
return
}
myChatTab := ChatTab{
Jid: chatJid,
Nick: nick,
Messages: []Message{},
isMuc: isMuc,
}
myUITab := CreateUITab(chatJid.String())
myUITab.Internal = &myChatTab
chatTabs[chatJidStr] = &myChatTab
UITabs[chatJidStr] = &myUITab
fyne.Do(func() {
AppTabs.Append(container.NewTabItem(chatJid.String(), myUITab.Scroller))
})
} }
func dropToSignInPage(reason string) { func dropToSignInPage(reason string) {
@@ -360,9 +363,9 @@ func main() {
tab.Messages = append(tab.Messages, myMessage) tab.Messages = append(tab.Messages, myMessage)
fyne.Do(func() { fyne.Do(func() {
tab.Scroller.Refresh() UITabs[userJidStr].Scroller.Refresh()
if scrollDownOnNewMessage { if scrollDownOnNewMessage {
tab.Scroller.ScrollToBottom() UITabs[userJidStr].Scroller.ScrollToBottom()
} }
}) })
} }
@@ -388,7 +391,7 @@ func main() {
var ImageID string = "" var ImageID string = ""
mucJidStr := msg.From.Bare().String() mucJidStr := msg.From.Bare().String()
if tab, ok := chatTabs[mucJidStr]; ok { if tab, ok := chatTabs[mucJidStr]; ok {
chatTabs[mucJidStr].Muc = muc chatTabs[mucJidStr].Muc = *muc
str := *msg.CleanedBody str := *msg.CleanedBody
if strings.Contains(str, login.DisplayName) { if strings.Contains(str, login.DisplayName) {
fmt.Println(str) fmt.Println(str)
@@ -430,7 +433,7 @@ func main() {
if tab.Messages[i].Raw.From.String() == msg.From.String() { if tab.Messages[i].Raw.From.String() == msg.From.String() {
tab.Messages[i].Content = *msg.CleanedBody + " (edited)" tab.Messages[i].Content = *msg.CleanedBody + " (edited)"
fyne.Do(func() { fyne.Do(func() {
tab.Scroller.Refresh() UITabs[mucJidStr].Scroller.Refresh()
}) })
return return
} }
@@ -450,9 +453,9 @@ func main() {
tab.Messages = append(tab.Messages, myMessage) tab.Messages = append(tab.Messages, myMessage)
} }
fyne.Do(func() { fyne.Do(func() {
tab.Scroller.Refresh() UITabs[mucJidStr].Scroller.Refresh()
if scrollDownOnNewMessage { if scrollDownOnNewMessage {
tab.Scroller.ScrollToBottom() UITabs[mucJidStr].Scroller.ScrollToBottom()
} }
}) })
} }
@@ -522,21 +525,21 @@ func main() {
SendCallback := func() { SendCallback := func() {
text := entry.Text text := entry.Text
if tabs.Selected() == nil || tabs.Selected().Content == nil || text == "" { if AppTabs.Selected() == nil || AppTabs.Selected().Content == nil || text == "" {
return return
} }
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
var activeMucJid string var activeMucJid string
var isMuc bool var isMuc bool
for jid, tabData := range chatTabs { for jid, tabData := range UITabs {
if tabData.Scroller == selectedScroller { if tabData.Scroller == selectedScroller {
activeMucJid = jid activeMucJid = jid
isMuc = tabData.isMuc isMuc = chatTabs[activeMucJid].isMuc
break break
} }
} }
@@ -578,7 +581,7 @@ func main() {
}) })
fyne.Do(func() { fyne.Do(func() {
if scrollDownOnNewMessage { if scrollDownOnNewMessage {
chatTabs[activeMucJid].Scroller.ScrollToBottom() UITabs[activeMucJid].Scroller.ScrollToBottom()
} }
}) })
} }
@@ -633,8 +636,9 @@ func main() {
}, w) }, w)
}) })
jtb := fyne.NewMenuItem("jump to bottom", func() { jtb := fyne.NewMenuItem("jump to bottom", func() {
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
@@ -642,7 +646,7 @@ func main() {
}) })
jtt := fyne.NewMenuItem("jump to top", func() { jtt := fyne.NewMenuItem("jump to top", func() {
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
@@ -767,21 +771,6 @@ func main() {
}, w) }, w)
}) })
rel := fyne.NewMenuItem("Forcefully reload tab sidebar", func() {
selectedScroller, ok := tabs.Selected().Content.(*widget.List)
if !ok {
return
}
var activeMucJid string
for jid, tabData := range chatTabs {
if tabData.Scroller == selectedScroller {
activeMucJid = jid
break
}
}
chatTabs[activeMucJid].UpdateSidebar = true
go chatTabs[activeMucJid].SidebarUpdateMethod(*client)
})
savedata := fyne.NewMenuItem("DEBUG: Save tab data to disk", func() { savedata := fyne.NewMenuItem("DEBUG: Save tab data to disk", func() {
d := []ChatTab{} d := []ChatTab{}
@@ -796,7 +785,7 @@ func main() {
os.Create("test.xml") os.Create("test.xml")
os.WriteFile("text.xml", b, os.ModeAppend) os.WriteFile("text.xml", b, os.ModeAppend)
}) })
menu_help := fyne.NewMenu("π", mit, reconnect, rel, savedata) menu_help := fyne.NewMenu("π", mit, reconnect, savedata)
menu_changeroom := fyne.NewMenu("β", mic, servDisc) menu_changeroom := fyne.NewMenu("β", mic, servDisc)
menu_configureview := fyne.NewMenu("γ", mia, mis, jtt, jtb) menu_configureview := fyne.NewMenu("γ", mia, mis, jtt, jtb)
hafjag := fyne.NewMenuItem("Hafjag", func() { hafjag := fyne.NewMenuItem("Hafjag", func() {
@@ -817,12 +806,12 @@ func main() {
}) })
menu_jokes := fyne.NewMenu("Δ", mycurrenttime, hafjag, hotfuck) menu_jokes := fyne.NewMenu("Δ", mycurrenttime, hafjag, hotfuck)
bit := fyne.NewMenuItem("mark selected message as read", func() { bit := fyne.NewMenuItem("mark selected message as read", func() {
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
var activeMucJid string var activeMucJid string
for jid, tabData := range chatTabs { for jid, tabData := range UITabs {
if tabData.Scroller == selectedScroller { if tabData.Scroller == selectedScroller {
activeMucJid = jid activeMucJid = jid
break break
@@ -840,13 +829,13 @@ func main() {
bic := fyne.NewMenuItem("show message XML", func() { bic := fyne.NewMenuItem("show message XML", func() {
pre := widget.NewLabel("") pre := widget.NewLabel("")
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
var activeChatJid string var activeChatJid string
for jid, tabData := range chatTabs { for jid, tabData := range UITabs {
if tabData.Scroller == selectedScroller { if tabData.Scroller == selectedScroller {
activeChatJid = jid activeChatJid = jid
break break
@@ -868,7 +857,7 @@ func main() {
ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview, menu_messageoptions, menu_jokes) ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview, menu_messageoptions, menu_jokes)
w.SetMainMenu(ma) w.SetMainMenu(ma)
tabs = container.NewAppTabs( AppTabs = container.NewAppTabs(
container.NewTabItem("τίποτα", widget.NewLabel(` container.NewTabItem("τίποτα", widget.NewLabel(`
pi pi
`)), `)),
@@ -889,34 +878,35 @@ func main() {
} }
} }
tabs.OnSelected = func(ti *container.TabItem) { AppTabs.OnSelected = func(ti *container.TabItem) {
selectedScroller, ok := tabs.Selected().Content.(*widget.List) selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
if !ok { if !ok {
return return
} }
var activeChatJid string var activeChatJid string
for jid, tabData := range chatTabs { for jid, tabData := range UITabs {
if tabData.Scroller == selectedScroller { if tabData.Scroller == selectedScroller {
activeChatJid = jid activeChatJid = jid
break break
} }
} }
chatTabs[activeChatJid].SidebarUpdateMethod(*client)
tab := chatTabs[activeChatJid] tab := chatTabs[activeChatJid]
UITab := UITabs[activeChatJid]
if tab.isMuc { if tab.isMuc {
chatInfo = *container.NewHBox(widget.NewLabel(tab.Muc.Addr().String())) chatInfo = *container.NewHBox(widget.NewLabel(tab.Muc.Addr().String()))
} else { } else {
chatInfo = *container.NewHBox(widget.NewLabel(tab.Jid.String())) chatInfo = *container.NewHBox(widget.NewLabel(tab.Jid.String()))
} }
chatSidebar = *tab.Sidebar chatSidebar = *UITab.Sidebar
chatSidebar.Refresh() chatSidebar.Refresh()
} }
statBar.SetText("") statBar.SetText("")
w.SetContent(container.NewVSplit(container.NewVSplit(container.NewHSplit(tabs, &chatSidebar), container.NewHSplit(entry, sendbtn)), container.NewHSplit(&statBar, &chatInfo))) w.SetContent(container.NewVSplit(container.NewVSplit(container.NewHSplit(AppTabs, &chatSidebar), container.NewHSplit(entry, sendbtn)), container.NewHSplit(&statBar, &chatInfo)))
w.ShowAndRun() w.ShowAndRun()
} }