diff --git a/browser/main/NewNoteButton/NewNoteButton.styl b/browser/main/NewNoteButton/NewNoteButton.styl new file mode 100644 index 00000000..db5b4ca8 --- /dev/null +++ b/browser/main/NewNoteButton/NewNoteButton.styl @@ -0,0 +1,68 @@ +.root + position relative + background-color $ui-noteList-backgroundColor + height $topBar-height - 1 + margin-left: auto; + width: 64px; + margin-right: -15px; + +.root--expanded + @extend .root + +$control-height = 34px + +.control + position absolute + top 13px + left 8px + right 8px + height $control-height + overflow hidden + display flex + +.control-newPostButton + display block + width 32px + height $control-height - 2 + navButtonColor() + font-size 16px + line-height 28px + padding 0 + &:active + border-color $ui-button--active-backgroundColor + &:hover .control-newPostButton-tooltip + opacity 1 + +.control-newPostButton-tooltip + tooltip() + position fixed + pointer-events none + top 50px + left 433px + z-index 200 + padding 5px + line-height normal + border-radius 2px + opacity 0 + transition 0.1s + +body[data-theme="dark"] + .root, .root--expanded + background-color $ui-dark-noteList-backgroundColor + + .control + border-color $ui-dark-borderColor + + .control-newPostButton + color $ui-inactive-text-color + border-color $ui-dark-borderColor + background-color $ui-dark-noteList-backgroundColor + &:hover + transition 0.15s + color $ui-dark-text-color + &:active + background-color alpha($ui-dark-button--active-backgroundColor, 20%) + border-color $ui-dark-button--active-backgroundColor + + .control-newPostButton-tooltip + darkTooltip() diff --git a/browser/main/NewNoteButton/index.js b/browser/main/NewNoteButton/index.js new file mode 100644 index 00000000..6e8674d7 --- /dev/null +++ b/browser/main/NewNoteButton/index.js @@ -0,0 +1,182 @@ +import React, { PropTypes } from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './NewNoteButton.styl' +import _ from 'lodash' +import modal from 'browser/main/lib/modal' +import NewNoteModal from 'browser/main/modals/NewNoteModal' +import { hashHistory } from 'react-router' +import ee from 'browser/main/lib/eventEmitter' +import ConfigManager from 'browser/main/lib/ConfigManager' +import dataApi from 'browser/main/lib/dataApi' + +const { remote } = require('electron') +const { dialog } = remote + +const OSX = window.process.platform === 'darwin' + +class NewNoteButton extends React.Component { + constructor (props) { + super(props) + + this.state = { + } + + this.newNoteHandler = () => { + this.handleNewPostButtonClick() + } + + } + + componentDidMount () { + ee.on('top:new-note', this.newNoteHandler) + } + + componentWillUnmount () { + ee.off('top:new-note', this.newNoteHandler) + } + + handleNewPostButtonClick (e) { + let { config, location } = this.props + + if (location.pathname === '/trashed') { + dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'warning', + message: 'Cannot create new note', + detail: 'You cannot create new note in trash box.', + buttons: ['OK'] + }) + return + } + + switch (config.ui.defaultNote) { + case 'MARKDOWN_NOTE': + this.createNote('MARKDOWN_NOTE') + break + case 'SNIPPET_NOTE': + this.createNote('SNIPPET_NOTE') + break + case 'ALWAYS_ASK': + default: + let { dispatch, location } = this.props + let { storage, folder } = this.resolveTargetFolder() + + modal.open(NewNoteModal, { + storage: storage.key, + folder: folder.key, + dispatch, + location + }) + } + } + + resolveTargetFolder () { + let { data, params } = this.props + let storage = data.storageMap.get(params.storageKey) + + // Find first storage + if (storage == null) { + for (let kv of data.storageMap) { + storage = kv[1] + break + } + } + if (storage == null) window.alert('No storage to create a note') + let folder = _.find(storage.folders, {key: params.folderKey}) + if (folder == null) folder = storage.folders[0] + if (folder == null) window.alert('No folder to create a note') + + return { + storage, + folder + } + } + + createNote (noteType) { + let { dispatch, location } = this.props + if (noteType !== 'MARKDOWN_NOTE' && noteType !== 'SNIPPET_NOTE') throw new Error('Invalid note type.') + + let { storage, folder } = this.resolveTargetFolder() + + let newNote = noteType === 'MARKDOWN_NOTE' + ? { + type: 'MARKDOWN_NOTE', + folder: folder.key, + title: '', + content: '' + } + : { + type: 'SNIPPET_NOTE', + folder: folder.key, + title: '', + description: '', + snippets: [{ + name: '', + mode: 'text', + content: '' + }] + } + + dataApi + .createNote(storage.key, newNote) + .then((note) => { + dispatch({ + type: 'UPDATE_NOTE', + note: note + }) + hashHistory.push({ + pathname: location.pathname, + query: {key: note.storage + '-' + note.key} + }) + ee.emit('detail:focus') + }) + } + + setDefaultNote (defaultNote) { + let { config, dispatch } = this.props + let ui = Object.assign(config.ui) + ui.defaultNote = defaultNote + ConfigManager.set({ + ui + }) + + dispatch({ + type: 'SET_UI', + config: ConfigManager.get() + }) + } + + render () { + let { config, style, data } = this.props + return ( +