mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-12 03:43:01 +02:00
Refactoring + optimizing files and folder updates
This commit is contained in:
+12
-8
@@ -135,14 +135,18 @@ export class Folders {
|
||||
let fileStats: FileInfo[] = [];
|
||||
|
||||
for (const file of files) {
|
||||
const fileName = file[0];
|
||||
const filePath = Uri.file(join(folderPath.fsPath, fileName));
|
||||
const stats = await workspace.fs.stat(filePath);
|
||||
fileStats.push({
|
||||
filePath: filePath.fsPath,
|
||||
fileName,
|
||||
...stats
|
||||
});
|
||||
try {
|
||||
const fileName = file[0];
|
||||
const filePath = Uri.file(join(folderPath.fsPath, fileName));
|
||||
const stats = await workspace.fs.stat(filePath);
|
||||
fileStats.push({
|
||||
filePath: filePath.fsPath,
|
||||
fileName,
|
||||
...stats
|
||||
});
|
||||
} catch (error) {
|
||||
// Skip the file
|
||||
}
|
||||
}
|
||||
|
||||
fileStats = fileStats.sort((a, b) => b.mtime - a.mtime).slice(0, 10);
|
||||
|
||||
+6
-4
@@ -108,6 +108,11 @@ export async function activate({ subscriptions, extensionUri, extensionPath }: v
|
||||
Template.init();
|
||||
Preview.init();
|
||||
Folders.updateVsCodeCtx();
|
||||
|
||||
const exView = ExplorerView.getInstance();
|
||||
exView.getSettings();
|
||||
exView.getFoldersAndFiles();
|
||||
MarkdownFoldingProvider.triggerHighlighting();
|
||||
});
|
||||
|
||||
// Create the status bar
|
||||
@@ -131,13 +136,10 @@ export async function activate({ subscriptions, extensionUri, extensionPath }: v
|
||||
subscriptions.push(vscode.workspace.onDidSaveTextDocument((doc: vscode.TextDocument) => {
|
||||
if (doc.languageId === 'markdown') {
|
||||
// Optimize the list of recently changed files
|
||||
ExplorerView.getInstance().getSettings();
|
||||
ExplorerView.getInstance().getFoldersAndFiles();
|
||||
}
|
||||
}));
|
||||
|
||||
// Listener for setting changes
|
||||
subscriptions.push(vscode.workspace.onDidChangeConfiguration(MarkdownFoldingProvider.triggerHighlighting));
|
||||
|
||||
// Webview for preview
|
||||
Preview.init();
|
||||
subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.preview, () => Preview.open(extensionPath) ));
|
||||
|
||||
@@ -9,7 +9,6 @@ export interface PanelSettings {
|
||||
scripts: CustomScript[];
|
||||
isInitialized: boolean;
|
||||
modifiedDateUpdate: boolean;
|
||||
contentInfo: FolderInfo[] | null;
|
||||
writingSettingsEnabled: boolean;
|
||||
fmHighlighting: boolean;
|
||||
preview: PreviewSettings;
|
||||
|
||||
@@ -5,4 +5,5 @@ export enum Command {
|
||||
focusOnTags = "focusOnTags",
|
||||
focusOnCategories = "focusOnCategories",
|
||||
closeSections = "closeSections",
|
||||
folderInfo = "folderInfo",
|
||||
}
|
||||
@@ -23,4 +23,5 @@ export enum CommandToCode {
|
||||
openPreview = "open-preview",
|
||||
updatePreviewUrl = "update-preview-url",
|
||||
openInEditor = "open-in-editor",
|
||||
updateMetadata = "update-metadata",
|
||||
}
|
||||
+10
-60
@@ -1,24 +1,21 @@
|
||||
import * as React from 'react';
|
||||
import { Actions } from './components/Actions';
|
||||
import { BaseView } from './components/BaseView';
|
||||
import { Collapsible } from './components/Collapsible';
|
||||
import { GlobalSettings } from './components/GlobalSettings';
|
||||
import { ListUnorderedIcon } from './components/Icons/ListUnorderedIcon';
|
||||
import { SymbolKeywordIcon } from './components/Icons/SymbolKeywordIcon';
|
||||
import { TagIcon } from './components/Icons/TagIcon';
|
||||
import { OtherActions } from './components/OtherActions';
|
||||
import { SeoStatus } from './components/SeoStatus';
|
||||
import { Spinner } from './components/Spinner';
|
||||
import { TagPicker } from './components/TagPicker';
|
||||
import { FileList } from './components/FileList';
|
||||
import useMessages from './hooks/useMessages';
|
||||
import { TagType } from './TagType';
|
||||
import { FolderAndFiles } from './components/FolderAndFiles';
|
||||
import { Metadata } from './components/Metadata';
|
||||
|
||||
export interface IViewPanelProps {
|
||||
}
|
||||
|
||||
export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React.PropsWithChildren<IViewPanelProps>) => {
|
||||
const { loading, metadata, settings, focusElm, unsetFocus } = useMessages();
|
||||
const { loading, metadata, settings, folderAndFiles, focusElm, unsetFocus } = useMessages();
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -28,7 +25,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
|
||||
if (!metadata || Object.keys(metadata).length === 0) {
|
||||
return (
|
||||
<BaseView settings={settings} />
|
||||
<BaseView settings={settings} folderAndFiles={folderAndFiles} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,60 +41,13 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
settings && metadata && <Actions metadata={metadata} settings={settings} />
|
||||
}
|
||||
|
||||
<Collapsible id={`tags`} title="Metadata" className={`inherit z-20`}>
|
||||
{
|
||||
<TagPicker type={TagType.keywords}
|
||||
icon={<SymbolKeywordIcon />}
|
||||
crntSelected={metadata.keywords || []}
|
||||
options={[]}
|
||||
freeform={true}
|
||||
focussed={focusElm === TagType.keywords}
|
||||
unsetFocus={unsetFocus}
|
||||
disableConfigurable />
|
||||
}
|
||||
{
|
||||
(settings && settings.tags && settings.tags.length > 0) && (
|
||||
<TagPicker type={TagType.tags}
|
||||
icon={<TagIcon />}
|
||||
crntSelected={metadata.tags || []}
|
||||
options={settings.tags}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.tags}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
{
|
||||
(settings && settings.categories && settings.categories.length > 0) && (
|
||||
<TagPicker type={TagType.categories}
|
||||
icon={<ListUnorderedIcon />}
|
||||
crntSelected={metadata.categories || []}
|
||||
options={settings.categories}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.categories}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
</Collapsible>
|
||||
<Metadata
|
||||
settings={settings}
|
||||
metadata={metadata}
|
||||
focusElm={focusElm}
|
||||
unsetFocus={unsetFocus} />
|
||||
|
||||
{
|
||||
(settings?.contentInfo && settings?.contentInfo.length > 0) && (
|
||||
<Collapsible id={`content`} title="Recently modified">
|
||||
<div className="information">
|
||||
{
|
||||
settings.contentInfo.map(folder => (
|
||||
<>
|
||||
{folder.lastModified && (
|
||||
<div key={folder.title}>
|
||||
<FileList folderName={folder.title} totalFiles={folder.files} files={folder.lastModified} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
<FolderAndFiles data={folderAndFiles} />
|
||||
|
||||
<OtherActions settings={settings} isFile={true} />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models';
|
||||
import { FolderInfo, PanelSettings } from '../../models';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { Collapsible } from './Collapsible';
|
||||
@@ -7,12 +7,14 @@ import { GlobalSettings } from './GlobalSettings';
|
||||
import { OtherActions } from './OtherActions';
|
||||
import { FileList } from './FileList';
|
||||
import { VsLabel } from './VscodeComponents';
|
||||
import { FolderAndFiles } from './FolderAndFiles';
|
||||
|
||||
export interface IBaseViewProps {
|
||||
settings: PanelSettings | undefined;
|
||||
folderAndFiles: FolderInfo[] | undefined;
|
||||
}
|
||||
|
||||
export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: React.PropsWithChildren<IBaseViewProps>) => {
|
||||
export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings, folderAndFiles}: React.PropsWithChildren<IBaseViewProps>) => {
|
||||
|
||||
const initProject = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.initProject);
|
||||
@@ -34,26 +36,8 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
<button onClick={createContent} disabled={!settings?.isInitialized}>Create new content</button>
|
||||
</div>
|
||||
</Collapsible>
|
||||
|
||||
{
|
||||
settings?.contentInfo && (
|
||||
<Collapsible id={`base_content`} title="Recently modified">
|
||||
<div className="base__information">
|
||||
{
|
||||
settings.contentInfo.map(folder => (
|
||||
<div key={folder.title}>
|
||||
{
|
||||
folder.lastModified ? <FileList folderName={folder.title} totalFiles={folder.files} files={folder.lastModified} /> : (
|
||||
<VsLabel>{folder.title}: {folder.files} file{folder.files > 1 ? 's' : ''}</VsLabel>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
|
||||
<FolderAndFiles data={folderAndFiles} isBase />
|
||||
|
||||
<OtherActions settings={settings} isFile={false} isBase />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import * as React from 'react';
|
||||
import { FolderInfo } from '../../models';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { FileList } from './FileList';
|
||||
import { VsLabel } from './VscodeComponents';
|
||||
|
||||
export interface IFolderAndFilesProps {
|
||||
data: FolderInfo[] | undefined;
|
||||
isBase?: boolean;
|
||||
}
|
||||
|
||||
export const FolderAndFiles: React.FunctionComponent<IFolderAndFilesProps> = ({data, isBase}: React.PropsWithChildren<IFolderAndFilesProps>) => {
|
||||
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
(data && data.length > 0) && (
|
||||
<Collapsible id={`${isBase ? "base_" : ""}content`} title="Recently modified">
|
||||
<div className="information">
|
||||
{
|
||||
data.map((folder: FolderInfo) => (
|
||||
<>
|
||||
{folder.lastModified ? (
|
||||
<div key={folder.title}>
|
||||
<FileList folderName={folder.title} totalFiles={folder.files} files={folder.lastModified} />
|
||||
</div>
|
||||
) : (
|
||||
isBase ? (
|
||||
<VsLabel>{folder.title}: {folder.files} file{folder.files > 1 ? 's' : ''}</VsLabel>
|
||||
) : null
|
||||
)}
|
||||
</>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { TagType } from '../TagType';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { ListUnorderedIcon } from './Icons/ListUnorderedIcon';
|
||||
import { SymbolKeywordIcon } from './Icons/SymbolKeywordIcon';
|
||||
import { TagIcon } from './Icons/TagIcon';
|
||||
import { TagPicker } from './TagPicker';
|
||||
|
||||
export interface IMetadataProps {
|
||||
settings: PanelSettings | undefined;
|
||||
metadata: { [prop: string]: string[] | null };
|
||||
focusElm: TagType | null;
|
||||
unsetFocus: () => void;
|
||||
}
|
||||
|
||||
export const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, metadata, focusElm, unsetFocus}: React.PropsWithChildren<IMetadataProps>) => {
|
||||
|
||||
const sendUpdate = (field: string, value: string) => {
|
||||
MessageHelper.sendMessage(CommandToCode.updateMetadata, {
|
||||
field,
|
||||
value
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Collapsible id={`tags`} title="Metadata" className={`inherit z-20`}>
|
||||
{
|
||||
<TagPicker type={TagType.keywords}
|
||||
icon={<SymbolKeywordIcon />}
|
||||
crntSelected={metadata.keywords || []}
|
||||
options={[]}
|
||||
freeform={true}
|
||||
focussed={focusElm === TagType.keywords}
|
||||
unsetFocus={unsetFocus}
|
||||
disableConfigurable />
|
||||
}
|
||||
{
|
||||
(settings && settings.tags && settings.tags.length > 0) && (
|
||||
<TagPicker type={TagType.tags}
|
||||
icon={<TagIcon />}
|
||||
crntSelected={metadata.tags || []}
|
||||
options={settings.tags}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.tags}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
{
|
||||
(settings && settings.categories && settings.categories.length > 0) && (
|
||||
<TagPicker type={TagType.categories}
|
||||
icon={<ListUnorderedIcon />}
|
||||
crntSelected={metadata.categories || []}
|
||||
options={settings.categories}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.categories}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
</Collapsible>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { PanelSettings } from '../../models/PanelSettings';
|
||||
import { FolderInfo, PanelSettings } from '../../models/PanelSettings';
|
||||
import { Command } from '../Command';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
@@ -12,6 +12,7 @@ export default function useMessages() {
|
||||
const [settings, setSettings] = useState<PanelSettings>();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [focusElm, setFocus] = useState<TagType | null>(null);
|
||||
const [folderAndFiles, setFolderAndFiles] = useState<FolderInfo[] | undefined>(undefined);
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
const message = event.data;
|
||||
@@ -25,6 +26,9 @@ export default function useMessages() {
|
||||
setSettings(message.data);
|
||||
setLoading(false);
|
||||
break;
|
||||
case Command.folderInfo:
|
||||
setFolderAndFiles(message.data);
|
||||
break;
|
||||
case Command.loading:
|
||||
setLoading(message.data);
|
||||
break;
|
||||
@@ -45,6 +49,7 @@ export default function useMessages() {
|
||||
return {
|
||||
metadata,
|
||||
settings,
|
||||
folderAndFiles,
|
||||
focusElm,
|
||||
loading,
|
||||
unsetFocus: () => { setFocus(null) }
|
||||
|
||||
@@ -83,6 +83,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
switch(msg.command) {
|
||||
case CommandToCode.getData:
|
||||
this.getSettings();
|
||||
this.getFoldersAndFiles();
|
||||
this.getFileData();
|
||||
break;
|
||||
case CommandToCode.updateSlug:
|
||||
@@ -308,7 +309,6 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
freeform: config.get(SETTING_PANEL_FREEFORM),
|
||||
scripts: config.get(SETTING_CUSTOM_SCRIPTS),
|
||||
isInitialized: await Template.isInitialized(),
|
||||
contentInfo: await Folders.getInfo() || null,
|
||||
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false,
|
||||
writingSettingsEnabled: this.isWritingSettingsEnabled() || false,
|
||||
fmHighlighting: config.get(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT),
|
||||
@@ -317,6 +317,16 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the information about the registered folders and its files
|
||||
*/
|
||||
public async getFoldersAndFiles() {
|
||||
this.postWebviewMessage({
|
||||
command: Command.folderInfo,
|
||||
data: await Folders.getInfo() || null
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the file its front matter
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user