From 806f4f1589536f2f993aa3e2a566ef8d960ddea4 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 20 Mar 2026 17:02:50 +0100 Subject: [PATCH] Add simple language selector to collection editor (#38316) --- .../features/collections/editor/details.tsx | 58 ++++++++++++++++++- app/javascript/mastodon/initial_state.ts | 2 +- app/javascript/mastodon/locales/en.json | 2 + 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/features/collections/editor/details.tsx b/app/javascript/mastodon/features/collections/editor/details.tsx index e34df3ef79..73847a2b20 100644 --- a/app/javascript/mastodon/features/collections/editor/details.tsx +++ b/app/javascript/mastodon/features/collections/editor/details.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from 'react'; +import { Fragment, useCallback, useMemo, useState } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; @@ -6,6 +6,7 @@ import { useHistory } from 'react-router-dom'; import { isFulfilled } from '@reduxjs/toolkit'; +import { languages } from '@/mastodon/initial_state'; import { hasSpecialCharacters, inputToHashtag, @@ -22,6 +23,7 @@ import { Fieldset, FormStack, RadioButtonField, + SelectField, TextAreaField, } from 'mastodon/components/form_fields'; import { TextInputField } from 'mastodon/components/form_fields/text_input_field'; @@ -201,6 +203,8 @@ export const CollectionDetails: React.FC = () => { + +
{ value={topic} items={tags} isLoading={isLoading} - renderItem={renderItem} + renderItem={renderTagItem} onSelectItem={handleSelectTopicSuggestion} onChange={handleTopicChange} autoCapitalize='off' @@ -380,4 +384,52 @@ const TopicField: React.FC = () => { ); }; -const renderItem = (item: TagSearchResult) => item.label ?? `#${item.name}`; +const renderTagItem = (item: TagSearchResult) => item.label ?? `#${item.name}`; + +const LanguageField: React.FC = () => { + const dispatch = useAppDispatch(); + const initialLanguage = useAppSelector( + (state) => state.compose.get('default_language') as string, + ); + const { language } = useAppSelector((state) => state.collections.editor); + + const selectedLanguage = language ?? initialLanguage; + + const handleLanguageChange = useCallback( + (event: React.ChangeEvent) => { + dispatch( + updateCollectionEditorField({ + field: 'language', + value: event.target.value, + }), + ); + }, + [dispatch], + ); + + return ( + + } + value={selectedLanguage} + onChange={handleLanguageChange} + > + + {languages?.map(([code, name, localName]) => ( + + ))} + + ); +}; diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts index 9af0c26f93..0493fcf622 100644 --- a/app/javascript/mastodon/initial_state.ts +++ b/app/javascript/mastodon/initial_state.ts @@ -153,7 +153,7 @@ export const languages = initialState?.languages.map((lang) => { lang[0], displayNames?.of(lang[0].replace('zh-YUE', 'yue')) ?? lang[1], lang[2], - ]; + ] as InitialStateLanguage; }); export function getAccessToken(): string | undefined { diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index f3b35a7741..e3feb120a2 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -349,6 +349,8 @@ "collections.accounts.empty_description": "Add up to {count} accounts you follow", "collections.accounts.empty_title": "This collection is empty", "collections.collection_description": "Description", + "collections.collection_language": "Language", + "collections.collection_language_none": "None", "collections.collection_name": "Name", "collections.collection_topic": "Topic", "collections.confirm_account_removal": "Are you sure you want to remove this account from this collection?",