mirror of
https://github.com/GenderDysphoria/GenderDysphoria.fyi.git
synced 2025-01-31 07:16:17 +00:00
Quoted tweets are now loaded recursively and displayed 2 layers deep
This commit is contained in:
parent
5a87f64e9d
commit
a7e266a558
@ -12,15 +12,7 @@ const schema = {
|
|||||||
protected: true,
|
protected: true,
|
||||||
},
|
},
|
||||||
html: true,
|
html: true,
|
||||||
quoted_status: {
|
quoted_status_id_str: true,
|
||||||
user: {
|
|
||||||
screen_name: true,
|
|
||||||
avatar: true,
|
|
||||||
name_html: true,
|
|
||||||
verified: true,
|
|
||||||
protected: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entities: { media: [ {
|
entities: { media: [ {
|
||||||
type: true,
|
type: true,
|
||||||
media_url_https: true,
|
media_url_https: true,
|
||||||
@ -51,13 +43,9 @@ var entityProcessors = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
urls (urls, tweet) {
|
urls (urls, tweet) {
|
||||||
urls.forEach((urlObj) => {
|
urls.forEach(({ url, expanded_url, display_url }) => {
|
||||||
var quotedTweetHtml = '';
|
const className = (tweet.quoted_status_permalink && url === tweet.quoted_status_permalink.url) ? 'quoted-tweet' : 'url';
|
||||||
var indices = urlObj.indices;
|
tweet.html = tweet.html.replace(url, `<a href="${expanded_url}" class="${className}">${display_url}</a>`);
|
||||||
var urlToReplace = (tweet.full_text || tweet.text).substring(indices[0], indices[1]);
|
|
||||||
|
|
||||||
var finalText = quotedTweetHtml || urlObj.display_url.link(urlObj.expanded_url);
|
|
||||||
tweet.html = tweet.html.replace(urlToReplace, finalText);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -28,17 +28,23 @@ module.exports = exports = async function tweets (pages) {
|
|||||||
|
|
||||||
/* Load Missing Tweets **************************************************/
|
/* Load Missing Tweets **************************************************/
|
||||||
|
|
||||||
if (tweetsNeeded.length) {
|
while (tweetsNeeded.length) {
|
||||||
log('Fetching tweets: ' + tweetsNeeded.join(', '));
|
log('Fetching tweets: ' + tweetsNeeded.join(', '));
|
||||||
const arriving = await Promise.all(chunk(tweetsNeeded, 99).map(twitter));
|
const arriving = await Promise.all(chunk(tweetsNeeded, 99).map(twitter));
|
||||||
|
const tweetsRequested = tweetsNeeded;
|
||||||
|
tweetsNeeded = [];
|
||||||
const loaded = [];
|
const loaded = [];
|
||||||
for (const tweet of arriving.flat(1)) {
|
for (const tweet of arriving.flat(1)) {
|
||||||
if (!twitterBackup[tweet.id_str]) twitterBackup[tweet.id_str] = tweet;
|
if (tweet.quoted_status_id_str && !twitterCache[tweet.quoted_status_id_str]) {
|
||||||
|
tweetsNeeded.push(tweet.quoted_status_id_str);
|
||||||
|
}
|
||||||
|
// if (!twitterBackup[tweet.id_str]) twitterBackup[tweet.id_str] = tweet;
|
||||||
|
twitterBackup[tweet.id_str] = tweet;
|
||||||
twitterCache[tweet.id_str] = tweetparse(tweet);
|
twitterCache[tweet.id_str] = tweetparse(tweet);
|
||||||
loaded.push(tweet.id_str);
|
loaded.push(tweet.id_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
const absent = difference(tweetsNeeded, loaded);
|
const absent = difference(tweetsRequested, loaded);
|
||||||
for (const id of absent) {
|
for (const id of absent) {
|
||||||
if (twitterBackup[id]) {
|
if (twitterBackup[id]) {
|
||||||
log('Pulled tweet from backup ' + id);
|
log('Pulled tweet from backup ' + id);
|
||||||
@ -53,18 +59,24 @@ module.exports = exports = async function tweets (pages) {
|
|||||||
|
|
||||||
const twitterMedia = [];
|
const twitterMedia = [];
|
||||||
|
|
||||||
|
function attachTweet (dict, tweetid) {
|
||||||
|
const tweet = twitterCache[tweetid];
|
||||||
|
if (!tweet) {
|
||||||
|
log.error(`Tweet ${tweetid} is missing from the cache.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dict[tweetid] = tweet;
|
||||||
|
twitterMedia.push( ...tweet.media );
|
||||||
|
|
||||||
|
if (tweet.quoted_status_id_str) attachTweet(dict, tweet.quoted_status_id_str);
|
||||||
|
}
|
||||||
|
|
||||||
// now loop through pages and substitute the tweet data for the ids
|
// now loop through pages and substitute the tweet data for the ids
|
||||||
for (const page of pages) {
|
for (const page of pages) {
|
||||||
if (!page.tweets || !page.tweets.length) continue;
|
if (!page.tweets || !page.tweets.length) continue;
|
||||||
|
|
||||||
page.tweets = page.tweets.reduce((dict, tweetid) => {
|
page.tweets = page.tweets.reduce((dict, tweetid) => {
|
||||||
const tweet = twitterCache[tweetid];
|
attachTweet(dict, tweetid);
|
||||||
if (!tweet) {
|
|
||||||
log.error(`Tweet ${tweetid} is missing from the cache.`);
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
dict[tweetid] = tweet;
|
|
||||||
twitterMedia.push( ...tweet.media );
|
|
||||||
return dict;
|
return dict;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
@ -121,9 +121,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tweet-text {
|
.tweet-text, .tweet-quoted-text {
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
p { margin-bottom: 0.5em; }
|
p { margin-bottom: 0.5em; }
|
||||||
|
p:last-child { margin-bottom: 0; }
|
||||||
a { color: $textHover; }
|
a { color: $textHover; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,13 +133,21 @@
|
|||||||
border: 1px solid $borderColor;
|
border: 1px solid $borderColor;
|
||||||
border-radius: .35em;
|
border-radius: .35em;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: block;
|
display: inline-block;
|
||||||
color: $textDark;
|
color: $textDark;
|
||||||
font-size: 14px;
|
font-size: 0.95em;
|
||||||
margin-top: 10px;
|
margin-top: 0.4em;
|
||||||
|
margin-bottom: 0.75em;
|
||||||
|
background: rgba(#ddd, 0.1);
|
||||||
|
|
||||||
|
> a {
|
||||||
|
color: inherit;
|
||||||
|
display: block;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: $borderHover;
|
color: $textHover;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@ -148,6 +157,10 @@
|
|||||||
span, strong {
|
span, strong {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tweet-entities {
|
.tweet-entities {
|
||||||
@ -157,6 +170,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
|
box-shadow: 0 0 3px rgba(#000, 0.3);
|
||||||
|
|
||||||
.tweet-entities-inner {
|
.tweet-entities-inner {
|
||||||
padding-bottom: 56.25%;
|
padding-bottom: 56.25%;
|
||||||
|
@ -12,17 +12,30 @@
|
|||||||
<span>@{{user.screen_name}}</span>
|
<span>@{{user.screen_name}}</span>
|
||||||
<img src="/tweets/logo.svg" alt="Twitter Logo" class="tweet-logo">
|
<img src="/tweets/logo.svg" alt="Twitter Logo" class="tweet-logo">
|
||||||
</a>
|
</a>
|
||||||
|
{{#if quoted_status_id_str}}{{#with (lookup ../../tweets quoted_status_id_str)}}
|
||||||
|
<div class="tweet-quoted">
|
||||||
|
<a href="https://twitter.com/{{user.screen_name}}/status/{{id_str}}">
|
||||||
|
<strong>{{{user.name_html}}}</strong>
|
||||||
|
<span>@{{user.screen_name}}</span>
|
||||||
|
</a>
|
||||||
|
{{#if quoted_status_id_str}}{{#with (lookup ../../../tweets quoted_status_id_str)}}
|
||||||
|
<div class="tweet-quoted">
|
||||||
|
<a href="https://twitter.com/{{user.screen_name}}/status/{{id_str}}">
|
||||||
|
<strong>{{{user.name_html}}}</strong>
|
||||||
|
<span>@{{user.screen_name}}</span>
|
||||||
|
</a>
|
||||||
|
<div class="tweet-quoted-text">{{{html}}}</div>
|
||||||
|
</div>
|
||||||
|
{{/with}}{{/if}}
|
||||||
|
<div class="tweet-quoted-text">{{{html}}}</div>
|
||||||
|
</div>
|
||||||
|
{{/with}}{{/if}}
|
||||||
<div class="tweet-text">{{{html}}}</div>
|
<div class="tweet-text">{{{html}}}</div>
|
||||||
{{#if quoted_status}}<a class="tweet-quoted" href="https://twitter.com/{{quoted_status.user.screen_name}}/status/{{quoted_status.id_str}}">
|
|
||||||
<strong>{{{quoted_status.user.name_html}}}</strong>
|
|
||||||
<span>@{{quoted_status.user.screen_name}}</span>
|
|
||||||
<div class="tweet-quoted-text">{{{quoted_status.html}}}</div>
|
|
||||||
</a>{{/if}}
|
|
||||||
{{#any extended_entities.media entities.media}}
|
{{#any extended_entities.media entities.media}}
|
||||||
<div class="tweet-entities"><div class="tweet-entities-inner"><div><div class="tweet-entities-grid count{{this.length}}">
|
<div class="tweet-entities lightbox"><div class="tweet-entities-inner"><div><div class="tweet-entities-grid count{{this.length}}">
|
||||||
{{#each this}}
|
{{#each this}}
|
||||||
<div class="tweet-entity">
|
<div class="tweet-entity">
|
||||||
{{#is type 'photo'}}<a class="tweet-photo" style="background-image: url({{media_url_https}}?name=medium);" href="{{media_url_https}}"></a>{{/is}}
|
{{#is type 'photo'}}<a class="tweet-photo lb" style="background-image: url({{media_url_https}}?name=medium);" href="{{media_url_https}}"></a>{{/is}}
|
||||||
{{#is type 'video'}}
|
{{#is type 'video'}}
|
||||||
<video controls poster="{{media_url}}" class="tweet-video">
|
<video controls poster="{{media_url}}" class="tweet-video">
|
||||||
{{#each video_info.variants}}
|
{{#each video_info.variants}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user