-
Notifications
You must be signed in to change notification settings - Fork 60
Mark new messages read on Slack when they arrive in the active channel #159
Description
Problem
When a new message arrives in the channel currently being viewed, slk treats it as read locally but does not advance Slack's server-side read cursor.
The active-channel path in internal/ui/reducer_send.go avoids applying a local unread indicator. However, conversations.mark is only called when entering or loading a channel. Its timestamp therefore covers messages that existed when the channel was opened, not messages received afterward.
This can leave slk showing a message as read while Slack still considers it unread. Besides inconsistent cross-client read state, this may allow Slack to send a mobile notification even though the message is visible in slk.
Selecting a channel inside slk does not necessarily mean the user can currently see it. For example, slk may be running in an inactive terminal, tmux window, or tmux pane while the same channel remains selected.
Expected behavior
When a top-level message or broadcast thread reply arrives in the active channel of the active workspace, slk should advance Slack's read cursor only if the terminal containing slk is currently focused.
If slk is running in an inactive terminal, tmux window, or tmux pane, the message should remain unread both locally and on Slack.
Plain thread replies should continue to use thread-specific read handling and should not advance the parent channel cursor unless broadcast.
Implementation considerations
- Track terminal focus using Bubble Tea's
tea.View.ReportFocusandtea.FocusMsg/tea.BlurMsg. - Require active workspace, active channel, and terminal focus before automatically marking an incoming message read.
- Document that tmux users need
set -g focus-events on. - If focus state is unavailable or unknown, do not automatically mark the message read.
- Send
conversations.markfor eligible messages received in the focused channel. - Serialize or coalesce updates to avoid issuing an unbounded request for every message in a burst.
- Check the HTTP status and Slack JSON response before treating the mark as successful.
- Only update the local persisted read state after Slack accepts the marker.
- Log failures while leaving the message unread locally so the state can be reconciled later.
Relevant code
cmd/slk/main.go:rtmEventHandler.OnMessagecmd/slk/main.go:markChannelReadAsyncinternal/ui/app.go:App.UpdateandApp.Viewinternal/ui/reducer_send.go:reduceNewMessageinternal/slack/client.go:markChannel/MarkChannelwiki/Terminal-Compatibility.md: tmux focus-event setup