feat navigation: style checkboxes in navigation
feat preferences: Show Hidden Files and Show Directories First options working
This commit is contained in:
parent
0ae06a77ae
commit
100dc03813
@ -12,11 +12,11 @@ Please read the Features section below and issues to make sure your issue is not
|
||||
- [x] Refresh
|
||||
- [x] Rename Files
|
||||
- [x] Error dialogs
|
||||
- [x] Show / Hide hidden files
|
||||
- [x] Show directories first
|
||||
- [ ] Create new files and directories
|
||||
- [ ] File Size
|
||||
- [ ] Directory Child Count
|
||||
- [ ] Show / Hide hidden files
|
||||
- [ ] Show directories first
|
||||
- [ ] File Preview
|
||||
- [ ] Filter Files
|
||||
- [ ] Different views (List, Icons, etc)
|
||||
|
817
build/main.js
817
build/main.js
File diff suppressed because it is too large
Load Diff
@ -101,6 +101,23 @@ input {
|
||||
font-weight: 200;
|
||||
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,
|
||||
.directory {
|
||||
display: flex;
|
||||
@ -230,6 +247,28 @@ nav li:last-of-type {
|
||||
padding-bottom: 0;
|
||||
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 {
|
||||
display: block;
|
||||
position: fixed;
|
||||
|
Binary file not shown.
8
src/js/actions/settings.js
Normal file
8
src/js/actions/settings.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { SETTINGS } from 'actions/types';
|
||||
|
||||
export default function(props) {
|
||||
return {
|
||||
type: SETTINGS,
|
||||
...props
|
||||
}
|
||||
}
|
@ -20,6 +20,8 @@ const TYPES = {
|
||||
|
||||
DIALOG: Symbol('DEBUG'),
|
||||
|
||||
SETTINGS: Symbol('SETTINGS'),
|
||||
|
||||
SEARCH: Symbol('SEARCH')
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,8 @@ import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import File from './file';
|
||||
import Directory from './directory';
|
||||
import store from 'store';
|
||||
import { type } from 'utils';
|
||||
|
||||
@connect(props)
|
||||
export default class FileList extends Component {
|
||||
@ -12,8 +14,24 @@ export default class FileList extends Component {
|
||||
render() {
|
||||
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) => {
|
||||
if (fileType(file) === 'File') {
|
||||
if (type(file) === 'File') {
|
||||
return <File key={index} index={index} name={file.name} />;
|
||||
} else {
|
||||
return <Directory key={index} index={index} name={file.name} />
|
||||
@ -40,7 +58,3 @@ async function getFiles(dir) {
|
||||
|
||||
return await root.getFilesAndDirectories();
|
||||
}
|
||||
|
||||
function fileType(file) {
|
||||
return Object.prototype.toString.call(file).slice(8, -1);
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { hide } from 'actions/navigation';
|
||||
import camelCase from 'lodash/string/camelCase';
|
||||
import updateSettings from 'actions/settings';
|
||||
import store from 'store';
|
||||
|
||||
@connect(props)
|
||||
export default class Navigation extends Component {
|
||||
render() {
|
||||
let { settings } = this.props;
|
||||
|
||||
return (
|
||||
<nav className={this.props.active ? 'active' : ''}>
|
||||
<i onClick={this.hide.bind(this)} />
|
||||
@ -22,9 +27,15 @@ export default class Navigation extends Component {
|
||||
</ul>
|
||||
|
||||
<p>Preferences</p>
|
||||
<ul>
|
||||
<li>Show Hidden Files <input type='checkbox' /></li>
|
||||
<li>Show Directories First <input type='checkbox' /></li>
|
||||
<ul onChange={this.onChange.bind(this)}>
|
||||
<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>
|
||||
</ul>
|
||||
</nav>
|
||||
@ -34,10 +45,24 @@ export default class Navigation extends Component {
|
||||
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) {
|
||||
return {
|
||||
active: store.get('navigation')
|
||||
active: store.get('navigation'),
|
||||
settings: store.get('settings')
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import navigation from './navigation';
|
||||
import activeFile from './active-file';
|
||||
import menu from './menu';
|
||||
import dialog from './dialog';
|
||||
import settings from './settings';
|
||||
|
||||
export default function(state = new Immutable.Map(), action) {
|
||||
console.log('action', action);
|
||||
@ -15,6 +16,7 @@ export default function(state = new Immutable.Map(), action) {
|
||||
files: files(state.get('files'), action),
|
||||
activeFile: activeFile(state.get('activeFile'), action),
|
||||
navigation: navigation(state.get('navigation'), action),
|
||||
settings: settings(state.get('settings'), action),
|
||||
fileMenu: menu(state, action, 'fileMenu'),
|
||||
directoryMenu: menu(state, action, 'directoryMenu'),
|
||||
renameDialog: dialog(state, action, 'renameDialog'),
|
||||
|
@ -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 { children } from 'api/files';
|
||||
import store from 'store';
|
||||
@ -11,7 +11,7 @@ export default function(state = '', action) {
|
||||
return action.dir;
|
||||
}
|
||||
|
||||
if (action.type === REFRESH) {
|
||||
if (action.type === REFRESH || action.type === SETTINGS) {
|
||||
children(state).then(files => {
|
||||
store.dispatch(listFiles(files));
|
||||
});
|
||||
|
@ -9,7 +9,6 @@ export default function(state = [], action) {
|
||||
return action.files;
|
||||
}
|
||||
|
||||
|
||||
if (action.type === RENAME_FILE) {
|
||||
let file = state[action.file];
|
||||
|
||||
|
15
src/js/reducers/settings.js
Normal file
15
src/js/reducers/settings.js
Normal 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;
|
||||
}
|
@ -7,7 +7,6 @@ import dialogs from './dialogs';
|
||||
|
||||
const DEFAULT = new Immutable.Map(Object.assign({
|
||||
dir: '',
|
||||
files: []
|
||||
}, dialogs, menus));
|
||||
|
||||
let store = createStore(reducers, DEFAULT);
|
||||
|
@ -52,6 +52,39 @@ nav {
|
||||
padding-bottom: 0;
|
||||
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 {
|
||||
|
@ -13,3 +13,28 @@ input {
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user