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/global" "work_cation/models" "work_cation/pkg/utils" "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() } // 分享 toolBar := widget.NewToolbar( widget.NewToolbarAction(theme.ContentAddIcon(), func() { dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w) }), widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }), widget.NewToolbarAction(theme.MailForwardIcon(), func() { game := NewTenGame(nil) online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port} err := game.AddNet(utils.Uuid.CreateUUID(), 0, online, &user) if err != nil { dialog.ShowInformation("错误", err.Error(), w) return } game.StartShow() }), ) 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 }