From b31d96881432ebb1d4918ae970fabfd6362e1186 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 26 Mar 2018 17:22:47 +0300 Subject: Show notifications and highlights in room list. Fixes #8 --- ui/view-main.go | 43 ++++++++++++++++++++++++++++++++++++++++++- ui/widget/message-view.go | 12 ++++++------ ui/widget/room-list.go | 34 +++++++++++++++++++++++----------- ui/widget/util.go | 16 ++++++++++++++-- 4 files changed, 85 insertions(+), 20 deletions(-) (limited to 'ui') diff --git a/ui/view-main.go b/ui/view-main.go index 94d09ab..a037ea0 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -28,6 +28,9 @@ import ( "maunium.net/go/gomatrix" "maunium.net/go/gomuks/config" "maunium.net/go/gomuks/interface" + "maunium.net/go/gomuks/matrix/pushrules" + "maunium.net/go/gomuks/matrix/rooms" + "maunium.net/go/gomuks/notification" "maunium.net/go/gomuks/ui/debug" "maunium.net/go/gomuks/ui/types" "maunium.net/go/gomuks/ui/widget" @@ -239,6 +242,10 @@ func (view *MainView) MouseEventHandler(roomView *widget.RoomView, event *tcell. msgView.AddScrollOffset(-WheelScrollOffsetDiff) view.parent.Render() + + if msgView.ScrollOffset == 0 { + roomView.Room.MarkRead() + } default: debug.Print("Mouse event received:", event.Buttons(), event.Modifiers(), x, y) return event @@ -263,7 +270,11 @@ func (view *MainView) SwitchRoom(roomIndex int) { } view.currentRoomIndex = roomIndex % len(view.roomIDs) view.roomView.SwitchToPage(view.CurrentRoomID()) - view.roomList.SetSelected(view.rooms[view.CurrentRoomID()].Room) + roomView := view.rooms[view.CurrentRoomID()] + if roomView.MessageView().ScrollOffset == 0 { + roomView.Room.MarkRead() + } + view.roomList.SetSelected(roomView.Room) view.gmx.App().SetFocus(view) view.parent.Render() } @@ -367,6 +378,36 @@ func (view *MainView) SetTyping(room string, users []string) { } } +func sendNotification(room *rooms.Room, sender, text string, critical bool) { + if room.GetTitle() != sender { + sender = fmt.Sprintf("%s (%s)", sender, room.GetTitle()) + } + notification.Send(sender, text, critical) +} + +func (view *MainView) NotifyMessage(room *rooms.Room, message *types.Message, should pushrules.PushActionArrayShould) { + isCurrent := room.ID == view.CurrentRoomID() + if !isCurrent { + room.HasNewMessages = true + } + shouldNotify := (should.Notify || !should.NotifySpecified) && message.Sender != view.config.Session.UserID + if shouldNotify { + sendNotification(room, message.Sender, message.Text, should.Highlight) + if !isCurrent { + room.UnreadMessages++ + } + } + if should.Highlight { + message.TextColor = tcell.ColorYellow + if !isCurrent { + room.Highlighted = true + } + } + if should.PlaySound { + // TODO play sound + } +} + func (view *MainView) AddServiceMessage(roomView *widget.RoomView, text string) { message := roomView.NewMessage("", "*", "gomuks.service", text, time.Now()) message.TextColor = tcell.ColorGray diff --git a/ui/widget/message-view.go b/ui/widget/message-view.go index 332af94..e48dddf 100644 --- a/ui/widget/message-view.go +++ b/ui/widget/message-view.go @@ -276,11 +276,11 @@ func getScrollbarStyle(scrollbarHere, isTop, isBottom bool) (char rune, style tc func (view *MessageView) Draw(screen tcell.Screen) { view.Box.Draw(screen) - x, y, width, height := view.GetInnerRect() + x, y, _, height := view.GetInnerRect() view.recalculateBuffers() if len(view.textBuffer) == 0 { - writeLine(screen, tview.AlignLeft, "It's quite empty in here.", x, y+height, width, tcell.ColorDefault) + writeLineSimple(screen, "It's quite empty in here.", x, y+height) return } @@ -294,7 +294,7 @@ func (view *MessageView) Draw(screen tcell.Screen) { if view.LoadingMessages { message = "Loading more messages..." } - writeLine(screen, tview.AlignLeft, message, messageX, y, width, tcell.ColorGreen) + writeLineSimpleColor(screen, message, messageX, y, tcell.ColorGreen) } if len(view.textBuffer) != len(view.metaBuffer) { @@ -339,16 +339,16 @@ func (view *MessageView) Draw(screen tcell.Screen) { text, meta := view.textBuffer[index], view.metaBuffer[index] if meta != prevMeta { if len(meta.GetTimestamp()) > 0 { - writeLine(screen, tview.AlignLeft, meta.GetTimestamp(), x, y+line, width, meta.GetTimestampColor()) + writeLineSimpleColor(screen, meta.GetTimestamp(), x, y+line, meta.GetTimestampColor()) } if prevMeta == nil || meta.GetSender() != prevMeta.GetSender() { - writeLine( + writeLineColor( screen, tview.AlignRight, meta.GetSender(), usernameX, y+line, view.widestSender, meta.GetSenderColor()) } prevMeta = meta } - writeLine(screen, tview.AlignLeft, text, messageX, y+line, width, meta.GetTextColor()) + writeLineSimpleColor(screen, text, messageX, y+line, meta.GetTextColor()) } } diff --git a/ui/widget/room-list.go b/ui/widget/room-list.go index b908510..d2fb543 100644 --- a/ui/widget/room-list.go +++ b/ui/widget/room-list.go @@ -17,6 +17,9 @@ package widget import ( + "fmt" + "strconv" + "github.com/gdamore/tcell" "maunium.net/go/gomuks/matrix/rooms" "maunium.net/go/tview" @@ -104,22 +107,31 @@ func (list *RoomList) Draw(screen tcell.Screen) { text := item.GetTitle() - writeLine(screen, tview.AlignLeft, text, x, y, width, list.mainTextColor) + lineWidth := width - // Background color of selected text. + style := tcell.StyleDefault.Foreground(list.mainTextColor) if item == list.selected { - textWidth := tview.StringWidth(text) - for bx := 0; bx < textWidth && bx < width; bx++ { - m, c, style, _ := screen.GetContent(x+bx, y) - fg, _, _ := style.Decompose() - if fg == list.mainTextColor { - fg = list.selectedTextColor - } - style = style.Background(list.selectedBackgroundColor).Foreground(fg) - screen.SetContent(x+bx, y, m, c, style) + style = style.Foreground(list.selectedTextColor).Background(list.selectedBackgroundColor) + } + if item.HasNewMessages { + style = style.Bold(true) + } + + if item.UnreadMessages > 0 { + unreadMessageCount := "99+" + if item.UnreadMessages < 100 { + unreadMessageCount = strconv.Itoa(item.UnreadMessages) + } + if item.Highlighted { + unreadMessageCount += "!" } + unreadMessageCount = fmt.Sprintf("(%s)", unreadMessageCount) + writeLine(screen, tview.AlignRight, unreadMessageCount, x+lineWidth-6, y, 6, style) + lineWidth -= len(unreadMessageCount) + 1 } + writeLine(screen, tview.AlignLeft, text, x, y, lineWidth, style) + y++ if y >= bottomLimit { break diff --git a/ui/widget/util.go b/ui/widget/util.go index 5bde263..0888210 100644 --- a/ui/widget/util.go +++ b/ui/widget/util.go @@ -22,7 +22,19 @@ import ( "maunium.net/go/tview" ) -func writeLine(screen tcell.Screen, align int, line string, x, y, maxWidth int, color tcell.Color) { +func writeLineSimple(screen tcell.Screen, line string, x, y int) { + writeLine(screen, tview.AlignLeft, line, x, y, 1<<30, tcell.StyleDefault) +} + +func writeLineSimpleColor(screen tcell.Screen, line string, x, y int, color tcell.Color) { + writeLine(screen, tview.AlignLeft, line, x, y, 1<<30, tcell.StyleDefault.Foreground(color)) +} + +func writeLineColor(screen tcell.Screen, align int, line string, x, y, maxWidth int, color tcell.Color) { + writeLine(screen, align, line, x, y, maxWidth, tcell.StyleDefault.Foreground(color)) +} + +func writeLine(screen tcell.Screen, align int, line string, x, y, maxWidth int, style tcell.Style) { offsetX := 0 if align == tview.AlignRight { offsetX = maxWidth - runewidth.StringWidth(line) @@ -37,7 +49,7 @@ func writeLine(screen tcell.Screen, align int, line string, x, y, maxWidth int, } for localOffset := 0; localOffset < chWidth; localOffset++ { - screen.SetContent(x+offsetX+localOffset, y, ch, nil, tcell.StyleDefault.Foreground(color)) + screen.SetContent(x+offsetX+localOffset, y, ch, nil, style) } offsetX += chWidth if offsetX > maxWidth { -- cgit v1.2.3