]> cat aescling's git repositories - mastodon.git/blob - app/javascript/glitch/components/status/header.js
Improvements to status headers
[mastodon.git] / app / javascript / glitch / components / status / header.js
1 /*
2
3 `<StatusHeader>`
4 ================
5
6 Originally a part of `<Status>`, but extracted into a separate
7 component for better documentation and maintainance by
8 @kibi@glitch.social as a part of glitch-soc/mastodon.
9
10 */
11
12 // * * * * * * * //
13
14 // Imports
15 // -------
16
17 // Package imports.
18 import React from 'react';
19 import PropTypes from 'prop-types';
20 import ImmutablePropTypes from 'react-immutable-proptypes';
21 import { defineMessages, injectIntl } from 'react-intl';
22
23 // Mastodon imports.
24 import Avatar from '../../../mastodon/components/avatar';
25 import AvatarOverlay from '../../../mastodon/components/avatar_overlay';
26 import DisplayName from '../../../mastodon/components/display_name';
27 import IconButton from '../../../mastodon/components/icon_button';
28 import VisibilityIcon from './visibility_icon';
29
30 // * * * * * * * //
31
32 // Initial setup
33 // -------------
34
35 // Messages for use with internationalization stuff.
36 const messages = defineMessages({
37 collapse: { id: 'status.collapse', defaultMessage: 'Collapse' },
38 uncollapse: { id: 'status.uncollapse', defaultMessage: 'Uncollapse' },
39 public: { id: 'privacy.public.short', defaultMessage: 'Public' },
40 unlisted: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
41 private: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
42 direct: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
43 });
44
45 // * * * * * * * //
46
47 // The component
48 // -------------
49
50 @injectIntl
51 export default class StatusHeader extends React.PureComponent {
52
53 static propTypes = {
54 status: ImmutablePropTypes.map.isRequired,
55 friend: ImmutablePropTypes.map,
56 mediaIcon: PropTypes.string,
57 collapsible: PropTypes.bool,
58 collapsed: PropTypes.bool,
59 parseClick: PropTypes.func.isRequired,
60 setExpansion: PropTypes.func.isRequired,
61 intl: PropTypes.object.isRequired,
62 };
63
64 // Handles clicks on collapsed button
65 handleCollapsedClick = (e) => {
66 const { collapsed, setExpansion } = this.props;
67 if (e.button === 0) {
68 setExpansion(collapsed ? null : false);
69 e.preventDefault();
70 }
71 }
72
73 // Handles clicks on account name/image
74 handleAccountClick = (e) => {
75 const { status, parseClick } = this.props;
76 parseClick(e, `/accounts/${+status.getIn(['account', 'id'])}`);
77 }
78
79 // Rendering.
80 render () {
81 const {
82 status,
83 friend,
84 mediaIcon,
85 collapsible,
86 collapsed,
87 intl,
88 } = this.props;
89
90 const account = status.get('account');
91
92 return (
93 <header className='status__info'>
94 <a
95 href={account.get('url')}
96 target='_blank'
97 className='status__avatar'
98 onClick={this.handleAccountClick}
99 >
100 {
101 friend ? (
102 <AvatarOverlay account={account} friend={friend} />
103 ) : (
104 <Avatar account={account} size={48} />
105 )
106 }
107 </a>
108 <a
109 href={account.get('url')}
110 target='_blank'
111 className='status__display-name'
112 onClick={this.handleAccountClick}
113 >
114 <DisplayName account={account} />
115 </a>
116 <div className='status__info__icons'>
117 {mediaIcon ? (
118 <i
119 className={`fa fa-fw fa-${mediaIcon}`}
120 aria-hidden='true'
121 />
122 ) : null}
123 {(
124 <VisibilityIcon visibility={status.get('visibility')} />
125 )}
126 {collapsible ? (
127 <IconButton
128 className='status__collapse-button'
129 animate flip
130 active={collapsed}
131 title={
132 collapsed ?
133 intl.formatMessage(messages.uncollapse) :
134 intl.formatMessage(messages.collapse)
135 }
136 icon='angle-double-up'
137 onClick={this.handleCollapsedClick}
138 />
139 ) : null}
140 </div>
141
142 </header>
143 );
144 }
145
146 }
This page took 0.158658 seconds and 6 git commands to generate.