From 61880b8b865e71dfd4f3bdca4a3d99ba5c278d18 Mon Sep 17 00:00:00 2001 From: tassoman Date: Mon, 21 Oct 2024 19:44:36 +0200 Subject: [PATCH 1/4] Show App used for posting a status, when available --- .../src/features/status/components/detailed-status.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/pl-fe/src/features/status/components/detailed-status.tsx b/packages/pl-fe/src/features/status/components/detailed-status.tsx index 71854c6cb..74f694291 100644 --- a/packages/pl-fe/src/features/status/components/detailed-status.tsx +++ b/packages/pl-fe/src/features/status/components/detailed-status.tsx @@ -150,6 +150,14 @@ const DetailedStatus: React.FC = ({ + {actualStatus.application && ( + + + ({actualStatus.application.name}) + + + )} + {actualStatus.edited_at && ( <> {' · '} From 34d68cf2d8cb240fb2c698cd4085766af46c395f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 21 Oct 2024 20:35:52 +0200 Subject: [PATCH 2/4] Fix chats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/queries/chats.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pl-fe/src/queries/chats.ts b/packages/pl-fe/src/queries/chats.ts index 1ad2bb1f3..e617ab771 100644 --- a/packages/pl-fe/src/queries/chats.ts +++ b/packages/pl-fe/src/queries/chats.ts @@ -181,7 +181,7 @@ const useChatActions = (chatId: string) => { chat_id: variables.chatId, content: variables.content, id: pendingId, - created_at: new Date(), + created_at: new Date().toISOString(), account_id: account?.id, unread: true, }), From a3c599379781606aaf4d9a22ec7e16a395093791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 21 Oct 2024 20:39:23 +0200 Subject: [PATCH 3/4] Default to whatever content type is supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-api/lib/entities/account.ts | 2 +- packages/pl-api/lib/entities/admin/account.ts | 2 +- .../pl-api/lib/entities/admin/announcement.ts | 2 +- packages/pl-api/lib/entities/admin/relay.ts | 2 +- packages/pl-api/lib/entities/admin/report.ts | 2 +- packages/pl-api/lib/entities/instance.ts | 2 +- packages/pl-api/lib/entities/rule.ts | 2 +- packages/pl-api/lib/entities/scrobble.ts | 2 +- packages/pl-api/lib/entities/suggestion.ts | 2 +- packages/pl-api/lib/entities/translation.ts | 2 +- packages/pl-api/lib/entities/trends-link.ts | 2 +- packages/pl-api/lib/features.ts | 1 + packages/pl-api/package.json | 2 +- packages/pl-fe/package.json | 2 +- .../components/content-type-button.tsx | 34 ++++++++++++------- .../pl-fe/src/features/preferences/index.tsx | 20 +++++++---- packages/pl-fe/src/reducers/compose.ts | 13 +++++-- packages/pl-fe/src/schemas/pl-fe/settings.ts | 2 +- packages/pl-fe/yarn.lock | 8 ++--- 19 files changed, 66 insertions(+), 38 deletions(-) diff --git a/packages/pl-api/lib/entities/account.ts b/packages/pl-api/lib/entities/account.ts index 420047317..9651842c9 100644 --- a/packages/pl-api/lib/entities/account.ts +++ b/packages/pl-api/lib/entities/account.ts @@ -87,7 +87,7 @@ const baseAccountSchema = v.object({ noindex: v.fallback(v.nullable(v.boolean()), null), suspended: v.fallback(v.optional(v.boolean()), undefined), limited: v.fallback(v.optional(v.boolean()), undefined), - created_at: v.fallback(datetimeSchema, new Date().toUTCString()), + created_at: v.fallback(datetimeSchema, new Date().toISOString()), last_status_at: v.fallback(v.nullable(v.pipe(v.string(), v.isoDate())), null), statuses_count: v.fallback(v.number(), 0), followers_count: v.fallback(v.number(), 0), diff --git a/packages/pl-api/lib/entities/admin/account.ts b/packages/pl-api/lib/entities/admin/account.ts index 58c713bf5..7d5274dc6 100644 --- a/packages/pl-api/lib/entities/admin/account.ts +++ b/packages/pl-api/lib/entities/admin/account.ts @@ -7,7 +7,7 @@ import { datetimeSchema, filteredArray } from '../utils'; import { adminIpSchema } from './ip'; /** @see {@link https://docs.joinmastodon.org/entities/Admin_Account/} */ -const adminAccountSchema = v.pipe( +const adminAccountSchema = v.pipe( v.any(), v.transform((account: any) => { if (!account.account) { diff --git a/packages/pl-api/lib/entities/admin/announcement.ts b/packages/pl-api/lib/entities/admin/announcement.ts index 5cef6c4a1..93d9bca26 100644 --- a/packages/pl-api/lib/entities/admin/announcement.ts +++ b/packages/pl-api/lib/entities/admin/announcement.ts @@ -4,7 +4,7 @@ import * as v from 'valibot'; import { announcementSchema } from '../announcement'; /** @see {@link https://docs.pleroma.social/backend/development/API/admin_api/#get-apiv1pleromaadminannouncements} */ -const adminAnnouncementSchema = v.pipe( +const adminAnnouncementSchema = v.pipe( v.any(), v.transform((announcement: any) => ({ ...announcement, diff --git a/packages/pl-api/lib/entities/admin/relay.ts b/packages/pl-api/lib/entities/admin/relay.ts index efe2df0a8..e5d4e6993 100644 --- a/packages/pl-api/lib/entities/admin/relay.ts +++ b/packages/pl-api/lib/entities/admin/relay.ts @@ -1,6 +1,6 @@ import * as v from 'valibot'; -const adminRelaySchema = v.pipe( +const adminRelaySchema = v.pipe( v.any(), v.transform((data: any) => ({ id: data.actor, ...data })), v.object({ diff --git a/packages/pl-api/lib/entities/admin/report.ts b/packages/pl-api/lib/entities/admin/report.ts index c3386aec1..6a0526f75 100644 --- a/packages/pl-api/lib/entities/admin/report.ts +++ b/packages/pl-api/lib/entities/admin/report.ts @@ -8,7 +8,7 @@ import { datetimeSchema, filteredArray } from '../utils'; import { adminAccountSchema } from './account'; /** @see {@link https://docs.joinmastodon.org/entities/Admin_Report/} */ -const adminReportSchema = v.pipe( +const adminReportSchema = v.pipe( v.any(), v.transform((report: any) => { if (report.actor) { diff --git a/packages/pl-api/lib/entities/instance.ts b/packages/pl-api/lib/entities/instance.ts index 6a1413781..22a7fc055 100644 --- a/packages/pl-api/lib/entities/instance.ts +++ b/packages/pl-api/lib/entities/instance.ts @@ -203,7 +203,7 @@ const pleromaSchema = coerceObject({ )), enabled: v.fallback(v.boolean(), false), }), - post_formats: v.fallback(v.optional(v.array(v.string())), undefined), + post_formats: v.fallback(v.array(v.string()), ['text/plain']), restrict_unauthenticated: coerceObject({ activities: coerceObject({ local: v.fallback(v.boolean(), false), diff --git a/packages/pl-api/lib/entities/rule.ts b/packages/pl-api/lib/entities/rule.ts index a94f2d117..c1077cb0d 100644 --- a/packages/pl-api/lib/entities/rule.ts +++ b/packages/pl-api/lib/entities/rule.ts @@ -7,7 +7,7 @@ const baseRuleSchema = v.object({ }); /** @see {@link https://docs.joinmastodon.org/entities/Rule/} */ -const ruleSchema = v.pipe( +const ruleSchema = v.pipe( v.any(), v.transform((data: any) => ({ ...data, diff --git a/packages/pl-api/lib/entities/scrobble.ts b/packages/pl-api/lib/entities/scrobble.ts index e27d2d607..483805caf 100644 --- a/packages/pl-api/lib/entities/scrobble.ts +++ b/packages/pl-api/lib/entities/scrobble.ts @@ -3,7 +3,7 @@ import * as v from 'valibot'; import { accountSchema } from './account'; import { datetimeSchema } from './utils'; -const scrobbleSchema = v.pipe( +const scrobbleSchema = v.pipe( v.any(), v.transform((scrobble: any) => scrobble ? { external_link: scrobble.externalLink, diff --git a/packages/pl-api/lib/entities/suggestion.ts b/packages/pl-api/lib/entities/suggestion.ts index 9b9f12168..875c0f8d1 100644 --- a/packages/pl-api/lib/entities/suggestion.ts +++ b/packages/pl-api/lib/entities/suggestion.ts @@ -3,7 +3,7 @@ import * as v from 'valibot'; import { accountSchema } from './account'; /** @see {@link https://docs.joinmastodon.org/entities/Suggestion} */ -const suggestionSchema = v.pipe( +const suggestionSchema = v.pipe( v.any(), v.transform((suggestion: any) => { /** diff --git a/packages/pl-api/lib/entities/translation.ts b/packages/pl-api/lib/entities/translation.ts index 07ffa270d..ed2727841 100644 --- a/packages/pl-api/lib/entities/translation.ts +++ b/packages/pl-api/lib/entities/translation.ts @@ -15,7 +15,7 @@ const translationMediaAttachment = v.object({ }); /** @see {@link https://docs.joinmastodon.org/entities/Translation/} */ -const translationSchema = v.pipe( +const translationSchema = v.pipe( v.any(), v.transform((translation: any) => { /** diff --git a/packages/pl-api/lib/entities/trends-link.ts b/packages/pl-api/lib/entities/trends-link.ts index 0ed03dbd2..e2909347a 100644 --- a/packages/pl-api/lib/entities/trends-link.ts +++ b/packages/pl-api/lib/entities/trends-link.ts @@ -4,7 +4,7 @@ import { blurhashSchema } from './media-attachment'; import { historySchema } from './tag'; /** @see {@link https://docs.joinmastodon.org/entities/PreviewCard/#trends-link} */ -const trendsLinkSchema = v.pipe( +const trendsLinkSchema = v.pipe( v.any(), v.transform((link: any) => ({ ...link, id: link.url })), v.object({ diff --git a/packages/pl-api/lib/features.ts b/packages/pl-api/lib/features.ts index f1056035f..82058cff3 100644 --- a/packages/pl-api/lib/features.ts +++ b/packages/pl-api/lib/features.ts @@ -1000,6 +1000,7 @@ const getFeatures = (instance: Instance) => { v.software === PLEROMA, v.software === MITRA, v.software === GOTOSOCIAL, + instance.pleroma.metadata.post_formats.length > 1, ]), /** diff --git a/packages/pl-api/package.json b/packages/pl-api/package.json index f9cdc9b72..6df7d29b5 100644 --- a/packages/pl-api/package.json +++ b/packages/pl-api/package.json @@ -1,6 +1,6 @@ { "name": "pl-api", - "version": "0.1.2", + "version": "0.1.3", "type": "module", "homepage": "https://github.com/mkljczk/pl-fe/tree/fork/packages/pl-api", "repository": { diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json index 9d9a59df8..026b19883 100644 --- a/packages/pl-fe/package.json +++ b/packages/pl-fe/package.json @@ -102,7 +102,7 @@ "mini-css-extract-plugin": "^2.9.1", "multiselect-react-dropdown": "^2.0.25", "path-browserify": "^1.0.1", - "pl-api": "^0.1.2", + "pl-api": "^0.1.3", "postcss": "^8.4.47", "process": "^0.11.10", "punycode": "^2.1.1", diff --git a/packages/pl-fe/src/features/compose/components/content-type-button.tsx b/packages/pl-fe/src/features/compose/components/content-type-button.tsx index d23f62cf5..bcd40c61a 100644 --- a/packages/pl-fe/src/features/compose/components/content-type-button.tsx +++ b/packages/pl-fe/src/features/compose/components/content-type-button.tsx @@ -29,19 +29,27 @@ const ContentTypeButton: React.FC = ({ composeId }) => { const handleChange = (contentType: string) => () => dispatch(changeComposeContentType(composeId, contentType)); - const options = [ - { + const postFormats = instance.pleroma.metadata.post_formats; + + const options = []; + + if (postFormats.includes('text/plain')) { + options.push({ icon: require('@tabler/icons/outline/pilcrow.svg'), text: intl.formatMessage(messages.content_type_plaintext), value: 'text/plain', - }, - { icon: require('@tabler/icons/outline/markdown.svg'), + }); + } + + if (postFormats.includes('text/markdown')) { + options.push({ + icon: require('@tabler/icons/outline/markdown.svg'), text: intl.formatMessage(messages.content_type_markdown), value: 'text/markdown', - }, - ]; + }); + } - if (instance.pleroma.metadata.post_formats?.includes('text/html')) { + if (postFormats.includes('text/html')) { options.push({ icon: require('@tabler/icons/outline/html.svg'), text: intl.formatMessage(messages.content_type_html), @@ -49,11 +57,13 @@ const ContentTypeButton: React.FC = ({ composeId }) => { }); } - options.push({ - icon: require('@tabler/icons/outline/text-caption.svg'), - text: intl.formatMessage(messages.content_type_wysiwyg), - value: 'wysiwyg', - }); + if (postFormats.includes('text/markdown')) { + options.push({ + icon: require('@tabler/icons/outline/text-caption.svg'), + text: intl.formatMessage(messages.content_type_wysiwyg), + value: 'wysiwyg', + }); + } const option = options.find(({ value }) => value === contentType); diff --git a/packages/pl-fe/src/features/preferences/index.tsx b/packages/pl-fe/src/features/preferences/index.tsx index a55057a30..a97c10ba1 100644 --- a/packages/pl-fe/src/features/preferences/index.tsx +++ b/packages/pl-fe/src/features/preferences/index.tsx @@ -9,6 +9,7 @@ import { Mutliselect, SelectDropdown } from 'pl-fe/features/forms'; import SettingToggle from 'pl-fe/features/notifications/components/setting-toggle'; import { useAppDispatch } from 'pl-fe/hooks/useAppDispatch'; import { useFeatures } from 'pl-fe/hooks/useFeatures'; +import { useInstance } from 'pl-fe/hooks/useInstance'; import { useSettings } from 'pl-fe/hooks/useSettings'; import ThemeToggle from '../ui/components/theme-toggle'; @@ -98,6 +99,7 @@ const Preferences = () => { const dispatch = useAppDispatch(); const features = useFeatures(); const settings = useSettings(); + const instance = useInstance(); const onSelectChange = (event: React.ChangeEvent, path: string[]) => { dispatch(changeSetting(path, event.target.value, { showAlert: true })); @@ -123,11 +125,17 @@ const Preferences = () => { private: intl.formatMessage(messages.privacy_followers_only), }), [settings.locale]); - const defaultContentTypeOptions = React.useMemo(() => ({ - 'text/plain': intl.formatMessage(messages.content_type_plaintext), - 'text/markdown': intl.formatMessage(messages.content_type_markdown), - 'text/html': intl.formatMessage(messages.content_type_html), - }), [settings.locale]); + const defaultContentTypeOptions = React.useMemo(() => { + const postFormats = instance.pleroma.metadata.post_formats; + + const options = Object.entries({ + 'text/plain': intl.formatMessage(messages.content_type_plaintext), + 'text/markdown': intl.formatMessage(messages.content_type_markdown), + 'text/html': intl.formatMessage(messages.content_type_html), + }).filter(([key]) => postFormats.includes(key)); + + if (options.length > 1) return Object.fromEntries(options); + }, [settings.locale]); return (
@@ -179,7 +187,7 @@ const Preferences = () => { )} - {features.richText && ( + {features.richText && !!defaultContentTypeOptions && ( }> { // } // }; +const updateDefaultContentType = (compose: Compose, instance: Instance) => { + const postFormats = instance.pleroma.metadata.post_formats; + + return compose.update('content_type', type => postFormats.includes(type) ? type : postFormats.includes('text/markdown') ? 'text/markdown' : postFormats[0]); +}; + const updateCompose = (state: State, key: string, updater: (compose: Compose) => Compose) => state.update(key, state.get('default')!, updater); @@ -283,7 +290,7 @@ const initialState: State = ImmutableMap({ default: ReducerCompose({ idempotencyKey: crypto.randomUUID(), resetFileKey: getResetFileKey() }), }); -const compose = (state = initialState, action: ComposeAction | EventsAction | MeAction | TimelineAction) => { +const compose = (state = initialState, action: ComposeAction | EventsAction | InstanceAction | MeAction | TimelineAction) => { switch (action.type) { case COMPOSE_TYPE_CHANGE: return updateCompose(state, action.composeId, compose => compose.withMutations(map => { @@ -589,6 +596,8 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | Me .set('quote', null)); case COMPOSE_FEDERATED_CHANGE: return updateCompose(state, action.composeId, compose => compose.update('federated', value => !value)); + case INSTANCE_FETCH_SUCCESS: + return updateCompose(state, 'default', (compose) => updateDefaultContentType(compose, action.instance)); default: return state; } diff --git a/packages/pl-fe/src/schemas/pl-fe/settings.ts b/packages/pl-fe/src/schemas/pl-fe/settings.ts index c0601614c..11584e66f 100644 --- a/packages/pl-fe/src/schemas/pl-fe/settings.ts +++ b/packages/pl-fe/src/schemas/pl-fe/settings.ts @@ -19,7 +19,7 @@ const settingsSchema = v.object({ deleteModal: v.fallback(v.boolean(), true), missingDescriptionModal: v.fallback(v.boolean(), true), defaultPrivacy: v.fallback(v.picklist(['public', 'unlisted', 'private', 'direct']), 'public'), - defaultContentType: v.fallback(v.picklist(['text/plain', 'text/markdown']), 'text/plain'), + defaultContentType: v.fallback(v.picklist(['text/plain', 'text/markdown', 'text/html']), 'text/plain'), themeMode: v.fallback(v.picklist(['system', 'light', 'dark', 'black']), 'system'), locale: v.fallback( v.pipe( diff --git a/packages/pl-fe/yarn.lock b/packages/pl-fe/yarn.lock index e368c3e7a..dd79bc7fb 100644 --- a/packages/pl-fe/yarn.lock +++ b/packages/pl-fe/yarn.lock @@ -7570,10 +7570,10 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -pl-api@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.1.2.tgz#08794b017f64c58ce128074afdd2144f715359e2" - integrity sha512-HZNrEDvnL1+8yax7lZwe/vCELme8ieNQB6LzUKTQU8qqhMSk7EdLBeEUQok/csyAu0X+IaSsoWKMA91xYzpuGA== +pl-api@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.1.3.tgz#72d434a0ec8d713e5b227b35497da33cf26975a6" + integrity sha512-vcl3aGOy3AocQek3+S97QB0jIcF+iV66FvMqrFB/qnfo3Ryte9dcG6XcDxQ5LpogFQAILKk/Mm5uY2W9RZtwHA== dependencies: blurhash "^2.0.5" http-link-header "^1.1.3" From fa38a39dfe3ce1114d87e40303ad7728406289f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 21 Oct 2024 21:04:06 +0200 Subject: [PATCH 4/4] pl-fe: introduce wrench reaction button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../src/components/status-action-bar.tsx | 35 +++++++++++++++++-- .../pl-fe/src/features/preferences/index.tsx | 6 ++++ packages/pl-fe/src/locales/en.json | 2 ++ packages/pl-fe/src/schemas/pl-fe/settings.ts | 1 + 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/pl-fe/src/components/status-action-bar.tsx b/packages/pl-fe/src/components/status-action-bar.tsx index ca96e3a67..8e59f9ac1 100644 --- a/packages/pl-fe/src/components/status-action-bar.tsx +++ b/packages/pl-fe/src/components/status-action-bar.tsx @@ -5,7 +5,7 @@ import { useHistory, useRouteMatch } from 'react-router-dom'; import { blockAccount } from 'pl-fe/actions/accounts'; import { directCompose, mentionCompose, quoteCompose, replyCompose } from 'pl-fe/actions/compose'; -import { emojiReact } from 'pl-fe/actions/emoji-reacts'; +import { emojiReact, unEmojiReact } from 'pl-fe/actions/emoji-reacts'; import { editEvent } from 'pl-fe/actions/events'; import { toggleBookmark, toggleDislike, toggleFavourite, togglePin, toggleReblog } from 'pl-fe/actions/interactions'; import { deleteStatusModal, toggleStatusSensitivityModal } from 'pl-fe/actions/moderation'; @@ -104,6 +104,7 @@ const messages = defineMessages({ unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' }, unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' }, viewReactions: { id: 'status.view_reactions', defaultMessage: 'View reactions' }, + wrench: { id: 'status.wrench', defaultMessage: 'Wrench reaction' }, addKnownLanguage: { id: 'status.add_known_language', defaultMessage: 'Do not auto-translate posts in {language}.' }, translate: { id: 'status.translate', defaultMessage: 'Translate' }, hideTranslation: { id: 'status.hide_translation', defaultMessage: 'Hide translation' }, @@ -143,7 +144,9 @@ const StatusActionBar: React.FC = ({ const { groupRelationship } = useGroupRelationship(status.group_id || undefined); const features = useFeatures(); const instance = useInstance(); - const { autoTranslate, boostModal, deleteModal, knownLanguages } = useSettings(); + const { autoTranslate, boostModal, deleteModal, knownLanguages, showWrenchButton } = useSettings(); + + const wrenches = showWrenchButton && status.emoji_reactions.find(emoji => emoji.name === '🔧') || undefined; const { translationLanguages } = useTranslationLanguages(); @@ -211,10 +214,24 @@ const StatusActionBar: React.FC = ({ } }; + const handleWrenchClick: React.EventHandler = (e) => { + if (!me) { + onOpenUnauthorizedModal('DISLIKE'); + } else if (wrenches?.me) { + dispatch(unEmojiReact(status, '🔧')); + } else { + dispatch(emojiReact(status, '🔧')); + } + }; + const handleDislikeLongPress = status.dislikes_count ? () => { openModal('DISLIKES', { statusId: status.id }); } : undefined; + const handleWrenchLongPress = wrenches?.count ? () => { + openModal('REACTIONS', { statusId: status.id, reaction: wrenches.name }); + } : undefined; + const handlePickEmoji = (emoji: EmojiType) => { dispatch(emojiReact(status, emoji.custom ? emoji.id : emoji.native, emoji.custom ? emoji.imageUrl : undefined)); }; @@ -784,6 +801,20 @@ const StatusActionBar: React.FC = ({ /> )} + {me && !withLabels && features.emojiReacts && showWrenchButton && ( + + )} + {me && !withLabels && features.emojiReacts && ( { > + + {features.emojiReacts && ( + } > + + + )} diff --git a/packages/pl-fe/src/locales/en.json b/packages/pl-fe/src/locales/en.json index 2ec123e00..0d0362392 100644 --- a/packages/pl-fe/src/locales/en.json +++ b/packages/pl-fe/src/locales/en.json @@ -1256,6 +1256,7 @@ "preferences.fields.theme": "Theme", "preferences.fields.underline_links_label": "Always underline links in posts", "preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone", + "preferences.fields.wrench_label": "Display wrench reaction button", "preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.", "preferences.notifications.advanced": "Show all notification categories", "preferences.options.content_type_html": "HTML", @@ -1512,6 +1513,7 @@ "status.visibility.local": "The post is only visible to users on your instance", "status.visibility.mutuals_only": "The post is only visible to people who mutually follow the author", "status.visibility.private": "The post is only visible to followers of the author", + "status.wrench": "Wrench reaction", "status_list.queue_label": "Click to see {count} new {count, plural, one {post} other {posts}}", "statuses.quote_tombstone": "Post is unavailable.", "statuses.tombstone": "One or more posts are unavailable.", diff --git a/packages/pl-fe/src/schemas/pl-fe/settings.ts b/packages/pl-fe/src/schemas/pl-fe/settings.ts index 11584e66f..07d315d3d 100644 --- a/packages/pl-fe/src/schemas/pl-fe/settings.ts +++ b/packages/pl-fe/src/schemas/pl-fe/settings.ts @@ -35,6 +35,7 @@ const settingsSchema = v.object({ preserveSpoilers: v.fallback(v.boolean(), false), autoTranslate: v.fallback(v.boolean(), false), knownLanguages: v.fallback(v.array(v.string()), []), + showWrenchButton: v.fallback(v.boolean(), true), systemFont: v.fallback(v.boolean(), false), demetricator: v.fallback(v.boolean(), false),