From 255ca8eaa6fa0080bfea0b20544e276ab5eafbbf Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Mon, 13 Feb 2023 01:21:18 +0800 Subject: [PATCH] Support edit media description for Mastodon v4.1 --- src/components/compose.jsx | 41 +++++++++++++++++++------------------- src/data/features.json | 3 +++ src/utils/store-utils.js | 18 +++++++++++++++++ src/utils/supports.js | 25 +++++++++++++++++++++++ 4 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 src/data/features.json create mode 100644 src/utils/supports.js diff --git a/src/components/compose.jsx b/src/components/compose.jsx index c0a22103..741c0d04 100644 --- a/src/components/compose.jsx +++ b/src/components/compose.jsx @@ -3,7 +3,7 @@ import './compose.css'; import '@github/text-expander-element'; import equal from 'fast-deep-equal'; import { forwardRef } from 'preact/compat'; -import { useEffect, useMemo, useRef, useState } from 'preact/hooks'; +import { useEffect, useRef, useState } from 'preact/hooks'; import { useHotkeys } from 'react-hotkeys-hook'; import stringLength from 'string-length'; import { uid } from 'uid/single'; @@ -18,7 +18,12 @@ import emojifyText from '../utils/emojify-text'; import openCompose from '../utils/open-compose'; import states, { saveStatus } from '../utils/states'; import store from '../utils/store'; -import { getCurrentAccount, getCurrentAccountNS } from '../utils/store-utils'; +import { + getCurrentAccount, + getCurrentAccountNS, + getCurrentInstance, +} from '../utils/store-utils'; +import supports from '../utils/supports'; import useInterval from '../utils/useInterval'; import visibilityIconsMap from '../utils/visibility-icons-map'; @@ -108,22 +113,8 @@ function Compose({ const currentAccount = getCurrentAccount(); const currentAccountInfo = currentAccount.info; - const configuration = useMemo(() => { - try { - const instances = store.local.getJSON('instances'); - const currentInstance = currentAccount.instanceURL.toLowerCase(); - const config = instances[currentInstance].configuration; - console.log(config); - return config; - } catch (e) { - console.error(e); - alert('Failed to load instance configuration. Please try again.'); - // Temporary fix for corrupted data - store.local.del('instances'); - location.reload(); - return {}; - } - }, []); + const { configuration } = getCurrentInstance(); + console.log('⚙️ Configuration', configuration); const { statuses: { maxCharacters, maxMediaAttachments, charactersReservedPerUrl }, @@ -771,7 +762,16 @@ function Compose({ // mediaIds: mediaAttachments.map((attachment) => attachment.id), media_ids: mediaAttachments.map((attachment) => attachment.id), }; - if (!editStatus) { + if (editStatus && supports('@mastodon/edit-media-attributes')) { + params.media_attributes = mediaAttachments.map((attachment) => { + return { + id: attachment.id, + description: attachment.description, + // focus + // thumbnail + }; + }); + } else if (!editStatus) { params.visibility = visibility; // params.inReplyToId = replyToStatus?.id || undefined; params.in_reply_to_id = replyToStatus?.id || undefined; @@ -1279,6 +1279,7 @@ function MediaAttachment({ onDescriptionChange = () => {}, onRemove = () => {}, }) { + const supportsEdit = supports('@mastodon/edit-media-attributes'); const { url, type, id } = attachment; console.log({ attachment }); const [description, setDescription] = useState(attachment.description); @@ -1304,7 +1305,7 @@ function MediaAttachment({ const descTextarea = ( <> - {!!id ? ( + {!!id && !supportsEdit ? (
Uploaded

diff --git a/src/data/features.json b/src/data/features.json new file mode 100644 index 00000000..16340ca3 --- /dev/null +++ b/src/data/features.json @@ -0,0 +1,3 @@ +{ + "@mastodon/edit-media-attributes": ">=4.1" +} diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index 0b1d5652..7b1deef5 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -33,3 +33,21 @@ export function saveAccount(account) { store.local.setJSON('accounts', accounts); store.session.set('currentAccount', account.info.id); } + +let currentInstance = null; +export function getCurrentInstance() { + if (currentInstance) return currentInstance; + try { + const account = getCurrentAccount(); + const instances = store.local.getJSON('instances'); + const instance = account.instanceURL.toLowerCase(); + return (currentInstance = instances[instance]); + } catch (e) { + console.error(e); + alert('Failed to load instance configuration. Please try again.'); + // Temporary fix for corrupted data + store.local.del('instances'); + location.reload(); + return {}; + } +} diff --git a/src/utils/supports.js b/src/utils/supports.js new file mode 100644 index 00000000..5f7e8163 --- /dev/null +++ b/src/utils/supports.js @@ -0,0 +1,25 @@ +import { satisfies } from 'semver'; + +import features from '../data/features.json'; + +import { getCurrentInstance } from './store-utils'; + +const supportsCache = {}; + +function supports(feature) { + try { + const { version, domain } = getCurrentInstance(); + const key = `${domain}-${feature}`; + if (supportsCache[key]) return supportsCache[key]; + const range = features[feature]; + if (!range) return false; + return (supportsCache[key] = satisfies(version, range, { + includePrerelease: true, + loose: true, + })); + } catch (e) { + return false; + } +} + +export default supports;