mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
Url share done
This commit is contained in:
@@ -9,7 +9,7 @@ import _ from 'lodash'
|
||||
import { isModalOpen, closeModal } from 'boost/modal'
|
||||
|
||||
const electron = require('electron')
|
||||
const BrowserWindow = electron.remote.BrowserWindow
|
||||
const remote = electron.remote
|
||||
|
||||
const TEXT_FILTER = 'TEXT_FILTER'
|
||||
const FOLDER_FILTER = 'FOLDER_FILTER'
|
||||
@@ -29,10 +29,10 @@ class HomePage extends React.Component {
|
||||
}
|
||||
|
||||
handleKeyDown (e) {
|
||||
if (process.env.BOOST_ENV === 'development' && e.keyCode === 73 && e.metaKey && e.altKey) {
|
||||
if (e.keyCode === 73 && e.metaKey && e.altKey) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
BrowserWindow.getFocusedWindow().toggleDevTools()
|
||||
remote.getCurrentWebContents().openDevTools()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ class HomePage extends React.Component {
|
||||
list.selectNextArticle()
|
||||
}
|
||||
|
||||
if (e.keyCode === 65 || (e.keyCode === 13 && e.metaKey) || (e.keyCode === 78 && e.metaKey)) {
|
||||
if ((e.keyCode === 65 && !e.metaKey && !e.ctrlKey) || (e.keyCode === 13 && e.metaKey) || (e.keyCode === 78 && e.metaKey)) {
|
||||
nav.handleNewPostButtonClick()
|
||||
e.preventDefault()
|
||||
}
|
||||
@@ -142,6 +142,7 @@ class HomePage extends React.Component {
|
||||
<ArticleDetail
|
||||
ref='detail'
|
||||
dispatch={dispatch}
|
||||
user={user}
|
||||
activeArticle={activeArticle}
|
||||
folders={folders}
|
||||
status={status}
|
||||
|
||||
135
browser/main/HomePage/ArticleDetail/ShareButton.js
Normal file
135
browser/main/HomePage/ArticleDetail/ShareButton.js
Normal file
@@ -0,0 +1,135 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import api from 'boost/api'
|
||||
import clientKey from 'boost/clientKey'
|
||||
const clipboard = require('electron').clipboard
|
||||
|
||||
function getDefault () {
|
||||
return {
|
||||
openDropdown: false,
|
||||
isSharing: false,
|
||||
// Fetched url
|
||||
url: null,
|
||||
// for tooltip Copy -> Copied!
|
||||
copied: false
|
||||
}
|
||||
}
|
||||
|
||||
export default class ShareButton extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = getDefault()
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
this.setState(getDefault())
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.dropdownInterceptor = e => {
|
||||
this.dropdownClicked = true
|
||||
}
|
||||
ReactDOM.findDOMNode(this.refs.dropdown).addEventListener('click', this.dropdownInterceptor)
|
||||
this.shareWithPublicURLHandler = e => {
|
||||
this.handleShareWithPublicURLClick(e)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
document.removeEventListener('click', this.dropdownHandler)
|
||||
ReactDOM.findDOMNode(this.refs.dropdown).removeEventListener('click', this.dropdownInterceptor)
|
||||
}
|
||||
|
||||
handleOpenButtonClick (e) {
|
||||
this.openDropdown()
|
||||
if (this.dropdownHandler == null) {
|
||||
this.dropdownHandler = e => {
|
||||
if (!this.dropdownClicked) {
|
||||
this.closeDropdown()
|
||||
} else {
|
||||
this.dropdownClicked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
document.removeEventListener('click', this.dropdownHandler)
|
||||
document.addEventListener('click', this.dropdownHandler)
|
||||
}
|
||||
|
||||
openDropdown () {
|
||||
this.setState({openDropdown: true})
|
||||
}
|
||||
|
||||
closeDropdown () {
|
||||
document.removeEventListener('click', this.dropdownHandler)
|
||||
this.setState({openDropdown: false})
|
||||
}
|
||||
|
||||
handleShareWithPublicURLClick (e) {
|
||||
let input = Object.assign({}, this.props.article, {clientKey: clientKey.get()})
|
||||
api.shareWithPublicURL(input)
|
||||
.then(res => {
|
||||
let url = res.body.url
|
||||
this.setState({url: url})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
handleCopyURLClick () {
|
||||
clipboard.writeText(this.state.url)
|
||||
this.setState({copied: true})
|
||||
}
|
||||
|
||||
// Restore copy url tooltip
|
||||
handleCopyURLMouseLeave () {
|
||||
this.setState({copied: false})
|
||||
}
|
||||
|
||||
render () {
|
||||
let hasPublicURL = this.state.url != null
|
||||
return (
|
||||
<div className='ShareButton'>
|
||||
<button ref='openButton' onClick={e => this.handleOpenButtonClick(e)} className='ShareButton-open-button'>
|
||||
<i className='fa fa-fw fa-share-alt'/>
|
||||
{
|
||||
this.state.openDropdown ? null : (
|
||||
<span className='tooltip'>Share</span>
|
||||
)
|
||||
}
|
||||
</button>
|
||||
<div ref='dropdown' className={'share-dropdown' + (this.state.openDropdown ? '' : ' hide')}>
|
||||
{
|
||||
!hasPublicURL ? (
|
||||
<button
|
||||
onClick={e => this.shareWithPublicURLHandler(e)}
|
||||
ref='sharePublicURL'
|
||||
disabled={this.state.isSharing}>
|
||||
<i className='fa fa-fw fa-external-link'/> {!this.state.isSharing ? 'Share with public URL' : 'Sharing...'}
|
||||
</button>
|
||||
) : (
|
||||
<div className='ShareButton-url'>
|
||||
<input className='ShareButton-url-input' value={this.state.url} readOnly/>
|
||||
<button
|
||||
onClick={e => this.handleCopyURLClick(e)}
|
||||
className='ShareButton-url-button'
|
||||
onMouseLeave={e => this.handleCopyURLMouseLeave(e)}
|
||||
>
|
||||
<i className='fa fa-fw fa-clipboard'/>
|
||||
<div className='ShareButton-url-button-tooltip'>{this.state.copied ? 'Copied!' : 'Copy URL'}</div>
|
||||
</button>
|
||||
<div className='ShareButton-url-alert'>This url is valid for 7 days.</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ShareButton.propTypes = {
|
||||
article: PropTypes.shape({
|
||||
publicURL: PropTypes.string
|
||||
})
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import TagLink from 'boost/components/TagLink'
|
||||
import TagSelect from 'boost/components/TagSelect'
|
||||
import ModeSelect from 'boost/components/ModeSelect'
|
||||
import activityRecord from 'boost/activityRecord'
|
||||
import api from 'boost/api'
|
||||
import ShareButton from './ShareButton'
|
||||
|
||||
const electron = require('electron')
|
||||
const clipboard = electron.clipboard
|
||||
@@ -106,12 +108,16 @@ export default class ArticleDetail extends React.Component {
|
||||
isTagChanged: false,
|
||||
isTitleChanged: false,
|
||||
isContentChanged: false,
|
||||
isModeChanged: false
|
||||
isModeChanged: false,
|
||||
openShareDropdown: false
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.refreshTimer = setInterval(() => this.forceUpdate(), 60 * 1000)
|
||||
this.shareDropdownInterceptor = e => {
|
||||
e.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
@@ -234,9 +240,12 @@ export default class ArticleDetail extends React.Component {
|
||||
<div className='tags'><i className='fa fa-fw fa-tags'/>{tags}</div>
|
||||
</div>
|
||||
<div className='right'>
|
||||
<ShareButton article={activeArticle}/>
|
||||
|
||||
<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>
|
||||
@@ -586,7 +595,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
|
||||
@@ -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 (
|
||||
<div className='Main'>
|
||||
{this.state.updateAvailable ? (
|
||||
<button onClick={this.updateApp} className='appUpdateButton'><i className='fa fa-cloud-download'/> Update available!</button>
|
||||
) : null}
|
||||
{/* <button onClick={this.openContactModal} className='contactButton'>
|
||||
<i className='fa fa-paper-plane-o'/>
|
||||
<div className='tooltip'>Contact us</div>
|
||||
</button> */}
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
@@ -142,6 +132,5 @@ export function emit (type, data = {}) {
|
||||
export default {
|
||||
init,
|
||||
emit,
|
||||
getClientKey,
|
||||
postRecords
|
||||
}
|
||||
|
||||
189
lib/api.js
189
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 shareWithPublicURL (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,
|
||||
shareWithPublicURL
|
||||
}
|
||||
|
||||
23
lib/clientKey.js
Normal file
23
lib/clientKey.js
Normal file
@@ -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
|
||||
}
|
||||
@@ -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 (
|
||||
<div className='ContactModal modal'>
|
||||
<div className='modal-header'><h1>Contact form</h1></div>
|
||||
|
||||
{!this.state.isSent ? (
|
||||
<div className='contactForm'>
|
||||
<div className='modal-body'>
|
||||
<div className='formField'>
|
||||
<input ref='title' valueLink={this.linkState('mail.title')} placeholder='Title'/>
|
||||
</div>
|
||||
<div className='formField'>
|
||||
<textarea valueLink={this.linkState('mail.content')} placeholder='Content'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='modal-footer'>
|
||||
<div className='formControl'>
|
||||
<button onClick={this.sendEmail} className='sendButton'>Send</button>
|
||||
<button onClick={this.props.close}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className='confirmation'>
|
||||
<div className='confirmationMessage'>Thanks for sharing your opinion!</div>
|
||||
<button className='doneButton' onClick={this.props.close}>Done</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ContactModal.propTypes = {
|
||||
close: PropTypes.func
|
||||
}
|
||||
@@ -180,7 +180,9 @@ 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
|
||||
|
||||
Reference in New Issue
Block a user