mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			141 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import * as message_lists from "./message_lists";
 | |
| import * as message_viewport from "./message_viewport";
 | |
| import * as rows from "./rows";
 | |
| import * as unread_ops from "./unread_ops";
 | |
| 
 | |
| function go_to_row(msg_id) {
 | |
|     message_lists.current.select_id(msg_id, {then_scroll: true, from_scroll: true});
 | |
| }
 | |
| 
 | |
| export function up() {
 | |
|     message_viewport.set_last_movement_direction(-1);
 | |
|     const msg_id = message_lists.current.prev();
 | |
|     if (msg_id === undefined) {
 | |
|         return;
 | |
|     }
 | |
|     go_to_row(msg_id);
 | |
| }
 | |
| 
 | |
| export function down(with_centering) {
 | |
|     message_viewport.set_last_movement_direction(1);
 | |
| 
 | |
|     if (message_lists.current.is_at_end()) {
 | |
|         if (with_centering) {
 | |
|             // At the last message, scroll to the bottom so we have
 | |
|             // lots of nice whitespace for new messages coming in.
 | |
|             const $current_msg_table = rows.get_table(message_lists.current.table_name);
 | |
|             message_viewport.scrollTop(
 | |
|                 $current_msg_table.safeOuterHeight(true) - message_viewport.height() * 0.1,
 | |
|             );
 | |
|             unread_ops.process_scrolled_to_bottom();
 | |
|         }
 | |
| 
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     // Normal path starts here.
 | |
|     const msg_id = message_lists.current.next();
 | |
|     if (msg_id === undefined) {
 | |
|         return;
 | |
|     }
 | |
|     go_to_row(msg_id);
 | |
| }
 | |
| 
 | |
| export function to_home() {
 | |
|     message_viewport.set_last_movement_direction(-1);
 | |
|     const first_id = message_lists.current.first().id;
 | |
|     message_lists.current.select_id(first_id, {then_scroll: true, from_scroll: true});
 | |
| }
 | |
| 
 | |
| export function to_end() {
 | |
|     const next_id = message_lists.current.last().id;
 | |
|     message_viewport.set_last_movement_direction(1);
 | |
|     message_lists.current.select_id(next_id, {then_scroll: true, from_scroll: true});
 | |
|     unread_ops.process_scrolled_to_bottom();
 | |
| }
 | |
| 
 | |
| function amount_to_paginate() {
 | |
|     // Some day we might have separate versions of this function
 | |
|     // for Page Up vs. Page Down, but for now it's the same
 | |
|     // strategy in either direction.
 | |
|     const info = message_viewport.message_viewport_info();
 | |
|     const page_size = info.visible_height;
 | |
| 
 | |
|     // We don't want to page up a full page, because Zulip users
 | |
|     // are especially worried about missing messages, so we want
 | |
|     // a little bit of the old page to stay on the screen.  The
 | |
|     // value chosen here is roughly 2 or 3 lines of text, but there
 | |
|     // is nothing sacred about it, and somebody more anal than me
 | |
|     // might wish to tie this to the size of some particular DOM
 | |
|     // element.
 | |
|     const overlap_amount = 55;
 | |
| 
 | |
|     let delta = page_size - overlap_amount;
 | |
| 
 | |
|     // If the user has shrunk their browser a whole lot, pagination
 | |
|     // is not going to be very pleasant, but we can at least
 | |
|     // ensure they go in the right direction.
 | |
|     if (delta < 1) {
 | |
|         delta = 1;
 | |
|     }
 | |
| 
 | |
|     return delta;
 | |
| }
 | |
| 
 | |
| export function page_up_the_right_amount() {
 | |
|     // This function's job is to scroll up the right amount,
 | |
|     // after the user hits Page Up.  We do this ourselves
 | |
|     // because we can't rely on the browser to account for certain
 | |
|     // page elements, like the compose box, that sit in fixed
 | |
|     // positions above the message pane.  For other scrolling
 | |
|     // related adjustments, try to make those happen in the
 | |
|     // scroll handlers, not here.
 | |
|     const delta = amount_to_paginate();
 | |
|     message_viewport.scrollTop(message_viewport.scrollTop() - delta);
 | |
| }
 | |
| 
 | |
| export function page_down_the_right_amount() {
 | |
|     // see also: page_up_the_right_amount
 | |
|     const delta = amount_to_paginate();
 | |
|     message_viewport.scrollTop(message_viewport.scrollTop() + delta);
 | |
| }
 | |
| 
 | |
| export function page_up() {
 | |
|     if (message_viewport.at_top() && !message_lists.current.empty()) {
 | |
|         message_lists.current.select_id(message_lists.current.first().id, {then_scroll: false});
 | |
|     } else {
 | |
|         page_up_the_right_amount();
 | |
|     }
 | |
| }
 | |
| 
 | |
| export function page_down() {
 | |
|     if (message_viewport.at_bottom() && !message_lists.current.empty()) {
 | |
|         message_lists.current.select_id(message_lists.current.last().id, {then_scroll: false});
 | |
|         unread_ops.process_scrolled_to_bottom();
 | |
|     } else {
 | |
|         page_down_the_right_amount();
 | |
|     }
 | |
| }
 | |
| 
 | |
| export function scroll_to_selected() {
 | |
|     const $selected_row = message_lists.current.selected_row();
 | |
|     if ($selected_row && $selected_row.length !== 0) {
 | |
|         message_viewport.recenter_view($selected_row);
 | |
|     }
 | |
| }
 | |
| 
 | |
| let scroll_to_selected_planned = false;
 | |
| 
 | |
| export function plan_scroll_to_selected() {
 | |
|     scroll_to_selected_planned = true;
 | |
| }
 | |
| 
 | |
| export function maybe_scroll_to_selected() {
 | |
|     // If we have made a plan to scroll to the selected message but
 | |
|     // deferred doing so, do so here.
 | |
|     if (scroll_to_selected_planned) {
 | |
|         scroll_to_selected();
 | |
|         scroll_to_selected_planned = false;
 | |
|     }
 | |
| }
 |