about summary refs log tree commit diff
path: root/app/assets/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/components/components/avatar.jsx17
-rw-r--r--app/assets/javascripts/components/components/display_name.jsx22
-rw-r--r--app/assets/javascripts/components/components/relative_timestamp.jsx55
-rw-r--r--app/assets/javascripts/components/components/status.jsx23
4 files changed, 113 insertions, 4 deletions
diff --git a/app/assets/javascripts/components/components/avatar.jsx b/app/assets/javascripts/components/components/avatar.jsx
new file mode 100644
index 000000000..7db3eeff7
--- /dev/null
+++ b/app/assets/javascripts/components/components/avatar.jsx
@@ -0,0 +1,17 @@
+const Avatar = React.createClass({
+
+  propTypes: {
+    src: React.PropTypes.string.isRequired
+  },
+
+  render () {
+    return (
+      <div style={{ width: '48px', height: '48px', flex: '0 0 auto' }}>
+        <img src={this.props.src} width={48} height={48} alt='' style={{ display: 'block', borderRadius: '4px' }} />
+      </div>
+    );
+  }
+
+});
+
+export default Avatar;
diff --git a/app/assets/javascripts/components/components/display_name.jsx b/app/assets/javascripts/components/components/display_name.jsx
new file mode 100644
index 000000000..97db31707
--- /dev/null
+++ b/app/assets/javascripts/components/components/display_name.jsx
@@ -0,0 +1,22 @@
+import ImmutablePropTypes from 'react-immutable-proptypes';
+
+const DisplayName = React.createClass({
+  propTypes: {
+    account: ImmutablePropTypes.map.isRequired
+  },
+
+  render () {
+    var displayName = this.props.account.get('display_name', this.props.account.get('username'));
+    var acct        = this.props.account.get('acct');
+    var url         = this.props.account.get('url');
+
+    return (
+      <a href={url} style={{ color: '#616b86', textDecoration: 'none' }}>
+        <strong style={{ fontWeight: 'bold', color: '#fff' }}>{displayName}</strong> <span>{acct}</span>
+      </a>
+    );
+  }
+
+});
+
+export default DisplayName;
diff --git a/app/assets/javascripts/components/components/relative_timestamp.jsx b/app/assets/javascripts/components/components/relative_timestamp.jsx
new file mode 100644
index 000000000..3216d0a0d
--- /dev/null
+++ b/app/assets/javascripts/components/components/relative_timestamp.jsx
@@ -0,0 +1,55 @@
+import moment from 'moment';
+
+moment.updateLocale('en', {
+  relativeTime : {
+    future: "in %s",
+    past:   "%s ago",
+    s:  "s",
+    m:  "a minute",
+    mm: "%dm",
+    h:  "an hour",
+    hh: "%dh",
+    d:  "a day",
+    dd: "%dd",
+    M:  "a month",
+    MM: "%dm",
+    y:  "a year",
+    yy: "%dy"
+  }
+});
+
+const RelativeTimestamp = React.createClass({
+  getInitialState () {
+    return {
+      text: ''
+    };
+  },
+
+  propTypes: {
+    timestamp: React.PropTypes.string.isRequired
+  },
+
+  componentWillMount () {
+    this._updateMomentText();
+    this.interval = setInterval(this._updateMomentText, 6000);
+  },
+
+  componentWillUnmount () {
+    clearInterval(this.interval);
+  },
+
+  _updateMomentText () {
+    this.setState({ text: moment(this.props.timestamp).fromNow() });
+  },
+
+  render () {
+    return (
+      <span style={{ color: '#616b86' }}>
+        {this.state.text}
+      </span>
+    );
+  }
+
+});
+
+export default RelativeTimestamp;
diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx
index 68c1efaad..e54bc8c04 100644
--- a/app/assets/javascripts/components/components/status.jsx
+++ b/app/assets/javascripts/components/components/status.jsx
@@ -1,17 +1,32 @@
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import Avatar             from './avatar';
+import DisplayName        from './display_name';
+import RelativeTimestamp  from './relative_timestamp';
 
 const Status = React.createClass({
   propTypes: {
     status: ImmutablePropTypes.map.isRequired
   },
 
-  render: function() {
+  render () {
     var content = { __html: this.props.status.get('content') };
+    var status  = this.props.status;
 
     return (
-      <div style={{ padding: '5px' }}>
-        <div><strong>{this.props.status.getIn(['account', 'username'])}</strong></div>
-        <div dangerouslySetInnerHTML={content} />
+      <div style={{ padding: '8px 10px', display: 'flex', flexDirection: 'row', borderBottom: '1px solid #363c4b' }}>
+        <Avatar src={status.getIn(['account', 'avatar'])} />
+
+        <div style={{ flex: '1 1 auto', marginLeft: '10px' }}>
+          <div style={{ overflow: 'hidden' }}>
+            <div style={{ float: 'right' }}>
+              <a href={status.get('url')} style={{ textDecoration: 'none' }}><RelativeTimestamp timestamp={status.get('created_at')} /></a>
+            </div>
+
+            <DisplayName account={status.get('account')} />
+          </div>
+
+          <div className='status__content' dangerouslySetInnerHTML={content} style={{ fontSize: '14px' }} />
+        </div>
       </div>
     );
   }