inbox_ui: Clarify inbox state when all sections are collapsed.

It was reported that the UI is pretty confusing when there is
just a collapsed folder in inbox view.

To address this issue, we now show a note below the folders in
following two situations:
  - All folders collapsed.
  - If all folders are not collapsed, all visible channels
    are collapsed.

Fixes: #35555
This commit is contained in:
whilstsomebody
2025-08-01 11:27:46 +05:30
committed by Tim Abbott
parent 21c1c24908
commit d0207a4297
3 changed files with 103 additions and 0 deletions

View File

@@ -1246,6 +1246,7 @@ export function complete_rerender(): void {
get_options: inbox_view_dropdown_options,
});
filters_dropdown_widget.setup();
update_collapsed_note_visibility();
});
}
@@ -1333,6 +1334,68 @@ export function collapse_or_expand(container_id: string): void {
}
save_data_to_ls();
update_collapsed_note_visibility();
}
// We show the note "All of your unread conversations are hidden.
// Click on a section, folder, or channel to see what's inside" for
// the following situations:
// - All folders collapsed.
// - If all folders are not collapsed, all visible channels are collapsed.
// For all other cases, the note is hidden.
function should_show_all_folders_collapsed_note(): boolean {
// TODO: Ideally this would read from internal structures, not the DOM.
const has_visible_dm_folder = !$("#inbox-dm-header").hasClass("hidden_by_filters");
if (has_visible_dm_folder && !collapsed_containers.has("inbox-dm-header")) {
// Some DM content is visible.
return false;
}
const visible_folders = [...channel_folders_dict.values()].filter(
(folder) => folder.is_header_visible,
);
if (visible_folders.length === 0) {
// Nothing at all is visible; the empty inbox message takes
// precedence.
return false;
}
// At least one uncollapsed row is visible in some folder.
const has_expanded_content = visible_folders.some((folder) => {
if (!collapsed_containers.has(folder.header_id)) {
const folder_streams = [...streams_dict.values()].filter(
(stream) => stream.folder_id === folder.id && !stream.is_hidden,
);
return folder_streams.some(
(stream) => !collapsed_containers.has(STREAM_HEADER_PREFIX + stream.stream_id),
);
}
return false;
});
return !has_expanded_content;
}
function update_collapsed_note_visibility(): void {
if (should_show_all_folders_collapsed_note()) {
$("#inbox-collapsed-note").show();
} else {
$("#inbox-collapsed-note").hide();
}
}
function expand_all_folders_and_channels(): void {
$(
"#inbox-list .inbox-folder.inbox-collapsed-state:not(.hidden_by_filters), .inbox-streams-container .inbox-header.inbox-collapsed-state:not(.hidden_by_filters)",
).each(function () {
const container_id = $(this).attr("id");
if (container_id) {
$(this).removeClass("inbox-collapsed-state");
collapsed_containers.delete(container_id);
}
});
save_data_to_ls();
update_collapsed_note_visibility();
}
function focus_current_id(): void {
@@ -2034,6 +2097,7 @@ export function update(): void {
revive_current_focus();
}
}
update_collapsed_note_visibility();
}
function get_focus_class_for_header(): string {
@@ -2224,6 +2288,12 @@ export function initialize({hide_other_views}: {hide_other_views: () => void}):
}
});
$("body").on("click", "#inbox-collapsed-note #inbox-expand-all-button", (e) => {
e.preventDefault();
e.stopPropagation();
expand_all_folders_and_channels();
});
$("body").on("click", "#inbox-list .inbox-left-part-wrapper", function (this: HTMLElement, e) {
if (e.metaKey || e.ctrlKey || e.shiftKey) {
return;

View File

@@ -335,6 +335,29 @@
}
}
#inbox-collapsed-note {
display: none;
overflow: hidden;
max-width: calc(
var(--width-inbox-search) +
var(--width-inbox-filters-dropdown) + 0.25em
);
.inbox-collapsed-note-and-button-wrapper {
margin-top: 3px;
padding-left: 8px;
.inbox-collpased-note-span {
font-size: 1em;
}
#inbox-expand-all-button {
display: block;
margin-top: 5px;
}
}
}
.inbox-right-part-wrapper {
display: flex;
align-items: center;

View File

@@ -27,6 +27,16 @@
{{> inbox_list .}}
{{/if}}
</div>
<div id="inbox-collapsed-note">
<div class="inbox-collapsed-note-and-button-wrapper">
<span class="inbox-collpased-note-span">
{{t "All unread conversations are hidden. Click on a section, folder, or channel to expand it."}}
</span>
<button id="inbox-expand-all-button" class="action-button action-button-quiet-neutral" tabindex="0">
<span class="action-button-label">{{t "Show all"}}</span>
</button>
</div>
</div>
<div id="inbox-loading-indicator">
{{#unless normal_view}}
{{> ../view_bottom_loading_indicator}}