Support thread reply context

This commit is contained in:
dangered wolf 2024-04-29 19:57:42 -04:00
parent de7224e0b9
commit e2bb948f7d
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
3 changed files with 27 additions and 12 deletions

View file

@ -163,6 +163,7 @@ export const fetchByRestId = async (
const processResponse = (instructions: ThreadInstruction[]): GraphQLProcessBucket => {
const bucket: GraphQLProcessBucket = {
statuses: [],
allStatuses: [],
cursors: []
};
instructions?.forEach?.(instruction => {
@ -318,7 +319,7 @@ export const constructTwitterThread = async (
return { status: null, thread: null, author: null, code: 404 };
}
const buildStatus = await buildAPITwitterStatus(c, result, language, false, legacyAPI);
const buildStatus = await buildAPITwitterStatus(c, result, language, null, legacyAPI);
if ((buildStatus as FetchResults)?.status === 401) {
return { status: null, thread: null, author: null, code: 401 };
@ -345,7 +346,7 @@ export const constructTwitterThread = async (
c,
originalStatus,
undefined,
false,
null,
legacyAPI
)) as APITwitterStatus;
@ -506,7 +507,7 @@ export const constructTwitterThread = async (
};
await Promise.all(threadStatuses.map(async status => {
const builtStatus = await buildAPITwitterStatus(c, status, undefined, true, false) as APITwitterStatus;
const builtStatus = await buildAPITwitterStatus(c, status, undefined, author, false) as APITwitterStatus;
socialThread.thread?.push(builtStatus);
}));

View file

@ -12,7 +12,7 @@ export const buildAPITwitterStatus = async (
c: Context,
status: GraphQLTwitterStatus,
language: string | undefined,
threadPiece = false,
threadAuthor: null | APIUser,
legacyAPI = false
// eslint-disable-next-line sonarjs/cognitive-complexity
): Promise<APITwitterStatus | FetchResults | null> => {
@ -58,7 +58,7 @@ export const buildAPITwitterStatus = async (
apiStatus.text = unescapeText(
linkFixer(status.legacy.entities?.urls, status.legacy.full_text || '')
);
if (!threadPiece) {
// if (threadAuthor && threadAuthor.id !== apiUser.id) {
apiStatus.author = {
id: apiUser.id,
name: apiUser.name,
@ -77,7 +77,7 @@ export const buildAPITwitterStatus = async (
birthday: apiUser.birthday,
website: apiUser.website
};
}
// }
apiStatus.replies = status.legacy.reply_count;
if (legacyAPI) {
// @ts-expect-error Use retweets for legacy API
@ -94,9 +94,9 @@ export const buildAPITwitterStatus = async (
delete apiStatus.author.global_screen_name;
} else {
apiStatus.reposts = status.legacy.retweet_count;
if (!threadPiece) {
// if ((threadAuthor && threadAuthor.id !== apiUser.id)) {
apiStatus.author.global_screen_name = apiUser.global_screen_name;
}
// }
}
apiStatus.likes = status.legacy.favorite_count;
apiStatus.embed_card = 'tweet';
@ -152,7 +152,7 @@ export const buildAPITwitterStatus = async (
/* We found a quote, let's process that too */
const quote = status.quoted_status_result;
if (quote) {
const buildQuote = await buildAPITwitterStatus(c, quote, language, threadPiece, legacyAPI);
const buildQuote = await buildAPITwitterStatus(c, quote, language, threadAuthor, legacyAPI);
if ((buildQuote as FetchResults).status) {
apiStatus.quote = undefined;
} else {
@ -199,7 +199,7 @@ export const buildAPITwitterStatus = async (
*/
/* Handle photos and mosaic if available */
if ((apiStatus?.media.photos?.length || 0) > 1 && !threadPiece) {
if ((apiStatus?.media.photos?.length || 0) > 1 && !threadAuthor) {
const mosaic = await handleMosaic(apiStatus.media?.photos || [], id);
if (typeof apiStatus.media !== 'undefined' && mosaic !== null) {
apiStatus.media.mosaic = mosaic;

View file

@ -117,6 +117,11 @@ const truncateSocialCount = (count: number): string => {
}
};
const generateInlineAuthorHeader = (status: APIStatus, author: APIUser): string => {
return `<i><a href="${status.url}">Reply</a> from <b>${author.name}</b> (<a href="${author.url}">@${author.screen_name}</a>):</i>`;
}
const generateStatusFooter = (status: APIStatus, isQuote = false, author: APIUser): string => {
let description = author.description;
description = htmlifyLinks(description);
@ -161,7 +166,7 @@ const generateStatusFooter = (status: APIStatus, isQuote = false, author: APIUse
});
};
const generateStatus = (status: APIStatus, author: APIUser, isQuote = false): string => {
const generateStatus = (status: APIStatus, author: APIUser, isQuote = false, differentAuthor = false): string => {
let text = paragraphify(sanitizeText(status.text), isQuote);
text = htmlifyLinks(text);
text = htmlifyHashtags(text);
@ -175,6 +180,8 @@ const generateStatus = (status: APIStatus, author: APIUser, isQuote = false): st
${generateStatusMedia(status, author)}
<!-- Translated text (if applicable) -->
${translatedText ? translatedText : notApplicableComment}
<!-- Inline author (if applicable) -->
${differentAuthor ? generateInlineAuthorHeader(status, author) : ''}
<!-- Embed Status text -->
${text}
<!-- Embedded quote status -->
@ -191,6 +198,8 @@ export const renderInstantView = (properties: RenderProperties): ResponseInstruc
const { status, thread, flags } = properties;
const instructions: ResponseInstructions = { addHeaders: [] };
let previousThreadPieceAuthor: string | null = null;
if (!status) {
throw new Error('Status is undefined');
}
@ -225,7 +234,12 @@ export const renderInstantView = (properties: RenderProperties): ResponseInstruc
<sub><a href="${status.url}">View original</a></sub>
<h1>${status.author.name} (@${status.author.screen_name})</h1>
${thread?.thread?.map(status => generateStatus(status, thread?.author ?? status.author, false)).join('')}
${thread?.thread?.map((status) => {
const differentAuthor = thread?.author?.id !== status.author?.id || (previousThreadPieceAuthor !== null && previousThreadPieceAuthor !== status.author?.id);
previousThreadPieceAuthor = status.author?.id;
return generateStatus(status, status.author ?? thread?.author, false, differentAuthor)
}).join('')}
${generateStatusFooter(status, false, thread?.author ?? status.author)}
<br>${`<a href="${status.url}">View original post</a>`}
</article>`;