diff --git a/atom-lib/finder-window.js b/atom-lib/finder-window.js index 466c40b5..01bc6eac 100644 --- a/atom-lib/finder-window.js +++ b/atom-lib/finder-window.js @@ -25,6 +25,4 @@ finderWindow.on('blur', function () { finderWindow.hide() }) -finderWindow.setVisibleOnAllWorkspaces(true) - module.exports = finderWindow diff --git a/atom-lib/main-window.js b/atom-lib/main-window.js index cf5dc42c..710e6fd6 100644 --- a/atom-lib/main-window.js +++ b/atom-lib/main-window.js @@ -16,8 +16,6 @@ const url = path.resolve(__dirname, '../browser/main/index.html') mainWindow.loadURL('file://' + url) -mainWindow.setVisibleOnAllWorkspaces(true) - mainWindow.webContents.on('new-window', function (e) { e.preventDefault() }) diff --git a/browser/main/HomePage.js b/browser/main/HomePage.js index b7880825..69c65948 100644 --- a/browser/main/HomePage.js +++ b/browser/main/HomePage.js @@ -1,6 +1,6 @@ import React, { PropTypes} from 'react' import { connect } from 'react-redux' -import { CREATE_MODE, EDIT_MODE, IDLE_MODE, NEW, toggleTutorial } from 'boost/actions' +import { EDIT_MODE, IDLE_MODE, NEW, toggleTutorial } from 'boost/actions' // import UserNavigator from './HomePage/UserNavigator' import ArticleNavigator from './HomePage/ArticleNavigator' import ArticleTopBar from './HomePage/ArticleTopBar' @@ -57,7 +57,7 @@ class HomePage extends React.Component { } switch (status.mode) { - case CREATE_MODE: + case EDIT_MODE: if (e.keyCode === 27) { detail.handleCancelButtonClick() @@ -65,6 +65,13 @@ class HomePage extends React.Component { if ((e.keyCode === 13 && e.metaKey) || (e.keyCode === 83 && e.metaKey)) { detail.handleSaveButtonClick() } + if (e.keyCode === 80 && e.metaKey) { + detail.handleTogglePreviewButtonClick() + } + if (e.keyCode === 78 && e.metaKey) { + nav.handleNewPostButtonClick() + e.preventDefault() + } break case IDLE_MODE: if (e.keyCode === 69) { @@ -99,7 +106,7 @@ class HomePage extends React.Component { list.selectNextArticle() } - if (e.keyCode === 65 || e.keyCode === 13 && e.metaKey) { + if (e.keyCode === 65 || (e.keyCode === 13 && e.metaKey) || (e.keyCode === 78 && e.metaKey)) { nav.handleNewPostButtonClick() e.preventDefault() } @@ -257,7 +264,8 @@ HomePage.propTypes = { folder: PropTypes.array, tag: PropTypes.array, text: PropTypes.array - }) + }), + tags: PropTypes.array } export default connect(remap)(HomePage) diff --git a/browser/main/HomePage/ArticleDetail.js b/browser/main/HomePage/ArticleDetail.js index c7daaa9e..4a4b7f0d 100644 --- a/browser/main/HomePage/ArticleDetail.js +++ b/browser/main/HomePage/ArticleDetail.js @@ -25,6 +25,9 @@ import TagSelect from 'boost/components/TagSelect' import ModeSelect from 'boost/components/ModeSelect' import activityRecord from 'boost/activityRecord' +const electron = require('electron') +const clipboard = electron.clipboard + const BRAND_COLOR = '#18AF90' const editDeleteTutorialElement = ( @@ -84,6 +87,10 @@ const modeSelectTutorialElement = ( ) +function notify (...args) { + return new window.Notification(...args) +} + function makeInstantArticle (article) { return Object.assign({}, article) } @@ -154,6 +161,13 @@ export default class ArticleDetail extends React.Component { ) } + handleClipboardButtonClick (e) { + clipboard.writeText(this.props.activeArticle.content) + notify('Saved to Clipboard!', { + body: 'Paste it wherever you want!' + }) + } + handleEditButtonClick (e) { let { dispatch } = this.props dispatch(switchMode(EDIT_MODE)) @@ -185,8 +199,13 @@ export default class ArticleDetail extends React.Component { : ( Not tagged yet ) : null + let folder = _.findWhere(folders, {key: activeArticle.FolderKey}) + let title = activeArticle.title.trim().length === 0 + ? (Untitled) + : activeArticle.title + return (
{this.state.openDeleteConfirmMenu @@ -214,6 +233,9 @@ export default class ArticleDetail extends React.Component {
{tags}
+ @@ -232,7 +254,7 @@ export default class ArticleDetail extends React.Component {
-
{activeArticle.title}
+
{title}
{activeArticle.mode === 'markdown' ? @@ -265,8 +287,12 @@ export default class ArticleDetail extends React.Component { delete newArticle.status newArticle.updatedAt = new Date() + newArticle.title = newArticle.title.trim() if (newArticle.createdAt == null) { newArticle.createdAt = new Date() + if (newArticle.title.length === 0) { + newArticle.title = `Created at ${moment(newArticle.createdAt).format('YYYY/MM/DD HH:mm')}` + } activityRecord.emit('ARTICLE_CREATE') } else { activityRecord.emit('ARTICLE_UPDATE') @@ -408,7 +434,9 @@ export default class ArticleDetail extends React.Component { } handleTogglePreviewButtonClick (e) { - this.setState({previewMode: !this.state.previewMode}) + if (this.state.article.mode === 'markdown') { + this.setState({previewMode: !this.state.previewMode}) + } } handleTitleKeyDown (e) { @@ -453,18 +481,36 @@ export default class ArticleDetail extends React.Component {
{ this.state.article.mode === 'markdown' - ? () + ? () : null } - - + +
- this.handleTitleKeyDown(e)} placeholder='Title' ref='title' value={this.state.article.title} onChange={e => this.handleTitleChange(e)}/> + this.handleTitleKeyDown(e)} + placeholder={this.state.article.createdAt == null + ? `Created at ${moment().format('YYYY/MM/DD HH:mm')}` + : 'Title'} + ref='title' + value={this.state.article.title} + onChange={e => this.handleTitleChange(e)} + />
Not tagged yet) let folder = _.findWhere(folders, {key: article.FolderKey}) + let title = article.status !== NEW + ? article.title.trim().length === 0 + ? (Untitled) + : article.title + : '(New article)' + return (
this.handleArticleClick(article)(e)} className={'articleItem' + (activeArticle.key === article.key ? ' active' : '')}> @@ -91,7 +97,7 @@ export default class ArticleList extends React.Component { {article.status != null ? article.status : moment(article.updatedAt).fromNow()}
-
{article.status !== NEW ? article.title : '(New article)'}
+
{title}
{tagElements}
diff --git a/browser/main/HomePage/ArticleNavigator.js b/browser/main/HomePage/ArticleNavigator.js index f3721e60..269d528f 100644 --- a/browser/main/HomePage/ArticleNavigator.js +++ b/browser/main/HomePage/ArticleNavigator.js @@ -1,6 +1,6 @@ import React, { PropTypes } from 'react' import { findWhere } from 'lodash' -import { setSearchFilter, switchFolder, switchMode, switchArticle, updateArticle, EDIT_MODE } from 'boost/actions' +import { setSearchFilter, switchFolder, switchMode, switchArticle, updateArticle, clearNewArticle, EDIT_MODE } from 'boost/actions' import { openModal } from 'boost/modal' import FolderMark from 'boost/components/FolderMark' import Preferences from 'boost/components/modal/Preferences' @@ -85,6 +85,7 @@ export default class ArticleNavigator extends React.Component { status: 'NEW' } + dispatch(clearNewArticle()) dispatch(updateArticle(newArticle)) dispatch(switchArticle(newArticle.key, true)) dispatch(switchMode(EDIT_MODE)) diff --git a/browser/main/HomePage/ArticleTopBar.js b/browser/main/HomePage/ArticleTopBar.js index 62880bc7..bcfba047 100644 --- a/browser/main/HomePage/ArticleTopBar.js +++ b/browser/main/HomePage/ArticleTopBar.js @@ -35,18 +35,33 @@ export default class ArticleTopBar extends React.Component { super(props) this.state = { - isTooltipHidden: true + isTooltipHidden: true, + isLinksDropdownOpen: false } } componentDidMount () { this.searchInput = ReactDOM.findDOMNode(this.refs.searchInput) + this.linksButton = ReactDOM.findDOMNode(this.refs.links) + this.showLinksDropdown = e => { + e.preventDefault() + e.stopPropagation() + if (!this.state.isLinksDropdownOpen) { + this.setState({isLinksDropdownOpen: true}) + } + } + this.linksButton.addEventListener('click', this.showLinksDropdown) + this.hideLinksDropdown = e => { + if (this.state.isLinksDropdownOpen) { + this.setState({isLinksDropdownOpen: false}) + } + } + document.addEventListener('click', this.hideLinksDropdown) } componentWillUnmount () { - this.searchInput.removeEventListener('keydown', this.showTooltip) - this.searchInput.removeEventListener('focus', this.showTooltip) - this.searchInput.removeEventListener('blur', this.showTooltip) + document.removeEventListener('click', this.hideLinksDropdown) + this.linksButton.removeEventListener('click', this.showLinksDropdown()) } handleTooltipRequest (e) { @@ -118,8 +133,11 @@ export default class ArticleTopBar extends React.Component { : null }
- - Search by tag : #{'{string}'}
- - Search by folder : /{'{folder_name}'} +
    +
  • - Search by tag : #{'{string}'}
  • +
  • - Search by folder : /{'{folder_name}'}
  • +
  • exact match : //{'{folder_name}'}
  • +
@@ -129,10 +147,23 @@ export default class ArticleTopBar extends React.Component {
- + - Boost official page - + + { + this.state.isLinksDropdownOpen + ? ( +
+ + Boost official page + + + Discuss + +
+ ) + : null + }
{status.isTutorialOpen ? ( diff --git a/browser/styles/main/HomeContainer/components/ArticleDetail.styl b/browser/styles/main/HomeContainer/components/ArticleDetail.styl index 2f4ae10c..e64e5da6 100644 --- a/browser/styles/main/HomeContainer/components/ArticleDetail.styl +++ b/browser/styles/main/HomeContainer/components/ArticleDetail.styl @@ -323,7 +323,8 @@ iptFocusBorderColor = #369DCD right 15px font-size 24px line-height 60px - white-space nowrap overflow-x auto overflow-y hidden + small + color #AAA diff --git a/browser/styles/main/HomeContainer/components/ArticleList.styl b/browser/styles/main/HomeContainer/components/ArticleList.styl index 6617773a..7d406c25 100644 --- a/browser/styles/main/HomeContainer/components/ArticleList.styl +++ b/browser/styles/main/HomeContainer/components/ArticleList.styl @@ -48,6 +48,8 @@ articleItemColor = #777 left 19px right 0 overflow ellipsis + small + color #AAA .bottom padding 5px 0 overflow-x auto diff --git a/browser/styles/main/HomeContainer/components/ArticleNavigator.styl b/browser/styles/main/HomeContainer/components/ArticleNavigator.styl index af61cf3d..93fd515f 100644 --- a/browser/styles/main/HomeContainer/components/ArticleNavigator.styl +++ b/browser/styles/main/HomeContainer/components/ArticleNavigator.styl @@ -14,7 +14,7 @@ articleCount = #999 .userProfileName color brandColor font-size 28px - padding 6px 0 0 10px + padding 6px 37px 0 10px white-space nowrap text-overflow ellipsis overflow hidden diff --git a/browser/styles/main/HomeContainer/components/ArticleTopBar.styl b/browser/styles/main/HomeContainer/components/ArticleTopBar.styl index 1d53d822..6397e74a 100644 --- a/browser/styles/main/HomeContainer/components/ArticleTopBar.styl +++ b/browser/styles/main/HomeContainer/components/ArticleTopBar.styl @@ -62,6 +62,13 @@ infoBtnActiveBgColor = #3A3A3A opacity 1 &.hide opacity 0 + ul + li:last-child + line-height 10px + margin-bottom 3px + small + font-size 10px + margin-left 15px input absolute top left width 350px @@ -140,17 +147,33 @@ infoBtnActiveBgColor = #3A3A3A .tooltip opacity 1 - &>.logo + &>.linksBtn display block position absolute top 8px right 15px opacity 0.7 - .tooltip - tooltip() - margin-top 44px - margin-left -120px &:hover opacity 1 .tooltip opacity 1 + &>.links-dropdown + position fixed + z-index 50 + right 10px + top 40px + background-color transparentify(invBackgroundColor, 80%) + padding 5px 0 + .links-item + padding 0 10px + height 33px + width 100% + display block + line-height 33px + text-decoration none + color white + &:hover + background-color transparentify(lighten(invBackgroundColor, 30%), 80%) + + + diff --git a/finder.js b/finder.js index 3ec97b6a..e0d12bf2 100755 --- a/finder.js +++ b/finder.js @@ -36,7 +36,7 @@ app.on('ready', function () { } })) trayMenu.append(new MenuItem({ - label: 'Open Finder', + label: 'Open Finder window', click: function () { finderWindow.show() } diff --git a/lib/components/modal/CreateNewFolder.js b/lib/components/modal/CreateNewFolder.js index 2686dafe..616f7692 100644 --- a/lib/components/modal/CreateNewFolder.js +++ b/lib/components/modal/CreateNewFolder.js @@ -1,4 +1,5 @@ import React, { PropTypes } from 'react' +import ReactDOM from 'react-dom' import linkState from 'boost/linkState' import { createFolder } from 'boost/actions' import store from 'boost/store' @@ -15,6 +16,10 @@ export default class CreateNewFolder extends React.Component { } } + componentDidMount () { + ReactDOM.findDOMNode(this.refs.folderName).focus() + } + handleCloseButton (e) { this.props.close() } @@ -84,7 +89,7 @@ export default class CreateNewFolder extends React.Component {
Create new folder
- this.handleKeyDown(e)} className='ipt' type='text' valueLink={this.linkState('name')} placeholder='Enter folder name'/> + this.handleKeyDown(e)} className='ipt' type='text' valueLink={this.linkState('name')} placeholder='Enter folder name'/>
{colorElements}
diff --git a/lib/components/modal/EditedAlert.js b/lib/components/modal/EditedAlert.js index fd60258d..5b487bb3 100644 --- a/lib/components/modal/EditedAlert.js +++ b/lib/components/modal/EditedAlert.js @@ -1,8 +1,13 @@ import React, { PropTypes } from 'react' +import ReactDOM from 'react-dom' import store from 'boost/store' import { unlockStatus, clearNewArticle } from 'boost/actions' export default class EditedAlert extends React.Component { + componentDidMount () { + ReactDOM.findDOMNode(this.refs.no).focus() + } + handleNoButtonClick (e) { this.props.close() } @@ -22,8 +27,8 @@ export default class EditedAlert extends React.Component {
Do you really want to leave without finishing?
- - + +
) diff --git a/package.json b/package.json index f06caf4a..827a3e4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "boost", - "version": "0.4.2", + "version": "0.4.3", "description": "Boost App", "main": "index.js", "scripts": {