this.handleClick(e)} onKeyDown={e => this.handleKeyDown(e)} className='Finder'>
+
+
+
+
@@ -286,7 +298,7 @@ export default class ArticleDetail extends React.Component {
dispatch(unlockStatus())
- delete newArticle.status
+ newArticle.status = null
newArticle.updatedAt = new Date()
newArticle.title = newArticle.title.trim()
if (newArticle.createdAt == null) {
@@ -586,7 +598,8 @@ export default class ArticleDetail extends React.Component {
ArticleDetail.propTypes = {
status: PropTypes.shape(),
activeArticle: PropTypes.shape(),
- activeUser: PropTypes.shape(),
+ user: PropTypes.shape(),
+ folders: PropTypes.array,
dispatch: PropTypes.func
}
ArticleDetail.prototype.linkState = linkState
diff --git a/browser/main/MainPage.js b/browser/main/MainPage.js
index e1490e96..a5db1fa9 100644
--- a/browser/main/MainPage.js
+++ b/browser/main/MainPage.js
@@ -2,8 +2,6 @@ const electron = require('electron')
const ipc = electron.ipcRenderer
import React, { PropTypes } from 'react'
-var ContactModal = require('boost/components/modal/ContactModal')
-
export default class MainContainer extends React.Component {
constructor (props) {
super(props)
@@ -20,20 +18,12 @@ export default class MainContainer extends React.Component {
ipc.send('update-app', 'Deal with it.')
}
- openContactModal () {
- this.openModal(ContactModal)
- }
-
render () {
return (
{this.state.updateAvailable ? (
) : null}
- {/*
*/}
{this.props.children}
)
diff --git a/browser/styles/main/HomeContainer/components/ArticleDetail.styl b/browser/styles/main/HomeContainer/components/ArticleDetail.styl
index e64e5da6..61e4d8d9 100644
--- a/browser/styles/main/HomeContainer/components/ArticleDetail.styl
+++ b/browser/styles/main/HomeContainer/components/ArticleDetail.styl
@@ -284,7 +284,87 @@ iptFocusBorderColor = #369DCD
color noTagsColor
.right
z-index 30
- button
+ div.share-dropdown
+ position absolute
+ right 5px
+ top 30px
+ background-color transparentify(invBackgroundColor, 80%)
+ padding 5px 0
+ width 200px
+ &.hide
+ display none
+ &>button
+ width 200px
+ text-align left
+ display block
+ height 33px
+ background-color transparent
+ color white
+ font-size 14px
+ padding 0 10px
+ border none
+ &:hover
+ background-color transparentify(lighten(invBackgroundColor, 30%), 80%)
+ &>.ShareButton-url
+ clearfix()
+ input.ShareButton-url-input
+ width 155px
+ margin 0 0 0 5px
+ height 25px
+ outline none
+ border none
+ border-top-left-radius 5px
+ border-bottom-left-radius 5px
+ float left
+ padding 5px
+ button.ShareButton-url-button
+ width 35px
+ height 25px
+ border none
+ margin 0 5px 0 0
+ outline none
+ border-top-right-radius 5px
+ border-bottom-right-radius 5px
+ background-color darken(white, 5%)
+ color inactiveTextColor
+ float right
+ div.ShareButton-url-button-tooltip
+ tooltip()
+ right 10px
+ &:hover
+ color textColor
+ div.ShareButton-url-button-tooltip
+ opacity 1
+ div.ShareButton-url-alert
+ float left
+ height 25px
+ line-height 25px
+ padding 0 15px
+ color white
+
+ .ShareButton
+ display inline-block
+ button.ShareButton-open-button
+ border-radius 16.5px
+ cursor pointer
+ height 33px
+ width 33px
+ border none
+ margin-right 5px
+ font-size 18px
+ color inactiveTextColor
+ background-color darken(white, 5%)
+ padding 0
+ .tooltip
+ tooltip()
+ margin-top 25px
+ margin-left -40px
+ &:hover
+ color textColor
+ .tooltip
+ opacity 1
+
+ &>button
border-radius 16.5px
cursor pointer
height 33px
diff --git a/finder.js b/finder.js
index 02da4244..627a3cbd 100755
--- a/finder.js
+++ b/finder.js
@@ -27,6 +27,10 @@ app.on('ready', function () {
var appIcon = new Tray(__dirname + '/resources/tray-icon.png')
appIcon.setToolTip('Boost')
+ var template = require('./atom-lib/menu-template')
+ var menu = Menu.buildFromTemplate(template)
+ Menu.setApplicationMenu(menu)
+
finderWindow = require('./atom-lib/finder-window')
finderWindow.webContents.on('did-finish-load', function () {
var trayMenu = new Menu()
diff --git a/lib/actions.js b/lib/actions.js
index 39c7a4f4..b33b0945 100644
--- a/lib/actions.js
+++ b/lib/actions.js
@@ -146,3 +146,23 @@ export function toggleTutorial () {
type: TOGGLE_TUTORIAL
}
}
+
+export default {
+ updateUser,
+ clearNewArticle,
+ updateArticle,
+ destroyArticle,
+ createFolder,
+ updateFolder,
+ destroyFolder,
+ replaceFolder,
+ switchFolder,
+ switchMode,
+ switchArticle,
+ setSearchFilter,
+ setTagFilter,
+ clearSearch,
+ lockStatus,
+ unlockStatus,
+ toggleTutorial
+}
diff --git a/lib/activityRecord.js b/lib/activityRecord.js
index 79036010..abf368b4 100644
--- a/lib/activityRecord.js
+++ b/lib/activityRecord.js
@@ -1,8 +1,8 @@
import _ from 'lodash'
import moment from 'moment'
-import keygen from 'boost/keygen'
import dataStore from 'boost/dataStore'
import { request, WEB_URL } from 'boost/api'
+import clientKey from 'boost/clientKey'
const electron = require('electron')
const version = electron.remote.app.getVersion()
@@ -28,16 +28,6 @@ export function init () {
}
}
-export function getClientKey () {
- let clientKey = localStorage.getItem('clientKey')
- if (!_.isString(clientKey) || clientKey.length !== 40) {
- clientKey = keygen()
- localStorage.setItem('clientKey', clientKey)
- }
-
- return clientKey
-}
-
export function getAllRecords () {
return JSON.parse(localStorage.getItem('activityRecords'))
}
@@ -67,7 +57,7 @@ export function postRecords (data) {
console.log('posting...', records)
let input = {
- clientKey: getClientKey(),
+ clientKey: clientKey.get(),
records
}
return request.post(WEB_URL + 'apis/activity')
@@ -108,6 +98,7 @@ export function emit (type, data = {}) {
case 'FINDER_OPEN':
case 'FINDER_COPY':
case 'MAIN_DETAIL_COPY':
+ case 'ARTICLE_SHARE':
todayRecord[type] = todayRecord[type] == null
? 1
: todayRecord[type] + 1
@@ -142,6 +133,5 @@ export function emit (type, data = {}) {
export default {
init,
emit,
- getClientKey,
postRecords
}
diff --git a/lib/api.js b/lib/api.js
index 6a5f9f91..729f1456 100644
--- a/lib/api.js
+++ b/lib/api.js
@@ -1,191 +1,22 @@
import superagent from 'superagent'
import superagentPromise from 'superagent-promise'
-import auth from 'boost/auth'
+// import auth from 'boost/auth'
-export const API_URL = 'http://boost-api4.elasticbeanstalk.com/'
-export const WEB_URL = 'https://b00st.io/'
-// export const WEB_URL = 'http://localhost:3333/'
+export const SERVER_URL = 'https://b00st.io/'
+// export const SERVER_URL = 'http://localhost:3333/'
export const request = superagentPromise(superagent, Promise)
-export function login (input) {
+export function shareViaPublicURL (input) {
return request
- .post(API_URL + 'auth/login')
- .send(input)
-}
-
-export function signup (input) {
- return request
- .post(API_URL + 'auth/register')
- .send(input)
-}
-
-export function updateUserInfo (input) {
- return request
- .put(API_URL + 'auth/user')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function updatePassword (input) {
- return request
- .post(API_URL + 'auth/password')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function fetchCurrentUser () {
- return request
- .get(API_URL + 'auth/user')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
-}
-
-export function fetchArticles (userId) {
- return request
- .get(API_URL + 'teams/' + userId + '/articles')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
-}
-
-export function createArticle (input) {
- return request
- .post(API_URL + 'articles/')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function saveArticle (input) {
- return request
- .put(API_URL + 'articles/' + input.id)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function destroyArticle (articleId) {
- return request
- .del(API_URL + 'articles/' + articleId)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
-}
-
-export function createTeam (input) {
- return request
- .post(API_URL + 'teams')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function updateTeamInfo (teamId, input) {
- return request
- .put(API_URL + 'teams/' + teamId)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function destroyTeam (teamId) {
- return request
- .del(API_URL + 'teams/' + teamId)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
-}
-
-export function searchUser (key) {
- return request
- .get(API_URL + 'search/users')
- .query({key: key})
-}
-
-export function setMember (teamId, input) {
- return request
- .post(API_URL + 'teams/' + teamId + '/members')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function deleteMember (teamId, input) {
- return request
- .del(API_URL + 'teams/' + teamId + '/members')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function createFolder (input) {
- return request
- .post(API_URL + 'folders/')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function updateFolder (id, input) {
- return request
- .put(API_URL + 'folders/' + id)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
- .send(input)
-}
-
-export function destroyFolder (id) {
- return request
- .del(API_URL + 'folders/' + id)
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
-}
-
-export function sendEmail (input) {
- return request
- .post(API_URL + 'mail')
- .set({
- Authorization: 'Bearer ' + auth.token()
- })
+ .post(SERVER_URL + 'apis/share')
+ // .set({
+ // Authorization: 'Bearer ' + auth.token()
+ // })
.send(input)
}
export default {
- API_URL,
- WEB_URL,
- request,
- login,
- signup,
- updateUserInfo,
- updatePassword,
- fetchCurrentUser,
- fetchArticles,
- createArticle,
- saveArticle,
- destroyArticle,
- createTeam,
- updateTeamInfo,
- destroyTeam,
- searchUser,
- setMember,
- deleteMember,
- createFolder,
- updateFolder,
- destroyFolder,
- sendEmail
+ SERVER_URL,
+ shareViaPublicURL
}
diff --git a/lib/clientKey.js b/lib/clientKey.js
new file mode 100644
index 00000000..b76d6bb8
--- /dev/null
+++ b/lib/clientKey.js
@@ -0,0 +1,23 @@
+import _ from 'lodash'
+import keygen from 'boost/keygen'
+
+function getClientKey () {
+ let clientKey = localStorage.getItem('clientKey')
+ if (!_.isString(clientKey) || clientKey.length !== 40) {
+ clientKey = keygen()
+ setClientKey(clientKey)
+ }
+
+ return clientKey
+}
+
+function setClientKey (newKey) {
+ localStorage.setItem('clientKey', newKey)
+}
+
+getClientKey()
+
+export default {
+ get: getClientKey,
+ set: setClientKey
+}
diff --git a/lib/components/CodeEditor.js b/lib/components/CodeEditor.js
index e6941ed8..91b39ac3 100644
--- a/lib/components/CodeEditor.js
+++ b/lib/components/CodeEditor.js
@@ -31,6 +31,14 @@ module.exports = React.createClass({
editor.setTheme('ace/theme/xcode')
editor.clearSelection()
editor.moveCursorTo(0, 0)
+ editor.commands.addCommand({
+ name: 'Emacs cursor up',
+ bindKey: {mac: 'Ctrl-P'},
+ exec: function (editor) {
+ editor.navigateUp(1)
+ },
+ readOnly: true
+ })
editor.setReadOnly(!!this.props.readOnly)
diff --git a/lib/components/modal/ContactModal.js b/lib/components/modal/ContactModal.js
deleted file mode 100644
index f3106ea6..00000000
--- a/lib/components/modal/ContactModal.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import React, { PropTypes, findDOMNode } from 'react'
-import linkState from 'boost/linkState'
-import { sendEmail } from 'boost/api'
-
-export default class ContactModal extends React.Component {
- constructor (props) {
- super(props)
-
- this.linkState = linkState
-
- this.state = {
- isSent: false,
- mail: {
- title: '',
- content: ''
- }
- }
- }
-
- onKeyCast (e) {
- switch (e.status) {
- case 'closeModal':
- this.props.close()
- break
- case 'submitContactModal':
- if (this.state.isSent) {
- this.props.close()
- return
- }
- this.sendEmail()
- break
- }
- }
-
- componentDidMount () {
- findDOMNode(this.refs.title).focus()
- }
-
- sendEmail () {
- sendEmail(this.state.mail)
- .then(function (res) {
- this.setState({isSent: !this.state.isSent})
- }.bind(this))
- .catch(function (err) {
- console.error(err)
- })
- }
-
- render () {
- return (
-
-
Contact form
-
- {!this.state.isSent ? (
-
- ) : (
-
-
Thanks for sharing your opinion!
-
-
- )}
-
- )
- }
-}
-
-ContactModal.propTypes = {
- close: PropTypes.func
-}
diff --git a/lib/reducer.js b/lib/reducer.js
index e125848b..c549a17e 100644
--- a/lib/reducer.js
+++ b/lib/reducer.js
@@ -134,6 +134,7 @@ function folders (state = initialFolders, action) {
state.splice(a, 1, folderB)
state.splice(b, 1, folderA)
}
+ dataStore.setFolders(state)
return state
default:
return state
@@ -180,10 +181,10 @@ function articles (state = initialArticles, action) {
let targetIndex = _.findIndex(state, _article => article.key === _article.key)
if (targetIndex < 0) state.unshift(article)
- else state.splice(targetIndex, 1, article)
+ else Object.assign(state[targetIndex], article)
if (article.status !== 'NEW') dataStore.setArticles(state)
- else isCreatingNew = true
+ else isCreatingNew = true
return state
}
case ARTICLE_DESTROY:
diff --git a/package.json b/package.json
index 6a936018..62a1df69 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,6 @@
{
"name": "boost",
- "version": "0.4.4",
- "version": "0.4.5",
+ "version": "0.4.6",
"description": "Boost App",
"main": "index.js",
"scripts": {