From 3d67c32500cb6415250960d12affad297d6572dc Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Fri, 20 Oct 2017 00:27:01 -0700 Subject: [PATCH 1/5] Prefetch documents on hover --- .../Layout/components/SidebarCollections.js | 109 ++++++++++-------- frontend/stores/DocumentsStore.js | 8 +- 2 files changed, 67 insertions(+), 50 deletions(-) diff --git a/frontend/components/Layout/components/SidebarCollections.js b/frontend/components/Layout/components/SidebarCollections.js index a1cf5aa2d..3d71e41ad 100644 --- a/frontend/components/Layout/components/SidebarCollections.js +++ b/frontend/components/Layout/components/SidebarCollections.js @@ -14,6 +14,7 @@ import CollectionMenu from 'menus/CollectionMenu'; import CollectionsStore from 'stores/CollectionsStore'; import UiStore from 'stores/UiStore'; import Document from 'models/Document'; +import DocumentsStore from 'stores/DocumentsStore'; import { type NavigationNode } from 'types'; type Props = { @@ -123,6 +124,7 @@ type Props = { } type DocumentLinkProps = { + documents: DocumentsStore, document: NavigationNode, history: Object, activeDocument: ?Document, @@ -130,58 +132,69 @@ type DocumentLinkProps = { depth: number, }; -const DocumentLink = observer( - ({ - document, - activeDocument, - activeDocumentRef, - depth, - }: DocumentLinkProps) => { - const isActiveDocument = - activeDocument && activeDocument.id === document.id; - const showChildren = - activeDocument && - (activeDocument.pathToDocument - .map(entry => entry.id) - .includes(document.id) || - isActiveDocument); +const DocumentLink = inject('documents')( + observer( + ({ + documents, + document, + activeDocument, + activeDocumentRef, + depth, + }: DocumentLinkProps) => { + const isActiveDocument = + activeDocument && activeDocument.id === document.id; + const showChildren = + activeDocument && + (activeDocument.pathToDocument + .map(entry => entry.id) + .includes(document.id) || + isActiveDocument); - return ( - - { + event.stopPropagation(); + event.preventDefault(); + documents.prefetchDocument(document.id); + }; + + return ( + - 0} - expanded={showChildren} + - {document.title} - - + 0} + expanded={showChildren} + > + {document.title} + + - {showChildren && - - {document.children && - document.children.map(childDocument => ( - - ))} - } - - ); - } + {showChildren && + + {document.children && + document.children.map(childDocument => ( + + ))} + } + + ); + } + ) ); const CollectionAction = styled.a` diff --git a/frontend/stores/DocumentsStore.js b/frontend/stores/DocumentsStore.js index 9ddf8925f..9d30926a9 100644 --- a/frontend/stores/DocumentsStore.js +++ b/frontend/stores/DocumentsStore.js @@ -111,8 +111,12 @@ class DocumentsStore extends BaseStore { return data.map(documentData => documentData.id); }; - @action fetch = async (id: string): Promise<*> => { - this.isFetching = true; + @action prefetchDocument = async (id: string) => { + if (!this.getById(id)) this.fetch(id, true); + }; + + @action fetch = async (id: string, prefetch: boolean): Promise<*> => { + if (!prefetch) this.isFetching = true; try { const res = await client.post('/documents.info', { id }); From c4d8c07859e6c211ef88d436ad80e4da3be6e3f5 Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Sat, 21 Oct 2017 16:11:08 -0700 Subject: [PATCH 2/5] addressed comments and added time limit --- .../Layout/components/SidebarCollections.js | 124 +++++++++--------- frontend/models/Document.js | 6 + frontend/stores/DocumentsStore.js | 5 + 3 files changed, 75 insertions(+), 60 deletions(-) diff --git a/frontend/components/Layout/components/SidebarCollections.js b/frontend/components/Layout/components/SidebarCollections.js index 3d71e41ad..a40a2d0ea 100644 --- a/frontend/components/Layout/components/SidebarCollections.js +++ b/frontend/components/Layout/components/SidebarCollections.js @@ -20,6 +20,7 @@ import { type NavigationNode } from 'types'; type Props = { history: Object, collections: CollectionsStore, + documents: DocumentsStore, activeDocument: ?Document, onCreateCollection: () => void, activeDocumentRef: HTMLElement => void, @@ -36,6 +37,7 @@ type Props = { activeDocument, ui, activeDocumentRef, + documents, } = this.props; return ( @@ -48,6 +50,7 @@ type Props = { collection={collection} activeDocument={activeDocument} activeDocumentRef={activeDocumentRef} + prefetchDocument={documents.prefetchDocument} ui={ui} /> ))} @@ -77,6 +80,7 @@ type Props = { activeDocument, ui, activeDocumentRef, + prefetchDocument, } = this.props; return ( @@ -113,6 +117,7 @@ type Props = { history={history} document={document} activeDocument={activeDocument} + prefetchDocument={prefetchDocument} depth={0} /> ))} @@ -124,77 +129,76 @@ type Props = { } type DocumentLinkProps = { - documents: DocumentsStore, document: NavigationNode, history: Object, activeDocument: ?Document, activeDocumentRef: HTMLElement => void, + prefetchDocument: string => void, depth: number, }; -const DocumentLink = inject('documents')( - observer( - ({ - documents, - document, - activeDocument, - activeDocumentRef, - depth, - }: DocumentLinkProps) => { - const isActiveDocument = - activeDocument && activeDocument.id === document.id; - const showChildren = - activeDocument && - (activeDocument.pathToDocument - .map(entry => entry.id) - .includes(document.id) || - isActiveDocument); +const DocumentLink = observer( + ({ + documents, + document, + activeDocument, + activeDocumentRef, + prefetchDocument, + depth, + }: DocumentLinkProps) => { + const isActiveDocument = + activeDocument && activeDocument.id === document.id; + const showChildren = + activeDocument && + (activeDocument.pathToDocument + .map(entry => entry.id) + .includes(document.id) || + isActiveDocument); - const handleMouseEnter = (event: SyntheticEvent) => { - event.stopPropagation(); - event.preventDefault(); - documents.prefetchDocument(document.id); - }; + const handleMouseEnter = (event: SyntheticEvent) => { + event.stopPropagation(); + event.preventDefault(); + prefetchDocument(document.id); + }; - return ( - + - 0} + expanded={showChildren} > - 0} - expanded={showChildren} - > - {document.title} - - + {document.title} + + - {showChildren && - - {document.children && - document.children.map(childDocument => ( - - ))} - } - - ); - } - ) + {showChildren && + + {document.children && + document.children.map(childDocument => ( + + ))} + } + + ); + } ); const CollectionAction = styled.a` @@ -230,4 +234,4 @@ const Children = styled(Flex)` margin-left: 20px; `; -export default inject('collections', 'ui')(SidebarCollections); +export default inject('collections', 'ui', 'documents')(SidebarCollections); diff --git a/frontend/models/Document.js b/frontend/models/Document.js index 4f4c760ef..b6a3455d5 100644 --- a/frontend/models/Document.js +++ b/frontend/models/Document.js @@ -40,6 +40,7 @@ class Document extends BaseModel { views: number; data: Object; + fetchedAt: Date; /* Computed */ @@ -101,6 +102,10 @@ class Document extends BaseModel { : null; } + get timeSinceFetch(): number { + return (new Date() - this.fetchedAt) / 1000; + } + /* Actions */ @action star = async () => { @@ -252,6 +257,7 @@ class Document extends BaseModel { this.updateData(data); this.errors = stores.errors; + this.fetchedAt = new Date(); } } diff --git a/frontend/stores/DocumentsStore.js b/frontend/stores/DocumentsStore.js index 9d30926a9..692ce14bb 100644 --- a/frontend/stores/DocumentsStore.js +++ b/frontend/stores/DocumentsStore.js @@ -116,6 +116,11 @@ class DocumentsStore extends BaseStore { }; @action fetch = async (id: string, prefetch: boolean): Promise<*> => { + /** If document has been fetched under 5s ago, return it */ + const existingDocument = this.getById(id); + if (existingDocument && existingDocument.timeSinceFetch < 5) + return existingDocument; + if (!prefetch) this.isFetching = true; try { From bd1cdb4a9f18549e3e57d509f2795199922f5d3c Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Sat, 21 Oct 2017 16:36:55 -0700 Subject: [PATCH 3/5] fixed lint --- frontend/stores/DocumentsStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/stores/DocumentsStore.js b/frontend/stores/DocumentsStore.js index 692ce14bb..817b11456 100644 --- a/frontend/stores/DocumentsStore.js +++ b/frontend/stores/DocumentsStore.js @@ -115,7 +115,7 @@ class DocumentsStore extends BaseStore { if (!this.getById(id)) this.fetch(id, true); }; - @action fetch = async (id: string, prefetch: boolean): Promise<*> => { + @action fetch = async (id: string, prefetch?: boolean): Promise<*> => { /** If document has been fetched under 5s ago, return it */ const existingDocument = this.getById(id); if (existingDocument && existingDocument.timeSinceFetch < 5) From 30bb7bcde5351b56cef0697e75deb0c4e7f1771b Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Sat, 21 Oct 2017 19:29:14 -0700 Subject: [PATCH 4/5] Fixes --- frontend/components/Layout/components/SidebarCollections.js | 3 +-- frontend/models/Document.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/components/Layout/components/SidebarCollections.js b/frontend/components/Layout/components/SidebarCollections.js index a40a2d0ea..d49c7cc72 100644 --- a/frontend/components/Layout/components/SidebarCollections.js +++ b/frontend/components/Layout/components/SidebarCollections.js @@ -133,13 +133,12 @@ type DocumentLinkProps = { history: Object, activeDocument: ?Document, activeDocumentRef: HTMLElement => void, - prefetchDocument: string => void, + prefetchDocument: (documentId: string) => void, depth: number, }; const DocumentLink = observer( ({ - documents, document, activeDocument, activeDocumentRef, diff --git a/frontend/models/Document.js b/frontend/models/Document.js index b6a3455d5..dbde53e3c 100644 --- a/frontend/models/Document.js +++ b/frontend/models/Document.js @@ -250,6 +250,7 @@ class Document extends BaseModel { if (dirty) this.hasPendingChanges = true; this.data = data; extendObservable(this, data); + this.fetchedAt = new Date(); } constructor(data?: Object = {}) { @@ -257,7 +258,6 @@ class Document extends BaseModel { this.updateData(data); this.errors = stores.errors; - this.fetchedAt = new Date(); } } From 0514090253fa29bf68b7aa8f0567108f90f8f6bb Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Sat, 21 Oct 2017 19:39:13 -0700 Subject: [PATCH 5/5] fixes --- frontend/models/Document.js | 6 ------ frontend/stores/DocumentsStore.js | 5 ----- 2 files changed, 11 deletions(-) diff --git a/frontend/models/Document.js b/frontend/models/Document.js index dbde53e3c..4f4c760ef 100644 --- a/frontend/models/Document.js +++ b/frontend/models/Document.js @@ -40,7 +40,6 @@ class Document extends BaseModel { views: number; data: Object; - fetchedAt: Date; /* Computed */ @@ -102,10 +101,6 @@ class Document extends BaseModel { : null; } - get timeSinceFetch(): number { - return (new Date() - this.fetchedAt) / 1000; - } - /* Actions */ @action star = async () => { @@ -250,7 +245,6 @@ class Document extends BaseModel { if (dirty) this.hasPendingChanges = true; this.data = data; extendObservable(this, data); - this.fetchedAt = new Date(); } constructor(data?: Object = {}) { diff --git a/frontend/stores/DocumentsStore.js b/frontend/stores/DocumentsStore.js index 817b11456..6314d1b05 100644 --- a/frontend/stores/DocumentsStore.js +++ b/frontend/stores/DocumentsStore.js @@ -116,11 +116,6 @@ class DocumentsStore extends BaseStore { }; @action fetch = async (id: string, prefetch?: boolean): Promise<*> => { - /** If document has been fetched under 5s ago, return it */ - const existingDocument = this.getById(id); - if (existingDocument && existingDocument.timeSinceFetch < 5) - return existingDocument; - if (!prefetch) this.isFetching = true; try {