Add ability to add notebooks and refactor code
This commit is contained in:
parent
03238ad179
commit
d30477bd9d
12 changed files with 518 additions and 97 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -41,4 +41,4 @@ jspm_packages
|
|||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
dist
|
||||
app/dist
|
||||
|
|
|
|||
|
|
@ -15,7 +15,17 @@ import Folder from 'material-ui/lib/svg-icons/file/folder'
|
|||
import Edit from 'material-ui/lib/svg-icons/editor/mode-edit'
|
||||
import Delete from 'material-ui/lib/svg-icons/action/delete'
|
||||
import Divider from 'material-ui/lib/divider'
|
||||
import { SelectableContainerEnhance } from 'material-ui/lib/hoc/selectable-enhance'
|
||||
import { SelectableContainerEnhance } from '../enhance/SelectableEnhance'
|
||||
|
||||
import uuid from 'node-uuid'
|
||||
import path from 'path-extra'
|
||||
|
||||
import * as utils from 'utils'
|
||||
import glob from 'glob'
|
||||
|
||||
import fs from 'fs'
|
||||
import mkdirp from 'mkdirp'
|
||||
import jsfile from 'jsonfile'
|
||||
|
||||
const colors = styles.Colors
|
||||
|
||||
|
|
@ -28,38 +38,45 @@ function eventFire(el, etype){
|
|||
el.dispatchEvent(evObj);
|
||||
}
|
||||
}
|
||||
String.prototype.trunc = String.prototype.trunc || function(n){
|
||||
return (this.length > n) ? this.substr(0, n-1)+'...' : this;
|
||||
};
|
||||
|
||||
const {AppBar,
|
||||
AppCanvas,
|
||||
FontIcon,
|
||||
IconButton,
|
||||
EnhancedButton,
|
||||
NavigationClose,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Mixins,
|
||||
RaisedButton,
|
||||
FlatButton,
|
||||
Popover,
|
||||
Badge,
|
||||
TextField,
|
||||
Dialog,
|
||||
Styles,
|
||||
Tab,
|
||||
Tabs,
|
||||
Paper} = mui
|
||||
const {
|
||||
AppBar,
|
||||
AppCanvas,
|
||||
FontIcon,
|
||||
IconButton,
|
||||
EnhancedButton,
|
||||
NavigationClose,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Mixins,
|
||||
RaisedButton,
|
||||
FlatButton,
|
||||
Popover,
|
||||
Badge,
|
||||
TextField,
|
||||
Dialog,
|
||||
Styles,
|
||||
Tab,
|
||||
Tabs,
|
||||
Paper} = mui
|
||||
|
||||
let SelectableList = SelectableContainerEnhance(List)
|
||||
|
||||
function wrapState(ComposedComponent) {
|
||||
const StateWrapper = React.createClass({
|
||||
getInitialState() {
|
||||
return {selectedIndex: 0};
|
||||
return {selectedIndex: -1};
|
||||
},
|
||||
setIndex(i, func){
|
||||
this.setState({
|
||||
selectedIndex: i,
|
||||
}, func);
|
||||
},
|
||||
handleUpdateSelectedIndex(e, index) {
|
||||
this.setState({
|
||||
selectedIndex: index,
|
||||
});
|
||||
this.setIndex(index);
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
|
|
@ -118,24 +135,38 @@ export default class LibraryNav extends React.Component {
|
|||
|
||||
],
|
||||
notebooks: [
|
||||
{'state': 'editing', 'title': '', 'notes': 0},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10},
|
||||
{'state': 'displaying', 'title': 'FieldNotes', 'notes': 10}
|
||||
]
|
||||
}
|
||||
this.sortNotebooks(true)
|
||||
this.getNotebooks()
|
||||
}
|
||||
|
||||
getNotebooks = () => {
|
||||
var dataPath = utils.getAppDataPath()
|
||||
var notebooks = glob.sync(path.join(dataPath, '*.qvnotebook'))
|
||||
for(var i=0; i<notebooks.length; i++){
|
||||
var nbFile = notebooks[i]
|
||||
var obj = jsfile.readFileSync(path.join(nbFile, 'meta.json'))
|
||||
var notes = glob.sync(path.join(nbFile, '*.qvnote'))
|
||||
var nb = {
|
||||
'title': obj.name,
|
||||
'uuid': obj.uuid,
|
||||
'notes': notes.length,
|
||||
'path': nbFile
|
||||
}
|
||||
|
||||
if(nb.title == ''){
|
||||
nb.state = 'editing'
|
||||
}
|
||||
else{
|
||||
nb.state = 'displaying'
|
||||
}
|
||||
|
||||
this.state.notebooks.push(nb)
|
||||
this.sortNotebooks(true)
|
||||
}
|
||||
};
|
||||
|
||||
compareNotebooks = (a, b) => {
|
||||
let atitle = a.title.toLowerCase()
|
||||
let btitle = b.title.toLowerCase()
|
||||
|
|
@ -147,10 +178,10 @@ export default class LibraryNav extends React.Component {
|
|||
return 0
|
||||
};
|
||||
|
||||
sortNotebooks = (notset) => {
|
||||
sortNotebooks = (dontSet, func) => {
|
||||
this.state.notebooks.sort(this.compareNotebooks)
|
||||
if (!notset){
|
||||
this.setState({notebooks: this.state.notebooks})
|
||||
if (!dontSet){
|
||||
this.setState({notebooks: this.state.notebooks}, func)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -188,16 +219,71 @@ export default class LibraryNav extends React.Component {
|
|||
|
||||
}
|
||||
|
||||
scrollToRenamedNotebook = (original) => {
|
||||
var newIndex = 0
|
||||
for (var j = 0; j < this.state.notebooks.length; j++){
|
||||
var n = this.state.notebooks[j]
|
||||
if (n == original){
|
||||
newIndex = j
|
||||
this.refs.notebookList.setIndex(j, () => {
|
||||
var nbitem = $(ReactDOM.findDOMNode(this.refs[n.title+newIndex]))
|
||||
var cont = $('#notebook-list')
|
||||
var newPos = nbitem.offset().top - cont.offset().top + cont.scrollTop() - cont.height()/2;
|
||||
$('#notebook-list').animate({
|
||||
scrollTop: newPos
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
createNewNotebook = (notebook, callback) => {
|
||||
var notePath = utils.getNotebookPath(notebook)
|
||||
mkdirp(notePath, (err) => {
|
||||
if(err){
|
||||
console.log('There was an error creating the directory '+notePath)
|
||||
console.log(err)
|
||||
}
|
||||
else{
|
||||
if (callback){
|
||||
callback()
|
||||
}
|
||||
this.createNotebookMeta(notebook)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
createNotebookMeta = (notebook) => {
|
||||
var notePath = utils.getNotebookPath(notebook)
|
||||
var meta = {
|
||||
'name': notebook.title,
|
||||
'uuid': notebook.uuid
|
||||
}
|
||||
var metaPath = path.join(notePath, 'meta.json')
|
||||
jsfile.writeFile(metaPath, meta, (err) => {
|
||||
if(err){
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
newNotebookUnfocus = (i) => {
|
||||
|
||||
var nb = this.state.notebooks[i]
|
||||
|
||||
var tf = this.refs["textField"+i]
|
||||
var notebookName = tf.getValue()
|
||||
if (notebookName){
|
||||
nb.title = notebookName
|
||||
nb.state = 'displaying'
|
||||
this.setState({notebooks: this.state.notebooks})
|
||||
this.sortNotebooks()
|
||||
this.sortNotebooks(false, ()=>{
|
||||
this.scrollToRenamedNotebook(nb)
|
||||
})
|
||||
this.createNotebookMeta(nb)
|
||||
}
|
||||
else if(nb.title){
|
||||
nb.state = 'displaying'
|
||||
|
|
@ -206,11 +292,23 @@ export default class LibraryNav extends React.Component {
|
|||
};
|
||||
|
||||
addNotebookTapped = () => {
|
||||
var nbs = this.state.notebooks
|
||||
nbs.splice(0, 0, {'state': 'editing',
|
||||
'title': '',
|
||||
'notes': 0})
|
||||
this.setState({notebooks: nbs})
|
||||
var nb_uuid = uuid.v4().toUpperCase()
|
||||
|
||||
var nb = {
|
||||
'state': 'editing',
|
||||
'title': '',
|
||||
'uuid': nb_uuid,
|
||||
'notes': 0
|
||||
}
|
||||
|
||||
this.createNewNotebook(nb, () => {
|
||||
var nbs = this.state.notebooks
|
||||
nbs.splice(0, 0, nb)
|
||||
this.setState({notebooks: nbs}, () => {
|
||||
this.refs['textField0'].focus()
|
||||
})
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
newNotebookTyped = (i) => {
|
||||
|
|
@ -218,6 +316,7 @@ export default class LibraryNav extends React.Component {
|
|||
};
|
||||
|
||||
menuItemClicked = (i, ev) => {
|
||||
this.refs.notebookList.setIndex(-1)
|
||||
var item = this.state.navItems[i]
|
||||
var type = 'leftClick'
|
||||
var nativeEvent = ev.nativeEvent
|
||||
|
|
@ -232,14 +331,9 @@ export default class LibraryNav extends React.Component {
|
|||
var nbs = this.state.notebooks
|
||||
nbs[i].state = 'editing'
|
||||
this.setState({notebooks: nbs}, () => {
|
||||
console.log(i)
|
||||
var nbsx = this.state.notebooks
|
||||
this.props.closeContextMenu()
|
||||
//this.refs['textField'+i].focus()
|
||||
//$(ReactDOM.findDOMNode(this.refs['listItem'+i])).click()
|
||||
//console.log(node.find(':input'))
|
||||
//node.find(':input')[0].focus()
|
||||
this.refs['textField'+i].focus()
|
||||
})
|
||||
this.props.closeContextMenu()
|
||||
}
|
||||
|
||||
deleteTapped = (i) => {
|
||||
|
|
@ -276,12 +370,63 @@ export default class LibraryNav extends React.Component {
|
|||
this.props.updateContextMenu(this.contextMenuItems(i))
|
||||
this.props.openContextMenu(x, y)
|
||||
}
|
||||
this.refs.mainList.setIndex(-1)
|
||||
};
|
||||
|
||||
notebookList = () => {
|
||||
return (<div id="notebook-list">
|
||||
|
||||
{this.state.notebooks.map((notebook, i) =>{
|
||||
var l = null
|
||||
|
||||
if (notebook.state == 'editing'){
|
||||
l = <ListItem
|
||||
key={notebook.uuid || i}
|
||||
value={i}
|
||||
innerDivStyle={{'paddingBottom': 0,
|
||||
'paddingTop': 0}}
|
||||
leftIcon={<NoteBook color={colors.grey500}/>}
|
||||
rightIcon={<Badge badgeContent={notebook.notes}/>}>
|
||||
|
||||
<TextField
|
||||
ref={"textField"+i}
|
||||
fullWidth={true}
|
||||
hintText={notebook.title.trunc(18) || "Notebook Name"}
|
||||
underlineShow={false}
|
||||
onBlur={this.newNotebookUnfocus.bind(this, i)}
|
||||
onEnterKeyDown={this.newNotebookUnfocus.bind(this, i)}
|
||||
/>
|
||||
|
||||
</ListItem>
|
||||
}
|
||||
else{
|
||||
l = <ListItem
|
||||
key={notebook.uuid || i}
|
||||
value={i}
|
||||
primaryText={notebook.title.trunc(18)}
|
||||
tooltip={notebook.title}
|
||||
ref={notebook.title+i}
|
||||
className="noselect"
|
||||
onTouchTap={this.noteBookTapped.bind(this, i)}
|
||||
leftIcon={<NoteBook onTouchTap={this.notebookIconTapped.bind(this, i)} color={colors.grey500}/>}
|
||||
rightIcon={<Badge
|
||||
style={{'padding': 0}}
|
||||
badgeContent={notebook.notes} />}
|
||||
/>
|
||||
}
|
||||
return l
|
||||
})}
|
||||
</div>)
|
||||
|
||||
};
|
||||
|
||||
notebookIconTapped = (i, ev) => {
|
||||
};
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div id={this.props.id} className={this.props.className || ""}>
|
||||
<SelectableList id="main-nav" subheader="Library">
|
||||
<SelectableList ref='mainList' className="list" id="main-nav" subheader="Library">
|
||||
{this.state.navItems.map((item, i) => {
|
||||
return <ListItem
|
||||
primaryText={item.name}
|
||||
|
|
@ -295,7 +440,7 @@ export default class LibraryNav extends React.Component {
|
|||
</SelectableList>
|
||||
<Divider />
|
||||
<div>
|
||||
<List id="nblist" subheader={<div>
|
||||
<SelectableList id="nblist" className="list" ref='notebookList' subheader={<div>
|
||||
<div className="inline">NoteBooks</div>
|
||||
<IconButton
|
||||
onTouchTap={this.addNotebookTapped}
|
||||
|
|
@ -306,43 +451,8 @@ export default class LibraryNav extends React.Component {
|
|||
color={colors.grey500}/>
|
||||
</IconButton>
|
||||
</div>}>
|
||||
<div id="notebook-list">
|
||||
|
||||
{this.state.notebooks.map((notebook, i) =>{
|
||||
var l = null
|
||||
|
||||
if (notebook.state == 'editing'){
|
||||
l = <ListItem
|
||||
key={i}
|
||||
innerDivStyle={{'paddingBottom': 0,
|
||||
'paddingTop': 0}}
|
||||
primaryText={<TextField
|
||||
ref={"textField"+i}
|
||||
fullWidth={true}
|
||||
hintText={notebook.title || "Notebook Name"}
|
||||
underlineShow={false}
|
||||
onBlur={this.newNotebookUnfocus.bind(this, i)}
|
||||
onEnterKeyDown={this.newNotebookUnfocus.bind(this, i)}
|
||||
/>}
|
||||
leftIcon={<NoteBook color={colors.grey500}/>}
|
||||
rightIcon={<Badge badgeContent={notebook.notes} />}
|
||||
/>
|
||||
}
|
||||
else{
|
||||
l = <ListItem
|
||||
key={i}
|
||||
primaryText={notebook.title}
|
||||
ref={notebook.title+i}
|
||||
className="noselect"
|
||||
onTouchTap={this.noteBookTapped.bind(this, i)}
|
||||
leftIcon={<NoteBook color={colors.grey500}/>}
|
||||
rightIcon={<Badge badgeContent={notebook.notes} />}
|
||||
/>
|
||||
}
|
||||
return l
|
||||
})}
|
||||
</div>
|
||||
</List>
|
||||
{this.notebookList()}
|
||||
</SelectableList>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
122
app/containers/App.jsx
Normal file
122
app/containers/App.jsx
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import React from 'react'
|
||||
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme'
|
||||
import LibraryNav from 'LibraryNav'
|
||||
import Styles from 'material-ui/lib/styles'
|
||||
import Rethink from 'rethinkdbdash'
|
||||
import mui from 'material-ui'
|
||||
import * as ContextMenuActions from '../actions'
|
||||
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
|
||||
const {
|
||||
Popover,
|
||||
Menu,
|
||||
MenuItem} = mui
|
||||
|
||||
const DefaultRawTheme = Styles.LightRawTheme
|
||||
|
||||
let r = Rethink({
|
||||
db: 'technote',
|
||||
servers: [
|
||||
{host: '162.243.255.144',
|
||||
port: 28015}
|
||||
]})
|
||||
|
||||
function createTables(){
|
||||
r.tableCreate('notes').run()
|
||||
.then(function(){
|
||||
r.table('notes').indexCreate('account_id').run()
|
||||
})
|
||||
.error(function(){})
|
||||
|
||||
r.tableCreate('accounts').run().error(function(){})
|
||||
}
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props, context){
|
||||
super(props, context)
|
||||
createTables()
|
||||
this.state = {
|
||||
entries: [],
|
||||
}
|
||||
}
|
||||
|
||||
static get childContextTypes(){
|
||||
return {muiTheme: React.PropTypes.object}
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
muiTheme: getMuiTheme(DefaultRawTheme)
|
||||
}
|
||||
}
|
||||
|
||||
entriesTapped = () => {
|
||||
r.table('notes').getAll('jyapayne@gmail.com', {index: 'account_id'}).run().then(
|
||||
function(notes){
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
handleRequestClose = () => {
|
||||
this.props.contextMenuActions.closeContextMenu()
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const { contextMenu, contextMenuActions } = this.props
|
||||
return (
|
||||
<div className="fill-height">
|
||||
<div style={{position: 'absolute',
|
||||
width: 1,
|
||||
height: 1,
|
||||
top: contextMenu.y,
|
||||
left: contextMenu.x}} ref='menuPos'></div>
|
||||
<Popover
|
||||
open={contextMenu.opened}
|
||||
anchorEl={this.refs.menuPos}
|
||||
anchorOrigin={{horizontal: 'middle', vertical: 'bottom'}}
|
||||
targetOrigin={{horizontal: 'left', vertical: 'top'}}
|
||||
onRequestClose={this.handleRequestClose}>
|
||||
<Menu desktop={true}>
|
||||
{contextMenu.items.map(function (el, i){
|
||||
return el;
|
||||
})}
|
||||
</Menu>
|
||||
</Popover>
|
||||
|
||||
<LibraryNav
|
||||
id="library-nav"
|
||||
ref="libraryNav"
|
||||
entriesTapped={this.entriesTapped}
|
||||
className="left inline fill-height"
|
||||
{...contextMenuActions}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
contextMenu: React.PropTypes.object.isRequired,
|
||||
contextMenuActions: React.PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
contextMenu: state.contextMenu
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
contextMenuActions: bindActionCreators(ContextMenuActions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(App)
|
||||
142
app/enhance/SelectableEnhance.jsx
Normal file
142
app/enhance/SelectableEnhance.jsx
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import React from 'react';
|
||||
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
|
||||
import StylePropable from 'material-ui/lib/mixins/style-propable';
|
||||
import ColorManipulator from 'material-ui/lib/utils/color-manipulator';
|
||||
|
||||
export const SelectableContainerEnhance = (Component) => {
|
||||
const composed = React.createClass({
|
||||
|
||||
displayName: `Selectable${Component.displayName}`,
|
||||
|
||||
propTypes: {
|
||||
children: React.PropTypes.node,
|
||||
selectedItemStyle: React.PropTypes.object,
|
||||
valueLink: React.PropTypes.shape({
|
||||
value: React.PropTypes.any,
|
||||
requestChange: React.PropTypes.func,
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
contextTypes: {
|
||||
muiTheme: React.PropTypes.object,
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
muiTheme: React.PropTypes.object,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
StylePropable,
|
||||
],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
muiTheme: this.context.muiTheme || getMuiTheme(),
|
||||
};
|
||||
},
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
muiTheme: this.state.muiTheme,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
|
||||
this.setState({muiTheme: newMuiTheme});
|
||||
},
|
||||
|
||||
getValueLink: function(props) {
|
||||
return props.valueLink || {
|
||||
value: props.value,
|
||||
requestChange: props.onChange,
|
||||
};
|
||||
},
|
||||
|
||||
extendChild(child, styles, selectedItemStyle) {
|
||||
if (child && child.type && child.type.displayName === 'ListItem') {
|
||||
let selected = this.isChildSelected(child, this.props);
|
||||
let selectedChildrenStyles = {};
|
||||
if (selected) {
|
||||
selectedChildrenStyles = this.mergeStyles(styles, selectedItemStyle);
|
||||
}
|
||||
|
||||
let mergedChildrenStyles = this.mergeStyles(child.props.style || {}, selectedChildrenStyles);
|
||||
|
||||
this.keyIndex += 1;
|
||||
|
||||
return React.cloneElement(child, {
|
||||
onTouchTap: (e) => {
|
||||
this.handleItemTouchTap(e, child);
|
||||
if (child.props.onTouchTap) {
|
||||
child.props.onTouchTap(e);
|
||||
}
|
||||
},
|
||||
key: this.keyIndex,
|
||||
style: mergedChildrenStyles,
|
||||
nestedItems: child.props.nestedItems.map((child) => this.extendChild(child, styles, selectedItemStyle)),
|
||||
initiallyOpen: this.isInitiallyOpen(child),
|
||||
});
|
||||
} else {
|
||||
var Type = child.type
|
||||
return <Type {...child.props} {...child.state}>{React.Children.map(child.props.children, (childx) => this.extendChild(childx, styles, selectedItemStyle))}</Type>;
|
||||
}
|
||||
},
|
||||
|
||||
isInitiallyOpen(child) {
|
||||
if (child.props.initiallyOpen) {
|
||||
return child.props.initiallyOpen;
|
||||
}
|
||||
return this.hasSelectedDescendant(false, child);
|
||||
},
|
||||
|
||||
hasSelectedDescendant(previousValue, child) {
|
||||
if (React.isValidElement(child) && child.props.nestedItems && child.props.nestedItems.length > 0) {
|
||||
return child.props.nestedItems.reduce(this.hasSelectedDescendant, previousValue);
|
||||
}
|
||||
return previousValue || this.isChildSelected(child, this.props);
|
||||
},
|
||||
|
||||
isChildSelected(child, props) {
|
||||
let itemValue = this.getValueLink(props).value;
|
||||
let childValue = child.props.value;
|
||||
|
||||
return (itemValue === childValue);
|
||||
},
|
||||
|
||||
handleItemTouchTap(e, item) {
|
||||
let valueLink = this.getValueLink(this.props);
|
||||
let itemValue = item.props.value;
|
||||
let menuValue = valueLink.value;
|
||||
if ( itemValue !== menuValue) {
|
||||
valueLink.requestChange(e, itemValue);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const {children, selectedItemStyle} = this.props;
|
||||
this.keyIndex = 0;
|
||||
let styles = {};
|
||||
|
||||
if (!selectedItemStyle) {
|
||||
let textColor = this.state.muiTheme.rawTheme.palette.textColor;
|
||||
let selectedColor = ColorManipulator.fade(textColor, 0.2);
|
||||
styles = {
|
||||
backgroundColor: selectedColor,
|
||||
};
|
||||
}
|
||||
|
||||
let newChildren = React.Children.map(children, (child) => this.extendChild(child, styles, selectedItemStyle));
|
||||
|
||||
return (
|
||||
<Component {...this.props} {...this.state}>
|
||||
{newChildren}
|
||||
</Component>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return composed;
|
||||
};
|
||||
|
||||
export default SelectableContainerEnhance;
|
||||
8
app/store/configureStore.jsx
Normal file
8
app/store/configureStore.jsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { createStore } from 'redux'
|
||||
import rootReducer from '../reducers'
|
||||
|
||||
export default function configureStore(initialState) {
|
||||
const store = createStore(rootReducer, initialState)
|
||||
return store
|
||||
}
|
||||
|
||||
10
app/utils.jsx
Normal file
10
app/utils.jsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import path from 'path-extra'
|
||||
|
||||
export function getAppDataPath(){
|
||||
return path.datadir(APP_NAME)
|
||||
}
|
||||
|
||||
export function getNotebookPath(notebook){
|
||||
var notePath = getAppDataPath()
|
||||
return path.join(notePath, notebook.uuid+'.qvnotebook')
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
<div id="main">
|
||||
</div>
|
||||
<script>
|
||||
var APP_NAME = 'TechNote'
|
||||
window.$ = window.jQuery = require('./app/static/jquery-1.12.0.min.js');
|
||||
$(document).ready(function(){
|
||||
document.addEventListener("keydown", function (e) {
|
||||
|
|
@ -36,6 +37,6 @@
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="dist/bundle.js"></script>
|
||||
<script type="text/javascript" src="app/dist/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
17
index.jsx
Normal file
17
index.jsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react'
|
||||
import injectTapEventPlugin from "react-tap-event-plugin"
|
||||
injectTapEventPlugin()
|
||||
import { render } from 'react-dom'
|
||||
import { Provider } from 'react-redux'
|
||||
import App from './app/containers/App'
|
||||
import configureStore from './app/store/configureStore'
|
||||
|
||||
const store = configureStore()
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>,
|
||||
document.getElementById('main')
|
||||
)
|
||||
|
||||
|
|
@ -57,9 +57,14 @@
|
|||
"linux-x64": true
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": "^7.0.0",
|
||||
"jsonfile": "^2.2.3",
|
||||
"material-ui": "^0.14.4",
|
||||
"materialize-css": "^0.97.5",
|
||||
"mkdirp": "^0.5.1",
|
||||
"moment": "^2.11.2",
|
||||
"node-uuid": "^1.4.7",
|
||||
"path-extra": "^3.0.0",
|
||||
"react": "^0.14.7",
|
||||
"react-dom": "^0.14.7",
|
||||
"react-quill": "^0.4.1",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ body, html{
|
|||
.noselect{
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.list > div:first-child{
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.inline{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
var path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: './app/main.jsx',
|
||||
entry: './index.jsx',
|
||||
output: {
|
||||
path: __dirname + "/dist",
|
||||
path: __dirname + "/app/dist",
|
||||
filename: "bundle.js",
|
||||
sourceMapFilename: 'bundle.map'
|
||||
},
|
||||
|
|
@ -23,7 +23,8 @@ module.exports = {
|
|||
resolve:{
|
||||
extensions: ['', '.js', '.jsx'],
|
||||
root: [
|
||||
path.resolve('./app/modules')
|
||||
path.resolve('./app/components'),
|
||||
path.resolve('./app')
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue