diff --git a/src/components/pure-status.tsx b/src/components/pure-status.tsx index 56134ea8b..ccc9a7ec3 100644 --- a/src/components/pure-status.tsx +++ b/src/components/pure-status.tsx @@ -11,8 +11,8 @@ import { unfilterStatus } from 'soapbox/actions/statuses.ts'; import PureEventPreview from 'soapbox/components/pure-event-preview.tsx'; import PureStatusContent from 'soapbox/components/pure-status-content.tsx'; import PureStatusReplyMentions from 'soapbox/components/pure-status-reply-mentions.tsx'; +import PureTranslateButton from 'soapbox/components/pure-translate-button.tsx'; import PureSensitiveContentOverlay from 'soapbox/components/statuses/pure-sensitive-content-overlay.tsx'; -import TranslateButton from 'soapbox/components/translate-button.tsx'; import { Card } from 'soapbox/components/ui/card.tsx'; import Icon from 'soapbox/components/ui/icon.tsx'; import Stack from 'soapbox/components/ui/stack.tsx'; @@ -475,7 +475,7 @@ const PureStatus: React.FC = (props) => { translatable /> - {/* fix later */} + {(quote || actualStatus.card || actualStatus.media_attachments.length > 0) && ( diff --git a/src/components/pure-translate-button.tsx b/src/components/pure-translate-button.tsx new file mode 100644 index 000000000..b5632e35d --- /dev/null +++ b/src/components/pure-translate-button.tsx @@ -0,0 +1,82 @@ +import languageIcon from '@tabler/icons/outline/language.svg'; +import { FormattedMessage, useIntl } from 'react-intl'; + +import { translateStatus, undoStatusTranslation } from 'soapbox/actions/statuses.ts'; +import Button from 'soapbox/components/ui/button.tsx'; +import Stack from 'soapbox/components/ui/stack.tsx'; +import Text from 'soapbox/components/ui/text.tsx'; +import { Entities, EntityTypes } from 'soapbox/entity-store/entities.ts'; +import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; +import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; +import { useFeatures } from 'soapbox/hooks/useFeatures.ts'; +import { useInstance } from 'soapbox/hooks/useInstance.ts'; + +interface IPureTranslateButton { + status: EntityTypes[Entities.STATUSES]; +} + +const PureTranslateButton: React.FC = ({ status }) => { + const dispatch = useAppDispatch(); + const intl = useIntl(); + const features = useFeatures(); + const { instance } = useInstance(); + + const me = useAppSelector((state) => state.me); + + const { + allow_remote: allowRemote, + allow_unauthenticated: allowUnauthenticated, + source_languages: sourceLanguages, + target_languages: targetLanguages, + } = instance.pleroma.metadata.translation; + + const renderTranslate = (me || allowUnauthenticated) && (allowRemote || status.account.local) && ['public', 'unlisted'].includes(status.visibility) && status.content.length > 0 && status.language !== null && intl.locale !== status.language; + + const supportsLanguages = (!sourceLanguages || sourceLanguages.includes(status.language!)) && (!targetLanguages || targetLanguages.includes(intl.locale)); + + const handleTranslate: React.MouseEventHandler = (e) => { + e.stopPropagation(); + + if (status.translation) { + dispatch(undoStatusTranslation(status.id)); + } else { + dispatch(translateStatus(status.id, intl.locale)); + } + }; + + if (!features.translations || !renderTranslate || !supportsLanguages) return null; + + if (status.translation) { + const languageNames = new Intl.DisplayNames([intl.locale], { type: 'language' }); + const languageName = languageNames.of(status.language!); + const provider = status.translation.provider; + + return ( + +