mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-08 01:42:58 +02:00
@@ -3,6 +3,11 @@
|
||||
## [2.4.0] - 2020-08-xx
|
||||
|
||||
- [#21](https://github.com/estruyf/vscode-front-matter/issues/21): Folding provider for Front Matter implemented
|
||||
- [#55](https://github.com/estruyf/vscode-front-matter/issues/55): Highlight Front Matter in Markdown files
|
||||
- [#56](https://github.com/estruyf/vscode-front-matter/issues/56): Action to collapse all Front Matter panel sections at once
|
||||
- [#57](https://github.com/estruyf/vscode-front-matter/issues/57): New action added to provide better writing settings (only for Markdown files)
|
||||
- [#58](https://github.com/estruyf/vscode-front-matter/issues/58): Sections remember their previous state (folded/unfolded)
|
||||
- [#59](https://github.com/estruyf/vscode-front-matter/issues/59): Center layout view toggle action added
|
||||
|
||||
## [2.3.0] - 2020-08-10
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" fill="none" viewBox="0 0 24 24" stroke="#F3EFF5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 216 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" fill="none" viewBox="0 0 24 24" stroke="currentcolor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 221 B |
@@ -278,10 +278,21 @@
|
||||
.ext_link_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ext_link_block svg {
|
||||
margin-right: .5rem;
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
}
|
||||
|
||||
.ext_link_block button span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ext_link_block button,
|
||||
@@ -301,6 +312,16 @@
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ext_link_block button.active {
|
||||
color: var(--vscode-button-foreground);
|
||||
background: var(--vscode-button-background);
|
||||
}
|
||||
.ext_link_block button.active:hover {
|
||||
cursor: pointer;
|
||||
background: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
|
||||
.ext_link_block a:hover,
|
||||
|
||||
+19
-1
@@ -57,6 +57,7 @@
|
||||
"onCommand:frontMatter.unregisterFolder",
|
||||
"onCommand:frontMatter.createContent",
|
||||
"onCommand:frontMatter.init",
|
||||
"onCommand:frontMatter.collapseSections",
|
||||
"onView:frontMatter.explorer"
|
||||
],
|
||||
"main": "./dist/extension",
|
||||
@@ -268,6 +269,15 @@
|
||||
"command": "frontMatter.createTemplate",
|
||||
"title": "Create a template from current file",
|
||||
"category": "Front matter"
|
||||
},
|
||||
{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"title": "Collapse sections",
|
||||
"category": "Front matter",
|
||||
"icon": {
|
||||
"light": "assets/icons/close-light.svg",
|
||||
"dark": "assets/icons/close-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -296,8 +306,16 @@
|
||||
{
|
||||
"command": "frontMatter.createTemplate",
|
||||
"when": "!frontMatterCanInit"
|
||||
},
|
||||
{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"when": "false"
|
||||
}
|
||||
]
|
||||
],
|
||||
"view/title": [{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"group": "navigation"
|
||||
}]
|
||||
},
|
||||
"grammars": [
|
||||
{
|
||||
|
||||
@@ -20,5 +20,6 @@ export const COMMAND_NAME = {
|
||||
registerFolder: getCommandName("registerFolder"),
|
||||
unregisterFolder: getCommandName("unregisterFolder"),
|
||||
createContent: getCommandName("createContent"),
|
||||
createTemplate: getCommandName("createTemplate")
|
||||
createTemplate: getCommandName("createTemplate"),
|
||||
collapseSections: getCommandName("collapseSections"),
|
||||
};
|
||||
+9
-2
@@ -26,6 +26,7 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
}
|
||||
});
|
||||
|
||||
// Folding the front matter of markdown files
|
||||
vscode.languages.registerFoldingRangeProvider(mdSelector, new MarkdownFoldingProvider());
|
||||
|
||||
let insertTags = vscode.commands.registerCommand(COMMAND_NAME.insertTags, async () => {
|
||||
@@ -73,7 +74,7 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
if (folderPath) {
|
||||
Template.create(folderPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let createTemplate = vscode.commands.registerCommand(COMMAND_NAME.createTemplate, Template.generate);
|
||||
|
||||
@@ -96,6 +97,11 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
Template.init();
|
||||
const projectInit = vscode.commands.registerCommand(COMMAND_NAME.init, Project.init);
|
||||
|
||||
// Collapse all sections in the webview
|
||||
const collapseAll = vscode.commands.registerCommand(COMMAND_NAME.collapseSections, () => {
|
||||
ExplorerView.getInstance()?.collapseAll();
|
||||
});
|
||||
|
||||
// Things to do when configuration changes
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
Template.init();
|
||||
@@ -137,7 +143,8 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
registerFolder,
|
||||
unregisterFolder,
|
||||
createContent,
|
||||
projectInit
|
||||
projectInit,
|
||||
collapseAll
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface PanelSettings {
|
||||
isInitialized: boolean;
|
||||
modifiedDateUpdate: boolean;
|
||||
contentInfo: FolderInfo[] | null;
|
||||
writingSettingsEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface SEO {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { TextEditorDecorationType, window, ColorThemeKind } from "vscode";
|
||||
|
||||
|
||||
export class FrontMatterDecorationProvider {
|
||||
|
||||
get(): TextEditorDecorationType {
|
||||
const colorThemeKind = window.activeColorTheme.kind;
|
||||
|
||||
return window.createTextEditorDecorationType({
|
||||
backgroundColor: colorThemeKind === ColorThemeKind.Dark ? "#ffffff14" : "#00000014",
|
||||
isWholeLine: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, TextDocument } from 'vscode';
|
||||
import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, Range, TextDocument, window, TextEditorDecorationType, Position } from 'vscode';
|
||||
import { FrontMatterDecorationProvider } from './FrontMatterDecorationProvider';
|
||||
|
||||
export class MarkdownFoldingProvider implements FoldingRangeProvider {
|
||||
|
||||
@@ -16,11 +17,17 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
|
||||
start = i;
|
||||
} else if (start !== null && end === null) {
|
||||
end = i;
|
||||
|
||||
const range = new Range(new Position(start, 0), new Position(end, line.length));
|
||||
const decoration = new FrontMatterDecorationProvider().get();
|
||||
window.activeTextEditor?.setDecorations(decoration, [range]);
|
||||
|
||||
ranges.push(new FoldingRange(start, end, FoldingRangeKind.Region));
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,6 @@ export enum Command {
|
||||
metadata = "metadata",
|
||||
settings = "settings",
|
||||
focusOnTags = "focusOnTags",
|
||||
focusOnCategories = "focusOnCategories"
|
||||
focusOnCategories = "focusOnCategories",
|
||||
closeSections = "closeSections",
|
||||
}
|
||||
@@ -17,4 +17,6 @@ export enum CommandToCode {
|
||||
createContent = "create-content",
|
||||
updateModifiedUpdating = "update-modified-updates",
|
||||
createTemplate = "create-template",
|
||||
toggleCenterMode = "toggle-center-mode",
|
||||
toggleWritingSettings = "toggle-writing-settings",
|
||||
}
|
||||
@@ -43,7 +43,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
settings && metadata && <Actions metadata={metadata} settings={settings} />
|
||||
}
|
||||
|
||||
<Collapsible title="Metadata" className={`inherit z-20`}>
|
||||
<Collapsible id={`tags`} title="Metadata" className={`inherit z-20`}>
|
||||
{
|
||||
<TagPicker type={TagType.keywords}
|
||||
icon={<SymbolKeywordIcon />}
|
||||
@@ -78,7 +78,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
}
|
||||
</Collapsible>
|
||||
|
||||
<OtherActions isFile={true} />
|
||||
<OtherActions settings={settings} isFile={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IActionButtonProps {
|
||||
title: string;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
onClick: (e: React.SyntheticEvent<HTMLButtonElement>) => void;
|
||||
}
|
||||
|
||||
export const ActionButton: React.FunctionComponent<IActionButtonProps> = ({className, onClick, disabled,title}: React.PropsWithChildren<IActionButtonProps>) => {
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={onClick} className={className || ""} disabled={disabled}>{title}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models/PanelSettings';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { CustomScript } from './CustomScript';
|
||||
import { DateAction } from './DateAction';
|
||||
@@ -19,8 +22,11 @@ export const Actions: React.FunctionComponent<IActionsProps> = (props: React.Pro
|
||||
}
|
||||
|
||||
return (
|
||||
<Collapsible title="Actions">
|
||||
<Collapsible id={`actions`} title="Actions">
|
||||
<div className={`article__actions`}>
|
||||
|
||||
<ActionButton onClick={() => MessageHelper.sendMessage(CommandToCode.toggleCenterMode)} title={`Toggle center mode`} />
|
||||
|
||||
{ metadata && metadata.title && <SlugAction value={metadata.title} crntValue={metadata.slug} slugOpts={settings.slug} /> }
|
||||
|
||||
<DateAction />
|
||||
|
||||
@@ -23,9 +23,9 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
return (
|
||||
<div className="frontmatter">
|
||||
<div className={`ext_actions`}>
|
||||
<GlobalSettings settings={settings} />
|
||||
<GlobalSettings settings={settings} isBase />
|
||||
|
||||
<Collapsible title="Actions">
|
||||
<Collapsible id={`base_actions`} title="Actions">
|
||||
<div className={`base__actions`}>
|
||||
<button onClick={initProject} disabled={settings?.isInitialized}>Initialize project</button>
|
||||
<button onClick={createContent} disabled={!settings?.isInitialized}>Create new content</button>
|
||||
@@ -34,7 +34,7 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
|
||||
{
|
||||
settings?.contentInfo && (
|
||||
<Collapsible title="Content information">
|
||||
<Collapsible id={`base_content`} title="Content information">
|
||||
<div className="base__information">
|
||||
{
|
||||
settings.contentInfo.map(folder => (
|
||||
@@ -48,7 +48,7 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
)
|
||||
}
|
||||
|
||||
<OtherActions isFile={false} />
|
||||
<OtherActions settings={settings} isFile={false} isBase />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { Command } from '../Command';
|
||||
import { VsCollapsible } from './VscodeComponents';
|
||||
|
||||
export interface ICollapsibleProps {
|
||||
id: string;
|
||||
title: string;
|
||||
className?: string;
|
||||
sendUpdate?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({children, title, sendUpdate, className}: React.PropsWithChildren<ICollapsibleProps>) => {
|
||||
const [ isOpen, setIsOpen ] = React.useState(true);
|
||||
export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({id, children, title, sendUpdate, className}: React.PropsWithChildren<ICollapsibleProps>) => {
|
||||
const [ isOpen, setIsOpen ] = React.useState(false);
|
||||
const collapseKey = `collapse-${id}`;
|
||||
|
||||
const updateStorage = (value: boolean) => {
|
||||
window.localStorage.setItem(collapseKey, value.toString());
|
||||
}
|
||||
|
||||
// This is a work around for a lit-element issue of duplicate slot names
|
||||
const triggerClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
@@ -17,11 +25,29 @@ export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({childre
|
||||
if (sendUpdate) {
|
||||
sendUpdate(!prev);
|
||||
}
|
||||
|
||||
updateStorage(!prev);
|
||||
return !prev;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const collapsed = window.localStorage.getItem(collapseKey);
|
||||
if (collapsed === null || collapsed === 'true') {
|
||||
setIsOpen(true);
|
||||
updateStorage(true);
|
||||
}
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
const message = event.data;
|
||||
if (message.command === Command.closeSections) {
|
||||
setIsOpen(false);
|
||||
updateStorage(false);
|
||||
}
|
||||
});
|
||||
}, ['']);
|
||||
|
||||
return (
|
||||
<VsCollapsible title={title} onClick={triggerClick} open={isOpen}>
|
||||
<div className={`section collapsible__body ${className || ""}`} slot="body">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface ICustomScriptProps {
|
||||
title: string;
|
||||
@@ -14,8 +15,6 @@ export const CustomScript: React.FunctionComponent<ICustomScriptProps> = ({title
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={runCustomScript}>{title}</button>
|
||||
</div>
|
||||
<ActionButton onClick={runCustomScript} title={title} />
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface IDateActionProps {}
|
||||
|
||||
@@ -16,12 +17,8 @@ export const DateAction: React.FunctionComponent<IDateActionProps> = (props: Rea
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`article__action`}>
|
||||
<button onClick={setDate}>Set publish date</button>
|
||||
</div>
|
||||
<div className={`article__action`}>
|
||||
<button onClick={setLastMod}>Set modified date</button>
|
||||
</div>
|
||||
<ActionButton onClick={setDate} title={`Set publish date`} />
|
||||
<ActionButton onClick={setLastMod} title={`Set modified date`} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -7,9 +7,10 @@ import { VsCheckbox } from './VscodeComponents';
|
||||
|
||||
export interface IGlobalSettingsProps {
|
||||
settings: PanelSettings | undefined;
|
||||
isBase?: boolean;
|
||||
}
|
||||
|
||||
export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({settings}: React.PropsWithChildren<IGlobalSettingsProps>) => {
|
||||
export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({settings, isBase}: React.PropsWithChildren<IGlobalSettingsProps>) => {
|
||||
const { modifiedDateUpdate } = settings || {};
|
||||
|
||||
const onCheck = () => {
|
||||
@@ -18,7 +19,7 @@ export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({s
|
||||
|
||||
return (
|
||||
<>
|
||||
<Collapsible title="Global settings">
|
||||
<Collapsible id={`${isBase ? "base_" : ""}settings`} title="Global settings">
|
||||
<div className={`base__actions`}>
|
||||
<VsCheckbox label="Auto-update modified date" checked={modifiedDateUpdate} onClick={onCheck} />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IWritingIconProps {}
|
||||
|
||||
export const WritingIcon: React.FunctionComponent<IWritingIconProps> = (props: React.PropsWithChildren<IWritingIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M7.223 10.933c.326.192.699.29 1.077.282a2.159 2.159 0 0 0 1.754-.842 3.291 3.291 0 0 0 .654-2.113 2.886 2.886 0 0 0-.576-1.877 1.99 1.99 0 0 0-1.634-.733 2.294 2.294 0 0 0-1.523.567V3.475h-.991V11.1h.995v-.344c.076.066.158.125.244.177zM7.85 6.7c.186-.079.388-.113.59-.1a1.08 1.08 0 0 1 .896.428c.257.363.382.802.357 1.245a2.485 2.485 0 0 1-.4 1.484 1.133 1.133 0 0 1-.96.508 1.224 1.224 0 0 1-.976-.417A1.522 1.522 0 0 1 6.975 8.8v-.6a1.722 1.722 0 0 1 .393-1.145c.13-.154.296-.276.482-.355zM3.289 5.675a3.03 3.03 0 0 0-.937.162 2.59 2.59 0 0 0-.8.4l-.1.077v1.2l.423-.359a2.1 2.1 0 0 1 1.366-.572.758.758 0 0 1 .661.282c.15.232.23.503.231.779L2.9 7.825a2.6 2.6 0 0 0-1.378.575 1.65 1.65 0 0 0-.022 2.336 1.737 1.737 0 0 0 1.253.454 1.96 1.96 0 0 0 1.107-.332c.102-.068.197-.145.286-.229v.444h.941V7.715a2.193 2.193 0 0 0-.469-1.5 1.687 1.687 0 0 0-1.329-.54zm.857 3.041c.02.418-.12.829-.391 1.148a1.221 1.221 0 0 1-.955.422.832.832 0 0 1-.608-.2.833.833 0 0 1 0-1.091c.281-.174.6-.277.93-.3l1.02-.148.004.169zm8.313 2.317c.307.13.64.193.973.182.495.012.983-.114 1.41-.365l.123-.075.013-.007V9.615l-.446.32c-.316.224-.696.34-1.084.329A1.3 1.3 0 0 1 12.4 9.8a1.975 1.975 0 0 1-.4-1.312 2.01 2.01 0 0 1 .453-1.381A1.432 1.432 0 0 1 13.6 6.6a1.8 1.8 0 0 1 .971.279l.43.265V5.97l-.17-.073a2.9 2.9 0 0 0-1.17-.247 2.52 2.52 0 0 0-1.929.817 2.9 2.9 0 0 0-.747 2.049c-.028.707.21 1.4.67 1.939.222.249.497.446.804.578z"/></svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IOtherActionButtonProps {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
onClick: (e: React.SyntheticEvent<HTMLButtonElement>) => void;
|
||||
}
|
||||
|
||||
export const OtherActionButton: React.FunctionComponent<IOtherActionButtonProps> = ({ className, disabled, onClick, children}: React.PropsWithChildren<IOtherActionButtonProps>) => {
|
||||
return (
|
||||
<div className={`ext_link_block`}>
|
||||
<button onClick={onClick} className={className || ""} disabled={disabled}>{children}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { Collapsible } from './Collapsible';
|
||||
@@ -7,12 +8,16 @@ import { FileIcon } from './Icons/FileIcon';
|
||||
import { FolderOpenedIcon } from './Icons/FolderOpenedIcon';
|
||||
import { SettingsIcon } from './Icons/SettingsIcon';
|
||||
import { TemplateIcon } from './Icons/TemplateIcon';
|
||||
import { WritingIcon } from './Icons/WritingIcon';
|
||||
import { OtherActionButton } from './OtherActionButton';
|
||||
|
||||
export interface IOtherActionsProps {
|
||||
isFile: boolean;
|
||||
settings: PanelSettings | undefined;
|
||||
isBase?: boolean;
|
||||
}
|
||||
|
||||
export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFile}: React.PropsWithChildren<IOtherActionsProps>) => {
|
||||
export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFile, settings, isBase}: React.PropsWithChildren<IOtherActionsProps>) => {
|
||||
|
||||
const openSettings = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.openSettings);
|
||||
@@ -30,27 +35,25 @@ export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFil
|
||||
MessageHelper.sendMessage(CommandToCode.createTemplate);
|
||||
};
|
||||
|
||||
const toggleWritingSettings = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.toggleWritingSettings);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Collapsible title="Other actions" className={`other_actions`}>
|
||||
<div className="ext_link_block">
|
||||
<button onClick={createAsTemplate} disabled={!isFile}><TemplateIcon /> Create as template</button>
|
||||
</div>
|
||||
<Collapsible id={`${isBase ? "base_" : ""}other_actions`} title="Other actions" className={`other_actions`}>
|
||||
<OtherActionButton className={settings?.writingSettingsEnabled ? "active" : ""} onClick={toggleWritingSettings} disabled={typeof settings?.writingSettingsEnabled === "undefined"}><WritingIcon /> <span>{settings?.writingSettingsEnabled ? "Writing settings enabled" : "Enable writing settings"}</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={createAsTemplate} disabled={!isFile}><TemplateIcon /> <span>Create as template</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openSettings}><SettingsIcon /> <span>Open settings</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openFile} disabled={!isFile}><FileIcon /> <span>Reveal file in folder</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openProject}><FolderOpenedIcon /> <span>Reveal project folder</span></OtherActionButton>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openSettings}><SettingsIcon /> Open settings</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openFile} disabled={!isFile}><FileIcon /> Reveal file in folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openProject}><FolderOpenedIcon /> Reveal project folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub"><BugIcon /> Report an issue</a>
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub"><BugIcon /> <span>Report an issue</span></a>
|
||||
</div>
|
||||
</Collapsible>
|
||||
</>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface IPublishActionProps {
|
||||
draft: boolean;
|
||||
@@ -16,8 +17,6 @@ export const PublishAction: React.FunctionComponent<IPublishActionProps> = (prop
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={publish} className={`${draft ? "" : "secondary"}`}>{draft ? "Publish" : "Revert to draft"}</button>
|
||||
</div>
|
||||
<ActionButton onClick={publish} className={`${draft ? "" : "secondary"}`} title={draft ? "Publish" : "Revert to draft"} />
|
||||
);
|
||||
};
|
||||
@@ -88,7 +88,7 @@ export const SeoStatus: React.FunctionComponent<ISeoStatusProps> = (props: React
|
||||
}, [title, data[descriptionField], data?.articleDetails?.wordCount]);
|
||||
|
||||
return (
|
||||
<Collapsible title="SEO Status" sendUpdate={(value) => setIsOpen(value)}>
|
||||
<Collapsible id={`seo`} title="SEO Status" sendUpdate={(value) => setIsOpen(value)}>
|
||||
{ renderContent() }
|
||||
</Collapsible>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SlugHelper } from '../../helpers/SlugHelper';
|
||||
import { Slug } from '../../models/PanelSettings';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface ISlugActionProps {
|
||||
value: string;
|
||||
@@ -21,8 +22,6 @@ export const SlugAction: React.FunctionComponent<ISlugActionProps> = (props: Rea
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={optimize} disabled={crntValue === slug}>Optimize slug</button>
|
||||
</div>
|
||||
<ActionButton onClick={optimize} disabled={crntValue === slug} title={`Optimize slug`} />
|
||||
);
|
||||
};
|
||||
@@ -152,6 +152,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
case CommandToCode.updateModifiedUpdating:
|
||||
this.updateModifiedUpdating(msg.data || false);
|
||||
break;
|
||||
case CommandToCode.toggleWritingSettings:
|
||||
this.toggleWritingSettings();
|
||||
break;
|
||||
case CommandToCode.toggleCenterMode:
|
||||
await commands.executeCommand(`workbench.action.toggleCenteredLayout`);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -201,6 +207,13 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger all sections to close
|
||||
*/
|
||||
public collapseAll() {
|
||||
this.postWebviewMessage({ command: Command.closeSections });
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a custom script
|
||||
* @param msg
|
||||
@@ -269,7 +282,8 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
scripts: config.get(SETTING_CUSTOM_SCRIPTS),
|
||||
isInitialized: await Template.isInitialized(),
|
||||
contentInfo: await Folders.getInfo() || null,
|
||||
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false
|
||||
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false,
|
||||
writingSettingsEnabled: this.isWritingSettingsEnabled() || false
|
||||
} as PanelSettings
|
||||
});
|
||||
}
|
||||
@@ -383,6 +397,43 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the writing settings
|
||||
*/
|
||||
private async toggleWritingSettings() {
|
||||
const config = workspace.getConfiguration("", { languageId: "markdown" });
|
||||
const enabled = this.isWritingSettingsEnabled();
|
||||
|
||||
await config.update("editor.fontSize", enabled ? undefined : 14, false, true);
|
||||
await config.update("editor.lineHeight", enabled ? undefined : 26, false, true);
|
||||
await config.update("editor.wordWrap", enabled ? undefined : "wordWrapColumn", false, true);
|
||||
await config.update("editor.wordWrapColumn", enabled ? undefined : 64, false, true);
|
||||
await config.update("editor.lineNumbers", enabled ? undefined : "off", false, true);
|
||||
await config.update("editor.quickSuggestions", enabled ? undefined : false, false, true);
|
||||
await config.update("editor.minimap.enabled", enabled ? undefined : false, false, true);
|
||||
|
||||
this.getSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the writing settings are enabled
|
||||
*/
|
||||
private isWritingSettingsEnabled() {
|
||||
const config = workspace.getConfiguration("", { languageId: "markdown" });
|
||||
|
||||
const fontSize = config.get("editor.fontSize");
|
||||
const lineHeight = config.get("editor.lineHeight");
|
||||
const wordWrap = config.get("editor.wordWrap");
|
||||
const wordWrapColumn = config.get("editor.wordWrapColumn");
|
||||
const lineNumbers = config.get("editor.lineNumbers");
|
||||
const quickSuggestions = config.get<boolean>("editor.quickSuggestions");
|
||||
|
||||
return fontSize && lineHeight && wordWrap && wordWrapColumn && lineNumbers && quickSuggestions !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the modified auto-update setting
|
||||
*/
|
||||
private async updateModifiedUpdating(autoUpdate: boolean) {
|
||||
const config = workspace.getConfiguration(CONFIG_KEY);
|
||||
await config.update(SETTING_AUTO_UPDATE_DATE, autoUpdate);
|
||||
@@ -397,7 +448,9 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
this.panel!.webview.postMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a unique nonce
|
||||
*/
|
||||
private getNonce() {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
Reference in New Issue
Block a user