diff --git a/src/card.ts b/src/card.ts new file mode 100644 index 0000000..0a0d1d2 --- /dev/null +++ b/src/card.ts @@ -0,0 +1,97 @@ +let barLength = 36; + +export const calculateTimeLeft = (date: Date) => { + const now = new Date(); + const diff = date.getTime() - now.getTime(); + const days = Math.floor(diff / (1000 * 60 * 60 * 24)); + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((diff % (1000 * 60)) / 1000); + return { days, hours, minutes, seconds }; +}; + +export const calculateTimeLeftString = (date: Date) => { + const { days, hours, minutes, seconds } = calculateTimeLeft(date); + const daysString = days > 0 ? `${days} ${days === 1 ? 'day left' : 'days left'}` : ''; + const hoursString = + hours > 0 ? `${hours} ${hours === 1 ? 'hour left' : 'hours left'}` : ''; + const minutesString = + minutes > 0 ? `${minutes} ${minutes === 1 ? 'minute left' : 'minutes left'}` : ''; + const secondsString = + seconds > 0 ? `${seconds} ${seconds === 1 ? 'second left' : 'seconds left'}` : ''; + return daysString || hoursString || minutesString || secondsString || 'Final results'; +}; + +export const renderCard = async (card: TweetCard, headers: string[], userAgent: string = ''): Promise => { + let str = '\n\n'; + const values = card.binding_values; + + console.log('rendering card on ', card); + + // Telegram's bars need to be a lot smaller to fit its bubbles + if (userAgent.indexOf('Telegram') > -1) { + barLength = 24; + } + + let choices: { [label: string]: number } = {}; + let totalVotes = 0; + let timeLeft = ''; + + /* TODO: make poll code cleaner */ + if (typeof values !== 'undefined') { + if (typeof values.choice1_count !== 'undefined' && + typeof values.choice2_count !== 'undefined') { + if (typeof values.end_datetime_utc !== 'undefined') { + const date = new Date(values.end_datetime_utc.string_value); + timeLeft = calculateTimeLeftString(date); + } + choices[values.choice1_label?.string_value || ''] = parseInt( + values.choice1_count.string_value + ); + totalVotes += parseInt(values.choice1_count.string_value); + choices[values.choice2_label?.string_value || ''] = parseInt( + values.choice2_count.string_value + ); + totalVotes += parseInt(values.choice2_count.string_value); + if (typeof values.choice3_count !== 'undefined') { + choices[values.choice3_label?.string_value || ''] = parseInt( + values.choice3_count.string_value + ); + totalVotes += parseInt(values.choice3_count.string_value); + } + if (typeof values.choice4_count !== 'undefined') { + choices[values.choice4_label?.string_value || ''] = parseInt( + values.choice4_count.string_value + ); + totalVotes += parseInt(values.choice4_count.string_value); + + for (const [label, votes] of Object.entries(choices)) { + // render bar + const bar = '█'.repeat(Math.round((votes / totalVotes || 0) * barLength)); + str += `${bar} + ${label}  (${Math.round((votes / totalVotes || 0) * 100)}%) + `; + } + + str += `\n${totalVotes} votes · ${timeLeft}`; + + console.log(str); + } + } else if (typeof values.player_url !== "undefined") { + headers.push( + ``, + ``, + ``, + ``, + ``, + ``, + ``, + ``, + ``, + ) + } + } + + + return str; +}; diff --git a/src/poll.ts b/src/poll.ts deleted file mode 100644 index f44dc0c..0000000 --- a/src/poll.ts +++ /dev/null @@ -1,89 +0,0 @@ -let barLength = 36; - -export const calculateTimeLeft = (date: Date) => { - const now = new Date(); - const diff = date.getTime() - now.getTime(); - const days = Math.floor(diff / (1000 * 60 * 60 * 24)); - const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); - const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); - const seconds = Math.floor((diff % (1000 * 60)) / 1000); - return { days, hours, minutes, seconds }; -}; - -export const calculateTimeLeftString = (date: Date) => { - const { days, hours, minutes, seconds } = calculateTimeLeft(date); - const daysString = days > 0 ? `${days} ${days === 1 ? 'day left' : 'days left'}` : ''; - const hoursString = - hours > 0 ? `${hours} ${hours === 1 ? 'hour left' : 'hours left'}` : ''; - const minutesString = - minutes > 0 ? `${minutes} ${minutes === 1 ? 'minute left' : 'minutes left'}` : ''; - const secondsString = - seconds > 0 ? `${seconds} ${seconds === 1 ? 'second left' : 'seconds left'}` : ''; - return daysString || hoursString || minutesString || secondsString || 'Final results'; -}; - -export const renderPoll = async (card: TweetCard, userAgent: string = ''): Promise => { - let str = '\n\n'; - const values = card.binding_values; - - console.log('rendering poll on ', card); - - // Telegram's bars need to be a lot smaller to fit its bubbles - if (userAgent.indexOf('Telegram') > -1) { - barLength = 24; - } - - let choices: { [label: string]: number } = {}; - let totalVotes = 0; - let timeLeft = ''; - - if (typeof values !== 'undefined' && typeof values.end_datetime_utc !== 'undefined') { - const date = new Date(values.end_datetime_utc.string_value); - timeLeft = calculateTimeLeftString(date); - } - - /* TODO: make this cleaner */ - if ( - typeof values !== 'undefined' && - typeof values.choice1_count !== 'undefined' && - typeof values.choice2_count !== 'undefined' - ) { - choices[values.choice1_label?.string_value || ''] = parseInt( - values.choice1_count.string_value - ); - totalVotes += parseInt(values.choice1_count.string_value); - choices[values.choice2_label?.string_value || ''] = parseInt( - values.choice2_count.string_value - ); - totalVotes += parseInt(values.choice2_count.string_value); - if (typeof values.choice3_count !== 'undefined') { - choices[values.choice3_label?.string_value || ''] = parseInt( - values.choice3_count.string_value - ); - totalVotes += parseInt(values.choice3_count.string_value); - } - if (typeof values.choice4_count !== 'undefined') { - choices[values.choice4_label?.string_value || ''] = parseInt( - values.choice4_count.string_value - ); - totalVotes += parseInt(values.choice4_count.string_value); - } - } else { - console.log('no choices found', values); - return ''; - } - console.log(choices); - - for (const [label, votes] of Object.entries(choices)) { - // render bar - const bar = '█'.repeat(Math.round((votes / totalVotes || 0) * barLength)); - str += `${bar} -${label}  (${Math.round((votes / totalVotes || 0) * 100)}%) -`; - } - - str += `\n${totalVotes} votes · ${timeLeft}`; - - console.log(str); - return str; -}; diff --git a/src/status.ts b/src/status.ts index b1808f8..b64c058 100644 --- a/src/status.ts +++ b/src/status.ts @@ -3,7 +3,7 @@ import { fetchUsingGuest } from './fetch'; import { Html } from './html'; import { linkFixer } from './linkFixer'; import { colorFromPalette } from './palette'; -import { renderPoll } from './poll'; +import { renderCard } from './card'; import { handleQuote } from './quote'; import { sanitizeText } from './utils'; @@ -60,7 +60,7 @@ export const handleStatus = async ( let authorText = 'Twitter'; if (tweet.card) { - text += await renderPoll(tweet.card, userAgent); + text += await renderCard(tweet.card, headers, userAgent); } text = linkFixer(tweet, text); @@ -129,7 +129,19 @@ export const handleStatus = async ( const processMedia = (media: TweetMedia) => { if (media.type === 'photo') { - headers.push(``); + headers.push( + ``, + `` + ); + + if (media.original_info?.width && media.original_info?.height) { + headers.push( + ``, + ``, + ``, + `` + ); + } if (!pushedCardType) { headers.push(``); diff --git a/src/tweetTypes.ts b/src/tweetTypes.ts index 4cb2efb..15f4740 100644 --- a/src/tweetTypes.ts +++ b/src/tweetTypes.ts @@ -76,6 +76,11 @@ type TweetCard = { counts_are_final?: CardValue; duration_minutes?: CardValue; end_datetime_utc?: CardValue; + + player_url?: CardValue; + player_width?: CardValue; + player_height?: CardValue; + title?: CardValue; }; name: string; };