mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +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
	 Elian Doran
						Elian Doran