Skip to content
This repository has been archived by the owner on Nov 12, 2019. It is now read-only.

Commit

Permalink
feat(archive): ability to archive / extract files in zip format
Browse files Browse the repository at this point in the history
fix(selectview): clear active files when user taps on select-view button in toolbar

resolve #10
resolve #12
  • Loading branch information
Mahdi Dibaiee committed Oct 24, 2015
1 parent 44340ab commit dfb7d8a
Show file tree
Hide file tree
Showing 10 changed files with 15,623 additions and 4,373 deletions.
19,833 changes: 15,478 additions & 4,355 deletions build/main.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"node": ">=0.12.0"
},
"homepage": "https://github.com/mdibaiee/",
"dependencies": {},
"dependencies": {
"jszip": "2.5.0"
},
"devDependencies": {
"babel": "^5.8.23",
"babelify": "^6.2.0",
Expand Down
15 changes: 15 additions & 0 deletions src/js/actions/compress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { COMPRESS, DECOMPRESS } from './types';

export function compress(file) {
return {
type: COMPRESS,
file
}
}

export function decompress(file) {
return {
type: DECOMPRESS,
file
}
}
3 changes: 3 additions & 0 deletions src/js/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const TYPES = {
REFRESH: Symbol('REFRESH'),
SORT: Symbol('SORT'),

COMPRESS: Symbol('COMPRESS'),
DECOMPRESS: Symbol('DECOMPRESS'),

NEW_FILE: Symbol('NEW_FILE'),
CREATE_FILE: Symbol('CREATE_FILE'),
SHARE_FILE: Symbol('SHARE_FILE'),
Expand Down
23 changes: 17 additions & 6 deletions src/js/api/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ export async function children(dir, gatherInfo) {
return childs;
}

export async function isDirectory(path) {
let file = await getFile(path);

return !(file instanceof Blob);
}

export async function readFile(path) {
let file = await getFile(path);

Expand All @@ -85,6 +91,16 @@ export async function readFile(path) {
});
}

export async function writeFile(path, content) {
let request = sdcard().addNamed(content, path);

return new Promise((resolve, reject) => {
request.onsuccess = resolve;
request.onerror = reject;
request.onabort = reject;
});
}

export async function createFile(...args) {
let parent = await root();

Expand Down Expand Up @@ -147,11 +163,6 @@ export async function copy(file, newPath) {

let blob = new Blob([content], {type: target.type});

return new Promise((resolve, reject) => {
let request = sdcard().addNamed(blob, newPath);
request.onsuccess = resolve;
request.onerror = reject;
request.onabort = reject;
});
return writeFile(newPath, blob);
}
}
1 change: 0 additions & 1 deletion src/js/components/breadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export default class Breadcrumb extends Component {
let path = current.join('/').replace(/^\//, ''); // remove starting slash
let key = directories.length + index;
let style = { zIndex: arr.length - index};
console.log('history', dir)

return (
<span key={key} className='history' onClick={bind(changedir(path))} style={style}>{dir}</span>
Expand Down
8 changes: 7 additions & 1 deletion src/js/components/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { refresh, selectView } from 'actions/files-view';
import { show as showDialog } from 'actions/dialog';
import { show as showMenu } from 'actions/menu';
import active from 'actions/active-file';
import settings from 'actions/settings';
import store, { bind } from 'store';
import { MENU_WIDTH } from './menu';
Expand All @@ -13,7 +14,7 @@ export default class Toolbar extends Component {
<button className='icon-back tour-item' onClick={this.goUp} />
<button className='icon-plus tour-item' onClick={this.newFile} />
<button className='icon-refresh tour-item' onClick={bind(refresh())} />
<button className='icon-select tour-item' onClick={bind(selectView('toggle'))} />
<button className='icon-select tour-item' onClick={this.selectView} />
<button className='icon-more tour-item' onClick={this.showMore.bind(this)} ref='more' />
</div>
);
Expand All @@ -39,6 +40,11 @@ export default class Toolbar extends Component {
store.dispatch(changedir(up));
}

selectView() {
store.dispatch(selectView('toggle'));
store.dispatch(active());
}

newFile() {
let cwd = store.getState().get('cwd');
let action = showDialog('createDialog', {
Expand Down
31 changes: 31 additions & 0 deletions src/js/menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { hideAll } from 'actions/menu';
import { show } from 'actions/dialog';
import { selectView } from 'actions/files-view';
import { copy, move } from 'actions/file';
import { compress, decompress } from 'actions/compress';
import store from 'store';

const entryMenu = {
Expand Down Expand Up @@ -64,6 +65,28 @@ const entryMenu = {
blob
});
}
},
{
name: 'Extract',
enabled() {
let active = store.getState().get('activeFile');

if (active) console.log(active[0].name);
return active && active[0].name.indexOf('.zip') > -1;
},
action() {
let active = store.getState().get('activeFile');

store.dispatch(decompress(active));
}
},
{
name: 'Archive',
action() {
let active = store.getState().get('activeFile');

store.dispatch(compress(active));
}
}
]
};
Expand Down Expand Up @@ -142,6 +165,14 @@ const moreMenu = {
})
}
},
{
name: 'Archive',
action() {
let active = store.getState().get('activeFile');

store.dispatch(compress(active));
}
}
]
}

Expand Down
6 changes: 1 addition & 5 deletions src/js/reducers/active-file.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { ACTIVE_FILE, CHANGE_DIRECTORY } from 'actions/types';
import { ACTIVE_FILE, SELECT_VIEW } from 'actions/types';

export default function(state = null, action) {
if (action.type === ACTIVE_FILE) {
return action.file;
}

if (action.type === CHANGE_DIRECTORY) {
return null;
}

return state;
}
72 changes: 68 additions & 4 deletions src/js/reducers/files.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE, MOVE_FILE, COPY_FILE, SEARCH } from 'actions/types';
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE, MOVE_FILE, COPY_FILE, SEARCH, COMPRESS, DECOMPRESS } from 'actions/types';
import zip from 'jszip';
import { refresh } from 'actions/files-view';
import { move, remove, sdcard, createFile, createDirectory, copy } from 'api/files';
import { move, remove, sdcard, createFile, readFile, writeFile, createDirectory, getFile, copy, children } from 'api/files';
import { show } from 'actions/dialog';
import store, { bind } from 'store';
import { reportError, type } from 'utils';
import { reportError, type, normalize } from 'utils';

let boundRefresh = bind(refresh());

Expand Down Expand Up @@ -74,14 +75,77 @@ export default function(state = [], action) {

if (action.type === DELETE_FILE) {
let all = Promise.all(action.file.map(file => {
let path = ((file.path || '') + file.name).replace(/^\//, '');
let path = normalize((file.path || '') + file.name);
return remove(path, true);
}))

all.then(boundRefresh, reportError);
return state;
}

if (action.type === COMPRESS) {
let archive = new zip();
let cwd = store.getState().get('cwd');

let all = Promise.all(action.file.map(function addFile(file) {
console.log('addFile', file);
let path = normalize((file.path || '') + file.name);
let archivePath = path.slice(cwd.length);
// directory
if (!(file instanceof Blob)) {
let folder = archive.folder(file.name);

return children(path).then(files => {
return Promise.all(files.map(child => {
return addFile(child);

// return readFile(childPath).then(content => {
// let blob = new Blob([content]);
// folder.file(child.name, blob);
// });
}));
})
}

return readFile(path).then(content => {
archive.file(archivePath + '/' + file.name, content);
});
}))

all.then(() => {
let buffer = archive.generate({ type: 'nodebuffer' });
console.log(buffer);
let blob = new Blob([buffer], { type: 'application/zip' });

let cwd = store.getState().get('cwd');
let path = normalize(cwd + '/archive.zip');
return writeFile(path, blob);
}).then(boundRefresh).catch(reportError);

return state;
}

if (action.type === DECOMPRESS) {
let file = action.file[0];
let path = normalize((file.path || '') + file.name);
readFile(path).then(content => {
let archive = new zip(content);
let files = Object.keys(archive.files);

let all = Promise.all(files.map(name => {
let buffer = archive.files[name].asArrayBuffer();
let blob = new Blob([buffer]);

let cwd = store.getState().get('cwd');
let filePath = normalize(cwd + '/' + name);

return writeFile(filePath, blob);
}));

all.then(boundRefresh, reportError);
});
}

return state;
}

Expand Down

0 comments on commit dfb7d8a

Please sign in to comment.