From 4791b3c07d850d015bdc9f18ef05321d2c6647ab Mon Sep 17 00:00:00 2001 From: idotj Date: Tue, 21 Feb 2023 18:48:38 +0100 Subject: [PATCH] Add dark theme + some fixes --- CHANGELOG | 5 ++ README.md | 9 ++- src/index.html | 2 +- src/mastodon-timeline.css | 59 ++++++++++++------ src/mastodon-timeline.js | 127 ++++++++++++++++++++++++-------------- 5 files changed, 133 insertions(+), 69 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1853f59..cdc5528 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v3.2.9 - 21/02/2023 +- Add dark theme +- Fix click on images +- Fix poll font size and color + v3.2.2 - 06/02/2023 - Rearrange JS functions - Use variables for CSS colors diff --git a/README.md b/README.md index 34a840f..ce808fa 100644 --- a/README.md +++ b/README.md @@ -55,19 +55,22 @@ Check the `src=""` url, your user id is between `/accounts/avatars/` and `/origi Here you have some parameters to customize your embed timeline: ``` - // Maximum amount of toots to get from the user (default: 20) + // Preferred color theme 'light' or 'dark' (default: auto) + default_theme: 'auto' + + // Maximum amount of toots to get (default: 20) toots_limit: '20' // Hide boosted toots (default: don't hide) hide_reblog: false - // Hide replies from the user (default: don't hide) + // Hide replies toots (default: don't hide) hide_replies: false // Limit the text content to a maximum number of lines (default: unlimited) text_max_lines: '0' - // Customize the text of the button linking to the user profile page (appears after the last toot) + // Customize the text of the link pointing to the Mastodon page (appears after the last toot) btn_see_more: 'See more posts at Mastodon' ``` diff --git a/src/index.html b/src/index.html index dba5cd6..f05442e 100644 --- a/src/index.html +++ b/src/index.html @@ -1,5 +1,5 @@ - + Mastodon embed timeline diff --git a/src/mastodon-timeline.css b/src/mastodon-timeline.css index 3f58316..a5d7696 100644 --- a/src/mastodon-timeline.css +++ b/src/mastodon-timeline.css @@ -1,26 +1,38 @@ -/* Mastodon embed feed timeline v3.2.2 */ +/* Mastodon embed feed timeline v3.2.9 */ /* More info at: */ /* https://gitlab.com/idotj/mastodon-embed-feed-timeline */ /* Variables */ :root { + --text-max-lines: none; +} + +/* Theme colors */ +:root, +html[data-theme="light"] { --bg-color: #fff; --bg-hover-color: #d9e1e8; --line-gray-color: #c0cdd9; --content-text: #000; --link-color: #3a3bff; --error-text-color: #8b0000; - --text-max-lines: none; +} +html[data-theme="dark"] { + --bg-color: #282c37; + --bg-hover-color: #313543; + --line-gray-color: #393f4f; + --content-text: #fff; + --link-color: #8c8dff; + --error-text-color: #fe6c6c; } /* Main container */ .mt-timeline { height: calc(100% - 2rem); - padding: 1rem 1.5rem; + padding: 1rem 0.5rem 1rem 1.5rem; position: relative; background: var(--bg-color); } - .mt-timeline a:link, .mt-timeline a:active, .mt-timeline a { @@ -36,8 +48,8 @@ overflow-y: auto; white-space: pre-wrap; word-wrap: break-word; + padding-right: 0.5rem; } - .mt-body .invisible { font-size: 0; line-height: 0; @@ -50,9 +62,9 @@ /* Toot container */ .mt-toot { margin: 0.25rem 0.5rem 0.25rem 0.25rem; - padding: 1rem 0 2rem 65px; + padding: 1rem 0.5rem 2rem 4rem; position: relative; - min-height: 60px; + min-height: 3.75rem; background-color: transparent; border-bottom: 1px solid var(--line-gray-color); } @@ -68,10 +80,10 @@ /* User icon */ .mt-avatar { position: absolute; - top: 20px; + top: 1rem; left: 5px; - width: 50px; - height: 50px; + width: 3rem; + height: 3rem; background-color: transparent; background-repeat: no-repeat; background-position: 50% 50%; @@ -80,14 +92,14 @@ border-radius: 5px; } .mt-avatar-boosted { - width: 40px; - height: 40px; + width: 2.5rem; + height: 2.5rem; } .mt-avatar-booster { - width: 25px; - height: 25px; - top: 25px; - left: 25px; + width: 1.5rem; + height: 1.5rem; + top: 1.5rem; + left: 1.5rem; } .mt-user { display: table; @@ -100,6 +112,7 @@ /* Text */ .toot-text { margin-bottom: 0.25rem; + color: var(--content-text); } .toot-text .spoiler-link { display: inline-block; @@ -108,10 +121,10 @@ border: 0; color: var(--content-text); font-weight: 700; - font-size: 11px; - padding: 0 6px; + font-size: 0.7rem; + padding: 0 0.35rem; text-transform: uppercase; - line-height: 20px; + line-height: 1.25rem; cursor: pointer; vertical-align: top; } @@ -135,19 +148,24 @@ justify-content: center; align-items: center; color: var(--error-text-color); - padding: 10px; + padding: 0.75rem; text-align: center; } /* Poll */ .toot-poll { margin-bottom: 0.25rem; + color: var(--content-text); } .toot-poll ul { list-style: none; padding: 0; margin: 0; } +.toot-poll ul li { + font-size: 0.9rem; + margin-bottom: 0.5rem; +} .toot-poll ul li:not(:last-child) { margin-bottom: 0.25rem; } @@ -179,6 +197,7 @@ bottom: 0; left: 0; } + .img-ratio14_7 { position: relative; padding-top: 48.95%; /* 14:7 */ diff --git a/src/mastodon-timeline.js b/src/mastodon-timeline.js index ce3426f..c37cd22 100644 --- a/src/mastodon-timeline.js +++ b/src/mastodon-timeline.js @@ -1,25 +1,45 @@ -// Mastodon embed feed timeline v3.2.2 +// Mastodon embed feed timeline v3.2.9 // More info at: // https://gitlab.com/idotj/mastodon-embed-feed-timeline // Timeline settings document.addEventListener("DOMContentLoaded", () => { let mapi = new MastodonApi({ + // Id of the
containing the timeline container_body_id: 'mt-body', + + // Preferred color theme: 'light', 'dark' or 'auto' (default: auto) + default_theme: 'auto', + + // Your Mastodon instance instance_uri: 'https://mastodon.online', - user_id: '180745', // leave empty if prefer to show local instance toots + + // Your user ID on Mastodon instance. Leave empty if you prefer to show local instance toots + user_id: '000180745', + + // Your user name on Mastodon instance profile_name: '@idotj', + + // Maximum amount of toots to get (default: 20) toots_limit: '20', + + // Hide boosted toots (default: don't hide) hide_reblog: false, + + // Hide replies toots (default: don't hide) hide_replies: false, + + // Limit the text content to a maximum number of lines (default: unlimited) text_max_lines: '0', + + // Customize the text of the link pointing to the Mastodon page (appears after the last toot) link_see_more: 'See more posts at Mastodon' }); }); let MastodonApi = function (params_) { - // Endpoint access settings / default values + this.DEFAULT_THEME = params_.default_theme || 'auto'; this.INSTANCE_URI = params_.instance_uri; this.USER_ID = params_.user_id || ''; this.PROFILE_NAME = this.USER_ID ? params_.profile_name : ''; @@ -32,49 +52,27 @@ let MastodonApi = function (params_) { // Target selector this.mtBodyContainer = document.getElementById(params_.container_body_id); - // Toot interactions - this.mtBodyContainer.addEventListener('click', function (event) { - // Check if clicked in a toot - if (event.target.localName == 'article' || event.target.offsetParent.localName == 'article') { - openTootURL(event); - } - // Check if clicked in Show More/Less button - if (event.target.localName == 'button' && event.target.className == 'spoiler-link') { - toogleSpoiler(event); - } - }); - this.mtBodyContainer.addEventListener('keydown', function (event) { - // Check if Enter key pressed with focus in an article - if (event.code === 'Enter' && event.target.localName == 'article') { - openTootURL(event); - } - }); - - // Open Toot in a new page avoiding any other natural link - function openTootURL(event_) { - let urlToot = event_.target.closest('.mt-toot').dataset.location; - if (event_.target.localName !== 'a' && event_.target.localName !== 'span' && event_.target.localName !== 'button' && urlToot) { - window.open(urlToot, '_blank'); - } - } - - // Spoiler button - function toogleSpoiler(event_) { - let spoilerText = event_.target.nextSibling; - let spoilerBtnText = event_.target.textContent; - spoilerText.classList.toggle('spoiler-text'); - if (spoilerBtnText == 'Show more') { - spoilerBtnText = 'Show less'; - event_.target.setAttribute('aria-expanded', 'true'); - } else { - spoilerBtnText = 'Show more'; - event_.target.setAttribute('aria-expanded', 'false'); - } - } + // Apply selected appearance + this.applyTheme(); // Get the toots this.getToots(); +} +// Theme style +MastodonApi.prototype.applyTheme = function () { + const setTheme = function (theme) { + document.documentElement.setAttribute('data-theme', theme); + } + if (this.DEFAULT_THEME === 'auto') { + let systemTheme = window.matchMedia('(prefers-color-scheme: dark)'); + systemTheme.matches ? setTheme('dark') : setTheme('light'); + systemTheme.addEventListener('change', event => { + event.matches ? setTheme('dark') : setTheme('light'); + }); + } else { + setTheme(this.DEFAULT_THEME); + } } // Listing toots function @@ -280,6 +278,47 @@ MastodonApi.prototype.getToots = function () { this.mtBodyContainer.insertAdjacentHTML('beforeend', toot); }; + // Toot interactions + this.mtBodyContainer.addEventListener('click', function (event) { + console.log({event}); + // Check if clicked in a toot + if (event.target.localName == 'article' || event.target.offsetParent.localName == 'article' || event.target.localName == 'img') { + openTootURL(event); + } + // Check if clicked in Show More/Less button + if (event.target.localName == 'button' && event.target.className == 'spoiler-link') { + toogleSpoiler(event); + } + }); + this.mtBodyContainer.addEventListener('keydown', function (event) { + // Check if Enter key pressed with focus in an article + if (event.code === 'Enter' && event.target.localName == 'article') { + openTootURL(event); + } + }); + + // Open Toot in a new page avoiding any other natural link + openTootURL = function (event_) { + let urlToot = event_.target.closest('.mt-toot').dataset.location; + if (event_.target.localName !== 'a' && event_.target.localName !== 'span' && event_.target.localName !== 'button' && urlToot) { + window.open(urlToot, '_blank'); + } + } + + // Spoiler button + toogleSpoiler = function (event_) { + let spoilerText = event_.target.nextSibling; + let spoilerBtnText = event_.target.textContent; + spoilerText.classList.toggle('spoiler-text'); + if (spoilerBtnText == 'Show more') { + spoilerBtnText = 'Show less'; + event_.target.setAttribute('aria-expanded', 'true'); + } else { + spoilerBtnText = 'Show more'; + event_.target.setAttribute('aria-expanded', 'false'); + } + } + }; // Place media @@ -308,10 +347,8 @@ MastodonApi.prototype.formatDate = function (date_) { return displayDate; }; - - // Loading spinner -function removeSpinner(element) { +removeSpinner = function (element) { const spinnerCSS = 'loading-spinner'; // Find closest parent container (1st, 2nd or 3rd level) let spinnerContainer = element.closest('.' + spinnerCSS);