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

Make polymaths.social threads actually readable lol

This commit is contained in:
Stefano Pigozzi 2024-10-04 22:54:24 +02:00
parent cbcf5c9b43
commit 321b60649f
No known key found for this signature in database
GPG key ID: 5ADA3868646C3FC0
2 changed files with 81 additions and 45 deletions

View file

@ -1658,29 +1658,31 @@ body:has(#modal-container .carousel) .status .media img:hover {
} }
} }
.status:not(.large) .hashtag-stuffing { .status .entity-stuffing {
opacity: 0.75; opacity: 0.50;
transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out;
} }
.status:not(.large) .hashtag-stuffing:is(:hover, :focus, :focus-within) { .status .entity-stuffing:is(:hover, :focus, :focus-within) {
opacity: 1; opacity: 1;
} }
.status:not(.large) .hashtag-stuffing { .status:not(.large) .entity-stuffing {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 100%; max-width: 100%;
font-size: smaller;
/* Convert breaks to spaces */ /* Convert breaks to spaces */
br { br {
display: none; display: none;
+ * { + * {
margin-inline-start: 1ex; margin-inline-start: 0.5ex;
} }
} }
} }
.status:not(.large) .hashtag-stuffing:first-child { .status:not(.large) .entity-stuffing:first-child {
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@ -1690,13 +1692,13 @@ body:has(#modal-container .carousel) .status .media img:hover {
/* If >= 9 hashtags, collapse */ /* If >= 9 hashtags, collapse */
/* TODO: lower the threshold one day */ /* TODO: lower the threshold one day */
.status:not(.large, .contextual .status) .status:not(.large, .contextual .status)
p:not(.hashtag-stuffing):has(.hashtag:nth-of-type(1)):has( p:not(.entity-stuffing):has(.mention:nth-of-type(1)):has(
.hashtag:nth-of-type(2) .mention:nth-of-type(2)
):has(.hashtag:nth-of-type(3)):has(.hashtag:nth-of-type(4)):has( ):has(.mention:nth-of-type(3)):has(.mention:nth-of-type(4)):has(
.hashtag:nth-of-type(5) .mention:nth-of-type(5)
):has(.hashtag:nth-of-type(6)):has(.hashtag:nth-of-type(7)):has( ):has(.mention:nth-of-type(6)):has(.mention:nth-of-type(7)):has(
.hashtag:nth-of-type(8) .mention:nth-of-type(8)
):has(.hashtag:nth-of-type(9)) { ):has(.mention:nth-of-type(9)) {
overflow: hidden; overflow: hidden;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
@ -2561,7 +2563,7 @@ a.card:is(:hover, :focus):visited {
display: revert; display: revert;
} }
.hashtag-stuffing { .entity-stuffing {
white-space: normal; white-space: normal;
opacity: 1; opacity: 1;
} }

View file

@ -35,6 +35,51 @@ function createDOM(html, isDocumentFragment) {
return isDocumentFragment ? tpl.content : tpl; return isDocumentFragment ? tpl.content : tpl;
} }
function _countEntities(p) {
let count = 0;
for (const node of p.childNodes) {
if(node.nodeType === Node.TEXT_NODE) {
// Check if there's text between the entities
const text = node.textContent.trim();
if(text !== '') {
// End if there's text
throw false;
}
}
else if(node.tagName === 'BR') {
// Ignore <br />
}
else if(node.tagName === 'A') {
// Check if the link has text
const linkText = node.textContent.trim();
if(!linkText) {
// End if there's a link without text
throw false;
}
else if(!(
linkText.startsWith('#') || linkText.startsWith('@')
)) {
// End if there's a link that's not a mention or an hashtag
throw false;
}
else {
// This is an entity
count++;
}
} else if(node.tagName === 'SPAN') {
// If this is a span, we might need to go deeper
count += _countEntities(node)
} else {
// There's something else here we should not touch
throw false;
}
}
return count
}
function _enhanceContent(content, opts = {}) { function _enhanceContent(content, opts = {}) {
const { emojis, returnDOM, postEnhanceDOM = () => {} } = opts; const { emojis, returnDOM, postEnhanceDOM = () => {} } = opts;
let enhancedContent = content; let enhancedContent = content;
@ -222,51 +267,40 @@ function _enhanceContent(content, opts = {}) {
} }
} }
// HASHTAG STUFFING // ENTITY STUFFING
// ================ // ================
// Get the <p> that contains a lot of hashtags, add a class to it // Get the <p> that contains a lot of hashtags or mentions, add a class to it
if (enhancedContent.includes('#')) { if (enhancedContent.includes('#') || enhancedContent.includes('@')) {
let prevIndex = null; let prevIndex = null;
const hashtagStuffedParagraphs = [...dom.querySelectorAll('p')].filter( const stuffedParagraphs = [...dom.querySelectorAll('p')].filter(
(p, index) => { (p, index) => {
let hashtagCount = 0; let entitiesCount = 0;
for (let i = 0; i < p.childNodes.length; i++) {
const node = p.childNodes[i]; try {
entitiesCount = _countEntities(p)
if (node.nodeType === Node.TEXT_NODE) { } catch(e) {
const text = node.textContent.trim(); if(e === false) {
if (text !== '') { return false
return false;
}
} else if (node.tagName === 'BR') {
// Ignore <br />
} else if (node.tagName === 'A') {
const linkText = node.textContent.trim();
if (!linkText || !linkText.startsWith('#')) {
return false;
} else {
hashtagCount++;
}
} else {
return false;
} }
throw e;
} }
// Only consider "stuffing" if: // Only consider "stuffing" if:
// - there are more than 3 hashtags // - there are more than 3 entities
// - there are more than 1 hashtag in adjacent paragraphs // - there are more than 1 entity in adjacent paragraphs
if (hashtagCount > 3) { if (entitiesCount > 3) {
prevIndex = index; prevIndex = index;
return true; return true;
} }
if (hashtagCount > 1 && prevIndex && index === prevIndex + 1) { if (entitiesCount > 1 && prevIndex && index === prevIndex + 1) {
prevIndex = index; prevIndex = index;
return true; return true;
} }
}, },
); );
if (hashtagStuffedParagraphs?.length) { if (stuffedParagraphs?.length) {
for (const p of hashtagStuffedParagraphs) { for (const p of stuffedParagraphs) {
p.classList.add('hashtag-stuffing'); p.classList.add('entity-stuffing');
p.title = p.innerText; p.title = p.innerText;
} }
} }