More styling for statuses
This commit is contained in:
		
							
								
								
									
										17
									
								
								app/assets/javascripts/components/components/avatar.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/assets/javascripts/components/components/avatar.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| @@ -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; | ||||
| @@ -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; | ||||
| @@ -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> | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -357,7 +357,6 @@ body { | ||||
|   } | ||||
| } | ||||
|  | ||||
| @import 'home'; | ||||
| @import 'accounts'; | ||||
| @import 'stream_entries'; | ||||
| @import 'dashboard' | ||||
| @import 'components' | ||||
|   | ||||
							
								
								
									
										20
									
								
								app/assets/stylesheets/components.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/assets/stylesheets/components.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -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; | ||||
|   } | ||||
| } | ||||
| @@ -1,11 +0,0 @@ | ||||
| .api-descriptions { | ||||
|   .address { | ||||
|     samp { | ||||
|       font-weight: 400; | ||||
|  | ||||
|       &.method { | ||||
|         font-weight: 500; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -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/ | ||||
| @@ -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/ | ||||
		Reference in New Issue
	
	Block a user