From 7716d98868b9bbb9a1be0964e5bf5e59e80dd5d4 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 27 Aug 2021 11:30:25 +0200 Subject: [PATCH] #69 - Welcome screen integration --- CHANGELOG.md | 1 + package.json | 9 +- src/commands/Dashboard.ts | 25 +++++- src/constants/Links.ts | 4 + src/extension.ts | 12 ++- src/helpers/Extension.ts | 44 ++++++++++ src/models/VersionInfo.ts | 6 ++ src/pagesView/DashboardMessage.ts | 2 + src/pagesView/components/Dashboard.tsx | 22 ++++- src/pagesView/components/Overview.tsx | 4 +- src/pagesView/components/SponsorMsg.tsx | 19 +++++ src/pagesView/components/Steps/Step.tsx | 60 ++++++++++++++ .../components/Steps/StepsToGetStarted.tsx | 45 ++++++++++ src/pagesView/components/WelcomeScreen.tsx | 82 +++++++++++++++++++ src/pagesView/hooks/useMessages.tsx | 3 +- src/pagesView/index.tsx | 3 +- src/pagesView/models/Settings.ts | 2 + src/pagesView/models/Status.ts | 7 ++ .../components/Icons/FrontMatterIcon.tsx | 2 +- src/viewpanel/components/Icons/GitHubIcon.tsx | 11 +++ src/viewpanel/components/OtherActions.tsx | 3 +- src/viewpanel/components/SponsorMsg.tsx | 3 +- 22 files changed, 342 insertions(+), 27 deletions(-) create mode 100644 src/constants/Links.ts create mode 100644 src/helpers/Extension.ts create mode 100644 src/models/VersionInfo.ts create mode 100644 src/pagesView/components/SponsorMsg.tsx create mode 100644 src/pagesView/components/Steps/Step.tsx create mode 100644 src/pagesView/components/Steps/StepsToGetStarted.tsx create mode 100644 src/pagesView/components/WelcomeScreen.tsx create mode 100644 src/pagesView/models/Status.ts create mode 100644 src/viewpanel/components/Icons/GitHubIcon.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 16f3d8e9..6aab0436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#64](https://github.com/estruyf/vscode-front-matter/issues/64): Publish toggle for easier publishing an article - [#65](https://github.com/estruyf/vscode-front-matter/issues/65): Aggregate articles in draft - [#66](https://github.com/estruyf/vscode-front-matter/issues/66): New dashboard webview on which you can manage all your content +- [#69](https://github.com/estruyf/vscode-front-matter/issues/69): Welcome screen for getting started ## [2.5.1] - 2020-08-23 diff --git a/package.json b/package.json index 9db8c101..e774eb07 100644 --- a/package.json +++ b/package.json @@ -267,18 +267,15 @@ }, { "command": "frontMatter.createFromTemplate", - "title": "New article from template", - "category": "Front matter" + "title": "Front Matter: New article from template" }, { "command": "frontMatter.registerFolder", - "title": "Register folder", - "category": "Front matter" + "title": "Front Matter: Register folder" }, { "command": "frontMatter.unregisterFolder", - "title": "Unregister folder", - "category": "Front matter" + "title": "Front Matter: Unregister folder" }, { "command": "frontMatter.createContent", diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index cb3fdb9c..e0b11a32 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -14,6 +14,7 @@ import { COMMAND_NAME } from '../constants/Extension'; import { Template } from './Template'; import { Notifications } from '../helpers/Notifications'; import { Settings } from '../pagesView/models/Settings'; +import { Extension } from '../helpers/Extension'; export class Dashboard { @@ -92,6 +93,10 @@ export class Dashboard { Dashboard.isDisposed = true; }); + workspace.onDidChangeConfiguration(() => { + Dashboard.getSettings(); + }); + Dashboard.webview.webview.onDidReceiveMessage(async (msg) => { switch(msg.command) { case DashboardMessage.getData: @@ -107,6 +112,19 @@ export class Dashboard { case DashboardMessage.updateSetting: Dashboard.updateSetting(msg.data); break; + case DashboardMessage.InitializeProject: + await commands.executeCommand(COMMAND_NAME.init); + // Delay to allow the project to be initialized + setTimeout(() => { + Dashboard.getSettings(); + }, 1000); + break; + case DashboardMessage.Reload: + Dashboard.webview?.dispose(); + setTimeout(() => { + Dashboard.open(Extension.getInstance().extensionPath); + }, 100); + break; } }); } @@ -122,7 +140,8 @@ export class Dashboard { initialized: await Template.isInitialized(), tags: SettingsHelper.getTaxonomy(TaxonomyType.Tag), categories: SettingsHelper.getTaxonomy(TaxonomyType.Category), - openOnStart: SettingsHelper.getConfig().get(SETTINGS_DASHBOARD_OPENONSTART) + openOnStart: SettingsHelper.getConfig().get(SETTINGS_DASHBOARD_OPENONSTART), + versionInfo: Extension.getInstance().getVersion() } as Settings }); } @@ -213,6 +232,8 @@ export class Dashboard { const nonce = getNonce(); + const version = Extension.getInstance().getVersion(); + return ` @@ -223,7 +244,7 @@ export class Dashboard { Front Matter Dashboard -
+
Daily usage diff --git a/src/constants/Links.ts b/src/constants/Links.ts new file mode 100644 index 00000000..23123acc --- /dev/null +++ b/src/constants/Links.ts @@ -0,0 +1,4 @@ +export const GITHUB_LINK = "https://github.com/sponsors/estruyf"; +export const ISSUE_LINK = "https://github.com/estruyf/vscode-front-matter/issues"; +export const SPONSOR_LINK = "https://github.com/estruyf/vscode-front-matter"; +export const REVIEW_LINK = "https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter&ssr=false#review-details"; \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 6fedba3f..29ac2173 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,12 +5,12 @@ import { Folders } from './commands/Folders'; import { Preview } from './commands/Preview'; import { Project } from './commands/Project'; import { Template } from './commands/Template'; -import { COMMAND_NAME, EXTENSION_ID, EXTENSION_STATE_VERSION } from './constants/Extension'; +import { COMMAND_NAME } from './constants/Extension'; import { TaxonomyType } from './models'; import { MarkdownFoldingProvider } from './providers/MarkdownFoldingProvider'; import { TagType } from './viewpanel/TagType'; import { ExplorerView } from './webview/ExplorerView'; -import { Notifications } from './helpers/Notifications'; +import { Extension } from './helpers/Extension'; let frontMatterStatusBar: vscode.StatusBarItem; let statusDebouncer: { (fnc: any, time: number): void; }; @@ -20,11 +20,9 @@ let collection: vscode.DiagnosticCollection; const mdSelector: vscode.DocumentSelector = { language: 'markdown', scheme: 'file' }; export async function activate({ subscriptions, extensionUri, extensionPath, globalState }: vscode.ExtensionContext) { - collection = vscode.languages.createDiagnosticCollection('frontMatter'); + const extension = Extension.getInstance(globalState, extensionPath); - const frontMatter = vscode.extensions.getExtension(EXTENSION_ID)!; - const frontMatterVersoin = frontMatter.packageJSON.version; - const crntVersion = globalState.get(EXTENSION_STATE_VERSION); + collection = vscode.languages.createDiagnosticCollection('frontMatter'); // Pages dashboard Dashboard.init(extensionPath); @@ -32,7 +30,7 @@ export async function activate({ subscriptions, extensionUri, extensionPath, glo Dashboard.open(extensionPath); })); - if (!crntVersion) { + if (!extension.getVersion().usedVersion) { vscode.commands.executeCommand(COMMAND_NAME.dashboard); } diff --git a/src/helpers/Extension.ts b/src/helpers/Extension.ts new file mode 100644 index 00000000..3526669e --- /dev/null +++ b/src/helpers/Extension.ts @@ -0,0 +1,44 @@ +import { Memento, extensions } from "vscode"; +import { EXTENSION_ID, EXTENSION_STATE_VERSION } from "../constants/Extension"; + + +export class Extension { + private static instance: Extension; + + private constructor(private globalState: Memento, private extPath: string) {} + + /** + * Creates the singleton instance for the panel + * @param extPath + */ + public static getInstance(globalState?: Memento, extPath?: string): Extension { + if (!Extension.instance && globalState && extPath) { + Extension.instance = new Extension(globalState, extPath); + } + + return Extension.instance; + } + + public getVersion(): { usedVersion: string | undefined, installedVersion: string } { + const frontMatter = extensions.getExtension(EXTENSION_ID)!; + const installedVersion = frontMatter.packageJSON.version; + const usedVersion = this.globalState.get(EXTENSION_STATE_VERSION); + + if (!usedVersion) { + this.setVersion(installedVersion); + }; + + return { + usedVersion, + installedVersion + }; + } + + public setVersion(installedVersion: string): void { + this.globalState.update(EXTENSION_STATE_VERSION, installedVersion); + } + + public get extensionPath(): string { + return this.extPath; + } +} \ No newline at end of file diff --git a/src/models/VersionInfo.ts b/src/models/VersionInfo.ts new file mode 100644 index 00000000..478a0188 --- /dev/null +++ b/src/models/VersionInfo.ts @@ -0,0 +1,6 @@ + + +export interface VersionInfo { + usedVersion: string | undefined; + installedVersion: string; +} \ No newline at end of file diff --git a/src/pagesView/DashboardMessage.ts b/src/pagesView/DashboardMessage.ts index 0382347b..9ccdac81 100644 --- a/src/pagesView/DashboardMessage.ts +++ b/src/pagesView/DashboardMessage.ts @@ -4,4 +4,6 @@ export enum DashboardMessage { getTheme = 'getTheme', createContent = 'createContent', updateSetting = 'updateSetting', + InitializeProject = 'InitializeProject', + Reload = 'Reload', } \ No newline at end of file diff --git a/src/pagesView/components/Dashboard.tsx b/src/pagesView/components/Dashboard.tsx index 77575184..cd397d04 100644 --- a/src/pagesView/components/Dashboard.tsx +++ b/src/pagesView/components/Dashboard.tsx @@ -7,10 +7,14 @@ import { Tab } from '../constants/Tab'; import { SortOption } from '../constants/SortOption'; import useDarkMode from '../../hooks/useDarkMode'; import usePages from '../hooks/usePages'; +import { SponsorMsg } from './SponsorMsg'; +import { WelcomeScreen } from './WelcomeScreen'; -export interface IDashboardProps {} +export interface IDashboardProps { + showWelcome: boolean; +} -export const Dashboard: React.FunctionComponent = ({}: React.PropsWithChildren) => { +export const Dashboard: React.FunctionComponent = ({showWelcome}: React.PropsWithChildren) => { const { loading, pages, settings } = useMessages(); const [ tab, setTab ] = React.useState(Tab.All); const [ sorting, setSorting ] = React.useState(SortOption.LastModified); @@ -22,6 +26,18 @@ export const Dashboard: React.FunctionComponent = ({}: React.Pr useDarkMode(); const pageGroups = [...new Set(pages.map(page => page.fmGroup))]; + + if (!settings) { + return ; + } + + if (showWelcome) { + return ; + } + + if (!settings.initialized || settings.folders?.length === 0) { + return ; + } return (
@@ -46,7 +62,7 @@ export const Dashboard: React.FunctionComponent = ({}: React.Pr { loading ? : } -

If you find FrontMatter useful, please consider sponsoring it, or if you use FrontMatter for work, please encourage your employer to sponsoring it.

+
); diff --git a/src/pagesView/components/Overview.tsx b/src/pagesView/components/Overview.tsx index aeb364c3..8644b110 100644 --- a/src/pagesView/components/Overview.tsx +++ b/src/pagesView/components/Overview.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { FrontMatterIcon } from '../../viewpanel/components/Icons/FrontMatterIcon'; -import { MarkdownIcon } from '../../viewpanel/components/Icons/MarkdownIcon'; import { Page } from '../models/Page'; import { Settings } from '../models/Settings'; import { Item } from './Item'; @@ -18,13 +17,12 @@ export const Overview: React.FunctionComponent = ({pages, settin return (
- + { settings?.folders?.length > 0 ? (

No Markdown to show

) : ( <> -

Hi, this might be the first time you opened the dashboard, or recently started using Front Matter.

Make sure you registered a content folder in your project to let Front Matter find the contents.

) diff --git a/src/pagesView/components/SponsorMsg.tsx b/src/pagesView/components/SponsorMsg.tsx new file mode 100644 index 00000000..3f186caf --- /dev/null +++ b/src/pagesView/components/SponsorMsg.tsx @@ -0,0 +1,19 @@ +import { HeartIcon, StarIcon } from '@heroicons/react/outline'; +import * as React from 'react'; +import { REVIEW_LINK, SPONSOR_LINK } from '../../constants/Links'; + +export interface ISponsorMsgProps {} + +export const SponsorMsg: React.FunctionComponent = (props: React.PropsWithChildren) => { + return ( +

+ + Sponsor + + FrontMatter + + Review + +

+ ); +}; \ No newline at end of file diff --git a/src/pagesView/components/Steps/Step.tsx b/src/pagesView/components/Steps/Step.tsx new file mode 100644 index 00000000..7e961ef4 --- /dev/null +++ b/src/pagesView/components/Steps/Step.tsx @@ -0,0 +1,60 @@ +import { CheckIcon } from '@heroicons/react/outline'; +import * as React from 'react'; +import { Status } from '../../models/Status'; + +export interface IStepProps { + name: string; + description: string; + status: Status; + showLine: boolean; + onClick?: () => void; +} + +export const Step: React.FunctionComponent = ({name, description, status, showLine, onClick}: React.PropsWithChildren) => { + return ( + <> + { + showLine ? ( +