diff --git a/bower.json b/bower.json index 547988d2..1f801466 100644 --- a/bower.json +++ b/bower.json @@ -4,6 +4,7 @@ "react": "~0.13.3", "fontawesome": "~4.3.0", "react-router": "~0.13.3", - "reflux": "~0.2.8" + "reflux": "~0.2.8", + "moment": "~2.10.3" } } diff --git a/browser/main/Containers/PlanetContainer.jsx b/browser/main/Containers/PlanetContainer.jsx index 60e4265a..0763ef8c 100644 --- a/browser/main/Containers/PlanetContainer.jsx +++ b/browser/main/Containers/PlanetContainer.jsx @@ -1,5 +1,7 @@ var React = require('react/addons') var ReactRouter = require('react-router') +var moment = require('moment') +var ForceUpdate = require('../Mixins/ForceUpdate') var ModalBase = require('../Components/ModalBase') var LaunchModal = require('../Components/LaunchModal') var CodeViewer = require('../Components/CodeViewer') @@ -109,7 +111,7 @@ var PlanetNavigator = React.createClass({ }) var PlanetArticleList = React.createClass({ - mixins: [ReactRouter.Navigation, ReactRouter.State], + mixins: [ReactRouter.Navigation, ReactRouter.State, ForceUpdate(60000)], propTypes: { planet: React.PropTypes.shape({ Snippets: React.PropTypes.array, @@ -118,11 +120,13 @@ var PlanetArticleList = React.createClass({ }, render: function () { var articles = this.props.planet.Snippets.map(function (snippet) { - var tags = snippet.Tags.map(function (tag) { + var tags = snippet.Tags.length > 0 ? snippet.Tags.map(function (tag) { return ( #{tag.name} ) - }) + }) : ( + Not tagged yet + ) var params = this.getParams() var isActive = parseInt(params.localId, 10) === snippet.localId @@ -138,9 +142,11 @@ var PlanetArticleList = React.createClass({ return (
  • -
    {snippet.callSign}
    -
    {snippet.description}
    -
    {snippet.updatedAt}
    +
    +
    {snippet.callSign}
    +
    {moment(snippet.updatedAt).fromNow()}
    +
    +
    {snippet.description.length > 50 ? snippet.description.substring(0, 50) + ' …' : snippet.description}
    {tags}
    @@ -159,6 +165,7 @@ var PlanetArticleList = React.createClass({ }) var PlanetArticleDetail = React.createClass({ + mixins: [ForceUpdate(60000)], propTypes: { snippet: React.PropTypes.object }, @@ -188,16 +195,18 @@ var PlanetArticleDetail = React.createClass({ render: function () { var snippet = this.props.snippet - var tags = snippet.Tags.map(function (tag) { + var tags = snippet.Tags.length > 0 ? snippet.Tags.map(function (tag) { return ( #{tag.name} ) - }) + }) : ( + Not tagged yet + ) return (
    - {snippet.callSign} {snippet.updatedAt} + {snippet.callSign} {moment(snippet.updatedAt).fromNow()} diff --git a/browser/main/Mixins/ForceUpdate.js b/browser/main/Mixins/ForceUpdate.js new file mode 100644 index 00000000..db49bc8e --- /dev/null +++ b/browser/main/Mixins/ForceUpdate.js @@ -0,0 +1,14 @@ +var ForceUpdate = function (interval) { + return { + componentDidMount: function () { + this.refreshTimer = setInterval(function () { + this.forceUpdate() + }.bind(this), interval) + }, + componentWillUnmount: function () { + clearInterval(this.refreshTimer) + } + } +} + +module.exports = ForceUpdate diff --git a/browser/main/Stores/PlanetStore.js b/browser/main/Stores/PlanetStore.js index 1916899b..121ea87e 100644 --- a/browser/main/Stores/PlanetStore.js +++ b/browser/main/Stores/PlanetStore.js @@ -36,6 +36,7 @@ var PlanetStore = Reflux.createStore({ }.bind(this)) }, createSnippet: function (planetName, input) { + input.description = input.description.substring(0, 255) request .post('http://localhost:8000/' + planetName + '/snippets') .set({ @@ -51,6 +52,7 @@ var PlanetStore = Reflux.createStore({ }.bind(this)) }, updateSnippet: function (id, input) { + input.description = input.description.substring(0, 255) request .put('http://localhost:8000/snippets/id/' + id) .set({ diff --git a/browser/main/index.html b/browser/main/index.html index b05a8ee4..5ad8cda6 100644 --- a/browser/main/index.html +++ b/browser/main/index.html @@ -39,7 +39,7 @@ }); } - + diff --git a/browser/styles/main/containers/PlanetContainer.styl b/browser/styles/main/containers/PlanetContainer.styl index dd7f9bb1..46bb3727 100644 --- a/browser/styles/main/containers/PlanetContainer.styl +++ b/browser/styles/main/containers/PlanetContainer.styl @@ -3,8 +3,13 @@ absolute top bottom right left 50px .tags + white-space: nowrap; + overflow-x: auto; a margin 0 2px + &.noTag + color inactiveTextColor + font-size 0.8em .PlanetHeader absolute left right top @@ -134,15 +139,20 @@ padding 10px cursor pointer transition 0.1s + .itemHeader + clearfix() + margin-bottom 5px .callSign - margin-bottom 5px + float left font-weight 600 - .description - margin-bottom 5px + font-size 1.1em .updatedAt - margin-bottom 5px + float right + line-height 16px color lighten(textColor, 25%) font-size 0.8em + .description + margin 10px 0 15px &:hover, &.hover background-color hoverBackgroundColor &:active, &.active @@ -160,24 +170,35 @@ height 44px line-height 44px padding 0 15px - border-bottom solid 1px borderColor box-sizing border-box + font-size 1.2em small - font-size 0.5em + font-size 0.8em + color lighten(textColor, 25%) .control-group float right button - margin 0 2px + margin 10px 3px .viewer-body absolute bottom right left 1px top 44px .viewer-detail border-bottom solid 1px borderColor + height 150px + box-sizing border-box padding 10px .description - margin-bottom 15px + height 100px + line-height 1.4em + overflow-y auto + .tags + position absolute + left 15px + right 15px + top 120px .content - padding 5px 0 .ace_editor - height 500px + absolute left right + top 155px + bottom 5px diff --git a/browser/styles/main/index.styl b/browser/styles/main/index.styl index 93dac151..282c5534 100644 --- a/browser/styles/main/index.styl +++ b/browser/styles/main/index.styl @@ -9,6 +9,7 @@ global-reset() body font-family "Lato" color textColor + font-size fontSize h1 font-size 2em diff --git a/browser/styles/shared/modal.styl b/browser/styles/shared/modal.styl index ac3ad7a9..ad517ae9 100644 --- a/browser/styles/shared/modal.styl +++ b/browser/styles/shared/modal.styl @@ -50,6 +50,7 @@ border-bottom-right-radius 10px textarea.snippetDescription height 75px + font-size 0.9em .Select .Select-control border-color borderColor diff --git a/browser/styles/vars.styl b/browser/styles/vars.styl index 36fa37e3..78c60e2b 100644 --- a/browser/styles/vars.styl +++ b/browser/styles/vars.styl @@ -9,11 +9,11 @@ lightButtonColor = #898989 hoverBackgroundColor= transparentify(#444, 3%) - // v0.2.0 inactiveTextColor = #888 textColor = #4D4D4D backgroundColor= white +fontSize= 16px btnColor = #888 btnHighlightenColor = #000 diff --git a/webpack.config.js b/webpack.config.js index 2ad54ced..578856d0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,14 +3,13 @@ module.exports = { main: './browser/main/index.jsx' }, output: { - filename: '[name].js', //this is the default name, so you can skip it + filename: '[name].js', publicPath: 'http://localhost:8090/assets' }, - devtool: "#inline-source-map", // Sourcemap + devtool: '#inline-source-map', module: { loaders: [ { - //tell webpack to use jsx-loader for all *.jsx files test: /\.jsx$/, loader: 'jsx-loader?insertPragma=React.DOM&harmony' }, @@ -25,13 +24,12 @@ module.exports = { ] }, externals: { - //don't bundle the 'react' npm package with our bundle.js - //but get it from a global 'React' variable 'react': 'React', 'react/addons': 'React', 'react-router': 'ReactRouter', 'ace': 'ace', - 'reflux': 'Reflux' + 'reflux': 'Reflux', + 'moment': 'moment' }, resolve: { extensions: ['', '.js', '.jsx']