Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions app/containers/HomePage/components/FileExplorer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ import {
redditShareUrl,
twitterShareUrl,
} from '../../../templates/socialMediaShareBtns';
import { baseName, pathInfo, pathUp, sanitizePath } from '../../../utils/files';
import { baseName, pathInfo, pathUp, sanitizePath, calculateFolderSize } from '../../../utils/files';
import {
DEVICE_TYPE,
FILE_EXPLORER_VIEW_TYPE,
Expand Down Expand Up @@ -202,6 +202,7 @@ class FileExplorer extends Component {
},
},
directoryGeneratedTime: Date.now(),
folderSizes: {}, // Add state for folder sizes
};

this.state = {
Expand Down Expand Up @@ -258,6 +259,7 @@ class FileExplorer extends Component {

if (nextDirectoryNodes !== prevDirectoryNodes) {
this._handleDirectoryGeneratedTime();
this.calculateFolderSizes(nextDirectoryNodes); // Calculate folder sizes when directory changes
}

if (nextShowDirectoriesFirst !== showDirectoriesFirst) {
Expand Down Expand Up @@ -1985,6 +1987,19 @@ class FileExplorer extends Component {
});
};

calculateFolderSizes = async (nodes) => {
const folderSizes = {};

for (const node of nodes) {
if (node.isFolder) {
const size = await calculateFolderSize(node.path);
folderSizes[node.path] = size;
}
}

this.setState({ folderSizes });
};

render() {
const {
classes: styles,
Expand All @@ -1999,7 +2014,7 @@ class FileExplorer extends Component {
isStatusBarEnabled,
fileTransferClipboard,
} = this.props;
const { toggleDialog, togglePasteConfirmDialog, directoryGeneratedTime } =
const { toggleDialog, togglePasteConfirmDialog, directoryGeneratedTime, folderSizes } =
this.state;
const { rename, newFolder } = toggleDialog;
const togglePasteDialog =
Expand Down Expand Up @@ -2181,6 +2196,7 @@ class FileExplorer extends Component {
this._handleFocussedFileExplorerDeviceType
}
onAcceleratorActivation={this._handleAcceleratorActivation}
folderSizes={folderSizes} // Pass folder sizes to FileExplorerBodyRender
/>
;
</Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import classNames from 'classnames';
import { niceBytes, springTruncate } from '../../../utils/funcs';
import { FILE_EXPLORER_TABLE_TRUNCATE_MAX_CHARS } from '../../../constants';
import { styles } from '../styles/FileExplorerTableBodyListRender';
// eslint-disable-next-line import/no-relative-packages
import prettyFileIcons from '../../../vendors/pretty-file-icons';
import { imgsrc } from '../../../utils/imgsrc';
import { appDateFormat } from '../../../utils/date';
import { calculateFolderSize } from '../../../utils/files';

class FileExplorerTableBodyListRender extends PureComponent {
RenderFileIcon = () => {
Expand Down Expand Up @@ -56,6 +56,7 @@ class FileExplorerTableBodyListRender extends PureComponent {
onContextMenuClick,
onTableClick,
onTableDoubleClick,
folderSizes,
} = this.props;

const { RenderFileIcon, RenderFolderIcon } = this;
Expand All @@ -65,6 +66,8 @@ class FileExplorerTableBodyListRender extends PureComponent {
FILE_EXPLORER_TABLE_TRUNCATE_MAX_CHARS
);

const folderSize = item.isFolder ? folderSizes[item.path] : null;

return (
<TableRow
draggable
Expand Down Expand Up @@ -144,7 +147,7 @@ class FileExplorerTableBodyListRender extends PureComponent {
onTableDoubleClick(item, deviceType, event)
}
>
{item.isFolder ? `--` : `${niceBytes(item.size)}`}
{item.isFolder ? (folderSize ? niceBytes(folderSize) : '--') : `${niceBytes(item.size)}`}
</TableCell>
)}
{hideColList.indexOf('dateAdded') < 0 && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,54 @@ import { faMobile, faLaptop } from '@fortawesome/free-solid-svg-icons';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import { styles } from '../styles/FileExplorerTableFooterStatusBarRender';
import { getPluralText } from '../../../utils/funcs';
import { getPluralText, niceBytes } from '../../../utils/funcs';
import { DEVICE_TYPE } from '../../../enums';
import { DEVICES_LABEL } from '../../../constants';
import { calculateFolderSize } from '../../../utils/files';

class FileExplorerTableFooterStatusBarRender extends PureComponent {
getDirectoryListStats = () => {
const { directoryLists } = this.props;

let directories = 0;
let files = 0;
let totalSize = 0;

(directoryLists.nodes || []).map((a) => {
if (a.isFolder) {
directories += 1;
} else {
files += 1;
totalSize += a.size;
}

return a;
});

const total = directories + files;

return { total, directories, files };
return { total, directories, files, totalSize };
};

getSelectedDirectoryStats = () => {
getSelectedDirectoryStats = async () => {
const { directoryLists } = this.props;

const total = directoryLists.queue.selected.length;
const selected = directoryLists.queue.selected;
const total = selected.length;
let totalSize = 0;

for (const path of selected) {
const node = directoryLists.nodes.find((n) => n.path === path);
if (node) {
if (node.isFolder) {
totalSize += await calculateFolderSize(node.path);
} else {
totalSize += node.size;
}
}
}

return { total };
return { total, totalSize };
};

RenderDeviceName = () => {
Expand Down Expand Up @@ -69,8 +85,8 @@ class FileExplorerTableFooterStatusBarRender extends PureComponent {
render() {
const { classes: styles, fileTransferClipboard } = this.props;

const { directories, files, total } = this.getDirectoryListStats();
const { total: selectedTotal } = this.getSelectedDirectoryStats();
const { directories, files, total, totalSize } = this.getDirectoryListStats();
const { total: selectedTotal, totalSize: selectedTotalSize } = this.getSelectedDirectoryStats();
const fileTransferClipboardLength = fileTransferClipboard.queue.length;
const { RenderDeviceName } = this;

Expand All @@ -80,7 +96,7 @@ class FileExplorerTableFooterStatusBarRender extends PureComponent {
<RenderDeviceName />

{selectedTotal > 0 ? (
<Fragment>{`${selectedTotal} of ${total} selected`}</Fragment>
<Fragment>{`${selectedTotal} of ${total} selected, ${niceBytes(selectedTotalSize)}`}</Fragment>
) : (
<Fragment>{`${total} ${getPluralText(
'item',
Expand All @@ -89,7 +105,7 @@ class FileExplorerTableFooterStatusBarRender extends PureComponent {
'directory',
directories,
'directories'
)}, ${files} ${getPluralText('file', files)})`}</Fragment>
)}, ${files} ${getPluralText('file', files)}, ${niceBytes(totalSize)})`}</Fragment>
)}
{`, ${fileTransferClipboardLength} ${getPluralText(
'item',
Expand Down
42 changes: 42 additions & 0 deletions app/utils/files.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { join, parse } from 'path';
import { homedir as homedirOs } from 'os';
import { APP_BUNDLE_ID } from '../constants/meta';
import fs from 'fs';

const homeDir = homedirOs();

Expand Down Expand Up @@ -52,3 +53,44 @@ export const getExtension = (fileName, isFolder) => {
export const pathInfo = (filePath) => {
return parse(filePath);
};

export const calculateFolderSize = (folderPath) => {
return new Promise((resolve, reject) => {
let totalSize = 0;

fs.readdir(folderPath, (err, files) => {
if (err) {
return reject(err);
}

let pending = files.length;
if (!pending) {
return resolve(totalSize);
}

files.forEach((file) => {
const filePath = join(folderPath, file);

fs.stat(filePath, (err, stats) => {
if (err) {
return reject(err);
}

if (stats.isDirectory()) {
calculateFolderSize(filePath).then((size) => {
totalSize += size;
if (!--pending) {
resolve(totalSize);
}
}).catch(reject);
} else {
totalSize += stats.size;
if (!--pending) {
resolve(totalSize);
}
}
});
});
});
});
};