#431 - Cache changes + Tab navigation

This commit is contained in:
Elio Struyf
2022-10-02 14:23:51 +02:00
parent 5fbb05f083
commit 726a26850d
4 changed files with 95 additions and 27 deletions
+44 -19
View File
@@ -13,6 +13,7 @@ import { parseWinPath } from '../../helpers/parseWinPath';
export default function usePages(pages: Page[]) {
const [ pageItems, setPageItems ] = useState<Page[]>([]);
const [ sortedPages, setSortedPages ] = useState<Page[]>([]);
const [ sorting, setSorting ] = useRecoilState(SortingAtom);
const [ tabInfo , setTabInfo ] = useRecoilState(TabInfoAtom);
const settings = useRecoilValue(SettingsSelector);
@@ -22,8 +23,10 @@ export default function usePages(pages: Page[]) {
const tag = useRecoilValue(TagSelector);
const category = useRecoilValue(CategorySelector);
const processPages = useCallback((searchedPages: Page[]) => {
const draftField = settings?.draftField;
/**
* Process all the pages by applying the sorting, filtering and searching.
*/
const processPages = useCallback((searchedPages: Page[], fullProcess: boolean = true) => {
const framework = settings?.crntFramework;
// Filter the pages
@@ -93,40 +96,52 @@ export default function usePages(pages: Page[]) {
pagesSorted = pagesSorted.filter(page => page.fmCategories && page.fmCategories.includes(category));
}
setSortedPages(pagesSorted);
}, [ settings, tab, folder, search, tag, category, sorting, tabInfo ]);
/**
* Process the pages when the tab changes
*/
const processByTab = useCallback((pages: Page[]) => {
const draftField = settings?.draftField;
let crntPages: Page[] = Object.assign([], pages);
// Process the tab data
const draftTypes = Object.assign({}, tabInfo);
draftTypes[Tab.All] = pagesSorted.length;
draftTypes[Tab.All] = crntPages.length;
// Filter by draft status
if (draftField && draftField.type === 'choice') {
const draftChoices = settings?.draftField?.choices;
for (const choice of (draftChoices || [])) {
if (choice) {
draftTypes[choice] = pagesSorted.filter(page => page.fmDraft === choice).length;
draftTypes[choice] = crntPages.filter(page => page.fmDraft === choice).length;
}
}
if (tab !== Tab.All) {
pagesSorted = pagesSorted.filter(page => page.fmDraft === tab);
crntPages = crntPages.filter(page => page.fmDraft === tab);
} else {
pagesSorted = pagesSorted;
crntPages = crntPages;
}
} else {
// Draft field is a boolean field
const draftFieldName = draftField?.name || "draft";
const drafts = pagesSorted.filter(page => page[draftFieldName] == true || page[draftFieldName] === "true");
const published = pagesSorted.filter(page => page[draftFieldName] == false || page[draftFieldName] === "false" || typeof page[draftFieldName] === "undefined");
const drafts = crntPages.filter(page => page[draftFieldName] == true || page[draftFieldName] === "true");
const published = crntPages.filter(page => page[draftFieldName] == false || page[draftFieldName] === "false" || typeof page[draftFieldName] === "undefined");
draftTypes[Tab.Draft] = draftField?.invert ? published.length : drafts.length;
draftTypes[Tab.Published] = draftField?.invert ? drafts.length : published.length;
if (tab === Tab.Published) {
pagesSorted = draftField?.invert ? drafts : published;
crntPages = draftField?.invert ? drafts : published;
} else if (tab === Tab.Draft) {
pagesSorted = draftField?.invert ? published : drafts;
crntPages = draftField?.invert ? published : drafts;
} else {
pagesSorted = pagesSorted;
crntPages = crntPages;
}
}
@@ -134,10 +149,14 @@ export default function usePages(pages: Page[]) {
setTabInfo(draftTypes);
// Set the pages
setPageItems(pagesSorted);
}, [ settings, tab, folder, search, tag, category, sorting, tabInfo ]);
setPageItems(crntPages);
}, [ tab, tabInfo, settings ]);
/**
* Search listener for filtered pages
* @param message
*/
const searchListener = (message: MessageEvent<EventData<any>>) => {
switch (message.data.command) {
case DashboardMessage.searchPages:
@@ -146,6 +165,7 @@ export default function usePages(pages: Page[]) {
}
};
useEffect(() => {
let usedSorting = sorting;
@@ -160,15 +180,20 @@ export default function usePages(pages: Page[]) {
// Check if search needs to be performed
let searchedPages = pages;
if (search) {
// const fuse = new Fuse(pages, fuseOptions);
// const results = fuse.search(search);
// searchedPages = results.map(page => page.item);
Messenger.send(DashboardMessage.searchPages, { query: search });
} else {
processPages(searchedPages);
}
}, [ settings?.draftField, pages, sorting, search, tab, tag, category, folder ]);
}, [ settings?.draftField, pages, sorting, search, tag, category, folder ]);
useEffect(() => {
console.log("useEffect: tab", tab, sortedPages.length);
if (sortedPages.length > 0) {
processByTab(sortedPages);
}
}, [sortedPages, tab])
useEffect(() => {
Messenger.listen(searchListener);
+5 -1
View File
@@ -1,6 +1,10 @@
import { Uri } from "vscode";
export interface Page {
// Properties for caching
fmCachePath: string;
fmCacheModifiedTime: number;
// Front matter fields
fmFolder: string;
fmFilePath: string;
fmFileName: string;
+1 -2
View File
@@ -161,8 +161,7 @@ export class PagesListener extends BaseListener {
this.sendPageData(pages);
this.sendMsg(DashboardCommand.searchReady, true);
await ext.setState(ExtensionState.Dashboard.Pages.Cache, pages, "workspace");
await this.createSearchIndex(pages);
});
}
+45 -5
View File
@@ -4,22 +4,30 @@ import { dirname, join } from "path";
import { StatusBarAlignment, Uri, window } from "vscode";
import { Dashboard } from "../commands/Dashboard";
import { Folders } from "../commands/Folders";
import { DefaultFields, DEFAULT_CONTENT_TYPE_NAME, SETTING_SEO_DESCRIPTION_FIELD } from "../constants";
import { DefaultFields, DEFAULT_CONTENT_TYPE_NAME, ExtensionState, SETTING_SEO_DESCRIPTION_FIELD } from "../constants";
import { Page } from "../dashboardWebView/models";
import { ArticleHelper, ContentType, DateHelper, isValidFile, Logger, Notifications, Settings } from "../helpers";
import { ArticleHelper, ContentType, DateHelper, Extension, isValidFile, Logger, Notifications, Settings } from "../helpers";
export class PagesParser {
public static allPages: Page[] = [];
public static cachedPages: Page[] | undefined = undefined;
private static parser: Promise<void> | undefined;
private static initialized: boolean = false;
/**
* Start the page parser
*/
public static start() {
if (!this.parser) {
this.parser = this.parsePages();
}
}
/**
* Retrieve the pages
* @param cb
*/
public static getPages(cb: (pages: Page[]) => void) {
if (this.parser) {
this.parser.then(() => cb(PagesParser.allPages));
@@ -34,12 +42,20 @@ export class PagesParser {
}
}
/**
* Reset the cache
*/
public static async reset() {
this.parser = undefined;
PagesParser.allPages = [];
}
/**
* Parse all pages in the workspace
*/
public static async parsePages() {
const ext = Extension.getInstance();
// Update the dashboard with the fresh data
const folderInfo = await Folders.getInfo();
const pages: Page[] = [];
@@ -53,12 +69,15 @@ export class PagesParser {
for (const file of folder.lastModified) {
if (isValidFile(file.fileName)) {
try {
const page = this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title);
let page = await PagesParser.getCachedPage(file.filePath, file.mtime);
if (page && !pages.find(p => p.fmFilePath === page.fmFilePath)) {
if (!page) {
page = this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title);
}
if (page && !pages.find(p => p.fmFilePath === page?.fmFilePath)) {
pages.push(page);
}
} catch (error: any) {
if ((error as Error)?.message.toLowerCase() === "webview is disposed") {
continue;
@@ -72,12 +91,30 @@ export class PagesParser {
}
}
await ext.setState(ExtensionState.Dashboard.Pages.Cache, pages, "workspace");
PagesParser.cachedPages = undefined;
this.parser = undefined;
this.initialized = true;
PagesParser.allPages = [...pages];
statusBar.hide();
}
/**
* Find the page in the cached data
* @param filePath
* @param modifiedTime
* @returns
*/
public static async getCachedPage(filePath: string, modifiedTime: number): Promise<Page | undefined> {
if (!PagesParser.cachedPages) {
const ext = Extension.getInstance();
PagesParser.cachedPages = await ext.getState<Page[]>(ExtensionState.Dashboard.Pages.Cache, "workspace") || [];
}
return PagesParser.cachedPages.find(p => p.fmCachePath === parseWinPath(filePath) && p.fmCacheModifiedTime === modifiedTime);
}
/**
* Process the page content
* @param filePath
@@ -103,6 +140,9 @@ export class PagesParser {
const page: Page = {
...article.data,
// Cache properties
fmCachePath: parseWinPath(filePath),
fmCacheModifiedTime: fileMtime,
// FrontMatter properties
fmFolder: folderTitle,
fmFilePath: filePath,