151 lines
4.0 KiB
Go
151 lines
4.0 KiB
Go
package views
|
|
|
|
import (
|
|
"fmt"
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
"time"
|
|
"work_cation/cfg"
|
|
"work_cation/global"
|
|
"work_cation/models"
|
|
"work_cation/repo"
|
|
"work_cation/service"
|
|
)
|
|
|
|
type ChatView struct {
|
|
usersChat map[string]*ChatUserInfo
|
|
}
|
|
|
|
type ChatUserInfo struct {
|
|
models.Users
|
|
messages []models.ChatMessage
|
|
shows *fyne.Container
|
|
scroll *container.Scroll
|
|
w fyne.Window
|
|
}
|
|
|
|
var chat = &ChatView{usersChat: make(map[string]*ChatUserInfo)}
|
|
|
|
func ListenChat() {
|
|
go func() {
|
|
for {
|
|
message := <-global.Send.SendChan
|
|
userInfo := chat.usersChat[message.User.ID]
|
|
if userInfo == nil {
|
|
userInfo = &ChatUserInfo{}
|
|
chat.usersChat[message.User.ID] = userInfo
|
|
userInfo.messages = repo.ChatMsg.GetUserMsgs(global.DB, message.User.ID, -1)
|
|
}
|
|
userInfo.messages = append(userInfo.messages, message.ChatMessage)
|
|
_ = repo.ChatMsg.Create(global.DB, &message.ChatMessage)
|
|
userInfo.Users = message.User.Users
|
|
if userInfo.shows == nil {
|
|
OpenChat(message.User.Users)
|
|
} else {
|
|
userInfo.shows.Add(itemMessage(message.ChatMessage))
|
|
userInfo.w.RequestFocus()
|
|
userInfo.scroll.ScrollToBottom()
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func OpenChat(user models.Users) {
|
|
userInfo := chat.usersChat[user.ID]
|
|
if userInfo == nil {
|
|
userInfo = &ChatUserInfo{}
|
|
chat.usersChat[user.ID] = userInfo
|
|
userInfo.messages = repo.ChatMsg.GetUserMsgs(global.DB, user.ID, -1)
|
|
}
|
|
if userInfo.shows == nil {
|
|
w := fyne.CurrentApp().NewWindow(fmt.Sprintf("%s %s", user.Name, user.Ip))
|
|
w.CenterOnScreen()
|
|
w.Resize(fyne.NewSize(500, 420))
|
|
list := container.NewVBox()
|
|
for _, item := range userInfo.messages {
|
|
list.Add(itemMessage(item))
|
|
}
|
|
scroll := container.NewScroll(list)
|
|
userInfo.scroll = scroll
|
|
scroll.ScrollToBottom()
|
|
// 发送表单
|
|
en := widget.NewEntry()
|
|
submit := func() {
|
|
if en.Text == "" {
|
|
return
|
|
}
|
|
online := service.Zeroconf.GetOnline(user.ID)
|
|
if online == nil {
|
|
online = &models.Online{ID: user.ID, Ip: user.Ip, Port: cfg.T.ServerAddr}
|
|
}
|
|
msg, err := service.Client.Chat(online, en.Text)
|
|
if err != nil || msg != "ok" {
|
|
dialog.ShowInformation("发送失败", err.Error(), w)
|
|
return
|
|
}
|
|
my := repo.User.GetUserInfo(global.DB)
|
|
chatItem := models.NewTextChatMsg(my, en.Text)
|
|
userInfo.messages = append(userInfo.messages, *chatItem)
|
|
_ = repo.ChatMsg.Create(global.DB, chatItem)
|
|
list.Add(itemMessage(*chatItem))
|
|
en.SetText("")
|
|
scroll.ScrollToBottom()
|
|
}
|
|
|
|
// 分享
|
|
toolBar := widget.NewToolbar(
|
|
widget.NewToolbarAction(theme.ContentAddIcon(), func() {
|
|
dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w)
|
|
}),
|
|
widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }),
|
|
)
|
|
button := widget.NewButton("", submit)
|
|
button.SetIcon(theme.ConfirmIcon())
|
|
en.OnSubmitted = func(_ string) { submit() }
|
|
w.SetContent(container.NewBorder(nil,
|
|
container.NewBorder(nil, toolBar, nil, button, en),
|
|
nil, nil, scroll))
|
|
|
|
userInfo.shows = list
|
|
userInfo.w = w
|
|
|
|
w.SetOnClosed(func() {
|
|
userInfo.shows = nil
|
|
userInfo.scroll = nil
|
|
userInfo.w = nil
|
|
})
|
|
w.Show()
|
|
}
|
|
userInfo.w.RequestFocus()
|
|
userInfo.scroll.ScrollToBottom()
|
|
}
|
|
|
|
func itemMessage(msg models.ChatMessage) fyne.CanvasObject {
|
|
my := repo.User.GetUserInfo(global.DB)
|
|
var card *widget.Card
|
|
if msg.UserID != my.ID {
|
|
title := fmt.Sprintf("%s %s", msg.CreateTx.Format(time.DateTime), msg.UserName)
|
|
card = widget.NewCard("", "",
|
|
container.NewVBox(
|
|
widget.NewLabel(title),
|
|
newLabel(msg.Text, fyne.TextAlignLeading)))
|
|
} else {
|
|
title := fmt.Sprintf("%s %s", msg.CreateTx.Format(time.DateTime), "我")
|
|
card = widget.NewCard("", "",
|
|
container.NewVBox(
|
|
widget.NewLabelWithStyle(title, fyne.TextAlignTrailing, fyne.TextStyle{}),
|
|
newLabel(msg.Text, fyne.TextAlignTrailing)))
|
|
|
|
}
|
|
return card
|
|
}
|
|
|
|
func newLabel(title string, ali fyne.TextAlign) *widget.Label {
|
|
text := widget.NewLabelWithStyle(title, ali, fyne.TextStyle{})
|
|
text.Wrapping = fyne.TextWrapBreak
|
|
return text
|
|
}
|