#178 - macOS and Linux support for date retrieval

This commit is contained in:
Elio Struyf
2021-11-18 12:56:23 +01:00
parent 8a0d308ceb
commit 8daaa23774
8 changed files with 153 additions and 49 deletions
+36 -13
View File
@@ -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, SortOrder, TaxonomyType } from '../models';
import { DraftField, Framework, SortingSetting, SortOrder, SortType, TaxonomyType } from '../models';
import { Folders } from './Folders';
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { DashboardMessage } from '../dashboardWebView/DashboardMessage';
@@ -27,6 +27,7 @@ import { DateHelper } from '../helpers/DateHelper';
import { FrameworkDetector } from '../helpers/FrameworkDetector';
import { ContentType } from '../helpers/ContentType';
import { SortingOption } from '../dashboardWebView/models';
import { Sorting } from '../helpers/Sorting';
export class Dashboard {
private static webview: WebviewPanel | null = null;
@@ -384,13 +385,16 @@ export class Dashboard {
if (relSelectedFolderPath) {
const files = await workspace.findFiles(join(relSelectedFolderPath, '/*'));
const media = Dashboard.filterMedia(files);
const media = await Dashboard.updateMediaData(selectedFolder, Dashboard.filterMedia(files));
allMedia = [...media];
} else {
if (staticFolder) {
const folderSearch = join(staticFolder || "", '/*');
const absFolderSearch = join(wsFolder?.fsPath || "", folderSearch);
const files = await workspace.findFiles(folderSearch);
const media = Dashboard.filterMedia(files);
const media = await Dashboard.updateMediaData(absFolderSearch, Dashboard.filterMedia(files));
allMedia = [...media];
}
@@ -401,22 +405,20 @@ export class Dashboard {
const relFolderPath = contentFolder.path.substring(wsFolder.fsPath.length + 1);
const folderSearch = relSelectedFolderPath ? join(relSelectedFolderPath, '/*') : join(relFolderPath, '/*');
const files = await workspace.findFiles(folderSearch);
const media = Dashboard.filterMedia(files);
const media = await Dashboard.updateMediaData(join(wsFolder.fsPath || "", folderSearch), Dashboard.filterMedia(files));
allMedia = [...allMedia, ...media];
}
}
}
allMedia = allMedia.sort((a, b) => {
if (a.fsPath.toLowerCase() < b.fsPath.toLowerCase()) {
return -1;
}
if (a.fsPath.toLowerCase() > b.fsPath.toLowerCase()) {
return 1;
}
return 0;
});
if (crntSort?.type === SortType.string) {
allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
} else if (crntSort?.type === SortType.date) {
allMedia = allMedia.sort(Sorting.date("modified"));
} else {
allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
}
if (crntSort?.order === SortOrder.desc) {
allMedia = allMedia.reverse();
@@ -499,6 +501,27 @@ export class Dashboard {
});
}
/**
* Update the metadata of the retrieved files
* @param folder
* @param files
*/
private static async updateMediaData(folder: string, files: MediaInfo[]) {
const fileMetadata = await MediaLibrary.getMetadata(folder);
if (fileMetadata && fileMetadata.length > 0) {
files = files.map((m: MediaInfo) => {
const metadata = fileMetadata.find((f) => m.fsPath.endsWith(f.fileName));
if (metadata) {
m.modified = metadata.date;
}
return m;
});
}
return Object.assign([], files);
}
/**
* Retrieve all the markdown pages
*/
@@ -17,7 +17,8 @@ export interface ISortingProps {
}
export const sortOptions: SortingOption[] = [
{ name: "Last modified", id: SortOption.LastModified, order: SortOrder.desc, type: SortType.string },
{ name: "Last modified (asc)", id: SortOption.LastModifiedAsc, order: SortOrder.asc, type: SortType.date },
{ name: "Last modified (desc)", id: SortOption.LastModifiedDesc, order: SortOrder.desc, type: SortType.date },
{ name: "By filename (asc)", id: SortOption.FileNameAsc, order: SortOrder.asc, type: SortType.string },
{ name: "By filename (desc)", id: SortOption.FileNameDesc, order: SortOrder.desc, type: SortType.string },
];
@@ -36,7 +37,7 @@ export const Sorting: React.FunctionComponent<ISortingProps> = ({disableCustomSo
setCrntSorting(value)
};
let allOptions = view === ViewType.Contents ? [...sortOptions] : [...sortOptions.slice(1)];
let allOptions = [...sortOptions];
if (settings?.customSorting && !disableCustomSorting) {
allOptions = [...allOptions, ...settings.customSorting.map((s) => ({
title: s.title || s.name,
+2 -1
View File
@@ -1,5 +1,6 @@
export enum SortOption {
LastModified = "LastModified",
LastModifiedAsc = "LastModifiedAsc",
LastModifiedDesc = "LastModifiedDesc",
FileNameAsc = "FileNameAsc",
FileNameDesc = "FileNameDesc"
}
+11 -31
View File
@@ -6,7 +6,7 @@ import Fuse from 'fuse.js';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CategorySelector, FolderSelector, SearchSelector, SettingsSelector, SortingAtom, TabSelector, TagSelector } from '../state';
import { SortOrder, SortType } from '../../models';
import { DateHelper } from '../../helpers/DateHelper';
import { Sorting } from '../../helpers/Sorting';
const fuseOptions: Fuse.IFuseOptions<Page> = {
keys: [
@@ -26,29 +26,6 @@ export default function usePages(pages: Page[]) {
const tag = useRecoilValue(TagSelector);
const category = useRecoilValue(CategorySelector);
// Sort field value alphabetically
const sortAlphabetically = (property: string) => {
return (a: Page, b: Page) => {
if (a[property] < b[property]) {
return -1;
}
if (a[property] > b[property]) {
return 1;
}
return 0;
};
};
// Sort by date
const sortByDate = (property: string) => {
return (a: Page, b: Page) => {
const dateA = DateHelper.tryParse(a[property]);
const dateB = DateHelper.tryParse(b[property]);
return (dateA || new Date(0)).getTime() - (dateB || new Date(0)).getTime();
};
};
useEffect(() => {
const draftField = settings?.draftField;
let usedSorting = sorting;
@@ -91,27 +68,30 @@ export default function usePages(pages: Page[]) {
// Sort the pages
let pagesSorted: Page[] = Object.assign([], pagesToShow);
debugger;
if (!search) {
if (sorting && sorting.id === SortOption.FileNameAsc) {
pagesSorted = pagesSorted.sort(sortAlphabetically("fmFileName"));
pagesSorted = pagesSorted.sort(Sorting.alphabetically("fmFileName"));
} else if (sorting && sorting.id === SortOption.FileNameDesc) {
pagesSorted = pagesSorted.sort(sortAlphabetically("fmFileName")).reverse();
} else if (sorting && sorting.id === SortOption.LastModified) {
pagesSorted = pagesSorted.sort((a, b) => b.fmModified - a.fmModified);
pagesSorted = pagesSorted.sort(Sorting.alphabetically("fmFileName")).reverse();
} else if (sorting && sorting.id === SortOption.LastModifiedAsc) {
pagesSorted = pagesSorted.sort(Sorting.number("fmModified"));
} else if (sorting && sorting.id === SortOption.LastModifiedDesc) {
pagesSorted = pagesSorted.sort(Sorting.number("fmModified")).reverse();
} else if (sorting && sorting.id && sorting.name) {
const { order, name, type } = sorting;
if (type === SortType.string) {
pagesSorted = pagesSorted.sort(sortAlphabetically(name));
pagesSorted = pagesSorted.sort(Sorting.alphabetically(name));
} else if (type === SortType.date) {
pagesSorted = pagesSorted.sort(sortByDate(name));
pagesSorted = pagesSorted.sort(Sorting.date(name));
}
if (order === SortOrder.desc) {
pagesSorted = pagesSorted.reverse();
}
} else {
pagesSorted = pagesSorted.sort((a, b) => b.fmModified - a.fmModified);
pagesSorted = pagesSorted.sort(Sorting.number("fmModified")).reverse();
}
}
@@ -2,7 +2,7 @@ import { atom } from 'recoil';
import { SortOption } from '../../constants/SortOption';
import { SortingOption } from '../../models/SortingOption';
export const DEFAULT_SORTING_OPTION = SortOption.LastModified;
export const DEFAULT_SORTING_OPTION = SortOption.LastModifiedDesc;
export const SortingAtom = atom<SortingOption | null>({
key: 'SortingAtom',
+52 -1
View File
@@ -1,5 +1,7 @@
import * as os from 'os';
import { DateHelper } from './DateHelper';
import { Dashboard } from '../commands/Dashboard';
import { workspace } from 'vscode';
import { workspace, env as vscodeEnv } from 'vscode';
import { JsonDB } from 'node-json-db/dist/JsonDB';
import { basename, dirname, join, parse } from 'path';
import { Folders, WORKSPACE_PLACEHOLDER } from '../commands/Folders';
@@ -7,6 +9,7 @@ import { existsSync, renameSync } from 'fs';
import { Notifications } from './Notifications';
import { parseWinPath } from './parseWinPath';
import { LocalStore } from '../constants';
import { exec } from 'child_process';
interface MediaRecord {
description: string;
@@ -47,6 +50,54 @@ export class MediaLibrary {
return MediaLibrary.instance;
}
public static async getMetadata(path: string): Promise<{ date: Date, fileName: string }[] | null> {
return new Promise((resolve) => {
let command: string = "";
// Run bash scripts to retrieve metadata faster
if (os.type() === "Darwin") {
command = `for file in *; do
fdate=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$file")
echo "$file,$fdate"
done`;
} else if (os.type() === "Windows_NT") {
resolve(null);
return;
} else if (os.type() === "Linux" && vscodeEnv.remoteName?.toLowerCase() === "wsl") {
command = `for file in *; do
fdate=$(stat -c "%y" "$file")
echo "$file,$fdate"
done`;
} else {
resolve(null);
return;
}
exec(`cd ${path} && ${command}`, (error, stdout, stderr) => {
if (error) {
resolve(null);
return;
}
const lines = stdout.split('\n');
const metadata: any[] = [];
let lineData: any = {};
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const parts = line.split(',');
metadata.push({
fileName: parts[0],
date: DateHelper.tryParse(parts[1])
});
}
resolve(metadata);
});
});
}
public get(id: string): MediaRecord | undefined {
try {
const fileId = this.parsePath(id);
+47
View File
@@ -0,0 +1,47 @@
import { DateHelper } from "./DateHelper";
export class Sorting {
/**
* Sort field value alphabetically
* @param property
* @returns
*/
public static alphabetically = (property: string) => {
return (a: any, b: any) => {
if (a[property] < b[property]) {
return -1;
}
if (a[property] > b[property]) {
return 1;
}
return 0;
};
};
/**
* Sort by date
* @param property
* @returns
*/
public static date = (property: string) => {
return (a: any, b: any) => {
const dateA = DateHelper.tryParse(a[property]);
const dateB = DateHelper.tryParse(b[property]);
return (dateA || new Date(0)).getTime() - (dateB || new Date(0)).getTime();
};
};
/**
* Sort by number
* @param property
* @returns
*/
public static number = (property: string) => {
return (a: any, b: any) => {
return a[property] - b[property];
};
};
}
+1
View File
@@ -15,4 +15,5 @@ export interface MediaInfo {
dimensions: ISizeCalculationResult | undefined;
caption?: string | undefined;
alt?: string | undefined;
modified?: Date | undefined;
}