import PropTypes from 'prop-types' import React from 'react' import CSSModules from 'browser/lib/CSSModules' import styles from './StoragesTab.styl' import dataApi from 'browser/main/lib/dataApi' import attachmentManagement from 'browser/main/lib/dataApi/attachmentManagement' import StorageItem from './StorageItem' import i18n from 'browser/lib/i18n' import { humanFileSize } from 'browser/lib/utils' import fs from 'fs' const electron = require('electron') const { shell, remote } = electron function browseFolder () { const dialog = remote.dialog const defaultPath = remote.app.getPath('home') return new Promise((resolve, reject) => { dialog.showOpenDialog({ title: i18n.__('Select Directory'), defaultPath, properties: ['openDirectory', 'createDirectory'] }, function (targetPaths) { if (targetPaths == null) return resolve('') resolve(targetPaths[0]) }) }) } class StoragesTab extends React.Component { constructor (props) { super(props) this.state = { page: 'LIST', newStorage: { name: 'Unnamed', type: 'FILESYSTEM', path: '' }, attachments: [] } this.loadAttachmentStorage() } loadAttachmentStorage () { const promises = [] this.props.data.noteMap.map(note => { const promise = attachmentManagement.getAttachmentsPathAndStatus( note.content, note.storage, note.key ) if (promise) promises.push(promise) }) Promise.all(promises) .then(data => { const result = data.reduce((acc, curr) => acc.concat(curr), []) this.setState({attachments: result}) }) .catch(console.error) } handleAddStorageButton (e) { this.setState({ page: 'ADD_STORAGE', newStorage: { name: 'Unnamed', type: 'FILESYSTEM', path: '' } }, () => { this.refs.addStorageName.select() }) } handleLinkClick (e) { shell.openExternal(e.currentTarget.href) e.preventDefault() } handleRemoveUnusedAttachments (attachments) { attachmentManagement.removeAttachmentsByPaths(attachments) .then(() => this.loadAttachmentStorage()) .catch(console.error) } renderList () { const { data, boundingBox } = this.props const { attachments } = this.state const unusedAttachments = attachments.filter(attachment => !attachment.isInUse) const inUseAttachments = attachments.filter(attachment => attachment.isInUse) const totalUnusedAttachments = unusedAttachments.length const totalInuseAttachments = inUseAttachments.length const totalAttachments = totalUnusedAttachments + totalInuseAttachments const totalUnusedAttachmentsSize = unusedAttachments .reduce((acc, curr) => { const stats = fs.statSync(curr.path) const fileSizeInBytes = stats.size return acc + fileSizeInBytes }, 0) const totalInuseAttachmentsSize = inUseAttachments .reduce((acc, curr) => { const stats = fs.statSync(curr.path) const fileSizeInBytes = stats.size return acc + fileSizeInBytes }, 0) const totalAttachmentsSize = totalUnusedAttachmentsSize + totalInuseAttachmentsSize const unusedAttachmentPaths = unusedAttachments .reduce((acc, curr) => acc.concat(curr.path), []) if (!boundingBox) { return null } const storageList = data.storageMap.map((storage) => { return }) return (
{i18n.__('Storage Locations')}
{storageList.length > 0 ? storageList :
{i18n.__('No storage found.')}
}
{i18n.__('Attachment storage')}

Unused attachments size: {humanFileSize(totalUnusedAttachmentsSize)} ({totalUnusedAttachments} items)

In use attachments size: {humanFileSize(totalInuseAttachmentsSize)} ({totalInuseAttachments} items)

Total attachments size: {humanFileSize(totalAttachmentsSize)} ({totalAttachments} items)

) } handleAddStorageBrowseButtonClick (e) { browseFolder() .then((targetPath) => { if (targetPath.length > 0) { const { newStorage } = this.state newStorage.path = targetPath this.setState({ newStorage }) } }) .catch((err) => { console.error('BrowseFAILED') console.error(err) }) } handleAddStorageChange (e) { const { newStorage } = this.state newStorage.name = this.refs.addStorageName.value newStorage.path = this.refs.addStoragePath.value this.setState({ newStorage }) } handleAddStorageCreateButton (e) { dataApi .addStorage({ name: this.state.newStorage.name, path: this.state.newStorage.path }) .then((data) => { const { dispatch } = this.props dispatch({ type: 'ADD_STORAGE', storage: data.storage, notes: data.notes }) this.setState({ page: 'LIST' }) }) } handleAddStorageCancelButton (e) { this.setState({ page: 'LIST' }) } renderAddStorage () { return (
{i18n.__('Add Storage')}
{i18n.__('Name')}
this.handleAddStorageChange(e)} />
{i18n.__('Type')}
{i18n.__('Setting up 3rd-party cloud storage integration:')}{' '} this.handleLinkClick(e)} >{i18n.__('Cloud-Syncing-and-Backup')}
{i18n.__('Location')}
this.handleAddStorageChange(e)} />
) } renderContent () { switch (this.state.page) { case 'ADD_STORAGE': case 'ADD_FOLDER': return this.renderAddStorage() case 'LIST': default: return this.renderList() } } render () { return (
{this.renderContent()}
) } } StoragesTab.propTypes = { boundingBox: PropTypes.shape({ bottom: PropTypes.number, height: PropTypes.number, left: PropTypes.number, right: PropTypes.number, top: PropTypes.number, width: PropTypes.number }), dispatch: PropTypes.func } export default CSSModules(StoragesTab, styles)