1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

Merge branch 'dev'

* dev:
  bump version
  Folder create modalを出したら、まっすぐName inputをFocusする
  編集警告が出ている時にCode editorがキー入力を認識する問題解決
  External link動きDebug
  add copy button
  External link用のDropdown menu追加
  コードを綺麗に
  Titleがなかったら灰色でUntitleと出す
  新規投稿 Cmd + n / Preview Cmd + P 追加
  articleのタイトルの基本タイトル追加 / 何も書かれていない時にUntitled labelをだす
  Finderのvisibile on all workspaces解除
  Searchbar tooltip changed(add exact match)
  change tray menu label(Open Finder => Open FInder window)
  Main windowの visible on all worpspace解除

Conflicts:
	package.json
This commit is contained in:
Rokt33r
2015-12-01 00:10:15 +09:00
15 changed files with 161 additions and 37 deletions

View File

@@ -25,6 +25,4 @@ finderWindow.on('blur', function () {
finderWindow.hide()
})
finderWindow.setVisibleOnAllWorkspaces(true)
module.exports = finderWindow

View File

@@ -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()
})

View File

@@ -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)

View File

@@ -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 = (
</svg>
)
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 {
: (
<span className='noTags'>Not tagged yet</span>
) : null
let folder = _.findWhere(folders, {key: activeArticle.FolderKey})
let title = activeArticle.title.trim().length === 0
? <small>(Untitled)</small>
: activeArticle.title
return (
<div className='ArticleDetail idle'>
{this.state.openDeleteConfirmMenu
@@ -214,6 +233,9 @@ export default class ArticleDetail extends React.Component {
<div className='tags'><i className='fa fa-fw fa-tags'/>{tags}</div>
</div>
<div className='right'>
<button onClick={e => this.handleClipboardButtonClick(e)} className='editBtn'>
<i className='fa fa-fw fa-clipboard'/><span className='tooltip'>Copy to clipboard</span>
</button>
<button onClick={e => this.handleEditButtonClick(e)} className='editBtn'>
<i className='fa fa-fw fa-edit'/><span className='tooltip'>Edit (e)</span>
</button>
@@ -232,7 +254,7 @@ export default class ArticleDetail extends React.Component {
<div className='detailPanel'>
<div className='header'>
<ModeIcon className='mode' mode={activeArticle.mode}/>
<div className='title'>{activeArticle.title}</div>
<div className='title'>{title}</div>
</div>
{activeArticle.mode === 'markdown'
? <MarkdownPreview content={activeArticle.content}/>
@@ -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 {
<div className='right'>
{
this.state.article.mode === 'markdown'
? (<button className='preview' onClick={e => this.handleTogglePreviewButtonClick(e)}>{!this.state.previewMode ? 'Preview' : 'Edit'}</button>)
? (<button className='preview' onClick={e => this.handleTogglePreviewButtonClick(e)}>
{
!this.state.previewMode
? 'Preview'
: 'Edit'
}
</button>)
: null
}
<button onClick={e => this.handleCancelButtonClick(e)}>Cancel</button>
<button onClick={e => this.handleSaveButtonClick(e)} className='primary'>Save</button>
<button onClick={e => this.handleCancelButtonClick(e)}>
Cancel
</button>
<button onClick={e => this.handleSaveButtonClick(e)} className='primary'>
Save
</button>
</div>
</div>
<div className='detailBody'>
<div className='detailPanel'>
<div className='header'>
<div className='title'>
<input onKeyDown={e => this.handleTitleKeyDown(e)} placeholder='Title' ref='title' value={this.state.article.title} onChange={e => this.handleTitleChange(e)}/>
<input
onKeyDown={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)}
/>
</div>
<ModeSelect
ref='mode'

View File

@@ -80,6 +80,12 @@ export default class ArticleList extends React.Component {
: (<span>Not tagged yet</span>)
let folder = _.findWhere(folders, {key: article.FolderKey})
let title = article.status !== NEW
? article.title.trim().length === 0
? <small>(Untitled)</small>
: article.title
: '(New article)'
return (
<div key={'article-' + article.key}>
<div onClick={e => this.handleArticleClick(article)(e)} className={'articleItem' + (activeArticle.key === article.key ? ' active' : '')}>
@@ -91,7 +97,7 @@ export default class ArticleList extends React.Component {
<span className='updatedAt'>{article.status != null ? article.status : moment(article.updatedAt).fromNow()}</span>
</div>
<div className='middle'>
<ModeIcon className='mode' mode={article.mode}/> <div className='title'>{article.status !== NEW ? article.title : '(New article)'}</div>
<ModeIcon className='mode' mode={article.mode}/> <div className='title'>{title}</div>
</div>
<div className='bottom'>
<div className='tags'><i className='fa fa-fw fa-tags'/>{tagElements}</div>

View File

@@ -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))

View File

@@ -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
}
<div className={'tooltip' + (this.state.isTooltipHidden ? ' hide' : '')}>
- Search by tag : #{'{string}'}<br/>
- Search by folder : /{'{folder_name}'}
<ul>
<li>- Search by tag : #{'{string}'}</li>
<li>- Search by folder : /{'{folder_name}'}</li>
<li><small>exact match : //{'{folder_name}'}</small></li>
</ul>
</div>
</div>
@@ -129,10 +147,23 @@ export default class ArticleTopBar extends React.Component {
<div className='right'>
<button onClick={e => this.handleTutorialButtonClick(e)}>?<span className='tooltip'>How to use</span>
</button>
<ExternalLink className='logo' href='http://b00st.io'>
<a ref='links' className='linksBtn' href>
<img src='../../resources/favicon-230x230.png' width='44' height='44'/>
<span className='tooltip'>Boost official page</span>
</ExternalLink>
</a>
{
this.state.isLinksDropdownOpen
? (
<div className='links-dropdown'>
<ExternalLink className='links-item' href='https://b00st.io'>
<i className='fa fa-fw fa-home'/>Boost official page
</ExternalLink>
<ExternalLink className='links-item' href='https://github.com/BoostIO/boost-app-discussions/issues'>
<i className='fa fa-fw fa-bullhorn'/> Discuss
</ExternalLink>
</div>
)
: null
}
</div>
{status.isTutorialOpen ? (

View File

@@ -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

View File

@@ -48,6 +48,8 @@ articleItemColor = #777
left 19px
right 0
overflow ellipsis
small
color #AAA
.bottom
padding 5px 0
overflow-x auto

View File

@@ -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

View File

@@ -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%)

View File

@@ -36,7 +36,7 @@ app.on('ready', function () {
}
}))
trayMenu.append(new MenuItem({
label: 'Open Finder',
label: 'Open Finder window',
click: function () {
finderWindow.show()
}

View File

@@ -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 {
<div className='title'>Create new folder</div>
<input onKeyDown={e => this.handleKeyDown(e)} className='ipt' type='text' valueLink={this.linkState('name')} placeholder='Enter folder name'/>
<input ref='folderName' onKeyDown={e => this.handleKeyDown(e)} className='ipt' type='text' valueLink={this.linkState('name')} placeholder='Enter folder name'/>
<div className='colorSelect'>
{colorElements}
</div>

View File

@@ -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 {
<div className='message'>Do you really want to leave without finishing?</div>
<div className='control'>
<button onClick={e => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close'/> No</button>
<button onClick={e => this.handleYesButtonClick(e)} className='primary'><i className='fa fa-fw fa-check'/> Yes</button>
<button ref='no' onClick={e => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close'/> No</button>
<button ref='yes' onClick={e => this.handleYesButtonClick(e)} className='primary'><i className='fa fa-fw fa-check'/> Yes</button>
</div>
</div>
)

View File

@@ -1,6 +1,6 @@
{
"name": "boost",
"version": "0.4.2",
"version": "0.4.3",
"description": "Boost App",
"main": "index.js",
"scripts": {