Files
work_cation/views/chatView.go
T
2024-10-18 22:42:58 +08:00

175 lines
4.7 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"
"github.com/gin-gonic/gin"
"time"
"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: user.Port}
}
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, user.ID, en.Text)
userInfo.messages = append(userInfo.messages, *chatItem)
_ = repo.ChatMsg.Create(global.DB, chatItem)
list.Add(itemMessage(*chatItem))
en.SetText("")
scroll.ScrollToBottom()
}
online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port}
// 分享
toolBar := widget.NewToolbar(
widget.NewToolbarAction(theme.ContentAddIcon(), func() {
dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w)
}),
widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }),
widget.NewToolbarAction(theme.WarningIcon(), func() {
var ilo *dialog.CustomDialog
box := container.NewVBox()
for _, item := range GameConfigList {
var itemCopy = item
box.Add(widget.NewButton(itemCopy.Name, func() {
req := gin.H{
"name": itemCopy.Name,
"x": itemCopy.X,
"y": itemCopy.Y,
"win": itemCopy.Win}
_, err := service.PostSend("/send_game", online, req)
if err != nil {
dialog.ShowError(err, w)
}
ilo.Hide()
}))
}
ilo = dialog.NewCustomWithoutButtons("选择", box, w)
ilo.Show()
}),
)
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
}