All unread messages are highlighted with a gray background. This is
currently the same color used on mouse hover, simply because it was easy
to copy.
A channel is marked read when:
* You switch channel (either via mouse or keyboard); or
* you send a message.
This means that new messages _from others in the channel_ will remain
unread until you either:
* send a message; or
* change the current channel.
Future improvements:
* Add a keybinding to mark the channel read (easy-ish)
* Mark a message as read as soon as it's received if the terminal window
(and thus comlink itself) is focused (harder).
* Mark a channel read on window focus (easy-ish).
- This might actually not be nice? I wouldn't want a channel to be
marked read as soon as I focus the window in case there's a long
scrollback I want to catch up on.
---
src/app.zig | 48 +++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/app.zig b/src/app.zig
index c774a3d..444390c 100644
--- a/src/app.zig+++ b/src/app.zig
@@ -760,6 +760,19 @@ pub const App = struct {
channel.has_unread = true;
}
}
++ // If we get a message from the current user mark the channel as+ // read, since they must have just sent the message.+ const sender: []const u8 = blk: {+ const src = msg2.source() orelse break :blk "";+ const l = std.mem.indexOfScalar(u8, src, '!') orelse+ std.mem.indexOfScalar(u8, src, '@') orelse+ src.len;+ break :blk src[0..l];+ };+ if (std.mem.eql(u8, sender, client.config.nick)) {+ self.markSelectedChannelRead();+ } },
}
},
@@ -773,6 +786,10 @@ pub const App = struct {
}
}
pub fn nextChannel(self: *App) void {
+ // When leaving a channel we mark it as read, so we make sure that's done+ // before we change to the new channel.+ self.markSelectedChannelRead();+ const state = self.state.buffers;
if (state.selected_idx >= state.count - 1)
self.state.buffers.selected_idx = 0
@@ -781,6 +798,10 @@ pub const App = struct {
}
pub fn prevChannel(self: *App) void {
+ // When leaving a channel we mark it as read, so we make sure that's done+ // before we change to the new channel.+ self.markSelectedChannelRead();+ switch (self.state.buffers.selected_idx) {
0 => self.state.buffers.selected_idx = self.state.buffers.count - 1,
else => self.state.buffers.selected_idx -|= 1,
@@ -1000,9 +1021,6 @@ pub const App = struct {
.client => {}, // nothing to do
.channel => |channel| {
- // Mark the channel as read- try channel.markRead();- // Request WHO if we don't already have it
if (!channel.who_requested) try channel.client.whox(channel);
@@ -1353,6 +1371,16 @@ pub const App = struct {
item.style.fg = .{ .index = 3 };
}
}
++ // Color the background of unread messages gray.+ if (message.localTime(&self.tz)) |instant| {+ if (instant.unixTimestamp() > channel.last_read) {+ for (segments.items) |*item| {+ item.style.bg = .{ .index = 8 };+ }+ }+ }+ _ = try content_win.print(
segments.items,
.{
@@ -1531,6 +1559,9 @@ pub const App = struct {
});
if (channel_win.hasMouse(self.state.mouse)) |mouse| {
if (mouse.type == .press and mouse.button == .left) {
+ // When leaving a channel we mark it as read, so we make sure that's done+ // before we change to the new channel.+ self.markSelectedChannelRead(); self.state.buffers.selected_idx = row;
}
}
@@ -1865,6 +1896,17 @@ pub const App = struct {
});
}
}
++ fn markSelectedChannelRead(self: *App) void {+ const buffer = self.selectedBuffer() orelse return;++ switch (buffer) {+ .channel => |channel| {+ channel.markRead() catch return;+ },+ else => {},+ }+ }};
/// this loop is run in a separate thread and handles writes to all clients.
--
2.39.5 (Apple Git-154)