mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-06 01:41:48 +02:00
#431 - Cache changes + Tab navigation
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user