From 840e6fc6fd33aaaec20652f909c24cee18d1312b Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 10 Sep 2021 14:01:46 +0200 Subject: [PATCH] Delete media --- package-lock.json | 6 +- package.json | 2 +- src/commands/Dashboard.ts | 26 +++++- src/pagesView/DashboardMessage.ts | 1 + src/pagesView/components/Media/Item.tsx | 102 +++++++++++++--------- src/pagesView/components/Modals/Alert.tsx | 89 +++++++++++++++++++ src/pagesView/state/atom/PageAtom.ts | 6 ++ src/pagesView/state/atom/index.ts | 1 + 8 files changed, 188 insertions(+), 45 deletions(-) create mode 100644 src/pagesView/components/Modals/Alert.tsx create mode 100644 src/pagesView/state/atom/PageAtom.ts diff --git a/package-lock.json b/package-lock.json index d19c5193..2ccfde93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -219,9 +219,9 @@ } }, "@headlessui/react": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.0.tgz", - "integrity": "sha512-C+FmBVF6YGvqcEI5fa2dfVbEaXr2RGR6Kw1E5HXIISIZEfsrH/yuCgsjWw5nlRF9vbCxmQ/EKs64GAdKeb8gCw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.1.tgz", + "integrity": "sha512-gL6Ns5xQM57cZBzX6IVv6L7nsam8rDEpRhs5fg28SN64ikfmuuMgunc+Rw5C1cMScnvFM+cz32ueVrlSFEVlSg==", "dev": true }, "@heroicons/react": { diff --git a/package.json b/package.json index d0b0cdee..14f75e41 100644 --- a/package.json +++ b/package.json @@ -397,7 +397,7 @@ "devDependencies": { "@bendera/vscode-webview-elements": "0.6.2", "@estruyf/vscode": "0.0.2", - "@headlessui/react": "1.4.0", + "@headlessui/react": "^1.4.1", "@heroicons/react": "1.0.4", "@iarna/toml": "2.2.3", "@tailwindcss/forms": "^0.3.3", diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index a4ea54de..09a425a1 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -1,7 +1,7 @@ import { SETTINGS_CONTENT_STATIC_FOLDERS, SETTING_DATE_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTINGS_DASHBOARD_OPENONSTART } from './../constants/settings'; import { ArticleHelper } from './../helpers/ArticleHelper'; -import { dirname, extname, join } from "path"; -import { existsSync, statSync, writeFileSync } from "fs"; +import { basename, dirname, extname, join } from "path"; +import { existsSync, statSync, unlinkSync, writeFileSync } from "fs"; import { commands, Uri, ViewColumn, Webview, WebviewPanel, window, workspace, env } from "vscode"; import { SettingsHelper } from '../helpers'; import { TaxonomyType } from '../models'; @@ -147,6 +147,9 @@ export class Dashboard { case DashboardMessage.uploadMedia: Dashboard.saveFile(msg?.data); break; + case DashboardMessage.deleteMedia: + Dashboard.deleteFile(msg?.data); + break; } }); } @@ -403,6 +406,25 @@ export class Dashboard { } } + /** + * Delete the selected file + * @param fileData + */ + private static async deleteFile({ file, page, folder }: { file: string; page: number; folder: string | null; }) { + if (!file) { + return; + } + + try { + unlinkSync(file); + + Dashboard.media = []; + Dashboard.getMedia(page || 0, folder || ""); + } catch(err) { + Notifications.error(`Something went wrong deleting ${basename(file)}`); + } + } + /** * Post data to the dashboard * @param msg diff --git a/src/pagesView/DashboardMessage.ts b/src/pagesView/DashboardMessage.ts index 9c512b8b..b8b33daa 100644 --- a/src/pagesView/DashboardMessage.ts +++ b/src/pagesView/DashboardMessage.ts @@ -11,4 +11,5 @@ export enum DashboardMessage { copyToClipboard = 'copyToClipboard', refreshMedia = 'refreshMedia', uploadMedia = 'uploadMedia', + deleteMedia = 'deleteMedia', } \ No newline at end of file diff --git a/src/pagesView/components/Media/Item.tsx b/src/pagesView/components/Media/Item.tsx index 4ba9c6f8..90575696 100644 --- a/src/pagesView/components/Media/Item.tsx +++ b/src/pagesView/components/Media/Item.tsx @@ -5,7 +5,8 @@ import * as React from 'react'; import { useRecoilState, useRecoilValue } from 'recoil'; import { MediaInfo } from '../../../models/MediaPaths'; import { DashboardMessage } from '../../DashboardMessage'; -import { LightboxAtom, SettingsSelector } from '../../state'; +import { LightboxAtom, SelectedMediaFolderSelector, SettingsSelector } from '../../state'; +import { Alert } from '../Modals/Alert'; export interface IItemProps { media: MediaInfo; @@ -13,7 +14,9 @@ export interface IItemProps { export const Item: React.FunctionComponent = ({media}: React.PropsWithChildren) => { const settings = useRecoilValue(SettingsSelector); + const selectedFolder = useRecoilValue(SelectedMediaFolderSelector); const [ , setLightbox ] = useRecoilState(LightboxAtom); + const [ showAlert, setShowAlert ] = React.useState(false); const parseWinPath = (path: string | undefined) => { return path?.split(`\\`).join(`/`); @@ -46,7 +49,14 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi }; const deleteMedia = () => { + setShowAlert(true); + }; + const confirmDeletion = () => { + Messenger.send(DashboardMessage.deleteMedia, { + file: media.fsPath, + folder: selectedFolder + }); }; const calculateSize = () => { @@ -65,44 +75,58 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi }; return ( -
  • - +
    +
    + + +
    +

    + {basename(parseWinPath(media.fsPath) || "")} +

    +

    + Folder: {getFolder()} +

    + { + media?.stats?.size && ( +

    + Size: {calculateSize()} +

    + ) + }
    -
    - {basename(media.fsPath)} -
    - -
    -
    - - -
    -

    - {basename(parseWinPath(media.fsPath) || "")} -

    -

    - Folder: {getFolder()} -

    - { - media?.stats?.size && ( -

    - Size: {calculateSize()} -

    - ) - } -
    -
  • + + + { + showAlert && ( + setShowAlert(false)} + trigger={confirmDeletion} /> + ) + } + ); }; \ No newline at end of file diff --git a/src/pagesView/components/Modals/Alert.tsx b/src/pagesView/components/Modals/Alert.tsx new file mode 100644 index 00000000..ecc7fca1 --- /dev/null +++ b/src/pagesView/components/Modals/Alert.tsx @@ -0,0 +1,89 @@ +import { Dialog, Transition, } from '@headlessui/react'; +import { ExclamationIcon } from '@heroicons/react/outline'; +import * as React from 'react'; +import { Fragment, useRef } from 'react'; + +export interface IAlertProps { + title: string; + description: string; + okBtnText: string; + cancelBtnText: string; + + dismiss: () => void; + trigger: () => void; +} + +export const Alert: React.FunctionComponent = ({title, description, cancelBtnText, okBtnText, dismiss, trigger}: React.PropsWithChildren) => { + + const cancelButtonRef = useRef(null); + + return ( + + dismiss()}> +
    + + + + + {/* This element is to trick the browser into centering the modal contents. */} + + + +
    +
    +
    +
    +
    + + {title} + +
    +

    + {description} +

    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + ); +}; \ No newline at end of file diff --git a/src/pagesView/state/atom/PageAtom.ts b/src/pagesView/state/atom/PageAtom.ts new file mode 100644 index 00000000..d02de481 --- /dev/null +++ b/src/pagesView/state/atom/PageAtom.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const PageAtom = atom({ + key: 'PageAtom', + default: 0 +}); \ No newline at end of file diff --git a/src/pagesView/state/atom/index.ts b/src/pagesView/state/atom/index.ts index 6d399e55..a8d30209 100644 --- a/src/pagesView/state/atom/index.ts +++ b/src/pagesView/state/atom/index.ts @@ -6,6 +6,7 @@ export * from './LightboxAtom'; export * from './LoadingAtom'; export * from './MediaFoldersAtom'; export * from './MediaTotalAtom'; +export * from './PageAtom'; export * from './SearchAtom'; export * from './SelectedMediaFolderAtom'; export * from './SettingsAtom';