1
0
Fork 0
mirror of https://github.com/cheeaun/phanpy.git synced 2025-03-11 00:18:51 +01:00

Smarter logic for auto-collapsing

This logic is getting similar to HackerWeb's
This commit is contained in:
Lim Chee Aun 2023-05-08 22:42:15 +08:00
parent 54849b60a9
commit 4c188ab59b

View file

@ -42,7 +42,6 @@ import useTitle from '../utils/useTitle';
import getInstanceStatusURL from './../utils/get-instance-status-url'; import getInstanceStatusURL from './../utils/get-instance-status-url';
const LIMIT = 40; const LIMIT = 40;
const THREAD_LIMIT = 20;
let cachedRepliesToggle = {}; let cachedRepliesToggle = {};
let cachedStatusesMap = {}; let cachedStatusesMap = {};
@ -293,6 +292,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
account: _r.account, account: _r.account,
repliesCount: _r.repliesCount, repliesCount: _r.repliesCount,
content: _r.content, content: _r.content,
weight: calcStatusWeight(_r),
replies: expandReplies(_r.__replies), replies: expandReplies(_r.__replies),
})); }));
} }
@ -304,13 +304,19 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
isThread: ancestorsIsThread, isThread: ancestorsIsThread,
accountID: s.account.id, accountID: s.account.id,
repliesCount: s.repliesCount, repliesCount: s.repliesCount,
weight: calcStatusWeight(s),
})), })),
{ id, accountID: heroStatus.account.id }, {
id,
accountID: heroStatus.account.id,
weight: calcStatusWeight(heroStatus),
},
...nestedDescendants.map((s) => ({ ...nestedDescendants.map((s) => ({
id: s.id, id: s.id,
accountID: s.account.id, accountID: s.account.id,
descendant: true, descendant: true,
thread: s.account.id === heroStatus.account.id, thread: s.account.id === heroStatus.account.id,
weight: calcStatusWeight(s),
replies: expandReplies(s.__replies), replies: expandReplies(s.__replies),
})), })),
]; ];
@ -412,6 +418,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
states.reloadStatusPage = 0; states.reloadStatusPage = 0;
cachedStatusesMap = {}; cachedStatusesMap = {};
cachedRepliesToggle = {}; cachedRepliesToggle = {};
statusWeightCache.clear();
}; };
}, []); }, []);
@ -458,7 +465,6 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
return statuses.length - limit; return statuses.length - limit;
}, [statuses.length, limit]); }, [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);
@ -589,6 +595,12 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
}); });
}, []); }, []);
const totalWeight = useMemo(() => {
return statuses.reduce((acc, status) => {
return acc + status.weight;
}, 0);
}, [id, statuses?.length]);
return ( return (
<div <div
tabIndex="-1" tabIndex="-1"
@ -778,6 +790,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
thread, thread,
replies, replies,
repliesCount, repliesCount,
weight,
} = status; } = status;
const isHero = statusID === id; const isHero = statusID === id;
return ( return (
@ -898,10 +911,10 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
{descendant && replies?.length > 0 && ( {descendant && replies?.length > 0 && (
<SubComments <SubComments
instance={instance} instance={instance}
hasManyStatuses={hasManyStatuses}
replies={replies} replies={replies}
hasParentThread={thread} hasParentThread={thread}
level={1} level={1}
accWeight={totalWeight}
/> />
)} )}
{uiState === 'loading' && {uiState === 'loading' &&
@ -980,33 +993,8 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
); );
} }
function SubComments({ function SubComments({ replies, instance, hasParentThread, level, accWeight }) {
hasManyStatuses,
replies,
instance,
hasParentThread,
level,
previousOpen,
}) {
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
// Set isBrief = true:
// - if less than or 2 replies
// - if replies have no sub-replies
// - if total number of characters of content from replies is less than 500
let isBrief = false;
if (replies.length <= 2) {
const containsSubReplies = replies.some(
(r) => r.repliesCount > 0 || r.replies?.length > 0,
);
if (!containsSubReplies) {
let totalLength = replies.reduce((acc, reply) => {
const { content } = reply;
const length = htmlContentLength(content);
return acc + length;
}, 0);
isBrief = totalLength < 500;
}
}
// Total comments count, including sub-replies // Total comments count, including sub-replies
const diveDeep = (replies) => { const diveDeep = (replies) => {
@ -1026,16 +1014,12 @@ function SubComments({
.slice(0, 3); .slice(0, 3);
let open = false; let open = false;
// const open = if (accWeight < 5) {
// !previousOpen && open = true;
// (!hasParentThread || totalComments === 1) && } else if (!hasParentThread && totalComments === 1) {
// (isBrief || !hasManyStatuses); const shortReply = calcStatusWeight(replies[0]) < 2;
if (hasParentThread) { if (shortReply) open = true;
open = totalComments === 1;
} else {
open = isBrief;
} }
if (!previousOpen && !open) open = true;
const openBefore = cachedRepliesToggle[replies[0].id]; const openBefore = cachedRepliesToggle[replies[0].id];
const handleMediaClick = useCallback((e, i, media, status) => { const handleMediaClick = useCallback((e, i, media, status) => {
@ -1060,6 +1044,12 @@ function SubComments({
}; };
}, []); }, []);
const totalWeight = useMemo(() => {
return replies?.reduce((acc, reply) => {
return acc + reply?.weight;
}, 0);
}, [replies?.length]);
return ( return (
<details <details
ref={detailsRef} ref={detailsRef}
@ -1134,10 +1124,9 @@ function SubComments({
{r.replies?.length && ( {r.replies?.length && (
<SubComments <SubComments
instance={instance} instance={instance}
hasManyStatuses={hasManyStatuses}
replies={r.replies} replies={r.replies}
level={level + 1} level={level + 1}
previousOpen={open} accWeight={!open ? totalWeight : accWeight + totalWeight}
/> />
)} )}
</li> </li>
@ -1147,4 +1136,26 @@ function SubComments({
); );
} }
const MEDIA_VIRTUAL_LENGTH = 140;
const POLL_VIRTUAL_LENGTH = 35;
const CARD_VIRTUAL_LENGTH = 70;
const WEIGHT_SEGMENT = 140;
const statusWeightCache = new Map();
function calcStatusWeight(status) {
const cachedWeight = statusWeightCache.get(status.id);
if (cachedWeight) return cachedWeight;
const { spoilerText, content, mediaAttachments, poll, card } = status;
const length = htmlContentLength(spoilerText + content);
const mediaLength = mediaAttachments?.length ? MEDIA_VIRTUAL_LENGTH : 0;
const pollLength = (poll?.options?.length || 0) * POLL_VIRTUAL_LENGTH;
const cardLength =
card && (mediaAttachments?.length || poll?.options?.length)
? 0
: CARD_VIRTUAL_LENGTH;
const totalLength = length + mediaLength + pollLength + cardLength;
const weight = totalLength / WEIGHT_SEGMENT;
statusWeightCache.set(status.id, weight);
return weight;
}
export default memo(StatusPage); export default memo(StatusPage);