feat navigation: style checkboxes in navigation

feat preferences: Show Hidden Files and Show Directories First options working
This commit is contained in:
Mahdi Dibaiee 2015-09-04 05:35:14 +04:30
parent 0ae06a77ae
commit 100dc03813
15 changed files with 745 additions and 263 deletions

View File

@ -12,11 +12,11 @@ Please read the Features section below and issues to make sure your issue is not
- [x] Refresh - [x] Refresh
- [x] Rename Files - [x] Rename Files
- [x] Error dialogs - [x] Error dialogs
- [x] Show / Hide hidden files
- [x] Show directories first
- [ ] Create new files and directories - [ ] Create new files and directories
- [ ] File Size - [ ] File Size
- [ ] Directory Child Count - [ ] Directory Child Count
- [ ] Show / Hide hidden files
- [ ] Show directories first
- [ ] File Preview - [ ] File Preview
- [ ] Filter Files - [ ] Filter Files
- [ ] Different views (List, Icons, etc) - [ ] Different views (List, Icons, etc)

File diff suppressed because it is too large Load Diff

View File

@ -101,6 +101,23 @@ input {
font-weight: 200; font-weight: 200;
font-size: 1.6rem; font-size: 1.6rem;
} }
input[type="checkbox"] {
width: 0;
height: 0;
}
input[type="checkbox"]::before {
content: '';
display: block;
border: 1px solid #f0f0f0;
background: transparent;
border-radius: 50%;
width: 10px;
height: 10px;
box-sizing: border-box;
}
input[type="checkbox"]::before:checked {
background: #63b0cd;
}
.file, .file,
.directory { .directory {
display: flex; display: flex;
@ -230,6 +247,28 @@ nav li:last-of-type {
padding-bottom: 0; padding-bottom: 0;
border-bottom: none; border-bottom: none;
} }
nav li label {
clear: left;
}
nav li label::after {
content: '';
display: block;
float: right;
margin-right: 13px;
border-radius: 50%;
width: 10px;
height: 10px;
background: transparent;
border: 1px solid #9b9b93;
}
nav li input {
clear: right;
float: right;
display: none;
}
nav li input:checked + label::after {
background: #63b0cd;
}
nav i { nav i {
display: block; display: block;
position: fixed; position: fixed;

Binary file not shown.

View File

@ -0,0 +1,8 @@
import { SETTINGS } from 'actions/types';
export default function(props) {
return {
type: SETTINGS,
...props
}
}

View File

@ -20,6 +20,8 @@ const TYPES = {
DIALOG: Symbol('DEBUG'), DIALOG: Symbol('DEBUG'),
SETTINGS: Symbol('SETTINGS'),
SEARCH: Symbol('SEARCH') SEARCH: Symbol('SEARCH')
}; };

View File

@ -2,6 +2,8 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import File from './file'; import File from './file';
import Directory from './directory'; import Directory from './directory';
import store from 'store';
import { type } from 'utils';
@connect(props) @connect(props)
export default class FileList extends Component { export default class FileList extends Component {
@ -12,8 +14,24 @@ export default class FileList extends Component {
render() { render() {
let { files } = this.props; let { files } = this.props;
let settings = store.getState().get('settings');
if (settings.showDirectoriesFirst) {
files = files.sort((a, b) => {
if (type(a) === 'Directory') return -1;
if (type(b) === 'Directory') return 1;
return 0;
})
}
if (!settings.showHiddenFiles) {
files = files.filter(file => {
return file.name[0] !== '.';
})
}
let els = files.map((file, index) => { let els = files.map((file, index) => {
if (fileType(file) === 'File') { if (type(file) === 'File') {
return <File key={index} index={index} name={file.name} />; return <File key={index} index={index} name={file.name} />;
} else { } else {
return <Directory key={index} index={index} name={file.name} /> return <Directory key={index} index={index} name={file.name} />
@ -40,7 +58,3 @@ async function getFiles(dir) {
return await root.getFilesAndDirectories(); return await root.getFilesAndDirectories();
} }
function fileType(file) {
return Object.prototype.toString.call(file).slice(8, -1);
}

View File

@ -1,10 +1,15 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { hide } from 'actions/navigation'; import { hide } from 'actions/navigation';
import camelCase from 'lodash/string/camelCase';
import updateSettings from 'actions/settings';
import store from 'store';
@connect(props) @connect(props)
export default class Navigation extends Component { export default class Navigation extends Component {
render() { render() {
let { settings } = this.props;
return ( return (
<nav className={this.props.active ? 'active' : ''}> <nav className={this.props.active ? 'active' : ''}>
<i onClick={this.hide.bind(this)} /> <i onClick={this.hide.bind(this)} />
@ -22,9 +27,15 @@ export default class Navigation extends Component {
</ul> </ul>
<p>Preferences</p> <p>Preferences</p>
<ul> <ul onChange={this.onChange.bind(this)}>
<li>Show Hidden Files <input type='checkbox' /></li> <li>
<li>Show Directories First <input type='checkbox' /></li> <input type='checkbox' id='showHiddenFiles' defaultChecked={settings.showHiddenFiles} />
<label htmlFor='showHiddenFiles'>Show Hidden Files</label>
</li>
<li>
<input id='showDirectoriesFirst' type='checkbox' defaultChecked={settings.showDirectoriesFirst} />
<label htmlFor='showDirectoriesFirst'>Show Directories First</label>
</li>
<li>Advanced Preferences</li> <li>Advanced Preferences</li>
</ul> </ul>
</nav> </nav>
@ -34,10 +45,24 @@ export default class Navigation extends Component {
hide() { hide() {
this.props.dispatch(hide()); this.props.dispatch(hide());
} }
onChange(e) {
if (e.target.nodeName.toLowerCase() !== 'input') return;
let key = e.target.id;
let value = this.props.settings[key];
let action = updateSettings({
[key]: e.target.checked
});
store.dispatch(action);
}
} }
function props(store) { function props(store) {
return { return {
active: store.get('navigation') active: store.get('navigation'),
settings: store.get('settings')
} }
} }

View File

@ -6,6 +6,7 @@ import navigation from './navigation';
import activeFile from './active-file'; import activeFile from './active-file';
import menu from './menu'; import menu from './menu';
import dialog from './dialog'; import dialog from './dialog';
import settings from './settings';
export default function(state = new Immutable.Map(), action) { export default function(state = new Immutable.Map(), action) {
console.log('action', action); console.log('action', action);
@ -15,6 +16,7 @@ export default function(state = new Immutable.Map(), action) {
files: files(state.get('files'), action), files: files(state.get('files'), action),
activeFile: activeFile(state.get('activeFile'), action), activeFile: activeFile(state.get('activeFile'), action),
navigation: navigation(state.get('navigation'), action), navigation: navigation(state.get('navigation'), action),
settings: settings(state.get('settings'), action),
fileMenu: menu(state, action, 'fileMenu'), fileMenu: menu(state, action, 'fileMenu'),
directoryMenu: menu(state, action, 'directoryMenu'), directoryMenu: menu(state, action, 'directoryMenu'),
renameDialog: dialog(state, action, 'renameDialog'), renameDialog: dialog(state, action, 'renameDialog'),

View File

@ -1,4 +1,4 @@
import { CHANGE_DIRECTORY, REFRESH } from 'actions/types'; import { CHANGE_DIRECTORY, REFRESH, SETTINGS } from 'actions/types';
import listFiles from 'actions/list-files'; import listFiles from 'actions/list-files';
import { children } from 'api/files'; import { children } from 'api/files';
import store from 'store'; import store from 'store';
@ -11,7 +11,7 @@ export default function(state = '', action) {
return action.dir; return action.dir;
} }
if (action.type === REFRESH) { if (action.type === REFRESH || action.type === SETTINGS) {
children(state).then(files => { children(state).then(files => {
store.dispatch(listFiles(files)); store.dispatch(listFiles(files));
}); });

View File

@ -9,7 +9,6 @@ export default function(state = [], action) {
return action.files; return action.files;
} }
if (action.type === RENAME_FILE) { if (action.type === RENAME_FILE) {
let file = state[action.file]; let file = state[action.file];

View File

@ -0,0 +1,15 @@
import { SETTINGS } from 'actions/types';
import omit from 'lodash/object/omit';
const DEFAULT = {
showHiddenFiles: false,
showDirectoriesFirst: true
}
export default function(state = DEFAULT, action) {
if (action.type === SETTINGS) {
return Object.assign({}, state, omit(action, 'type'));
}
return state;
}

View File

@ -7,7 +7,6 @@ import dialogs from './dialogs';
const DEFAULT = new Immutable.Map(Object.assign({ const DEFAULT = new Immutable.Map(Object.assign({
dir: '', dir: '',
files: []
}, dialogs, menus)); }, dialogs, menus));
let store = createStore(reducers, DEFAULT); let store = createStore(reducers, DEFAULT);

View File

@ -52,6 +52,39 @@ nav {
padding-bottom: 0; padding-bottom: 0;
border-bottom: none; border-bottom: none;
} }
label {
clear: left;
&::after {
content: '';
display: block;
float: right;
margin-right: 13px;
border-radius: 50%;
width: 10px;
height: 10px;
background: transparent;
border: 1px solid @overlay;
}
}
input {
clear: right;
float: right;
display: none;
}
input:checked + label::after {
background: @blue;
}
} }
i { i {

View File

@ -13,3 +13,28 @@ input {
.light-medium; .light-medium;
} }
input[type="checkbox"] {
width: 0;
height: 0;
}
input[type="checkbox"]::before {
content: '';
display: block;
border: 1px solid @gray;
background: transparent;
border-radius: 50%;
width: 10px;
height: 10px;
box-sizing: border-box;
&:checked {
background: @blue;
}
}