mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-23 09:45:46 +03:00
Status thread page improvements
- Show level 3 comments - Change header-tap to scroll top to a button instead (prevent accidental scroll top) - Show avatars in <summary> - Clean up CSS a bit
This commit is contained in:
parent
ae90b41aae
commit
a088b48eb7
3 changed files with 196 additions and 82 deletions
161
src/app.css
161
src/app.css
|
@ -148,17 +148,26 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline.contextual {
|
||||||
|
--thread-start: 40px;
|
||||||
|
--line-start: 40px;
|
||||||
|
--line-width: 3px;
|
||||||
|
--line-end: calc(var(--line-start) + var(--line-width));
|
||||||
|
--line-margin-end: 16px;
|
||||||
|
--line-radius: 10px;
|
||||||
|
--line-diameter: calc(var(--line-radius) * 2);
|
||||||
|
--avatar-size: 50px;
|
||||||
|
--avatar-margin-start: 16px;
|
||||||
|
--avatar-margin-end: 12px;
|
||||||
|
}
|
||||||
.timeline.contextual > li {
|
.timeline.contextual > li {
|
||||||
--width: 3px;
|
|
||||||
--left: 40px;
|
|
||||||
--right: calc(var(--left) + var(--width));
|
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
to right,
|
to right,
|
||||||
transparent,
|
transparent,
|
||||||
transparent var(--left),
|
transparent var(--line-start),
|
||||||
var(--comment-line-color) var(--left),
|
var(--comment-line-color) var(--line-start),
|
||||||
var(--comment-line-color) var(--right),
|
var(--comment-line-color) var(--line-end),
|
||||||
transparent var(--right),
|
transparent var(--line-end),
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -184,41 +193,83 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
> .status-link
|
> .status-link
|
||||||
+ .replies
|
+ .replies
|
||||||
> summary {
|
> summary {
|
||||||
margin-left: calc(50px + 16px + 12px);
|
margin-left: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.timeline.contextual
|
||||||
|
> li.descendant.thread
|
||||||
|
> .status-link
|
||||||
|
+ .replies
|
||||||
|
.replies
|
||||||
|
> summary {
|
||||||
|
margin-left: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
|
||||||
|
var(--line-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual
|
.timeline.contextual
|
||||||
> li.descendant.thread
|
> li.descendant.thread
|
||||||
> .status-link
|
> .status-link
|
||||||
+ .replies
|
+ .replies
|
||||||
.status-link {
|
.status-link {
|
||||||
padding-left: calc(50px + 16px + 12px);
|
padding-left: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.timeline.contextual
|
||||||
|
> li.descendant.thread
|
||||||
|
> .status-link
|
||||||
|
+ .replies
|
||||||
|
.replies
|
||||||
|
.status-link {
|
||||||
|
padding-left: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
|
||||||
|
var(--line-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual
|
.timeline.contextual
|
||||||
> li.descendant:not(.thread)
|
> li.descendant:not(.thread)
|
||||||
> .status-link
|
> .status-link
|
||||||
+ .replies
|
+ .replies
|
||||||
> summary {
|
> summary {
|
||||||
margin-left: calc(40px + 16px);
|
margin-left: calc(var(--thread-start) + var(--line-margin-end));
|
||||||
|
}
|
||||||
|
.timeline.contextual
|
||||||
|
> li.descendant:not(.thread)
|
||||||
|
> .status-link
|
||||||
|
+ .replies
|
||||||
|
.replies
|
||||||
|
> summary {
|
||||||
|
margin-left: calc(
|
||||||
|
var(--thread-start) + var(--line-margin-end) + var(--line-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual
|
.timeline.contextual
|
||||||
> li.descendant:not(.thread)
|
> li.descendant:not(.thread)
|
||||||
> .status-link
|
> .status-link
|
||||||
+ .replies
|
+ .replies
|
||||||
.status-link {
|
.status-link {
|
||||||
padding-left: calc(40px + 16px);
|
padding-left: calc(var(--thread-start) + var(--line-margin-end));
|
||||||
|
}
|
||||||
|
.timeline.contextual
|
||||||
|
> li.descendant:not(.thread)
|
||||||
|
> .status-link
|
||||||
|
+ .replies
|
||||||
|
.replies
|
||||||
|
.status-link {
|
||||||
|
--line-margin-end: 32px;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li.descendant:not(.thread):before {
|
.timeline.contextual > li.descendant:not(.thread):before {
|
||||||
--radius: 10px;
|
|
||||||
--diameter: calc(var(--radius) * 2);
|
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 40px;
|
left: var(--line-start);
|
||||||
width: var(--diameter);
|
width: var(--line-diameter);
|
||||||
height: var(--diameter);
|
height: var(--line-diameter);
|
||||||
border-radius: var(--radius);
|
border-radius: var(--line-radius);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: var(--width);
|
border-width: var(--line-width);
|
||||||
border-color: transparent transparent var(--comment-line-color) transparent;
|
border-color: transparent transparent var(--comment-line-color) transparent;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +281,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li.thread > .status-link .replies-link {
|
.timeline.contextual > li.thread > .status-link .replies-link {
|
||||||
margin-left: calc(50px + 16px + 12px);
|
margin-left: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies-link * {
|
.timeline.contextual > li .replies-link * {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -243,7 +296,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies summary {
|
.timeline.contextual > li .replies > summary {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
background-color: var(--bg-faded-color);
|
background-color: var(--bg-faded-color);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -256,9 +309,16 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
box-shadow: 0 0 0 2px var(--bg-color);
|
box-shadow: 0 0 0 2px var(--bg-color);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
list-style: none;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies summary:active,
|
.timeline.contextual > li .replies > summary > * {
|
||||||
.timeline.contextual > li .replies[open] summary {
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.timeline.contextual > li .replies > summary .avatars {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.timeline.contextual > li .replies > summary:active,
|
||||||
|
.timeline.contextual > li .replies[open] > summary {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
background-color: var(--comment-line-color);
|
background-color: var(--comment-line-color);
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
|
@ -267,7 +327,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
var(--bg-faded-color)
|
var(--bg-faded-color)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies[open] summary {
|
.timeline.contextual > li .replies[open] > summary {
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies summary[hidden] {
|
.timeline.contextual > li .replies summary[hidden] {
|
||||||
|
@ -277,43 +337,66 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies li {
|
.timeline.contextual > li .replies li {
|
||||||
--width: 3px;
|
--line-start: calc(var(--thread-start) + var(--line-margin-end));
|
||||||
--left: calc(40px + 16px);
|
--line-end: calc(var(--line-start) + var(--line-width));
|
||||||
--right: calc(var(--left) + var(--width));
|
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
to right,
|
to right,
|
||||||
transparent,
|
transparent,
|
||||||
transparent var(--left),
|
transparent var(--line-start),
|
||||||
var(--comment-line-color) var(--left),
|
var(--comment-line-color) var(--line-start),
|
||||||
var(--comment-line-color) var(--right),
|
var(--comment-line-color) var(--line-end),
|
||||||
transparent var(--right),
|
transparent var(--line-end),
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
.timeline.contextual > li .replies .replies li {
|
||||||
|
--line-start: calc(
|
||||||
|
var(--thread-start) + var(--line-margin-end) + var(--line-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
.timeline.contextual > li.thread .replies li {
|
.timeline.contextual > li.thread .replies li {
|
||||||
--left: calc(50px + 16px + 12px);
|
--line-start: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.timeline.contextual > li.thread .replies .replies li {
|
||||||
|
--line-start: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
|
||||||
|
var(--line-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies li:last-child {
|
.timeline.contextual > li .replies li:last-child {
|
||||||
background-size: 100% 20px;
|
background-size: 100% 20px;
|
||||||
}
|
}
|
||||||
.timeline.contextual > li .replies li:before {
|
.timeline.contextual > li .replies li:before {
|
||||||
--radius: 10px;
|
|
||||||
--diameter: calc(var(--radius) * 2);
|
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: calc(40px + 16px);
|
left: var(--line-start);
|
||||||
width: var(--diameter);
|
width: var(--line-diameter);
|
||||||
height: var(--diameter);
|
height: var(--line-diameter);
|
||||||
border-radius: var(--radius);
|
border-radius: var(--line-radius);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: var(--width);
|
border-width: var(--line-width);
|
||||||
border-color: transparent transparent var(--comment-line-color) transparent;
|
border-color: transparent transparent var(--comment-line-color) transparent;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
.timeline.contextual > li .replies .replies li:before {
|
||||||
|
--line-start: calc(
|
||||||
|
var(--thread-start) + var(--line-margin-end) + var(--line-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
.timeline.contextual > li.thread .replies li:before {
|
.timeline.contextual > li.thread .replies li:before {
|
||||||
left: calc(50px + 16px + 12px);
|
--line-start: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.timeline.contextual > li.thread .replies .replies li:before {
|
||||||
|
--line-start: calc(
|
||||||
|
var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) +
|
||||||
|
var(--line-margin-end)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.timeline.contextual.loading > li:not(.hero) {
|
.timeline.contextual.loading > li:not(.hero) {
|
||||||
/* opacity: 0.5; */
|
/* opacity: 0.5; */
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
.hero-heading {
|
.hero-heading {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
pointer-events: none;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 0.25em;
|
margin-bottom: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { InView } from 'react-intersection-observer';
|
||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useSnapshot } from 'valtio';
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
|
import Avatar from '../components/avatar';
|
||||||
import Icon from '../components/icon';
|
import Icon from '../components/icon';
|
||||||
import Link from '../components/link';
|
import Link from '../components/link';
|
||||||
import Loader from '../components/loader';
|
import Loader from '../components/loader';
|
||||||
|
@ -24,6 +25,7 @@ import useScroll from '../utils/useScroll';
|
||||||
import useTitle from '../utils/useTitle';
|
import useTitle from '../utils/useTitle';
|
||||||
|
|
||||||
const LIMIT = 40;
|
const LIMIT = 40;
|
||||||
|
const THREAD_LIMIT = 20;
|
||||||
|
|
||||||
let cachedStatusesMap = {};
|
let cachedStatusesMap = {};
|
||||||
function resetScrollPosition(id) {
|
function resetScrollPosition(id) {
|
||||||
|
@ -164,8 +166,16 @@ function StatusPage() {
|
||||||
thread: s.account.id === heroStatus.account.id,
|
thread: s.account.id === heroStatus.account.id,
|
||||||
replies: s.__replies?.map((r) => ({
|
replies: s.__replies?.map((r) => ({
|
||||||
id: r.id,
|
id: r.id,
|
||||||
|
account: r.account,
|
||||||
repliesCount: r.repliesCount,
|
repliesCount: r.repliesCount,
|
||||||
content: r.content,
|
content: r.content,
|
||||||
|
replies: r.__replies?.map((r2) => ({
|
||||||
|
// Level 3
|
||||||
|
id: r2.id,
|
||||||
|
account: r2.account,
|
||||||
|
repliesCount: r2.repliesCount,
|
||||||
|
content: r2.content,
|
||||||
|
})),
|
||||||
})),
|
})),
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
@ -305,7 +315,7 @@ function StatusPage() {
|
||||||
return statuses.length - limit;
|
return statuses.length - limit;
|
||||||
}, [statuses.length, limit]);
|
}, [statuses.length, limit]);
|
||||||
|
|
||||||
const hasManyStatuses = statuses.length > LIMIT;
|
const hasManyStatuses = statuses.length > THREAD_LIMIT;
|
||||||
const hasDescendants = statuses.some((s) => s.descendant);
|
const hasDescendants = statuses.some((s) => s.descendant);
|
||||||
const ancestors = statuses.filter((s) => s.ancestor);
|
const ancestors = statuses.filter((s) => s.ancestor);
|
||||||
|
|
||||||
|
@ -405,17 +415,6 @@ function StatusPage() {
|
||||||
>
|
>
|
||||||
<header
|
<header
|
||||||
class={`${heroInView ? 'inview' : ''}`}
|
class={`${heroInView ? 'inview' : ''}`}
|
||||||
onClick={(e) => {
|
|
||||||
if (
|
|
||||||
!/^(a|button)$/i.test(e.target.tagName) &&
|
|
||||||
heroStatusRef.current
|
|
||||||
) {
|
|
||||||
heroStatusRef.current.scrollIntoView({
|
|
||||||
behavior: 'smooth',
|
|
||||||
block: 'start',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onDblClick={(e) => {
|
onDblClick={(e) => {
|
||||||
// reload statuses
|
// reload statuses
|
||||||
states.reloadStatusPage++;
|
states.reloadStatusPage++;
|
||||||
|
@ -428,23 +427,34 @@ function StatusPage() {
|
||||||
</div> */}
|
</div> */}
|
||||||
<h1>
|
<h1>
|
||||||
{!heroInView && heroStatus && uiState !== 'loading' ? (
|
{!heroInView && heroStatus && uiState !== 'loading' ? (
|
||||||
<span class="hero-heading">
|
<>
|
||||||
{!!heroPointer && (
|
<span class="hero-heading">
|
||||||
<>
|
<NameText showAvatar account={heroStatus.account} short />{' '}
|
||||||
<Icon
|
<span class="insignificant">
|
||||||
icon={heroPointer === 'down' ? 'arrow-down' : 'arrow-up'}
|
•{' '}
|
||||||
/>{' '}
|
<RelativeTime
|
||||||
</>
|
datetime={heroStatus.createdAt}
|
||||||
)}
|
format="micro"
|
||||||
<NameText showAvatar account={heroStatus.account} short />{' '}
|
/>
|
||||||
<span class="insignificant">
|
</span>
|
||||||
•{' '}
|
</span>{' '}
|
||||||
<RelativeTime
|
<button
|
||||||
datetime={heroStatus.createdAt}
|
type="button"
|
||||||
format="micro"
|
class="ancestors-indicator light small"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
heroStatusRef.current.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start',
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon={heroPointer === 'down' ? 'arrow-down' : 'arrow-up'}
|
||||||
/>
|
/>
|
||||||
</span>
|
</button>
|
||||||
</span>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
Status{' '}
|
Status{' '}
|
||||||
|
@ -551,24 +561,22 @@ function StatusPage() {
|
||||||
withinContext
|
withinContext
|
||||||
size={thread || ancestor ? 'm' : 's'}
|
size={thread || ancestor ? 'm' : 's'}
|
||||||
/>
|
/>
|
||||||
{replies?.length > LIMIT && (
|
{/* {replies?.length > LIMIT && (
|
||||||
<div class="replies-link">
|
<div class="replies-link">
|
||||||
<Icon icon="comment" />{' '}
|
<Icon icon="comment" />{' '}
|
||||||
<span title={replies.length}>
|
<span title={replies.length}>
|
||||||
{shortenNumber(replies.length)}
|
{shortenNumber(replies.length)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{descendant &&
|
{descendant && replies?.length > 0 && (
|
||||||
replies?.length > 0 &&
|
<SubComments
|
||||||
replies?.length <= LIMIT && (
|
hasManyStatuses={hasManyStatuses}
|
||||||
<SubComments
|
replies={replies}
|
||||||
hasManyStatuses={hasManyStatuses}
|
/>
|
||||||
replies={replies}
|
)}
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{uiState === 'loading' &&
|
{uiState === 'loading' &&
|
||||||
isHero &&
|
isHero &&
|
||||||
!!heroStatus?.repliesCount &&
|
!!heroStatus?.repliesCount &&
|
||||||
|
@ -658,13 +666,31 @@ function SubComments({ hasManyStatuses, replies }) {
|
||||||
isBrief = totalLength < 500;
|
isBrief = totalLength < 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the first 3 accounts, unique by id
|
||||||
|
const accounts = replies
|
||||||
|
.map((r) => r.account)
|
||||||
|
.filter((a, i, arr) => arr.findIndex((b) => b.id === a.id) === i)
|
||||||
|
.slice(0, 5);
|
||||||
|
|
||||||
const open = isBrief || !hasManyStatuses;
|
const open = isBrief || !hasManyStatuses;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<details class="replies" open={open}>
|
<details class="replies" open={open}>
|
||||||
<summary hidden={open}>
|
<summary hidden={open}>
|
||||||
<span title={replies.length}>{shortenNumber(replies.length)}</span> repl
|
<span class="avatars">
|
||||||
{replies.length === 1 ? 'y' : 'ies'}
|
{accounts.map((a) => (
|
||||||
|
<Avatar
|
||||||
|
key={a.id}
|
||||||
|
url={a.avatarStatic}
|
||||||
|
title={`${a.displayName} @${a.username}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<span title={replies.length}>{shortenNumber(replies.length)}</span>{' '}
|
||||||
|
repl
|
||||||
|
{replies.length === 1 ? 'y' : 'ies'}
|
||||||
|
</span>
|
||||||
</summary>
|
</summary>
|
||||||
<ul>
|
<ul>
|
||||||
{replies.map((r) => (
|
{replies.map((r) => (
|
||||||
|
@ -677,15 +703,21 @@ function SubComments({ hasManyStatuses, replies }) {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Status statusID={r.id} withinContext size="s" />
|
<Status statusID={r.id} withinContext size="s" />
|
||||||
{r.repliesCount > 0 && (
|
{/* {r.repliesCount > 0 && (
|
||||||
<div class="replies-link">
|
<div class="replies-link">
|
||||||
<Icon icon="comment" />{' '}
|
<Icon icon="comment" />{' '}
|
||||||
<span title={r.repliesCount}>
|
<span title={r.repliesCount}>
|
||||||
{shortenNumber(r.repliesCount)}
|
{shortenNumber(r.repliesCount)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)} */}
|
||||||
</Link>
|
</Link>
|
||||||
|
{r.replies?.length && (
|
||||||
|
<SubComments
|
||||||
|
hasManyStatuses={hasManyStatuses}
|
||||||
|
replies={r.replies}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Reference in a new issue