mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 10:39:00 +01:00
chore(react/collections): add intersection observer
This commit is contained in:
parent
2689b22674
commit
6e575df40b
@ -3,7 +3,7 @@ import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks";
|
|||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import "./NoteList.css";
|
import "./NoteList.css";
|
||||||
import { ListView, GridView } from "./legacy/ListOrGridView";
|
import { ListView, GridView } from "./legacy/ListOrGridView";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useRef, useState } from "preact/hooks";
|
||||||
|
|
||||||
interface NoteListProps {
|
interface NoteListProps {
|
||||||
note?: FNote | null;
|
note?: FNote | null;
|
||||||
@ -12,15 +12,38 @@ interface NoteListProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function NoteList({ note: providedNote, highlightedTokens }: NoteListProps) {
|
export default function NoteList({ note: providedNote, highlightedTokens }: NoteListProps) {
|
||||||
|
const widgetRef = useRef<HTMLDivElement>(null);
|
||||||
const { note: contextNote } = useNoteContext();
|
const { note: contextNote } = useNoteContext();
|
||||||
const note = providedNote ?? contextNote;
|
const note = providedNote ?? contextNote;
|
||||||
const viewType = useNoteViewType(note);
|
const viewType = useNoteViewType(note);
|
||||||
const noteIds = useNoteIds(note, viewType);
|
const noteIds = useNoteIds(note, viewType);
|
||||||
const isEnabled = (note && !!viewType);
|
|
||||||
const isFullHeight = (viewType !== "list" && viewType !== "grid");
|
const isFullHeight = (viewType !== "list" && viewType !== "grid");
|
||||||
|
const [ isIntersecting, setIsIntersecting ] = useState(false);
|
||||||
|
const shouldRender = (isFullHeight || isIntersecting);
|
||||||
|
const isEnabled = (note && !!viewType && shouldRender);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
if (!isIntersecting) {
|
||||||
|
setIsIntersecting(entries[0].isIntersecting);
|
||||||
|
}
|
||||||
|
observer.disconnect();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rootMargin: "50px",
|
||||||
|
threshold: 0.1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// there seems to be a race condition on Firefox which triggers the observer only before the widget is visible
|
||||||
|
// (intersection is false). https://github.com/zadam/trilium/issues/4165
|
||||||
|
setTimeout(() => widgetRef.current && observer.observe(widgetRef.current), 10);
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`note-list-widget ${isFullHeight ? "full-height" : ""}`}>
|
<div ref={widgetRef} className={`note-list-widget ${isFullHeight ? "full-height" : ""}`}>
|
||||||
{isEnabled && (
|
{isEnabled && (
|
||||||
<div className="note-list-widget-content">
|
<div className="note-list-widget-content">
|
||||||
{getComponentByViewType(note, noteIds, viewType, highlightedTokens)}
|
{getComponentByViewType(note, noteIds, viewType, highlightedTokens)}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import type ViewMode from "../view_widgets/view_mode.js";
|
|||||||
export default class NoteListWidget extends NoteContextAwareWidget {
|
export default class NoteListWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
private $content!: JQuery<HTMLElement>;
|
private $content!: JQuery<HTMLElement>;
|
||||||
private isIntersecting?: boolean;
|
|
||||||
private noteIdRefreshed?: string;
|
private noteIdRefreshed?: string;
|
||||||
private shownNoteId?: string | null;
|
private shownNoteId?: string | null;
|
||||||
private viewMode?: ViewMode<any> | null;
|
private viewMode?: ViewMode<any> | null;
|
||||||
@ -33,56 +32,6 @@ export default class NoteListWidget extends NoteContextAwareWidget {
|
|||||||
return this.noteContext?.hasNoteList();
|
return this.noteContext?.hasNoteList();
|
||||||
}
|
}
|
||||||
|
|
||||||
doRender() {
|
|
||||||
this.$widget = $(TPL);
|
|
||||||
this.contentSized();
|
|
||||||
this.$content = this.$widget.find(".note-list-widget-content");
|
|
||||||
|
|
||||||
const observer = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
this.isIntersecting = entries[0].isIntersecting;
|
|
||||||
|
|
||||||
this.checkRenderStatus();
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rootMargin: "50px",
|
|
||||||
threshold: 0.1
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// there seems to be a race condition on Firefox which triggers the observer only before the widget is visible
|
|
||||||
// (intersection is false). https://github.com/zadam/trilium/issues/4165
|
|
||||||
setTimeout(() => observer.observe(this.$widget[0]), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkRenderStatus() {
|
|
||||||
// console.log("this.isIntersecting", this.isIntersecting);
|
|
||||||
// console.log(`${this.noteIdRefreshed} === ${this.noteId}`, this.noteIdRefreshed === this.noteId);
|
|
||||||
// console.log("this.shownNoteId !== this.noteId", this.shownNoteId !== this.noteId);
|
|
||||||
|
|
||||||
if (this.note && this.isIntersecting && this.noteIdRefreshed === this.noteId && this.shownNoteId !== this.noteId) {
|
|
||||||
this.shownNoteId = this.noteId;
|
|
||||||
this.renderNoteList(this.note);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderNoteList(note: FNote) {
|
|
||||||
const noteListRenderer = new NoteListRenderer({
|
|
||||||
$parent: this.$content,
|
|
||||||
parentNote: note,
|
|
||||||
parentNotePath: this.notePath
|
|
||||||
});
|
|
||||||
this.$widget.toggleClass("full-height", noteListRenderer.isFullHeight);
|
|
||||||
await noteListRenderer.renderList();
|
|
||||||
this.viewMode = noteListRenderer.viewMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
async refresh() {
|
|
||||||
this.shownNoteId = null;
|
|
||||||
|
|
||||||
await super.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
async refreshNoteListEvent({ noteId }: EventData<"refreshNoteList">) {
|
async refreshNoteListEvent({ noteId }: EventData<"refreshNoteList">) {
|
||||||
if (this.isNote(noteId) && this.note) {
|
if (this.isNote(noteId) && this.note) {
|
||||||
await this.renderNoteList(this.note);
|
await this.renderNoteList(this.note);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user