kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Insert depth lines on status threads
rodzic
313d96e0f9
commit
0f7ebe539b
|
@ -94,6 +94,7 @@ class Status extends ImmutablePureComponent {
|
|||
group: ImmutablePropTypes.map,
|
||||
displayMedia: PropTypes.string,
|
||||
depth: PropTypes.number,
|
||||
hasDescendants: PropTypes.bool,
|
||||
};
|
||||
|
||||
// Avoid checking props that are functions (and whose equality will always
|
||||
|
@ -276,12 +277,19 @@ class Status extends ImmutablePureComponent {
|
|||
|
||||
const { intl, hidden, featured, otherAccounts, unread, showThread, group } = this.props;
|
||||
|
||||
let { status, account, depth, ...other } = this.props;
|
||||
let { status, account, depth, hasDescendants, ...other } = this.props;
|
||||
|
||||
if (status === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let ancestorLine = depth ? <div className='status__expand__ancestor-line' /> : '';
|
||||
let descendantLine = hasDescendants ? <div className='status__expand__descendant-line' /> : '';
|
||||
let depthLines = [];
|
||||
for (let i = 0; i < depth; i++) {
|
||||
depthLines.push(<div className='status__depth-lines__line' key={i} style={{ left: `${i * 30}px` }} />);
|
||||
}
|
||||
|
||||
if (hidden) {
|
||||
return (
|
||||
<div ref={this.handleRef}>
|
||||
|
@ -449,6 +457,9 @@ class Status extends ImmutablePureComponent {
|
|||
return (
|
||||
<HotKeys handlers={handlers}>
|
||||
<div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), read: unread === false, focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText)} ref={this.handleRef}>
|
||||
<div className='status__depth-lines'>
|
||||
{depthLines}
|
||||
</div>
|
||||
{prepend}
|
||||
|
||||
<div className={classNames('status', `status-${status.get('visibility')}`, `status__nested--${depth}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted, read: unread === false })} data-id={status.get('id')}>
|
||||
|
|
|
@ -37,6 +37,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
|||
showMedia: PropTypes.bool,
|
||||
onToggleMediaVisibility: PropTypes.func,
|
||||
depth: PropTypes.number,
|
||||
hasDescendants: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
@ -87,7 +88,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
|||
render() {
|
||||
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
|
||||
const outerStyle = { boxSizing: 'border-box' };
|
||||
const { compact, depth } = this.props;
|
||||
const { compact, depth, hasDescendants } = this.props;
|
||||
const favicon = status.getIn(['account', 'pleroma', 'favicon']);
|
||||
const domain = getDomain(status.get('account'));
|
||||
|
||||
|
@ -95,6 +96,13 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
|||
return null;
|
||||
}
|
||||
|
||||
let ancestorLine = depth ? <div className='status__expand__ancestor-line' /> : '';
|
||||
let descendantLine = hasDescendants ? <div className='status__expand__descendant-line' /> : '';
|
||||
let depthLines = [];
|
||||
for (let i = 0; i < depth; i++) {
|
||||
depthLines.push(<div className='status__depth-lines__line' key={i} style={{ left: `${i * 30}px` }} />);
|
||||
}
|
||||
|
||||
let media = '';
|
||||
let poll = '';
|
||||
let statusTypeIcon = '';
|
||||
|
@ -164,7 +172,14 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<div style={outerStyle}>
|
||||
<div className='status__depth-lines'>
|
||||
{depthLines}
|
||||
</div>
|
||||
<div ref={this.setRef} className={classNames('detailed-status', { compact })} style={{ paddingLeft: `${depth * 30 + 15}px` }}>
|
||||
<div className='status__expand' style={{ paddingLeft: `${depth * 30}px` }}>
|
||||
{ancestorLine}
|
||||
{descendantLine}
|
||||
</div>
|
||||
<div className='detailed-status__profile'>
|
||||
<div className='detailed-status__display-name'>
|
||||
<NavLink to={`/@${status.getIn(['account', 'acct'])}`}>
|
||||
|
|
|
@ -73,6 +73,7 @@ const makeMapStateToProps = () => {
|
|||
let ancestorsIds = Immutable.List();
|
||||
let descendantsIds = Immutable.List();
|
||||
let depths = {};
|
||||
let hasDescendants = {};
|
||||
|
||||
if (status) {
|
||||
depths[status.get('id')] = 0;
|
||||
|
@ -85,6 +86,12 @@ const makeMapStateToProps = () => {
|
|||
id = state.getIn(['contexts', 'inReplyTos', id]);
|
||||
}
|
||||
});
|
||||
let currentDepth = 0;
|
||||
ancestorsIds.forEach(ancestor => {
|
||||
depths[ancestor] = currentDepth++;
|
||||
hasDescendants[ancestor] = true;
|
||||
});
|
||||
depths[status.get('id')] = currentDepth;
|
||||
|
||||
descendantsIds = descendantsIds.withMutations(mutable => {
|
||||
const ids = [status.get('id')];
|
||||
|
@ -100,10 +107,13 @@ const makeMapStateToProps = () => {
|
|||
}
|
||||
|
||||
if (replies) {
|
||||
hasDescendants[id] = true;
|
||||
replies.reverse().forEach(reply => {
|
||||
ids.unshift(reply);
|
||||
depths[reply] = depth + 1;
|
||||
});
|
||||
} else {
|
||||
hasDescendants[id] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -117,6 +127,7 @@ const makeMapStateToProps = () => {
|
|||
domain: state.getIn(['meta', 'domain']),
|
||||
me: state.get('me'),
|
||||
depths,
|
||||
hasDescendants,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -400,6 +411,7 @@ class Status extends ImmutablePureComponent {
|
|||
onMoveDown={this.handleMoveDown}
|
||||
contextType='thread'
|
||||
depth={this.props.depths[id]}
|
||||
hasDescendants={this.props.hasDescendants[id]}
|
||||
/>
|
||||
));
|
||||
}
|
||||
|
@ -511,6 +523,7 @@ class Status extends ImmutablePureComponent {
|
|||
showMedia={this.state.showMedia}
|
||||
onToggleMediaVisibility={this.handleToggleMediaVisibility}
|
||||
depth={depth}
|
||||
hasDescendants={this.props.hasDescendants[status.get('id')]}
|
||||
/>
|
||||
|
||||
<ActionBar
|
||||
|
|
|
@ -125,6 +125,14 @@
|
|||
.video-player {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
&__profile {
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
.status__expand__ancestor-line {
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
.account__header__bar {padding: 5px 10px;}
|
||||
|
||||
|
@ -137,6 +145,10 @@
|
|||
padding: 15px 15px 15px (48px + 15px * 2);
|
||||
min-height: 48px + 2px;
|
||||
|
||||
&__depth-lines {
|
||||
left: 38px;
|
||||
}
|
||||
|
||||
&__avatar {
|
||||
left: 15px;
|
||||
top: 17px;
|
||||
|
@ -159,6 +171,19 @@
|
|||
.video-player {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&__expand__ancestor-line {
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.status__expand__ancestor-line {
|
||||
right: 28px;
|
||||
}
|
||||
|
||||
.status__expand__descendant-line {
|
||||
right: 28px;
|
||||
top: 66px;
|
||||
}
|
||||
|
||||
.account {
|
||||
|
|
|
@ -43,6 +43,19 @@
|
|||
.audio-player {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.status__expand__ancestor-line {
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.status__expand__descendant-line {
|
||||
top: 64px;
|
||||
}
|
||||
|
||||
&__profile {
|
||||
position: relative;
|
||||
right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.detailed-status__meta {
|
||||
|
|
|
@ -104,18 +104,22 @@
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.status__wrapper--filtered {
|
||||
color: var(--primary-text-color);
|
||||
border: 0;
|
||||
font-size: inherit;
|
||||
text-align: center;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
border-bottom: 1px solid var(--brand-color--med);
|
||||
.status__wrapper {
|
||||
position: relative;
|
||||
|
||||
&--filtered {
|
||||
color: var(--primary-text-color);
|
||||
border: 0;
|
||||
font-size: inherit;
|
||||
text-align: center;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
border-bottom: 1px solid var(--brand-color--med);
|
||||
}
|
||||
}
|
||||
|
||||
.status__prepend-icon-wrapper {
|
||||
|
@ -212,6 +216,46 @@
|
|||
}
|
||||
}
|
||||
|
||||
.status__depth-lines {
|
||||
position: absolute;
|
||||
left: 33px;
|
||||
height: 100%;
|
||||
|
||||
&__line {
|
||||
content: "";
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
display: inline;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
border-left: 1px solid var(--brand-color--faint);
|
||||
}
|
||||
}
|
||||
|
||||
.status__expand__ancestor-line {
|
||||
content: "";
|
||||
height: 9px;
|
||||
width: 1px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
border-left: 1px solid var(--brand-color--faint);
|
||||
right: 33px;
|
||||
}
|
||||
|
||||
.status__expand__descendant-line {
|
||||
content: "";
|
||||
height: auto;
|
||||
width: 1px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
border-left: 1px solid var(--brand-color--faint);
|
||||
right: 33px;
|
||||
top: 60px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.status__display-name {
|
||||
color: var(--primary-text-color--faint);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue