From 8a0d308ceb784dac85e8e2025e644272ba9391f6 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Wed, 17 Nov 2021 14:18:04 +0100 Subject: [PATCH] #178 - Sorting for media files --- CHANGELOG.md | 1 + src/commands/Dashboard.ts | 44 +++++++++++++++---- src/constants/ExtensionState.ts | 7 ++- .../components/Contents/Contents.tsx | 8 ++-- src/dashboardWebView/components/Dashboard.tsx | 7 ++- .../components/Header/Breadcrumb.tsx | 10 ++++- .../components/Header/Header.tsx | 22 ++++++---- .../components/Header/Sorting.tsx | 28 ++++++++---- .../components/Media/Pagination.tsx | 18 ++++++-- src/dashboardWebView/hooks/useMessages.tsx | 5 ++- src/dashboardWebView/hooks/usePages.tsx | 2 +- src/dashboardWebView/models/Settings.ts | 5 +++ src/dashboardWebView/models/ViewType.ts | 4 ++ src/dashboardWebView/models/index.ts | 2 + .../state/atom/DashboardViewAtom.ts | 5 ++- 15 files changed, 126 insertions(+), 42 deletions(-) create mode 100644 src/dashboardWebView/models/ViewType.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index defc7e09..6f6ad5ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Updated camera icon from VS Code to media icon - Updated `check` icon on media inserts to `plus` icon +- [#178](https://github.com/estruyf/vscode-front-matter/issues/178): Sorting added to the media dashboard - [#179](https://github.com/estruyf/vscode-front-matter/issues/179): Updated the `open dashboard` icon to make it easier to spot it ## [5.5.0] - 2021-11-15 diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index 91c3290c..f7ce1ebd 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -4,7 +4,7 @@ import { basename, dirname, extname, join, parse } from "path"; import { existsSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs"; import { commands, Uri, ViewColumn, Webview, WebviewPanel, window, workspace, env, Position } from "vscode"; import { Settings as SettingsHelper } from '../helpers'; -import { DraftField, Framework, SortingSetting, TaxonomyType } from '../models'; +import { DraftField, Framework, SortingSetting, SortOrder, TaxonomyType } from '../models'; import { Folders } from './Folders'; import { DashboardCommand } from '../dashboardWebView/DashboardCommand'; import { DashboardMessage } from '../dashboardWebView/DashboardMessage'; @@ -26,6 +26,7 @@ import { parseWinPath } from '../helpers/parseWinPath'; import { DateHelper } from '../helpers/DateHelper'; import { FrameworkDetector } from '../helpers/FrameworkDetector'; import { ContentType } from '../helpers/ContentType'; +import { SortingOption } from '../dashboardWebView/models'; export class Dashboard { private static webview: WebviewPanel | null = null; @@ -174,7 +175,7 @@ export class Dashboard { Extension.getInstance().setState(ExtensionState.PagesView, msg.data, "workspace"); break; case DashboardMessage.getMedia: - Dashboard.getMedia(msg?.data?.page, msg?.data?.folder); + Dashboard.getMedia(msg?.data?.page, msg?.data?.folder, msg?.data?.sorting); break; case DashboardMessage.copyToClipboard: env.clipboard.writeText(msg.data); @@ -299,7 +300,12 @@ export class Dashboard { crntFramework: SettingsHelper.get(SETTINGS_FRAMEWORK_ID), framework: (!isInitialized && wsFolder) ? FrameworkDetector.get(wsFolder.fsPath) : null, dashboardState: { - sorting: await ext.getState(ExtensionState.Dashboard.Sorting, "workspace") + contents: { + sorting: await ext.getState(ExtensionState.Dashboard.Contents.Sorting, "workspace") + }, + media: { + sorting: await ext.getState(ExtensionState.Dashboard.Media.Sorting, "workspace") + } } } as Settings }); @@ -334,16 +340,19 @@ export class Dashboard { /** * Retrieve all media files */ - private static async getMedia(page: number = 0, requestedFolder: string = '') { + private static async getMedia(page: number = 0, requestedFolder: string = '', sort: SortingOption | null = null) { const wsFolder = Folders.getWorkspaceFolder(); const staticFolder = SettingsHelper.get(SETTINGS_CONTENT_STATIC_FOLDER); const contentFolders = Folders.get(); const viewData = Dashboard.viewData; let selectedFolder = requestedFolder; + const ext = Extension.getInstance(); + const crntSort = sort === null ? await ext.getState(ExtensionState.Dashboard.Media.Sorting, "workspace") : sort; + // If the static folder is not set, retreive the last opened location if (!selectedFolder) { - const stateValue = await Extension.getInstance().getState(ExtensionState.SelectedFolder, "workspace"); + const stateValue = await ext.getState(ExtensionState.SelectedFolder, "workspace"); if (stateValue !== HOME_PAGE_NAVIGATION_ID) { // Support for page bundles @@ -400,15 +409,19 @@ export class Dashboard { } allMedia = allMedia.sort((a, b) => { - if (b.fsPath < a.fsPath) { + if (a.fsPath.toLowerCase() < b.fsPath.toLowerCase()) { return -1; } - if (b.fsPath > a.fsPath) { + if (a.fsPath.toLowerCase() > b.fsPath.toLowerCase()) { return 1; } return 0; }); + if (crntSort?.order === SortOrder.desc) { + allMedia = allMedia.reverse(); + } + Dashboard.media = Object.assign([], allMedia); let files: MediaInfo[] = Dashboard.media; @@ -459,13 +472,28 @@ export class Dashboard { // Store the last opened folder await Extension.getInstance().setState(ExtensionState.SelectedFolder, requestedFolder === HOME_PAGE_NAVIGATION_ID ? HOME_PAGE_NAVIGATION_ID : selectedFolder, "workspace"); + + let sortedFolders = [...allContentFolders, ...allFolders]; + sortedFolders = sortedFolders.sort((a, b) => { + if (a.toLowerCase() < b.toLowerCase()) { + return -1; + } + if (a.toLowerCase() > b.toLowerCase()) { + return 1; + } + return 0; + }); + + if (crntSort?.order === SortOrder.desc) { + sortedFolders = sortedFolders.reverse(); + } Dashboard.postWebviewMessage({ command: DashboardCommand.media, data: { media: files, total: total, - folders: [...allContentFolders, ...allFolders], + folders: sortedFolders, selectedFolder } as MediaPaths }); diff --git a/src/constants/ExtensionState.ts b/src/constants/ExtensionState.ts index d486d45a..36139f50 100644 --- a/src/constants/ExtensionState.ts +++ b/src/constants/ExtensionState.ts @@ -7,6 +7,11 @@ export const ExtensionState = { MoveTemplatesFolder: `frontMatter:Templates:Move`, Dashboard: { - Sorting: `frontMatter:Dashboard:Sorting`, + Contents: { + Sorting: `frontMatter:Dashboard:Contents:Sorting`, + }, + Media: { + Sorting: `frontMatter:Dashboard:Media:Sorting`, + } } }; \ No newline at end of file diff --git a/src/dashboardWebView/components/Contents/Contents.tsx b/src/dashboardWebView/components/Contents/Contents.tsx index 5817d556..b2450786 100644 --- a/src/dashboardWebView/components/Contents/Contents.tsx +++ b/src/dashboardWebView/components/Contents/Contents.tsx @@ -6,6 +6,7 @@ import { Header } from '../Header'; import { Overview } from './Overview'; import { Spinner } from '../Spinner'; import { SponsorMsg } from '../SponsorMsg'; +import usePages from '../../hooks/usePages'; export interface IContentsProps { pages: Page[]; @@ -14,19 +15,20 @@ export interface IContentsProps { export const Contents: React.FunctionComponent = ({pages, loading}: React.PropsWithChildren) => { const settings = useRecoilValue(SettingsSelector); + const { pageItems } = usePages(pages); - const pageFolders = [...new Set(pages.map(page => page.fmFolder))]; + const pageFolders = [...new Set(pageItems.map(page => page.fmFolder))]; return (
- { loading ? : } + { loading ? : }
diff --git a/src/dashboardWebView/components/Dashboard.tsx b/src/dashboardWebView/components/Dashboard.tsx index c48071b3..b4519d0a 100644 --- a/src/dashboardWebView/components/Dashboard.tsx +++ b/src/dashboardWebView/components/Dashboard.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import { Spinner } from './Spinner'; import useMessages from '../hooks/useMessages'; import useDarkMode from '../../hooks/useDarkMode'; -import usePages from '../hooks/usePages'; import { WelcomeScreen } from './WelcomeScreen'; import { useRecoilValue } from 'recoil'; import { DashboardViewSelector } from '../state'; import { Contents } from './Contents/Contents'; import { Media } from './Media/Media'; +import { ViewType } from '../models'; export interface IDashboardProps { showWelcome: boolean; @@ -15,7 +15,6 @@ export interface IDashboardProps { export const Dashboard: React.FunctionComponent = ({showWelcome}: React.PropsWithChildren) => { const { loading, pages, settings } = useMessages(); - const { pageItems } = usePages(pages); const view = useRecoilValue(DashboardViewSelector); useDarkMode(); @@ -31,9 +30,9 @@ export const Dashboard: React.FunctionComponent = ({showWelcome return ; } - if (view === 'media') { + if (view === ViewType.Media) { return ; } - return ; + return ; }; \ No newline at end of file diff --git a/src/dashboardWebView/components/Header/Breadcrumb.tsx b/src/dashboardWebView/components/Header/Breadcrumb.tsx index 3675354c..86486725 100644 --- a/src/dashboardWebView/components/Header/Breadcrumb.tsx +++ b/src/dashboardWebView/components/Header/Breadcrumb.tsx @@ -2,8 +2,10 @@ import { CollectionIcon } from '@heroicons/react/outline'; import { basename, join } from 'path'; import * as React from 'react'; import { useRecoilState, useRecoilValue } from 'recoil'; +import { Sorting } from '.'; import { HOME_PAGE_NAVIGATION_ID } from '../../../constants'; import { parseWinPath } from '../../../helpers/parseWinPath'; +import { ViewType } from '../../models'; import { SelectedMediaFolderAtom, SettingsAtom } from '../../state'; export interface IBreadcrumbProps {} @@ -63,8 +65,8 @@ export const Breadcrumb: React.FunctionComponent = (props: Rea }, [selectedFolder]); return ( -