feat search: search files, depth-first

feat files.view: Open files using Web Activities
feat copy/paste: Copy and Paste/Move files
fix filters: add "all" filter which clears filters out
This commit is contained in:
Mahdi Dibaiee
2015-09-06 15:53:48 +04:30
parent 764554c6b9
commit 7f6884cea8
50 changed files with 9157 additions and 5534 deletions

View File

@@ -8,6 +8,8 @@ import menu from './menu';
import dialog from './dialog';
import settings from './settings';
import selectView from './select-view';
import spinner from './spinner';
import search from './search';
export default function(state = new Immutable.Map(), action) {
console.log('action', action);
@@ -15,6 +17,8 @@ export default function(state = new Immutable.Map(), action) {
lwd: lwd(state, action), // last working directory
cwd: cwd(state.get('cwd'), action),
files: files(state.get('files'), action),
search: search(state.get('search'), action),
spinner: spinner(state.get('spinner'), action),
selectView: selectView(state.get('selectView'), action),
activeFile: activeFile(state.get('activeFile'), action),
navigation: navigation(state.get('navigation'), action),
@@ -26,5 +30,6 @@ export default function(state = new Immutable.Map(), action) {
deleteDialog: dialog(state, action, 'deleteDialog'),
errorDialog: dialog(state, action, 'errorDialog'),
createDialog: dialog(state, action, 'createDialog'),
searchDialog: dialog(state, action, 'searchDialog')
});
}

View File

@@ -1,8 +1,8 @@
import { CHANGE_DIRECTORY, REFRESH, SETTINGS } from 'actions/types';
import listFiles from 'actions/list-files';
import { children } from 'api/files';
import store from 'store';
import { reportError } from 'utils';
import { listFiles } from 'actions/files-view';
export default function(state = '', action) {
if (action.type === CHANGE_DIRECTORY) {

View File

@@ -1,6 +1,6 @@
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE } from 'actions/types';
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE, MOVE_FILE, COPY_FILE, SEARCH } from 'actions/types';
import { refresh } from 'actions/files-view';
import { move, remove, sdcard, createFile, createDirectory } from 'api/files';
import { move, remove, sdcard, createFile, createDirectory, copy } from 'api/files';
import { show } from 'actions/dialog';
import store, { bind } from 'store';
import { reportError, type } from 'utils';
@@ -8,8 +8,8 @@ import { reportError, type } from 'utils';
let boundRefresh = bind(refresh());
export default function(state = [], action) {
if (action.type === LIST_FILES) {
if (action.type === LIST_FILES) {
let settings = store.getState().get('settings');
if (settings.showDirectoriesFirst) {
@@ -22,7 +22,16 @@ export default function(state = [], action) {
if (!settings.showHiddenFiles) {
action.files = action.files.filter(file => {
return file.name[0] !== '.';
})
});
}
if (settings.filter) {
action.files = action.files.filter(file => {
if (type(file) === 'Directory') return true;
let fileType = file.type.slice(0, file.type.indexOf('/'));
return fileType === settings.filter;
});
}
return action.files;
@@ -36,34 +45,45 @@ export default function(state = [], action) {
}
if (action.type === RENAME_FILE) {
let file = state[action.file];
let all = Promise.all(action.file.map(file => {
return move(file, (file.path || '') + action.name);
}));
move(file, (file.path || '') + action.name).then(boundRefresh, reportError);
all.then(boundRefresh, reportError);
return state;
}
if (action.type === MOVE_FILE) {
let all = Promise.all(action.file.map(file => {
return move(file, action.newPath + '/' + file.name);
}));
all.then(boundRefresh, reportError);
return state;
}
if (action.type === COPY_FILE) {
let all = Promise.all(action.file.map(file => {
return copy(file, action.newPath + '/' + file.name);
}));
all.then(boundRefresh, reportError);
return state;
}
if (action.type === DELETE_FILE) {
let copy = state.slice(0);
let all = Promise.all(action.file.map(file => {
let path = ((file.path || '') + file.name).replace(/^\//, '');
return remove(path, true);
}))
if (action.file.length) {
for (let index of action.file) {
del(state, index);
}
copy = copy.filter((a, i) => action.file.indexOf(i) === -1);
} else {
del(state, action.file);
copy.splice(action.file, 1);
}
return copy;
all.then(boundRefresh, reportError);
return state;
}
return state;
}
function del(state, index) {
let file = state[index];
return remove((file.path || '') + '/' + file.name).catch(reportError);
function mov(file, newPath) {
return
}

50
src/js/reducers/search.js Normal file
View File

@@ -0,0 +1,50 @@
import { SEARCH } from 'actions/types';
import store from 'store';
import { reportError } from 'utils';
import { listFiles } from 'actions/files-view';
import { children } from 'api/files';
import { type } from 'utils';
export default function(state = '', action) {
if (action.type === SEARCH) {
search(action.keywords);
return action.keywords;
}
return state;
}
function search(keywords) {
if (!keywords) {
let cwd = store.getState().get('cwd');
console.log(cwd);
children(cwd, true).then(files => {
store.dispatch(listFiles(files));
}, reportError);
return '';
}
let keys = keywords.split(' ');
// We don't want to show all the currently visible files from the
// first iteration
let once = true;
children('/', true).then(function showResults(files) {
if (!store.getState().get('search')) return;
let current = once ? [] : store.getState().get('files');
once = false;
let filtered = files.filter(file => {
if (type(file) === 'Directory') {
let path = (file.path + file.name).replace(/^\//, '');
children(path, true).then(showResults, reportError);
}
return keys.some(key => {
return file.name.indexOf(key) > -1;
});
});
store.dispatch(listFiles(current.concat(filtered)));
}, reportError);
}

View File

@@ -0,0 +1,21 @@
import { SPINNER, CHANGE_DIRECTORY, LIST_FILES, REFRESH, DIALOG, CREATE_FILE, DELETE_FILE } from 'actions/types';
export default function(state = false, action) {
if (action.type === SPINNER) {
return action.active === 'toggle' ? !state : action.active;
}
if (action.type === DIALOG && action.id === 'errorDialog') {
return false;
}
switch (action.type) {
case CHANGE_DIRECTORY:
case REFRESH:
return true;
case LIST_FILES:
return false;
}
return state;
}