Thread: display status connectors (basic threading)

This commit is contained in:
Alex Gleason 2021-10-06 17:50:43 -05:00
parent cb0a034e85
commit 5807b8f823
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 89 additions and 3 deletions

View 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>
);
}
}

View file

@ -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

View file

@ -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);
}
}
}
}