Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions crates/tinyclient/src/gui/sidebar/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub struct Home {
/// The Telegram folder chosen, by id.
pub folder: Option<String>,
pub loaded: bool,
/// The home has completed a read; sublist loading keeps its cached rows ready.
pub loaded_once: bool,
pub epoch: u64,
// The user's folds, for this session.
pub dms_all: bool,
Expand Down Expand Up @@ -133,6 +135,10 @@ fn header(out: &mut Vec<Item>, label: &'static str) {
/// user's order with folders. `open_space`: the Space of the open conversation. `unread`: the
/// Unread segment, which keeps only what has news.
pub fn discord(home: &Home, spaces: &[Space], open_space: Option<&str>, unread: bool) -> Vec<Item> {
// Spaces arrive separately. Showing them before chats inserts DMs above visible rows.
if !home.loaded_once {
return Vec::new();
}
let mut out = Vec::new();
if !unread || home.friend_requests > 0 {
let after = if home.online > 0 { format!("{} online", home.online) } else { String::new() };
Expand Down Expand Up @@ -402,13 +408,49 @@ mod tests {
in_voice: (0..5).map(|n| chat(&format!("v{n}"), 0)).collect(),
requests: 2,
online: 6,
loaded: true,
loaded_once: true,
..Home::for_network(Network::Discord)
};
let got = shape(&discord(&home, &spaces, None, false), &spaces);
assert_eq!(got, ["<Friends>", "<Message requests>", "[In voice]", "v0", "v1", "v2", "<2 more>", "[Direct messages]", "ines", "kofi", "[Servers]", "moss"]);
assert_eq!(shape(&discord(&home, &spaces, None, true), &spaces), ["[Direct messages]", "ines"]);
}

#[test]
fn discord_waits_for_chats_before_showing_cached_servers() {
let spaces = [space("moss", None, 0, false)];
let mut home = Home::for_network(Network::Discord);
assert!(discord(&home, &spaces, None, false).is_empty());
assert!(discord(&home, &spaces, None, true).is_empty());

home.chats = vec![chat("ines", 1)];
home.loaded = true;
home.loaded_once = true;
let ready = shape(&discord(&home, &spaces, None, false), &spaces);
assert_eq!(ready, ["<Friends>", "[Direct messages]", "ines", "[Servers]", "moss"]);
// Refreshes and sublist loading keep the cached home ready.
home.epoch += 1;
home.loaded = false;
assert_eq!(shape(&discord(&home, &spaces, None, false), &spaces), ready);
}

#[test]
fn discord_shows_servers_after_a_completed_empty_chat_read() {
let spaces = [space("moss", None, 0, false)];
let home = Home { loaded: true, loaded_once: true, ..Home::for_network(Network::Discord) };
assert_eq!(shape(&discord(&home, &spaces, None, false), &spaces), ["<Friends>", "[Servers]", "moss"]);
}

#[test]
fn discord_servers_arriving_after_chats_append_below_them() {
let home = Home { loaded: true, loaded_once: true, chats: vec![chat("ines", 0)], ..Home::for_network(Network::Discord) };
let chats = shape(&discord(&home, &[], None, false), &[]);
let spaces = [space("moss", None, 0, false)];
let complete = shape(&discord(&home, &spaces, None, false), &spaces);
assert!(complete.starts_with(&chats));
}

#[test]
fn teams_keeps_quiet_meetings_in_their_fold_and_shows_unread_channels_of_closed_teams() {
const NOW: i64 = 100 * 86_400;
Expand Down
1 change: 1 addition & 0 deletions crates/tinyclient/src/gui/sidebar/home_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ impl Shell {
home.archive_total = read.archive_total;
home.drilled = rows(read.drilled);
home.loaded = true;
home.loaded_once = true;
this.rebuild_home(cx);
});
}
Expand Down
6 changes: 6 additions & 0 deletions docs/design/polish/02-discord-slack.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ Opens in the sidebar from the Threads row (`‹ Threads`, workspace name `text_f
| `Unread` segment | check glyph, "Nothing unread", "3 muted channels have new messages" · Show them | n/a | n/a |
| Threads | "No new replies" · "Threads you follow show here when someone replies." | five 48 skeletons | banner "Couldn't load threads" + Try again over saved rows |

The first Discord home remains in its loading state until its chat read finishes,
even when cached servers arrive sooner. DMs then appear above servers in the
normal order. A completed empty DM read still shows servers. Once the home has
loaded, background refreshes keep its existing rows visible, including when
returning from a sublist.

## New tokens
For reconciliation with `polish/01-system.md`: `LEAD 20` (leading box of every 28 row), `NAME_X 36`, `INDENT_CHILD 12`, `INDENT_SUB 28`; `tag` component (16, r4, 11/500, `text_soft` on `quiet_fill`, which survives here only as the tag fill); `folder_spine` (the folder's own colour at 70%, 3 wide); `sticky_header` (`sidebar` fill, no rule, per C8). **Divergence to reconcile**: C9 puts DMs in homes on 48 rows; Slack DMs stay 28 because they sit in the user's sections beside channels in one `uniform_list` (Slack's own structure, ruling 1). Discord DMs are 48. Glyphs added: mail, phone, radio, image, building-2, calendar, headphones, headphone-off, monitor, eye, list, moon, smile, log-out, external-link, check-check, wifi-off.

Expand Down
Loading