mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 06:23:38 +00:00
Expand pointer and unread counts guide.
This commit is contained in:
111
docs/pointer.md
111
docs/pointer.md
@@ -1,40 +1,54 @@
|
|||||||
# Pointer and unread counts
|
# Unread counts and the pointer
|
||||||
|
|
||||||
When you're using Zulip and you reload, or narrow to a stream, how
|
When you're using Zulip and you reload, or narrow to a stream, how
|
||||||
does Zulip decide where to place you?
|
does Zulip decide where to place you?
|
||||||
|
|
||||||
In general, Zulip takes you to the place where you left off (e.g. the
|
Conceptually, Zulip takes you to the place where you left off
|
||||||
first unread message), not the most recent messages, to facilitate
|
(e.g. the first unread message), not the most recent messages, to
|
||||||
reviewing all the discussions that happened while you were away from
|
facilitate reviewing all the discussions that happened while you were
|
||||||
your computer. The scroll position is then set to keep that message in
|
away from your computer. The scroll position is then set to keep that
|
||||||
view and away from both the top and bottom of the visible section of
|
message in view and away from both the top and bottom of the visible
|
||||||
messages.
|
section of messages.
|
||||||
|
|
||||||
But there a lot of details around doing this right, and around
|
But there a lot of details around doing this right, and around
|
||||||
counting unread messages. Here's how Zulip decides which message to
|
counting unread messages. Here's how Zulip currently decides which
|
||||||
select.
|
message to select, along with some notes on improvements we'd like to
|
||||||
|
make to the model.
|
||||||
|
|
||||||
## Recipient bar: message you clicked
|
First a bit of terminology:
|
||||||
|
|
||||||
|
* "Narrowing" is the process of filtering to a particular subset of
|
||||||
|
the messages the user has access to.
|
||||||
|
|
||||||
|
* The blue cursor box (the "pointer") is around is called the
|
||||||
|
"selected" message. Zulip ensures that the currently selected
|
||||||
|
message is always in-view.
|
||||||
|
|
||||||
|
## Pointer logic
|
||||||
|
|
||||||
|
### Recipient bar: message you clicked
|
||||||
|
|
||||||
If you enter a narrow by clicking on a message group's *recipient bar*
|
If you enter a narrow by clicking on a message group's *recipient bar*
|
||||||
(stream/topic or private message recipient list at the top of a group
|
(stream/topic or private message recipient list at the top of a group
|
||||||
of messages), Zulip will center the new narrow around the message you
|
of messages), Zulip will select the the message you clicked on. This
|
||||||
clicked on. This provides a nice user experience where you get to see
|
provides a nice user experience where you get to see the stuff near
|
||||||
the stuff near what you clicked on.
|
what you clicked on, and in fact the message you clicked on stays at
|
||||||
|
exactly the same scroll position in the window after the narrowing as
|
||||||
|
it was at before.
|
||||||
|
|
||||||
## Search or sidebar click: unread/recent matching narrow
|
### Search or sidebar click: unread/recent matching narrow
|
||||||
|
|
||||||
If you instead narrow by clicking on something in the left sidebar or
|
If you instead narrow by clicking on something in the left sidebar or
|
||||||
typing some terms into the search box, Zulip will instead focus on the
|
typing some terms into the search box, Zulip will instead selected on
|
||||||
first unread message matching that narrow, or if there are none, the
|
the first unread message matching that narrow, or if there are none,
|
||||||
most recent messages matching that narrow. This provides the nice user
|
the most recent messages matching that narrow. This provides the nice
|
||||||
experience of taking you to the start of the new stuff (with maybe a
|
user experience of taking you to the start of the new stuff (with
|
||||||
bit of old stuff still in view at the top), which is usually what you
|
enough messages you'ev seen before still in view at the top to provide
|
||||||
want. (When finding the "first unread message", Zulip ignores unread
|
you with context), which is usually what you want. (When finding the
|
||||||
messages in muted streams or in muted topics within non-muted
|
"first unread message", Zulip ignores unread messages in muted streams
|
||||||
streams.)
|
or in muted topics within non-muted streams.)
|
||||||
|
|
||||||
## Unnarrow: previous sequence
|
### Unnarrow: previous sequence
|
||||||
|
|
||||||
When you unnarrow using e.g. the escape key, you will automatically be
|
When you unnarrow using e.g. the escape key, you will automatically be
|
||||||
taken to the same message that was selected in the home view before
|
taken to the same message that was selected in the home view before
|
||||||
@@ -44,32 +58,53 @@ message in the home view (or the bottom of the feed if there is
|
|||||||
none). This makes for a nice experience reading threads via the home
|
none). This makes for a nice experience reading threads via the home
|
||||||
view in sequence.
|
view in sequence.
|
||||||
|
|
||||||
## New home view: "high watermark"
|
### New home view: "high watermark"
|
||||||
|
|
||||||
When you open a new browser window or tab to the home view (a.k.a. the
|
When you open a new browser window or tab to the home view (a.k.a. the
|
||||||
interleaved view you get if you visit `/`), Zulip will take you to the
|
interleaved view you get if you visit `/`), Zulip will select the
|
||||||
highest message ID (a.k.a. "high watermark") that your cursor has ever
|
furthest down that your cursor has ever reached in the home
|
||||||
reached in the home view (called the *"pointer"* in the Zulip
|
view. Because of the logic around unnarrowing in the last bullet, this
|
||||||
API). Because of the logic around unnarrowing in the last bullet, this
|
is usually just before the first unread message in the home view, but
|
||||||
is usually the same as the first unread message in the home view, but
|
|
||||||
if you never go to the home view, or you leave messages unread on some
|
if you never go to the home view, or you leave messages unread on some
|
||||||
streams in your home view, this can lag.
|
streams in your home view, this can lag.
|
||||||
|
|
||||||
## Narrow in a new tab: closest to pointer
|
We plan to change this to automatically advance the pointer in a way
|
||||||
|
similar to the unnarrow logic.
|
||||||
|
|
||||||
|
### Narrow in a new tab: closest to pointer
|
||||||
|
|
||||||
When you load a new browser tab or window to a narrowed view, Zulip
|
When you load a new browser tab or window to a narrowed view, Zulip
|
||||||
will take you to the message closest to your pointer, which is what
|
will select the message closest to your pointer, which is what you
|
||||||
you would have got had you loaded the browser window to your home view
|
would have got had you loaded the browser window to your home view and
|
||||||
and then clicked on the nearest message matching your narrow (which
|
then clicked on the nearest message matching your narrow (which might
|
||||||
might have been offscreen).
|
have been offscreen).
|
||||||
|
|
||||||
## Forced reload: historical recreation
|
We plan to change this to match the Search/sidebar behavior.
|
||||||
|
|
||||||
|
### Forced reload: state preservation
|
||||||
|
|
||||||
When the server forces a reload of a browser that's otherwise caught
|
When the server forces a reload of a browser that's otherwise caught
|
||||||
up (which happens within 30 minutes when a new version of the server
|
up (which happens within 30 minutes when a new version of the server
|
||||||
is deployed), Zulip will try to take the user back to the exact same
|
is deployed, usually at a type when the user isn't looking at the
|
||||||
place where you were before the server-initiated reload, in every way
|
browser), Zulip will preserve the state -- what (if any) narrow the
|
||||||
(same selected message, and even the same exact scroll position!).
|
user was in, the selected message, and even exact scroll position!
|
||||||
|
|
||||||
For more on the user experience philosophy guiding these decisions,
|
For more on the user experience philosophy guiding these decisions,
|
||||||
see [the architectural overview](architecture-overview.html).
|
see [the architectural overview](architecture-overview.html).
|
||||||
|
|
||||||
|
## Unread count logic
|
||||||
|
|
||||||
|
How does Zulip decide whether a message has been read by the user?
|
||||||
|
The algorithm needs to correctly handle a range of ways people might
|
||||||
|
use the product. The algorithm is as follows:
|
||||||
|
|
||||||
|
* Any message which is selected or above a message which is selected
|
||||||
|
is marked as read. So messages are marked as read as you scroll
|
||||||
|
down the keyboard when the pointer passes over them.
|
||||||
|
|
||||||
|
* If the whitspace at the very bottom of the feed is in view, all
|
||||||
|
messages in view are marked as read.
|
||||||
|
|
||||||
|
These two simple rules, combined with the pointer logic above, end up
|
||||||
|
matching user expectations well for whether the product should treat
|
||||||
|
them as having read a set of messages (or not).
|
||||||
|
|||||||
Reference in New Issue
Block a user