mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-09 01:26:24 +01:00
Experiment unlinked replies (again)
But still show link to the post's "thread"
This commit is contained in:
parent
bc2886f7e2
commit
54314de976
3 changed files with 176 additions and 66 deletions
90
src/app.css
90
src/app.css
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 && (
|
||||||
{' '}
|
<>
|
||||||
·{' '}
|
{' '}
|
||||||
<span>
|
·{' '}
|
||||||
<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"
|
||||||
|
>
|
||||||
|
»
|
||||||
|
</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>
|
||||||
|
|
Loading…
Reference in a new issue