Experiment unlinked replies (again)

But still show link to the post's "thread"
This commit is contained in:
Lim Chee Aun 2024-01-05 19:15:22 +08:00
parent bc2886f7e2
commit 54314de976
3 changed files with 176 additions and 66 deletions

View file

@ -547,9 +547,10 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
list-style: none; list-style: none;
} }
.timeline.contextual > li .replies > .replies-summary { .timeline.contextual > li .replies > .replies-summary {
padding: 8px; --summary-padding: 8px;
padding: var(--summary-padding);
background-color: var(--bg-faded-color); background-color: var(--bg-faded-color);
display: inline-block; display: inline-flex;
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
text-transform: uppercase; text-transform: uppercase;
@ -559,12 +560,67 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
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; list-style: none;
white-space: nowrap; gap: 8px;
align-items: center;
margin-right: calc(44px + 8px);
b { b {
font-weight: 500; font-weight: 500;
color: var(--text-color); color: var(--text-color);
} }
.avatars {
flex-shrink: 0;
transition: opacity 0.3s ease;
.avatar {
transition: transform 0.3s ease;
&:not(:first-child) {
margin: 0 0 0 -4px;
}
}
}
.replies-counts {
/* flex-grow: 1; */
> * {
display: inline-block;
}
}
.replies-summary-chevron {
transition: transform 0.3s ease;
}
.replies-parent-link {
position: absolute;
right: 4px;
height: 100%;
z-index: 2;
font-size: 16px;
font-weight: bold;
align-self: stretch;
text-decoration: none;
display: flex;
align-items: center;
padding: var(--summary-padding) calc(var(--summary-padding) * 2);
transform: translateX(100%);
margin: calc(-1 * var(--summary-padding)) calc(-1 * var(--summary-padding))
calc(-1 * var(--summary-padding)) 0;
border-radius: 8px;
background-color: var(--link-bg-color);
&:is(:hover, :focus) {
color: var(--link-text-color);
box-shadow: inset 0 0 0 2px var(--link-faded-color);
}
&:active {
background-color: var(--link-faded-color);
}
}
} }
.timeline.contextual > li .replies > .replies-summary::-webkit-details-marker { .timeline.contextual > li .replies > .replies-summary::-webkit-details-marker {
display: none; display: none;
@ -572,14 +628,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.timeline.contextual > li .replies > .replies-summary > * { .timeline.contextual > li .replies > .replies-summary > * {
vertical-align: middle; vertical-align: middle;
} }
.timeline.contextual > li .replies > .replies-summary .avatars { .timeline.contextual
margin-right: 8px; > li
.replies
> *:not(:first-child) { > .replies-summary
margin: 0 0 0 -4px; .timeline.contextual
} > li
} .replies
.timeline.contextual > li .replies > .replies-summary:active, > .replies-summary:active,
.timeline.contextual > li .replies[open] > .replies-summary { .timeline.contextual > li .replies[open] > .replies-summary {
color: var(--text-color); color: var(--text-color);
background-color: var(--comment-line-color); background-color: var(--comment-line-color);
@ -591,6 +647,18 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
} }
.timeline.contextual > li .replies[open] > .replies-summary { .timeline.contextual > li .replies[open] > .replies-summary {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
.avatars {
opacity: 0.5;
.avatar {
transform: rotate(-15deg);
}
}
.replies-summary-chevron {
transform: rotate(180deg);
}
} }
.timeline.contextual > li .replies .replies-summary[hidden] { .timeline.contextual > li .replies .replies-summary[hidden] {
display: none; display: none;

View file

@ -32,6 +32,7 @@
--text-color: #1c1e21; --text-color: #1c1e21;
--text-insignificant-color: #1c1e2199; --text-insignificant-color: #1c1e2199;
--link-color: var(--blue-color); --link-color: var(--blue-color);
--link-bg-color: #4169e122;
--link-light-color: #4169e199; --link-light-color: #4169e199;
--link-faded-color: #4169e155; --link-faded-color: #4169e155;
--link-bg-hover-color: #f0f2f599; --link-bg-hover-color: #f0f2f599;

View file

@ -184,6 +184,15 @@ function StatusPage(params) {
); );
} }
function StatusParent(props) {
const { linkable, to, onClick, ...restProps } = props;
return linkable ? (
<Link class="status-link" to={to} onClick={onClick} {...restProps} />
) : (
<div class="status-focus" tabIndex={0} {...restProps} />
);
}
function StatusThread({ id, closeLink = '/', instance: propInstance }) { function StatusThread({ id, closeLink = '/', instance: propInstance }) {
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const mediaParam = searchParams.get('media'); const mediaParam = searchParams.get('media');
@ -705,24 +714,8 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
weight, weight,
} = status; } = status;
const isHero = statusID === id; const isHero = statusID === id;
// const StatusParent = useCallback( const isLinkable = isThread || ancestor;
// (props) =>
// isThread || thread || ancestor ? (
// <Link
// class="status-link"
// to={
// instance ? `/${instance}/s/${statusID}` : `/s/${statusID}`
// }
// onClick={() => {
// resetScrollPosition(statusID);
// }}
// {...props}
// />
// ) : (
// <div class="status-focus" tabIndex={0} {...props} />
// ),
// [isThread, thread],
// );
return ( return (
<li <li
key={statusID} key={statusID}
@ -808,25 +801,42 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
)} )}
</> </>
) : ( ) : (
// <StatusParent> <StatusParent
<Link linkable={isLinkable}
class="status-link"
to={instance ? `/${instance}/s/${statusID}` : `/s/${statusID}`} to={instance ? `/${instance}/s/${statusID}` : `/s/${statusID}`}
onClick={() => { onClick={() => {
resetScrollPosition(statusID); resetScrollPosition(statusID);
}} }}
> >
<InView {/* <Link
skip={i !== 0 || !ancestor} class="status-link"
threshold={0.5} to={instance ? `/${instance}/s/${statusID}` : `/s/${statusID}`}
onChange={(inView) => { onClick={() => {
queueMicrotask(() => { resetScrollPosition(statusID);
requestAnimationFrame(() => { }}
setReachTopPost(inView); > */}
{i === 0 && ancestor ? (
<InView
threshold={0.5}
onChange={(inView) => {
queueMicrotask(() => {
requestAnimationFrame(() => {
setReachTopPost(inView);
});
}); });
}); }}
}} >
> <Status
statusID={statusID}
instance={instance}
withinContext
size={thread || ancestor ? 'm' : 's'}
enableTranslate
onMediaClick={handleMediaClick}
onStatusLinkClick={handleStatusLinkClick}
/>
</InView>
) : (
<Status <Status
statusID={statusID} statusID={statusID}
instance={instance} instance={instance}
@ -836,7 +846,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
onMediaClick={handleMediaClick} onMediaClick={handleMediaClick}
onStatusLinkClick={handleStatusLinkClick} onStatusLinkClick={handleStatusLinkClick}
/> />
</InView> )}
{ancestor && repliesCount > 1 && ( {ancestor && repliesCount > 1 && (
<div class="replies-link"> <div class="replies-link">
<Icon icon="comment2" />{' '} <Icon icon="comment2" />{' '}
@ -853,8 +863,8 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
</span> </span>
</div> </div>
)} */} )} */}
{/* </StatusParent> */} </StatusParent>
</Link> // </Link>
)} )}
{descendant && replies?.length > 0 && ( {descendant && replies?.length > 0 && (
<SubComments <SubComments
@ -864,6 +874,10 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
level={1} level={1}
accWeight={weight} accWeight={weight}
openAll={totalDescendants.current < SUBCOMMENTS_OPEN_ALL_LIMIT} openAll={totalDescendants.current < SUBCOMMENTS_OPEN_ALL_LIMIT}
parentLink={{
to: instance ? `/${instance}/s/${statusID}` : `/s/${statusID}`,
onClick: () => resetScrollPosition(statusID),
}}
/> />
)} )}
{uiState === 'loading' && {uiState === 'loading' &&
@ -932,6 +946,11 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
return ids.map((id) => statusKey(id, instance)); return ids.map((id) => statusKey(id, instance));
}, [showMore, statuses, limit, instance]); }, [showMore, statuses, limit, instance]);
const statusesList = useMemo(
() => statuses.slice(0, limit).map(renderStatus),
[statuses, limit, renderStatus],
);
return ( return (
<div <div
tabIndex="-1" tabIndex="-1"
@ -1176,7 +1195,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
uiState === 'loading' ? 'loading' : '' uiState === 'loading' ? 'loading' : ''
}`} }`}
> >
{statuses.slice(0, limit).map(renderStatus)} {statusesList}
{showMore > 0 && ( {showMore > 0 && (
<li> <li>
<button <button
@ -1244,6 +1263,7 @@ function SubComments({
level, level,
accWeight, accWeight,
openAll, openAll,
parentLink,
}) { }) {
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
@ -1330,34 +1350,49 @@ function SubComments({
/> />
))} ))}
</span> </span>
<b> <span class="replies-counts">
<span title={replies.length}>{shortenNumber(replies.length)}</span>{' '} <b>
repl <span title={replies.length}>{shortenNumber(replies.length)}</span>{' '}
{replies.length === 1 ? 'y' : 'ies'} repl
</b> {replies.length === 1 ? 'y' : 'ies'}
{!sameCount && totalComments > 1 && ( </b>
<> {!sameCount && totalComments > 1 && (
{' '} <>
&middot;{' '} {' '}
<span> &middot;{' '}
<span title={totalComments}>{shortenNumber(totalComments)}</span>{' '} <span>
comment <span title={totalComments}>
{totalComments === 1 ? '' : 's'} {shortenNumber(totalComments)}
</span> </span>{' '}
</> comment
{totalComments === 1 ? '' : 's'}
</span>
</>
)}
</span>
<Icon icon="chevron-down" class="replies-summary-chevron" />
{!!parentLink && (
<Link
class="replies-parent-link"
to={parentLink.to}
onClick={parentLink.onClick}
title="View post with its replies"
>
&raquo;
</Link>
)} )}
</summary> </summary>
<ul> <ul>
{replies.map((r) => ( {replies.map((r) => (
<li key={r.id}> <li key={r.id}>
<Link {/* <Link
class="status-link" class="status-link"
to={instance ? `/${instance}/s/${r.id}` : `/s/${r.id}`} to={instance ? `/${instance}/s/${r.id}` : `/s/${r.id}`}
onClick={() => { onClick={() => {
resetScrollPosition(r.id); resetScrollPosition(r.id);
}} }}
> > */}
{/* <div class="status-focus" tabIndex={0}> */} <div class="status-focus" tabIndex={0}>
<Status <Status
statusID={r.id} statusID={r.id}
instance={instance} instance={instance}
@ -1374,8 +1409,8 @@ function SubComments({
</span> </span>
</div> </div>
)} )}
{/* </div> */} </div>
</Link> {/* </Link> */}
{r.replies?.length && ( {r.replies?.length && (
<SubComments <SubComments
instance={instance} instance={instance}
@ -1383,6 +1418,12 @@ function SubComments({
level={level + 1} level={level + 1}
accWeight={!open ? r.weight : totalWeight} accWeight={!open ? r.weight : totalWeight}
openAll={openAll} openAll={openAll}
parentLink={{
to: instance ? `/${instance}/s/${r.id}` : `/s/${r.id}`,
onClick: () => {
resetScrollPosition(r.id);
},
}}
/> />
)} )}
</li> </li>