Thread: display status connectors (basic threading)
This commit is contained in:
parent
cb0a034e85
commit
5807b8f823
3 changed files with 89 additions and 3 deletions
54
app/soapbox/features/status/components/thread_status.js
Normal file
54
app/soapbox/features/status/components/thread_status.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import StatusContainer from 'soapbox/containers/status_container';
|
||||
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const mapStateToProps = (state, { id }) => {
|
||||
return {
|
||||
replyToId: state.getIn(['statuses', id, 'in_reply_to_id']),
|
||||
replyCount: state.getIn(['contexts', 'replies', id], ImmutableOrderedSet()).size,
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class ThreadStatus extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
focusedStatusId: PropTypes.string,
|
||||
replyToId: PropTypes.string,
|
||||
replyCount: PropTypes.number,
|
||||
}
|
||||
|
||||
renderConnector() {
|
||||
const { focusedStatusId, replyToId, replyCount } = this.props;
|
||||
|
||||
const isConnectedTop = replyToId && replyToId !== focusedStatusId;
|
||||
const isConnectedBottom = replyCount > 0;
|
||||
const isConnected = isConnectedTop || isConnectedBottom;
|
||||
|
||||
if (!isConnected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('thread__connector', {
|
||||
'thread__connector--top': isConnectedTop,
|
||||
'thread__connector--bottom': isConnectedBottom,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='thread__status'>
|
||||
{this.renderConnector()}
|
||||
<StatusContainer {...this.props} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -37,7 +37,6 @@ import { initMuteModal } from '../../actions/mutes';
|
|||
import { initReport } from '../../actions/reports';
|
||||
import { makeGetStatus } from '../../selectors';
|
||||
// import ColumnHeader from '../../components/column_header';
|
||||
import StatusContainer from '../../containers/status_container';
|
||||
import { openModal } from '../../actions/modal';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
@ -49,6 +48,7 @@ import { textForScreenReader, defaultMediaVisibility } from '../../components/st
|
|||
import { getSettings } from 'soapbox/actions/settings';
|
||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||
import { deactivateUserModal, deleteUserModal, deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation';
|
||||
import ThreadStatus from './components/thread_status';
|
||||
import SubNavigation from 'soapbox/components/sub_navigation';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -471,10 +471,13 @@ class Status extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
renderStatus(id) {
|
||||
const { status } = this.props;
|
||||
|
||||
return (
|
||||
<StatusContainer
|
||||
<ThreadStatus
|
||||
key={id}
|
||||
id={id}
|
||||
focusedStatusId={status && status.get('id')}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType='thread'
|
||||
|
@ -600,7 +603,7 @@ class Status extends ImmutablePureComponent {
|
|||
<div className='thread__ancestors'>{ancestors}</div>
|
||||
)}
|
||||
|
||||
<div className='thread__status'>
|
||||
<div className='thread__status thread__status--focused'>
|
||||
<HotKeys handlers={handlers}>
|
||||
<div ref={this.setStatusRef} className={classNames('focusable', 'detailed-status__wrapper')} tabIndex='0' aria-label={textForScreenReader(intl, status, false)}>
|
||||
<DetailedStatus
|
||||
|
|
|
@ -157,3 +157,32 @@
|
|||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.thread {
|
||||
&__status {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__connector {
|
||||
background: hsla(var(--primary-text-color_hsl), 0.2);
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
left: 33px;
|
||||
display: none;
|
||||
|
||||
&--bottom {
|
||||
height: calc(100% - 8px - 48px - 14px);
|
||||
top: calc(8px + 48px + 13px);
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 630px) {
|
||||
left: 38px;
|
||||
|
||||
&--bottom {
|
||||
height: calc(100% - 15px - 48px);
|
||||
top: calc(15px + 48px + 9px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue