farjs-app
Version:
FAR.js - Cross-platform File and Archive Manager app in your terminal
178 lines (156 loc) • 4.35 kB
JavaScript
/**
* @typedef {import("@farjs/filelist/api/FileListItem.mjs").FileListItem} FileListItem
* @typedef {import("@farjs/filelist/FileListState.mjs").FileListState} FileListState
* @import { Dispatch } from "@farjs/filelist/FileListData.mjs"
*/
import React, { useLayoutEffect, useRef, useState } from "react";
import Task from "@farjs/ui/task/Task.mjs";
import TextAlign from "@farjs/ui/TextAlign.mjs";
import TextLine from "@farjs/ui/TextLine.mjs";
import StatusPopup from "@farjs/ui/popup/StatusPopup.mjs";
import TaskAction from "@farjs/ui/task/TaskAction.mjs";
import FileListItem from "@farjs/filelist/api/FileListItem.mjs";
import PanelStack from "@farjs/filelist/stack/PanelStack.mjs";
import FileListTheme from "@farjs/filelist/theme/FileListTheme.mjs";
import FileListActions from "@farjs/filelist/FileListActions.mjs";
import FileListState from "@farjs/filelist/FileListState.mjs";
import { formatSize } from "@farjs/filelist/utils.mjs";
const h = React.createElement;
/**
* @typedef {{
* readonly name: string;
* readonly parent: string;
* readonly folders: number;
* readonly files: number;
* readonly filesSize: number;
* }} QuickViewParams
*/
/**
* @typedef {{
* readonly dispatch: Dispatch;
* readonly actions: FileListActions;
* readonly state: FileListState;
* readonly stack: PanelStack;
* readonly width: number;
* readonly currItem: FileListItem;
* }} QuickViewDirProps
*/
/**
* @param {QuickViewDirProps} props
*/
const QuickViewDir = (props) => {
const { statusPopupComp, textLineComp } = QuickViewDir;
const [showPopup, setShowPopup] = useState(false);
const inProgress = useRef(false);
const stack = props.stack;
/** @type {QuickViewParams} */
const params = stack.params();
const theme = FileListTheme.useTheme().fileList;
/**
* @returns {void}
*/
function scanDir() {
const parent = props.state.currDir.path;
let folders = 0;
let files = 0;
let filesSize = 0;
/** @type {QuickViewParams} */
const params = {
name: props.currItem.name,
parent,
folders,
files,
filesSize,
};
stack.update((_) => _.withState(params));
const resultP = props.actions.scanDirs(
parent,
[props.currItem],
(_, items) => {
items.forEach((i) => {
if (i.isDir) folders += 1;
else {
files += 1;
filesSize += i.size;
}
});
return inProgress.current;
}
);
resultP.then(
(res) => {
if (res) {
setShowPopup(false);
const newParams = { ...params, folders, files, filesSize };
stack.update((_) => _.withState(newParams));
}
},
() => {
setShowPopup(false);
props.dispatch(TaskAction(Task("Quick view dir scan", resultP)));
}
);
}
useLayoutEffect(() => {
if (!inProgress.current && showPopup) {
// start scan
inProgress.current = true;
scanDir();
} else if (inProgress.current && !showPopup) {
// stop scan
inProgress.current = false;
}
}, [showPopup]);
useLayoutEffect(() => {
if (
params.name !== props.currItem.name ||
params.parent !== props.state.currDir.path
) {
setShowPopup(true);
}
}, [props.currItem.name, props.state.currDir.path, params]);
return h(
React.Fragment,
null,
showPopup
? h(statusPopupComp, {
text: `Scanning the folder\n${props.currItem.name}`,
title: "View Dir",
onClose: () => {
setShowPopup(false);
},
})
: null,
h("text", {
left: 2,
top: 2,
style: theme.regularItem,
content: `Folder
Contains:
Folders
Files
Files size`,
}),
h(textLineComp, {
align: TextAlign.left,
left: 12,
top: 2,
width: props.width - 14,
text: `"${props.currItem.name}"`,
style: theme.regularItem,
padding: 0,
}),
h("text", {
left: 15,
top: 6,
style: theme.selectedItem,
content: `${formatSize(params.folders)}
${formatSize(params.files)}
${formatSize(params.filesSize)}`,
})
);
};
QuickViewDir.displayName = "QuickViewDir";
QuickViewDir.statusPopupComp = StatusPopup;
QuickViewDir.textLineComp = TextLine;
export default QuickViewDir;