diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js index 6a0e6b98..3d4f20c3 100644 --- a/Resources/Scripts/code.js +++ b/Resources/Scripts/code.js @@ -80,43 +80,76 @@ // // Function: Event callback for a new tweet. // - var onNewTweet = function(column, tweet){ - if (column.model.getHasNotification()){ - let html = $(tweet.render({ - withFooter: false, - withTweetActions: false, - withMediaPreview: true, - isMediaPreviewOff: true, - isMediaPreviewSmall: false, - isMediaPreviewLarge: false - })); - - html.css("border", "0"); - html.find("footer").last().remove(); // apparently withTweetActions breaks for certain tweets, nice - html.find(".js-media").last().remove(); // and quoted tweets still show media previews, nice nice - html.find(".js-quote-detail").removeClass("is-actionable"); // prevent quoted tweets from changing the cursor - - html.find("a[href='#']").each(function(){ // remove <a> tags around links that don't lead anywhere (such as account names the tweet replied to) - this.outerHTML = this.innerHTML; - }); - - if (tweet.getChirpType().includes("list_member")){ - html.find(".activity-header").first().css("margin-top", "2px"); - html.find(".avatar").first().css("margin-bottom", "0"); + var onNewTweet = (function(){ + let recentTweets = new Set(); + let recentTweetTimer = null; + + let startRecentTweetTimer = () => { + if (recentTweetTimer){ + window.clearTimeout(recentTweetTimer); } - let source = tweet.getRelatedTweet(); - let duration = source ? source.text.length+(source.quotedTweet ? source.quotedTweet.text.length : 0) : tweet.text.length; - let tweetUrl = source ? source.getChirpURL() : ""; - let quoteUrl = source && source.quotedTweet ? source.quotedTweet.getChirpURL() : ""; - - $TD.onTweetPopup(columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl); - } + recentTweetTimer = window.setTimeout(() => { + recentTweetTimer = null; + recentTweets.clear(); + }, 10000); + }; - if (column.model.getHasSound()){ - $TD.onTweetSound(); - } - }; + let checkRecentTweet = id => { + if (recentTweets.size > 50){ + recentTweets.clear(); + } + else if (recentTweets.has(id)){ + return true; + } + + recentTweets.add(id); + startRecentTweetTimer(); + return false; + }; + + return function(column, tweet){ + if (checkRecentTweet(tweet.id)){ + return; + } + + if (column.model.getHasNotification()){ + let html = $(tweet.render({ + withFooter: false, + withTweetActions: false, + withMediaPreview: true, + isMediaPreviewOff: true, + isMediaPreviewSmall: false, + isMediaPreviewLarge: false + })); + + html.css("border", "0"); + html.find("footer").last().remove(); // apparently withTweetActions breaks for certain tweets, nice + html.find(".js-media").last().remove(); // and quoted tweets still show media previews, nice nice + html.find(".js-quote-detail").removeClass("is-actionable"); // prevent quoted tweets from changing the cursor + + html.find("a[href='#']").each(function(){ // remove <a> tags around links that don't lead anywhere (such as account names the tweet replied to) + this.outerHTML = this.innerHTML; + }); + + if (tweet.getChirpType().includes("list_member")){ + html.find(".activity-header").first().css("margin-top", "2px"); + html.find(".avatar").first().css("margin-bottom", "0"); + } + + let source = tweet.getRelatedTweet(); + let duration = source ? source.text.length+(source.quotedTweet ? source.quotedTweet.text.length : 0) : tweet.text.length; + let tweetUrl = source ? source.getChirpURL() : ""; + let quoteUrl = source && source.quotedTweet ? source.quotedTweet.getChirpURL() : ""; + + $TD.onTweetPopup(columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl); + } + + if (column.model.getHasSound()){ + $TD.onTweetSound(); + } + }; + })(); // // Function: Retrieves the tags to be put into <head> for notification HTML code.