*/
- /* * * * */
+// * * * * * * * //
-/*
-
-Imports:
---------
+// Imports
+// -------
-*/
-
-// Package imports //
+// Package imports.
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl } from 'react-intl';
-// Mastodon imports //
+// Mastodon imports.
import Avatar from '../../../mastodon/components/avatar';
import AvatarOverlay from '../../../mastodon/components/avatar_overlay';
import DisplayName from '../../../mastodon/components/display_name';
import IconButton from '../../../mastodon/components/icon_button';
import VisibilityIcon from './visibility_icon';
- /* * * * */
-
-/*
-
-Inital setup:
--------------
+// * * * * * * * //
-The `messages` constant is used to define any messages that we need
-from inside props. In our case, these are the `collapse` and
-`uncollapse` messages used with our collapse/uncollapse buttons.
-
-*/
+// Initial setup
+// -------------
+// Messages for use with internationalization stuff.
const messages = defineMessages({
collapse: { id: 'status.collapse', defaultMessage: 'Collapse' },
uncollapse: { id: 'status.uncollapse', defaultMessage: 'Uncollapse' },
direct: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
});
- /* * * * */
-
-/*
-
-The `<StatusHeader>` component:
--------------------------------
-
-The `<StatusHeader>` component wraps together the header information
-(avatar, display name) and upper buttons and icons (collapsing, media
-icons) into a single `<header>` element.
-
-### Props
-
- - __`account`, `friend` (`ImmutablePropTypes.map`) :__
- These give the accounts associated with the status. `account` is
- the author of the post; `friend` will have their avatar appear
- in the overlay if provided.
-
- - __`mediaIcon` (`PropTypes.string`) :__
- If a mediaIcon should be placed in the header, this string
- specifies it.
-
- - __`collapsible`, `collapsed` (`PropTypes.bool`) :__
- These props tell whether a post can be, and is, collapsed.
-
- - __`parseClick` (`PropTypes.func`) :__
- This function will be called when the user clicks inside the header
- information.
-
- - __`setExpansion` (`PropTypes.func`) :__
- This function is used to set the expansion state of the post.
+// * * * * * * * //
- - __`intl` (`PropTypes.object`) :__
- This is our internationalization object, provided by
- `injectIntl()`.
-
-*/
+// The component
+// -------------
@injectIntl
export default class StatusHeader extends React.PureComponent {
intl: PropTypes.object.isRequired,
};
-/*
-
-### Implementation
-
-#### `handleCollapsedClick()`.
-
-`handleCollapsedClick()` is just a simple callback for our collapsing
-button. It calls `setExpansion` to set the collapsed state of the
-status.
-
-*/
-
+ // Handles clicks on collapsed button
handleCollapsedClick = (e) => {
const { collapsed, setExpansion } = this.props;
if (e.button === 0) {
}
}
-/*
-
-#### `handleAccountClick()`.
-
-`handleAccountClick()` handles any clicks on the header info. It calls
-`parseClick()` with our `account` as the anticipatory `destination`.
-
-*/
-
+ // Handles clicks on account name/image
handleAccountClick = (e) => {
const { status, parseClick } = this.props;
parseClick(e, `/accounts/${+status.getIn(['account', 'id'])}`);
}
-/*
-
-#### `render()`.
-
-`render()` actually puts our element on the screen. `<StatusHeader>`
-has a very straightforward rendering process.
-
-*/
-
+ // Rendering.
render () {
const {
status,
return (
<header className='status__info'>
- {
-
-/*
-
-We have to include the status icons before the header content because
-it is rendered as a float.
-
-*/
-
- }
+ <a
+ href={account.get('url')}
+ target='_blank'
+ className='status__avatar'
+ onClick={this.handleAccountClick}
+ >
+ {
+ friend ? (
+ <AvatarOverlay account={account} friend={friend} />
+ ) : (
+ <Avatar account={account} size={48} />
+ )
+ }
+ </a>
+ <a
+ href={account.get('url')}
+ target='_blank'
+ className='status__display-name'
+ onClick={this.handleAccountClick}
+ >
+ <DisplayName account={account} />
+ </a>
<div className='status__info__icons'>
{mediaIcon ? (
<i
/>
) : null}
</div>
- {
-
-/*
-
-This begins our header content. It is all wrapped inside of a link
-which gets handled by `handleAccountClick`. We use an `<AvatarOverlay>`
-if we have a `friend` and a normal `<Avatar>` if we don't.
-
-*/
-
- }
- <a
- href={account.get('url')}
- target='_blank'
- className='status__display-name'
- onClick={this.handleAccountClick}
- >
- <div className='status__avatar'>{
- friend ? (
- <AvatarOverlay account={account} friend={friend} />
- ) : (
- <Avatar account={account} size={48} />
- )
- }</div>
- <DisplayName account={account} />
- </a>
</header>
);
.status__content,
.reply-indicator__content {
position: relative;
+ padding: 5px 12px;
font-size: 15px;
line-height: 20px;
color: $primary-text-color;
.status {
padding: 8px 10px;
- padding-left: 68px;
position: relative;
height: auto;
min-height: 48px;
content: "";
}
- .status__display-name:hover strong {
+ .display-name:hover .display-name__html {
text-decoration: none;
}
}
.status__display-name {
+ margin: 0 auto 0 0;
color: $ui-base-lighter-color;
}
-.status__info .status__display-name {
- display: block;
- max-width: 100%;
-}
-
.status__info {
- margin: 2px 0 0;
+ display: flex;
+ margin: 2px 0 5px;
font-size: 15px;
line-height: 24px;
}
.status__info__icons {
- display: inline-block;
+ flex: none;
position: relative;
- float: right;
color: lighten($ui-base-color, 26%);
- z-index: 5; // to make it clickable
.status__visibility-icon {
padding-left: 6px;
.status__action-bar {
align-items: center;
display: flex;
- margin-top: 10px;
- margin-left: -58px;
-
- &::before {
- display: block;
- flex: 1 1 0;
- max-width: 58px;
- content: "";
- }
+ margin: 10px 12px 0;
}
.status__action-bar-button {
}
}
-.status__display-name,
-.reply-indicator__display-name,
-.detailed-status__display-name,
-.account__display-name {
- &:hover strong {
- text-decoration: underline;
- }
-}
-
.account__display-name strong {
display: block;
}
}
.status__avatar {
- position: absolute;
- margin-left: -58px;
+ flex: none;
+ margin: 0 10px 0 0;
height: 48px;
width: 48px;
}
.display-name {
display: block;
- position: relative;
+ padding: 6px 0;
max-width: 100%;
- //overflow: hidden;
- //text-overflow: ellipsis;
- //white-space: nowrap;
-}
+ height: 36px;
+ overflow: hidden;
-.display-name__html {
- font-weight: 500;
-}
+ strong {
+ display: block;
+ height: 18px;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 18px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
-.display-name__account {
- font-size: 14px;
- display: block;
- line-height: 1.1; // reduce the distance from the display name
- padding-bottom: 3px;
+ span {
+ display: block;
+ height: 18px;
+ font-size: 15px;
+ line-height: 18px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
- // block ellipsis
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
+ &:hover {
+ strong {
+ text-decoration: underline;
+ }
+ }
}
.status__relative-time,
flex-direction: column;
.status__display-name {
- display: block;
- max-width: 100%;
- padding-right: 25px;
- }
-
- .status__avatar {
- height: 28px;
- left: 10px;
- position: absolute;
- top: 10px;
- width: 48px;
+ display: flex;
}
}