diff --git a/src/app.css b/src/app.css index ca8ca8b..b149534 100644 --- a/src/app.css +++ b/src/app.css @@ -1917,7 +1917,8 @@ body > .szh-menu-container { /* two columns only */ grid-template-columns: repeat(2, 1fr); } -.szh-menu .menu-horizontal:has(> .szh-menu__item:only-child) { +.szh-menu .menu-horizontal:has(> .szh-menu__item:only-child), +.szh-menu .menu-horizontal:has(> .szh-menu__submenu:only-child) { grid-template-columns: 1fr; } .szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):first-child, diff --git a/src/components/nav-menu.jsx b/src/components/nav-menu.jsx index 769fb84..74f2567 100644 --- a/src/components/nav-menu.jsx +++ b/src/components/nav-menu.jsx @@ -12,6 +12,7 @@ import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; import states from '../utils/states'; import store from '../utils/store'; import { getCurrentAccountID } from '../utils/store-utils'; +import supports from '../utils/supports'; import Avatar from './avatar'; import Icon from './icon'; @@ -83,8 +84,10 @@ function NavMenu(props) { return results; } + const supportsLists = supports('@mastodon/lists'); const [lists, setLists] = useState([]); useEffect(() => { + if (!supportsLists) return; if (menuState === 'open') { getLists().then(setLists); } @@ -186,9 +189,11 @@ function NavMenu(props) { Catch-up - - Mentions - + {supports('@mastodon/mentions') && ( + + Mentions + + )} Notifications {snapStates.notificationsShowNew && ( @@ -232,10 +237,12 @@ function NavMenu(props) { )} ) : ( - - - Lists - + supportsLists && ( + + + Lists + + ) )} Bookmarks @@ -260,10 +267,12 @@ function NavMenu(props) { Followed Hashtags - - - Filters - + {supports('@mastodon/filters') && ( + + + Filters + + )} { states.showGenericAccounts = { diff --git a/src/components/status.jsx b/src/components/status.jsx index 21a423d..455cd4e 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -55,6 +55,7 @@ import states, { getStatus, saveStatus, statusKey } from '../utils/states'; import statusPeek from '../utils/status-peek'; import store from '../utils/store'; import { getCurrentAccountID } from '../utils/store-utils'; +import supports from '../utils/supports'; import unfurlMastodonLink from '../utils/unfurl-link'; import useHotkeys from '../utils/useHotkeys'; import useTruncated from '../utils/useTruncated'; @@ -149,6 +150,12 @@ const PostContent = memo( }, ); +const SIZE_CLASS = { + s: 'small', + m: 'medium', + l: 'large', +}; + function Status({ statusID, status, @@ -174,7 +181,11 @@ function Status({ }) { if (skeleton) { return ( -
+
{!mediaFirst && }
@@ -640,6 +651,7 @@ function Status({ }; const bookmarkStatus = async () => { + if (!supports('@mastodon/post-bookmark')) return; if (!sameInstance || !authenticated) { alert(unauthInteractionErrorMessage); return false; @@ -827,13 +839,15 @@ function Status({ : 'Like'} - - - {bookmarked ? 'Unbookmark' : 'Bookmark'} - + {supports('@mastodon/post-bookmark') && ( + + + {bookmarked ? 'Unbookmark' : 'Bookmark'} + + )}
)} @@ -1077,16 +1091,18 @@ function Status({ )} {isSelf && ( -
- -
+ {supports('@mastodon/post-bookmark') && ( +
+ +
+ )} link.type === 'link'); - console.log('links', links); - if (links?.length) { - setLinks(links); + if (supports('@mastodon/trending-links')) { + try { + const { value } = await fetchLinks(masto, instance); + // 4 types available: link, photo, video, rich + // Only want links for now + const links = value?.filter?.((link) => link.type === 'link'); + console.log('links', links); + if (links?.length) { + setLinks(links); + } + } catch (e) { + console.error(e); } - } catch (e) { - console.error(e); } } const results = await trendIterator.current.next(); diff --git a/src/utils/supports.js b/src/utils/supports.js index 02b1a49..4733cd9 100644 --- a/src/utils/supports.js +++ b/src/utils/supports.js @@ -4,6 +4,20 @@ import features from '../data/features.json'; import { getCurrentInstance } from './store-utils'; +// Non-semver(?) UA string detection +// Can't put this inside features.json due to regex +const containPixelfed = /pixelfed/i; +const notContainPixelfed = /^(?!.*pixelfed).*$/i; +const platformFeatures = { + '@mastodon/lists': notContainPixelfed, + '@mastodon/filters': notContainPixelfed, + '@mastodon/mentions': notContainPixelfed, + '@mastodon/trending-hashtags': notContainPixelfed, + '@mastodon/trending-links': notContainPixelfed, + '@mastodon/post-bookmark': notContainPixelfed, + '@mastodon/post-edit': notContainPixelfed, + '@pixelfed/trending': containPixelfed, +}; const supportsCache = {}; function supports(feature) { @@ -11,6 +25,11 @@ function supports(feature) { const { version, domain } = getCurrentInstance(); const key = `${domain}-${feature}`; if (supportsCache[key]) return supportsCache[key]; + + if (platformFeatures[feature]) { + return (supportsCache[key] = platformFeatures[feature].test(version)); + } + const range = features[feature]; if (!range) return false; return (supportsCache[key] = satisfies(version, range, {