diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/components/components/avatar.jsx | 17 | ||||
-rw-r--r-- | app/assets/javascripts/components/components/display_name.jsx | 22 | ||||
-rw-r--r-- | app/assets/javascripts/components/components/relative_timestamp.jsx | 55 | ||||
-rw-r--r-- | app/assets/javascripts/components/components/status.jsx | 23 | ||||
-rw-r--r-- | app/assets/stylesheets/application.scss | 3 | ||||
-rw-r--r-- | app/assets/stylesheets/components.scss | 20 | ||||
-rw-r--r-- | app/assets/stylesheets/dashboard.scss | 356 | ||||
-rw-r--r-- | app/assets/stylesheets/home.scss | 11 | ||||
-rw-r--r-- | app/assets/stylesheets/settings.scss | 3 | ||||
-rw-r--r-- | app/assets/stylesheets/statuses.scss | 3 |
10 files changed, 134 insertions, 379 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> ); } diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 668b6f90d..a444a2ff2 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -357,7 +357,6 @@ body { } } -@import 'home'; @import 'accounts'; @import 'stream_entries'; -@import 'dashboard' +@import 'components' diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss new file mode 100644 index 000000000..0bec9ba80 --- /dev/null +++ b/app/assets/stylesheets/components.scss @@ -0,0 +1,20 @@ +.status__content { + a { + color: #2b90d9; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &.mention { + &:hover { + text-decoration: none; + + span { + text-decoration: underline; + } + } + } + } +} diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss deleted file mode 100644 index 983172bd0..000000000 --- a/app/assets/stylesheets/dashboard.scss +++ /dev/null @@ -1,356 +0,0 @@ -.dashboard-wrapper { - background: #282c37; - border-radius: 4px; - margin: 20px auto; - width: 940px; - display: flex; - overflow: hidden; - - .dashboard__sidebar { - width: 240px; - border-radius: 4px 0 0 4px; - flex-shrink: 0; - - .dashboard__top-bar { - border-radius: 4px 0 0 0; - } - - ul { - padding: 20px 0; - - a { - display: block; - padding: 7px 20px; - color: #d9e1e8; - text-decoration: none; - font-size: 14px; - font-weight: 400; - - .fa { - display: inline-block; - width: 18px; - text-align: center; - margin-right: 5px; - } - - &:hover { - color: #fff; - background: darken(#282c37, 1%); - } - } - - .active { - a { - background: darken(#282c37, 5%); - border-left: 2px solid #2b90d9; - padding-left: 18px; - } - } - } - } - - .dashboard__current-user { - padding: 20px; - - a { - text-decoration: none; - color: inherit; - outline: 0; - } - - .dashboard__current-user__avatar { - display: block; - width: 50px; - height: 50px; - border-radius: 50px; - float: left; - margin-right: 15px; - } - - .dashboard__current-user__display-name { - font-weight: 500; - font-size: 13px; - color: #d9e1e8; - display: block; - margin-top: 5px; - } - - .dashboard__current-user__username { - font-size: 12px; - display: block; - color: #2b90d9; - } - } - - .dashboard__logo { - color: #2b90d9; - - span { - font-weight: 500; - } - } - - .dashboard__top-bar { - background: #fff; - padding: 20px; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); - color: #282c37; - font-size: 16px; - overflow: hidden; - - &.alternate { - background: lighten(#282c37, 10%); - text-align: center; - } - - ul { - float: right; - list-style: none; - display: block; - - li { - display: inline-block; - margin-left: 7px; - } - } - - a { - color: #9baec8; - text-decoration: none; - } - } - - .dashboard__content { - flex: 1; - background: #d9e1e8; - border-radius: 0 4px 4px 0; - - .dashboard__top-bar { - border-radius: 0 4px 0 0; - } - } -} - -.dashboard__content__content { - padding: 20px; - color: #282c37; - line-height: 18px; - - h3 { - font-size: 14px; - font-weight: 500; - margin-bottom: 15px; - } - - p { - margin-bottom: 15px; - } - - samp { - font-family: 'Roboto Mono', monospace; - } - - ul { - list-style: circle; - padding-left: 15px; - margin-bottom: 15px; - } - - .table { - width: 100%; - - th { - font-weight: 500; - text-align: left; - border-bottom: 1px solid lighten(#282c37, 55%); - } - - th, td { - padding: 5px 0; - line-height: 18px; - } - } - - a { - color: #2b90d9; - text-decoration: underline; - - &:hover { - text-decoration: none; - } - } - - .btn { - display: inline-block; - border: 0; - background: #2b90d9; - border-radius: 16px; - padding: 6px 16px; - font-size: 12px; - font-weight: 500; - color: #fff; - cursor: pointer; - font-family: 'Roboto', sans-serif; - text-decoration: none; - - &:hover { - background: lighten(#2b90d9, 5%); - } - - &.btn-iconized { - font-size: 16px; - font-weight: 400; - width: 24px; - text-align: center; - padding: 10px 7px; - border-radius: 100px; - box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); - } - } - - hr { - clear: both; - border: 0; - padding: 0; - width: 100%; - height: 0; - margin: 30px 0; - } -} - -.simple_form { - .form-actions { - padding-top: 20px; - text-align: center; - } - - .error_notification { - color: #df405a; - font-weight: 500; - margin-bottom: 15px; - } - - .input { - margin-bottom: 15px; - - label { - display: block; - text-transform: uppercase; - font-size: 11px; - font-weight: 500; - margin-bottom: 10px; - } - - input[type=text], input[type=email], input[type=password], textarea { - display: block; - box-sizing: border-box; - width: 100%; - border: 0; - background: transparent; - border-bottom: 1px solid lighten(#282c37, 55%); - padding: 5px 0; - outline: 0; - padding-bottom: 6px; - font-size: 14px; - font-family: 'Roboto', sans-serif; - color: #282c37; - - &:focus, &:active { - border-bottom: 2px solid #2b90d9; - padding-bottom: 5px; - } - } - - input[type=file] { - display: block; - } - - .hint { - display: block; - margin-top: 5px; - color: lighten(#282c37, 25%); - } - - &.field_with_errors { - input[type=text], input[type=email], input[type=password], textarea { - border-bottom: 2px solid #df405a; - padding-bottom: 5px; - - &:focus, &:active { - border-bottom: 2px solid #2b90d9; - padding-bottom: 5px; - } - } - - .error { - display: block; - margin-top: 5px; - color: #df405a; - } - } - } -} - -.panel { - box-sizing: border-box; - padding: 10px 15px; - background: lighten(#d9e1e8, 5%); - margin-bottom: 20px; - border-radius: 4px; - - .panel-heading { - font-size: 13px; - text-transform: uppercase; - color: lighten(#282c37, 25%); - margin-bottom: 10px; - } - - &.panel-full { - width: 100%; - } - - .panel-row { - display: flex; - - dt { - color: #282c37; - width: 100px; - } - - dd { - flex: 1; - color: lighten(#282c37, 25%); - } - - &.panel-row-wider { - dt { - width: auto; - flex: 1; - } - } - } -} - -.row { - overflow: hidden; - clear: both; - - .panel { - float: left; - width: 320px; - margin-right: 20px; - - &:last-child { - margin-right: 0; - } - } -} - -.page-actions { - margin-top: 20px; - text-align: right; - - .btn { - margin-left: 5px; - } -} diff --git a/app/assets/stylesheets/home.scss b/app/assets/stylesheets/home.scss deleted file mode 100644 index c9f2740ad..000000000 --- a/app/assets/stylesheets/home.scss +++ /dev/null @@ -1,11 +0,0 @@ -.api-descriptions { - .address { - samp { - font-weight: 400; - - &.method { - font-weight: 500; - } - } - } -} diff --git a/app/assets/stylesheets/settings.scss b/app/assets/stylesheets/settings.scss deleted file mode 100644 index fbe669080..000000000 --- a/app/assets/stylesheets/settings.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the settings controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/statuses.scss b/app/assets/stylesheets/statuses.scss deleted file mode 100644 index bb9365adc..000000000 --- a/app/assets/stylesheets/statuses.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the statuses controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ |