mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
Stream EPIPEエラー解決、データはこれからJSON保存
This commit is contained in:
@@ -28,3 +28,12 @@ export function refreshData (data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
SELECT_ARTICLE,
|
||||
SEARCH_ARTICLE,
|
||||
REFRESH_DATA,
|
||||
selectArticle,
|
||||
searchArticle,
|
||||
refreshData
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ import { createStore } from 'redux'
|
||||
import FinderInput from './FinderInput'
|
||||
import FinderList from './FinderList'
|
||||
import FinderDetail from './FinderDetail'
|
||||
import { selectArticle, searchArticle, refreshData } from './actions'
|
||||
import actions, { selectArticle, searchArticle } from './actions'
|
||||
import _ from 'lodash'
|
||||
import dataStore from 'boost/dataStore'
|
||||
|
||||
const electron = require('electron')
|
||||
const { remote, clipboard } = electron
|
||||
const ipc = electron.ipcRenderer
|
||||
|
||||
var hideFinder = remote.getGlobal('hideFinder')
|
||||
|
||||
@@ -212,16 +212,19 @@ function remap (state) {
|
||||
var Finder = connect(remap)(FinderMain)
|
||||
var store = createStore(reducer)
|
||||
|
||||
window.onfocus = e => {
|
||||
ipc.send('request-data')
|
||||
function refreshData () {
|
||||
let data = dataStore.getData()
|
||||
store.dispatch(actions.refreshData(data))
|
||||
}
|
||||
|
||||
ipc.on('refresh-data', function (e, data) {
|
||||
store.dispatch(refreshData(data))
|
||||
})
|
||||
window.onfocus = e => {
|
||||
refreshData()
|
||||
}
|
||||
|
||||
ReactDOM.render((
|
||||
<Provider store={store}>
|
||||
<Finder/>
|
||||
</Provider>
|
||||
), document.getElementById('content'))
|
||||
), document.getElementById('content'), function () {
|
||||
refreshData()
|
||||
})
|
||||
|
||||
@@ -11,7 +11,6 @@ require('../styles/main/index.styl')
|
||||
import { openModal } from 'boost/modal'
|
||||
import Tutorial from 'boost/components/modal/Tutorial'
|
||||
import activityRecord from 'boost/activityRecord'
|
||||
import dataStore from 'boost/dataStore'
|
||||
const electron = require('electron')
|
||||
const ipc = electron.ipcRenderer
|
||||
|
||||
@@ -30,10 +29,6 @@ ipc.on('notify', function (e, payload) {
|
||||
})
|
||||
})
|
||||
|
||||
ipc.on('request-data', function () {
|
||||
ipc.send('refresh-data', dataStore.getData())
|
||||
})
|
||||
|
||||
let routes = (
|
||||
<Route path='/' component={MainPage}>
|
||||
<IndexRoute name='home' component={HomePage}/>
|
||||
|
||||
14
finder.js
14
finder.js
@@ -3,7 +3,6 @@ const app = electron.app
|
||||
const Tray = electron.Tray
|
||||
const Menu = electron.Menu
|
||||
const MenuItem = electron.MenuItem
|
||||
const ipc = electron.ipcMain
|
||||
|
||||
process.stdin.setEncoding('utf8')
|
||||
|
||||
@@ -11,14 +10,14 @@ console.log = function () {
|
||||
process.stdout.write(JSON.stringify({
|
||||
type: 'log',
|
||||
data: JSON.stringify(Array.prototype.slice.call(arguments).join(' '))
|
||||
}))
|
||||
}), 'utf-8')
|
||||
}
|
||||
|
||||
function emit (type, data) {
|
||||
process.stdout.write(JSON.stringify({
|
||||
type: type,
|
||||
data: JSON.stringify(data)
|
||||
}))
|
||||
}), 'utf-8')
|
||||
}
|
||||
|
||||
var finderWindow
|
||||
@@ -50,10 +49,6 @@ app.on('ready', function () {
|
||||
}))
|
||||
appIcon.setContextMenu(trayMenu)
|
||||
|
||||
ipc.on('request-data', function () {
|
||||
emit('request-data')
|
||||
})
|
||||
|
||||
process.stdin.on('data', function (payload) {
|
||||
try {
|
||||
payload = JSON.parse(payload)
|
||||
@@ -66,13 +61,8 @@ app.on('ready', function () {
|
||||
case 'open-finder':
|
||||
finderWindow.show()
|
||||
break
|
||||
case 'refresh-data':
|
||||
finderWindow.webContents.send('refresh-data', payload.data)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
emit('request-data')
|
||||
})
|
||||
|
||||
global.hideFinder = function () {
|
||||
|
||||
8
index.js
8
index.js
@@ -1,5 +1,9 @@
|
||||
var argv = process.argv.slice(1)
|
||||
if (argv.some(arg => arg.match(/--finder/))) {
|
||||
function isFinderCalled () {
|
||||
var argv = process.argv.slice(1)
|
||||
return argv.some(arg => arg.match(/--finder/))
|
||||
}
|
||||
|
||||
if (isFinderCalled()) {
|
||||
require('./finder.js')
|
||||
} else {
|
||||
require('./main.js')
|
||||
|
||||
@@ -83,158 +83,6 @@ class Preferences extends React.Component {
|
||||
return (<AppSettingTab/>)
|
||||
}
|
||||
}
|
||||
|
||||
// handleProfileSaveButtonClick (e) {
|
||||
// let profileState = this.state.profile
|
||||
// profileState.userInfo.alert = {
|
||||
// type: 'info',
|
||||
// message: 'Sending...'
|
||||
// }
|
||||
// this.setState({profile: profileState}, () => {
|
||||
// let input = {
|
||||
// profileName: profileState.userInfo.profileName,
|
||||
// email: profileState.userInfo.email
|
||||
// }
|
||||
// api.updateUserInfo(input)
|
||||
// .then(res => {
|
||||
// let profileState = this.state.profile
|
||||
// profileState.userInfo.alert = {
|
||||
// type: 'success',
|
||||
// message: 'Successfully done!'
|
||||
// }
|
||||
// this.setState({profile: profileState})
|
||||
// })
|
||||
// .catch(err => {
|
||||
// var message
|
||||
// if (err.status != null) {
|
||||
// message = err.response.body.message
|
||||
// } else if (err.code === 'ECONNREFUSED') {
|
||||
// message = 'Can\'t connect to API server.'
|
||||
// } else throw err
|
||||
|
||||
// let profileState = this.state.profile
|
||||
// profileState.userInfo.alert = {
|
||||
// type: 'error',
|
||||
// message: message
|
||||
// }
|
||||
|
||||
// this.setState({profile: profileState})
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
// handlePasswordSaveButton (e) {
|
||||
// let profileState = this.state.profile
|
||||
|
||||
// if (profileState.password.newPassword !== profileState.password.confirmation) {
|
||||
// profileState.password.alert = {
|
||||
// type: 'error',
|
||||
// message: 'Confirmation doesn\'t match'
|
||||
// }
|
||||
// this.setState({profile: profileState})
|
||||
// return
|
||||
// }
|
||||
|
||||
// profileState.password.alert = {
|
||||
// type: 'info',
|
||||
// message: 'Sending...'
|
||||
// }
|
||||
|
||||
// this.setState({profile: profileState}, () => {
|
||||
// let input = {
|
||||
// password: profileState.password.currentPassword,
|
||||
// newPassword: profileState.password.newPassword
|
||||
// }
|
||||
// api.updatePassword(input)
|
||||
// .then(res => {
|
||||
// let profileState = this.state.profile
|
||||
// profileState.password.alert = {
|
||||
// type: 'success',
|
||||
// message: 'Successfully done!'
|
||||
// }
|
||||
// profileState.password.currentPassword = ''
|
||||
// profileState.password.newPassword = ''
|
||||
// profileState.password.confirmation = ''
|
||||
|
||||
// this.setState({profile: profileState})
|
||||
// })
|
||||
// .catch(err => {
|
||||
// var message
|
||||
// if (err.status != null) {
|
||||
// message = err.response.body.message
|
||||
// } else if (err.code === 'ECONNREFUSED') {
|
||||
// message = 'Can\'t connect to API server.'
|
||||
// } else throw err
|
||||
|
||||
// let profileState = this.state.profile
|
||||
// profileState.password.alert = {
|
||||
// type: 'error',
|
||||
// message: message
|
||||
// }
|
||||
// profileState.password.currentPassword = ''
|
||||
// profileState.password.newPassword = ''
|
||||
// profileState.password.confirmation = ''
|
||||
|
||||
// this.setState({profile: profileState}, () => {
|
||||
// if (this.refs.currentPassword != null) findDOMNode(this.refs.currentPassword).focus()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
// renderProfile () {
|
||||
// let profileState = this.state.profile
|
||||
// return (
|
||||
// <div className='content profile'>
|
||||
// <div className='section userSection'>
|
||||
// <div className='sectionTitle'>User Info</div>
|
||||
// <div className='sectionInput'>
|
||||
// <label>Profile Name</label>
|
||||
// <input valueLink={this.linkState('profile.userInfo.profileName')} type='text'/>
|
||||
// </div>
|
||||
// <div className='sectionInput'>
|
||||
// <label>E-mail</label>
|
||||
// <input valueLink={this.linkState('profile.userInfo.email')} type='text'/>
|
||||
// </div>
|
||||
// <div className='sectionConfirm'>
|
||||
// <button onClick={e => this.handleProfileSaveButtonClick(e)}>Save</button>
|
||||
|
||||
// {this.state.profile.userInfo.alert != null
|
||||
// ? (
|
||||
// <div className={'alert ' + profileState.userInfo.alert.type}>{profileState.userInfo.alert.message}</div>
|
||||
// )
|
||||
// : null}
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div className='section passwordSection'>
|
||||
// <div className='sectionTitle'>Password</div>
|
||||
// <div className='sectionInput'>
|
||||
// <label>Current Password</label>
|
||||
// <input ref='currentPassword' valueLink={this.linkState('profile.password.currentPassword')} type='password' placeholder='Current Password'/>
|
||||
// </div>
|
||||
// <div className='sectionInput'>
|
||||
// <label>New Password</label>
|
||||
// <input valueLink={this.linkState('profile.password.newPassword')} type='password' placeholder='New Password'/>
|
||||
// </div>
|
||||
// <div className='sectionInput'>
|
||||
// <label>Confirmation</label>
|
||||
// <input valueLink={this.linkState('profile.password.confirmation')} type='password' placeholder='Confirmation'/>
|
||||
// </div>
|
||||
// <div className='sectionConfirm'>
|
||||
// <button onClick={e => this.handlePasswordSaveButton(e)}>Save</button>
|
||||
|
||||
// {profileState.password.alert != null
|
||||
// ? (
|
||||
// <div className={'alert ' + profileState.password.alert.type}>{profileState.password.alert.message}</div>
|
||||
// )
|
||||
// : null}
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
Preferences.propTypes = {
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
import keygen from 'boost/keygen'
|
||||
const electron = require('electron')
|
||||
const remote = electron.remote
|
||||
const jetpack = require('fs-jetpack')
|
||||
const path = require('path')
|
||||
|
||||
let defaultContent = 'Boost is a brand new note App for programmers.\n\n> 下に日本語版があります。\n\n# \u25CEfeature\n\nBoost has some preponderant functions for efficient engineer\'s task.See some part of it.\n\n1. classify information by\u300CFolders\u300D\n2. deal with great variety of syntax\n3. Finder function\n\n\uFF0A\u3000\uFF0A\u3000\uFF0A\u3000\uFF0A\n\n# 1. classify information by \u300CFolders\u300D- access the information you needed easily.\n\n\u300CFolders\u300D which on the left side bar. Press plus button now. flexible way of classification.\n- Create Folder every language or flamework\n- Make Folder for your own casual memos\n\n# 2. Deal with a great variety of syntax \u2013 instead of your brain\nSave handy all information related with programming\n- Use markdown and gather api specification\n- Well using module and snippet\n\nSave them on Boost, you don\'t need to rewrite or re-search same code again.\n\n# 3. Load Finder function \u2013 now you don\'t need to spell command by hand typing.\n\n**Shift +ctrl+tab** press buttons at same time.\nThen, the window will show up for search Boost contents that instant.\n\nUsing cursor key to chose, press enter, cmd+v to paste and\u2026 please check it out by your own eye.\n\n- Such command spl or linux which programmers often use but troublesome to hand type\n\n- (Phrases commonly used for e-mail or customer support)\n\nWe support preponderant efficiency\n\n\uFF0A\u3000\uFF0A\u3000\uFF0A\u3000\uFF0A\n\n## \u25CEfor more information\nFrequently updated with this blog ( http:\/\/blog-jp.b00st.io )\n\nHave wonderful programmer life!\n\n## Hack your memory**\n\n\n\n# 日本語版\n\n**Boost**は全く新しいエンジニアライクのノートアプリです。\n\n# ◎特徴\nBoostはエンジニアの仕事を圧倒的に効率化するいくつかの機能を備えています。\nその一部をご紹介します。\n1. Folderで情報を分類\n2. 豊富なsyantaxに対応\n3. Finder機能\n\n\n* * * *\n\n# 1. Folderで情報を分類、欲しい情報にすぐアクセス。\n左側のバーに存在する「Folders」。\n今すぐプラスボタンを押しましょう。\n分類の仕方も自由自在です。\n- 言語やフレームワークごとにFolderを作成\n- 自分用のカジュアルなメモをまとめる場としてFolderを作成\n\n\n# 2. 豊富なsyntaxに対応、自分の脳の代わりに。\nプログラミングに関する情報を全て、手軽に保存しましょう。\n- mdで、apiの仕様をまとめる\n- よく使うモジュールやスニペット\n\nBoostに保存しておくことで、何度も同じコードを書いたり調べたりする必要がなくなります。\n\n# 3. Finder機能を搭載、もうコマンドを手打ちする必要はありません。\n**「shift+ctrl+tab」** を同時に押してみてください。\nここでは、一瞬でBoostの中身を検索するウィンドウを表示させることができます。\n\n矢印キーで選択、Enterを押し、cmd+vでペーストすると…続きはご自身の目でお確かめください。\n- sqlやlinux等の、よく使うが手打ちが面倒なコマンド\n- (メールやカスタマーサポート等でよく使うフレーズ)\n\n私たちは、圧倒的な効率性を支援します。\n\* * * *\n\n\n## ◎詳しくは\nこちらのブログ( http://blog-jp.b00st.io )にて随時更新しています。\n\nそれでは素晴らしいエンジニアライフを!\n\n## Hack your memory**'
|
||||
|
||||
function getLocalPath () {
|
||||
return path.join(remote.app.getPath('userData'), 'local.json')
|
||||
}
|
||||
|
||||
export function init () {
|
||||
console.log('initialize data store')
|
||||
let data = JSON.parse(localStorage.getItem('local'))
|
||||
let data = jetpack.read(getLocalPath(), 'json')
|
||||
|
||||
if (data == null) {
|
||||
if (localStorage.getItem('local') != null) {
|
||||
data = JSON.parse(localStorage.getItem('local'))
|
||||
jetpack.write(getLocalPath(), data)
|
||||
localStorage.removeItem('local')
|
||||
}
|
||||
|
||||
let defaultFolder = {
|
||||
name: 'default',
|
||||
key: keygen()
|
||||
@@ -24,37 +39,35 @@ export function init () {
|
||||
folders: [defaultFolder],
|
||||
version: '0.4'
|
||||
}
|
||||
localStorage.setItem('local', JSON.stringify(data))
|
||||
jetpack.write(getLocalPath(), data)
|
||||
}
|
||||
}
|
||||
|
||||
function getKey (teamId) {
|
||||
return teamId == null
|
||||
? 'local'
|
||||
: `team-${teamId}`
|
||||
export function getData () {
|
||||
return jetpack.read(getLocalPath(), 'json')
|
||||
}
|
||||
|
||||
export function getData (teamId) {
|
||||
let key = getKey(teamId)
|
||||
return JSON.parse(localStorage.getItem(key))
|
||||
}
|
||||
|
||||
export function setArticles (teamId, articles) {
|
||||
let key = getKey(teamId)
|
||||
let data = JSON.parse(localStorage.getItem(key))
|
||||
export function setArticles (articles) {
|
||||
let data = getData()
|
||||
data.articles = articles
|
||||
localStorage.setItem(key, JSON.stringify(data))
|
||||
jetpack.write(getLocalPath(), data)
|
||||
}
|
||||
|
||||
export function setFolders (teamId, folders) {
|
||||
let key = getKey(teamId)
|
||||
let data = JSON.parse(localStorage.getItem(key))
|
||||
export function setFolders (folders) {
|
||||
let data = getData()
|
||||
data.folders = folders
|
||||
localStorage.setItem(key, JSON.stringify(data))
|
||||
jetpack.write(getLocalPath(), data)
|
||||
}
|
||||
|
||||
function isFinderCalled () {
|
||||
var argv = process.argv.slice(1)
|
||||
return argv.some(arg => arg.match(/--finder/))
|
||||
}
|
||||
|
||||
export default (function () {
|
||||
init()
|
||||
if (!isFinderCalled()) {
|
||||
init()
|
||||
}
|
||||
return {
|
||||
init,
|
||||
getData,
|
||||
|
||||
@@ -67,7 +67,7 @@ function folders (state = initialFolders, action) {
|
||||
if (conflictFolder != null) throw new Error(`${newFolder.name} already exists!`)
|
||||
state.push(newFolder)
|
||||
|
||||
dataStore.setFolders(null, state)
|
||||
dataStore.setFolders(state)
|
||||
activityRecord.emit('FOLDER_CREATE')
|
||||
return state
|
||||
}
|
||||
@@ -94,7 +94,7 @@ function folders (state = initialFolders, action) {
|
||||
updatedAt: new Date()
|
||||
})
|
||||
|
||||
dataStore.setFolders(null, state)
|
||||
dataStore.setFolders(state)
|
||||
activityRecord.emit('FOLDER_UPDATE')
|
||||
return state
|
||||
}
|
||||
@@ -107,7 +107,7 @@ function folders (state = initialFolders, action) {
|
||||
if (targetIndex >= 0) {
|
||||
state.splice(targetIndex, 1)
|
||||
}
|
||||
dataStore.setFolders(null, state)
|
||||
dataStore.setFolders(state)
|
||||
activityRecord.emit('FOLDER_DESTROY')
|
||||
return state
|
||||
}
|
||||
@@ -167,7 +167,7 @@ function articles (state = initialArticles, action) {
|
||||
if (targetIndex < 0) state.unshift(article)
|
||||
else state.splice(targetIndex, 1, article)
|
||||
|
||||
if (article.status !== 'NEW') dataStore.setArticles(null, state)
|
||||
if (article.status !== 'NEW') dataStore.setArticles(state)
|
||||
else isCreatingNew = true
|
||||
return state
|
||||
}
|
||||
@@ -178,7 +178,7 @@ function articles (state = initialArticles, action) {
|
||||
let targetIndex = _.findIndex(state, _article => articleKey === _article.key)
|
||||
if (targetIndex >= 0) state.splice(targetIndex, 1)
|
||||
|
||||
dataStore.setArticles(null, state)
|
||||
dataStore.setArticles(state)
|
||||
return state
|
||||
}
|
||||
case FOLDER_DESTROY:
|
||||
@@ -187,7 +187,7 @@ function articles (state = initialArticles, action) {
|
||||
|
||||
state = state.filter(article => article.FolderKey !== folderKey)
|
||||
|
||||
dataStore.setArticles(null, state)
|
||||
dataStore.setArticles(state)
|
||||
return state
|
||||
}
|
||||
default:
|
||||
|
||||
21
main.js
21
main.js
@@ -93,13 +93,14 @@ app.on('ready', function () {
|
||||
mainWindow.hide()
|
||||
})
|
||||
mainWindow.webContents.on('did-finish-load', function () {
|
||||
require('module')._load(path.resolve(__dirname, 'finder.js'), module, true)
|
||||
finderProcess = ChildProcess
|
||||
.execFile(process.execPath, [path.resolve(__dirname, 'finder.js'), '--finder'], {
|
||||
stdio: 'pipe'
|
||||
})
|
||||
finderProcess.stdout.on('data', format)
|
||||
finderProcess.stderr.on('data', errorFormat)
|
||||
if (finderProcess == null) {
|
||||
finderProcess = ChildProcess
|
||||
.execFile(process.execPath, [path.resolve(__dirname, 'finder.js'), '--finder'])
|
||||
finderProcess.stdout.setEncoding('utf8')
|
||||
finderProcess.stderr.setEncoding('utf8')
|
||||
finderProcess.stdout.on('data', format)
|
||||
finderProcess.stderr.on('data', errorFormat)
|
||||
}
|
||||
|
||||
if (update != null) {
|
||||
mainWindow.webContents.send('update-available', 'whoooooooh!')
|
||||
@@ -152,13 +153,9 @@ app.on('ready', function () {
|
||||
type: type,
|
||||
data: data
|
||||
}
|
||||
finderProcess.stdin.write(JSON.stringify(payload))
|
||||
finderProcess.stdin.write(JSON.stringify(payload), 'utf-8')
|
||||
}
|
||||
|
||||
ipc.on('refresh-data', function (e, data) {
|
||||
emitToFinder('refresh-data', data)
|
||||
})
|
||||
|
||||
var userDataPath = app.getPath('userData')
|
||||
if (!jetpack.cwd(userDataPath).exists('keymap.json')) {
|
||||
jetpack.cwd(userDataPath).file('keymap.json', {content: '{}'})
|
||||
|
||||
@@ -50,7 +50,8 @@ var config = {
|
||||
'markdown-it',
|
||||
'moment',
|
||||
'highlight.js',
|
||||
'markdown-it-emoji'
|
||||
'markdown-it-emoji',
|
||||
'fs-jetpack'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ module.exports = {
|
||||
'markdown-it',
|
||||
'moment',
|
||||
'highlight.js',
|
||||
'markdown-it-emoji'
|
||||
'markdown-it-emoji',
|
||||
'fs-jetpack'
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['', '.js', '.jsx', 'styl']
|
||||
|
||||
Reference in New Issue
Block a user