#430 - support for post_asset_folder folder

This commit is contained in:
Elio Struyf
2022-10-08 17:33:42 +02:00
parent b9a0c656d3
commit 8d53990aea
19 changed files with 277 additions and 59 deletions
+1
View File
@@ -10,6 +10,7 @@
- [#406](https://github.com/estruyf/vscode-front-matter/issues/406): Added support for single data entries in the data dashboard
- [#428](https://github.com/estruyf/vscode-front-matter/issues/428): Improved UX for inserting images to your content
- [#430](https://github.com/estruyf/vscode-front-matter/issues/430): Support for HEXO its `post_asset_folder` setting (image location)
- [#434](https://github.com/estruyf/vscode-front-matter/issues/434): Webview errors are logged in the extension output
### ⚡️ Optimizations
+11 -11
View File
@@ -1,3 +1,4 @@
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
import { Questions } from './../helpers/Questions';
import { SETTING_CONTENT_PAGE_FOLDERS, SETTING_CONTENT_STATIC_FOLDER, SETTING_CONTENT_SUPPORTED_FILETYPES, TelemetryEvent } from './../constants';
import { commands, Uri, workspace, window } from "vscode";
@@ -43,6 +44,10 @@ export class Folders {
startPath += "/";
}
if (startPath.includes(STATIC_FOLDER_PLACEHOLDER.hexo.placeholder)) {
startPath = startPath.replace(STATIC_FOLDER_PLACEHOLDER.hexo.placeholder, STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder);
}
const folderName = await window.showInputBox({
title: `Add media folder`,
prompt: `Which name would you like to give to your folder (use "/" to create multi-level folders)?`,
@@ -56,22 +61,17 @@ export class Folders {
return;
}
const folders = folderName.split("/").filter(f => f);
let parentFolders: string[] = [];
await Folders.createFolder(join(parseWinPath(wsFolder?.fsPath || ""), folderName));
}
for (const folder of folders) {
const folderPath = join(parseWinPath(wsFolder?.fsPath || ""), parentFolders.join("/"), folder);
parentFolders.push(folder);
if (!(await existsAsync(folderPath))) {
await mkdirAsync(folderPath);
}
public static async createFolder(folderPath: string) {
if (!(await existsAsync(folderPath))) {
await mkdirAsync(folderPath, { recursive: true });
}
if (Dashboard.isOpen) {
MediaHelpers.resetMedia();
MediaListener.sendMediaFiles(0, folderName);
MediaListener.sendMediaFiles(0, folderPath);
}
Telemetry.send(TelemetryEvent.addMediaFolder);
+8
View File
@@ -0,0 +1,8 @@
export const STATIC_FOLDER_PLACEHOLDER = {
hexo: {
postsFolder: "source/_posts",
placeholder: "hexo:post_asset_folder",
}
}
+1
View File
@@ -12,6 +12,7 @@ export * from './LocalStore';
export * from './Navigation';
export * from './NotificationType';
export * from './PreviewCommands';
export * from './StaticFolderPlaceholder';
export * from './TelemetryEvent';
export * from './charCode';
export * from './charMap';
+1
View File
@@ -31,6 +31,7 @@ export enum DashboardMessage {
updateMediaMetadata = 'updateMediaMetadata',
createMediaFolder = 'createMediaFolder',
insertFile = 'insertFile',
createHexoAssetFolder = 'createHexoAssetFolder',
// Data dashboard
getDataEntries = 'getDataEntries',
@@ -65,6 +65,8 @@ export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, ti
return [];
}, [settings, pageData]);
console.log(pageData[PREVIEW_IMAGE_FIELD])
if (view === DashboardViewType.Grid) {
return (
<li className="relative">
@@ -2,16 +2,34 @@ import * as React from 'react';
import {FolderAddIcon, LightningBoltIcon} from '@heroicons/react/outline';
import { useRecoilValue } from 'recoil';
import { DashboardMessage } from '../../DashboardMessage';
import { SelectedMediaFolderAtom, SettingsSelector } from '../../state';
import { AllContentFoldersAtom, AllStaticFoldersAtom, SelectedMediaFolderAtom, SettingsSelector, ViewDataSelector } from '../../state';
import { Messenger } from '@estruyf/vscode/dist/client';
import { ChoiceButton } from '../ChoiceButton';
import { CustomScript, ScriptType } from '../../../models';
import { STATIC_FOLDER_PLACEHOLDER } from '../../../constants';
import { useCallback, useMemo } from 'react';
import { extname } from 'path';
import { parseWinPath } from '../../../helpers/parseWinPath';
export interface IFolderCreationProps {}
export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (props: React.PropsWithChildren<IFolderCreationProps>) => {
const selectedFolder = useRecoilValue(SelectedMediaFolderAtom);
const settings = useRecoilValue(SettingsSelector);
const allStaticFolders = useRecoilValue(AllStaticFoldersAtom);
const allContentFolders = useRecoilValue(AllContentFoldersAtom);
const viewData = useRecoilValue(ViewDataSelector);
const hexoAssetFolderPath = useMemo(() => {
const path = viewData?.data?.filePath?.replace(extname(viewData.data.filePath), '');
return parseWinPath(path);
}, [viewData?.data?.filePath]);
const onAssetFolderCreation = useCallback(() => {
Messenger.send(DashboardMessage.createHexoAssetFolder, {
hexoAssetFolderPath
});
}, [hexoAssetFolderPath]);
const onFolderCreation = () => {
Messenger.send(DashboardMessage.createMediaFolder, {
@@ -23,11 +41,34 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (pr
Messenger.send(DashboardMessage.runCustomScript, {script, path: selectedFolder});
};
const isHexoPostAssetsEnabled = useMemo(() => {
if (allStaticFolders && allContentFolders && settings?.staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder && hexoAssetFolderPath) {
return ![...allStaticFolders, ...allContentFolders].some(f => f.startsWith(hexoAssetFolderPath));
}
return false;
}, [settings?.staticFolder, allStaticFolders, allContentFolders, hexoAssetFolderPath]);
const scripts = (settings?.scripts || []).filter(script => script.type === ScriptType.MediaFolder && !script.hidden);
const renderPostAssetsButton = useMemo(() => {
if (isHexoPostAssetsEnabled) {
return (
<button
className={`mr-2 inline-flex items-center px-3 py-1 border border-transparent text-xs leading-4 font-medium text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 focus:outline-none disabled:bg-gray-500`}
title={`Create post asset folder`}
onClick={onAssetFolderCreation}>
<FolderAddIcon className={`mr-2 h-6 w-6`} />
<span className={``}>Create post asset folder</span>
</button>
);
}
return null;
}, [isHexoPostAssetsEnabled]);
if (scripts.length > 0) {
return (
<div className="flex flex-1 justify-end">
{ renderPostAssetsButton }
<ChoiceButton
title={`Create new folder`}
choices={scripts.map(s => ({
@@ -43,6 +84,7 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (pr
return (
<div className="flex flex-1 justify-end">
{ renderPostAssetsButton }
<button
className={`inline-flex items-center px-3 py-1 border border-transparent text-xs leading-4 font-medium text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 focus:outline-none disabled:bg-gray-500`}
title={`Create new folder`}
+40 -19
View File
@@ -9,15 +9,16 @@ import { Item } from './Item';
import { Lightbox } from './Lightbox';
import { List } from './List';
import { useDropzone } from 'react-dropzone'
import { useCallback, useEffect } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { DashboardMessage } from '../../DashboardMessage';
import { FrontMatterIcon } from '../../../panelWebView/components/Icons/FrontMatterIcon';
import { FolderItem } from './FolderItem';
import useMedia from '../../hooks/useMedia';
import { TelemetryEvent } from '../../../constants';
import { STATIC_FOLDER_PLACEHOLDER, TelemetryEvent } from '../../../constants';
import { PageLayout } from '../Layout/PageLayout';
import { parseWinPath } from '../../../helpers/parseWinPath';
import { basename, extname, join } from 'path';
import { MediaInfo } from '../../../models';
export interface IMediaProps {}
@@ -29,9 +30,20 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
const folders = useRecoilValue(MediaFoldersAtom);
const loading = useRecoilValue(LoadingAtom);
const contentFolders = React.useMemo(() => {
// Check if content allows page bundle
if (viewData && viewData.data && typeof viewData.data.pageBundle !== "undefined" && !viewData.data.pageBundle) {
const currentStaticFolder = useMemo(() => {
if (settings?.staticFolder) {
let staticFolderPath = join('/', settings?.staticFolder || '', '/');
if (settings?.staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
staticFolderPath = join('/', STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder, '/');
}
return staticFolderPath;
}
return;
}, [settings?.staticFolder])
const contentFolders = useMemo(() => {
// Check if content allows page bundle or if Hexo post assets are enabled
if (viewData && viewData.data && typeof viewData.data.pageBundle !== "undefined" && !viewData.data.pageBundle && settings?.staticFolder !== STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
return [];
}
@@ -46,17 +58,26 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
}
return groupedFolders;
}, [folders, viewData, settings?.contentFolders]);
}, [folders, viewData, settings?.contentFolders, settings?.staticFolder]);
const publicFolders = React.useMemo(() => {
return folders.filter(f => parseWinPath(f).includes(join('/', settings?.staticFolder || '', '/')));
}, [folders, viewData, settings?.staticFolder]);
const publicFolders = useMemo(() => {
if (currentStaticFolder && settings?.staticFolder !== STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
return folders.filter(f => parseWinPath(f).includes(currentStaticFolder));
}
const allMedia = React.useMemo(() => {
let mediaFiles = media;
return undefined;
}, [folders, viewData, currentStaticFolder, settings?.staticFolder]);
const allMedia = useMemo(() => {
let mediaFiles: MediaInfo[] = Object.assign([], media);
// Check if content allows page bundle
if (viewData && viewData.data && typeof viewData.data.pageBundle !== "undefined" && !viewData.data.pageBundle) {
mediaFiles = media.filter(m => parseWinPath(m.fsPath).includes(join('/', settings?.staticFolder || '', '/')));
if (currentStaticFolder && viewData && viewData.data && typeof viewData.data.pageBundle !== "undefined" && !viewData.data.pageBundle) {
mediaFiles = media.filter(m => parseWinPath(m.fsPath).includes(currentStaticFolder));
}
// Filter if Hexo post folder
if (currentStaticFolder && settings?.staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
mediaFiles = mediaFiles.filter(m => parseWinPath(m.fsPath).includes(currentStaticFolder));
}
if (viewData && viewData.data && viewData.data.type === "file" && viewData.data.fileExtensions && viewData.data.fileExtensions.length > 0) {
@@ -70,7 +91,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
}
return mediaFiles;
}, [media, viewData, settings?.staticFolder]);
}, [media, viewData, currentStaticFolder, settings?.staticFolder]);
const onDrop = useCallback((acceptedFiles: File[]) => {
acceptedFiles.forEach((file) => {
@@ -120,7 +141,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
<div className="absolute top-0 left-0 w-full h-full text-whisper-500 bg-gray-900 bg-opacity-70 flex flex-col justify-center items-center z-50">
<UploadIcon className={`h-32`} />
<p className={`text-xl max-w-md text-center`}>
{selectedFolder ? `Upload to ${selectedFolder}` : `No folder selected, files you drop will be added to the ${settings?.staticFolder || "public"} folder.`}
{selectedFolder ? `Upload to ${selectedFolder}` : `No folder selected, files you drop will be added to the ${currentStaticFolder || "public"} folder.`}
</p>
</div>
)
@@ -132,7 +153,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
<div className={`max-w-xl text-center`}>
<FrontMatterIcon className={`text-vulcan-300 dark:text-whisper-800 h-32 mx-auto opacity-90 mb-8`} />
<p className={`text-xl font-medium`}>No media files to show. You can drag &amp; drop new files.</p>
<p className={`text-xl font-medium`}>No media files to show. You can drag &amp; drop new files by holding your [shift] key.</p>
</div>
</div>
)
@@ -147,7 +168,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
<List gap={0}>
{
group.folders.map((folder) => (
<FolderItem key={folder} folder={folder} staticFolder={settings?.staticFolder} wsFolder={settings?.wsFolder} />
<FolderItem key={folder} folder={folder} staticFolder={currentStaticFolder} wsFolder={settings?.wsFolder} />
))
}
</List>
@@ -160,13 +181,13 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
publicFolders && publicFolders.length > 0 && (
<div className={`mb-8`}>
{
contentFolders && contentFolders.length > 0 && (<h2 className='text-lg mb-8'>Public folder{settings?.staticFolder && (<span>: <b>{settings?.staticFolder}</b></span>)}</h2>)
contentFolders && contentFolders.length > 0 && (<h2 className='text-lg mb-8'>Public folder{currentStaticFolder && (<span>: <b>{currentStaticFolder}</b></span>)}</h2>)
}
<List gap={0}>
{
publicFolders.map((folder) => (
<FolderItem key={folder} folder={folder} staticFolder={settings?.staticFolder} wsFolder={settings?.wsFolder} />
<FolderItem key={folder} folder={folder} staticFolder={currentStaticFolder} wsFolder={settings?.wsFolder} />
))
}
</List>
+5 -1
View File
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { MediaInfo, MediaPaths } from '../../models';
import { DashboardCommand } from '../DashboardCommand';
import { LoadingAtom, MediaFoldersAtom, MediaTotalAtom, PageAtom, SearchAtom, SelectedMediaFolderAtom, SettingsAtom } from '../state';
import { AllContentFoldersAtom, AllStaticFoldersAtom, LoadingAtom, MediaFoldersAtom, MediaTotalAtom, PageAtom, SearchAtom, SelectedMediaFolderAtom, SettingsAtom } from '../state';
import Fuse from 'fuse.js';
import usePagination from './usePagination';
@@ -26,6 +26,8 @@ export default function useMedia() {
const [ , setSelectedFolder ] = useRecoilState(SelectedMediaFolderAtom);
const [ , setTotal ] = useRecoilState(MediaTotalAtom);
const [ , setFolders ] = useRecoilState(MediaFoldersAtom);
const [ , setAllContentFolders ] = useRecoilState(AllContentFoldersAtom);
const [ , setAllStaticFolders ] = useRecoilState(AllStaticFoldersAtom);
const [ , setLoading ] = useRecoilState(LoadingAtom);
const search = useRecoilValue(SearchAtom);
const settings = useRecoilValue(SettingsAtom);
@@ -44,6 +46,8 @@ export default function useMedia() {
setFolders(data.folders);
setSelectedFolder(data.selectedFolder);
setSearchedMedia(data.media);
setAllContentFolders(data.allContentFolders);
setAllStaticFolders(data.allStaticfolders);
}
};
@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const AllContentFoldersAtom = atom<string[] | undefined>({
key: 'AllContentFoldersAtom',
default: undefined
});
@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const AllStaticFoldersAtom = atom<string[] | undefined>({
key: 'AllStaticFoldersAtom',
default: undefined
});
+2
View File
@@ -1,3 +1,5 @@
export * from './AllContentFoldersAtom';
export * from './AllStaticFoldersAtom';
export * from './CategoryAtom';
export * from './DashboardViewAtom';
export * from './FolderAtom';
+70 -1
View File
@@ -1,13 +1,16 @@
import { parseWinPath } from './parseWinPath';
import * as jsoncParser from 'jsonc-parser';
import jsyaml = require("js-yaml");
import { join, resolve } from "path";
import { commands, Uri } from "vscode";
import { Folders } from "../commands/Folders";
import { COMMAND_NAME } from "../constants";
import { COMMAND_NAME, SETTING_CONTENT_STATIC_FOLDER, SETTING_FRAMEWORK_ID, STATIC_FOLDER_PLACEHOLDER } from "../constants";
import { FrameworkDetectors } from "../constants/FrameworkDetectors";
import { Framework } from "../models";
import { Logger } from "./Logger";
import { existsAsync, readFileAsync } from '../utils';
import { Settings } from '.';
import { parse } from 'path';
export class FrameworkDetector {
@@ -84,10 +87,76 @@ export class FrameworkDetector {
public static async checkDefaultSettings(framework: Framework) {
if (framework.name.toLowerCase() === "jekyll") {
await FrameworkDetector.jekyll();
} else if (framework.name.toLowerCase() === "hexo") {
await FrameworkDetector.hexo();
}
}
/**
* Check if there are any changes for the current framework that need to be applied
* @param relAssetPath
* @param filePath
*/
public static relAssetPathUpdate(relAssetPath: string, filePath: string): string {
const staticFolder = Folders.getStaticFolderRelativePath();
const frameworkId = Settings.get(SETTING_FRAMEWORK_ID);
// Support for HEXO post asset folders
if (staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
relAssetPath = relAssetPath.replace(STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder, "");
// Filename without the extension
const fileParsing = parse(filePath);
const name = fileParsing.name;
relAssetPath = relAssetPath.replace(name, "");
relAssetPath = join(relAssetPath);
// Remove remove the slash at the beginning
relAssetPath = parseWinPath(relAssetPath);
if (relAssetPath.startsWith("/")) {
relAssetPath = relAssetPath.substring(1);
}
}
// Support for HEXO image folder
else if (frameworkId === "hexo") {
relAssetPath = parseWinPath(relAssetPath);
if (relAssetPath.startsWith("/")) {
relAssetPath = relAssetPath.substring(1);
}
}
return parseWinPath(relAssetPath);
}
/**
* Define the default settings for Hexo
*/
private static async hexo() {
try {
const wsFolder = Folders.getWorkspaceFolder();
const hexoConfig = join(wsFolder?.fsPath || "", '_config.yml');
let assetFoler = "source/images";
if (await existsAsync(hexoConfig)) {
const content = await readFileAsync(hexoConfig, "utf8");
// Convert YAML to JSON
const config = jsyaml.safeLoad(content);
// Check if post assets are used: https://hexo.io/docs/asset-folders.html#Post-Asset-Folder
if (config.post_asset_folder) {
assetFoler = STATIC_FOLDER_PLACEHOLDER.hexo.placeholder;
}
}
await Settings.update(SETTING_CONTENT_STATIC_FOLDER, assetFoler, true);
} catch (e) {
Logger.error(`Something failed while processing your Hexo configuration. ${(e as Error).message}`);
}
}
/**
* Define the default settings for Jekyll
*/
private static async jekyll() {
try {
const wsFolder = Folders.getWorkspaceFolder();
+17 -2
View File
@@ -1,6 +1,7 @@
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
import { ExplorerView } from './../explorerView/ExplorerView';
import { Uri, window } from 'vscode';
import { dirname, join } from "path";
import { dirname, extname, join } from "path";
import { Field } from '../models';
import { existsSync } from 'fs';
import { Folders } from '../commands/Folders';
@@ -49,7 +50,21 @@ export class ImageHelper {
*/
public static relToAbs(filePath: string, value: string) {
const wsFolder = Folders.getWorkspaceFolder();
const staticFolder = Folders.getStaticFolderRelativePath();
let staticFolder = Folders.getStaticFolderRelativePath();
if (staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
const editor = window.activeTextEditor;
if (editor) {
const document = editor.document;
const filePath = parseWinPath(document.fileName);
const pathWithoutExtension = filePath.replace(extname(filePath), '');
const assetFilePath = join(pathWithoutExtension, value);
if (existsSync(assetFilePath)) {
return Uri.file(assetFilePath);
}
}
}
const staticPath = join(parseWinPath(wsFolder?.fsPath || ""), staticFolder || "", value);
const contentFolderPath = filePath ? join(dirname(filePath), value) : null;
+43 -21
View File
@@ -1,4 +1,5 @@
import { decodeBase64, Extension, MediaLibrary, Notifications, parseWinPath, Settings, Sorting } from ".";
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
import { decodeBase64, Extension, FrameworkDetector, MediaLibrary, Notifications, parseWinPath, Settings, Sorting } from ".";
import { Dashboard } from "../commands/Dashboard";
import { Folders } from "../commands/Folders";
import { DEFAULT_CONTENT_TYPE, ExtensionState, HOME_PAGE_NAVIGATION_ID, SETTING_MEDIA_SUPPORTED_MIMETYPES } from "../constants";
@@ -78,11 +79,17 @@ export class MediaHelpers {
allMedia = [...media];
} else {
if (staticFolder) {
if (staticFolder && staticFolder !== STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
const folderSearch = join(staticFolder || "", '/*');
const files = await workspace.findFiles(folderSearch);
const media = await MediaHelpers.updateMediaData(MediaHelpers.filterMedia(files));
allMedia = [...media];
} else if (staticFolder && staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
const folderSearch = join(STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder, '/*');
const files = await workspace.findFiles(folderSearch);
const media = await MediaHelpers.updateMediaData(MediaHelpers.filterMedia(files));
allMedia = [...media];
}
@@ -150,31 +157,40 @@ export class MediaHelpers {
let allContentFolders: string[] = [];
let allFolders: string[] = [];
let foldersFromSelection: string[] = [];
if (selectedFolder) {
if (await existsAsync(selectedFolder)) {
allFolders = (await readdirAsync(selectedFolder, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(selectedFolder, dir.name)));
foldersFromSelection = (await readdirAsync(selectedFolder, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(selectedFolder, dir.name)));
}
} else {
if (pageBundleContentTypes.length > 0) {
for (const contentFolder of contentFolders) {
const contentPath = contentFolder.path;
if (contentPath && await existsAsync(contentPath)) {
const subFolders = (await readdirAsync(contentPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(contentPath, dir.name)));
allContentFolders = [...allContentFolders, ...subFolders];
}
}
// Retrieve all the content folders
if (pageBundleContentTypes.length > 0) {
for (const contentFolder of contentFolders) {
const contentPath = contentFolder.path;
if (contentPath && await existsAsync(contentPath)) {
const subFolders = (await readdirAsync(contentPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(contentPath, dir.name)));
allContentFolders = [...allContentFolders, ...subFolders];
}
}
const staticPath = join(parseWinPath(wsFolder?.fsPath || ""), staticFolder || "");
if (staticPath && await existsAsync(staticPath)) {
allFolders = (await readdirAsync(staticPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(staticPath, dir.name)));
}
}
// Retrieve all the static folders
let staticPath = join(parseWinPath(wsFolder?.fsPath || ""), staticFolder || "");
if (staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
staticPath = join(parseWinPath(wsFolder?.fsPath || ""), STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder);
}
if (staticPath && await existsAsync(staticPath)) {
allFolders = (await readdirAsync(staticPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(staticPath, dir.name)));
}
// 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];
let sortedFolders = selectedFolder ? foldersFromSelection : [...allContentFolders, ...allFolders];
sortedFolders = sortedFolders.sort((a, b) => {
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
@@ -193,7 +209,9 @@ export class MediaHelpers {
media: files,
total: total,
folders: sortedFolders,
selectedFolder
selectedFolder,
allContentFolders,
allStaticfolders: allFolders,
} as MediaPaths
}
@@ -276,6 +294,10 @@ export class MediaHelpers {
Dashboard.resetViewData();
const editor = window.activeTextEditor;
if (!editor) {
return;
}
const wsFolder = Folders.getWorkspaceFolder();
const filePath = data.file;
let relPath = data.relPath;
@@ -304,7 +326,7 @@ export class MediaHelpers {
// Snippets are already parsed, so update the URL of the image
if (data.snippet) {
data.snippet = data.snippet.replace(data.relPath, relPath);
data.snippet = data.snippet.replace(data.relPath, FrameworkDetector.relAssetPathUpdate(relPath, editor.document.fileName));
}
}
}
@@ -325,7 +347,7 @@ export class MediaHelpers {
const caption = isFile ? `${data.title || ""}` : `${data.alt || data.caption || ""}`;
const snippet = data.snippet || `${isFile ? "" : "!"}[${caption}](${relPath.replace(/ /g, "%20")})`;
const snippet = data.snippet || `${isFile ? "" : "!"}[${caption}](${FrameworkDetector.relAssetPathUpdate(relPath, editor.document.fileName).replace(/ /g, "%20")})`;
if (selection !== undefined) {
builder.replace(selection, snippet);
} else {
@@ -339,7 +361,7 @@ export class MediaHelpers {
DataListener.updateMetadata({
field: data.fieldName,
value: relPath,
value: FrameworkDetector.relAssetPathUpdate(relPath, editor.document.fileName),
parents: data.parents,
blockData: data.blockData
});
+6
View File
@@ -7,6 +7,7 @@ import { SortingOption } from '../../dashboardWebView/models';
import { commands, env, Uri } from 'vscode';
import { COMMAND_NAME, TelemetryEvent } from '../../constants';
import * as os from 'os';
import { Folders } from '../../commands';
export class MediaListener extends BaseListener {
@@ -51,6 +52,11 @@ export class MediaListener extends BaseListener {
case DashboardMessage.createMediaFolder:
await commands.executeCommand(COMMAND_NAME.createFolder, msg?.data);
break;
case DashboardMessage.createHexoAssetFolder:
if (msg?.data.hexoAssetFolderPath) {
Folders.createFolder(msg?.data.hexoAssetFolderPath);
}
break;
}
}
+3 -1
View File
@@ -66,7 +66,9 @@ export class SettingsListener extends BaseListener {
const allFrameworks = FrameworkDetector.getAll();
const framework = allFrameworks.find((f: Framework) => f.name === frameworkId);
if (framework) {
await Settings.update(SETTING_CONTENT_STATIC_FOLDER, framework.static, true);
if (framework.static) {
await Settings.update(SETTING_CONTENT_STATIC_FOLDER, framework.static, true);
}
await FrameworkDetector.checkDefaultSettings(framework);
} else {
+2
View File
@@ -4,6 +4,8 @@ export interface MediaPaths {
media: MediaInfo[];
total: number;
folders: string[];
allContentFolders: string[];
allStaticfolders: string[];
selectedFolder: string;
}
+10 -2
View File
@@ -1,5 +1,6 @@
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
import { parseWinPath } from './../helpers/parseWinPath';
import { dirname, join } from "path";
import { dirname, extname, join } from "path";
import { StatusBarAlignment, Uri, window } from "vscode";
import { Dashboard } from "../commands/Dashboard";
import { Folders } from "../commands/Folders";
@@ -236,7 +237,14 @@ export class PagesParser {
// Revalidate as the array could have been empty
if (fieldValue) {
const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
let staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
if (staticFolder === STATIC_FOLDER_PLACEHOLDER.hexo.placeholder) {
const crntFilePath = parseWinPath(filePath)
const pathWithoutExtension = crntFilePath.replace(extname(crntFilePath), '');
staticPath = join(pathWithoutExtension, fieldValue);
}
const contentFolderPath = join(dirname(filePath), fieldValue);
let previewUri = null;