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

Merge branch 'dev'

* dev:
  temporary setup
  0.4.5
  emit empty event(to create new record of today if not exists)
  MAIN_DETAIL_COPY, *_BY_SYNTAX, CLIENT_VERSION 追加
  debug ModeSelect component
  fix markdown style a little more
  Markdown styleを少し改善
  bump up version to 0.4.5 and change codesign path
  自動的にスクロールを合わせてくれる
  fix release path
  add electron-builder & modify deploy scripts
  bump up Ace editor
  Github release

Conflicts:
	package.json
This commit is contained in:
Rokt33r
2015-12-08 18:53:26 +09:00
10 changed files with 143 additions and 47 deletions

3
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.env
node_modules/*
!node_modules/boost
Boost-darwin-x64/
backup/
dist/
compiled

View File

@@ -162,6 +162,7 @@ export default class ArticleDetail extends React.Component {
}
handleClipboardButtonClick (e) {
activityRecord.emit('MAIN_DETAIL_COPY')
clipboard.writeText(this.props.activeArticle.content)
notify('Saved to Clipboard!', {
body: 'Paste it wherever you want!'
@@ -293,9 +294,9 @@ export default class ArticleDetail extends React.Component {
if (newArticle.title.length === 0) {
newArticle.title = `Created at ${moment(newArticle.createdAt).format('YYYY/MM/DD HH:mm')}`
}
activityRecord.emit('ARTICLE_CREATE')
activityRecord.emit('ARTICLE_CREATE', {mode: newArticle.mode})
} else {
activityRecord.emit('ARTICLE_UPDATE')
activityRecord.emit('ARTICLE_UPDATE', {mode: newArticle.mode})
}
dispatch(updateArticle(newArticle))
@@ -435,7 +436,34 @@ export default class ArticleDetail extends React.Component {
handleTogglePreviewButtonClick (e) {
if (this.state.article.mode === 'markdown') {
this.setState({previewMode: !this.state.previewMode})
if (!this.state.previewMode) {
let cursorPosition = this.refs.code.getCursorPosition()
let firstVisibleRow = this.refs.code.getFirstVisibleRow()
this.setState({
previewMode: true,
cursorPosition,
firstVisibleRow
}, function () {
let previewEl = ReactDOM.findDOMNode(this.refs.preview)
let anchors = previewEl.querySelectorAll('.lineAnchor')
for (let i = 0; i < anchors.length; i++) {
if (parseInt(anchors[i].dataset.key, 10) > cursorPosition.row || i === anchors.length - 1) {
var targetAnchor = anchors[i > 0 ? i - 1 : 0]
previewEl.scrollTop = targetAnchor.offsetTop - 100
break
}
}
})
} else {
this.setState({
previewMode: false
}, function () {
console.log(this.state.cursorPosition)
this.refs.code.moveCursorTo(this.state.cursorPosition.row, this.state.cursorPosition.column)
this.refs.code.scrollToLine(this.state.firstVisibleRow)
this.refs.code.editor.focus()
})
}
}
}
@@ -524,7 +552,7 @@ export default class ArticleDetail extends React.Component {
</div>
{this.state.previewMode
? <MarkdownPreview content={this.state.article.content}/>
? <MarkdownPreview ref='preview' content={this.state.article.content}/>
: (<CodeEditor
ref='code'
onChange={(e, value) => this.handleContentChange(e, value)}

View File

@@ -1,36 +1,38 @@
marked()
h1, h2, h3, h4, h5, h6, p
&:first-child
margin-top 0
hr
border-top none
border-bottom solid 1px borderColor
margin 15px 0
h1, h2, h3, h4, h5, h6
margin 0 0 15px
font-weight 600
* + h1, * + h2, * + h3, * + h4, * + h5, * + h6
margin-top 25px
h1
font-size 2em
border-bottom solid 2px borderColor
margin 0.33em auto 0.67em
line-height 2.333em
h2
font-size 1.5em
margin 0.42em auto 0.83em
font-size 1.66em
line-height 2.07em
h3
font-size 1.17em
margin 0.5em auto 1em
font-size 1.33em
line-height 1.6625em
h4
font-size 1em
margin 0.67em auto 1.33em
font-size 1.15em
line-height 1.4375em
h5
font-size 0.83em
margin 0.84em auto 1.67em
font-size 1em
line-height 1.25em
h6
font-size 0.67em
margin 1.16em auto 2.33em
h1, h2, h3, h4, h5, h6
font-weight 700
line-height 1.8em
font-size 0.8em
line-height 1em
* + p, * + blockquote, * + ul, * + ol, * + pre
margin-top 15px
p
line-height 1.8em
margin 15px 0 25px
line-height 1.9em
margin 0 0 15px
img
max-width 100%
strong
@@ -41,15 +43,17 @@ marked()
text-decoration line-through
blockquote
border-left solid 4px brandBorderColor
margin 15px 0 25px
margin 0 0 15px
padding 0 25px
ul
list-style-type disc
padding-left 35px
margin-bottom 35px
margin-bottom 15px
li
display list-item
line-height 1.8em
&>li>ul, &>li>ol
margin 0
&>li>ul
list-style-type circle
&>li>ul
@@ -57,10 +61,12 @@ marked()
ol
list-style-type decimal
padding-left 35px
margin-bottom 35px
margin-bottom 15px
li
display list-item
line-height 1.8em
&>li>ul, &>li>ol
margin 0
code
font-family Monaco, Menlo, 'Ubuntu Mono', Consolas, source-code-pro, monospace;
padding 2px 4px
@@ -70,15 +76,19 @@ marked()
color black
text-decoration none
background-color #F6F6F6
margin-right 2px
* + code
margin-left 2px
pre
padding 5px
border solid 1px borderColor
border-radius 5px
overflow-x auto
margin 15px 0 25px
margin 0 0 15px
background-color #F6F6F6
line-height 1.35em
&>code
margin 0
padding 0
border none
border-radius 0

12
builder-config.json Normal file
View File

@@ -0,0 +1,12 @@
{
"osx" : {
"title": "Boost Installer",
// "background": "resources/background.png",
"icon": "resources/app.icns",
"icon-size": 80,
"contents": [
{ "x": 438, "y": 344, "type": "link", "path": "/Applications" },
{ "x": 192, "y": 344, "type": "file" }
]
}
}

View File

@@ -4,6 +4,9 @@ import keygen from 'boost/keygen'
import dataStore from 'boost/dataStore'
import { request, WEB_URL } from 'boost/api'
const electron = require('electron')
const version = electron.remote.app.getVersion()
function isSameDate (a, b) {
a = moment(a).utcOffset(+540).format('YYYYMMDD')
b = moment(b).utcOffset(+540).format('YYYYMMDD')
@@ -16,6 +19,7 @@ export function init () {
if (records == null) {
saveAllRecords([])
}
emit(null)
postRecords()
if (window != null) {
@@ -81,7 +85,7 @@ export function postRecords (data) {
})
}
export function emit (type, data) {
export function emit (type, data = {}) {
let records = getAllRecords()
let index = _.findIndex(records, record => {
@@ -94,7 +98,6 @@ export function emit (type, data) {
records.push(todayRecord)
}
else todayRecord = records[index]
console.log(type)
switch (type) {
case 'ARTICLE_CREATE':
case 'ARTICLE_UPDATE':
@@ -104,6 +107,7 @@ export function emit (type, data) {
case 'FOLDER_DESTROY':
case 'FINDER_OPEN':
case 'FINDER_COPY':
case 'MAIN_DETAIL_COPY':
todayRecord[type] = todayRecord[type] == null
? 1
: todayRecord[type] + 1
@@ -111,9 +115,26 @@ export function emit (type, data) {
break
}
// Count ARTICLE_CREATE and ARTICLE_UPDATE again by syntax
if ((type === 'ARTICLE_CREATE' || type === 'ARTICLE_UPDATE') && data.mode != null) {
let recordKey = type + '_BY_SYNTAX'
if (todayRecord[recordKey] == null) todayRecord[recordKey] = {}
todayRecord[recordKey][data.mode] = todayRecord[recordKey][data.mode] == null
? 1
: todayRecord[recordKey][data.mode] + 1
}
let storeData = dataStore.getData()
todayRecord.FOLDER_COUNT = _.isArray(storeData.folders) ? storeData.folders.length : 0
todayRecord.ARTICLE_COUNT = _.isArray(storeData.articles) ? storeData.articles.length : 0
todayRecord.CLIENT_VERSION = version
todayRecord.SYNTAX_COUNT = storeData.articles.reduce((sum, article) => {
if (sum[article.mode] == null) sum[article.mode] = 1
else sum[article.mode]++
return sum
}, {})
saveAllRecords(records)
}

View File

@@ -30,6 +30,7 @@ module.exports = React.createClass({
editor.renderer.setShowGutter(true)
editor.setTheme('ace/theme/xcode')
editor.clearSelection()
editor.moveCursorTo(0, 0)
editor.setReadOnly(!!this.props.readOnly)
@@ -50,16 +51,14 @@ module.exports = React.createClass({
this.props.onChange(e, value)
}
}.bind(this))
this.setState({editor: editor})
},
componentDidUpdate: function (prevProps) {
if (this.state.editor.getValue() !== this.props.code) {
this.state.editor.setValue(this.props.code)
this.state.editor.clearSelection()
if (this.editor.getValue() !== this.props.code) {
this.editor.setValue(this.props.code)
this.editor.clearSelection()
}
if (prevProps.mode !== this.props.mode) {
var session = this.state.editor.getSession()
var session = this.editor.getSession()
let mode = _.findWhere(modes, {name: this.props.mode})
let syntaxMode = mode != null
? mode.mode
@@ -67,6 +66,18 @@ module.exports = React.createClass({
session.setMode('ace/mode/' + syntaxMode)
}
},
getFirstVisibleRow: function () {
return this.editor.getFirstVisibleRow()
},
getCursorPosition: function () {
return this.editor.getCursorPosition()
},
moveCursorTo: function (row, col) {
this.editor.moveCursorTo(row, col)
},
scrollToLine: function (num) {
this.editor.scrollToLine(num, false, false)
},
render: function () {
return (
<div ref='target' className={this.props.className == null ? 'CodeEditor' : 'CodeEditor ' + this.props.className}></div>

View File

@@ -161,8 +161,8 @@ export default class ModeSelect extends React.Component {
let filteredOptions = modes
.filter(mode => {
let search = this.state.search
let nameMatched = mode.name.match(search)
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
let nameMatched = mode.name.match(_.escapeRegExp(search))
let aliasMatched = _.some(mode.alias, alias => alias.match(_.escapeRegExp(search)))
return nameMatched || aliasMatched
})
.map((mode, index) => {

View File

@@ -8,20 +8,31 @@ var md = markdownit({
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value;
return hljs.highlight(lang, str).value
} catch (__) {}
}
try {
return hljs.highlightAuto(str).value;
return hljs.highlightAuto(str).value
} catch (__) {}
return ''; // use external default escaping
return ''
}
})
md.use(emoji)
let originalRenderToken = md.renderer.renderToken
md.renderer.renderToken = function renderToken (tokens, idx, options) {
let token = tokens[idx]
let result = originalRenderToken.call(md.renderer, tokens, idx, options)
if (token.map != null) {
return result + '<a class=\'lineAnchor\' data-key=\'' + token.map[0] + '\'></a>'
}
return result
}
export default function markdown (content) {
if (content == null) content = ''
return md.render(content.toString())
}

View File

@@ -68,7 +68,7 @@ const modes = [
{
name: 'csharp',
label: 'C#',
alias: ['cs'],
alias: ['cs', 'c#'],
mode: 'csharp'
},
{

View File

@@ -1,19 +1,22 @@
{
"name": "boost",
"version": "0.4.4",
"version": "0.4.5",
"description": "Boost App",
"main": "index.js",
"scripts": {
"start": "BOOST_ENV=development electron ./main.js",
"webpack": "webpack-dev-server --hot --inline --config webpack.config.js",
"compile": "NODE_ENV=production webpack --config webpack.config.production.js",
"build": "electron-packager ./ Boost --app-version=$npm_package_version $npm_package_config_platform $npm_package_config_version $npm_package_config_ignore --overwrite --asar",
"codesign": "codesign --verbose --deep --force --sign \"MAISIN solutions Inc.\" Boost-darwin-x64/Boost.app"
"pack:osx": "electron-packager ./ Boost --app-version=$npm_package_version $npm_package_config_platform $npm_package_config_version $npm_package_config_ignore --overwrite --out=\"dist\"",
"codesign": "codesign --verbose --deep --force --sign \"MAISIN solutions Inc.\" dist/Boost-darwin-x64/Boost.app",
"build:osx": "electron-builder \"dist/Boost-darwin-x64/Boost.app\" --platform=osx --out=\"dist\" --config=\"./builder-config.json\"",
"release": "electron-release --app=\"dist/Boost-darwin-x64/Boost.app\" --token=$(cat .env/.github-token) --repo=\"BoostIO/boost-releases\""
},
"config": {
"version": "--version=0.35.1 --app-bundle-id=com.maisin.boost",
"version": "--version=0.35.3 --app-bundle-id=com.maisin.boost",
"platform": "--platform=darwin --arch=x64 --prune --icon=resources/app.icns",
"ignore": "--ignore=Boost-darwin-x64 --ignore=node_modules/devicon/icons --ignore=submodules/ace/(?!src-min)|submodules/ace/(?=src-min-noconflict)"
"ignore": "--ignore=.env --ignore=Boost-darwin-x64 --ignore=node_modules/devicon/icons --ignore=submodules/ace/(?!src-min)|submodules/ace/(?=src-min-noconflict)"
},
"repository": {
"type": "git",
@@ -56,6 +59,7 @@
"css-loader": "^0.19.0",
"electron-packager": "^5.1.0",
"electron-prebuilt": "^0.35.1",
"electron-release": "^2.2.0",
"nib": "^1.1.0",
"react": "^0.14.0",
"react-dom": "^0.14.0",