From 0febcacb938f36946f80e34aadde0b391d67ea00 Mon Sep 17 00:00:00 2001 From: Frederic Hemberger Date: Sat, 3 Aug 2024 13:30:22 +0200 Subject: [PATCH 01/11] fix(shortcuts-settings): `settingsJSON` must be defined if note doesn't exist --- src/components/shortcuts-settings.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/shortcuts-settings.jsx b/src/components/shortcuts-settings.jsx index ad8aca576..de31c3348 100644 --- a/src/components/shortcuts-settings.jsx +++ b/src/components/shortcuts-settings.jsx @@ -1055,16 +1055,16 @@ function ImportExport({ shortcuts, onClose }) { const { note = '' } = relationship; // const newNote = `${note}\n\n\n${shortcutsStr}`; let newNote = ''; + const settingsJSON = JSON.stringify({ + v: '1', // version + dt: Date.now(), // datetime stamp + data: shortcutsStr, // shortcuts settings string + }); if ( /(.*)<\/phanpy-shortcuts-settings>/.test( note, ) ) { - const settingsJSON = JSON.stringify({ - v: '1', // version - dt: Date.now(), // datetime stamp - data: shortcutsStr, // shortcuts settings string - }); newNote = note.replace( /(.*)<\/phanpy-shortcuts-settings>/, `${settingsJSON}`, From cf2461add52f7ff0f8f955291c154673499551a7 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Fri, 2 Aug 2024 13:42:43 +0800 Subject: [PATCH 02/11] Better checks --- src/utils/group-notifications.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utils/group-notifications.jsx b/src/utils/group-notifications.jsx index f67d9d577..1aeb0fafe 100644 --- a/src/utils/group-notifications.jsx +++ b/src/utils/group-notifications.jsx @@ -29,8 +29,12 @@ export function fixNotifications(notifications) { } export function massageNotifications2(notifications) { - if (notifications?.accounts) { - const { accounts, notificationGroups, statuses } = notifications; + if (notifications?.notificationGroups) { + const { + accounts = [], + notificationGroups = [], + statuses = [], + } = notifications; return notificationGroups.map((group) => { const { sampleAccountIds, statusId } = group; const sampleAccounts = From 4ebfb544aa1aa476e660dd742ec8fe7aac3b7d67 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Sat, 3 Aug 2024 19:14:04 +0800 Subject: [PATCH 03/11] This caching seems still buggy Revert to SWR with 1-min expiry --- public/sw.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/sw.js b/public/sw.js index b1a95073e..715037296 100644 --- a/public/sw.js +++ b/public/sw.js @@ -101,11 +101,11 @@ const apiIntermediateRoute = new RegExpRoute( // - trends/* // - timelines/link /^https?:\/\/[^\/]+\/api\/v\d+\/(trends|timelines\/link)/, - new CacheFirst({ + new StaleWhileRevalidate({ cacheName: 'api-intermediate', plugins: [ new ExpirationPlugin({ - maxAgeSeconds: 10 * 60, // 10 minutes + maxAgeSeconds: 1 * 60, // 1min }), new CacheableResponsePlugin({ statuses: [0, 200], From 99ee6c3979e15cd3660c637780f96bd9f0b6d331 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Sun, 4 Aug 2024 10:06:55 +0800 Subject: [PATCH 04/11] Don't reuse var for both timeout and interval --- src/components/background-service.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/background-service.jsx b/src/components/background-service.jsx index 15647fe1b..bcadd2a44 100644 --- a/src/components/background-service.jsx +++ b/src/components/background-service.jsx @@ -46,6 +46,7 @@ export default memo(function BackgroundService({ isLoggedIn }) { useEffect(() => { let sub; + let streamTimeout; let pollNotifications; if (isLoggedIn && visible) { const { masto, streaming, instance } = api(); @@ -56,7 +57,7 @@ export default memo(function BackgroundService({ isLoggedIn }) { let hasStreaming = false; // 2. Start streaming if (streaming) { - pollNotifications = setTimeout(() => { + streamTimeout = setTimeout(() => { (async () => { try { hasStreaming = true; @@ -94,7 +95,7 @@ export default memo(function BackgroundService({ isLoggedIn }) { return () => { sub?.unsubscribe?.(); sub = null; - clearTimeout(pollNotifications); + clearTimeout(streamTimeout); clearInterval(pollNotifications); }; }, [visible, isLoggedIn]); From 2aff1dc1fd98f40a5ce3efe6de1b3a13960d5aad Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Sun, 4 Aug 2024 10:09:33 +0800 Subject: [PATCH 05/11] Try switch to 20s interval --- src/components/background-service.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/background-service.jsx b/src/components/background-service.jsx index bcadd2a44..46b9c4cc6 100644 --- a/src/components/background-service.jsx +++ b/src/components/background-service.jsx @@ -9,7 +9,7 @@ import useInterval from '../utils/useInterval'; import usePageVisibility from '../utils/usePageVisibility'; const STREAMING_TIMEOUT = 1000 * 3; // 3 seconds -const POLL_INTERVAL = 15_000; // 15 seconds +const POLL_INTERVAL = 20_000; // 20 seconds export default memo(function BackgroundService({ isLoggedIn }) { // Notifications service From f05e3012e390ba23486f4cf916a884055ff5dfef Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Sun, 4 Aug 2024 13:32:30 +0800 Subject: [PATCH 06/11] Preliminary step for RTL --- src/app.css | 321 +++++++++++++------------- src/app.jsx | 2 + src/components/ICONS.jsx | 117 +++++++--- src/components/account-block.css | 2 + src/components/account-block.jsx | 2 +- src/components/account-info.css | 32 ++- src/components/account-info.jsx | 11 +- src/components/compose.css | 28 +-- src/components/compose.jsx | 10 +- src/components/drafts.css | 2 +- src/components/generic-accounts.css | 6 +- src/components/icon.jsx | 10 +- src/components/links-bar.css | 13 +- src/components/media-modal.jsx | 20 +- src/components/media-post.css | 2 +- src/components/menu2.jsx | 14 +- src/components/modal.css | 19 +- src/components/name-text.jsx | 6 +- src/components/nav-menu.css | 12 +- src/components/poll.jsx | 3 - src/components/report-modal.css | 4 +- src/components/search-form.jsx | 1 + src/components/shortcuts-settings.css | 18 +- src/components/shortcuts-settings.jsx | 5 + src/components/shortcuts.css | 10 +- src/components/status.css | 172 ++++++++------ src/components/status.jsx | 20 +- src/components/timeline.jsx | 11 +- src/components/translation-block.css | 7 +- src/index.css | 16 ++ src/pages/accounts.css | 4 +- src/pages/catchup.css | 44 ++-- src/pages/filters.jsx | 1 + src/pages/hashtag.jsx | 5 +- src/pages/login.css | 5 +- src/pages/login.jsx | 1 + src/pages/notifications.css | 15 +- src/pages/search.css | 15 +- src/pages/settings.css | 10 +- src/pages/status.css | 4 +- src/pages/status.jsx | 2 + src/pages/trending.jsx | 2 +- src/pages/welcome.css | 7 +- src/utils/is-rtl.js | 26 +++ 44 files changed, 654 insertions(+), 383 deletions(-) create mode 100644 src/utils/is-rtl.js diff --git a/src/app.css b/src/app.css index e675c4d14..52245283c 100644 --- a/src/app.css +++ b/src/app.css @@ -162,7 +162,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { white-space: nowrap; } .deck > header .header-grid > .header-side:last-of-type { - text-align: right; + text-align: end; grid-column: 3; } .deck > header .header-grid :is(button, .button).plain { @@ -181,8 +181,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { grid-template-columns: 1fr max-content; } .deck > header .header-grid-2 h1 { - text-align: left; - padding-left: 8px; + text-align: start; + padding-inline-start: 8px; } .deck > header .header-grid h1:has(.ancestors-indicator) { display: flex; @@ -217,6 +217,19 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { opacity: 0.25; } } +@keyframes indeterminate-bar-rtl { + 0% { + transform: translateX(50%); + opacity: 0.25; + } + 50% { + opacity: 1; + } + 100% { + transform: translateX(-50%); + opacity: 0.25; + } +} .deck > header.loading:after { pointer-events: none; content: ''; @@ -232,6 +245,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { transparent ); animation: indeterminate-bar 1s ease-in-out infinite alternate; + &:dir(rtl) { + animation-name: indeterminate-bar-rtl; + } } @media (min-width: 40em) { .deck > header.loading:after { @@ -268,6 +284,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { width: 95vw; max-width: calc(320px * 3.3); transform: translateX(calc(-50% + var(--main-width) / 2)); + &:dir(rtl) { + transform: translateX(calc(50% - var(--main-width) / 2)); + } } } @@ -346,6 +365,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { margin: 0; padding: 0; border-bottom: var(--hairline-width) solid var(--divider-color); + --line-dir: var(--to-forward); } .timeline.flat > li { border-bottom: none; @@ -362,10 +382,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { --avatar-size: 50px; --avatar-margin-start: 16px; --avatar-margin-end: 12px; + --line-curve: 45deg; + :dir(rtl) & { + --line-curve: -45deg; + } } .timeline.contextual > li { background-image: linear-gradient( - to right, + var(--line-dir), transparent, transparent var(--line-start), var(--comment-line-color) var(--line-start), @@ -394,7 +418,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .timeline.contextual > li.descendant:not(.thread) > :is(.status-link, .status-focus) { - padding-left: 40px; + padding-inline-start: 40px; } .timeline.contextual .replies[data-scroll-left]:not([data-scroll-left='0']) { background-color: var(--bg-color); @@ -408,7 +432,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { } .timeline.contextual .replies[data-comments-level='4']:has(.replies) { overflow-x: auto; - mask-image: linear-gradient(to left, transparent, black 32px); + mask-image: linear-gradient(var(--to-backward), transparent, black 32px); } .timeline.contextual .replies[data-comments-level='4']:has(.replies) @@ -426,145 +450,61 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { > :is(.status-link, .status-focus) + .replies .replies-summary { - margin-left: calc( + margin-inline-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + (var(--line-margin-end) * (var(--comments-level) - 1)) ); } -/* .timeline.contextual - > li.descendant.thread - > .status-link - + .replies - .replies - > .replies-summary { - margin-left: calc( - var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + - var(--line-margin-end) - ); -} -.timeline.contextual - > li.descendant.thread - > .status-link - + .replies - .replies - .replies - > .replies-summary { - margin-left: calc( - var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + - (var(--line-margin-end) * 2) - ); -} */ .timeline.contextual > li.descendant.thread > :is(.status-link, .status-focus) + .replies :is(.status-link, .status-focus) { - padding-left: calc( + padding-inline-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + (var(--line-margin-end) * (var(--comments-level) - 1)) ); } -/* .timeline.contextual - > li.descendant.thread - > .status-link - + .replies - .replies - .status-link { - padding-left: calc( - var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + - var(--line-margin-end) - ); -} -.timeline.contextual - > li.descendant.thread - > .status-link - + .replies - .replies - .replies - .status-link { - padding-left: calc( - var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + - (var(--line-margin-end) * 2) - ); -} */ .timeline.contextual > li.descendant:not(.thread) > :is(.status-link, .status-focus) + .replies .replies-summary { - margin-left: calc( + margin-inline-start: calc( var(--thread-start) + var(--line-margin-end) * var(--comments-level) ); } -/* .timeline.contextual - > li.descendant:not(.thread) - > .status-link - + .replies - .replies - > .replies-summary { - margin-left: calc( - var(--thread-start) + var(--line-margin-end) + var(--line-margin-end) - ); -} -.timeline.contextual - > li.descendant:not(.thread) - > .status-link - + .replies - .replies - .replies - > .replies-summary { - margin-left: calc( - var(--thread-start) + var(--line-margin-end) + (var(--line-margin-end) * 2) - ); -} */ .timeline.contextual > li.descendant:not(.thread) > :is(.status-link, .status-focus) + .replies :is(.status-link, .status-focus) { - padding-left: calc( + padding-inline-start: calc( var(--thread-start) + var(--line-margin-end) * var(--comments-level) ); } -/* .timeline.contextual - > li.descendant:not(.thread) - > .status-link - + .replies - .replies - .status-link { - padding-left: calc(var(--thread-start) + (var(--line-margin-end) * 2)); -} -.timeline.contextual - > li.descendant:not(.thread) - > .status-link - + .replies - .replies - .replies - .status-link { - padding-left: calc(var(--thread-start) + (var(--line-margin-end) * 3)); -} */ .timeline.contextual > li.descendant:not(.thread):before { content: ''; position: absolute; top: 10px; - left: var(--line-start); + inset-inline-start: var(--line-start); width: var(--line-diameter); height: var(--line-diameter); border-radius: var(--line-radius); border-style: solid; border-width: var(--line-width); border-color: transparent transparent var(--comment-line-color) transparent; - transform: rotate(45deg); + transform: rotate(var(--line-curve)); } .timeline.contextual > li .replies-link { color: var(--text-insignificant-color); - margin-left: 16px; + margin-inline-start: 16px; margin-top: -12px; padding-bottom: 12px; font-size: 90%; } .timeline.contextual > li.ancestor .replies-link { - margin-left: calc( + margin-inline-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) ); } @@ -572,7 +512,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { > li.thread > :is(.status-link, .status-focus) .replies-link { - margin-left: calc( + margin-inline-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) ); } @@ -603,7 +543,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { list-style: none; gap: 8px; align-items: center; - margin-right: calc(44px + 8px); + margin-inline-end: calc(44px + 8px); b { font-weight: 500; @@ -618,7 +558,9 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { transition: transform 0.3s ease; &:not(:first-child) { - margin: 0 0 0 -4px; + transform: rotate(0deg); + margin: 0; + margin-inline-start: -4px; } } } @@ -637,7 +579,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .replies-parent-link { position: absolute; - right: 4px; + inset-inline-end: 4px; height: 100%; z-index: 2; font-size: 16px; @@ -648,8 +590,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { align-items: center; padding: var(--summary-padding) calc(var(--summary-padding) * 2); transform: translateX(100%); - margin: calc(-1 * var(--summary-padding)) calc(-1 * var(--summary-padding)) - calc(-1 * var(--summary-padding)) 0; + &:dir(rtl) { + transform: translateX(-100%); + } + margin: calc(-1 * var(--summary-padding)) 0; + margin-inline-end: calc(-1 * var(--summary-padding)); border-radius: 8px; background-color: var(--link-bg-color); @@ -681,7 +626,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { color: var(--text-color); background-color: var(--comment-line-color); background-image: linear-gradient( - to top right, + to top var(--forward), var(--comment-line-color), var(--bg-faded-color) ); @@ -697,7 +642,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { } } .timeline.contextual > li .replies[open] > .replies-summary { - border-bottom-left-radius: 0; + border-end-start-radius: 0; .avatars { opacity: 0.5; @@ -727,7 +672,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { ); --line-end: calc(var(--line-start) + var(--line-width)); background-image: linear-gradient( - to right, + var(--line-dir), transparent, transparent var(--line-start), var(--comment-line-color) var(--line-start), @@ -768,14 +713,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { content: ''; position: absolute; top: 10px; - left: var(--line-start); + inset-inline-start: var(--line-start); width: var(--line-diameter); height: var(--line-diameter); border-radius: var(--line-radius); border-style: solid; border-width: var(--line-width); border-color: transparent transparent var(--comment-line-color) transparent; - transform: rotate(45deg); + transform: rotate(var(--line-curve)); } /* .timeline.contextual > li .replies .replies li:before { --line-start: calc( @@ -814,8 +759,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { > ul > li:only-child { > .replies { > ul > li:only-child { - margin-left: calc(-1 * var(--line-margin-end)); - background-position: calc(16px) 0; + margin-inline-start: calc(-1 * var(--line-margin-end)); + background-position: 16px 0; + &:dir(rtl) { + background-position: -16px 0; + } background-size: 100% calc(20px + 8px); &:before { @@ -856,7 +804,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { --line-width: 3px; --line-end: calc(var(--line-start) + var(--line-width)); background-image: linear-gradient( - to right, + var(--line-dir), transparent, transparent var(--line-start), var(--comment-line-color) var(--line-start), @@ -868,8 +816,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { } .timeline:not(.flat) > li.timeline-item-container-start { margin-bottom: 0; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-end-start-radius: 0; + border-end-end-radius: 0; border-bottom: 0; background-position: 0 calc(16px + var(--avatar-size)); } @@ -882,8 +830,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { } .timeline:not(.flat) > li.timeline-item-container-end { margin-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; + border-start-start-radius: 0; + border-start-end-radius: 0; border-top: 0; background-size: 100% 16px; @@ -909,8 +857,10 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { } .timeline .show-more { - padding-left: calc(var(--line-end) + var(--line-margin-end)) !important; - text-align: left; + padding-inline-start: calc( + var(--line-end) + var(--line-margin-end) + ) !important; + text-align: start; background-color: transparent !important; backdrop-filter: none !important; position: relative; @@ -918,7 +868,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { padding-block: 16px !important; .avatars-bunch > .avatar:not(:first-child) { - margin-left: -4px; + margin-inline-start: -4px; } } .timeline .show-more:hover { @@ -930,14 +880,14 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { content: ''; position: absolute; top: 10px; - left: var(--line-start); + inset-inline-start: var(--line-start); width: var(--line-diameter); height: var(--line-diameter); border-radius: var(--line-radius); border-style: solid; border-width: var(--line-width); border-color: transparent transparent var(--comment-line-color) transparent; - transform: rotate(45deg); + transform: rotate(var(--line-curve)); } .status-loading { @@ -988,7 +938,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .status-carousel { --carousel-faded-color: var(--bg-faded-color); background: linear-gradient( - to bottom right, + to bottom var(--forward), var(--carousel-faded-color), transparent ); @@ -1058,12 +1008,12 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { display: none; } .status-carousel .status-carousel-beacon { - margin-right: calc(-1 * var(--carousel-gap)); + margin-inline-end: calc(-1 * var(--carousel-gap)); pointer-events: none; opacity: 0; ~ .status-carousel-beacon { - margin-left: calc(-1 * var(--carousel-gap)); + margin-inline-start: calc(-1 * var(--carousel-gap)); } } /* @@ -1107,7 +1057,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .status-carousel.boosts-carousel > ul > li:before { content: counter(index); position: absolute; - left: 0; + inset-inline-start: 0; font-size: 10px; color: var(--text-insignificant-color); padding: 6px; @@ -1147,11 +1097,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { box-shadow: 0 1px var(--bg-color); &:has(.status-badge:not(:empty)) { - border-top-right-radius: 8px; + border-start-end-radius: 8px; } - .status-carousel.boosts-carousel & { - border-top-left-radius: 8px; + .status-carousel.boosts-carousel &:not(.timeline-item-carousel-group &) { + border-start-start-radius: 8px; } } .status-carousel-link::focus { @@ -1189,14 +1139,29 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { transform: translate3d(0, 0, 0); } } +@keyframes slide-in-rtl { + 0% { + transform: translate3d(-100%, 0, 0); + } + 100% { + transform: translate3d(0, 0, 0); + } +} .deck-backdrop .deck { width: var(--main-width); max-width: 100vw; background-color: var(--bg-color); box-shadow: -1px 0 var(--bg-color); + &:dir(rtl) { + box-shadow: 1px 0 var(--bg-color); + } } .deck-backdrop .deck.slide-in:not(.deck-view-full) { animation: slide-in 0.5s var(--timing-function); + + &:dir(rtl) { + animation-name: slide-in-rtl; + } } .deck-backdrop .deck .status { max-width: var(--main-width); @@ -1240,7 +1205,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { content: ''; display: inline-block; position: absolute; - right: 10px; + inset-inline-end: 10px; width: 4px; height: 4px; border-radius: 50%; @@ -1519,7 +1484,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link { .media-modal-container + .status-deck { /* display: none; */ position: absolute; - right: 0; + inset-inline-end: 0; z-index: -1; pointer-events: none; user-select: none; @@ -1547,8 +1512,8 @@ body:has(.media-modal-container + .status-deck) .media-post-link { ) #modal-container > div { - left: 0; - right: 350px; + inset-inline-start: 0; + inset-inline-end: 350px; width: auto; } /* ✨ New */ @@ -1579,8 +1544,8 @@ body:has(.media-modal-container + .status-deck) .media-post-link { position: fixed; bottom: 16px; bottom: max(16px, env(safe-area-inset-bottom)); - right: 16px; - right: max(16px, env(safe-area-inset-right)); + inset-inline-end: 16px; + inset-inline-end: max(16px, env(safe-area-inset-right)); padding: 16px; background-color: var(--button-bg-blur-color); /* backdrop-filter: blur(16px); */ @@ -1629,7 +1594,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link { display: block; position: absolute; top: 0; - right: 0; + inset-inline-end: 0; width: 14px; height: 14px; border-radius: 50%; @@ -1696,6 +1661,10 @@ body:has(.media-modal-container + .status-deck) .media-post-link { border-radius: 0; padding: 0; right: env(safe-area-inset-right); + &:dir(rtl) { + right: auto; + left: env(safe-area-inset-left); + } width: 44px; height: 44px; display: inline-flex; @@ -1737,6 +1706,11 @@ body:has(.media-modal-container + .status-deck) .media-post-link { } .sheet .sheet-close:not(.outer) + header { padding-right: max(44px, env(safe-area-inset-right)); + + &:dir(rtl) { + padding-right: max(16px, env(safe-area-inset-right)); + padding-left: max(44px, env(safe-area-inset-left)); + } } .sheet header :is(h1, h2, h3) { margin: 0; @@ -1774,6 +1748,10 @@ body:has(.media-modal-container + .status-deck) .media-post-link { width: 100%; height: 100%; } + + :dir(rtl) &.rtl-flip { + transform: scaleX(-1); + } } /* TAG */ @@ -1839,7 +1817,7 @@ body > .szh-menu-container { border: 1px solid var(--outline-color); border-radius: 8px; box-shadow: 0 3px 16px -3px var(--drop-shadow-color); - text-align: left; + text-align: start; /* animation: appear-smooth 0.15s ease-in-out; */ width: 16em; max-width: 90vw; @@ -1975,7 +1953,7 @@ body > .szh-menu-container { } .szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):first-child, .szh-menu .menu-horizontal > *:not(:only-child):first-child .szh-menu__item { - padding-right: 4px !important; + padding-inline-end: 4px !important; } .szh-menu .menu-horizontal @@ -1984,12 +1962,12 @@ body > .szh-menu-container { .menu-horizontal > *:not(:only-child):not(:first-child):not(:last-child) .szh-menu__item { - padding-left: 8px !important; - padding-right: 4px !important; + padding-inline-start: 8px !important; + padding-inline-end: 4px !important; } .szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):last-child, .szh-menu .menu-horizontal > *:not(:only-child):last-child .szh-menu__item { - padding-left: 8px !important; + padding-inline-start: 8px !important; } .szh-menu .szh-menu__item .menu-shortcut { opacity: 0.5; @@ -2053,7 +2031,11 @@ body > .szh-menu-container { text-align: center; opacity: 0.5; text-overflow: clip; - mask-image: linear-gradient(to left, transparent, black 16px); + mask-image: linear-gradient( + var(--to-backward), + transparent, + black 16px + ); } } } @@ -2069,10 +2051,10 @@ body > .szh-menu-container { } > [class^='szh-menu']:first-child { - border-top-left-radius: 8px; + border-start-start-radius: 8px; } > [class^='szh-menu']:last-child { - border-top-right-radius: 8px; + border-start-end-radius: 8px; } } } @@ -2153,6 +2135,9 @@ body > .szh-menu-container { background-image: var(--middle-circle), conic-gradient(var(--color) var(--fill), var(--outline-color) 0); transform: scale(0.7); + &:dir(rtl) { + transform: scale(-0.7, 0.7); + } transition: transform 0.2s ease-in-out; &::-webkit-meter-inner-element, @@ -2362,12 +2347,12 @@ ul.link-list li a { } } ul.link-list li:first-child a { - border-top-left-radius: var(--radius); - border-top-right-radius: var(--radius); + border-start-start-radius: var(--radius); + border-start-end-radius: var(--radius); } ul.link-list li:last-child a { - border-bottom-left-radius: var(--radius); - border-bottom-right-radius: var(--radius); + border-end-start-radius: var(--radius); + border-end-end-radius: var(--radius); } ul.link-list li a:is(:hover, :focus) { color: var(--text-color); @@ -2404,8 +2389,8 @@ ul.link-list li a .icon { } .nav-menu-button.with-avatar .icon { position: absolute; - bottom: 4px; - right: 8px; + inset-block-end: 4px; + inset-inline-end: 8px; background-color: var(--bg-color); border-radius: 2px; } @@ -2433,13 +2418,17 @@ ul.link-list li a .icon { } */ #columns > * { overscroll-behavior: auto; - scroll-snap-align: left; + scroll-snap-align: start; scroll-snap-stop: always; overscroll-behavior: auto; flex-basis: min(100vw, 360px); flex-shrink: 0; box-shadow: -1px 0 var(--bg-color), -2px 0 var(--drop-shadow-color), -3px 0 var(--bg-color); + &:dir(rtl) { + box-shadow: 1px 0 var(--bg-color), 2px 0 var(--drop-shadow-color), + 3px 0 var(--bg-color); + } } #columns:has(> :nth-child(3)) > *:nth-child(even), #columns:has(> :nth-child(3)) @@ -2572,7 +2561,7 @@ ul.link-list li a .icon { gap: 8px; overflow-x: auto; mask-image: linear-gradient( - to right, + var(--to-forward), transparent, black 16px, black calc(100% - 16px), @@ -2586,6 +2575,9 @@ ul.link-list li a .icon { width: 95vw; max-width: calc(320px * 3.3); transform: translateX(calc(-50% + var(--main-width) / 2)); + &:dir(rtl) { + transform: translateX(calc(50% - var(--main-width) / 2)); + } } } @@ -2704,7 +2696,8 @@ ul.link-list li a .icon { min-width: 16px; min-height: 16px; padding: 4px; - margin: -4px -8px -4px 0; + margin: -4px 0; + margin-inline-end: -8px; background-color: var(--bg-faded-color); border-radius: 999px; } @@ -2734,11 +2727,14 @@ ul.link-list li a .icon { .deck-container:has(~ .deck-backdrop .deck) { transition: transform 0.4s ease-out; transform: translate3d(-5vw, 0, 0); + &:dir(rtl) { + transform: translate3d(5vw, 0, 0); + } } .deck-backdrop .deck { /* width: 50%; min-width: var(--main-width); */ - border-left: 1px solid var(--divider-color); + border-inline-start: 1px solid var(--divider-color); } .timeline-deck { border: 0; @@ -2799,16 +2795,19 @@ ul.link-list li a .icon { > li:not(.timeline-item-container-end, .timeline-item-container-middle):has( .status-badge:not(:empty) ) { - border-top-right-radius: 8px; + border-start-end-radius: 8px; } .timeline:not(.flat) > li:has(.status-link.is-active) { transition: var(--back-transition); transform: translate3d(-2.5vw, 0, 0); + &:dir(rtl) { + transform: translate3d(2.5vw, 0, 0); + } } .timeline:not(.flat) > li.timeline-item-container:has(.status-link.is-active) { - border-top-left-radius: var(--item-radius); - border-bottom-left-radius: var(--item-radius); + border-start-start-radius: var(--item-radius); + border-end-start-radius: var(--item-radius); } .timeline:not(.flat) > li:not(:has(.status-carousel)):has(+ li .status-link.is-active), @@ -2817,19 +2816,22 @@ ul.link-list li a .icon { + li { transition: var(--back-transition); transform: translate3d(-1.25vw, 0, 0); + &:dir(rtl) { + transform: translate3d(1.25vw, 0, 0); + } } .timeline:not(.flat) > li.timeline-item-container:not(:has(.status-carousel)):has( + li .status-link.is-active ) { - border-top-left-radius: var(--item-radius); + border-start-start-radius: var(--item-radius); } .timeline:not(.flat) > li.timeline-item-container:not(:has(.status-carousel)):has( .status-link.is-active ) + li.timeline-item-container { - border-bottom-left-radius: var(--item-radius); + border-end-start-radius: var(--item-radius); } .box { padding: 32px; @@ -2841,5 +2843,8 @@ ul.link-list li a .icon { width: 95vw; max-width: calc(320px * 3.3); transform: translateX(calc(-50% + var(--main-width) / 2)); + &:dir(rtl) { + transform: translateX(calc(50% - var(--main-width) / 2)); + } } } diff --git a/src/app.jsx b/src/app.jsx index d2d044c23..fd3ef5ed7 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -132,6 +132,8 @@ setTimeout(() => { setTimeout(() => { if (Array.isArray(ICONS[icon])) { ICONS[icon][0]?.(); + } else if (typeof ICONS[icon] === 'object') { + ICONS[icon].module?.(); } else { ICONS[icon]?.(); } diff --git a/src/components/ICONS.jsx b/src/components/ICONS.jsx index 0fa7880f0..cac8190bf 100644 --- a/src/components/ICONS.jsx +++ b/src/components/ICONS.jsx @@ -6,8 +6,14 @@ export const ICONS = { 'x-circle': () => import('@iconify-icons/mingcute/close-circle-line'), transfer: () => import('@iconify-icons/mingcute/transfer-4-line'), rocket: () => import('@iconify-icons/mingcute/rocket-line'), - 'arrow-left': () => import('@iconify-icons/mingcute/arrow-left-line'), - 'arrow-right': () => import('@iconify-icons/mingcute/arrow-right-line'), + 'arrow-left': { + module: () => import('@iconify-icons/mingcute/arrow-left-line'), + rtl: true, + }, + 'arrow-right': { + module: () => import('@iconify-icons/mingcute/arrow-right-line'), + rtl: true, + }, 'arrow-up': () => import('@iconify-icons/mingcute/arrow-up-line'), 'arrow-down': () => import('@iconify-icons/mingcute/arrow-down-line'), earth: () => import('@iconify-icons/mingcute/earth-line'), @@ -16,8 +22,14 @@ export const ICONS = { 'eye-close': () => import('@iconify-icons/mingcute/eye-close-line'), 'eye-open': () => import('@iconify-icons/mingcute/eye-2-line'), message: () => import('@iconify-icons/mingcute/mail-line'), - comment: () => import('@iconify-icons/mingcute/chat-3-line'), - comment2: () => import('@iconify-icons/mingcute/comment-2-line'), + comment: { + module: () => import('@iconify-icons/mingcute/chat-3-line'), + rtl: true, + }, + comment2: { + module: () => import('@iconify-icons/mingcute/comment-2-line'), + rtl: true, + }, home: () => import('@iconify-icons/mingcute/home-3-line'), notification: () => import('@iconify-icons/mingcute/notification-line'), follow: () => import('@iconify-icons/mingcute/user-follow-line'), @@ -31,23 +43,46 @@ export const ICONS = { gear: () => import('@iconify-icons/mingcute/settings-3-line'), more: () => import('@iconify-icons/mingcute/more-3-line'), more2: () => import('@iconify-icons/mingcute/more-1-fill'), - external: () => import('@iconify-icons/mingcute/external-link-line'), - popout: () => import('@iconify-icons/mingcute/external-link-line'), - popin: [() => import('@iconify-icons/mingcute/external-link-line'), '180deg'], + external: { + module: () => import('@iconify-icons/mingcute/external-link-line'), + rtl: true, + }, + popout: { + module: () => import('@iconify-icons/mingcute/external-link-line'), + rtl: true, + }, + popin: { + module: () => import('@iconify-icons/mingcute/external-link-line'), + rotate: '180deg', + rtl: true, + }, plus: () => import('@iconify-icons/mingcute/add-circle-line'), - 'chevron-left': () => import('@iconify-icons/mingcute/left-line'), - 'chevron-right': () => import('@iconify-icons/mingcute/right-line'), + 'chevron-left': { + module: () => import('@iconify-icons/mingcute/left-line'), + rtl: true, + }, + 'chevron-right': { + module: () => import('@iconify-icons/mingcute/right-line'), + rtl: true, + }, 'chevron-down': () => import('@iconify-icons/mingcute/down-line'), - reply: [ - () => import('@iconify-icons/mingcute/share-forward-line'), - '180deg', - 'horizontal', - ], + reply: { + module: () => import('@iconify-icons/mingcute/share-forward-line'), + rotate: '180deg', + flip: 'horizontal', + rtl: true, + }, thread: () => import('@iconify-icons/mingcute/route-line'), - group: () => import('@iconify-icons/mingcute/group-line'), + group: { + module: () => import('@iconify-icons/mingcute/group-line'), + rtl: true, + }, bot: () => import('@iconify-icons/mingcute/android-2-line'), menu: () => import('@iconify-icons/mingcute/rows-4-line'), - list: () => import('@iconify-icons/mingcute/list-check-line'), + list: { + module: () => import('@iconify-icons/mingcute/list-check-line'), + rtl: true, + }, search: () => import('@iconify-icons/mingcute/search-2-line'), hashtag: () => import('@iconify-icons/mingcute/hashtag-line'), info: () => import('@iconify-icons/mingcute/information-line'), @@ -62,12 +97,21 @@ export const ICONS = { share: () => import('@iconify-icons/mingcute/share-2-line'), sparkles: () => import('@iconify-icons/mingcute/sparkles-line'), sparkles2: () => import('@iconify-icons/mingcute/sparkles-2-line'), - exit: () => import('@iconify-icons/mingcute/exit-line'), + exit: { + module: () => import('@iconify-icons/mingcute/exit-line'), + rtl: true, + }, translate: () => import('@iconify-icons/mingcute/translate-line'), play: () => import('@iconify-icons/mingcute/play-fill'), trash: () => import('@iconify-icons/mingcute/delete-2-line'), - mute: () => import('@iconify-icons/mingcute/volume-mute-line'), - unmute: () => import('@iconify-icons/mingcute/volume-line'), + mute: { + module: () => import('@iconify-icons/mingcute/volume-mute-line'), + rtl: true, + }, + unmute: { + module: () => import('@iconify-icons/mingcute/volume-line'), + rtl: true, + }, block: () => import('@iconify-icons/mingcute/forbid-circle-line'), unblock: [ () => import('@iconify-icons/mingcute/forbid-circle-line'), @@ -81,30 +125,51 @@ export const ICONS = { filters: () => import('@iconify-icons/mingcute/filter-line'), chart: () => import('@iconify-icons/mingcute/chart-line-line'), react: () => import('@iconify-icons/mingcute/react-line'), - layout4: () => import('@iconify-icons/mingcute/layout-4-line'), + layout4: { + module: () => import('@iconify-icons/mingcute/layout-4-line'), + rtl: true, + }, layout5: () => import('@iconify-icons/mingcute/layout-5-line'), - announce: () => import('@iconify-icons/mingcute/announcement-line'), + announce: { + module: () => import('@iconify-icons/mingcute/announcement-line'), + rtl: true, + }, alert: () => import('@iconify-icons/mingcute/alert-line'), round: () => import('@iconify-icons/mingcute/round-fill'), 'arrow-up-circle': () => import('@iconify-icons/mingcute/arrow-up-circle-line'), 'arrow-down-circle': () => import('@iconify-icons/mingcute/arrow-down-circle-line'), - clipboard: () => import('@iconify-icons/mingcute/clipboard-line'), + clipboard: { + module: () => import('@iconify-icons/mingcute/clipboard-line'), + rtl: true, + }, 'account-edit': () => import('@iconify-icons/mingcute/user-edit-line'), 'account-warning': () => import('@iconify-icons/mingcute/user-warning-line'), keyboard: () => import('@iconify-icons/mingcute/keyboard-line'), cloud: () => import('@iconify-icons/mingcute/cloud-line'), - month: () => import('@iconify-icons/mingcute/calendar-month-line'), + month: { + module: () => import('@iconify-icons/mingcute/calendar-month-line'), + rtl: true, + }, media: () => import('@iconify-icons/mingcute/photo-album-line'), speak: () => import('@iconify-icons/mingcute/radar-line'), building: () => import('@iconify-icons/mingcute/building-5-line'), - history2: () => import('@iconify-icons/mingcute/history-2-line'), + history2: { + module: () => import('@iconify-icons/mingcute/history-2-line'), + rtl: true, + }, document: () => import('@iconify-icons/mingcute/document-line'), - 'arrows-right': () => import('@iconify-icons/mingcute/arrows-right-line'), + 'arrows-right': { + module: () => import('@iconify-icons/mingcute/arrows-right-line'), + rtl: true, + }, code: () => import('@iconify-icons/mingcute/code-line'), copy: () => import('@iconify-icons/mingcute/copy-2-line'), - quote: () => import('@iconify-icons/mingcute/quote-left-line'), + quote: { + module: () => import('@iconify-icons/mingcute/quote-left-line'), + rtl: true, + }, settings: () => import('@iconify-icons/mingcute/settings-6-line'), 'heart-break': () => import('@iconify-icons/mingcute/heart-crack-line'), 'user-x': () => import('@iconify-icons/mingcute/user-x-line'), diff --git a/src/components/account-block.css b/src/components/account-block.css index 14309fb93..890e4968b 100644 --- a/src/components/account-block.css +++ b/src/components/account-block.css @@ -29,6 +29,8 @@ line-clamp: 1; text-overflow: ellipsis; overflow: hidden; + unicode-bidi: isolate; + direction: initial; } a { diff --git a/src/components/account-block.jsx b/src/components/account-block.jsx index 326f415c8..47b4e711d 100644 --- a/src/components/account-block.jsx +++ b/src/components/account-block.jsx @@ -120,7 +120,7 @@ function AccountBlock({ )} )}{' '} -