From c88d6be1d7918ece7cbc9ec4b2b4df8a878cca4c Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 9 Aug 2021 10:47:13 +0200 Subject: [PATCH] #31 - implementation of auto-update --- CHANGELOG.md | 4 +++ README.md | 12 ++++++++- package.json | 5 ++++ src/commands/Article.ts | 7 ++--- src/commands/StatusListener.ts | 9 ++++++- src/constants/settings.ts | 1 + src/models/PanelSettings.ts | 1 + src/viewpanel/CommandToCode.ts | 1 + src/viewpanel/ViewPanel.tsx | 3 +++ src/viewpanel/components/BaseView.tsx | 3 +++ src/viewpanel/components/GlobalSettings.tsx | 28 ++++++++++++++++++++ src/viewpanel/components/VscodeComponents.ts | 3 ++- src/viewpanel/index.tsx | 1 + src/webview/ExplorerView.ts | 14 ++++++++-- 14 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/viewpanel/components/GlobalSettings.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e2c19f1..70f01394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [2.3.0] - 2020-08-XX + +- [#31](https://github.com/estruyf/vscode-front-matter/issues/31): Automatically update the last modification date of the file when performing changes + ## [2.2.0] - 2020-08-06 - [#28](https://github.com/estruyf/vscode-front-matter/issues/28): Align the file its name with the article slug diff --git a/README.md b/README.md index 714b4a7f..bb4c5f95 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ Update the `date` property of the current article/post/... to the current date & **Front Matter: Set lastmod date** -Update the `lastmod` (last modified) property of the current article/post/... to the current date & time. +Update the `lastmod` (last modified) property of the current article/post/... to the current date & time. By setting the `frontMatter.content.autoUpdateDate` setting, it can be done automatically when performing changes to your markdown files. > **note**: Uses the same date format settings key as current date: `frontMatter.taxonomy.dateFormat`. @@ -355,6 +355,16 @@ This array of folders defines where the extension can easily create new content > **Important**: This setting can be configured by right-clicking on a folder in the VSCode file explorer view and clicking on the `Front Matter: Register folder` menu item. +### `frontMatter.content.autoUpdateDate` + +Specify if you want to automatically update the modification date of your markdown page when doing changes to it. Default: `false`. + +```json +{ + "frontMatter.content.autoUpdateDate": false +} +``` + ## Feedback / issues / ideas Please submit them via creating an issue in the project repository: [issue list](https://github.com/estruyf/vscode-front-matter/issues). diff --git a/package.json b/package.json index d28b3a23..960ff977 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,11 @@ "default": "lastmod", "description": "Specifies the modified date field name to use in your Front Matter" }, + "frontMatter.content.autoUpdateDate": { + "type": "boolean", + "default": false, + "description": "Specify if you want to automatically update the modified date of your article/page." + }, "frontMatter.taxonomy.tags": { "type": "array", "description": "Specifies the tags which can be used in the Front Matter" diff --git a/src/commands/Article.ts b/src/commands/Article.ts index 2b4a7515..30ac09c9 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -126,16 +126,17 @@ export class Article { return; } + const cloneArticle = Object.assign({}, article); const dateFormat = config.get(SETTING_DATE_FORMAT) as string; const dateField = config.get(SETTING_MODIFIED_FIELD) as string || "lastmod"; try { if (dateFormat && typeof dateFormat === "string") { - article.data[dateField] = format(new Date(), dateFormat); + cloneArticle.data[dateField] = format(new Date(), dateFormat); } else { - article.data[dateField] = new Date().toISOString(); + cloneArticle.data[dateField] = new Date().toISOString(); } - ArticleHelper.update(editor, article); + ArticleHelper.update(editor, cloneArticle); } catch (e) { Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`); console.log(e.message); diff --git a/src/commands/StatusListener.ts b/src/commands/StatusListener.ts index af1df44b..e844968c 100644 --- a/src/commands/StatusListener.ts +++ b/src/commands/StatusListener.ts @@ -1,8 +1,9 @@ -import { SETTING_SEO_DESCRIPTION_FIELD, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH } from './../constants/settings'; +import { SETTING_AUTO_UPDATE_DATE, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH } from './../constants/settings'; import * as vscode from 'vscode'; import { CONFIG_KEY } from '../constants'; import { ArticleHelper, SeoHelper } from '../helpers'; import { ExplorerView } from '../webview/ExplorerView'; +import { Article } from '.'; export class StatusListener { @@ -15,6 +16,7 @@ export class StatusListener { public static async verify(frontMatterSB: vscode.StatusBarItem, collection: vscode.DiagnosticCollection) { const draftMsg = "in draft"; const publishMsg = "to publish"; + const config = vscode.workspace.getConfiguration(CONFIG_KEY); let editor = vscode.window.activeTextEditor; if (editor && ArticleHelper.isMarkdownDile()) { @@ -51,6 +53,11 @@ export class StatusListener { SeoHelper.checkLength(editor, collection, article, fieldName, descLength); } } + + const autoUpdate = config.get(SETTING_AUTO_UPDATE_DATE); + if (autoUpdate) { + Article.setLastModifiedDate(); + } const panel = ExplorerView.getInstance(); if (panel && panel.visible) { diff --git a/src/constants/settings.ts b/src/constants/settings.ts index c03dd548..ad75786c 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -7,6 +7,7 @@ export const SETTING_TAXONOMY_CATEGORIES = "taxonomy.categories"; export const SETTING_DATE_FORMAT = "taxonomy.dateFormat"; export const SETTING_DATE_FIELD = "taxonomy.dateField"; export const SETTING_MODIFIED_FIELD = "taxonomy.modifiedField"; +export const SETTING_AUTO_UPDATE_DATE = "content.autoUpdateDate"; export const SETTING_SLUG_PREFIX = "taxonomy.slugPrefix"; export const SETTING_SLUG_SUFFIX = "taxonomy.slugSuffix"; diff --git a/src/models/PanelSettings.ts b/src/models/PanelSettings.ts index f2bfb351..45917630 100644 --- a/src/models/PanelSettings.ts +++ b/src/models/PanelSettings.ts @@ -7,6 +7,7 @@ export interface PanelSettings { freeform: boolean; scripts: CustomScript[]; isInitialized: boolean; + modifiedDateUpdate: boolean; contentInfo: FolderInfo[] | null; } diff --git a/src/viewpanel/CommandToCode.ts b/src/viewpanel/CommandToCode.ts index 1dc29d3c..3e9eb4a1 100644 --- a/src/viewpanel/CommandToCode.ts +++ b/src/viewpanel/CommandToCode.ts @@ -15,4 +15,5 @@ export enum CommandToCode { runCustomScript = "custom-script", initProject = "init-project", createContent = "create-content", + updateModifiedUpdating = "update-modified-updates", } \ No newline at end of file diff --git a/src/viewpanel/ViewPanel.tsx b/src/viewpanel/ViewPanel.tsx index e2e279ea..aeaa7223 100644 --- a/src/viewpanel/ViewPanel.tsx +++ b/src/viewpanel/ViewPanel.tsx @@ -3,6 +3,7 @@ import { CommandToCode } from './CommandToCode'; import { Actions } from './components/Actions'; import { BaseView } from './components/BaseView'; import { Collapsible } from './components/Collapsible'; +import { GlobalSettings } from './components/GlobalSettings'; import { BugIcon } from './components/Icons/BugIcon'; import { FileIcon } from './components/Icons/FileIcon'; import { FolderOpenedIcon } from './components/Icons/FolderOpenedIcon'; @@ -50,6 +51,8 @@ export const ViewPanel: React.FunctionComponent = (props: React return (
+ + { settings && settings.seo && } diff --git a/src/viewpanel/components/BaseView.tsx b/src/viewpanel/components/BaseView.tsx index 4d022f7c..d22ea754 100644 --- a/src/viewpanel/components/BaseView.tsx +++ b/src/viewpanel/components/BaseView.tsx @@ -3,6 +3,7 @@ import { PanelSettings } from '../../models'; import { CommandToCode } from '../CommandToCode'; import { MessageHelper } from '../helper/MessageHelper'; import { Collapsible } from './Collapsible'; +import { GlobalSettings } from './GlobalSettings'; export interface IBaseViewProps { settings: PanelSettings | undefined; @@ -21,6 +22,8 @@ export const BaseView: React.FunctionComponent = ({settings}: Re return (
+ +
diff --git a/src/viewpanel/components/GlobalSettings.tsx b/src/viewpanel/components/GlobalSettings.tsx new file mode 100644 index 00000000..2bac74f6 --- /dev/null +++ b/src/viewpanel/components/GlobalSettings.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { PanelSettings } from '../../models'; +import { CommandToCode } from '../CommandToCode'; +import { MessageHelper } from '../helper/MessageHelper'; +import { Collapsible } from './Collapsible'; +import { VsCheckbox } from './VscodeComponents'; + +export interface IGlobalSettingsProps { + settings: PanelSettings | undefined; +} + +export const GlobalSettings: React.FunctionComponent = ({settings}: React.PropsWithChildren) => { + const { modifiedDateUpdate } = settings || {}; + + const onCheck = () => { + MessageHelper.sendMessage(CommandToCode.updateModifiedUpdating, !modifiedDateUpdate); + }; + + return ( + <> + +
+ +
+
+ + ); +}; \ No newline at end of file diff --git a/src/viewpanel/components/VscodeComponents.ts b/src/viewpanel/components/VscodeComponents.ts index d4cb77f2..e2a10abe 100644 --- a/src/viewpanel/components/VscodeComponents.ts +++ b/src/viewpanel/components/VscodeComponents.ts @@ -6,4 +6,5 @@ export const VsTableHeaderCell = wrapWc(`vscode-table-header-cell`); export const VsTableBody = wrapWc(`vscode-table-body`); export const VsTableRow = wrapWc(`vscode-table-row`); export const VsTableCell = wrapWc(`vscode-table-cell`); -export const VsCollapsible = wrapWc(`vscode-collapsible`); \ No newline at end of file +export const VsCollapsible = wrapWc(`vscode-collapsible`); +export const VsCheckbox = wrapWc(`vscode-checkbox`); \ No newline at end of file diff --git a/src/viewpanel/index.tsx b/src/viewpanel/index.tsx index 55182aad..a3fb72a3 100644 --- a/src/viewpanel/index.tsx +++ b/src/viewpanel/index.tsx @@ -10,6 +10,7 @@ import '@bendera/vscode-webview-elements/dist/vscode-table-body'; import '@bendera/vscode-webview-elements/dist/vscode-table-row'; import '@bendera/vscode-webview-elements/dist/vscode-table-cell'; import '@bendera/vscode-webview-elements/dist/vscode-collapsible'; +import '@bendera/vscode-webview-elements/dist/vscode-checkbox'; declare const acquireVsCodeApi: () => { getState: () => T; diff --git a/src/webview/ExplorerView.ts b/src/webview/ExplorerView.ts index 4fc494f1..7e315836 100644 --- a/src/webview/ExplorerView.ts +++ b/src/webview/ExplorerView.ts @@ -1,5 +1,5 @@ import { Template } from './../commands/Template'; -import { SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME } from './../constants/settings'; +import { SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME } from './../constants/settings'; import * as os from 'os'; import { PanelSettings, CustomScript } from './../models/PanelSettings'; import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv } from "vscode"; @@ -146,6 +146,9 @@ export class ExplorerView implements WebviewViewProvider, Disposable { case CommandToCode.createContent: await commands.executeCommand(COMMAND_NAME.createContent); break; + case CommandToCode.updateModifiedUpdating: + this.updateModifiedUpdating(msg.data || false); + break; } }); @@ -262,7 +265,8 @@ 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 + contentInfo: await Folders.getInfo() || null, + modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false } as PanelSettings }); } @@ -376,6 +380,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable { } } + private async updateModifiedUpdating(autoUpdate: boolean) { + const config = workspace.getConfiguration(CONFIG_KEY); + await config.update(SETTING_AUTO_UPDATE_DATE, autoUpdate); + this.getSettings(); + } + /** * Post data to the panel * @param msg