Skip to content
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

feat: add file operations in preview #936

Merged
merged 11 commits into from
Jan 24, 2019
32 changes: 31 additions & 1 deletion src/bundles/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ const make = (basename, action) => (...args) => async (args2) => {
try {
data = await action(getIpfs(), ...args, id, args2)
dispatch({ type: `FILES_${basename}_FINISHED`, payload: { id, ...data } })

// Rename specific logic
if (basename === actions.MOVE) {
const src = args[0][0]
const dst = args[0][1]

if (src === store.selectFiles().path) {
await store.doUpdateHash(`/files${dst}`)
}
}

// Delete specific logic
if (basename === actions.DELETE) {
const src = args[0][0]

let path = src.split('/')
path.pop()
path = path.join('/')

await store.doUpdateHash(`/files${path}`)
}
} catch (error) {
dispatch({ type: `FILES_${basename}_FAILED`, payload: { id, error } })
} finally {
Expand All @@ -67,7 +88,16 @@ const fetchFiles = make(actions.FETCH, async (ipfs, id, { store }) => {
fetched: Date.now(),
type: 'file',
stats: stats,
read: () => ipfs.files.read(path)
read: () => ipfs.files.read(path),
// TODO - This will be refactored in the future
// I'm adding this here to make the file actions work in preview mode
extra: [{
name: path.split('/').pop(),
path: path,
type: 'file',
size: stats.size,
hash: stats.hash
}]
}
}

Expand Down
62 changes: 35 additions & 27 deletions src/files/FilesPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Breadcrumbs from './breadcrumbs/Breadcrumbs'
import FilesList from './files-list/FilesList'
import FilePreview from './file-preview/FilePreview'
import FileInput from './file-input/FileInput'
import ContextMenu from './context-menu/ContextMenu'
import Overlay from '../components/overlay/Overlay'
import ShareModal from './share-modal/ShareModal'
import RenameModal from './rename-modal/RenameModal'
Expand All @@ -35,7 +36,8 @@ const defaultState = {
paths: [],
files: 0,
folders: 0
}
},
isContextMenuOpen: false
}

class FilesPage extends React.Component {
Expand Down Expand Up @@ -178,23 +180,23 @@ class FilesPage extends React.Component {
this.props.doFilesDelete(paths)
}

handleContextMenuClick = (ev) => {
// This is needed to disable the native OS right-click menu
// and deal with the clicking on the ContextMenu options
if (ev !== undefined && typeof ev !== 'string') {
ev.preventDefault()
}

this.setState(state => ({ isContextMenuOpen: !state.isContextMenuOpen }))
}

render () {
const {
ipfsProvider,
files,
writeFilesProgress,
doFilesMove,
doFilesNavigateTo,
doFilesUpdateSorting,
filesSorting: sort,
t
ipfsProvider, files, writeFilesProgress, filesSorting: sort, t,
doFilesMove, doFilesNavigateTo, doFilesUpdateSorting
} = this.props

const {
share,
rename,
delete: deleteModal
} = this.state
const { share, rename, delete: deleteModal } = this.state

const isCompanion = ipfsProvider === 'window.ipfs'
const filesExist = files && files.content && files.content.length
Expand All @@ -208,17 +210,26 @@ class FilesPage extends React.Component {

{ files &&
<div>
<div className='flex flex-wrap'>
<Breadcrumbs className='mb3' path={files.path} onClick={doFilesNavigateTo} />
<div className='flex flex-wrap items-center mb3'>
<Breadcrumbs path={files.path} onClick={doFilesNavigateTo} />

{ files.type === 'directory' &&
<FileInput
className='mb3 ml-auto'
{ files.type === 'directory'
? <FileInput
className='ml-auto'
onMakeDir={this.makeDir}
onAddFiles={this.add}
onAddByPath={this.addByPath}
addProgress={writeFilesProgress} />
}
: <ContextMenu
className='ml-auto'
handleClick={this.handleContextMenuClick}
isOpen={this.state.isContextMenuOpen}
onShare={() => this.showShareModal(files.extra)}
onDelete={() => this.showDeleteModal(files.extra)}
onRename={() => this.showRenameModal(files.extra)}
onInspect={() => this.inspect(files.extra)}
onDownload={() => this.download(files.extra)}
hash={files.stats.hash} /> }
</div>

{ isRoot && isCompanion && <CompanionInfo /> }
Expand All @@ -227,8 +238,8 @@ class FilesPage extends React.Component {

{ isRoot && !filesExist && <WelcomeInfo t={t} /> }

{ files.type === 'directory' ? (
<FilesList
{ files.type === 'directory'
? <FilesList
key={window.encodeURIComponent(files.path)}
root={files.path}
sort={sort}
Expand All @@ -243,11 +254,8 @@ class FilesPage extends React.Component {
onRename={this.showRenameModal}
onDelete={this.showDeleteModal}
onNavigate={doFilesNavigateTo}
onMove={doFilesMove}
/>
) : (
<FilePreview {...files} gatewayUrl={this.props.gatewayUrl} />
)}
onMove={doFilesMove} />
: <FilePreview {...files} gatewayUrl={this.props.gatewayUrl} /> }
</div>
}

Expand Down
7 changes: 5 additions & 2 deletions src/files/context-menu/ContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ContextMenu extends React.Component {
onInspect: PropTypes.func,
onShare: PropTypes.func,
hash: PropTypes.string.isRequired,
className: PropTypes.string,
t: PropTypes.func.isRequired,
tReady: PropTypes.bool.isRequired
}
Expand All @@ -34,6 +35,8 @@ class ContextMenu extends React.Component {
top: 0,
left: 0,
right: 'auto',
translateX: 0,
translateY: 0,
className: ''
}

Expand All @@ -47,10 +50,10 @@ class ContextMenu extends React.Component {
}

render () {
const { t, onRename, onDelete, onDownload, onInspect, onShare, translateX, translateY } = this.props
const { t, onRename, onDelete, onDownload, onInspect, onShare, translateX, translateY, className } = this.props

return (
<Dropdown>
<Dropdown className={className}>
<GlyphDots width='1.5rem' className='fill-gray-muted pointer hover-fill-gray transition-all' onClick={this.props.handleClick} />
<DropdownMenu
top={-8}
Expand Down
5 changes: 3 additions & 2 deletions src/files/file-preview/FilePreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class FilesPreview extends React.Component {

const type = typeFromExt(stats.name)
const src = `${gatewayUrl}/ipfs/${stats.hash}`
const className = 'mw-100 bg-snow-muted pa2 br2'
const className = 'mw-100 mt3 bg-snow-muted pa2 br2'

switch (type) {
case 'audio':
return (
Expand All @@ -54,7 +55,7 @@ class FilesPreview extends React.Component {
return <img className={className} alt={stats.name} src={src} />
default:
const cantPreview = (
<div>
<div className='mt4'>
<p className='b'>{t('cantBePreviewed')} <span role='img' aria-label='sad'>😢</span></p>
<p>
<Trans i18nKey='downloadInstead'>
Expand Down
1 change: 0 additions & 1 deletion src/files/file/File.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ class File extends React.Component {
translateX={this.state.translateX}
translateY={this.state.translateY}
isOpen={this.state.isContextMenuOpen}
mousePosition={this.state.mousePosition}
onShare={onShare}
onDelete={onDelete}
onRename={onRename}
Expand Down
16 changes: 5 additions & 11 deletions src/files/files-list/FilesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,12 @@ export class FilesList extends React.Component {
unselect={unselectAll}
remove={() => this.props.onDelete(this.selectedFiles)}
rename={() => this.props.onRename(this.selectedFiles)}
share={this.wrapWithSelected('onShare')}
download={this.wrapWithSelected('onDownload')}
inspect={this.wrapWithSelected('onInspect')}
share={() => this.props.onShare(this.selectedFiles)}
download={() => this.props.onDownload(this.selectedFiles)}
inspect={() => this.props.onInspect(this.selectedFiles)}
count={this.state.selected.length}
downloadProgress={this.props.downloadProgress}
size={size}
/>
size={size} />
)
}

Expand Down Expand Up @@ -133,8 +132,7 @@ export class FilesList extends React.Component {
key={window.encodeURIComponent(file.name)}
setIsDragging={this.isDragging}
translucent={this.state.isDragging || (isOver && canDrop)}
{...file}
/>
{...file} />
))
}

Expand All @@ -156,10 +154,6 @@ export class FilesList extends React.Component {
}
}

wrapWithSelected = (fn) => async () => {
this.props[fn](this.selectedFiles)
}

keyHandler = (e) => {
const { selected, focused } = this.state

Expand Down