mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-22 23:20:44 +01:00
More styling for statuses
This commit is contained in:
parent
bc0692d75b
commit
a541e937ca
11 changed files with 135 additions and 379 deletions
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 ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
import Avatar from './avatar';
|
||||||
|
import DisplayName from './display_name';
|
||||||
|
import RelativeTimestamp from './relative_timestamp';
|
||||||
|
|
||||||
const Status = React.createClass({
|
const Status = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
status: ImmutablePropTypes.map.isRequired
|
status: ImmutablePropTypes.map.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render () {
|
||||||
var content = { __html: this.props.status.get('content') };
|
var content = { __html: this.props.status.get('content') };
|
||||||
|
var status = this.props.status;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '5px' }}>
|
<div style={{ padding: '8px 10px', display: 'flex', flexDirection: 'row', borderBottom: '1px solid #363c4b' }}>
|
||||||
<div><strong>{this.props.status.getIn(['account', 'username'])}</strong></div>
|
<Avatar src={status.getIn(['account', 'avatar'])} />
|
||||||
<div dangerouslySetInnerHTML={content} />
|
|
||||||
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,7 +357,6 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import 'home';
|
|
||||||
@import 'accounts';
|
@import 'accounts';
|
||||||
@import 'stream_entries';
|
@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/
|
|
|
@ -12,6 +12,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
|
"moment": "^2.14.1",
|
||||||
"react-immutable-proptypes": "^2.1.0",
|
"react-immutable-proptypes": "^2.1.0",
|
||||||
"react-redux": "^4.4.5",
|
"react-redux": "^4.4.5",
|
||||||
"redux": "^3.5.2",
|
"redux": "^3.5.2",
|
||||||
|
|
Loading…
Reference in a new issue