Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use html as scroll container for recent view. #30134

Merged
merged 3 commits into from
Jun 7, 2024

Conversation

amanagr
Copy link
Member

@amanagr amanagr commented May 19, 2024

discussion: https://chat.zulip.org/#narrow/stream/9-issues/topic/recent.20conversations.20loses.20filter.20checkboxes

Things I tested:

  • No topics
  • only 1 topic
  • Filters work as expected.
  • Compose reply works
  • Page up / down works
  • focus changes correctly when navigating rows at the edge of visible area.
  • load more works correctly.
  • Recent view -> messages narrow -> recent view correctly preserves row focus
  • Loading to Combined feed -> recent view correctly sets focus to first row.
  • Initial loading indicator when no messages are fetched is displayed correctly.
Screenshot 2024-05-20 at 4 48 14 PM

@amanagr amanagr changed the title [WIP] Use html as scroll container from recent view. [WIP] Use html as scroll container for recent view. May 19, 2024
@zulip zulip deleted a comment from sentry-io bot May 19, 2024
@amanagr amanagr force-pushed the rt_scroll_html branch 2 times, most recently from 42bf7aa to 6de22ad Compare May 20, 2024 11:10
@amanagr amanagr changed the title [WIP] Use html as scroll container for recent view. Use html as scroll container for recent view. May 20, 2024
@alya
Copy link
Contributor

alya commented May 20, 2024

Works for me in light manual testing!

amanagr added a commit to amanagr/zulip that referenced this pull request May 22, 2024
The bug is hard to reproduce, but I was able to reproduce with zulip#30134
and used the same strategy to fix it here.
amanagr added a commit to amanagr/zulip that referenced this pull request May 23, 2024
The bug is hard to reproduce, but I was able to reproduce with zulip#30134
and used the same strategy to fix it here.
timabbott pushed a commit to amanagr/zulip that referenced this pull request May 23, 2024
The bug is hard to reproduce, but I was able to reproduce with zulip#30134
and used the same strategy to fix it here.
timabbott pushed a commit that referenced this pull request May 23, 2024
The bug is hard to reproduce, but I was able to reproduce with #30134
and used the same strategy to fix it here.
@amanagr
Copy link
Member Author

amanagr commented May 30, 2024

Pushed to resolve conflicts.

@timabbott
Copy link
Sponsor Member

Test-deploying this on chat.zulip.org.

@timabbott timabbott added the deployed on chat.zulip.org Added by maintainers when a PR is currently being tested on chat.zulip.org. label Jun 3, 2024
@amanagr amanagr force-pushed the rt_scroll_html branch 7 times, most recently from 0e3bc2d to b9997d1 Compare June 5, 2024 19:08
// TypeEventHandlers<HTMLElement, any, any, any> which is confusing.
//
// @ts-expect-error Maybe JQuery<Window>.TypeEventHandlers is not defined?
meta.$scroll_event_handler.off("scroll.list_widget_container");
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you start a #frontend thread about this? Seems like something is wrong here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, seems like it'll be OK to address in a quick follow-up, so not going to block merging on this.

@@ -261,6 +262,13 @@ export function create<Key, Item = Key>(
old_widget.clear_event_handlers();
}

// When `html` is the scroll container, scroll event is fired on `window`.
// TODO: Add an online reference for this since it's not intuitive.
Copy link
Sponsor Member

@timabbott timabbott Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the proposal in this comment, or the purpose of this block in general.

Also why is this called $scroll_event_handler? To me that really sounds like a function, not a DOM element; how does this differ from $scroll_container? Probably you just want a clear naming distinction between the two.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed $scroll_event_handler to $scroll_listening_element.

Modified the comment to be more clear:

    // When `html` is is `$scroll_container`, scroll event is fired on `window/document`.
    // This is because when a scroll event happens on the body or html element,
    // the event is fired on the document object, not the body or html element itself.
    // We still keep `html` as `$scroll_container` to use it's various methods as `HTMLElement`.

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified and moved this inside the conditional block:

    if ($scroll_listening_element.is("html")) {                                      
        // When `$scroll_container` is the entire page (`html`),                     
        // scroll events are fired on `window/document`, so we need to               
        // listen for scrolling events on that.                                      
        //                                                                           
        // We still keep `html` as `$scroll_container` to use                        
        // its various methods as `HTMLElement`.                                     
        $scroll_listening_element = $(window);                                       
    }                                                                                

const compose_max_height = $("html").css("--max-unexpanded-compose-height");
assert(typeof compose_max_height === "string");
const scroll_max = document.body.scrollHeight - Number.parseInt(compose_max_height, 10);
return scroll_position + scroll_height >= (2 / 3) * scroll_max;
}
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you tweak this function to document why --max-unexpanded-compose-height is the right compose height to use?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this comment:

    // `--max-unexpanded-compose-height` is just empty space below the last rendered row
    // in recent view. We don't want user to see this empty space until there are no new
    // rows to render when the user is scrolling to the bottom of the view. So, we render new
    // rows when user has scrolled 2 / 3 of (the total scrollable height - the empty space).

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, made some small edits and line-wrapped it.

web/src/recent_view_ui.ts Outdated Show resolved Hide resolved
@timabbott
Copy link
Sponsor Member

This looks pretty good; posted a round of reviews and wanted to note that I think we can merge this after completing those.

@amanagr
Copy link
Member Author

amanagr commented Jun 7, 2024

Updated based on feedback.

}
meta.$scroll_listening_element.on(
"scroll.list_widget_container",
function (this: HTMLElement) {
Copy link
Member

@andersk andersk Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If $scroll_listening_element is JQuery<Window>, then this is not HTMLElement.

Since we moved to use standard empty view handlebars everywhere,
this became stale.
If recent view load more banner is at the center as a result of
`document.elementFromPoint(topic_center_x, topic_center_y)`,
there is no `tr` to focus, resulting in first row to be focused
as the closest element as per previous logic.

To fix it, we just focus the last row which is just above the
load more banner and is visible.
Fixes zulip#17933, zulip#27517

Instead of `recent_view_table`, we make `html` as our scroll container.
This fixes an important bug for us where filters sometimes disappear
due to them scrolling under navbar which is unexpected. Since we are
now using separate containers to display rows and
filter (while includes table headers), where filters use sticky
positioning, this bug will be fixed.
@timabbott
Copy link
Sponsor Member

Merged after doing a few edits to the comments; we have two TS-related follow-ups to fix:

@timabbott timabbott merged commit 371cd0d into zulip:main Jun 7, 2024
4 of 5 checks passed
@timabbott
Copy link
Sponsor Member

timabbott commented Jun 7, 2024

@amanagr just a note on GitHub's commit message auto-closing feature: It does no fancy parsing at all -- it doesn't look at punctuatioin, and just looks for phrases like "fixes|fixing|fixed|fix #{issue_id}, matching even stuff in the middle of sentences like this does not fix #1234, because .... So Fixes #17933, #27517 only closed the first issue. Just say Fixes #17933. Fixes #27517. if you want to close multiple issues.

@amanagr amanagr deleted the rt_scroll_html branch June 7, 2024 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deployed on chat.zulip.org Added by maintainers when a PR is currently being tested on chat.zulip.org. size: XL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants