New feature: thread numbering

pull/47/head
Lim Chee Aun 2023-01-10 19:59:02 +08:00
rodzic b2bc596209
commit c4236e6de7
4 zmienionych plików z 75 dodań i 25 usunięć

Wyświetl plik

@ -149,7 +149,7 @@
margin: 4px 0 0 0;
gap: 4px;
align-items: center;
color: var(--reply-to-color);
color: var(--reply-to-text-color);
background: var(--bg-color);
border: 1px solid var(--reply-to-color);
border-radius: 4px;

Wyświetl plik

@ -270,30 +270,32 @@ function Status({
</span>
))}
</div>
{!!inReplyToId &&
!!inReplyToAccountId &&
!withinContext &&
size !== 's' && (
<>
{inReplyToAccountId === status.account.id ? (
<div class="status-thread-badge">
<Icon icon="thread" size="s" />
Thread
{!withinContext && size !== 's' && (
<>
{inReplyToAccountId === status.account?.id ||
!!snapStates.statusThreadNumber[id] ? (
<div class="status-thread-badge">
<Icon icon="thread" size="s" />
Thread
{snapStates.statusThreadNumber[id]
? ` ${snapStates.statusThreadNumber[id]}/X`
: ''}
</div>
) : (
!!inReplyToId &&
!!inReplyToAccount &&
(!!spoilerText ||
!mentions.find((mention) => {
return mention.id === inReplyToAccountId;
})) && (
<div class="status-reply-badge">
<Icon icon="reply" />{' '}
<NameText account={inReplyToAccount} short />
</div>
) : (
!!inReplyToAccount &&
(!!spoilerText ||
!mentions.find((mention) => {
return mention.id === inReplyToAccountId;
})) && (
<div class="status-reply-badge">
<Icon icon="reply" />{' '}
<NameText account={inReplyToAccount} short />
</div>
)
)}
</>
)}
)
)}
</>
)}
<div
class={`content-container ${
sensitive || spoilerText ? 'has-spoiler' : ''

Wyświetl plik

@ -24,6 +24,7 @@
--reblog-color: var(--purple-color);
--reblog-faded-color: #892be220;
--reply-to-color: var(--orange-color);
--reply-to-text-color: #b36200;
--favourite-color: var(--red-color);
--reply-to-faded-color: #ffa6001a;
--outline-color: rgba(128, 128, 128, 0.2);

Wyświetl plik

@ -3,6 +3,7 @@ import { proxy } from 'valtio';
const states = proxy({
history: [],
statuses: {},
statusThreadNumber: {},
home: [],
homeNew: [],
homeLastFetchTime: null,
@ -22,11 +23,57 @@ const states = proxy({
export default states;
export function saveStatus(status, opts) {
const { override } = Object.assign({ override: true }, opts);
const { override, skipThreading } = Object.assign(
{ override: true, skipThreading: false },
opts,
);
if (!status) return;
if (!override && states.statuses[status.id]) return;
states.statuses[status.id] = status;
if (status.reblog) {
states.statuses[status.reblog.id] = status.reblog;
}
// THREAD TRAVERSER
if (!skipThreading) {
requestAnimationFrame(() => {
threadifyStatus(status);
});
}
}
function threadifyStatus(status) {
// Return all statuses in the thread, via inReplyToId, if inReplyToAccountId === account.id
let fetchIndex = 0;
async function traverse(status, index = 0) {
const { inReplyToId, inReplyToAccountId } = status;
if (!inReplyToId || inReplyToAccountId !== status.account.id) {
return [status];
}
if (inReplyToId && inReplyToAccountId !== status.account.id) {
throw 'Not a thread';
// Possibly thread of replies by multiple people?
}
let prevStatus = states.statuses[inReplyToId];
if (!prevStatus) {
if (fetchIndex++ > 3) throw 'Too many fetches for thread'; // Some people revive old threads
await new Promise((r) => setTimeout(r, 500 * fetchIndex)); // Be nice to rate limits
prevStatus = await masto.v1.statuses.fetch(inReplyToId);
saveStatus(prevStatus, { skipThreading: true });
}
// Prepend so that first status in thread will be index 0
return [...(await traverse(prevStatus, ++index)), status];
}
return traverse(status)
.then((statuses) => {
if (statuses.length > 1) {
console.debug('THREAD', statuses);
statuses.forEach((status, index) => {
states.statusThreadNumber[status.id] = index + 1;
});
}
})
.catch((e) => {
console.error(e, status);
});
}