-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow user to view attachments and clear unused attachments #1
Changes from 2 commits
69faf5d
9e2de65
5998d98
37f0add
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,10 @@ 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 fs from 'fs' | ||
|
||
const electron = require('electron') | ||
const { shell, remote } = electron | ||
|
@@ -25,6 +27,20 @@ function browseFolder () { | |
}) | ||
} | ||
|
||
function humanFileSize (bytes) { | ||
const threshold = 1000 | ||
if (Math.abs(bytes) < threshold) { | ||
return bytes + ' B' | ||
} | ||
var units = ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] | ||
var u = -1 | ||
do { | ||
bytes /= threshold | ||
++u | ||
} while (Math.abs(bytes) >= threshold && u < units.length - 1) | ||
return bytes.toFixed(1) + ' ' + units[u] | ||
} | ||
|
||
class StoragesTab extends React.Component { | ||
constructor (props) { | ||
super(props) | ||
|
@@ -35,8 +51,29 @@ class StoragesTab extends React.Component { | |
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) { | ||
|
@@ -57,8 +94,53 @@ class StoragesTab extends React.Component { | |
e.preventDefault() | ||
} | ||
|
||
removeAllAttachments (attachments) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this method should also be in the attachmentManagement-file..? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And a test for it is required There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm gonna put it in attachmentManagement, maybe I should change the |
||
const promises = [] | ||
for (const attachment of attachments) { | ||
for (const file of attachment) { | ||
const promise = new Promise((resolve, reject) => { | ||
fs.unlink(file, (err) => { | ||
if (err) { | ||
console.error('Could not delete "%s"', file) | ||
console.error(err) | ||
reject(err) | ||
return | ||
} | ||
resolve() | ||
}) | ||
}) | ||
promises.push(promise) | ||
} | ||
} | ||
Promise.all(promises) | ||
.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 | ||
|
||
if (!boundingBox) { return null } | ||
const storageList = data.storageMap.map((storage) => { | ||
|
@@ -82,6 +164,19 @@ class StoragesTab extends React.Component { | |
<i className='fa fa-plus' /> {i18n.__('Add Storage Location')} | ||
</button> | ||
</div> | ||
<div styleName='header'>{i18n.__('Attachment storage')}</div> | ||
<p styleName='list-attachment-label'> | ||
Unused attachments size: {humanFileSize(totalUnusedAttachmentsSize)} ({totalUnusedAttachments} items) | ||
</p> | ||
<p styleName='list-attachment-label'> | ||
In use attachments size: {humanFileSize(totalInuseAttachmentsSize)} ({totalInuseAttachments} items) | ||
</p> | ||
<p styleName='list-attachment-label'> | ||
Total attachments size: {humanFileSize(totalAttachmentsSize)} ({totalAttachments} items) | ||
</p> | ||
<button styleName='list-attachement-clear-button' onClick={() => this.removeAllAttachments(unusedAttachments)}> | ||
{i18n.__('Clear unused attachments')} | ||
</button> | ||
</div> | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: Move this into util file