From 839023cefc5020b07f490c04f4835802d5351f39 Mon Sep 17 00:00:00 2001 From: Scott Feeney Date: Thu, 19 Sep 2024 01:08:52 -0700 Subject: [PATCH 1/4] Use NodeInfo to detect features if available For Mastodon <=4.3 (all current stable releases of Mastodon), the NodeInfo request will always fail due to mastodon/mastodon#23135 and fall back to the existing behavior. For other server software, this will allow for more accurate checking of feature availability. Fixes #808: adds support for exclusive lists with GoToSocial 0.17+. --- src/data/features.json | 8 ---- src/utils/api.js | 27 +++++++++++- src/utils/store-utils.js | 2 +- src/utils/supports.js | 91 +++++++++++++++++++++++++++------------- 4 files changed, 88 insertions(+), 40 deletions(-) delete mode 100644 src/data/features.json diff --git a/src/data/features.json b/src/data/features.json deleted file mode 100644 index 6ff4bb1e..00000000 --- a/src/data/features.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "@mastodon/edit-media-attributes": ">=4.1", - "@mastodon/list-exclusive": ">=4.2", - "@mastodon/filtered-notifications": "~4.3 || >=4.3", - "@mastodon/fetch-multiple-statuses": "~4.3 || >=4.3", - "@mastodon/trending-link-posts": "~4.3 || >=4.3", - "@mastodon/grouped-notifications": "~4.3 || >=4.3" -} diff --git a/src/utils/api.js b/src/utils/api.js index cf6652bc..c2f742ad 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -80,7 +80,6 @@ export async function initInstance(client, instance) { } __BENCHMARK.end('fetch-instance'); if (!info) return; - console.log(info); const { // v1 uri, @@ -89,6 +88,32 @@ export async function initInstance(client, instance) { domain, configuration: { urls: { streaming } = {} } = {}, } = info; + + let nodeInfo; + try { + if (uri || domain) { + let urlBase = uri || `https://${domain}`; + const wellKnownResponse = await fetch(`${urlBase}/.well-known/nodeinfo`); + if (wellKnownResponse.ok) { + const wellKnown = await wellKnownResponse.json(); + if (wellKnown && Array.isArray(wellKnown.links)) { + const nodeInfoUrl = wellKnown.links.find( + (link) => typeof link.rel === 'string' && + link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') + )?.href; + if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { + const nodeInfoResponse = await fetch(nodeInfoUrl); + nodeInfo = await nodeInfoResponse.json(); + } + } + } + } + } catch (e) {} + if (nodeInfo) { + info.nodeInfo = nodeInfo; + } + console.log(info); + const instances = store.local.getJSON('instances') || {}; if (uri || domain) { instances[ diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index cc236215..c2caf9e5 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -163,5 +163,5 @@ export function getVapidKey() { export function isMediaFirstInstance() { const instance = getCurrentInstance(); - return /pixelfed/i.test(instance?.version); + return instance.nodeInfo?.software?.name === 'pixelfed'; } diff --git a/src/utils/supports.js b/src/utils/supports.js index 66454224..8721d925 100644 --- a/src/utils/supports.js +++ b/src/utils/supports.js @@ -1,51 +1,82 @@ import { satisfies } from 'compare-versions'; -import features from '../data/features.json'; - import { getCurrentInstance } from './store-utils'; -// Non-semver(?) UA string detection -const containPixelfed = /pixelfed/i; -const notContainPixelfed = /^(?!.*pixelfed).*$/i; -const containPleroma = /pleroma/i; -const containAkkoma = /akkoma/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, - '@mastodon/profile-edit': notContainPixelfed, - '@mastodon/profile-private-note': notContainPixelfed, - '@pixelfed/trending': containPixelfed, - '@pixelfed/home-include-reblogs': containPixelfed, - '@pixelfed/global-feed': containPixelfed, - '@pleroma/local-visibility-post': containPleroma, - '@akkoma/local-visibility-post': containAkkoma, + '@mastodon/edit-media-attributes': [['mastodon', '>=4.1']], + '@mastodon/list-exclusive': [ + ['mastodon', '>=4.2'], + ['gotosocial', '>=0.17'], + ], + '@mastodon/filtered-notifications': [['mastodon', '>=4.3']], + '@mastodon/fetch-multiple-statuses': [['mastodon', '>=4.3']], + '@mastodon/trending-link-posts': [['mastodon', '>=4.3']], + '@mastodon/grouped-notifications': [['mastodon', '>=4.3']], + '@mastodon/lists': [['!pixelfed']], + '@mastodon/filters': [['!pixelfed']], + '@mastodon/mentions': [['!pixelfed']], + '@mastodon/trending-hashtags': [['!pixelfed']], + '@mastodon/trending-links': [['!pixelfed']], + '@mastodon/post-bookmark': [['!pixelfed']], + '@mastodon/post-edit': [['!pixelfed']], + '@mastodon/profile-edit': [['!pixelfed']], + '@mastodon/profile-private-note': [['!pixelfed']], + '@pixelfed/trending': [['pixelfed']], + '@pixelfed/home-include-reblogs': [['pixelfed']], + '@pixelfed/global-feed': [['pixelfed']], + '@pleroma/local-visibility-post': [['pleroma']], + '@akkoma/local-visibility-post': [['akkoma']], }; + const supportsCache = {}; function supports(feature) { + const specs = platformFeatures[feature]; + if (!specs) return false; + try { - const { version, domain } = getCurrentInstance(); + let { version, domain, nodeInfo } = getCurrentInstance(); + const key = `${domain}-${feature}`; if (supportsCache[key]) return supportsCache[key]; - if (platformFeatures[feature]) { - return (supportsCache[key] = platformFeatures[feature].test(version)); + let software = 'mastodon'; + if ( + nodeInfo && nodeInfo.software && typeof nodeInfo.software.version === 'string' + && typeof nodeInfo.software.name === 'string' + ) { + software = nodeInfo.software.name.toLowerCase(); + version = nodeInfo.software.version; } - const range = features[feature]; - if (!range) return false; - return (supportsCache[key] = satisfies(version, range, { - includePrerelease: true, - loose: true, - })); + const isSupported = specs.some((spec) => versionSatisfies(software, version, spec)); + return (supportsCache[key] = isSupported); } catch (e) { return false; } } +function versionSatisfies(software, version, [softwareSpec, versionSpec]) { + let softwareMatches; + + // Inverted spec, like !pixelfed + if (softwareSpec.startsWith('!')) { + softwareMatches = software !== softwareSpec.slice(1); + } else { + softwareMatches = ( + software === softwareSpec || ( + // Hometown inherits Mastodon features + software === 'hometown' && softwareSpec === 'mastodon' + ) + ); + } + + return softwareMatches && ( + versionSpec == null || satisfies(version, versionSpec, { + includePrerelease: true, + loose: true, + }) + ); +} + export default supports; From ad0ab0c84588592cd277c153794ff87ae7c628bb Mon Sep 17 00:00:00 2001 From: Scott Feeney Date: Fri, 20 Sep 2024 00:13:02 -0700 Subject: [PATCH 2/4] Shrink the size of the feature detection change --- src/components/list-add-edit.jsx | 2 +- src/data/features.json | 9 ++++ src/utils/api.js | 27 +++++----- src/utils/store-utils.js | 2 +- src/utils/supports.js | 93 ++++++++++++-------------------- 5 files changed, 57 insertions(+), 76 deletions(-) create mode 100644 src/data/features.json diff --git a/src/components/list-add-edit.jsx b/src/components/list-add-edit.jsx index d9a21a4b..8630d712 100644 --- a/src/components/list-add-edit.jsx +++ b/src/components/list-add-edit.jsx @@ -24,7 +24,7 @@ function ListAddEdit({ list, onClose }) { } } }, [editMode]); - const supportsExclusive = supports('@mastodon/list-exclusive'); + const supportsExclusive = supports('@mastodon/list-exclusive') || supports('@gotosocial/list-exclusive'); return (
diff --git a/src/data/features.json b/src/data/features.json new file mode 100644 index 00000000..7376418b --- /dev/null +++ b/src/data/features.json @@ -0,0 +1,9 @@ +{ + "@mastodon/edit-media-attributes": ">=4.1", + "@mastodon/list-exclusive": ">=4.2", + "@gotosocial/list-exclusive": ">=0.17", + "@mastodon/filtered-notifications": "~4.3 || >=4.3", + "@mastodon/fetch-multiple-statuses": "~4.3 || >=4.3", + "@mastodon/trending-link-posts": "~4.3 || >=4.3", + "@mastodon/grouped-notifications": "~4.3 || >=4.3" +} diff --git a/src/utils/api.js b/src/utils/api.js index c2f742ad..4ea12ddc 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -89,29 +89,26 @@ export async function initInstance(client, instance) { configuration: { urls: { streaming } = {} } = {}, } = info; - let nodeInfo; + // GoToSocial requires we get the NodeInfo to identify server type + // spec: https://github.com/jhass/nodeinfo try { if (uri || domain) { let urlBase = uri || `https://${domain}`; - const wellKnownResponse = await fetch(`${urlBase}/.well-known/nodeinfo`); - if (wellKnownResponse.ok) { - const wellKnown = await wellKnownResponse.json(); - if (wellKnown && Array.isArray(wellKnown.links)) { - const nodeInfoUrl = wellKnown.links.find( - (link) => typeof link.rel === 'string' && - link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') - )?.href; - if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { - const nodeInfoResponse = await fetch(nodeInfoUrl); - nodeInfo = await nodeInfoResponse.json(); + const wellKnown = await (await fetch(`${urlBase}/.well-known/nodeinfo`)).json(); + if (Array.isArray(wellKnown?.links)) { + const nodeInfoUrl = wellKnown.links.find( + (link) => typeof link.rel === 'string' && + link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') + )?.href; + if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { + const nodeInfo = await (await fetch(nodeInfoUrl)).json(); + if (typeof nodeInfo?.software?.name === 'string') { + info.software_name = nodeInfo.software.name; } } } } } catch (e) {} - if (nodeInfo) { - info.nodeInfo = nodeInfo; - } console.log(info); const instances = store.local.getJSON('instances') || {}; diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index c2caf9e5..cc236215 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -163,5 +163,5 @@ export function getVapidKey() { export function isMediaFirstInstance() { const instance = getCurrentInstance(); - return instance.nodeInfo?.software?.name === 'pixelfed'; + return /pixelfed/i.test(instance?.version); } diff --git a/src/utils/supports.js b/src/utils/supports.js index 8721d925..07b1d54b 100644 --- a/src/utils/supports.js +++ b/src/utils/supports.js @@ -1,82 +1,57 @@ import { satisfies } from 'compare-versions'; +import features from '../data/features.json'; + import { getCurrentInstance } from './store-utils'; +// Non-semver(?) UA string detection +const containPixelfed = /pixelfed/i; +const notContainPixelfed = /^(?!.*pixelfed).*$/i; +const containPleroma = /pleroma/i; +const containAkkoma = /akkoma/i; +const containGTS = /gotosocial/i; const platformFeatures = { - '@mastodon/edit-media-attributes': [['mastodon', '>=4.1']], - '@mastodon/list-exclusive': [ - ['mastodon', '>=4.2'], - ['gotosocial', '>=0.17'], - ], - '@mastodon/filtered-notifications': [['mastodon', '>=4.3']], - '@mastodon/fetch-multiple-statuses': [['mastodon', '>=4.3']], - '@mastodon/trending-link-posts': [['mastodon', '>=4.3']], - '@mastodon/grouped-notifications': [['mastodon', '>=4.3']], - '@mastodon/lists': [['!pixelfed']], - '@mastodon/filters': [['!pixelfed']], - '@mastodon/mentions': [['!pixelfed']], - '@mastodon/trending-hashtags': [['!pixelfed']], - '@mastodon/trending-links': [['!pixelfed']], - '@mastodon/post-bookmark': [['!pixelfed']], - '@mastodon/post-edit': [['!pixelfed']], - '@mastodon/profile-edit': [['!pixelfed']], - '@mastodon/profile-private-note': [['!pixelfed']], - '@pixelfed/trending': [['pixelfed']], - '@pixelfed/home-include-reblogs': [['pixelfed']], - '@pixelfed/global-feed': [['pixelfed']], - '@pleroma/local-visibility-post': [['pleroma']], - '@akkoma/local-visibility-post': [['akkoma']], + '@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, + '@mastodon/profile-edit': notContainPixelfed, + '@mastodon/profile-private-note': notContainPixelfed, + '@pixelfed/trending': containPixelfed, + '@pixelfed/home-include-reblogs': containPixelfed, + '@pixelfed/global-feed': containPixelfed, + '@pleroma/local-visibility-post': containPleroma, + '@akkoma/local-visibility-post': containAkkoma, }; const supportsCache = {}; function supports(feature) { - const specs = platformFeatures[feature]; - if (!specs) return false; - try { - let { version, domain, nodeInfo } = getCurrentInstance(); + let { version, domain, software_name } = getCurrentInstance(); const key = `${domain}-${feature}`; if (supportsCache[key]) return supportsCache[key]; - let software = 'mastodon'; - if ( - nodeInfo && nodeInfo.software && typeof nodeInfo.software.version === 'string' - && typeof nodeInfo.software.name === 'string' - ) { - software = nodeInfo.software.name.toLowerCase(); - version = nodeInfo.software.version; + if (platformFeatures[feature]) { + return (supportsCache[key] = platformFeatures[feature].test(version)); } - const isSupported = specs.some((spec) => versionSatisfies(software, version, spec)); - return (supportsCache[key] = isSupported); + const range = features[feature]; + if (!range) return false; + return (supportsCache[key] = ( + containGTS.test(feature) === containGTS.test(software_name) + && satisfies(version, range, { + includePrerelease: true, + loose: true, + }) + )); } catch (e) { return false; } } -function versionSatisfies(software, version, [softwareSpec, versionSpec]) { - let softwareMatches; - - // Inverted spec, like !pixelfed - if (softwareSpec.startsWith('!')) { - softwareMatches = software !== softwareSpec.slice(1); - } else { - softwareMatches = ( - software === softwareSpec || ( - // Hometown inherits Mastodon features - software === 'hometown' && softwareSpec === 'mastodon' - ) - ); - } - - return softwareMatches && ( - versionSpec == null || satisfies(version, versionSpec, { - includePrerelease: true, - loose: true, - }) - ); -} - export default supports; From 22f0703162fb14fae4f12774fbf1ab4ebc3f5f27 Mon Sep 17 00:00:00 2001 From: Scott Feeney Date: Thu, 10 Oct 2024 17:31:16 -0700 Subject: [PATCH 3/4] Store nodeInfo separately + other feedback --- src/utils/api.js | 48 ++++++++++++++++++++++------------------ src/utils/store-utils.js | 14 ++++++++++++ src/utils/supports.js | 26 ++++++++++++++-------- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index 4ea12ddc..ff22f3d2 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -80,6 +80,7 @@ export async function initInstance(client, instance) { } __BENCHMARK.end('fetch-instance'); if (!info) return; + console.log(info); const { // v1 uri, @@ -89,28 +90,6 @@ export async function initInstance(client, instance) { configuration: { urls: { streaming } = {} } = {}, } = info; - // GoToSocial requires we get the NodeInfo to identify server type - // spec: https://github.com/jhass/nodeinfo - try { - if (uri || domain) { - let urlBase = uri || `https://${domain}`; - const wellKnown = await (await fetch(`${urlBase}/.well-known/nodeinfo`)).json(); - if (Array.isArray(wellKnown?.links)) { - const nodeInfoUrl = wellKnown.links.find( - (link) => typeof link.rel === 'string' && - link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') - )?.href; - if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { - const nodeInfo = await (await fetch(nodeInfoUrl)).json(); - if (typeof nodeInfo?.software?.name === 'string') { - info.software_name = nodeInfo.software.name; - } - } - } - } - } catch (e) {} - console.log(info); - const instances = store.local.getJSON('instances') || {}; if (uri || domain) { instances[ @@ -124,6 +103,31 @@ export async function initInstance(client, instance) { instances[instance.toLowerCase()] = info; } store.local.setJSON('instances', instances); + + let nodeInfo; + // GoToSocial requires we get the NodeInfo to identify server type + // spec: https://github.com/jhass/nodeinfo + try { + if (uri || domain) { + let urlBase = uri || `https://${domain}`; + const wellKnown = await (await fetch(`${urlBase}/.well-known/nodeinfo`)).json(); + if (Array.isArray(wellKnown?.links)) { + const nodeInfoUrl = wellKnown.links.find( + (link) => typeof link.rel === 'string' && + link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') + )?.href; + if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { + nodeInfo = await (await fetch(nodeInfoUrl)).json(); + } + } + } + } catch (e) {} + const nodeInfos = store.local.getJSON('nodeInfos') || {}; + if (nodeInfo) { + nodeInfos[instance.toLowerCase()] = nodeInfo; + } + store.local.setJSON('nodeInfos', nodeInfos); + // This is a weird place to put this but here's updating the masto instance with the streaming API URL set in the configuration // Reason: Streaming WebSocket URL may change, unlike the standard API REST URLs const supportsWebSocket = 'WebSocket' in window; diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index cc236215..99f3186d 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -115,6 +115,20 @@ export function getCurrentInstance() { } } +let currentNodeInfo = null; +export function getCurrentNodeInfo() { + if (currentNodeInfo) return currentNodeInfo; + try { + const account = getCurrentAccount(); + const nodeInfos = store.local.getJSON('nodeInfos') || {}; + const instanceURL = account.instanceURL.toLowerCase(); + return (currentNodeInfo = (nodeInfos[instanceURL] || {})); + } catch (e) { + console.error(e); + return {}; + } +} + // Massage these instance configurations to match the Mastodon API // - Pleroma function getInstanceConfiguration(instance) { diff --git a/src/utils/supports.js b/src/utils/supports.js index 07b1d54b..f8183526 100644 --- a/src/utils/supports.js +++ b/src/utils/supports.js @@ -2,7 +2,7 @@ import { satisfies } from 'compare-versions'; import features from '../data/features.json'; -import { getCurrentInstance } from './store-utils'; +import { getCurrentInstance, getCurrentNodeInfo } from './store-utils'; // Non-semver(?) UA string detection const containPixelfed = /pixelfed/i; @@ -31,7 +31,13 @@ const supportsCache = {}; function supports(feature) { try { - let { version, domain, software_name } = getCurrentInstance(); + let { version, domain } = getCurrentInstance(); + let softwareName = getCurrentNodeInfo()?.software?.name || 'mastodon'; + + if (softwareName === 'hometown') { + // Hometown is a Mastodon fork and inherits its features + softwareName = 'mastodon'; + } const key = `${domain}-${feature}`; if (supportsCache[key]) return supportsCache[key]; @@ -42,13 +48,15 @@ function supports(feature) { const range = features[feature]; if (!range) return false; - return (supportsCache[key] = ( - containGTS.test(feature) === containGTS.test(software_name) - && satisfies(version, range, { - includePrerelease: true, - loose: true, - }) - )); + + // '@mastodon/blah' => 'mastodon' + const featureSoftware = feature.match(/^@([a-z]+)\//)[1]; + + const doesSoftwareMatch = featureSoftware === softwareName.toLowerCase(); + return (supportsCache[key] = doesSoftwareMatch && satisfies(version, range, { + includePrerelease: true, + loose: true, + })); } catch (e) { return false; } From 59d5c7335968dfff9b1e20fe59a8e9834b27500e Mon Sep 17 00:00:00 2001 From: Scott Feeney Date: Thu, 10 Oct 2024 17:38:06 -0700 Subject: [PATCH 4/4] Run prettier --- src/components/list-add-edit.jsx | 4 +++- src/locales/en.po | 30 +++++++++++++++--------------- src/utils/api.js | 9 ++++++--- src/utils/store-utils.js | 2 +- src/utils/supports.js | 10 ++++++---- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/components/list-add-edit.jsx b/src/components/list-add-edit.jsx index 8630d712..17279b7b 100644 --- a/src/components/list-add-edit.jsx +++ b/src/components/list-add-edit.jsx @@ -24,7 +24,9 @@ function ListAddEdit({ list, onClose }) { } } }, [editMode]); - const supportsExclusive = supports('@mastodon/list-exclusive') || supports('@gotosocial/list-exclusive'); + const supportsExclusive = + supports('@mastodon/list-exclusive') || + supports('@gotosocial/list-exclusive'); return (
diff --git a/src/locales/en.po b/src/locales/en.po index cd31af4a..38fbdbbf 100644 --- a/src/locales/en.po +++ b/src/locales/en.po @@ -409,7 +409,7 @@ msgstr "" #: src/components/embed-modal.jsx:12 #: src/components/generic-accounts.jsx:142 #: src/components/keyboard-shortcuts-help.jsx:39 -#: src/components/list-add-edit.jsx:33 +#: src/components/list-add-edit.jsx:35 #: src/components/media-alt-modal.jsx:33 #: src/components/media-modal.jsx:247 #: src/components/notification-service.jsx:156 @@ -453,7 +453,7 @@ msgid "No lists." msgstr "" #: src/components/account-info.jsx:1936 -#: src/components/list-add-edit.jsx:37 +#: src/components/list-add-edit.jsx:39 #: src/pages/lists.jsx:58 msgid "New list" msgstr "" @@ -480,7 +480,7 @@ msgid "Unable to update profile." msgstr "" #: src/components/account-info.jsx:2152 -#: src/components/list-add-edit.jsx:102 +#: src/components/list-add-edit.jsx:104 msgid "Name" msgstr "" @@ -501,7 +501,7 @@ msgid "Content" msgstr "" #: src/components/account-info.jsx:2220 -#: src/components/list-add-edit.jsx:147 +#: src/components/list-add-edit.jsx:149 #: src/components/shortcuts-settings.jsx:712 #: src/pages/filters.jsx:554 #: src/pages/notifications.jsx:934 @@ -888,7 +888,7 @@ msgid "Error deleting draft! Please try again." msgstr "" #: src/components/drafts.jsx:127 -#: src/components/list-add-edit.jsx:183 +#: src/components/list-add-edit.jsx:185 #: src/components/status.jsx:1318 #: src/pages/filters.jsx:587 msgid "Deleteā€¦" @@ -1115,44 +1115,44 @@ msgstr "" msgid "<0>Shift + <1>Alt + <2>k" msgstr "" -#: src/components/list-add-edit.jsx:37 +#: src/components/list-add-edit.jsx:39 msgid "Edit list" msgstr "" -#: src/components/list-add-edit.jsx:93 +#: src/components/list-add-edit.jsx:95 msgid "Unable to edit list." msgstr "" -#: src/components/list-add-edit.jsx:94 +#: src/components/list-add-edit.jsx:96 msgid "Unable to create list." msgstr "" -#: src/components/list-add-edit.jsx:122 +#: src/components/list-add-edit.jsx:124 msgid "Show replies to list members" msgstr "" -#: src/components/list-add-edit.jsx:125 +#: src/components/list-add-edit.jsx:127 msgid "Show replies to people I follow" msgstr "" -#: src/components/list-add-edit.jsx:128 +#: src/components/list-add-edit.jsx:130 msgid "Don't show replies" msgstr "" -#: src/components/list-add-edit.jsx:141 +#: src/components/list-add-edit.jsx:143 msgid "Hide posts on this list from Home/Following" msgstr "" -#: src/components/list-add-edit.jsx:147 +#: src/components/list-add-edit.jsx:149 #: src/pages/filters.jsx:554 msgid "Create" msgstr "" -#: src/components/list-add-edit.jsx:154 +#: src/components/list-add-edit.jsx:156 msgid "Delete this list?" msgstr "" -#: src/components/list-add-edit.jsx:173 +#: src/components/list-add-edit.jsx:175 msgid "Unable to delete list." msgstr "" diff --git a/src/utils/api.js b/src/utils/api.js index ff22f3d2..7c311e4c 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -110,11 +110,14 @@ export async function initInstance(client, instance) { try { if (uri || domain) { let urlBase = uri || `https://${domain}`; - const wellKnown = await (await fetch(`${urlBase}/.well-known/nodeinfo`)).json(); + const wellKnown = await ( + await fetch(`${urlBase}/.well-known/nodeinfo`) + ).json(); if (Array.isArray(wellKnown?.links)) { const nodeInfoUrl = wellKnown.links.find( - (link) => typeof link.rel === 'string' && - link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/') + (link) => + typeof link.rel === 'string' && + link.rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/'), )?.href; if (nodeInfoUrl && nodeInfoUrl.startsWith(urlBase)) { nodeInfo = await (await fetch(nodeInfoUrl)).json(); diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index 99f3186d..83033708 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -122,7 +122,7 @@ export function getCurrentNodeInfo() { const account = getCurrentAccount(); const nodeInfos = store.local.getJSON('nodeInfos') || {}; const instanceURL = account.instanceURL.toLowerCase(); - return (currentNodeInfo = (nodeInfos[instanceURL] || {})); + return (currentNodeInfo = nodeInfos[instanceURL] || {}); } catch (e) { console.error(e); return {}; diff --git a/src/utils/supports.js b/src/utils/supports.js index f8183526..e240037a 100644 --- a/src/utils/supports.js +++ b/src/utils/supports.js @@ -53,10 +53,12 @@ function supports(feature) { const featureSoftware = feature.match(/^@([a-z]+)\//)[1]; const doesSoftwareMatch = featureSoftware === softwareName.toLowerCase(); - return (supportsCache[key] = doesSoftwareMatch && satisfies(version, range, { - includePrerelease: true, - loose: true, - })); + return (supportsCache[key] = + doesSoftwareMatch && + satisfies(version, range, { + includePrerelease: true, + loose: true, + })); } catch (e) { return false; }