From 1a110951211326ce72590e6e2ca7f3d281b96d78 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 05:32:10 +0900 Subject: [PATCH 1/8] User name change and modify style --- browser/main/HomePage.js | 17 +++--- browser/main/HomePage/ArticleNavigator.js | 8 +-- lib/actions.js | 10 ++++ .../modal/Preference/AppSettingTab.js | 28 ++++++++- lib/components/modal/Preferences.js | 15 ++++- lib/dataStore.js | 57 ++++++++++++++++++- lib/keygen.js | 2 +- lib/reducer.js | 16 ++++++ 8 files changed, 132 insertions(+), 21 deletions(-) diff --git a/browser/main/HomePage.js b/browser/main/HomePage.js index 69c65948..ccbad0df 100644 --- a/browser/main/HomePage.js +++ b/browser/main/HomePage.js @@ -1,7 +1,6 @@ import React, { PropTypes} from 'react' import { connect } from 'react-redux' -import { EDIT_MODE, IDLE_MODE, NEW, toggleTutorial } from 'boost/actions' -// import UserNavigator from './HomePage/UserNavigator' +import { EDIT_MODE, IDLE_MODE, toggleTutorial } from 'boost/actions' import ArticleNavigator from './HomePage/ArticleNavigator' import ArticleTopBar from './HomePage/ArticleTopBar' import ArticleList from './HomePage/ArticleList' @@ -114,13 +113,14 @@ class HomePage extends React.Component { } render () { - let { dispatch, status, articles, allArticles, activeArticle, folders, tags, filters } = this.props + let { dispatch, status, user, articles, allArticles, activeArticle, folders, tags, filters } = this.props return (
{ @@ -234,6 +234,7 @@ function remap (state) { if (activeArticle == null) activeArticle = articles[0] return { + user, folders, status, allArticles, @@ -249,11 +250,9 @@ function remap (state) { } HomePage.propTypes = { - params: PropTypes.shape({ - userId: PropTypes.string - }), - status: PropTypes.shape({ - userId: PropTypes.string + status: PropTypes.shape(), + user: PropTypes.shape({ + name: PropTypes.string }), articles: PropTypes.array, allArticles: PropTypes.array, diff --git a/browser/main/HomePage/ArticleNavigator.js b/browser/main/HomePage/ArticleNavigator.js index 269d528f..a2f6755f 100644 --- a/browser/main/HomePage/ArticleNavigator.js +++ b/browser/main/HomePage/ArticleNavigator.js @@ -7,10 +7,6 @@ import Preferences from 'boost/components/modal/Preferences' import CreateNewFolder from 'boost/components/modal/CreateNewFolder' import keygen from 'boost/keygen' -const electron = require('electron') -const remote = electron.remote -let userName = remote.getGlobal('process').env.USER - const BRAND_COLOR = '#18AF90' const preferenceTutorialElement = ( @@ -109,7 +105,7 @@ export default class ArticleNavigator extends React.Component { } render () { - let { status, folders, allArticles } = this.props + let { status, user, folders, allArticles } = this.props let { targetFolders } = status if (targetFolders == null) targetFolders = [] @@ -127,7 +123,7 @@ export default class ArticleNavigator extends React.Component { return (
-
{userName}
+
{user.name}
localStorage
+ {alertElement} +
+
Hotkey
@@ -101,3 +124,6 @@ export default class AppSettingTab extends React.Component { } AppSettingTab.prototype.linkState = linkState +AppSettingTab.propTypes = { + dispatch: PropTypes.func +} diff --git a/lib/components/modal/Preferences.js b/lib/components/modal/Preferences.js index 51813751..a1b4f4a2 100644 --- a/lib/components/modal/Preferences.js +++ b/lib/components/modal/Preferences.js @@ -62,7 +62,7 @@ class Preferences extends React.Component { } renderContent () { - let { folders, dispatch } = this.props + let { user, folders, dispatch } = this.props switch (this.state.currentTab) { case HELP: @@ -80,12 +80,20 @@ class Preferences extends React.Component { ) case APP: default: - return () + return ( + + ) } } } Preferences.propTypes = { + user: PropTypes.shape({ + name: PropTypes.string + }), folders: PropTypes.array, dispatch: PropTypes.func } @@ -93,9 +101,10 @@ Preferences.propTypes = { Preferences.prototype.linkState = linkState function remap (state) { - let { folders, status } = state + let { user, folders, status } = state return { + user, folders, status } diff --git a/lib/dataStore.js b/lib/dataStore.js index 128c634d..e8b62af4 100644 --- a/lib/dataStore.js +++ b/lib/dataStore.js @@ -1,4 +1,6 @@ import keygen from 'boost/keygen' +import _ from 'lodash' + const electron = require('electron') const remote = electron.remote const jetpack = require('fs-jetpack') @@ -10,15 +12,66 @@ function getLocalPath () { return path.join(remote.app.getPath('userData'), 'local.json') } +function forgeInitialRepositories () { + return [{ + key: keygen(), + name: 'local', + type: 'userData', + user: { + name: remote.getGlobal('process').env.USER + } + }] +} + +function getRepositories () { + let raw = localStorage.getItem('repositories') + try { + let parsed = JSON.parse(raw) + if (!_.isArray(parsed)) { + throw new Error('repositories data is currupte. re-init data.') + } + return parsed + } catch (e) { + console.log(e) + let newRepos = forgeInitialRepositories() + saveRepositories(newRepos) + return newRepos + } +} + +function saveRepositories (repos) { + localStorage.setItem('repositories', JSON.stringify(repos)) +} + +export function getUser (repoName) { + if (repoName == null) { + return getRepositories()[0] + } + return null +} + +export function saveUser (repoName, user) { + let repos = getRepositories() + if (repoName == null) { + Object.assign(repos[0].user, user) + } + saveRepositories(repos) +} + export function init () { - console.log('initialize data store') + // set repositories info + getRepositories() + + // set local.json let data = jetpack.read(getLocalPath(), 'json') if (data == null) { + // for 0.4.1 -> 0.4.2 if (localStorage.getItem('local') != null) { data = JSON.parse(localStorage.getItem('local')) jetpack.write(getLocalPath(), data) localStorage.removeItem('local') + console.log('update 0.4.1 => 0.4.2') return } @@ -70,6 +123,8 @@ export default (function () { init() } return { + getUser, + saveUser, init, getData, setArticles, diff --git a/lib/keygen.js b/lib/keygen.js index 4cc04385..da8cf6b1 100644 --- a/lib/keygen.js +++ b/lib/keygen.js @@ -2,6 +2,6 @@ var crypto = require('crypto') module.exports = function () { var shasum = crypto.createHash('sha1') - shasum.update(((new Date()).getTime()).toString()) + shasum.update(((new Date()).getTime() + Math.round(Math.random()*1000)).toString()) return shasum.digest('hex') } diff --git a/lib/reducer.js b/lib/reducer.js index 4ca9d268..27971fb9 100644 --- a/lib/reducer.js +++ b/lib/reducer.js @@ -12,6 +12,9 @@ import { UNLOCK_STATUS, TOGGLE_TUTORIAL, + // user + USER_UPDATE, + // Article action type ARTICLE_UPDATE, ARTICLE_DESTROY, @@ -42,10 +45,22 @@ const initialStatus = { let data = dataStore.getData() let initialArticles = data.articles let initialFolders = data.folders +let initialUser = dataStore.getUser().user let isStatusLocked = false let isCreatingNew = false +function user (state = initialUser, action) { + switch (action.type) { + case USER_UPDATE: + let updated = Object.assign(state, action.data) + dataStore.saveUser(updated) + return updated + default: + return state + } +} + function folders (state = initialFolders, action) { state = state.slice() switch (action.type) { @@ -250,6 +265,7 @@ function status (state = initialStatus, action) { } export default combineReducers({ + user, folders, articles, status From 15c23630980a2520c9dcd20a3dffe38a1c256511 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 06:44:52 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Search=20input=E3=81=ABRegExp=20operator?= =?UTF-8?q?=E3=81=8C=E5=85=A5=E3=82=8B=E3=81=A8=E4=BD=BF=E3=81=88=E3=81=AA?= =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=9F=E5=95=8F=E9=A1=8C=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser/finder/index.js | 16 ++++++++++++---- browser/main/HomePage.js | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/browser/finder/index.js b/browser/finder/index.js index f845bbcf..33413062 100644 --- a/browser/finder/index.js +++ b/browser/finder/index.js @@ -152,6 +152,14 @@ function buildFilter (key) { return {type: TEXT_FILTER, value: key} } +function isContaining (target, needle) { + return target.match(new RegExp(_.escapeRegExp(needle))) +} + +function startsWith (target, needle) { + return target.match(new RegExp('^' + _.escapeRegExp(needle))) +} + function remap (state) { let { articles, folders, status } = state @@ -168,10 +176,10 @@ function remap (state) { let targetFolders if (folders != null) { let exactTargetFolders = folders.filter(folder => { - return _.find(folderExactFilters, filter => folder.name.match(new RegExp(`^${filter.value}$`))) + return _.find(folderExactFilters, filter => isContaining(folder.name, filter.value)) }) let fuzzyTargetFolders = folders.filter(folder => { - return _.find(folderFilters, filter => folder.name.match(new RegExp(`^${filter.value}`))) + return _.find(folderFilters, filter => startsWith(folder.name, filter.value)) }) targetFolders = status.targetFolders = exactTargetFolders.concat(fuzzyTargetFolders) @@ -184,7 +192,7 @@ function remap (state) { if (textFilters.length > 0) { articles = textFilters.reduce((articles, textFilter) => { return articles.filter(article => { - return article.title.match(new RegExp(textFilter.value, 'i')) || article.content.match(new RegExp(textFilter.value, 'i')) + return isContaining(article.title, textFilter.value) || isContaining(article.content, textFilter.value) }) }, articles) } @@ -192,7 +200,7 @@ function remap (state) { if (tagFilters.length > 0) { articles = tagFilters.reduce((articles, tagFilter) => { return articles.filter(article => { - return _.find(article.tags, tag => tag.match(new RegExp(tagFilter.value, 'i'))) + return _.find(article.tags, tag => isContaining(tag, tagFilter.value)) }) }, articles) } diff --git a/browser/main/HomePage.js b/browser/main/HomePage.js index ccbad0df..cc0c127a 100644 --- a/browser/main/HomePage.js +++ b/browser/main/HomePage.js @@ -7,6 +7,7 @@ import ArticleList from './HomePage/ArticleList' import ArticleDetail from './HomePage/ArticleDetail' import _ from 'lodash' import { isModalOpen, closeModal } from 'boost/modal' + const electron = require('electron') const BrowserWindow = electron.remote.BrowserWindow @@ -171,6 +172,14 @@ function buildFilter (key) { return {type: TEXT_FILTER, value: key} } +function isContaining (target, needle) { + return target.match(new RegExp(_.escapeRegExp(needle))) +} + +function startsWith (target, needle) { + return target.match(new RegExp('^' + _.escapeRegExp(needle))) +} + function remap (state) { let { user, folders, articles, status } = state @@ -199,10 +208,10 @@ function remap (state) { let targetFolders if (folders != null) { let exactTargetFolders = folders.filter(folder => { - return _.find(folderExactFilters, filter => folder.name.match(new RegExp(`^${filter.value}$`))) + return _.findWhere(folderExactFilters, {value: folder.name}) }) let fuzzyTargetFolders = folders.filter(folder => { - return _.find(folderFilters, filter => folder.name.match(new RegExp(`^${filter.value}`))) + return _.find(folderFilters, filter => startsWith(folder.name, filter.value)) }) targetFolders = status.targetFolders = exactTargetFolders.concat(fuzzyTargetFolders) @@ -215,7 +224,7 @@ function remap (state) { if (textFilters.length > 0) { articles = textFilters.reduce((articles, textFilter) => { return articles.filter(article => { - return article.title.match(new RegExp(textFilter.value, 'i')) || article.content.match(new RegExp(textFilter.value, 'i')) + return isContaining(article.title, textFilter.value) || isContaining(article.content, textFilter.value) }) }, articles) } @@ -223,7 +232,7 @@ function remap (state) { if (tagFilters.length > 0) { articles = tagFilters.reduce((articles, tagFilter) => { return articles.filter(article => { - return _.find(article.tags, tag => tag.match(new RegExp(tagFilter.value, 'i'))) + return _.find(article.tags, tag => isContaining(tag, tagFilter.value)) }) }, articles) } From ca7b9c786a5450ff492c7355c4d0ecf070e468d9 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 07:25:35 +0900 Subject: [PATCH 3/8] =?UTF-8?q?Finder=E3=81=AEInput=E3=81=ABLato=20font?= =?UTF-8?q?=E3=81=8C=E4=BD=BF=E3=82=8F=E3=82=8C=E3=81=A6=E3=81=84=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=95=8F=E9=A1=8C=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser/finder/index.js | 1 - browser/styles/finder/index.styl | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/browser/finder/index.js b/browser/finder/index.js index 33413062..e64dec5a 100644 --- a/browser/finder/index.js +++ b/browser/finder/index.js @@ -209,7 +209,6 @@ function remap (state) { let activeArticle = _.findWhere(articles, {key: status.articleKey}) if (activeArticle == null) activeArticle = articles[0] - console.log(status.search) return { articles, activeArticle, diff --git a/browser/styles/finder/index.styl b/browser/styles/finder/index.styl index d91383c5..be83adfa 100644 --- a/browser/styles/finder/index.styl +++ b/browser/styles/finder/index.styl @@ -14,6 +14,8 @@ body width 100% height 100% overflow hidden +button, input + font-family "Lato" .Finder absolute top bottom left right From 364917c910e6df6a0ddc4b33933100e8769ed6df Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 07:59:47 +0900 Subject: [PATCH 4/8] =?UTF-8?q?Finder=E3=81=AEActivity=20log=E3=82=92?= =?UTF-8?q?=E3=81=A1=E3=82=83=E3=82=93=E3=81=A8=E5=8F=96=E3=81=A3=E3=81=A6?= =?UTF-8?q?=E3=81=8F=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser/finder/index.js | 3 ++- browser/main/index.js | 7 +++++++ finder.js | 5 +++++ main.js | 9 ++++++--- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/browser/finder/index.js b/browser/finder/index.js index e64dec5a..c72987f2 100644 --- a/browser/finder/index.js +++ b/browser/finder/index.js @@ -11,7 +11,7 @@ import _ from 'lodash' import dataStore from 'boost/dataStore' const electron = require('electron') -const { remote, clipboard } = electron +const { remote, clipboard, ipcRenderer } = electron var hideFinder = remote.getGlobal('hideFinder') @@ -64,6 +64,7 @@ class FinderMain extends React.Component { let { activeArticle } = this.props clipboard.writeText(activeArticle.content) + ipcRenderer.send('copy-finder') notify('Saved to Clipboard!', { body: 'Paste it wherever you want!' }) diff --git a/browser/main/index.js b/browser/main/index.js index a7958fad..3224ab6d 100644 --- a/browser/main/index.js +++ b/browser/main/index.js @@ -29,6 +29,13 @@ ipc.on('notify', function (e, payload) { }) }) +ipc.on('copy-finder', function () { + activityRecord.emit('FINDER_COPY') +}) +ipc.on('open-finder', function () { + activityRecord.emit('FINDER_OPEN') +}) + let routes = ( diff --git a/finder.js b/finder.js index e0d12bf2..02da4244 100755 --- a/finder.js +++ b/finder.js @@ -3,6 +3,7 @@ const app = electron.app const Tray = electron.Tray const Menu = electron.Menu const MenuItem = electron.MenuItem +const ipcMain = electron.ipcMain process.stdin.setEncoding('utf8') @@ -63,6 +64,10 @@ app.on('ready', function () { break } }) + + ipcMain.on('copy-finder', function () { + emit('copy-finder') + }) }) global.hideFinder = function () { diff --git a/main.js b/main.js index a520380e..0dd48204 100644 --- a/main.js +++ b/main.js @@ -129,9 +129,10 @@ app.on('ready', function () { console.log('FINDER(stdout): ' + payload.data) break case 'show-main-window': - if (mainWindow != null) { - mainWindow.show() - } + mainWindow.show() + break + case 'copy-finder': + mainWindow.webContents.send('copy-finder') break case 'request-data': mainWindow.webContents.send('request-data') @@ -174,6 +175,7 @@ app.on('ready', function () { try { globalShortcut.register(toggleFinderKey, function () { emitToFinder('open-finder') + mainWindow.webContents.send('open-finder', {}) }) } catch (err) { console.log(err.name) @@ -190,6 +192,7 @@ app.on('ready', function () { try { globalShortcut.register(toggleFinderKey, function () { emitToFinder('open-finder') + mainWindow.webContents.send('open-finder', {}) }) mainWindow.webContents.send('APP_SETTING_DONE', {}) } catch (err) { From 5b520a7a811be57401d6a1a53bdd5a3cab67fe66 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 12:02:21 +0900 Subject: [PATCH 5/8] rollback: setVisibleOnAllWorkspaces(true) --- atom-lib/finder-window.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom-lib/finder-window.js b/atom-lib/finder-window.js index 01bc6eac..466c40b5 100644 --- a/atom-lib/finder-window.js +++ b/atom-lib/finder-window.js @@ -25,4 +25,6 @@ finderWindow.on('blur', function () { finderWindow.hide() }) +finderWindow.setVisibleOnAllWorkspaces(true) + module.exports = finderWindow From 182af99e7c55d4e00d8fb49616dee51a71018fb7 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 12:02:29 +0900 Subject: [PATCH 6/8] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a2a514f..98f68590 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "boost", - "version": "0.4.3-rc.0", + "version": "0.4.4-rc", "description": "Boost App", "main": "index.js", "scripts": { From aa32f59dc6704bf57e71e54a7aeb40e25b63b949 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Thu, 3 Dec 2015 12:15:07 +0900 Subject: [PATCH 7/8] debug missing argument --- lib/actions.js | 1 - lib/reducer.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/actions.js b/lib/actions.js index c440e974..39c7a4f4 100644 --- a/lib/actions.js +++ b/lib/actions.js @@ -40,7 +40,6 @@ export function clearNewArticle () { } } - export function updateArticle (article) { return { type: ARTICLE_UPDATE, diff --git a/lib/reducer.js b/lib/reducer.js index 27971fb9..e125848b 100644 --- a/lib/reducer.js +++ b/lib/reducer.js @@ -54,7 +54,7 @@ function user (state = initialUser, action) { switch (action.type) { case USER_UPDATE: let updated = Object.assign(state, action.data) - dataStore.saveUser(updated) + dataStore.saveUser(null, updated) return updated default: return state From 7c2d2044a9c7ea2f237f79075350e00d01d79716 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Fri, 4 Dec 2015 04:56:04 +0900 Subject: [PATCH 8/8] alert fix --- .../modal/Preference/AppSettingTab.js | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/components/modal/Preference/AppSettingTab.js b/lib/components/modal/Preference/AppSettingTab.js index 35cbad98..e55953a6 100644 --- a/lib/components/modal/Preference/AppSettingTab.js +++ b/lib/components/modal/Preference/AppSettingTab.js @@ -13,26 +13,29 @@ export default class AppSettingTab extends React.Component { let userName = props.user != null ? props.user.name : null this.state = { - toggleFinder: keymap.toggleFinder, user: { name: userName, alert: null }, - alert: null + userAlert: null, + keymap: { + toggleFinder: keymap.toggleFinder + }, + keymapAlert: null } } componentDidMount () { this.handleSettingDone = () => { - this.setState({alert: { + this.setState({keymapAlert: { type: 'success', message: 'Successfully done!' }}) } this.handleSettingError = err => { - this.setState({alert: { + this.setState({keymapAlert: { type: 'error', - message: err.message + message: err.message != null ? err.message : 'Error occurs!' }}) } ipc.addListener('APP_SETTING_DONE', this.handleSettingDone) @@ -46,7 +49,7 @@ export default class AppSettingTab extends React.Component { submitHotKey () { ipc.send('hotkeyUpdated', { - toggleFinder: this.state.toggleFinder + toggleFinder: this.state.keymap.toggleFinder }) } @@ -64,13 +67,27 @@ export default class AppSettingTab extends React.Component { let { dispatch } = this.props dispatch(updateUser({name: this.state.user.name})) + this.setState({ + userAlert: { + type: 'success', + message: 'Successfully done!' + } + }) } render () { - let alert = this.state.alert - let alertElement = alert != null ? ( -

- {alert.message} + let keymapAlert = this.state.keymapAlert + let keymapAlertElement = keymapAlert != null + ? ( +

+ {keymapAlert.message} +

+ ) : null + let userAlert = this.state.userAlert + let userAlertElement = userAlert != null + ? ( +

+ {userAlert.message}

) : null @@ -84,18 +101,18 @@ export default class AppSettingTab extends React.Component {
- {alertElement} + {userAlertElement}
Hotkey
- this.handleKeyDown(e)} valueLink={this.linkState('toggleFinder')} type='text'/> + this.handleKeyDown(e)} valueLink={this.linkState('keymap.toggleFinder')} type='text'/>
- {alertElement} + {keymapAlertElement}