package views import ( "fmt" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "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 } 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 = append(userInfo.messages, message.ChatMessage) userInfo.Users = message.User.Users if userInfo.shows == nil { OpenChat(message.User.Users) } else { userInfo.shows.Add(itemMessage(message.ChatMessage)) userInfo.scroll.ScrollToBottom() } } }() } func OpenChat(user models.Users) { userInfo := chat.usersChat[user.ID] if userInfo == nil { userInfo = &ChatUserInfo{} chat.usersChat[user.ID] = userInfo } if userInfo.shows == nil { w := fyne.CurrentApp().NewWindow(user.Name) w.CenterOnScreen() w.Resize(fyne.NewSize(500, 300)) list := container.NewVBox() for _, item := range userInfo.messages { list.Add(itemMessage(item)) } scroll := container.NewScroll(list) userInfo.scroll = scroll scroll.ScrollToBottom() // 发送表单 en := widget.NewEntry() formBase := &widget.Form{ SubmitText: "发送", OnSubmit: 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 } chatItem := models.ChatMessage{ User: *repo.User.GetUserInfo(global.DB), Time: time.Now(), Text: en.Text, } userInfo.messages = append(userInfo.messages, chatItem) list.Add(itemMessage(chatItem)) en.SetText("") scroll.ScrollToBottom() }} formBase.AppendItem(&widget.FormItem{Text: "", Widget: en}) w.SetContent(container.NewBorder(nil, formBase, nil, nil, scroll)) userInfo.shows = list w.SetOnClosed(func() { userInfo.shows = nil userInfo.scroll = nil }) w.Show() } userInfo.scroll.ScrollToBottom() } func itemMessage(msg models.ChatMessage) fyne.CanvasObject { my := repo.User.GetUserInfo(global.DB) var card *widget.Card if msg.User.ID != my.ID { card = widget.NewCard("", fmt.Sprintf("%s %s", msg.Time.Format(time.DateTime), msg.User.Name), widget.NewLabel(msg.Text)) } else { title := fmt.Sprintf("%s %s", msg.Time.Format(time.DateTime), "我") card = widget.NewCard("", "", container.NewVBox( widget.NewLabelWithStyle(title, fyne.TextAlignTrailing, fyne.TextStyle{}), widget.NewLabelWithStyle(msg.Text, fyne.TextAlignTrailing, fyne.TextStyle{}))) } return card }