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 IntersectionObserver to detect current page #3682

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

G-Ambatte
Copy link
Collaborator

This PR uses the IntersectionObserver to detect which page elements are in the viewport and thus visible to the end user. This data is updated as the user scrolls, and is passed to a new function updatePageArray in helpers.js.

This PR also adds two further new functions to helpers.js:

  • getPageNumber : returns an integer, the average value of the content of the pageArray which should be the most central page in the range of visible pages
  • getVisiblePageRange : returns a string, if the array length is 3 or less, joined by commas (e.g. 1, 2, 3) and for lengths greater than 3, the first and last page separated by a dash (e.g. 1 - 5).

@Gazook89
Copy link
Collaborator

What problem is this fixing?

@calculuschild
Copy link
Member

@Gazook89 I believe this is working toward #2198

@5e-Cleric
Copy link
Member

If this works, it should solve an issue at #3694

@5e-Cleric 5e-Cleric mentioned this pull request Sep 6, 2024

const pageRef = useRef();

const rootMargin = '-50% 0px';
Copy link
Member

@calculuschild calculuschild Sep 9, 2024

Choose a reason for hiding this comment

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

Can you explain the behavior of how rootMargin works here? Any difference between this and threshold instead?

Maybe just add a brief comment explaining how this boundary determines the current page.

useEffect(()=>{
const observer = new IntersectionObserver(
([entry])=>{
const pageNo = parseInt(entry.target.getAttribute('id').slice(1));
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we can just use the component's index prop directly instead of reading it from the DOM target?

if(pageRef.current == null) return;
observer.unobserve(pageRef.current);
};
}, [pageRef.current, rootMargin]);
Copy link
Member

@calculuschild calculuschild Sep 9, 2024

Choose a reason for hiding this comment

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

Neither of these values trigger a redraw when changed, so they won't have any effect here in the useEffect dependency array. The effect will just fire once when the page component is mounted and then never again. In that case, this is equivalent to just an empty array [].

@@ -50,8 +50,42 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{
}));
};

let pageArray = [];
Copy link
Member

@calculuschild calculuschild Sep 9, 2024

Choose a reason for hiding this comment

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

What is the purpose of the pageArray instead of simply setting the current page directly from the page that triggered the intersectionObserver event?

Seems we could get away with a simple getPage and setPage?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My thinking was that - particularly with the new BrewRenderer toolbar - that there can be multiple pages visible in the view port, so an array of page numbers is more appropriate than a single value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

Successfully merging this pull request may close these issues.

4 participants