#73 - persist view type setting

This commit is contained in:
Elio Struyf
2021-09-04 12:40:28 +02:00
parent 9f5d180447
commit 918f914c91
16 changed files with 72 additions and 27 deletions
+12 -5
View File
@@ -10,12 +10,13 @@ import { DashboardCommand } from '../pagesView/DashboardCommand';
import { DashboardMessage } from '../pagesView/DashboardMessage';
import { Page } from '../pagesView/models/Page';
import { openFileInEditor } from '../helpers/openFileInEditor';
import { COMMAND_NAME } from '../constants/Extension';
import { COMMAND_NAME, EXTENSION_STATE_PAGES_VIEW } from '../constants/Extension';
import { Template } from './Template';
import { Notifications } from '../helpers/Notifications';
import { Settings } from '../pagesView/models/Settings';
import { Extension } from '../helpers/Extension';
import { parseJSON } from 'date-fns';
import { ViewType } from '../pagesView/state';
export class Dashboard {
@@ -114,10 +115,10 @@ export class Dashboard {
case DashboardMessage.updateSetting:
Dashboard.updateSetting(msg.data);
break;
case DashboardMessage.InitializeProject:
case DashboardMessage.initializeProject:
await commands.executeCommand(COMMAND_NAME.init, Dashboard.getSettings);
break;
case DashboardMessage.Reload:
case DashboardMessage.reload:
if (!Dashboard.isDisposed) {
Dashboard.webview?.dispose();
setTimeout(() => {
@@ -125,6 +126,9 @@ export class Dashboard {
}, 100);
}
break;
case DashboardMessage.setPageViewType:
Extension.getInstance().setState(EXTENSION_STATE_PAGES_VIEW, msg.data);
break;
}
});
}
@@ -133,6 +137,8 @@ export class Dashboard {
* Retrieve the settings for the dashboard
*/
private static async getSettings() {
const ext = Extension.getInstance();
Dashboard.postWebviewMessage({
command: DashboardCommand.settings,
data: {
@@ -141,7 +147,8 @@ export class Dashboard {
tags: SettingsHelper.getTaxonomy(TaxonomyType.Tag),
categories: SettingsHelper.getTaxonomy(TaxonomyType.Category),
openOnStart: SettingsHelper.getConfig().get(SETTINGS_DASHBOARD_OPENONSTART),
versionInfo: Extension.getInstance().getVersion()
versionInfo: ext.getVersion(),
pageViewType: await ext.getState<ViewType | undefined>(EXTENSION_STATE_PAGES_VIEW)
} as Settings
});
}
@@ -202,7 +209,7 @@ export class Dashboard {
pages.push(page);
}
} catch (error) {
} catch (error: any) {
Notifications.error(`File error: ${file.filePath} - ${error?.message || error}`);
}
}
+2
View File
@@ -1,7 +1,9 @@
const extensionName = "frontMatter";
export const EXTENSION_ID = 'eliostruyf.vscode-front-matter';
export const EXTENSION_STATE_VERSION = 'frontMatter:Version';
export const EXTENSION_STATE_PAGES_VIEW = 'frontMatter:Pages:ViewType';
export const getCommandName = (command: string) => {
return `${extensionName}.${command}`;
+8
View File
@@ -73,4 +73,12 @@ export class Extension {
await config.update(`${SETTINGS_CONTENT_PAGE_FOLDERS}`, paths);
}
}
public async setState(propKey: string, propValue: string): Promise<void> {
await this.globalState.update(propKey, propValue);
}
public async getState<T>(propKey: string): Promise<T | undefined> {
return await this.globalState.get(propKey);
}
}
+3 -2
View File
@@ -4,6 +4,7 @@ export enum DashboardMessage {
getTheme = 'getTheme',
createContent = 'createContent',
updateSetting = 'updateSetting',
InitializeProject = 'InitializeProject',
Reload = 'Reload',
initializeProject = 'initializeProject',
reload = 'reload',
setPageViewType = 'setPageViewType',
}
+1 -1
View File
@@ -43,7 +43,7 @@ export const Dashboard: React.FunctionComponent<IDashboardProps> = ({showWelcome
{ loading ? <Spinner /> : <Overview pages={pageItems} settings={settings} /> }
</div>
<SponsorMsg />
<SponsorMsg version={settings.versionInfo} />
</div>
</main>
);
+1 -1
View File
@@ -49,7 +49,7 @@ export const Header: React.FunctionComponent<IHeaderProps> = ({totalPages, folde
<Navigation totalPages={totalPages} />
</div>
<div className={`my-4 lg:my-0 w-full flex items-center justify-end space-x-4 lg:space-x-6 xl:space-x-8 order-first lg:order-last`}>
<div className={`my-4 lg:my-0 w-full flex items-center justify-between lg:justify-end space-x-4 lg:space-x-6 xl:space-x-8 order-first lg:order-last`}>
<Folders folders={folders} />
<Filter label={`Tag filter`} activeItem={crntTag} items={settings.tags} onClick={(value) => setCrntTag(value)} />
+13 -4
View File
@@ -1,20 +1,29 @@
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { ViewAtom, ViewType } from '../../state';
import { ViewGridIcon, ViewListIcon } from '@heroicons/react/solid';
import { STORAGE_VIEW_TYPE } from '../../constants/Storage';
import { SettingsAtom } from '../../state/atom/SettingsAtom';
import { MessageHelper } from '../../../helpers/MessageHelper';
import { DashboardMessage } from '../../DashboardMessage';
export interface IViewSwitchProps {}
export const ViewSwitch: React.FunctionComponent<IViewSwitchProps> = (props: React.PropsWithChildren<IViewSwitchProps>) => {
const [ view, setView ] = useRecoilState(ViewAtom);
const settings = useRecoilValue(SettingsAtom);
const toggleView = () => {
const newView = view === ViewType.Grid ? ViewType.List : ViewType.Grid;
window.localStorage.setItem(STORAGE_VIEW_TYPE, newView.toString());
setView(newView);
MessageHelper.sendMessage(DashboardMessage.setPageViewType, newView);
};
React.useEffect(() => {
if (settings?.pageViewType) {
setView(settings?.pageViewType);
}
}, [settings?.pageViewType]);
return (
<div className={`flex rounded-sm bg-vulcan-50 lg:mb-1`}>
<button className={`flex items-center p-2 rounded-l-sm ${view === ViewType.Grid ? 'bg-teal-500 text-vulcan-500' : 'text-whisper-500'}`} onClick={toggleView}>
+6 -3
View File
@@ -1,16 +1,19 @@
import { HeartIcon, StarIcon } from '@heroicons/react/outline';
import * as React from 'react';
import { REVIEW_LINK, SPONSOR_LINK } from '../../constants/Links';
import { VersionInfo } from '../../models';
export interface ISponsorMsgProps {}
export interface ISponsorMsgProps {
version: VersionInfo;
}
export const SponsorMsg: React.FunctionComponent<ISponsorMsgProps> = (props: React.PropsWithChildren<ISponsorMsgProps>) => {
export const SponsorMsg: React.FunctionComponent<ISponsorMsgProps> = ({version}: React.PropsWithChildren<ISponsorMsgProps>) => {
return (
<p className={`w-full max-w-7xl mx-auto px-4 text-vulcan-50 dark:text-whisper-900 py-2 text-center space-x-8 flex items-center justify-between`}>
<a className={`group inline-flex justify-center items-center space-x-2 text-vulcan-500 dark:text-whisper-500 hover:text-vulcan-600 dark:hover:text-whisper-300 opacity-50 hover:opacity-100`} href={SPONSOR_LINK} title="Sponsor Front Matter">
<span>Sponsor</span> <HeartIcon className={`h-5 w-5 group-hover:fill-current`} />
</a>
<span>FrontMatter</span>
<span>FrontMatter{version ? ` (v${version.installedVersion})` : ''}</span>
<a className={`group inline-flex justify-center items-center space-x-2 text-vulcan-500 dark:text-whisper-500 hover:text-vulcan-600 dark:hover:text-whisper-300 opacity-50 hover:opacity-100`} href={REVIEW_LINK} title="Review Front Matter">
<StarIcon className={`h-5 w-5 group-hover:fill-current`} /> <span>Review</span>
</a>
@@ -16,7 +16,7 @@ export const StepsToGetStarted: React.FunctionComponent<IStepsToGetStartedProps>
name: 'Initialize project',
description: 'Initialize the project with a template folder and sample markdown file. The template folder can be used to define your own templates. <b>Start by clicking on this action</b>.',
status: settings.initialized ? Status.Completed : Status.NotStarted,
onClick: settings.initialized ? undefined : () => { MessageHelper.sendMessage(DashboardMessage.InitializeProject); }
onClick: settings.initialized ? undefined : () => { MessageHelper.sendMessage(DashboardMessage.initializeProject); }
},
{
name: 'Register content folders (manual action)',
@@ -27,7 +27,7 @@ export const StepsToGetStarted: React.FunctionComponent<IStepsToGetStartedProps>
name: 'Show the dashboard',
description: 'Once both actions are completed, click on this action to load the dashboard.',
status: (settings.initialized && settings.folders && settings.folders.length > 0) ? Status.Active : Status.NotStarted,
onClick: (settings.initialized && settings.folders && settings.folders.length > 0) ? () => { MessageHelper.sendMessage(DashboardMessage.Reload); } : undefined
onClick: (settings.initialized && settings.folders && settings.folders.length > 0) ? () => { MessageHelper.sendMessage(DashboardMessage.reload); } : undefined
}
];
+1 -1
View File
@@ -16,7 +16,7 @@ export const WelcomeScreen: React.FunctionComponent<IWelcomeScreenProps> = ({set
React.useEffect(() => {
return () => {
MessageHelper.sendMessage(DashboardMessage.Reload)
MessageHelper.sendMessage(DashboardMessage.reload)
};
}, ['']);
-1
View File
@@ -1 +0,0 @@
export const STORAGE_VIEW_TYPE = 'FrontMatter:ListViewType';
+4 -3
View File
@@ -1,16 +1,17 @@
import { useState, useEffect } from 'react';
import { useRecoilState } from 'recoil';
import { MessageHelper } from '../../helpers/MessageHelper';
import { DashboardCommand } from '../DashboardCommand';
import { DashboardMessage } from '../DashboardMessage';
import { Page } from '../models/Page';
import { Settings } from '../models/Settings';
import { SettingsAtom } from '../state/atom/SettingsAtom';
const vscode = MessageHelper.getVsCodeAPI();
export default function useMessages(options?: any) {
export default function useMessages() {
const [loading, setLoading] = useState<boolean>(false);
const [pages, setPages] = useState<Page[]>([]);
const [settings, setSettings] = useState<Settings | undefined>(undefined);
const [settings, setSettings] = useRecoilState(SettingsAtom);
window.addEventListener('message', event => {
const message = event.data;
+2
View File
@@ -1,4 +1,5 @@
import { VersionInfo } from '../../models/VersionInfo';
import { ViewType } from '../state';
import { ContentFolder } from './../../models/ContentFolder';
export interface Settings {
@@ -8,4 +9,5 @@ export interface Settings {
categories: string[];
openOnStart: boolean | null;
versionInfo: VersionInfo;
pageViewType: ViewType | undefined;
}
+7
View File
@@ -0,0 +1,7 @@
import { atom } from 'recoil';
import { Settings } from '../../models';
export const SettingsAtom = atom<Settings | null>({
key: 'SettingsAtom',
default: null
});
+1 -4
View File
@@ -1,14 +1,11 @@
import { atom } from 'recoil';
import { STORAGE_VIEW_TYPE } from '../../constants/Storage';
export enum ViewType {
Grid = 1,
List
}
const defaultView: number = parseInt(window.localStorage.getItem(STORAGE_VIEW_TYPE) as string);
export const ViewAtom = atom<ViewType>({
key: 'ViewAtom',
default: isNaN(defaultView) ? ViewType.Grid : defaultView
default: ViewType.Grid
});
@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { SettingsAtom } from '../atom/SettingsAtom';
export const SettingsSelector = selector({
key: 'SettingsSelector',
get: ({get}) => {
return get(SettingsAtom);
}
});