Skip to content

Commit

Permalink
message_list: Add buttons for different actions.
Browse files Browse the repository at this point in the history
  • Loading branch information
amanagr committed Sep 18, 2024
1 parent a0d13cc commit 3a70638
Show file tree
Hide file tree
Showing 37 changed files with 534 additions and 181 deletions.
13 changes: 13 additions & 0 deletions templates/zerver/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,19 @@
<div id="page_loading_indicator"></div>
<div id="message_feed_errors_container"></div>
<div id="message-lists-container"></div>
<div id="message-list-navigation">
<div id="message-list-navigation-buttons-wrapper">
<button id="message-list-navigation-mark-as-read" class="message-list-navigation-button tippy-zulip-tooltip" data-tippy-placement="bottom">
Mark as read
</button>
<button id="message-list-navigation-next-unread-conversation" class="message-list-navigation-button">
Next unread conversation
</button>
<button id="message-list-navigation-home-view" class="message-list-navigation-button" data-tippy-placement="bottom-start">
Home view
</button>
</div>
</div>
<div id="scheduled_message_indicator">
</div>
<div id="mark_read_on_scroll_state_banner">
Expand Down
1 change: 1 addition & 0 deletions tools/test-js-with-node
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ EXEMPT_FILES = make_set(
"web/src/message_list_data.ts",
"web/src/message_list_data_cache.ts",
"web/src/message_list_hover.js",
"web/src/message_list_navigation.ts",
"web/src/message_list_tooltips.ts",
"web/src/message_list_view.ts",
"web/src/message_lists.ts",
Expand Down
23 changes: 23 additions & 0 deletions web/src/browser_history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,26 @@ export function update_current_history_state_data(new_data: StateData): void {
const state_data = {...current_state_data, ...new_data};
window.history.replaceState(state_data, "", window.location.href);
}

export function get_home_view_hash(): string {
let home_view_hash = `#${user_settings.web_home_view}`;
if (home_view_hash === "#recent_topics") {
home_view_hash = "#recent";
}

if (home_view_hash === "#all_messages") {
home_view_hash = "#feed";
}

return home_view_hash;
}

export function is_current_hash_home_view(): boolean {
const current_hash = window.location.hash;
if (current_hash === "") {
// Empty hash for home view is always valid.
return true;
}

return current_hash === get_home_view_hash();
}
10 changes: 10 additions & 0 deletions web/src/click_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,16 @@ export function initialize() {

// MISC

$("#message-list-navigation-next-unread-conversation").on("click", () => {
assert(message_lists.current !== undefined);

if (message_lists.current.data.filter.can_show_next_unread_dm_conversation_button()) {
message_view.narrow_to_next_pm_string({trigger: "hotkey"});
} else {
message_view.narrow_to_next_topic({trigger: "hotkey", only_followed_topics: false});
}
});

{
const sel = [
"#stream_filters",
Expand Down
26 changes: 26 additions & 0 deletions web/src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,32 @@ export class Filter {
});
}

can_show_next_unread_topic_conversation_button(): boolean {
const term_type = this.sorted_term_types();
if (
_.isEqual(term_type, ["channel", "topic", "near"]) ||
_.isEqual(term_type, ["channel", "topic", "with"]) ||
_.isEqual(term_type, ["channel", "topic"]) ||
_.isEqual(term_type, ["channel"])
) {
return true;
}
return false;
}

can_show_next_unread_dm_conversation_button(): boolean {
const term_type = this.sorted_term_types();
if (
_.isEqual(term_type, ["dm", "near"]) ||
_.isEqual(term_type, ["dm", "with"]) ||
_.isEqual(term_type, ["dm"]) ||
_.isEqual(term_type, ["is-dm"])
) {
return true;
}
return false;
}

is_conversation_view(): boolean {
const term_type = this.sorted_term_types();
if (
Expand Down
53 changes: 20 additions & 33 deletions web/src/hashchange.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,44 +91,31 @@ function get_user_settings_tab(section) {
}

export function set_hash_to_home_view(triggered_by_escape_key = false) {
const current_hash = window.location.hash;
if (current_hash === "") {
// Empty hash for home view is always valid.
if (browser_history.is_current_hash_home_view()) {
return;
}

let home_view_hash = `#${user_settings.web_home_view}`;
if (home_view_hash === "#recent_topics") {
home_view_hash = "#recent";
}

if (home_view_hash === "#all_messages") {
home_view_hash = "#feed";
const hash_before_current = browser_history.old_hash();
if (
triggered_by_escape_key &&
browser_history.get_home_view_hash() === "#feed" &&
(hash_before_current === "" || hash_before_current === "#feed")
) {
// If the previous view was the user's Combined Feed home
// view, and this change was triggered by escape keypress,
// then we simulate the back button in order to reuse
// existing code for restoring the user's scroll position.
window.history.back();
return;
}

if (current_hash !== home_view_hash) {
const hash_before_current = browser_history.old_hash();
if (
triggered_by_escape_key &&
home_view_hash === "#feed" &&
(hash_before_current === "" || hash_before_current === "#feed")
) {
// If the previous view was the user's Combined Feed home
// view, and this change was triggered by escape keypress,
// then we simulate the back button in order to reuse
// existing code for restoring the user's scroll position.
window.history.back();
return;
}

// We want to set URL with no hash here. It is not possible
// to do so with `window.location.hash` since it will set an empty
// hash. So, we use `pushState` which simply updates the current URL
// but doesn't trigger `hashchange`. So, we trigger hashchange directly
// here to let it handle the whole rendering process for us.
browser_history.set_hash("");
hashchanged(false);
}
// We want to set URL with no hash here. It is not possible
// to do so with `window.location.hash` since it will set an empty
// hash. So, we use `pushState` which simply updates the current URL
// but doesn't trigger `hashchange`. So, we trigger hashchange directly
// here to let it handle the whole rendering process for us.
browser_history.set_hash("");
hashchanged(false);
}

function show_home_view() {
Expand Down
11 changes: 11 additions & 0 deletions web/src/hotkey.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import * as list_util from "./list_util";
import * as message_actions_popover from "./message_actions_popover";
import * as message_edit from "./message_edit";
import * as message_edit_history from "./message_edit_history";
import * as message_list_navigation from "./message_list_navigation";
import * as message_lists from "./message_lists";
import * as message_scroll_state from "./message_scroll_state";
import * as message_view from "./message_view";
Expand Down Expand Up @@ -64,6 +65,7 @@ import * as user_card_popover from "./user_card_popover";
import * as user_group_popover from "./user_group_popover";
import {user_settings} from "./user_settings";
import * as user_topics_ui from "./user_topics_ui";
import * as views_util from "./views_util";

function do_narrow_action(action) {
if (message_lists.current === undefined) {
Expand Down Expand Up @@ -695,6 +697,15 @@ export function process_hotkey(e, hotkey) {
}
}

switch (event_name) {
case "right_arrow":
case "left_arrow":
// TODO: Implement tab and shift-tab support.
if (message_lists.current?.navigation_bar_focused && views_util.is_in_focus()) {
return message_list_navigation.handle_hotkey(event_name);
}
}

// We handle the most complex keys in their own functions.
switch (event_name) {
case "escape":
Expand Down
2 changes: 2 additions & 0 deletions web/src/message_fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as message_feed_loading from "./message_feed_loading";
import * as message_feed_top_notices from "./message_feed_top_notices";
import * as message_helper from "./message_helper";
import type {MessageListData} from "./message_list_data";
import * as message_list_navigation from "./message_list_navigation";
import * as message_lists from "./message_lists";
import {raw_message_schema} from "./message_store";
import * as message_util from "./message_util";
Expand Down Expand Up @@ -129,6 +130,7 @@ function process_result(data: MessageFetchResponse, opts: MessageFetchOptions):
direct_message_group_data.process_loaded_messages(messages);
stream_list.update_streams_sidebar();
stream_list.maybe_scroll_narrow_into_view();
message_list_navigation.update();

if (
message_lists.current !== undefined &&
Expand Down
23 changes: 23 additions & 0 deletions web/src/message_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ export class MessageList {
// the user. Possibly this can be unified in some nice way.
this.reading_prevented = false;

// Tracks if the message list is visibly focused (has blue border
// around the selected message) or if the navigation buttons at
// the bottom of the feed are focused.
this.navigation_bar_focused = false;

return this;
}

Expand Down Expand Up @@ -335,11 +340,19 @@ export class MessageList {
opts.id = id;
this.data.set_selected_id(id);

if (!this.navigation_bar_focused) {
// Unfocus navigation bar when navigation to a new message list
this.unfocus_navigation_bar();
}

// Avoid recursive calls to message_selected event
// by temporarily blocking triggering the event by
// setting `should_trigger_message_selected_event`.
if (opts.force_rerender) {
this.should_trigger_message_selected_event = false;
if (this.last()?.id === this.selected_id()) {
this.focus_navigation_bar();
}
this.rerender();
this.should_trigger_message_selected_event = true;
} else if (!opts.from_rendering) {
Expand All @@ -353,6 +366,16 @@ export class MessageList {
}
}

focus_navigation_bar() {
this.navigation_bar_focused = true;
this.view.focus_navigation_bar();
}

unfocus_navigation_bar() {
this.navigation_bar_focused = false;
this.view.unfocus_navigation_bar();
}

selected_message() {
return this.get(this.data.selected_id());
}
Expand Down
Loading

0 comments on commit 3a70638

Please sign in to comment.