diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2018-10-07 23:44:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-07 23:44:58 +0200 |
commit | 774ac473736cbf348827cf6d861e7fbbb72d7623 (patch) | |
tree | c8ce87b43cd8fa58f7124a8a6baf93a71cb274e8 /app/javascript/mastodon/features/direct_timeline/components/conversation.js | |
parent | 25744d43b0c9ae58227e1e46ac9e2b33a7944925 (diff) |
Add conversations API (#8832)
* Add conversations API * Add web UI for conversations * Add test for conversations API * Add tests for ConversationAccount * Improve web UI * Rename ConversationAccount to AccountConversation * Remove conversations on block and mute * Change last_status_id to be a denormalization of status_ids * Add optimistic locking
Diffstat (limited to 'app/javascript/mastodon/features/direct_timeline/components/conversation.js')
-rw-r--r-- | app/javascript/mastodon/features/direct_timeline/components/conversation.js | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.js new file mode 100644 index 000000000..f9a8d4f72 --- /dev/null +++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.js @@ -0,0 +1,85 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import StatusContent from '../../../components/status_content'; +import RelativeTimestamp from '../../../components/relative_timestamp'; +import DisplayName from '../../../components/display_name'; +import Avatar from '../../../components/avatar'; +import AttachmentList from '../../../components/attachment_list'; +import { HotKeys } from 'react-hotkeys'; + +export default class Conversation extends ImmutablePureComponent { + + static contextTypes = { + router: PropTypes.object, + }; + + static propTypes = { + conversationId: PropTypes.string.isRequired, + accounts: ImmutablePropTypes.list.isRequired, + lastStatus: ImmutablePropTypes.map.isRequired, + onMoveUp: PropTypes.func, + onMoveDown: PropTypes.func, + }; + + handleClick = () => { + if (!this.context.router) { + return; + } + + const { lastStatus } = this.props; + this.context.router.history.push(`/statuses/${lastStatus.get('id')}`); + } + + handleHotkeyMoveUp = () => { + this.props.onMoveUp(this.props.conversationId); + } + + handleHotkeyMoveDown = () => { + this.props.onMoveDown(this.props.conversationId); + } + + render () { + const { accounts, lastStatus, lastAccount } = this.props; + + if (lastStatus === null) { + return null; + } + + const handlers = { + moveDown: this.handleHotkeyMoveDown, + moveUp: this.handleHotkeyMoveUp, + open: this.handleClick, + }; + + let media; + + if (lastStatus.get('media_attachments').size > 0) { + media = <AttachmentList compact media={lastStatus.get('media_attachments')} />; + } + + return ( + <HotKeys handlers={handlers}> + <div className='conversation focusable' tabIndex='0' onClick={this.handleClick} role='button'> + <div className='conversation__header'> + <div className='conversation__avatars'> + <div>{accounts.map(account => <Avatar key={account.get('id')} size={36} account={account} />)}</div> + </div> + + <div className='conversation__time'> + <RelativeTimestamp timestamp={lastStatus.get('created_at')} /> + <br /> + <DisplayName account={lastAccount} withAcct={false} /> + </div> + </div> + + <StatusContent status={lastStatus} onClick={this.handleClick} /> + + {media} + </div> + </HotKeys> + ); + } + +} |