mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
改善 - PlanetArticleList, PlanetArticleDetail
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var moment = require('moment')
|
var moment = require('moment')
|
||||||
|
|
||||||
var CodeViewer = require('../Components/CodeViewer')
|
var CodeViewer = require('./CodeViewer')
|
||||||
|
var CodeEditModal = require('./CodeEditModal')
|
||||||
var CodeEditModal = require('../Components/CodeEditModal')
|
var CodeDeleteModal = require('./CodeDeleteModal')
|
||||||
var CodeDeleteModal = require('../Components/CodeDeleteModal')
|
var NoteEditModal = require('./NoteEditModal')
|
||||||
var NoteEditModal = require('../Components/NoteEditModal')
|
var NoteDeleteModal = require('./NoteDeleteModal')
|
||||||
var NoteDeleteModal = require('../Components/NoteDeleteModal')
|
var MarkdownPreview = require('./MarkdownPreview')
|
||||||
var MarkdownPreview = require('../Components/MarkdownPreview')
|
var ProfileImage = require('./ProfileImage')
|
||||||
|
|
||||||
var Modal = require('../Mixins/Modal')
|
var Modal = require('../Mixins/Modal')
|
||||||
var ForceUpdate = require('../Mixins/ForceUpdate')
|
var ForceUpdate = require('../Mixins/ForceUpdate')
|
||||||
@@ -61,18 +61,24 @@ module.exports = React.createClass({
|
|||||||
if (article.type === 'code') {
|
if (article.type === 'code') {
|
||||||
return (
|
return (
|
||||||
<div className='PlanetArticleDetail codeDetail'>
|
<div className='PlanetArticleDetail codeDetail'>
|
||||||
<div className='viewer-header'>
|
<div className='detailHeader'>
|
||||||
<i className='fa fa-code fa-fw'></i> {article.callSign} <small className='updatedAt'>{moment(article.updatedAt).fromNow()}</small>
|
<div className='itemLeft'>
|
||||||
<span className='control-group'>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
|
<i className='fa fa-file-text-o fa-fw'></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='itemRight'>
|
||||||
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
|
<div className='description'>{article.description}</div>
|
||||||
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className='itemControl'>
|
||||||
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
||||||
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='viewer-body'>
|
<div className='detailBody'>
|
||||||
<div className='viewer-detail'>
|
|
||||||
<div className='description'>{article.description}</div>
|
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
|
||||||
</div>
|
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
<CodeViewer code={article.content} mode={article.mode}/>
|
<CodeViewer code={article.content} mode={article.mode}/>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,15 +88,24 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className='PlanetArticleDetail noteDetail'>
|
<div className='PlanetArticleDetail noteDetail'>
|
||||||
<div className='viewer-header'>
|
<div className='detailHeader'>
|
||||||
<i className='fa fa-file-text-o fa-fw'></i> {article.title} <small className='updatedAt'>{moment(article.updatedAt).fromNow()}</small>
|
<div className='itemLeft'>
|
||||||
<span className='control-group'>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
|
<i className='fa fa-file-text-o fa-fw'></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='itemRight'>
|
||||||
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
|
<div className='description'>{article.title}</div>
|
||||||
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className='itemControl'>
|
||||||
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
||||||
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='viewer-body'>
|
<div className='detailBody'>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
|
||||||
<MarkdownPreview className='content' content={article.content}/>
|
<MarkdownPreview className='content' content={article.content}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
|
var Link = ReactRouter.Link
|
||||||
var moment = require('moment')
|
var moment = require('moment')
|
||||||
|
|
||||||
var ForceUpdate = require('../Mixins/ForceUpdate')
|
var ForceUpdate = require('../Mixins/ForceUpdate')
|
||||||
@@ -13,6 +14,31 @@ module.exports = React.createClass({
|
|||||||
articles: React.PropTypes.array,
|
articles: React.PropTypes.array,
|
||||||
showOnlyWithTag: React.PropTypes.func
|
showOnlyWithTag: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
handleArticleClikck: function (article) {
|
||||||
|
if (article.type === 'code') {
|
||||||
|
return function () {
|
||||||
|
var params = this.getParams()
|
||||||
|
|
||||||
|
this.transitionTo('codes', {
|
||||||
|
userName: params.userName,
|
||||||
|
planetName: params.planetName,
|
||||||
|
localId: article.localId
|
||||||
|
})
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (article.type === 'note') {
|
||||||
|
return function () {
|
||||||
|
var params = this.getParams()
|
||||||
|
|
||||||
|
this.transitionTo('notes', {
|
||||||
|
userName: params.userName,
|
||||||
|
planetName: params.planetName,
|
||||||
|
localId: article.localId
|
||||||
|
})
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var articles = this.props.articles.map(function (article) {
|
var articles = this.props.articles.map(function (article) {
|
||||||
var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
|
var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
|
||||||
@@ -28,24 +54,15 @@ module.exports = React.createClass({
|
|||||||
var handleClick
|
var handleClick
|
||||||
|
|
||||||
if (article.type === 'code') {
|
if (article.type === 'code') {
|
||||||
|
|
||||||
handleClick = function () {
|
|
||||||
this.transitionTo('codes', {
|
|
||||||
userName: params.userName,
|
|
||||||
planetName: params.planetName,
|
|
||||||
localId: article.localId
|
|
||||||
})
|
|
||||||
}.bind(this)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li onClick={handleClick} key={'code-' + article.id}>
|
<li onClick={this.handleArticleClikck(article)} key={'code-' + article.id}>
|
||||||
<div className={'articleItem' + (isActive ? ' active' : '')}>
|
<div className={'articleItem' + (isActive ? ' active' : '')}>
|
||||||
<div className='itemLeft'>
|
<div className='itemLeft'>
|
||||||
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
<i className='fa fa-code fa-fw'></i>
|
<i className='fa fa-code fa-fw'></i>
|
||||||
</div>
|
</div>
|
||||||
<div className='itemRight'>
|
<div className='itemRight'>
|
||||||
<div className='updatedAt'>{moment(article.updatedAt).fromNow()}</div>
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
<div className='description'>{article.description.length > 50 ? article.description.substring(0, 50) + ' …' : article.description}</div>
|
<div className='description'>{article.description.length > 50 ? article.description.substring(0, 50) + ' …' : article.description}</div>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,16 +72,8 @@ module.exports = React.createClass({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick = function () {
|
|
||||||
this.transitionTo('notes', {
|
|
||||||
userName: params.userName,
|
|
||||||
planetName: params.planetName,
|
|
||||||
localId: article.localId
|
|
||||||
})
|
|
||||||
}.bind(this)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li onClick={handleClick} key={'note-' + article.id}>
|
<li onClick={this.handleArticleClikck(article)} key={'note-' + article.id}>
|
||||||
<div className={'articleItem blueprintItem' + (isActive ? ' active' : '')}>
|
<div className={'articleItem blueprintItem' + (isActive ? ' active' : '')}>
|
||||||
<div className='itemLeft'>
|
<div className='itemLeft'>
|
||||||
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
@@ -72,7 +81,7 @@ module.exports = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='itemRight'>
|
<div className='itemRight'>
|
||||||
<div className='updatedAt'>{moment(article.updatedAt).fromNow()}</div>
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
<div className='description'>{article.title}</div>
|
<div className='description'>{article.title}</div>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ articleListWidth= 275px
|
|||||||
margin 0 2px
|
margin 0 2px
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
cursor pointer
|
cursor pointer
|
||||||
font-size 0.9em
|
font-size 0.95em
|
||||||
&.noTag
|
&.noTag
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
@@ -178,15 +178,18 @@ articleListWidth= 275px
|
|||||||
overflow-y auto
|
overflow-y auto
|
||||||
li
|
li
|
||||||
.articleItem
|
.articleItem
|
||||||
user-select none
|
|
||||||
border solid 2px transparent
|
border solid 2px transparent
|
||||||
padding 10px
|
position relative
|
||||||
|
height 94px
|
||||||
|
width 100%
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition 0.1s
|
transition 0.1s
|
||||||
clearfix()
|
|
||||||
.itemLeft
|
.itemLeft
|
||||||
float left
|
position absolute
|
||||||
width 25px
|
top 4px
|
||||||
|
bottom 4px
|
||||||
|
width 38px
|
||||||
|
padding 3px 0 3px 3px
|
||||||
text-align center
|
text-align center
|
||||||
.profileImage
|
.profileImage
|
||||||
margin-bottom 5px
|
margin-bottom 5px
|
||||||
@@ -194,18 +197,31 @@ articleListWidth= 275px
|
|||||||
.fa
|
.fa
|
||||||
line-height 25px
|
line-height 25px
|
||||||
.itemRight
|
.itemRight
|
||||||
float left
|
position absolute
|
||||||
width 225px
|
top 4px
|
||||||
|
bottom 4px
|
||||||
|
right 2px
|
||||||
|
left 40px
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
padding-left 10px
|
padding 3px 10px 3px 3px
|
||||||
.updatedAt
|
.itemInfo
|
||||||
margin-bottom 10px
|
margin 5px 0 13px
|
||||||
color lighten(textColor, 25%)
|
color lighten(textColor, 25%)
|
||||||
font-size 0.7em
|
font-size 0.7em
|
||||||
|
.userProfileName
|
||||||
|
color brandColor
|
||||||
|
font-size 1.2em
|
||||||
.description
|
.description
|
||||||
line-height 120%
|
line-height 120%
|
||||||
margin-bottom 15px
|
margin-bottom 10px
|
||||||
font-size 1em
|
font-size 1em
|
||||||
|
overflow-x hidden
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
.tags
|
||||||
|
position absolute
|
||||||
|
bottom 5px
|
||||||
|
font-size 0.9em
|
||||||
&:hover, &.hover
|
&:hover, &.hover
|
||||||
background-color hoverBackgroundColor
|
background-color hoverBackgroundColor
|
||||||
&:active, &.active
|
&:active, &.active
|
||||||
@@ -219,57 +235,71 @@ articleListWidth= 275px
|
|||||||
absolute right bottom
|
absolute right bottom
|
||||||
top 55px
|
top 55px
|
||||||
left navigationWidth + articleListWidth
|
left navigationWidth + articleListWidth
|
||||||
&>.viewer-header
|
.detailHeader
|
||||||
height 44px
|
border solid 2px transparent
|
||||||
line-height 44px
|
position relative
|
||||||
padding 0 15px
|
height 105px
|
||||||
box-sizing border-box
|
width 100%
|
||||||
font-size 1.2em
|
transition 0.1s
|
||||||
small
|
.itemLeft
|
||||||
font-size 0.8em
|
position absolute
|
||||||
color lighten(textColor, 25%)
|
top 7px
|
||||||
.control-group
|
bottom 4px
|
||||||
float right
|
width 38px
|
||||||
button
|
padding 3px 0 3px 3px
|
||||||
margin 10px 3px
|
text-align center
|
||||||
.viewer-body
|
.profileImage
|
||||||
absolute bottom right
|
margin-bottom 5px
|
||||||
left 1px
|
circle()
|
||||||
top 44px
|
.fa
|
||||||
&.codeDetail>.viewer-body
|
line-height 25px
|
||||||
.viewer-detail
|
.itemRight
|
||||||
border-bottom solid 1px borderColor
|
position absolute
|
||||||
height 150px
|
top 7px
|
||||||
box-sizing border-box
|
bottom 4px
|
||||||
padding 10px
|
right 2px
|
||||||
|
left 40px
|
||||||
|
overflow-x hidden
|
||||||
|
padding 3px 10px 3px 3px
|
||||||
|
.itemInfo
|
||||||
|
margin 5px 0 13px
|
||||||
|
color lighten(textColor, 25%)
|
||||||
|
font-size 0.7em
|
||||||
|
.userProfileName
|
||||||
|
color brandColor
|
||||||
|
font-size 1.2em
|
||||||
.description
|
.description
|
||||||
height 100px
|
line-height 120%
|
||||||
line-height 1.4em
|
margin-bottom 10px
|
||||||
overflow-y auto
|
font-size 1em
|
||||||
|
overflow-x auto
|
||||||
|
white-space nowrap
|
||||||
.tags
|
.tags
|
||||||
position absolute
|
position absolute
|
||||||
left 15px
|
|
||||||
right 15px
|
|
||||||
top 120px
|
|
||||||
.content
|
|
||||||
.ace_editor
|
|
||||||
absolute left right
|
|
||||||
top 155px
|
|
||||||
bottom 5px
|
bottom 5px
|
||||||
&.noteDetail>.viewer-body
|
font-size 0.9em
|
||||||
.tags
|
.itemControl
|
||||||
absolute top
|
position absolute
|
||||||
left 15px
|
z-index 1
|
||||||
right 15px
|
top 2px
|
||||||
height 24px
|
right 2px
|
||||||
line-height 24px
|
.detailBody
|
||||||
|
absolute left right bottom
|
||||||
|
top 105px
|
||||||
.content
|
.content
|
||||||
absolute left right bottom
|
|
||||||
top 30px
|
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
padding 5px
|
padding 5px
|
||||||
border-top solid 1px borderColor
|
border-top solid 1px borderColor
|
||||||
padding 10px
|
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
|
&.noteDetail
|
||||||
|
.detailBody .content
|
||||||
marked()
|
marked()
|
||||||
|
&.codeDetail
|
||||||
|
.detailBody .content
|
||||||
|
.ace_editor
|
||||||
|
position absolute
|
||||||
|
top 5px
|
||||||
|
bottom 5px
|
||||||
|
left 2px
|
||||||
|
right 2px
|
||||||
|
|||||||
@@ -105,14 +105,16 @@ textarea.block-input
|
|||||||
z-index 2000
|
z-index 2000
|
||||||
bottom 5px
|
bottom 5px
|
||||||
right 53px
|
right 53px
|
||||||
btnDefault()
|
btnPrimary()
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
|
background-color backgroundColor
|
||||||
.contactButton
|
.contactButton
|
||||||
position fixed
|
position fixed
|
||||||
z-index 2000
|
z-index 2000
|
||||||
bottom 5px
|
bottom 5px
|
||||||
right 5px
|
right 5px
|
||||||
btnDefault()
|
btnPrimary()
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
|
background-color backgroundColor
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ marked()
|
|||||||
padding 5px
|
padding 5px
|
||||||
border solid 1px borderColor
|
border solid 1px borderColor
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
margin 0.5em 0
|
margin-bottom 0.5em
|
||||||
overflow-x auto
|
overflow-x auto
|
||||||
&>code
|
&>code
|
||||||
padding 0
|
padding 0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "boost",
|
"name": "boost",
|
||||||
"version": "0.2.1",
|
"version": "0.2.1.1",
|
||||||
"description": "Boost App",
|
"description": "Boost App",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user