Skip to content

Commit

Permalink
Shrink the size of the feature detection change
Browse files Browse the repository at this point in the history
  • Loading branch information
graue committed Sep 20, 2024
1 parent 945096e commit 933676c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/components/list-add-edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div class="sheet">
Expand Down
9 changes: 9 additions & 0 deletions src/data/features.json
Original file line number Diff line number Diff line change
@@ -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"
}
27 changes: 12 additions & 15 deletions src/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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') || {};
Expand Down
2 changes: 1 addition & 1 deletion src/utils/store-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
93 changes: 34 additions & 59 deletions src/utils/supports.js
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 933676c

Please sign in to comment.