From 3d46f478174403a64bd194e8c60e11b07bbd5d2d Mon Sep 17 00:00:00 2001 From: Eugen Rochko <eugen@zeonfederated.com> Date: Thu, 12 Sep 2024 11:41:19 +0200 Subject: [PATCH] Change embedded posts to use web UI (#31766) Co-authored-by: Claire <claire.github-309c@sitedethib.com> --- app/helpers/accounts_helper.rb | 8 - app/helpers/media_component_helper.rb | 36 -- app/javascript/entrypoints/embed.tsx | 74 ++++ app/javascript/entrypoints/public.tsx | 37 -- app/javascript/hooks/useRenderSignal.ts | 32 ++ app/javascript/mastodon/actions/statuses.js | 6 +- app/javascript/mastodon/components/logo.tsx | 7 + .../mastodon/components/more_from_author.jsx | 6 +- .../features/standalone/status/index.tsx | 87 ++++ .../status/components/detailed_status.jsx | 322 --------------- .../status/components/detailed_status.tsx | 390 ++++++++++++++++++ .../containers/detailed_status_container.js | 140 ------- .../mastodon/features/status/index.jsx | 2 +- app/javascript/styles/application.scss | 1 - .../styles/mastodon/components.scss | 31 +- app/javascript/styles/mastodon/statuses.scss | 152 ------- app/serializers/oembed_serializer.rb | 20 +- app/views/layouts/embedded.html.haml | 2 +- app/views/statuses/_detailed_status.html.haml | 80 ---- app/views/statuses/_poll.html.haml | 36 -- app/views/statuses/_simple_status.html.haml | 70 ---- app/views/statuses/_status.html.haml | 2 - app/views/statuses/embed.html.haml | 3 +- config/locales/af.yml | 1 - config/locales/an.yml | 12 - config/locales/ar.yml | 20 - config/locales/ast.yml | 9 - config/locales/be.yml | 16 - config/locales/bg.yml | 12 - config/locales/bn.yml | 1 - config/locales/br.yml | 4 - config/locales/ca.yml | 12 - config/locales/ckb.yml | 12 - config/locales/co.yml | 12 - config/locales/cs.yml | 16 - config/locales/cy.yml | 20 - config/locales/da.yml | 12 - config/locales/de.yml | 12 - config/locales/el.yml | 12 - config/locales/en-GB.yml | 12 - config/locales/en.yml | 12 - config/locales/eo.yml | 12 - config/locales/es-AR.yml | 12 - config/locales/es-MX.yml | 12 - config/locales/es.yml | 12 - config/locales/et.yml | 12 - config/locales/eu.yml | 12 - config/locales/fa.yml | 12 - config/locales/fi.yml | 12 - config/locales/fo.yml | 12 - config/locales/fr-CA.yml | 12 - config/locales/fr.yml | 12 - config/locales/fy.yml | 12 - config/locales/ga.yml | 18 - config/locales/gd.yml | 16 - config/locales/gl.yml | 12 - config/locales/he.yml | 16 - config/locales/hi.yml | 1 - config/locales/hr.yml | 14 - config/locales/hu.yml | 12 - config/locales/hy.yml | 12 - config/locales/ia.yml | 12 - config/locales/id.yml | 10 - config/locales/ie.yml | 12 - config/locales/io.yml | 12 - config/locales/is.yml | 12 - config/locales/it.yml | 12 - config/locales/ja.yml | 10 - config/locales/ka.yml | 3 - config/locales/kab.yml | 12 - config/locales/kk.yml | 12 - config/locales/ko.yml | 10 - config/locales/ku.yml | 12 - config/locales/la.yml | 1 - config/locales/lad.yml | 12 - config/locales/lt.yml | 6 - config/locales/lv.yml | 14 - config/locales/ml.yml | 1 - config/locales/ms.yml | 10 - config/locales/my.yml | 10 - config/locales/nl.yml | 12 - config/locales/nn.yml | 12 - config/locales/no.yml | 12 - config/locales/oc.yml | 12 - config/locales/pa.yml | 1 - config/locales/pl.yml | 16 - config/locales/pt-BR.yml | 12 - config/locales/pt-PT.yml | 12 - config/locales/ro.yml | 14 - config/locales/ru.yml | 16 - config/locales/ry.yml | 1 - config/locales/sc.yml | 12 - config/locales/sco.yml | 12 - config/locales/si.yml | 12 - config/locales/sk.yml | 16 - config/locales/sl.yml | 16 - config/locales/sq.yml | 12 - config/locales/sr-Latn.yml | 14 - config/locales/sr.yml | 14 - config/locales/sv.yml | 12 - config/locales/ta.yml | 2 - config/locales/te.yml | 1 - config/locales/th.yml | 10 - config/locales/tr.yml | 12 - config/locales/tt.yml | 7 - config/locales/uk.yml | 16 - config/locales/uz.yml | 2 - config/locales/vi.yml | 10 - config/locales/zgh.yml | 1 - config/locales/zh-CN.yml | 10 - config/locales/zh-HK.yml | 10 - config/locales/zh-TW.yml | 10 - public/embed.js | 105 +++-- spec/controllers/statuses_controller_spec.rb | 1 - spec/helpers/media_component_helper_spec.rb | 22 - 115 files changed, 710 insertions(+), 1928 deletions(-) create mode 100644 app/javascript/entrypoints/embed.tsx create mode 100644 app/javascript/hooks/useRenderSignal.ts create mode 100644 app/javascript/mastodon/features/standalone/status/index.tsx delete mode 100644 app/javascript/mastodon/features/status/components/detailed_status.jsx create mode 100644 app/javascript/mastodon/features/status/components/detailed_status.tsx delete mode 100644 app/javascript/mastodon/features/status/containers/detailed_status_container.js delete mode 100644 app/javascript/styles/mastodon/statuses.scss delete mode 100644 app/views/statuses/_detailed_status.html.haml delete mode 100644 app/views/statuses/_poll.html.haml delete mode 100644 app/views/statuses/_simple_status.html.haml delete mode 100644 app/views/statuses/_status.html.haml diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 158a0815e1..d804566c93 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -19,14 +19,6 @@ module AccountsHelper end end - def account_action_button(account) - return if account.memorial? || account.moved? - - link_to ActivityPub::TagManager.instance.url_for(account), class: 'button logo-button', target: '_new' do - safe_join([logo_as_symbol, t('accounts.follow')]) - end - end - def account_formatted_stat(value) number_to_human(value, precision: 3, strip_insignificant_zeros: true) end diff --git a/app/helpers/media_component_helper.rb b/app/helpers/media_component_helper.rb index fa8f34fb4d..60ccdd0835 100644 --- a/app/helpers/media_component_helper.rb +++ b/app/helpers/media_component_helper.rb @@ -57,26 +57,6 @@ module MediaComponentHelper end end - def render_card_component(status, **options) - component_params = { - sensitive: sensitive_viewer?(status, current_account), - card: serialize_status_card(status).as_json, - }.merge(**options) - - react_component :card, component_params - end - - def render_poll_component(status, **options) - component_params = { - disabled: true, - poll: serialize_status_poll(status).as_json, - }.merge(**options) - - react_component :poll, component_params do - render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: prefers_autoplay? } - end - end - private def serialize_media_attachment(attachment) @@ -86,22 +66,6 @@ module MediaComponentHelper ) end - def serialize_status_card(status) - ActiveModelSerializers::SerializableResource.new( - status.preview_card, - serializer: REST::PreviewCardSerializer - ) - end - - def serialize_status_poll(status) - ActiveModelSerializers::SerializableResource.new( - status.preloadable_poll, - serializer: REST::PollSerializer, - scope: current_user, - scope_name: :current_user - ) - end - def sensitive_viewer?(status, account) if !account.nil? && account.id == status.account_id status.sensitive diff --git a/app/javascript/entrypoints/embed.tsx b/app/javascript/entrypoints/embed.tsx new file mode 100644 index 0000000000..f8c824d287 --- /dev/null +++ b/app/javascript/entrypoints/embed.tsx @@ -0,0 +1,74 @@ +import './public-path'; +import { createRoot } from 'react-dom/client'; + +import { afterInitialRender } from 'mastodon/../hooks/useRenderSignal'; + +import { start } from '../mastodon/common'; +import { Status } from '../mastodon/features/standalone/status'; +import { loadPolyfills } from '../mastodon/polyfills'; +import ready from '../mastodon/ready'; + +start(); + +function loaded() { + const mountNode = document.getElementById('mastodon-status'); + + if (mountNode) { + const attr = mountNode.getAttribute('data-props'); + + if (!attr) return; + + const props = JSON.parse(attr) as { id: string; locale: string }; + const root = createRoot(mountNode); + + root.render(<Status {...props} />); + } +} + +function main() { + ready(loaded).catch((error: unknown) => { + console.error(error); + }); +} + +loadPolyfills() + .then(main) + .catch((error: unknown) => { + console.error(error); + }); + +interface SetHeightMessage { + type: 'setHeight'; + id: string; + height: number; +} + +function isSetHeightMessage(data: unknown): data is SetHeightMessage { + if ( + data && + typeof data === 'object' && + 'type' in data && + data.type === 'setHeight' + ) + return true; + else return false; +} + +window.addEventListener('message', (e) => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases + if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return; + + const data = e.data; + + // We use a timeout to allow for the React page to render before calculating the height + afterInitialRender(() => { + window.parent.postMessage( + { + type: 'setHeight', + id: data.id, + height: document.getElementsByTagName('html')[0]?.scrollHeight, + }, + '*', + ); + }); +}); diff --git a/app/javascript/entrypoints/public.tsx b/app/javascript/entrypoints/public.tsx index b06675c2ee..d33e00d5da 100644 --- a/app/javascript/entrypoints/public.tsx +++ b/app/javascript/entrypoints/public.tsx @@ -37,43 +37,6 @@ const messages = defineMessages({ }, }); -interface SetHeightMessage { - type: 'setHeight'; - id: string; - height: number; -} - -function isSetHeightMessage(data: unknown): data is SetHeightMessage { - if ( - data && - typeof data === 'object' && - 'type' in data && - data.type === 'setHeight' - ) - return true; - else return false; -} - -window.addEventListener('message', (e) => { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases - if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return; - - const data = e.data; - - ready(() => { - window.parent.postMessage( - { - type: 'setHeight', - id: data.id, - height: document.getElementsByTagName('html')[0]?.scrollHeight, - }, - '*', - ); - }).catch((e: unknown) => { - console.error('Error in setHeightMessage postMessage', e); - }); -}); - function loaded() { const { messages: localeData } = getLocale(); diff --git a/app/javascript/hooks/useRenderSignal.ts b/app/javascript/hooks/useRenderSignal.ts new file mode 100644 index 0000000000..740df4a35a --- /dev/null +++ b/app/javascript/hooks/useRenderSignal.ts @@ -0,0 +1,32 @@ +// This hook allows a component to signal that it's done rendering in a way that +// can be used by e.g. our embed code to determine correct iframe height + +let renderSignalReceived = false; + +type Callback = () => void; + +let onInitialRender: Callback; + +export const afterInitialRender = (callback: Callback) => { + if (renderSignalReceived) { + callback(); + } else { + onInitialRender = callback; + } +}; + +export const useRenderSignal = () => { + return () => { + if (renderSignalReceived) { + return; + } + + renderSignalReceived = true; + + if (typeof onInitialRender !== 'undefined') { + window.requestAnimationFrame(() => { + onInitialRender(); + }); + } + }; +}; diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 340cee8024..1e4e545d8c 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -49,11 +49,13 @@ export function fetchStatusRequest(id, skipLoading) { }; } -export function fetchStatus(id, forceFetch = false) { +export function fetchStatus(id, forceFetch = false, alsoFetchContext = true) { return (dispatch, getState) => { const skipLoading = !forceFetch && getState().getIn(['statuses', id], null) !== null; - dispatch(fetchContext(id)); + if (alsoFetchContext) { + dispatch(fetchContext(id)); + } if (skipLoading) { return; diff --git a/app/javascript/mastodon/components/logo.tsx b/app/javascript/mastodon/components/logo.tsx index b7f8bd6695..fe9680d0e3 100644 --- a/app/javascript/mastodon/components/logo.tsx +++ b/app/javascript/mastodon/components/logo.tsx @@ -7,6 +7,13 @@ export const WordmarkLogo: React.FC = () => ( </svg> ); +export const IconLogo: React.FC = () => ( + <svg viewBox='0 0 79 79' className='logo logo--icon' role='img'> + <title>Mastodon</title> + <use xlinkHref='#logo-symbol-icon' /> + </svg> +); + export const SymbolLogo: React.FC = () => ( <img src={logo} alt='Mastodon' className='logo logo--icon' /> ); diff --git a/app/javascript/mastodon/components/more_from_author.jsx b/app/javascript/mastodon/components/more_from_author.jsx index c20e76ac45..719f4dda86 100644 --- a/app/javascript/mastodon/components/more_from_author.jsx +++ b/app/javascript/mastodon/components/more_from_author.jsx @@ -2,14 +2,12 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; +import { IconLogo } from 'mastodon/components/logo'; import { AuthorLink } from 'mastodon/features/explore/components/author_link'; export const MoreFromAuthor = ({ accountId }) => ( <div className='more-from-author'> - <svg viewBox='0 0 79 79' className='logo logo--icon' role='img'> - <use xlinkHref='#logo-symbol-icon' /> - </svg> - + <IconLogo /> <FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <AuthorLink accountId={accountId} /> }} /> </div> ); diff --git a/app/javascript/mastodon/features/standalone/status/index.tsx b/app/javascript/mastodon/features/standalone/status/index.tsx new file mode 100644 index 0000000000..d5cb7e7f40 --- /dev/null +++ b/app/javascript/mastodon/features/standalone/status/index.tsx @@ -0,0 +1,87 @@ +/* eslint-disable @typescript-eslint/no-unsafe-return, + @typescript-eslint/no-explicit-any, + @typescript-eslint/no-unsafe-assignment */ + +import { useEffect, useCallback } from 'react'; + +import { Provider } from 'react-redux'; + +import { useRenderSignal } from 'mastodon/../hooks/useRenderSignal'; +import { fetchStatus, toggleStatusSpoilers } from 'mastodon/actions/statuses'; +import { hydrateStore } from 'mastodon/actions/store'; +import { Router } from 'mastodon/components/router'; +import { DetailedStatus } from 'mastodon/features/status/components/detailed_status'; +import initialState from 'mastodon/initial_state'; +import { IntlProvider } from 'mastodon/locales'; +import { makeGetStatus, makeGetPictureInPicture } from 'mastodon/selectors'; +import { store, useAppSelector, useAppDispatch } from 'mastodon/store'; + +const getStatus = makeGetStatus() as unknown as (arg0: any, arg1: any) => any; +const getPictureInPicture = makeGetPictureInPicture() as unknown as ( + arg0: any, + arg1: any, +) => any; + +const Embed: React.FC<{ id: string }> = ({ id }) => { + const status = useAppSelector((state) => getStatus(state, { id })); + const pictureInPicture = useAppSelector((state) => + getPictureInPicture(state, { id }), + ); + const domain = useAppSelector((state) => state.meta.get('domain')); + const dispatch = useAppDispatch(); + const dispatchRenderSignal = useRenderSignal(); + + useEffect(() => { + dispatch(fetchStatus(id, false, false)); + }, [dispatch, id]); + + const handleToggleHidden = useCallback(() => { + dispatch(toggleStatusSpoilers(id)); + }, [dispatch, id]); + + // This allows us to calculate the correct page height for embeds + if (status) { + dispatchRenderSignal(); + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + const permalink = status?.get('url') as string; + + return ( + <div className='embed'> + <DetailedStatus + status={status} + domain={domain} + pictureInPicture={pictureInPicture} + onToggleHidden={handleToggleHidden} + withLogo + /> + + <a + className='embed__overlay' + href={permalink} + target='_blank' + rel='noreferrer noopener' + aria-label='' + /> + </div> + ); +}; + +export const Status: React.FC<{ id: string }> = ({ id }) => { + useEffect(() => { + if (initialState) { + store.dispatch(hydrateStore(initialState)); + } + }, []); + + return ( + <IntlProvider> + <Provider store={store}> + <Router> + <Embed id={id} /> + </Router> + </Provider> + </IntlProvider> + ); +}; diff --git a/app/javascript/mastodon/features/status/components/detailed_status.jsx b/app/javascript/mastodon/features/status/components/detailed_status.jsx deleted file mode 100644 index 8ee1ec9b9b..0000000000 --- a/app/javascript/mastodon/features/status/components/detailed_status.jsx +++ /dev/null @@ -1,322 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedDate, FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { Link, withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; -import { AnimatedNumber } from 'mastodon/components/animated_number'; -import { ContentWarning } from 'mastodon/components/content_warning'; -import EditedTimestamp from 'mastodon/components/edited_timestamp'; -import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar'; -import { Icon } from 'mastodon/components/icon'; -import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder'; -import { VisibilityIcon } from 'mastodon/components/visibility_icon'; -import { WithRouterPropTypes } from 'mastodon/utils/react_router'; - -import { Avatar } from '../../../components/avatar'; -import { DisplayName } from '../../../components/display_name'; -import MediaGallery from '../../../components/media_gallery'; -import StatusContent from '../../../components/status_content'; -import Audio from '../../audio'; -import scheduleIdleTask from '../../ui/util/schedule_idle_task'; -import Video from '../../video'; - -import Card from './card'; - -class DetailedStatus extends ImmutablePureComponent { - - static propTypes = { - status: ImmutablePropTypes.map, - onOpenMedia: PropTypes.func.isRequired, - onOpenVideo: PropTypes.func.isRequired, - onToggleHidden: PropTypes.func.isRequired, - onTranslate: PropTypes.func.isRequired, - measureHeight: PropTypes.bool, - onHeightChange: PropTypes.func, - domain: PropTypes.string.isRequired, - compact: PropTypes.bool, - showMedia: PropTypes.bool, - pictureInPicture: ImmutablePropTypes.contains({ - inUse: PropTypes.bool, - available: PropTypes.bool, - }), - onToggleMediaVisibility: PropTypes.func, - ...WithRouterPropTypes, - }; - - state = { - height: null, - }; - - handleAccountClick = (e) => { - if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.props.history) { - e.preventDefault(); - this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); - } - - e.stopPropagation(); - }; - - handleOpenVideo = (options) => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options); - }; - - handleExpandedToggle = () => { - this.props.onToggleHidden(this.props.status); - }; - - _measureHeight (heightJustChanged) { - if (this.props.measureHeight && this.node) { - scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 })); - - if (this.props.onHeightChange && heightJustChanged) { - this.props.onHeightChange(); - } - } - } - - setRef = c => { - this.node = c; - this._measureHeight(); - }; - - componentDidUpdate (prevProps, prevState) { - this._measureHeight(prevState.height !== this.state.height); - } - - handleModalLink = e => { - e.preventDefault(); - - let href; - - if (e.target.nodeName !== 'A') { - href = e.target.parentNode.href; - } else { - href = e.target.href; - } - - window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes'); - }; - - handleTranslate = () => { - const { onTranslate, status } = this.props; - onTranslate(status); - }; - - _properStatus () { - const { status } = this.props; - - if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') { - return status.get('reblog'); - } else { - return status; - } - } - - getAttachmentAspectRatio () { - const attachments = this._properStatus().get('media_attachments'); - - if (attachments.getIn([0, 'type']) === 'video') { - return `${attachments.getIn([0, 'meta', 'original', 'width'])} / ${attachments.getIn([0, 'meta', 'original', 'height'])}`; - } else if (attachments.getIn([0, 'type']) === 'audio') { - return '16 / 9'; - } else { - return (attachments.size === 1 && attachments.getIn([0, 'meta', 'small', 'aspect'])) ? attachments.getIn([0, 'meta', 'small', 'aspect']) : '3 / 2'; - } - } - - render () { - const status = this._properStatus(); - const outerStyle = { boxSizing: 'border-box' }; - const { compact, pictureInPicture } = this.props; - - if (!status) { - return null; - } - - let media = ''; - let applicationLink = ''; - let reblogLink = ''; - let favouriteLink = ''; - - if (this.props.measureHeight) { - outerStyle.height = `${this.state.height}px`; - } - - const language = status.getIn(['translation', 'language']) || status.get('language'); - - if (pictureInPicture.get('inUse')) { - media = <PictureInPicturePlaceholder aspectRatio={this.getAttachmentAspectRatio()} />; - } else if (status.get('media_attachments').size > 0) { - if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { - const attachment = status.getIn(['media_attachments', 0]); - const description = attachment.getIn(['translation', 'description']) || attachment.get('description'); - - media = ( - <Audio - src={attachment.get('url')} - alt={description} - lang={language} - duration={attachment.getIn(['meta', 'original', 'duration'], 0)} - poster={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])} - backgroundColor={attachment.getIn(['meta', 'colors', 'background'])} - foregroundColor={attachment.getIn(['meta', 'colors', 'foreground'])} - accentColor={attachment.getIn(['meta', 'colors', 'accent'])} - sensitive={status.get('sensitive')} - visible={this.props.showMedia} - blurhash={attachment.get('blurhash')} - height={150} - onToggleVisibility={this.props.onToggleMediaVisibility} - /> - ); - } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { - const attachment = status.getIn(['media_attachments', 0]); - const description = attachment.getIn(['translation', 'description']) || attachment.get('description'); - - media = ( - <Video - preview={attachment.get('preview_url')} - frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])} - aspectRatio={`${attachment.getIn(['meta', 'original', 'width'])} / ${attachment.getIn(['meta', 'original', 'height'])}`} - blurhash={attachment.get('blurhash')} - src={attachment.get('url')} - alt={description} - lang={language} - width={300} - height={150} - onOpenVideo={this.handleOpenVideo} - sensitive={status.get('sensitive')} - visible={this.props.showMedia} - onToggleVisibility={this.props.onToggleMediaVisibility} - /> - ); - } else { - media = ( - <MediaGallery - standalone - sensitive={status.get('sensitive')} - media={status.get('media_attachments')} - lang={language} - height={300} - onOpenMedia={this.props.onOpenMedia} - visible={this.props.showMedia} - onToggleVisibility={this.props.onToggleMediaVisibility} - /> - ); - } - } else if (status.get('spoiler_text').length === 0) { - media = <Card sensitive={status.get('sensitive')} onOpenMedia={this.props.onOpenMedia} card={status.get('card', null)} />; - } - - if (status.get('application')) { - applicationLink = <>·<a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></>; - } - - const visibilityLink = <>·<VisibilityIcon visibility={status.get('visibility')} /></>; - - if (['private', 'direct'].includes(status.get('visibility'))) { - reblogLink = ''; - } else if (this.props.history) { - reblogLink = ( - <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'> - <span className='detailed-status__reblogs'> - <AnimatedNumber value={status.get('reblogs_count')} /> - </span> - <FormattedMessage id='status.reblogs' defaultMessage='{count, plural, one {boost} other {boosts}}' values={{ count: status.get('reblogs_count') }} /> - </Link> - ); - } else { - reblogLink = ( - <a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}> - <span className='detailed-status__reblogs'> - <AnimatedNumber value={status.get('reblogs_count')} /> - </span> - <FormattedMessage id='status.reblogs' defaultMessage='{count, plural, one {boost} other {boosts}}' values={{ count: status.get('reblogs_count') }} /> - </a> - ); - } - - if (this.props.history) { - favouriteLink = ( - <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'> - <span className='detailed-status__favorites'> - <AnimatedNumber value={status.get('favourites_count')} /> - </span> - <FormattedMessage id='status.favourites' defaultMessage='{count, plural, one {favorite} other {favorites}}' values={{ count: status.get('favourites_count') }} /> - </Link> - ); - } else { - favouriteLink = ( - <a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}> - <span className='detailed-status__favorites'> - <AnimatedNumber value={status.get('favourites_count')} /> - </span> - <FormattedMessage id='status.favourites' defaultMessage='{count, plural, one {favorite} other {favorites}}' values={{ count: status.get('favourites_count') }} /> - </a> - ); - } - - const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status); - const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0; - - return ( - <div style={outerStyle}> - <div ref={this.setRef} className={classNames('detailed-status', { compact })}> - {status.get('visibility') === 'direct' && ( - <div className='status__prepend'> - <div className='status__prepend-icon-wrapper'><Icon id='at' icon={AlternateEmailIcon} className='status__prepend-icon' /></div> - <FormattedMessage id='status.direct_indicator' defaultMessage='Private mention' /> - </div> - )} - <a href={`/@${status.getIn(['account', 'acct'])}`} data-hover-card-account={status.getIn(['account', 'id'])} onClick={this.handleAccountClick} className='detailed-status__display-name'> - <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={46} /></div> - <DisplayName account={status.get('account')} localDomain={this.props.domain} /> - </a> - - {status.get('spoiler_text').length > 0 && <ContentWarning text={status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml')} expanded={expanded} onClick={this.handleExpandedToggle} />} - - {expanded && ( - <> - <StatusContent - status={status} - onTranslate={this.handleTranslate} - {...statusContentProps} - /> - - {media} - {hashtagBar} - </> - )} - - <div className='detailed-status__meta'> - <div className='detailed-status__meta__line'> - <a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} target='_blank' rel='noopener noreferrer'> - <FormattedDate value={new Date(status.get('created_at'))} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' /> - </a> - - {visibilityLink} - - {applicationLink} - </div> - - {status.get('edited_at') && <div className='detailed-status__meta__line'><EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} /></div>} - - <div className='detailed-status__meta__line'> - {reblogLink} - {reblogLink && <>·</>} - {favouriteLink} - </div> - </div> - </div> - </div> - ); - } - -} - -export default withRouter(DetailedStatus); diff --git a/app/javascript/mastodon/features/status/components/detailed_status.tsx b/app/javascript/mastodon/features/status/components/detailed_status.tsx new file mode 100644 index 0000000000..fa843122fb --- /dev/null +++ b/app/javascript/mastodon/features/status/components/detailed_status.tsx @@ -0,0 +1,390 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access, + @typescript-eslint/no-unsafe-call, + @typescript-eslint/no-explicit-any, + @typescript-eslint/no-unsafe-assignment */ + +import type { CSSProperties } from 'react'; +import { useState, useRef, useCallback } from 'react'; + +import { FormattedDate, FormattedMessage } from 'react-intl'; + +import classNames from 'classnames'; +import { Link } from 'react-router-dom'; + +import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; +import { AnimatedNumber } from 'mastodon/components/animated_number'; +import { ContentWarning } from 'mastodon/components/content_warning'; +import EditedTimestamp from 'mastodon/components/edited_timestamp'; +import type { StatusLike } from 'mastodon/components/hashtag_bar'; +import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar'; +import { Icon } from 'mastodon/components/icon'; +import { IconLogo } from 'mastodon/components/logo'; +import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder'; +import { VisibilityIcon } from 'mastodon/components/visibility_icon'; + +import { Avatar } from '../../../components/avatar'; +import { DisplayName } from '../../../components/display_name'; +import MediaGallery from '../../../components/media_gallery'; +import StatusContent from '../../../components/status_content'; +import Audio from '../../audio'; +import scheduleIdleTask from '../../ui/util/schedule_idle_task'; +import Video from '../../video'; + +import Card from './card'; + +interface VideoModalOptions { + startTime: number; + autoPlay?: boolean; + defaultVolume: number; + componentIndex: number; +} + +export const DetailedStatus: React.FC<{ + status: any; + onOpenMedia?: (status: any, index: number, lang: string) => void; + onOpenVideo?: (status: any, lang: string, options: VideoModalOptions) => void; + onTranslate?: (status: any) => void; + measureHeight?: boolean; + onHeightChange?: () => void; + domain: string; + showMedia?: boolean; + withLogo?: boolean; + pictureInPicture: any; + onToggleHidden?: (status: any) => void; + onToggleMediaVisibility?: () => void; +}> = ({ + status, + onOpenMedia, + onOpenVideo, + onTranslate, + measureHeight, + onHeightChange, + domain, + showMedia, + withLogo, + pictureInPicture, + onToggleMediaVisibility, + onToggleHidden, +}) => { + const properStatus = status?.get('reblog') ?? status; + const [height, setHeight] = useState(0); + const nodeRef = useRef<HTMLDivElement>(); + + const handleOpenVideo = useCallback( + (options: VideoModalOptions) => { + const lang = (status.getIn(['translation', 'language']) || + status.get('language')) as string; + if (onOpenVideo) + onOpenVideo(status.getIn(['media_attachments', 0]), lang, options); + }, + [onOpenVideo, status], + ); + + const handleExpandedToggle = useCallback(() => { + if (onToggleHidden) onToggleHidden(status); + }, [onToggleHidden, status]); + + const _measureHeight = useCallback( + (heightJustChanged?: boolean) => { + if (measureHeight && nodeRef.current) { + scheduleIdleTask(() => { + if (nodeRef.current) + setHeight(Math.ceil(nodeRef.current.scrollHeight) + 1); + }); + + if (onHeightChange && heightJustChanged) { + onHeightChange(); + } + } + }, + [onHeightChange, measureHeight, setHeight], + ); + + const handleRef = useCallback( + (c: HTMLDivElement) => { + nodeRef.current = c; + _measureHeight(); + }, + [_measureHeight], + ); + + const handleTranslate = useCallback(() => { + if (onTranslate) onTranslate(status); + }, [onTranslate, status]); + + if (!properStatus) { + return null; + } + + let media; + let applicationLink; + let reblogLink; + let attachmentAspectRatio; + + if (properStatus.get('media_attachments').getIn([0, 'type']) === 'video') { + attachmentAspectRatio = `${properStatus.get('media_attachments').getIn([0, 'meta', 'original', 'width'])} / ${properStatus.get('media_attachments').getIn([0, 'meta', 'original', 'height'])}`; + } else if ( + properStatus.get('media_attachments').getIn([0, 'type']) === 'audio' + ) { + attachmentAspectRatio = '16 / 9'; + } else { + attachmentAspectRatio = + properStatus.get('media_attachments').size === 1 && + properStatus + .get('media_attachments') + .getIn([0, 'meta', 'small', 'aspect']) + ? properStatus + .get('media_attachments') + .getIn([0, 'meta', 'small', 'aspect']) + : '3 / 2'; + } + + const outerStyle = { boxSizing: 'border-box' } as CSSProperties; + + if (measureHeight) { + outerStyle.height = height; + } + + const language = + status.getIn(['translation', 'language']) || status.get('language'); + + if (pictureInPicture.get('inUse')) { + media = <PictureInPicturePlaceholder aspectRatio={attachmentAspectRatio} />; + } else if (status.get('media_attachments').size > 0) { + if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { + const attachment = status.getIn(['media_attachments', 0]); + const description = + attachment.getIn(['translation', 'description']) || + attachment.get('description'); + + media = ( + <Audio + src={attachment.get('url')} + alt={description} + lang={language} + duration={attachment.getIn(['meta', 'original', 'duration'], 0)} + poster={ + attachment.get('preview_url') || + status.getIn(['account', 'avatar_static']) + } + backgroundColor={attachment.getIn(['meta', 'colors', 'background'])} + foregroundColor={attachment.getIn(['meta', 'colors', 'foreground'])} + accentColor={attachment.getIn(['meta', 'colors', 'accent'])} + sensitive={status.get('sensitive')} + visible={showMedia} + blurhash={attachment.get('blurhash')} + height={150} + onToggleVisibility={onToggleMediaVisibility} + /> + ); + } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { + const attachment = status.getIn(['media_attachments', 0]); + const description = + attachment.getIn(['translation', 'description']) || + attachment.get('description'); + + media = ( + <Video + preview={attachment.get('preview_url')} + frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])} + aspectRatio={`${attachment.getIn(['meta', 'original', 'width'])} / ${attachment.getIn(['meta', 'original', 'height'])}`} + blurhash={attachment.get('blurhash')} + src={attachment.get('url')} + alt={description} + lang={language} + width={300} + height={150} + onOpenVideo={handleOpenVideo} + sensitive={status.get('sensitive')} + visible={showMedia} + onToggleVisibility={onToggleMediaVisibility} + /> + ); + } else { + media = ( + <MediaGallery + standalone + sensitive={status.get('sensitive')} + media={status.get('media_attachments')} + lang={language} + height={300} + onOpenMedia={onOpenMedia} + visible={showMedia} + onToggleVisibility={onToggleMediaVisibility} + /> + ); + } + } else if (status.get('spoiler_text').length === 0) { + media = ( + <Card + sensitive={status.get('sensitive')} + onOpenMedia={onOpenMedia} + card={status.get('card', null)} + /> + ); + } + + if (status.get('application')) { + applicationLink = ( + <> + · + <a + className='detailed-status__application' + href={status.getIn(['application', 'website'])} + target='_blank' + rel='noopener noreferrer' + > + {status.getIn(['application', 'name'])} + </a> + </> + ); + } + + const visibilityLink = ( + <> + ·<VisibilityIcon visibility={status.get('visibility')} /> + </> + ); + + if (['private', 'direct'].includes(status.get('visibility') as string)) { + reblogLink = ''; + } else { + reblogLink = ( + <Link + to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} + className='detailed-status__link' + > + <span className='detailed-status__reblogs'> + <AnimatedNumber value={status.get('reblogs_count')} /> + </span> + <FormattedMessage + id='status.reblogs' + defaultMessage='{count, plural, one {boost} other {boosts}}' + values={{ count: status.get('reblogs_count') }} + /> + </Link> + ); + } + + const favouriteLink = ( + <Link + to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} + className='detailed-status__link' + > + <span className='detailed-status__favorites'> + <AnimatedNumber value={status.get('favourites_count')} /> + </span> + <FormattedMessage + id='status.favourites' + defaultMessage='{count, plural, one {favorite} other {favorites}}' + values={{ count: status.get('favourites_count') }} + /> + </Link> + ); + + const { statusContentProps, hashtagBar } = getHashtagBarForStatus( + status as StatusLike, + ); + const expanded = + !status.get('hidden') || status.get('spoiler_text').length === 0; + + return ( + <div style={outerStyle}> + <div ref={handleRef} className={classNames('detailed-status')}> + {status.get('visibility') === 'direct' && ( + <div className='status__prepend'> + <div className='status__prepend-icon-wrapper'> + <Icon + id='at' + icon={AlternateEmailIcon} + className='status__prepend-icon' + /> + </div> + <FormattedMessage + id='status.direct_indicator' + defaultMessage='Private mention' + /> + </div> + )} + <Link + to={`/@${status.getIn(['account', 'acct'])}`} + data-hover-card-account={status.getIn(['account', 'id'])} + className='detailed-status__display-name' + > + <div className='detailed-status__display-avatar'> + <Avatar account={status.get('account')} size={46} /> + </div> + <DisplayName account={status.get('account')} localDomain={domain} /> + {withLogo && ( + <> + <div className='spacer' /> + <IconLogo /> + </> + )} + </Link> + + {status.get('spoiler_text').length > 0 && ( + <ContentWarning + text={ + status.getIn(['translation', 'spoilerHtml']) || + status.get('spoilerHtml') + } + expanded={expanded} + onClick={handleExpandedToggle} + /> + )} + + {expanded && ( + <> + <StatusContent + status={status} + onTranslate={handleTranslate} + {...(statusContentProps as any)} + /> + + {media} + {hashtagBar} + </> + )} + + <div className='detailed-status__meta'> + <div className='detailed-status__meta__line'> + <a + className='detailed-status__datetime' + href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} + target='_blank' + rel='noopener noreferrer' + > + <FormattedDate + value={new Date(status.get('created_at') as string)} + year='numeric' + month='short' + day='2-digit' + hour='2-digit' + minute='2-digit' + /> + </a> + + {visibilityLink} + {applicationLink} + </div> + + {status.get('edited_at') && ( + <div className='detailed-status__meta__line'> + <EditedTimestamp + statusId={status.get('id')} + timestamp={status.get('edited_at')} + /> + </div> + )} + + <div className='detailed-status__meta__line'> + {reblogLink} + {reblogLink && <>·</>} + {favouriteLink} + </div> + </div> + </div> + </div> + ); +}; diff --git a/app/javascript/mastodon/features/status/containers/detailed_status_container.js b/app/javascript/mastodon/features/status/containers/detailed_status_container.js deleted file mode 100644 index 0e73697fef..0000000000 --- a/app/javascript/mastodon/features/status/containers/detailed_status_container.js +++ /dev/null @@ -1,140 +0,0 @@ -import { injectIntl } from 'react-intl'; - -import { connect } from 'react-redux'; - -import { showAlertForError } from '../../../actions/alerts'; -import { initBlockModal } from '../../../actions/blocks'; -import { - replyCompose, - mentionCompose, - directCompose, -} from '../../../actions/compose'; -import { - toggleReblog, - toggleFavourite, - pin, - unpin, -} from '../../../actions/interactions'; -import { openModal } from '../../../actions/modal'; -import { initMuteModal } from '../../../actions/mutes'; -import { initReport } from '../../../actions/reports'; -import { - muteStatus, - unmuteStatus, - deleteStatus, - toggleStatusSpoilers, -} from '../../../actions/statuses'; -import { deleteModal } from '../../../initial_state'; -import { makeGetStatus, makeGetPictureInPicture } from '../../../selectors'; -import DetailedStatus from '../components/detailed_status'; - -const makeMapStateToProps = () => { - const getStatus = makeGetStatus(); - const getPictureInPicture = makeGetPictureInPicture(); - - const mapStateToProps = (state, props) => ({ - status: getStatus(state, props), - domain: state.getIn(['meta', 'domain']), - pictureInPicture: getPictureInPicture(state, props), - }); - - return mapStateToProps; -}; - -const mapDispatchToProps = (dispatch) => ({ - - onReply (status) { - dispatch((_, getState) => { - let state = getState(); - if (state.getIn(['compose', 'text']).trim().length !== 0) { - dispatch(openModal({ modalType: 'CONFIRM_REPLY', modalProps: { status } })); - } else { - dispatch(replyCompose(status)); - } - }); - }, - - onReblog (status, e) { - dispatch(toggleReblog(status.get('id'), e.shiftKey)); - }, - - onFavourite (status) { - dispatch(toggleFavourite(status.get('id'))); - }, - - onPin (status) { - if (status.get('pinned')) { - dispatch(unpin(status)); - } else { - dispatch(pin(status)); - } - }, - - onEmbed (status) { - dispatch(openModal({ - modalType: 'EMBED', - modalProps: { - id: status.get('id'), - onError: error => dispatch(showAlertForError(error)), - }, - })); - }, - - onDelete (status, withRedraft = false) { - if (!deleteModal) { - dispatch(deleteStatus(status.get('id'), withRedraft)); - } else { - dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } })); - } - }, - - onDirect (account) { - dispatch(directCompose(account)); - }, - - onMention (account) { - dispatch(mentionCompose(account)); - }, - - onOpenMedia (media, index, lang) { - dispatch(openModal({ - modalType: 'MEDIA', - modalProps: { media, index, lang }, - })); - }, - - onOpenVideo (media, lang, options) { - dispatch(openModal({ - modalType: 'VIDEO', - modalProps: { media, lang, options }, - })); - }, - - onBlock (status) { - const account = status.get('account'); - dispatch(initBlockModal(account)); - }, - - onReport (status) { - dispatch(initReport(status.get('account'), status)); - }, - - onMute (account) { - dispatch(initMuteModal(account)); - }, - - onMuteConversation (status) { - if (status.get('muted')) { - dispatch(unmuteStatus(status.get('id'))); - } else { - dispatch(muteStatus(status.get('id'))); - } - }, - - onToggleHidden (status) { - dispatch(toggleStatusSpoilers(status.get('id'))); - }, - -}); - -export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(DetailedStatus)); diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index 5f325fe7b8..c115f77755 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -69,7 +69,7 @@ import Column from '../ui/components/column'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen'; import ActionBar from './components/action_bar'; -import DetailedStatus from './components/detailed_status'; +import { DetailedStatus } from './components/detailed_status'; const messages = defineMessages({ diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss index 0dd573da9b..465b748078 100644 --- a/app/javascript/styles/application.scss +++ b/app/javascript/styles/application.scss @@ -11,7 +11,6 @@ @import 'mastodon/widgets'; @import 'mastodon/forms'; @import 'mastodon/accounts'; -@import 'mastodon/statuses'; @import 'mastodon/components'; @import 'mastodon/polls'; @import 'mastodon/modal'; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 5a8fa3e5c0..c6ce8f55ab 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1677,18 +1677,6 @@ body > [data-popper-placement] { padding: 16px; border-top: 1px solid var(--background-border-color); - &--flex { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - align-items: flex-start; - - .status__content, - .detailed-status__meta { - flex: 100%; - } - } - .status__content { font-size: 19px; line-height: 24px; @@ -1723,6 +1711,25 @@ body > [data-popper-placement] { margin-bottom: 0; } } + + .logo { + width: 40px; + height: 40px; + color: $dark-text-color; + } +} + +.embed { + position: relative; + + &__overlay { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } } .scrollable > div:first-child .detailed-status { diff --git a/app/javascript/styles/mastodon/statuses.scss b/app/javascript/styles/mastodon/statuses.scss deleted file mode 100644 index b6d4f98cce..0000000000 --- a/app/javascript/styles/mastodon/statuses.scss +++ /dev/null @@ -1,152 +0,0 @@ -.activity-stream { - box-shadow: 0 0 15px rgba($base-shadow-color, 0.2); - border-radius: 4px; - overflow: hidden; - margin-bottom: 10px; - - &--under-tabs { - border-radius: 0 0 4px 4px; - } - - @media screen and (max-width: $no-gap-breakpoint) { - margin-bottom: 0; - border-radius: 0; - box-shadow: none; - } - - &--headless { - border-radius: 0; - margin: 0; - box-shadow: none; - - .detailed-status, - .status { - border-radius: 0 !important; - } - } - - div[data-component] { - width: 100%; - } - - .entry { - background: $ui-base-color; - - .detailed-status, - .status, - .load-more { - animation: none; - } - - &:last-child { - .detailed-status, - .status, - .load-more { - border-bottom: 0; - border-radius: 0 0 4px 4px; - } - } - - &:first-child { - .detailed-status, - .status, - .load-more { - border-radius: 4px 4px 0 0; - } - - &:last-child { - .detailed-status, - .status, - .load-more { - border-radius: 4px; - } - } - } - - @media screen and (width <= 740px) { - .detailed-status, - .status, - .load-more { - border-radius: 0 !important; - } - } - } - - &--highlighted .entry { - background: lighten($ui-base-color, 8%); - } -} - -.button.logo-button svg { - width: 20px; - height: auto; - vertical-align: middle; - margin-inline-end: 5px; - fill: $primary-text-color; - - @media screen and (max-width: $no-gap-breakpoint) { - display: none; - } -} - -.embed { - .status__content[data-spoiler='folded'] { - .e-content { - display: none; - } - - p:first-child { - margin-bottom: 0; - } - } - - .detailed-status { - padding: 15px; - - .detailed-status__display-avatar .account__avatar { - width: 48px; - height: 48px; - } - } - - .status { - padding: 15px 15px 15px (48px + 15px * 2); - min-height: 48px + 2px; - - &__avatar { - inset-inline-start: 15px; - top: 17px; - - .account__avatar { - width: 48px; - height: 48px; - } - } - - &__content { - padding-top: 5px; - } - - &__prepend { - margin-inline-start: 48px + 15px * 2; - padding-top: 15px; - } - - &__prepend-icon-wrapper { - inset-inline-start: -32px; - } - - .media-gallery, - &__action-bar, - .video-player { - margin-top: 10px; - } - - &__action-bar-button { - font-size: 18px; - width: 23.1429px; - height: 23.1429px; - line-height: 23.15px; - } - } -} diff --git a/app/serializers/oembed_serializer.rb b/app/serializers/oembed_serializer.rb index d6261d7242..3882b0e305 100644 --- a/app/serializers/oembed_serializer.rb +++ b/app/serializers/oembed_serializer.rb @@ -37,16 +37,16 @@ class OEmbedSerializer < ActiveModel::Serializer end def html - attributes = { - src: embed_short_account_status_url(object.account, object), - class: 'mastodon-embed', - style: 'max-width: 100%; border: 0', - width: width, - height: height, - allowfullscreen: true, - } - - content_tag(:iframe, nil, attributes) + content_tag(:script, nil, src: full_asset_url('embed.js', skip_pipeline: true), async: true) + <<~HTML.squish + <blockquote class="mastodon-embed" data-embed-url="#{embed_short_account_status_url(object.account, object)}" style="max-width: 540px; min-width: 270px; background:#FCF8FF; border: 1px solid #C9C4DA; border-radius: 8px; overflow: hidden; margin: 0; padding: 0;"> + <a href="#{short_account_status_url(object.account, object)}" target="_blank" style="color: #1C1A25; text-decoration: none; display: flex; align-items: center; justify-content: center; flex-direction: column; padding: 24px; font-size: 14px; line-height: 20px; letter-spacing: 0.25px; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif;"> + <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"/></svg> + <div style="margin-top: 16px; color: #787588;">Post by @#{object.account.pretty_acct}@#{provider_name}</div> + <div style="font-weight: 500;">View on Mastodon</div> + </a> + </blockquote> + <script data-allowed-prefixes="#{root_url}" src="#{full_asset_url('embed.js', skip_pipeline: true)}" async="true"></script> + HTML end def width diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml index 9258e80833..0237e04515 100644 --- a/app/views/layouts/embedded.html.haml +++ b/app/views/layouts/embedded.html.haml @@ -15,7 +15,7 @@ = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous' = preload_pack_asset "locale/#{I18n.locale}-json.js" = render_initial_state - = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' + = javascript_pack_tag 'embed', integrity: true, crossorigin: 'anonymous' %body.embed = yield diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml deleted file mode 100644 index 6cd240bbbc..0000000000 --- a/app/views/statuses/_detailed_status.html.haml +++ /dev/null @@ -1,80 +0,0 @@ -.detailed-status.detailed-status--flex{ class: "detailed-status-#{status.visibility}" } - .p-author.h-card - = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'detailed-status__display-name u-url', target: stream_link_target, rel: 'noopener' do - .detailed-status__display-avatar - - if prefers_autoplay? - = image_tag status.account.avatar_original_url, alt: '', class: 'account__avatar u-photo' - - else - = image_tag status.account.avatar_static_url, alt: '', class: 'account__avatar u-photo' - %span.display-name - %bdi - %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: prefers_autoplay?) - %span.display-name__account - = acct(status.account) - = material_symbol('lock') if status.account.locked? - - = account_action_button(status.account) - - .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< - - if status.spoiler_text? - %p< - %span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} - %button.status__content__spoiler-link= t('statuses.show_more') - .e-content{ lang: status.language } - = prerender_custom_emojis(status_content_format(status), status.emojis) - - - if status.preloadable_poll - = render_poll_component(status) - - - if !status.ordered_media_attachments.empty? - - if status.ordered_media_attachments.first.video? - = render_video_component(status, width: 670, height: 380, detailed: true) - - elsif status.ordered_media_attachments.first.audio? - = render_audio_component(status, width: 670, height: 380) - - else - = render_media_gallery_component(status, height: 380, standalone: true) - - elsif status.preview_card - = render_card_component(status) - - .detailed-status__meta - %data.dt-published{ value: status.created_at.to_time.iso8601 } - - if status.edited? - %data.dt-updated{ value: status.edited_at.to_time.iso8601 } - - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do - %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) - · - - if status.edited? - = t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')) - · - %span.detailed-status__visibility-icon - = visibility_icon status - · - - if status.application && status.account.user&.setting_show_application - - if status.application.website.blank? - %strong.detailed-status__application= status.application.name - - else - = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener noreferrer' - · - %span.detailed-status__link - - if status.in_reply_to_id.nil? - = material_symbol('reply') - - else - = material_symbol('reply_all') - %span.detailed-status__reblogs>= friendly_number_to_human status.replies_count - - · - - if status.public_visibility? || status.unlisted_visibility? - %span.detailed-status__link - = material_symbol('repeat') - %span.detailed-status__reblogs>= friendly_number_to_human status.reblogs_count - - · - %span.detailed-status__link - = material_symbol('star') - %span.detailed-status__favorites>= friendly_number_to_human status.favourites_count - - - - if user_signed_in? - · - = link_to t('statuses.open_in_web'), web_url("@#{status.account.pretty_acct}/#{status.id}"), class: 'detailed-status__application', target: '_blank', rel: 'noopener noreferrer' diff --git a/app/views/statuses/_poll.html.haml b/app/views/statuses/_poll.html.haml deleted file mode 100644 index 62416a44da..0000000000 --- a/app/views/statuses/_poll.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -:ruby - show_results = (user_signed_in? && poll.voted?(current_account)) || poll.expired? - total_votes_count = poll.voters_count || poll.votes_count - -.poll - %ul - - poll.loaded_options.each do |option| - %li - - if show_results - - percent = total_votes_count.positive? ? 100 * option.votes_count / total_votes_count : 0 - %label.poll__option>< - %span.poll__number>< - #{percent.round}% - %span.poll__option__text - = prerender_custom_emojis(h(option.title), status.emojis) - - %progress{ max: 100, value: [percent, 1].max, 'aria-hidden': 'true' } - %span.poll__chart - - else - %label.poll__option>< - %span.poll__input{ class: poll.multiple? ? 'checkbox' : nil }>< - %span.poll__option__text - = prerender_custom_emojis(h(option.title), status.emojis) - .poll__footer - - unless show_results - %button.button.button-secondary{ disabled: true } - = t('statuses.poll.vote') - - - if poll.voters_count.nil? - %span= t('statuses.poll.total_votes', count: poll.votes_count) - - else - %span= t('statuses.poll.total_people', count: poll.voters_count) - - - unless poll.expires_at.nil? - · - %span= l poll.expires_at diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml deleted file mode 100644 index ee7900fbfa..0000000000 --- a/app/views/statuses/_simple_status.html.haml +++ /dev/null @@ -1,70 +0,0 @@ -:ruby - hide_show_thread ||= false - -.status{ class: "status-#{status.visibility}" } - .status__info - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do - %span.status__visibility-icon>< - = visibility_icon status - %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) - - if status.edited? - %abbr{ title: t('statuses.edited_at_html', date: l(status.edited_at.to_date)) } - * - %data.dt-published{ value: status.created_at.to_time.iso8601 } - - .p-author.h-card - = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener noreferrer' do - .status__avatar - %div - - if prefers_autoplay? - = image_tag status.account.avatar_original_url, alt: '', class: 'u-photo account__avatar' - - else - = image_tag status.account.avatar_static_url, alt: '', class: 'u-photo account__avatar' - %span.display-name - %bdi - %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: prefers_autoplay?) - - %span.display-name__account - = acct(status.account) - = material_symbol('lock') if status.account.locked? - .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< - - if status.spoiler_text? - %p< - %span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} - %button.status__content__spoiler-link= t('statuses.show_more') - .e-content{ lang: status.language } - = prerender_custom_emojis(status_content_format(status), status.emojis) - - - if status.preloadable_poll - = render_poll_component(status) - - - if !status.ordered_media_attachments.empty? - - if status.ordered_media_attachments.first.video? - = render_video_component(status, width: 610, height: 343) - - elsif status.ordered_media_attachments.first.audio? - = render_audio_component(status, width: 610, height: 343) - - else - = render_media_gallery_component(status, height: 343) - - elsif status.preview_card - = render_card_component(status) - - - if !status.in_reply_to_id.nil? && status.in_reply_to_account_id == status.account.id && !hide_show_thread - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__content__read-more-button', target: stream_link_target, rel: 'noopener noreferrer' do - = t 'statuses.show_thread' - - .status__action-bar - %span.status__action-bar-button.icon-button.icon-button--with-counter - - if status.in_reply_to_id.nil? - = material_symbol 'reply' - - else - = material_symbol 'reply_all' - %span.icon-button__counter= obscured_counter status.replies_count - %span.status__action-bar-button.icon-button - - if status.distributable? - = material_symbol 'repeat' - - elsif status.private_visibility? || status.limited_visibility? - = material_symbol 'lock' - - else - = material_symbol 'alternate_email' - %span.status__action-bar-button.icon-button - = material_symbol 'star' diff --git a/app/views/statuses/_status.html.haml b/app/views/statuses/_status.html.haml deleted file mode 100644 index bf51b5ff7d..0000000000 --- a/app/views/statuses/_status.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -.entry - = render (centered ? 'statuses/detailed_status' : 'statuses/simple_status'), status: status.proper, hide_show_thread: false diff --git a/app/views/statuses/embed.html.haml b/app/views/statuses/embed.html.haml index 18d62fd8e3..09d0792ea2 100644 --- a/app/views/statuses/embed.html.haml +++ b/app/views/statuses/embed.html.haml @@ -1,2 +1 @@ -.activity-stream.activity-stream--headless - = render 'status', status: @status, centered: true +#mastodon-status{ data: { props: Oj.dump(default_props.merge(id: @status.id.to_s)) } } diff --git a/config/locales/af.yml b/config/locales/af.yml index 648ec6091d..89ede096e2 100644 --- a/config/locales/af.yml +++ b/config/locales/af.yml @@ -6,7 +6,6 @@ af: hosted_on: Mastodon gehuisves op %{domain} title: Aangaande accounts: - follow: Volg followers: one: Volgeling other: Volgelinge diff --git a/config/locales/an.yml b/config/locales/an.yml index 41eeee4614..589bb39836 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -7,7 +7,6 @@ an: hosted_on: Mastodon alochau en %{domain} title: Sobre accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1410,23 +1409,12 @@ an: edited_at_html: Editau %{date} errors: in_reply_not_found: Lo estau a lo qual intentas responder no existe. - open_in_web: Ubrir en web over_character_limit: Limite de caracters de %{max} superau pin_errors: direct: Las publicacions que son visibles solo pa los usuarios mencionaus no pueden fixar-se limit: Ya has fixau lo numero maximo de publicacions ownership: La publicación d'unatra persona no puede fixar-se reblog: Un boost no puede fixar-se - poll: - total_people: - one: "%{count} persona" - other: "%{count} chent" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Vota - show_more: Amostrar mas - show_thread: Amostrar discusión title: "%{name}: «%{quote}»" visibilities: direct: Directa diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 06cea7ecb3..480feeba2d 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -7,7 +7,6 @@ ar: hosted_on: ماستدون Ù…ÙØ³ØªØ¶Ø§Ù على %{domain} title: عن accounts: - follow: متابَعة followers: few: Ù…ØªØ§Ø¨ÙØ¹ÙˆÙ† many: Ù…ØªØ§Ø¨ÙØ¹ÙˆÙ† @@ -1772,31 +1771,12 @@ ar: edited_at_html: Ø¹ÙØ¯Ù‘Ù„ ÙÙŠ %{date} errors: in_reply_not_found: إنّ المنشور الذي ØªØØ§ÙˆÙ„ الرد عليه غير موجود على ما يبدو. - open_in_web: Ø§ÙØªØ ÙÙŠ الويب over_character_limit: تم تجاوز ØØ¯ الـ %{max} ØØ±Ù Ø§Ù„Ù…Ø³Ù…ÙˆØ Ø¨Ù‡Ø§ pin_errors: direct: لا يمكن تثبيت المنشورات التي يراها Ùقط المتسخدمون المشار إليهم limit: لقد بلغت Ø§Ù„ØØ¯ الأقصى للمنشورات المثبتة ownership: لا يمكن تثبيت منشور نشره شخص آخر reblog: لا يمكن تثبيت إعادة نشر - poll: - total_people: - few: "%{count} أشخاص" - many: "%{count} أشخاص" - one: "%{count} شخص ÙˆØ§ØØ¯" - other: "%{count} شخصا" - two: "%{count} شخصين" - zero: "%{count} شخص" - total_votes: - few: "%{count} أصوات" - many: "%{count} أصوات" - one: صوت ÙˆØ§ØØ¯ %{count} - other: "%{count} صوتا" - two: صوتين %{count} - zero: بدون صوت %{count} - vote: صوّت - show_more: أظهر المزيد - show_thread: اعرض خيط Ø§Ù„Ù…ØØ§Ø¯Ø«Ø© title: '%{name}: "%{quote}"' visibilities: direct: مباشرة diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 70a0ad3bdd..be3441507e 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -800,20 +800,11 @@ ast: default_language: La mesma que la de la interfaz errors: in_reply_not_found: L'artÃculu al que tentes de responder paez que nun esiste. - open_in_web: Abrir na web pin_errors: direct: Nun se puen fixar los artÃculos que son visibles namás pa los usuarios mentaos limit: Yá fixesti'l númberu máximu d'artÃculos ownership: Nun se pue fixar l'artÃculu d'otru perfil reblog: Nun se pue fixar un artÃculu compartÃu - poll: - total_people: - one: "%{count} persona" - other: "%{count} persones" - total_votes: - one: "%{count} votu" - other: "%{count} votos" - show_more: Amosar más title: "%{name}: «%{quote}»" visibilities: direct: Mensaxe direutu diff --git a/config/locales/be.yml b/config/locales/be.yml index 31a31e9e61..48ca5751cc 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -7,7 +7,6 @@ be: hosted_on: Mastodon меÑціцца на %{domain} title: Пра Ð½Ð°Ñ accounts: - follow: ПадпіÑацца followers: few: ПадпіÑчыка many: ПадпіÑчыкаў @@ -1778,27 +1777,12 @@ be: edited_at_html: ÐдрÑдагавана %{date} errors: in_reply_not_found: Здаецца, допіÑ, на Ñкі вы Ñпрабуеце адказаць, не Ñ–Ñнуе. - open_in_web: Ðдчыніць у вÑб-верÑÑ–Ñ– over_character_limit: Ð¿ÐµÑ€Ð°Ð²Ñ‹ÑˆÐ°Ð½Ð°Ñ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць Ñімвалаў у %{max} pin_errors: direct: ДопіÑÑ‹, Ð±Ð°Ñ‡Ð½Ñ‹Ñ Ñ‚Ð¾Ð»ÑŒÐºÑ– згаданым карыÑтальнікам, не могуць быць Ð·Ð°Ð¼Ð°Ñ†Ð°Ð²Ð°Ð½Ñ‹Ñ limit: Ð’Ñ‹ ўжо замацавалі макÑімальную колькаÑць допіÑаў ownership: Ðемагчыма замацаваць чужы Ð´Ð¾Ð¿Ñ–Ñ reblog: Ðемагчыма замацаваць пашырÑнне - poll: - total_people: - few: "%{count} чалавекі" - many: "%{count} чалавек" - one: "%{count} чалавек" - other: "%{count} чалавека" - total_votes: - few: "%{count} галаÑÑ‹" - many: "%{count} галаÑоў" - one: "%{count} голаÑ" - other: "%{count} голаÑу" - vote: ПрагалаÑаваць - show_more: Паказаць больш - show_thread: Паказаць ланцуг title: '%{name}: "%{quote}"' visibilities: direct: ÐÑабіÑта diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 42a626c695..604eeca480 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -7,7 +7,6 @@ bg: hosted_on: Mastodon е разположен на хоÑÑ‚ %{domain} title: ОтноÑно accounts: - follow: ПоÑледване followers: one: ПоÑледовател other: ПоÑледователи @@ -1664,23 +1663,12 @@ bg: edited_at_html: Редактирано на %{date} errors: in_reply_not_found: Изглежда, че публикациÑта, на коÑто Ñе опитвате да отговорите, не ÑъщеÑтвува. - open_in_web: Отвори в уеб over_character_limit: прехвърлен лимит от %{max} Ñимвола pin_errors: direct: Публикациите, които Ñа видими Ñамо за потребители Ñпоменати в Ñ‚ÑÑ…, не могат да бъдат закачани limit: Вече Ñте закачили макÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ð±Ñ€Ð¾Ð¹ публикации ownership: ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð½Ð° нÑкого другиго не може да бъде закачена reblog: Раздуване не може да бъде закачано - poll: - total_people: - one: "%{count} човек" - other: "%{count} души" - total_votes: - one: "%{count} глаÑ" - other: "%{count} глаÑа" - vote: ГлаÑуване - show_more: Покажи повече - show_thread: Показване на нишката title: "%{name}: „%{quote}“" visibilities: direct: Директно diff --git a/config/locales/bn.yml b/config/locales/bn.yml index edbef73ae2..74ff25d754 100644 --- a/config/locales/bn.yml +++ b/config/locales/bn.yml @@ -7,7 +7,6 @@ bn: hosted_on: à¦à¦‡ মাসà§à¦Ÿà¦¾à¦¡à¦¨à¦Ÿà¦¿ আছে %{domain} ঠtitle: পরিচিতি accounts: - follow: যà§à¦•à§à¦¤ followers: one: যà§à¦•à§à¦¤ আছে other: যারা যà§à¦•à§à¦¤ হয়েছে diff --git a/config/locales/br.yml b/config/locales/br.yml index 4ef8fa1a18..f9fbd34adb 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -6,7 +6,6 @@ br: hosted_on: Servijer Mastodon herberc'hiet war %{domain} title: Diwar-benn accounts: - follow: Heuliañ followers: few: Heulier·ez many: Heulier·ez @@ -519,9 +518,6 @@ br: two: "%{count} skeudenn" pin_errors: ownership: N'hallit ket spilhennañ embannadurioù ar re all - poll: - vote: Mouezhiañ - show_more: Diskouez muioc'h visibilities: direct: War-eeun public: Publik diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 63654ae708..d985a2ac42 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -7,7 +7,6 @@ ca: hosted_on: Mastodon allotjat a %{domain} title: Quant a accounts: - follow: Segueix followers: one: Seguidor other: Seguidors @@ -1734,23 +1733,12 @@ ca: edited_at_html: Editat %{date} errors: in_reply_not_found: El tut al qual intentes respondre sembla que no existeix. - open_in_web: Obre en la web over_character_limit: LÃmit de carà cters de %{max} superat pin_errors: direct: Els tuts que només són visibles per als usuaris mencionats no poden ser fixats limit: Ja has fixat el mà xim nombre de tuts ownership: No es pot fixar el tut d'algú altre reblog: No es pot fixar un impuls - poll: - total_people: - one: "%{count} persona" - other: "%{count} persones" - total_votes: - one: "%{count} vot" - other: "%{count} vots" - vote: Vota - show_more: Mostra'n més - show_thread: Mostra el fil title: '%{name}: "%{quote}"' visibilities: direct: Directe diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 3ecef4bb4d..8af3d86388 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -7,7 +7,6 @@ ckb: hosted_on: مەستودۆن میوانداری کراوە Ù„Û• %{domain} title: دەربارە accounts: - follow: شوێن Ú©Û•ÙˆÛ• followers: one: شوێنکەوتوو other: شوێن‌کەوتووان @@ -938,22 +937,11 @@ ckb: other: 'هاشتاگەکانی ڕێگەپێنەدراوەی تێدابوو: %{tags}' errors: in_reply_not_found: ئەو دۆخەی Ú©Û• تۆ Ù‡Û•ÙˆÚµÛŒ وەڵامدانەوەی دەدەیت وادەرناکەوێت Ú©Û• هەبێت. - open_in_web: کردنەوە Ù„Û• وێب over_character_limit: سنووری نووسەی %{max} تێپەڕێنرا pin_errors: limit: تۆ پێشتر زۆرترین ژمارەی توتتی چەسپیوەت هەیە ownership: نووسراوەکانی تر ناتوانرێ بسەلمێت reblog: بەهێزکردن ناتوانرێت بچەسپێ - poll: - total_people: - one: "%{count} کەس" - other: "%{count} خەڵک" - total_votes: - one: "%{count} دەنگ" - other: "%{count} دەنگەکان" - vote: دەنگ - show_more: زیاتر پیشان بدە - show_thread: نیشاندانی ڕشتە visibilities: private: شوێنکەوتوانی تەنها private_long: تەنها بۆ شوێنکەوتوانی پیشان بدە diff --git a/config/locales/co.yml b/config/locales/co.yml index 7c0695a770..b072e5e4ef 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -6,7 +6,6 @@ co: contact_unavailable: Micca dispunibule hosted_on: Mastodon allughjatu nant’à %{domain} accounts: - follow: Siguità followers: one: Abbunatu·a other: Abbunati @@ -922,22 +921,11 @@ co: other: 'cuntene l’hashtag disattivati: %{tags}' errors: in_reply_not_found: U statutu à quellu avete pruvatu di risponde ùn sembra micca esiste. - open_in_web: Apre nant’à u web over_character_limit: site sopr’à a limita di %{max} caratteri pin_errors: limit: Avete digià puntarulatu u numeru massimale di statuti ownership: Pudete puntarulà solu unu di i vostri propii statuti reblog: Ùn pudete micca puntarulà una spartera - poll: - total_people: - one: "%{count} persona" - other: "%{count} persone" - total_votes: - one: "%{count} votu" - other: "%{count} voti" - vote: Vutà - show_more: Vede di più - show_thread: Vede u filu title: '%{name}: "%{quote}"' visibilities: direct: Direttu diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 7d4d2296ca..1000442870 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -7,7 +7,6 @@ cs: hosted_on: Mastodon na doménÄ› %{domain} title: O aplikaci accounts: - follow: Sledovat followers: few: SledujÃcà many: SledujÃcÃch @@ -1721,27 +1720,12 @@ cs: edited_at_html: Upraven %{date} errors: in_reply_not_found: PÅ™ÃspÄ›vek, na který se pokouÅ¡Ãte odpovÄ›dÄ›t, neexistuje. - open_in_web: OtevÅ™Ãt na webu over_character_limit: byl pÅ™ekroÄen limit %{max} znaků pin_errors: direct: PÅ™ÃspÄ›vky viditelné pouze zmÃnÄ›ným uživatelům nelze pÅ™ipnout limit: Už jste si pÅ™ipnuli maximálnà poÄet pÅ™ÃspÄ›vků ownership: Nelze pÅ™ipnout pÅ™ÃspÄ›vek nÄ›koho jiného reblog: Boosty nelze pÅ™ipnout - poll: - total_people: - few: "%{count} lidé" - many: "%{count} lidÃ" - one: "%{count} ÄlovÄ›k" - other: "%{count} lidÃ" - total_votes: - few: "%{count} hlasy" - many: "%{count} hlasů" - one: "%{count} hlas" - other: "%{count} hlasů" - vote: Hlasovat - show_more: Zobrazit vÃce - show_thread: Zobrazit vlákno title: "%{name}: „%{quote}“" visibilities: direct: PÅ™Ãmé diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 2e425bb497..9d3c0c82f3 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -7,7 +7,6 @@ cy: hosted_on: Mastodon wedi ei weinyddu ar %{domain} title: Ynghylch accounts: - follow: Dilyn followers: few: Dilynwyr many: Dilynwyr @@ -1860,31 +1859,12 @@ cy: edited_at_html: Wedi'i olygu %{date} errors: in_reply_not_found: Nid yw'n ymddangos bod y postiad rydych chi'n ceisio ei ateb yn bodoli. - open_in_web: Agor yn y we over_character_limit: wedi mynd y tu hwnt i'r terfyn nodau o %{max} pin_errors: direct: Nid oes modd pinio postiadau sy'n weladwy i ddefnyddwyr a grybwyllwyd yn unig limit: Rydych chi eisoes wedi pinio uchafswm nifer y postiadau ownership: Nid oes modd pinio postiad rhywun arall reblog: Nid oes modd pinio hwb - poll: - total_people: - few: "%{count} person" - many: "%{count} person" - one: "%{count} berson" - other: "%{count} person" - two: "%{count} person" - zero: "%{count} o bersonau" - total_votes: - few: "%{count} pleidlais" - many: "%{count} pleidlais" - one: "%{count} bleidlais" - other: "%{count} pleidlais" - two: "%{count} pleidlais" - zero: "%{count} o bleidleisiau" - vote: Pleidlais - show_more: Dangos mwy - show_thread: Dangos edefyn title: '%{name}: "%{quote}"' visibilities: direct: Uniongyrchol diff --git a/config/locales/da.yml b/config/locales/da.yml index 731c1f0b40..6f781742a8 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -7,7 +7,6 @@ da: hosted_on: Mastodon hostet pÃ¥ %{domain} title: Om accounts: - follow: Følg followers: one: Følger other: tilhængere @@ -1740,23 +1739,12 @@ da: edited_at_html: Redigeret %{date} errors: in_reply_not_found: Indlægget, der forsøges besvaret, ser ikke ud til at eksistere. - open_in_web: Ã…bn i webbrowser over_character_limit: grænsen pÃ¥ %{max} tegn overskredet pin_errors: direct: Indlæg, som kun kan ses af omtalte brugere, kan ikke fastgøres limit: Maksimalt antal indlæg allerede fastgjort ownership: Andres indlæg kan ikke fastgøres reblog: Et boost kan ikke fastgøres - poll: - total_people: - one: "%{count} person" - other: "%{count} personer" - total_votes: - one: "%{count} stemme" - other: "%{count} stemmer" - vote: Stem - show_more: Vis flere - show_thread: Vis trÃ¥d title: '%{name}: "%{quote}"' visibilities: direct: Direkte diff --git a/config/locales/de.yml b/config/locales/de.yml index cc049c5903..040ddaaf69 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -7,7 +7,6 @@ de: hosted_on: Mastodon, gehostet auf %{domain} title: Über accounts: - follow: Folgen followers: one: Follower other: Follower @@ -1740,23 +1739,12 @@ de: edited_at_html: 'Bearbeitet: %{date}' errors: in_reply_not_found: Der Beitrag, auf den du antworten möchtest, scheint nicht zu existieren. - open_in_web: Im Webinterface öffnen over_character_limit: Begrenzung von %{max} Zeichen überschritten pin_errors: direct: Beiträge, die nur für erwähnte Profile sichtbar sind, können nicht angeheftet werden limit: Du hast bereits die maximale Anzahl an Beiträgen angeheftet ownership: Du kannst nur eigene Beiträge anheften reblog: Du kannst keine geteilten Beiträge anheften - poll: - total_people: - one: "%{count} Stimme" - other: "%{count} Stimmen" - total_votes: - one: "%{count} Stimme" - other: "%{count} Stimmen" - vote: Abstimmen - show_more: Mehr anzeigen - show_thread: Thread anzeigen title: "%{name}: „%{quote}“" visibilities: direct: Direktnachricht diff --git a/config/locales/el.yml b/config/locales/el.yml index 3cb9075c38..1f408e26ea 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -7,7 +7,6 @@ el: hosted_on: Το Mastodon φιλοξενείται στο %{domain} title: Σχετικά accounts: - follow: ΑκολοÏθησε followers: one: Ακόλουθος other: Ακόλουθοι @@ -1636,23 +1635,12 @@ el: edited_at_html: ΕπεξεÏγάστηκε στις %{date} errors: in_reply_not_found: Η ανάÏτηση στην οποία Ï€Ïοσπαθείς να απαντήσεις δεν φαίνεται να υπάÏχει. - open_in_web: Άνοιγμα στο διαδίκτυο over_character_limit: Ï…Ï€ÎÏβαση μÎγιστου οÏίου %{max} χαÏακτήÏων pin_errors: direct: ΑναÏτήσεις που είναι οÏατÎÏ‚ μόνο στους αναφεÏόμενους χÏήστες δεν μποÏοÏν να καÏφιτσωθοÏν limit: Έχεις ήδη καÏφιτσώσει το μÎγιστο αÏιθμό επιτÏεπτών αναÏτήσεων ownership: Δεν μποÏείς να καÏφιτσώσεις ανάÏτηση κάποιου άλλου reblog: Οι ενισχÏσεις δεν καÏφιτσώνονται - poll: - total_people: - one: "%{count} άτομο" - other: "%{count} άτομα" - total_votes: - one: "%{count} ψήφος" - other: "%{count} ψήφοι" - vote: Ψήφισε - show_more: Δείξε πεÏισσότεÏα - show_thread: Εμφάνιση νήματος title: '%{name}: "%{quote}"' visibilities: direct: Άμεση diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index dc07dcff0b..56255f5d7a 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -7,7 +7,6 @@ en-GB: hosted_on: Mastodon hosted on %{domain} title: About accounts: - follow: Follow followers: one: Follower other: Followers @@ -1740,23 +1739,12 @@ en-GB: edited_at_html: Edited %{date} errors: in_reply_not_found: The post you are trying to reply to does not appear to exist. - open_in_web: Open in web over_character_limit: character limit of %{max} exceeded pin_errors: direct: Posts that are only visible to mentioned users cannot be pinned limit: You have already pinned the maximum number of posts ownership: Someone else's post cannot be pinned reblog: A boost cannot be pinned - poll: - total_people: - one: "%{count} person" - other: "%{count} people" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Vote - show_more: Show more - show_thread: Show thread title: '%{name}: "%{quote}"' visibilities: direct: Direct diff --git a/config/locales/en.yml b/config/locales/en.yml index 05300acea5..b1c100da0c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -7,7 +7,6 @@ en: hosted_on: Mastodon hosted on %{domain} title: About accounts: - follow: Follow followers: one: Follower other: Followers @@ -1741,23 +1740,12 @@ en: edited_at_html: Edited %{date} errors: in_reply_not_found: The post you are trying to reply to does not appear to exist. - open_in_web: Open in web over_character_limit: character limit of %{max} exceeded pin_errors: direct: Posts that are only visible to mentioned users cannot be pinned limit: You have already pinned the maximum number of posts ownership: Someone else's post cannot be pinned reblog: A boost cannot be pinned - poll: - total_people: - one: "%{count} person" - other: "%{count} people" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Vote - show_more: Show more - show_thread: Show thread title: '%{name}: "%{quote}"' visibilities: direct: Direct diff --git a/config/locales/eo.yml b/config/locales/eo.yml index c1873c2f24..46c6cbcf86 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -7,7 +7,6 @@ eo: hosted_on: "%{domain} estas nodo de Mastodon" title: Pri accounts: - follow: Sekvi followers: one: Sekvanto other: Sekvantoj @@ -1553,23 +1552,12 @@ eo: edited_at_html: Redaktis je %{date} errors: in_reply_not_found: MesaÄo kiun vi provas respondi Åajnas ne ekzisti. - open_in_web: Malfermi retumile over_character_limit: limo de %{max} signoj transpasita pin_errors: direct: MesaÄoj kiu videbla nun al la uzantoj ne povas alpinglitis limit: Vi jam atingis la maksimuman nombron de alpinglitaj mesaÄoj ownership: MesaÄo de iu alia ne povas esti alpinglita reblog: Diskonigo ne povas esti alpinglita - poll: - total_people: - one: "%{count} persono" - other: "%{count} personoj" - total_votes: - one: "%{count} voĉdono" - other: "%{count} voĉdonoj" - vote: Voĉdoni - show_more: Montri pli - show_thread: Montri la mesaÄaron title: "%{name}: “%{quote}â€" visibilities: direct: Rekta diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 63d2adc47c..4d60d080a2 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -7,7 +7,6 @@ es-AR: hosted_on: Mastodon alojado en %{domain} title: Información accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1740,23 +1739,12 @@ es-AR: edited_at_html: Editado el %{date} errors: in_reply_not_found: El mensaje al que intentás responder no existe. - open_in_web: Abrir en la web over_character_limit: se excedió el lÃmite de %{max} caracteres pin_errors: direct: Los mensajes que sólo son visibles para los usuarios mencionados no pueden ser fijados limit: Ya fijaste el número máximo de mensajes ownership: No se puede fijar el mensaje de otra cuenta reblog: No se puede fijar una adhesión - poll: - total_people: - one: "%{count} persona" - other: "%{count} personas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Votar - show_more: Mostrar más - show_thread: Mostrar hilo title: '%{name}: "%{quote}"' visibilities: direct: Directo diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 84663aa895..050388c180 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -7,7 +7,6 @@ es-MX: hosted_on: Mastodon alojado en %{domain} title: Acerca de accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1730,23 +1729,12 @@ es-MX: edited_at_html: Editado %{date} errors: in_reply_not_found: El estado al que intentas responder no existe. - open_in_web: Abrir en web over_character_limit: LÃmite de caracteres de %{max} superado pin_errors: direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse limit: Ya has fijado el número máximo de publicaciones ownership: El toot de alguien más no puede fijarse reblog: Un boost no puede fijarse - poll: - total_people: - one: persona %{count} - other: "%{count} gente" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Vota - show_more: Mostrar más - show_thread: Mostrar discusión title: "%{name}: «%{quote}»" visibilities: direct: Directa diff --git a/config/locales/es.yml b/config/locales/es.yml index e245dde5d6..81a547ad88 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -7,7 +7,6 @@ es: hosted_on: Mastodon alojado en %{domain} title: Acerca de accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1730,23 +1729,12 @@ es: edited_at_html: Editado %{date} errors: in_reply_not_found: La publicación a la que intentas responder no existe. - open_in_web: Abrir en web over_character_limit: LÃmite de caracteres de %{max} superado pin_errors: direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse limit: Ya has fijado el número máximo de publicaciones ownership: La publicación de otra persona no puede fijarse reblog: Un boost no puede fijarse - poll: - total_people: - one: "%{count} persona" - other: "%{count} personas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Vota - show_more: Mostrar más - show_thread: Mostrar discusión title: "%{name}: «%{quote}»" visibilities: direct: Directa diff --git a/config/locales/et.yml b/config/locales/et.yml index 88d48fefcb..d8cdbf4143 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -7,7 +7,6 @@ et: hosted_on: Mastodon majutatud %{domain}-is title: Teave accounts: - follow: Jälgi followers: one: Jälgija other: Jälgijaid @@ -1701,23 +1700,12 @@ et: edited_at_html: Muudetud %{date} errors: in_reply_not_found: Postitus, millele üritad vastata, ei näi enam eksisteerivat. - open_in_web: Ava veebis over_character_limit: tähtmärkide limiit %{max} ületatud pin_errors: direct: Ei saa kinnitada postitusi, mis on nähtavad vaid mainitud kasutajatele limit: Kinnitatud on juba maksimaalne arv postitusi ownership: Kellegi teise postitust ei saa kinnitada reblog: Jagamist ei saa kinnitada - poll: - total_people: - one: "%{count} inimene" - other: "%{count} inimest" - total_votes: - one: "%{count} hääl" - other: "%{count} häält" - vote: Hääleta - show_more: Näita rohkem - show_thread: Kuva lõim title: '%{name}: "%{quote}"' visibilities: direct: Otsene diff --git a/config/locales/eu.yml b/config/locales/eu.yml index e5ae0ab79d..6260033990 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -7,7 +7,6 @@ eu: hosted_on: Mastodon %{domain} domeinuan ostatatua title: Honi buruz accounts: - follow: Jarraitu followers: one: Jarraitzaile other: jarraitzaile @@ -1639,23 +1638,12 @@ eu: edited_at_html: Editatua %{date} errors: in_reply_not_found: Erantzuten saiatu zaren bidalketa antza ez da existitzen. - open_in_web: Ireki web-ean over_character_limit: "%{max}eko karaktere muga gaindituta" pin_errors: direct: Aipatutako erabiltzaileentzat soilik ikusgai dauden bidalketak ezin dira finkatu limit: Gehienez finkatu daitekeen bidalketa kopurua finkatu duzu jada ownership: Ezin duzu beste norbaiten bidalketa bat finkatu reblog: Bultzada bat ezin da finkatu - poll: - total_people: - one: pertsona %{count} - other: "%{count} pertsona" - total_votes: - one: Boto %{count} - other: "%{count} boto" - vote: Bozkatu - show_more: Erakutsi gehiago - show_thread: Erakutsi haria title: '%{name}: "%{quote}"' visibilities: direct: Zuzena diff --git a/config/locales/fa.yml b/config/locales/fa.yml index ce8a61e3f0..f2fe134e32 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -7,7 +7,6 @@ fa: hosted_on: ماستودون، میزبانی‌شده روی %{domain} title: درباره accounts: - follow: پیگیری followers: one: پیگیر other: پیگیر @@ -1404,23 +1403,12 @@ fa: edited_at_html: ویراسته در %{date} errors: in_reply_not_found: به نظر نمی‌رسد وضعیتی Ú©Ù‡ می‌خواهید به آن پاسخ دهید، وجود داشته باشد. - open_in_web: گشودن در وب over_character_limit: از ØØ¯ مجاز %{max} ØØ±Ù ÙØ±Ø§ØªØ± Ø±ÙØªÛŒØ¯ pin_errors: direct: ÙØ±Ø³ØªÙ‡â€ŒÙ‡Ø§ÛŒÛŒ Ú©Ù‡ Ùقط برای کاربران اشاره شده نمایانند نمی‌توانند سنجاق شوند limit: از این بیشتر نمی‌شود نوشته‌های ثابت داشت ownership: نوشته‌های دیگران را نمی‌توان ثابت کرد reblog: تقویت نمی‌تواند سنجاق شود - poll: - total_people: - one: "%{count} Ù†ÙØ±" - other: "%{count} Ù†ÙØ±" - total_votes: - one: "%{count} رأی" - other: "%{count} رأی" - vote: رأی - show_more: نمایش - show_thread: نمایش رشته title: "%{name}: «%{quote}»" visibilities: direct: مستقیم diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 5c39346a9f..30837b6003 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -7,7 +7,6 @@ fi: hosted_on: Mastodon palvelimella %{domain} title: Tietoja accounts: - follow: Seuraa followers: one: seuraaja other: seuraajaa @@ -1738,23 +1737,12 @@ fi: edited_at_html: Muokattu %{date} errors: in_reply_not_found: Julkaisua, johon yrität vastata, ei näytä olevan olemassa. - open_in_web: Avaa selaimessa over_character_limit: merkkimäärän rajoitus %{max} ylitetty pin_errors: direct: Vain mainituille käyttäjille näkyviä julkaisuja ei voi kiinnittää limit: Olet jo kiinnittänyt enimmäismäärän julkaisuja ownership: Muiden julkaisuja ei voi kiinnittää reblog: Tehostusta ei voi kiinnittää - poll: - total_people: - one: "%{count} käyttäjä" - other: "%{count} käyttäjää" - total_votes: - one: "%{count} ääni" - other: "%{count} ääntä" - vote: Äänestä - show_more: Näytä lisää - show_thread: Näytä ketju title: "%{name}: â€%{quote}â€" visibilities: direct: Suoraan diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 6d7b38e18a..d5127b4ad3 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -7,7 +7,6 @@ fo: hosted_on: Mastodon hýst á %{domain} title: Um accounts: - follow: Fylg followers: one: Fylgjari other: Fylgjarar @@ -1740,23 +1739,12 @@ fo: edited_at_html: Rættað %{date} errors: in_reply_not_found: Posturin, sum tú roynir at svara, sýnist ikki at finnast. - open_in_web: Lat upp á vevinum over_character_limit: mesta tal av teknum, %{max}, rokkið pin_errors: direct: Postar, sum einans eru sjónligir hjá nevndum brúkarum, kunnu ikki festast limit: Tú hevur longu fest loyvda talið av postum ownership: Postar hjá øðrum kunnu ikki festast reblog: Ein stimbran kann ikki festast - poll: - total_people: - one: "%{count} fólk" - other: "%{count} fólk" - total_votes: - one: "%{count} atkvøða" - other: "%{count} atkvøður" - vote: Atkvøð - show_more: VÃs meira - show_thread: VÃs tráð title: '%{name}: "%{quote}"' visibilities: direct: Beinleiðis diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index 27e09d1f9c..a47d7447a1 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -7,7 +7,6 @@ fr-CA: hosted_on: Serveur Mastodon hébergé sur %{domain} title: À propos accounts: - follow: Suivre followers: one: Abonné·e other: Abonné·e·s @@ -1711,23 +1710,12 @@ fr-CA: edited_at_html: Édité le %{date} errors: in_reply_not_found: Le message auquel vous essayez de répondre ne semble pas exister. - open_in_web: Ouvrir sur le web over_character_limit: limite de %{max} caractères dépassée pin_errors: direct: Les messages qui ne sont visibles que pour les utilisateur·rice·s mentionné·e·s ne peuvent pas être épinglés limit: Vous avez déjà épinglé le nombre maximum de messages ownership: Vous ne pouvez pas épingler un message ne vous appartenant pas reblog: Un partage ne peut pas être épinglé - poll: - total_people: - one: "%{count} personne" - other: "%{count} personnes" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Voter - show_more: Déplier - show_thread: Afficher le fil de discussion title: "%{name} : « %{quote} »" visibilities: direct: Direct diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 055b50900c..b2c692ea6f 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -7,7 +7,6 @@ fr: hosted_on: Serveur Mastodon hébergé sur %{domain} title: À propos accounts: - follow: Suivre followers: one: Abonné·e other: Abonné·e·s @@ -1711,23 +1710,12 @@ fr: edited_at_html: Modifié le %{date} errors: in_reply_not_found: Le message auquel vous essayez de répondre ne semble pas exister. - open_in_web: Ouvrir sur le web over_character_limit: limite de %{max} caractères dépassée pin_errors: direct: Les messages qui ne sont visibles que pour les utilisateur·rice·s mentionné·e·s ne peuvent pas être épinglés limit: Vous avez déjà épinglé le nombre maximum de messages ownership: Vous ne pouvez pas épingler un message ne vous appartenant pas reblog: Un partage ne peut pas être épinglé - poll: - total_people: - one: "%{count} personne" - other: "%{count} personnes" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Voter - show_more: Déplier - show_thread: Afficher le fil de discussion title: "%{name} : « %{quote} »" visibilities: direct: Direct diff --git a/config/locales/fy.yml b/config/locales/fy.yml index 27fcaf3af7..6afdecd556 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -7,7 +7,6 @@ fy: hosted_on: Mastodon op %{domain} title: Oer accounts: - follow: Folgje followers: one: Folger other: Folgers @@ -1730,23 +1729,12 @@ fy: edited_at_html: Bewurke op %{date} errors: in_reply_not_found: It berjocht wêrop jo probearje te reagearjen liket net te bestean. - open_in_web: Yn de webapp iepenje over_character_limit: Oer de limyt fan %{max} tekens pin_errors: direct: Berjochten dy’t allinnich sichtber binne foar fermelde brûkers kinne net fêstset wurde limit: Jo hawwe it maksimaal tal berjochten al fêstmakke ownership: In berjocht fan in oar kin net fêstmakke wurde reblog: In boost kin net fêstset wurde - poll: - total_people: - one: "%{count} persoan" - other: "%{count} persoanen" - total_votes: - one: "%{count} stim" - other: "%{count} stimmen" - vote: Stimme - show_more: Mear toane - show_thread: Petear toane title: '%{name}: "%{quote}"' visibilities: direct: Direkt diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 870f79cba9..09d5f7ae18 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -7,7 +7,6 @@ ga: hosted_on: Mastodon arna óstáil ar %{domain} title: Maidir le accounts: - follow: Lean followers: few: Leantóirà many: Leantóirà @@ -1823,29 +1822,12 @@ ga: edited_at_html: "%{date} curtha in eagar" errors: in_reply_not_found: Is cosúil nach ann don phostáil a bhfuil tú ag iarraidh freagra a thabhairt air. - open_in_web: Oscail i ngréasán over_character_limit: teorainn carachtar %{max} sáraithe pin_errors: direct: Nà féidir postálacha nach bhfuil le feiceáil ach ag úsáideoirà luaite a phinnáil limit: Tá uaslÃon na bpostálacha pinn agat cheana féin ownership: Nà féidir postáil duine éigin eile a phionnáil reblog: Nà féidir treisiú a phinnáil - poll: - total_people: - few: "%{count} daoine" - many: "%{count} daoine" - one: "%{count} duine" - other: "%{count} daoine" - two: "%{count} daoine" - total_votes: - few: "%{count} vótaÃ" - many: "%{count} vótaÃ" - one: "%{count} vóta" - other: "%{count} vótaÃ" - two: "%{count} vótaÃ" - vote: Vótáil - show_more: Taispeáin nÃos mó - show_thread: Taispeáin snáithe title: '%{name}: "%{quote}"' visibilities: direct: DÃreach diff --git a/config/locales/gd.yml b/config/locales/gd.yml index dda918d15c..3f30d37823 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -7,7 +7,6 @@ gd: hosted_on: Mastodon ’ga òstadh air %{domain} title: Mu dhèidhinn accounts: - follow: Lean followers: few: Luchd-leantainn one: Neach-leantainn @@ -1793,27 +1792,12 @@ gd: edited_at_html: Air a dheasachadh %{date} errors: in_reply_not_found: Tha coltas nach eil am post dhan a tha thu airson freagairt ann. - open_in_web: Fosgail air an lìon over_character_limit: chaidh thu thar crìoch charactaran de %{max} pin_errors: direct: Chan urrainn dhut post a phrìneachadh nach fhaic ach na cleachdaichean le iomradh orra limit: Tha an à ireamh as motha de phostaichean prìnichte agad a tha ceadaichte ownership: Chan urrainn dhut post cà ich a phrìneachadh reblog: Chan urrainn dhut brosnachadh a phrìneachadh - poll: - total_people: - few: "%{count} daoine" - one: "%{count} neach" - other: "%{count} duine" - two: "%{count} neach" - total_votes: - few: "%{count} bhòtaichean" - one: "%{count} bhòt" - other: "%{count} bhòt" - two: "%{count} bhòt" - vote: Bhòt - show_more: Seall barrachd dheth - show_thread: Seall an snà ithlean title: "%{name}: “%{quote}â€" visibilities: direct: Dìreach diff --git a/config/locales/gl.yml b/config/locales/gl.yml index d275b844fd..58fd2d9bab 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -7,7 +7,6 @@ gl: hosted_on: Mastodon aloxado en %{domain} title: Sobre accounts: - follow: Seguir followers: one: Seguidora other: Seguidoras @@ -1740,23 +1739,12 @@ gl: edited_at_html: Editado %{date} errors: in_reply_not_found: A publicación á que tentas responder semella que non existe. - open_in_web: Abrir na web over_character_limit: Excedeu o lÃmite de caracteres %{max} pin_errors: direct: As publicacións que só son visibles para as usuarias mencionadas non se poden fixar limit: Xa fixaches o número máximo permitido de publicacións ownership: Non podes fixar a publicación doutra usuaria reblog: Non se poden fixar as mensaxes promovidas - poll: - total_people: - one: "%{count} persoa" - other: "%{count} persoas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Votar - show_more: Mostrar máis - show_thread: Amosar fÃo title: '%{name}: "%{quote}"' visibilities: direct: Directa diff --git a/config/locales/he.yml b/config/locales/he.yml index 341e2bf023..7a2d0a1d98 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -7,7 +7,6 @@ he: hosted_on: מסטודון שיושב בכתובת %{domain} title: ×ודות accounts: - follow: לעקוב followers: many: ×¢×•×§×‘×™× one: עוקב @@ -1800,27 +1799,12 @@ he: edited_at_html: × ×¢×¨×š ב-%{date} errors: in_reply_not_found: × ×¨××” שההודעה ש×ת/×” ×ž× ×¡×” להגיב לה ×œ× ×§×™×™×ž×ª. - open_in_web: פתח ברשת over_character_limit: חריגה מגבול ×”×ª×•×•×™× ×©×œ %{max} pin_errors: direct: ×œ× × ×™×ª×Ÿ לקבע הודעות ×©× ×¨×ותן מוגבלת ×œ×ž×›×•×ª×‘×™× ×‘×œ×‘×“ limit: הגעת למספר המירבי של ההודעות המוצמדות ownership: הודעות של ××—×¨×™× ×œ× ×™×›×•×œ×•×ª להיות מוצמדות reblog: ×ין ×פשרות להצמיד ×”×“×”×•×“×™× - poll: - total_people: - many: "%{count} ×× ×©×™×" - one: ×יש/×” %{count} - other: "%{count} ×× ×©×™×" - two: "%{count} ×× ×©×™×" - total_votes: - many: "%{count} קולות" - one: קול %{count} - other: "%{count} קולות" - two: "%{count} קולות" - vote: הצבעה - show_more: עוד - show_thread: הצג שרשור title: '%{name}: "%{quote}"' visibilities: direct: ישיר diff --git a/config/locales/hi.yml b/config/locales/hi.yml index 60b500c7ec..37df2afe1a 100644 --- a/config/locales/hi.yml +++ b/config/locales/hi.yml @@ -5,7 +5,6 @@ hi: contact_unavailable: लागू नहीं है title: के बारे में accounts: - follow: अनà¥à¤¸à¤°à¥‡ following: फ़ॉलो कर रहे हैं instance_actor_flash: यह खाता आà¤à¤¾à¤¸à¥€ है जो सरà¥à¤µà¤° को दिखाने के लिये है और ये किसी वà¥à¤¯à¤•à¥à¤¤à¤¿à¤•ा पà¥à¤°à¤¤à¤¿à¤¨à¤¿à¤§à¤¿à¤¤à¥à¤µ नहि करता। यह सिरà¥à¤« देखरेख के हेतॠसे कारà¥à¤¯à¤°à¤¤ है और इसको निलंबित करने कि आवशà¥à¤¯à¤•ता नहि है। last_active: आखिरि बार इस वकà¥à¤¤ सकà¥à¤°à¤¿à¤¯ थे diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 6a67ea0129..7dacf20077 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -5,7 +5,6 @@ hr: contact_missing: Nije postavljeno title: O aplikaciji accounts: - follow: Prati following: Praćenih last_active: posljednja aktivnost nothing_here: Ovdje nema niÄeg! @@ -215,20 +214,7 @@ hr: statuses_cleanup: Automatsko brisanje postova two_factor_authentication: Dvofaktorska autentifikacija statuses: - open_in_web: Otvori na webu over_character_limit: prijeÄ‘eno je ograniÄenje od %{max} znakova - poll: - total_people: - few: "%{count} osobe" - one: "%{count} osoba" - other: "%{count} ljudi" - total_votes: - few: "%{count} glasa" - one: "%{count} glas" - other: "%{count} glasova" - vote: Glasaj - show_more: Prikaži viÅ¡e - show_thread: Prikaži nit visibilities: private: Samo pratitelji public: Javno diff --git a/config/locales/hu.yml b/config/locales/hu.yml index e29472f8d8..10c7506b01 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -7,7 +7,6 @@ hu: hosted_on: "%{domain} Mastodon-kiszolgáló" title: Névjegy accounts: - follow: Követés followers: one: KövetÅ‘ other: KövetÅ‘ @@ -1740,23 +1739,12 @@ hu: edited_at_html: 'Szerkesztve: %{date}' errors: in_reply_not_found: Már nem létezik az a bejegyzés, melyre válaszolni szeretnél. - open_in_web: Megnyitás a weben over_character_limit: túllépted a maximális %{max} karakteres keretet pin_errors: direct: A csak a megemlÃtett felhasználók számára látható bejegyzések nem tűzhetÅ‘k ki limit: Elérted a kitűzhetÅ‘ bejegyzések maximális számát ownership: Nem tűzheted ki valaki más bejegyzését reblog: Megtolt bejegyzést nem tudsz kitűzni - poll: - total_people: - one: "%{count} személy" - other: "%{count} személy" - total_votes: - one: "%{count} szavazat" - other: "%{count} szavazat" - vote: Szavazás - show_more: Több megjelenÃtése - show_thread: Szál mutatása title: "%{name}: „%{quote}â€" visibilities: direct: Közvetlen diff --git a/config/locales/hy.yml b/config/locales/hy.yml index c7128a2a46..80dbc77991 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -7,7 +7,6 @@ hy: hosted_on: Õ„Õ¡Õ½Õ¿Õ¸Õ¤Õ¸Õ¶Õ¨ Õ¿Õ¥Õ²Õ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ¡Õ® Õ§ %{domain}Õ¸Ö‚Õ´ title: Õ„Õ¡Õ½Õ«Õ¶ accounts: - follow: Õ€Õ¥Õ¿Ö‡Õ¥Õ¬ followers: one: Õ€Õ¥Õ¿Õ¥Ö‚Õ¸Ö€Õ¤ other: Õ€Õ¥Õ¿Ö‡Õ¸Ö€Õ¤Õ¶Õ¥Ö€ @@ -782,18 +781,7 @@ hy: other: "%{count} Õ¾Õ«Õ¤Õ¥Õ¸" content_warning: Õ†Õ¡ÕÕ¡Õ¦Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´Ö‰ %{warning} edited_at_html: Ô½Õ´Õ¢Õ¡Õ£Ö€Õ¸Ö‚Õ¡Õ®Õ %{date} - open_in_web: Ô²Õ¡ÖÕ¥Õ¬ Õ¾Õ§Õ¢Õ¸Ö‚Õ´ over_character_limit: "%{max} Õ¶Õ«Õ·Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¨ Õ£Õ¥Ö€Õ¡Õ¦Õ¡Õ¶ÖÕ¸Ö‚Õ¡Õ® Õ§" - poll: - total_people: - one: "%{count} Õ´Õ¡Ö€Õ¤" - other: "%{count} Õ´Õ¡Ö€Õ¤Õ«Õ¯" - total_votes: - one: "%{count} Õ±Õ¡ÕµÕ¶" - other: "%{count} Õ±Õ¡ÕµÕ¶Õ¥Ö€" - vote: Õ”Õ¸Ö‚Õ§Õ¡Ö€Õ¯Õ¥Õ¬ - show_more: Ô±Ö‚Õ¥Õ¬Õ«Õ¶ - show_thread: Ô²Õ¡ÖÕ¥Õ¬ Õ·Õ²Õ©Õ¡Õ¶ title: '%{name}: "%{quote}"' visibilities: direct: Õ€Õ¡Õ½ÖÕ§Õ¡Õ£Ö€Õ¸Ö‚Õ¡Õ® diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 87789562fd..957bae3991 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -7,7 +7,6 @@ ia: hosted_on: Mastodon albergate sur %{domain} title: A proposito accounts: - follow: Sequer followers: one: Sequitor other: Sequitores @@ -1723,23 +1722,12 @@ ia: edited_at_html: Modificate le %{date} errors: in_reply_not_found: Le message a que tu tenta responder non pare exister. - open_in_web: Aperir sur le web over_character_limit: limite de characteres de %{max} excedite pin_errors: direct: Messages que es solo visibile a usatores mentionate non pote esser appunctate limit: Tu ha jam appunctate le maxime numero de messages ownership: Le message de alcuno altere non pote esser appunctate reblog: Un impulso non pote esser affixate - poll: - total_people: - one: "%{count} persona" - other: "%{count} personas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Votar - show_more: Monstrar plus - show_thread: Monstrar discussion title: "%{name}: “%{quote}â€" visibilities: direct: Directe diff --git a/config/locales/id.yml b/config/locales/id.yml index 575daddca6..222d2b5680 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -7,7 +7,6 @@ id: hosted_on: Mastodon dihosting di %{domain} title: Tentang accounts: - follow: Ikuti followers: other: Pengikut following: Mengikuti @@ -1378,21 +1377,12 @@ id: edited_at_html: Diedit %{date} errors: in_reply_not_found: Status yang ingin Anda balas sudah tidak ada. - open_in_web: Buka di web over_character_limit: melebihi %{max} karakter pin_errors: direct: Kiriman yang hanya terlihat oleh pengguna yang disebutkan tidak dapat disematkan limit: Anda sudah mencapai jumlah maksimum kiriman yang dapat disematkan ownership: Kiriman orang lain tidak bisa disematkan reblog: Boost tidak bisa disematkan - poll: - total_people: - other: "%{count} orang" - total_votes: - other: "%{count} memilih" - vote: Pilih - show_more: Tampilkan selengkapnya - show_thread: Tampilkan utas title: '%{name}: "%{quote}"' visibilities: direct: Langsung diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 1529ea04b8..6a79686f48 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -7,7 +7,6 @@ ie: hosted_on: Mastodon logiat che %{domain} title: Pri accounts: - follow: Sequer followers: one: Sequitor other: Sequitores @@ -1637,23 +1636,12 @@ ie: edited_at_html: Modificat ye %{date} errors: in_reply_not_found: Li posta a quel tu prova responder ne sembla exister. - open_in_web: Aperter in web over_character_limit: lÃmite de carácteres de %{max} transpassat pin_errors: direct: On ne posse pinglar postas queles es visibil solmen a mentionat usatores limit: Tu ja ha pinglat li maxim númere de postas ownership: On ne posse pinglar li posta de un altri person reblog: On ne posse pinglar un boost - poll: - total_people: - one: "%{count} person" - other: "%{count} persones" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Votar - show_more: Monstrar plu - show_thread: Monstrar fil title: "%{name}: «%{quote}»" visibilities: direct: Direct diff --git a/config/locales/io.yml b/config/locales/io.yml index d1b9aef3e5..dbbe228e72 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -7,7 +7,6 @@ io: hosted_on: Mastodon hostigesas che %{domain} title: Pri co accounts: - follow: Sequar followers: one: Sequanto other: Sequanti @@ -1590,23 +1589,12 @@ io: edited_at_html: Modifikesis ye %{date} errors: in_reply_not_found: Posto quon vu probas respondar semblas ne existas. - open_in_web: Apertar retnavigile over_character_limit: limito de %{max} signi ecesita pin_errors: direct: Posti quo povas videsar nur mencionita uzanti ne povas pinglagesar limit: Vu ja pinglagis maxima posti ownership: Posto di altra persono ne povas pinglagesar reblog: Repeto ne povas pinglizesar - poll: - total_people: - one: "%{count} persono" - other: "%{count} personi" - total_votes: - one: "%{count} voto" - other: "%{count} voti" - vote: Votez - show_more: Montrar plue - show_thread: Montrez postaro title: '%{name}: "%{quote}"' visibilities: direct: Direta diff --git a/config/locales/is.yml b/config/locales/is.yml index 5fa147e8db..78dfd6048f 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -7,7 +7,6 @@ is: hosted_on: Mastodon hýst á %{domain} title: Um hugbúnaðinn accounts: - follow: Fylgjast með followers: one: fylgjandi other: fylgjendur @@ -1744,23 +1743,12 @@ is: edited_at_html: Breytt %{date} errors: in_reply_not_found: Færslan sem þú ert að reyna að svara að er lÃklega ekki til. - open_in_web: Opna à vafra over_character_limit: hámarksfjölda stafa (%{max}) náð pin_errors: direct: Ekki er hægt að festa færslur sem einungis eru sýnilegar þeim notendum sem minnst er á limit: Þú hefur þegar fest leyfilegan hámarksfjölda færslna ownership: Færslur frá einhverjum öðrum er ekki hægt að festa reblog: Ekki er hægt að festa endurbirtingu - poll: - total_people: - one: "%{count} aðili" - other: "%{count} aðilar" - total_votes: - one: "%{count} atkvæði" - other: "%{count} atkvæði" - vote: Greiða atkvæði - show_more: Sýna meira - show_thread: Birta þráð title: "%{name}: „%{quote}‟" visibilities: direct: Beint diff --git a/config/locales/it.yml b/config/locales/it.yml index 7de24fe259..792add14e3 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -7,7 +7,6 @@ it: hosted_on: Mastodon ospitato su %{domain} title: Info accounts: - follow: Segui followers: one: Seguace other: Seguaci @@ -1742,23 +1741,12 @@ it: edited_at_html: Modificato il %{date} errors: in_reply_not_found: Il post a cui stai tentando di rispondere non sembra esistere. - open_in_web: Apri sul Web over_character_limit: Limite caratteri superato di %{max} pin_errors: direct: I messaggi visibili solo agli utenti citati non possono essere fissati in cima limit: Hai già fissato in cima il massimo numero di post ownership: Non puoi fissare in cima un post di qualcun altro reblog: Un toot condiviso non può essere fissato in cima - poll: - total_people: - one: "%{count} persona" - other: "%{count} persone" - total_votes: - one: "%{count} voto" - other: "%{count} voti" - vote: Vota - show_more: Mostra di più - show_thread: Mostra thread title: '%{name}: "%{quote}"' visibilities: direct: Diretto diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 3f50b0d7a6..13f59e981b 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -7,7 +7,6 @@ ja: hosted_on: Mastodon hosted on %{domain} title: ã“ã®ã‚µãƒ¼ãƒãƒ¼ã«ã¤ã„㦠accounts: - follow: フォãƒãƒ¼ followers: other: フォãƒãƒ¯ãƒ¼ following: フォãƒãƒ¼ä¸ @@ -1700,21 +1699,12 @@ ja: edited_at_html: "%{date} 編集済ã¿" errors: in_reply_not_found: ã‚ãªãŸãŒè¿”ä¿¡ã—よã†ã¨ã—ã¦ã„る投稿ã¯å˜åœ¨ã—ãªã„よã†ã§ã™ã€‚ - open_in_web: Webã§é–‹ã over_character_limit: 上é™ã¯%{max}æ–‡å—ã§ã™ pin_errors: direct: 返信ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ã«è¡¨ç¤ºã•れる投稿ã¯ãƒ”ン留ã‚ã§ãã¾ã›ã‚“ limit: 固定ã§ãる投稿数ã®ä¸Šé™ã«é”ã—ã¾ã—㟠ownership: ä»–äººã®æŠ•ç¨¿ã‚’å›ºå®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ reblog: ブーストを固定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ - poll: - total_people: - other: "%{count}人" - total_votes: - other: "%{count}票" - vote: 投票 - show_more: ã‚‚ã£ã¨è¦‹ã‚‹ - show_thread: スレッドを表示 title: '%{name}: "%{quote}"' visibilities: direct: ダイレクト diff --git a/config/locales/ka.yml b/config/locales/ka.yml index 97b56ea35c..5769375078 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -6,7 +6,6 @@ ka: contact_unavailable: მიუწ. hosted_on: მáƒáƒ¡áƒ¢áƒáƒ“áƒáƒœáƒ¡ მáƒáƒ¡áƒžáƒ˜áƒœáƒ«áƒšáƒáƒ‘ს %{domain} accounts: - follow: გáƒáƒ§áƒ”ვი following: მიჰყვებრnothing_here: áƒáƒ¥ áƒáƒ áƒáƒ¤áƒ”რიáƒ! pin_errors: @@ -430,13 +429,11 @@ ka: disallowed_hashtags: one: 'მáƒáƒ˜áƒªáƒáƒ•დრáƒáƒ™áƒ ძáƒáƒšáƒ£áƒš ჰეშტეგს: %{tags}' other: 'მáƒáƒ˜áƒªáƒáƒ•ს áƒáƒ™áƒ ძáƒáƒšáƒ£áƒš ჰეშტეგს: %{tags}' - open_in_web: ვებში გáƒáƒ®áƒœáƒ¡áƒ over_character_limit: ნიშნების ლიმიტი გáƒáƒ“áƒáƒ¡áƒªáƒ“რ%{max}-ს pin_errors: limit: ტუტების მáƒáƒ¥áƒ¡áƒ˜áƒ›áƒáƒšáƒ£áƒ ი რáƒáƒáƒ“ენáƒáƒ‘რუკვე áƒáƒžáƒ˜áƒœáƒ”თ ownership: სხვისი ტუტი ვერáƒáƒ˜áƒžáƒ˜áƒœáƒ”ბრreblog: ბუსტი ვერáƒáƒ˜áƒžáƒ˜áƒœáƒ”ბრ- show_more: მეტის ჩვენებრvisibilities: private: მხáƒáƒšáƒáƒ“-მიმდევრები private_long: áƒáƒ©áƒ•ენე მხáƒáƒšáƒáƒ“ მიმდევრებს diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 3aed6c55e7..7c3d526702 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -7,7 +7,6 @@ kab: hosted_on: Maá¹£á¹udun yersen deg %{domain} title: Æ”ef accounts: - follow: Ḍfeá¹› followers: one: Umeá¸faá¹› other: Imeá¸faá¹›en @@ -798,17 +797,6 @@ kab: one: "%{count} n tbidyutt" other: "%{count} n tbidyutin" edited_at_html: Tettwaẓreg ass n %{date} - open_in_web: Ldi deg Web - poll: - total_people: - one: "%{count} n wemdan" - other: "%{count} n yemdanen" - total_votes: - one: "%{count} n wedÉ£ar" - other: "%{count} n yedÉ£aren" - vote: DÉ£eá¹› - show_more: Ssken-d ugar - show_thread: Ssken-d lxiḠtitle: '%{name} : "%{quote}"' visibilities: direct: Usrid diff --git a/config/locales/kk.yml b/config/locales/kk.yml index f89bdee622..67969d4d69 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -6,7 +6,6 @@ kk: contact_unavailable: БелгіÑіз hosted_on: Mastodon орнатылған %{domain} доменінде accounts: - follow: Жазылу followers: one: Оқырман other: Оқырман @@ -647,22 +646,11 @@ kk: disallowed_hashtags: one: 'Ñ€Ò±Ò›Ñат етілмеген Ñ…Ñштег: %{tags}' other: 'Ñ€Ò±Ò›Ñат етілмеген Ñ…Ñштегтер: %{tags}' - open_in_web: Вебте ашу over_character_limit: "%{max} макÑимум таңбадан аÑып кетті" pin_errors: limit: ЖабыÑтырылатын жазба Ñаны макÑимумынан аÑты ownership: Біреудің жазбаÑÑ‹ жабыÑтырылмайды reblog: БөліÑілген жазба жабыÑтырылмайды - poll: - total_people: - one: "%{count} адам" - other: "%{count} адам" - total_votes: - one: "%{count} дауыÑ" - other: "%{count} дауыÑ" - vote: Ð”Ð°ÑƒÑ‹Ñ Ð±ÐµÑ€Ñƒ - show_more: Тағы әкел - show_thread: Тақырыпты көрÑет visibilities: private: Тек оқырмандарға private_long: Тек оқырмандарға ғана көрінеді diff --git a/config/locales/ko.yml b/config/locales/ko.yml index ab377df304..cbcc09a4da 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -7,7 +7,6 @@ ko: hosted_on: "%{domain}ì—서 호스팅 ë˜ëŠ” ë§ˆìŠ¤í† ëˆ" title: ì •ë³´ accounts: - follow: 팔로우 followers: other: 팔로워 following: 팔로잉 @@ -1705,21 +1704,12 @@ ko: edited_at_html: "%{date}ì— íŽ¸ì§‘ë¨" errors: in_reply_not_found: ë‹µìž¥í•˜ë ¤ëŠ” ê²Œì‹œë¬¼ì´ ì¡´ìž¬í•˜ì§€ 않습니다. - open_in_web: Web으로 열기 over_character_limit: 최대 %{max}ìžê¹Œì§€ ìž…ë ¥í• ìˆ˜ 있습니다 pin_errors: direct: ë©˜ì…˜ëœ ì‚¬ìš©ìžë“¤ì—게만 ë³´ì´ëŠ” ê²Œì‹œë¬¼ì€ ê³ ì •ë 수 없습니다 limit: ì´ë¯¸ 너무 ë§Žì€ ê²Œì‹œë¬¼ì„ ê³ ì •í–ˆìŠµë‹ˆë‹¤ ownership: 다른 ì‚¬ëžŒì˜ ê²Œì‹œë¬¼ì€ ê³ ì •ë 수 없습니다 reblog: 부스트는 ê³ ì •ë 수 없습니다 - poll: - total_people: - other: "%{count}명" - total_votes: - other: "%{count} 명 투표함" - vote: 투표 - show_more: ë” ë³´ê¸° - show_thread: 글타래 보기 title: '%{name}: "%{quote}"' visibilities: direct: 다ì´ë ‰íЏ diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 20fe6cf6de..6b80e32ba8 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -7,7 +7,6 @@ ku: hosted_on: Mastodon li ser %{domain} tê pêşkêşkirin title: Derbar accounts: - follow: BiÅŸopîne followers: one: Åžopîner other: Åžopîner @@ -1404,23 +1403,12 @@ ku: edited_at_html: Di %{date} de hate serrastkirin errors: in_reply_not_found: Ew ÅŸandiya ku tu dikî nakî bersivê bide xuya nake an jî hatiye jêbirin. - open_in_web: Di tevnê de veke over_character_limit: sînorê karakterê %{max} derbas kir pin_errors: direct: Åžandiyên ku tenê ji bikarhênerên qalkirî re têne xuyangkirin, nayê derzîkirin limit: Jixwe te mezintirîn hejmara ÅŸandîyên xwe derzî kir ownership: Åžandiya kesekî din nay derzî kirin reblog: Ev ÅŸandî nayê derzî kirin - poll: - total_people: - one: "%{count} kes" - other: "%{count} kes" - total_votes: - one: "%{count} deng" - other: "%{count} deng" - vote: Deng bide - show_more: Bêtir nîşan bide - show_thread: Mijarê nîşan bide title: "%{name}%{quote}" visibilities: direct: Rasterast diff --git a/config/locales/la.yml b/config/locales/la.yml index d3733df934..cc92bf6d28 100644 --- a/config/locales/la.yml +++ b/config/locales/la.yml @@ -7,7 +7,6 @@ la: hosted_on: Mastodon in %{domain} hospitÄtum title: De accounts: - follow: Sequere followers: one: SectÄtor other: SectÄtÅrÄ“s diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 164967159b..2f5eb1553e 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -7,7 +7,6 @@ lad: hosted_on: Mastodon balabayado en %{domain} title: Sovre mozotros accounts: - follow: Sige followers: one: Suivante other: Suivantes @@ -1677,23 +1676,12 @@ lad: edited_at_html: Editado %{date} errors: in_reply_not_found: La publikasion a la ke aprovas arispondir no egziste. - open_in_web: Avre en web over_character_limit: limito de karakteres de %{max} superado pin_errors: direct: Las publikasyones ke son vizivles solo para los utilizadores enmentados no pueden fiksarse limit: Ya tienes fiksado el numero maksimo de publikasyones ownership: La publikasyon de otra persona no puede fiksarse reblog: No se puede fixar una repartajasyon - poll: - total_people: - one: "%{count} persona" - other: "%{count} personas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Vota - show_more: Amostra mas - show_thread: Amostra diskusyon title: '%{name}: "%{quote}"' visibilities: direct: Direkto diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 07e8ba75a2..42495053e9 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -7,7 +7,6 @@ lt: hosted_on: Mastodon talpinamas %{domain} title: Apie accounts: - follow: Sekti followers: few: SekÄ—jai many: SekÄ—jo @@ -1107,16 +1106,11 @@ lt: other: "%{count} vaizdų" boosted_from_html: Pakelta iÅ¡ %{acct_link} content_warning: 'Turinio įspÄ—jimas: %{warning}' - open_in_web: Atidaryti naudojan Web over_character_limit: pasiektas %{max} simbolių limitas pin_errors: limit: JÅ«s jau prisegÄ—te maksimalų toot'ų skaiÄų ownership: Kitų vartotojų toot'ai negali bÅ«ti prisegti reblog: Pakeltos žinutÄ—s negali bÅ«ti prisegtos - poll: - vote: Balsuoti - show_more: Rodyti daugiau - show_thread: Rodyti gijÄ… visibilities: private: Tik sekÄ—jams private_long: rodyti tik sekÄ—jams diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 5dd6ff9e1e..09e6b9ba0e 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -7,7 +7,6 @@ lv: hosted_on: Mastodon mitinÄts %{domain} title: Par accounts: - follow: Sekot followers: one: SekotÄjs other: SekotÄji @@ -1645,25 +1644,12 @@ lv: edited_at_html: Labots %{date} errors: in_reply_not_found: Å Ä·iet, ka ziņa, uz kuru tu mēģini atbildÄ“t, nepastÄv. - open_in_web: AtvÄ“rt webÄ over_character_limit: pÄrsniegts %{max} rakstzÄ«mju ierobežojums pin_errors: direct: Ziņojumus, kas ir redzami tikai minÄ“tajiem lietotÄjiem, nevar piespraust limit: Tu jau esi piespraudis maksimÄlo ziņu skaitu ownership: KÄda cita ierakstu nevar piespraust reblog: Izceltu ierakstu nevar piespraust - poll: - total_people: - one: "%{count} cilvÄ“ks" - other: "%{count} cilvÄ“ki" - zero: "%{count} cilvÄ“ku" - total_votes: - one: "%{count} balss" - other: "%{count} balsis" - zero: "%{count} balsu" - vote: Balsu skaits - show_more: RÄdÄ«t vairÄk - show_thread: RÄdÄ«t tematu title: "%{name}: “%{quote}â€" visibilities: direct: TieÅ¡s diff --git a/config/locales/ml.yml b/config/locales/ml.yml index a4b9391c00..bdc0475a6f 100644 --- a/config/locales/ml.yml +++ b/config/locales/ml.yml @@ -4,7 +4,6 @@ ml: contact_missing: സജàµà´œà´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´² contact_unavailable: à´²à´àµà´¯à´®à´²àµà´² accounts: - follow: പിനàµà´¤àµà´Ÿà´°àµà´• following: പിനàµà´¤àµà´Ÿà´°àµà´¨àµà´¨àµ last_active: അവസാനം സജീവമായിരàµà´¨àµà´¨à´¤àµ link_verified_on: സനàµà´§à´¿à´¯àµà´Ÿàµ† ഉടമസàµà´¥à´¾à´µà´¸àµâ€Œà´•ാശം %{date} ൽ പരിശോധികàµà´•à´ªàµà´ªàµ†à´Ÿàµà´Ÿàµ diff --git a/config/locales/ms.yml b/config/locales/ms.yml index c91a624230..39c695a539 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -7,7 +7,6 @@ ms: hosted_on: Mastodon dihoskan di %{domain} title: Perihal accounts: - follow: Ikut followers: other: Pengikut following: Mengikuti @@ -1560,21 +1559,12 @@ ms: edited_at_html: Disunting %{date} errors: in_reply_not_found: Pos yang anda cuba balas nampaknya tidak wujud. - open_in_web: Buka dalam web over_character_limit: had aksara %{max} melebihi pin_errors: direct: Pos yang hanya boleh dilihat oleh pengguna yang disebut tidak boleh disematkan limit: Anda telah menyematkan bilangan maksimum pos ownership: Siaran orang lain tidak boleh disematkan reblog: Rangsangan tidak boleh disematkan - poll: - total_people: - other: "%{count} orang" - total_votes: - other: "%{count} undi" - vote: Undi - show_more: Tunjuk lebih banyak - show_thread: Tunjuk bebenang title: '%{name}: "%{quote}"' visibilities: direct: Terus diff --git a/config/locales/my.yml b/config/locales/my.yml index 771fbba579..92464523a0 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -7,7 +7,6 @@ my: hosted_on: "%{domain} မှ လက်á€á€¶á€†á€±á€¬á€„်ရွက်ထားသော Mastodon" title: အကြောင်း accounts: - follow: စောင့်ကြည့်မယ် followers: other: စောင့်ကြည့်သူ following: စောင့်ကြည့်နေသည် @@ -1560,21 +1559,12 @@ my: edited_at_html: "%{date} ကá€á€¯ ပြင်ဆင်ပြီးပါပြီ" errors: in_reply_not_found: သင် စာပြန်နေသည့်ပá€á€¯á€·á€…်မှာ မရှá€á€á€±á€¬á€·á€•ါዠ- open_in_web: á€á€˜á€ºá€á€½á€„် ဖွင့်ပါ over_character_limit: စာလုံးကန့်သá€á€ºá€á€»á€€á€º %{max} ကá€á€¯ ကျော်လွန်သွားပါပြီ pin_errors: direct: အမည်ဖော်ပြထားသည့် ပá€á€¯á€·á€…်များကá€á€¯ ပင်á€á€½á€²áမရပါ limit: သင်သည် ပá€á€¯á€·á€…်အရေအá€á€½á€€á€ºá€¡á€™á€»á€¬á€¸á€†á€¯á€¶á€¸á€€á€á€¯ ပင်á€á€½á€²á€‘ားပြီးဖြစ်သည် ownership: အá€á€¼á€¬á€¸á€žá€°áပá€á€¯á€·á€…်ကá€á€¯ ပင်á€á€½á€²áမရပါ reblog: Boost လုပ်ထားသောပá€á€¯á€·á€…်ကá€á€¯ ပင်ထားáမရပါ - poll: - total_people: - other: "%{count} ယောက်" - total_votes: - other: မဲအရေအá€á€½á€€á€º %{count} မဲ - vote: မဲပေးမည် - show_more: ပá€á€¯á€™á€á€¯á€•ြရန် - show_thread: Thread ကá€á€¯ ပြပါ title: '%{name}: "%{quote}"' visibilities: direct: á€á€á€¯á€€á€ºá€›á€á€¯á€€á€º diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 63fcf1c857..63656991a8 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -7,7 +7,6 @@ nl: hosted_on: Mastodon op %{domain} title: Over accounts: - follow: Volgen followers: one: Volger other: Volgers @@ -1740,23 +1739,12 @@ nl: edited_at_html: Bewerkt op %{date} errors: in_reply_not_found: Het bericht waarop je probeert te reageren lijkt niet te bestaan. - open_in_web: In de webapp openen over_character_limit: Limiet van %{max} tekens overschreden pin_errors: direct: Berichten die alleen zichtbaar zijn voor vermelde gebruikers, kunnen niet worden vastgezet limit: Je hebt het maximaal aantal bericht al vastgemaakt ownership: Een bericht van iemand anders kan niet worden vastgemaakt reblog: Een boost kan niet worden vastgezet - poll: - total_people: - one: "%{count} persoon" - other: "%{count} personen" - total_votes: - one: "%{count} stem" - other: "%{count} stemmen" - vote: Stemmen - show_more: Meer tonen - show_thread: Gesprek tonen title: '%{name}: "%{quote}"' visibilities: direct: Privébericht diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 47dcc1ac8e..b7beeb4263 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -7,7 +7,6 @@ nn: hosted_on: "%{domain} er vert for Mastodon" title: Om accounts: - follow: Fylg followers: one: Fylgjar other: Fylgjarar @@ -1740,23 +1739,12 @@ nn: edited_at_html: Redigert %{date} errors: in_reply_not_found: Det ser ut til at tutet du freistar Ã¥ svara ikkje finst. - open_in_web: Opn pÃ¥ nett over_character_limit: øvregrensa for teikn, %{max}, er nÃ¥dd pin_errors: direct: Innlegg som bare er synlige for nevnte brukere kan ikke festes limit: Du har allereie festa sÃ¥ mange tut som det gÃ¥r an Ã¥ festa ownership: Du kan ikkje festa andre sine tut reblog: Ei framheving kan ikkje festast - poll: - total_people: - one: "%{count} person" - other: "%{count} folk" - total_votes: - one: "%{count} røyst" - other: "%{count} røyster" - vote: Røyst - show_more: Vis meir - show_thread: Vis trÃ¥den title: "%{name}: «%{quote}»" visibilities: direct: Direkte diff --git a/config/locales/no.yml b/config/locales/no.yml index b3eebd8ecc..635ceedde4 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -7,7 +7,6 @@ hosted_on: Mastodon driftet pÃ¥ %{domain} title: Om accounts: - follow: Følg followers: one: Følger other: Følgere @@ -1619,23 +1618,12 @@ edited_at_html: Redigert %{date} errors: in_reply_not_found: Posten du prøver Ã¥ svare ser ikke ut til eksisterer. - open_in_web: Ã…pne i nettleser over_character_limit: grensen pÃ¥ %{max} tegn overskredet pin_errors: direct: Innlegg som bare er synlige for nevnte brukere kan ikke festes limit: Du har allerede festet det maksimale antall innlegg ownership: Kun egne innlegg kan festes reblog: En fremheving kan ikke festes - poll: - total_people: - one: "%{count} person" - other: "%{count} personer" - total_votes: - one: "%{count} stemme" - other: "%{count} stemmer" - vote: Stem - show_more: Vis mer - show_thread: Vis trÃ¥den title: "%{name}: «%{quote}»" visibilities: direct: Direkte diff --git a/config/locales/oc.yml b/config/locales/oc.yml index e88f8a3f69..5cdd9240b0 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -7,7 +7,6 @@ oc: hosted_on: Mastodon albergat sus %{domain} title: A prepaus accounts: - follow: Sègre followers: one: Seguidor other: Seguidors @@ -846,22 +845,11 @@ oc: edited_at_html: Modificat %{date} errors: in_reply_not_found: La publicacion que respondètz sembla pas mai exisitir. - open_in_web: Dobrir sul web over_character_limit: limit de %{max} caractèrs passat pin_errors: limit: Avètz ja lo maximum de tuts penjats ownership: Se pòt pas penjar lo tut de qualqu’un mai reblog: Se pòt pas penjar un tut partejat - poll: - total_people: - one: "%{count} persona" - other: "%{count} personas" - total_votes: - one: "%{count} vòte" - other: "%{count} vòtes" - vote: Votar - show_more: Ne veire mai - show_thread: Mostrar lo fil title: '%{name} : "%{quote}"' visibilities: direct: Dirècte diff --git a/config/locales/pa.yml b/config/locales/pa.yml index 7a34358ddb..1899d71008 100644 --- a/config/locales/pa.yml +++ b/config/locales/pa.yml @@ -7,7 +7,6 @@ pa: hosted_on: "%{domain} ਉੱਤੇ ਹੋਸਟ ਕੀਤਾ ਮਸਟਾਡੋਨ" title: ਇਸ ਬਾਰੇ accounts: - follow: ਫ਼ਾਲੋ following: ਫ਼ਾਲੋ ਕੀਤੇ ਜਾ ਰਹੇ posts_tab_heading: ਪੋਸਟਾਂ admin: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index b710df2e78..f0d09cb2d3 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -7,7 +7,6 @@ pl: hosted_on: Mastodon prowadzony na %{domain} title: O nas accounts: - follow: Obserwuj followers: few: Å›ledzÄ…cych many: Å›ledzÄ…cych @@ -1800,27 +1799,12 @@ pl: edited_at_html: Edytowane %{date} errors: in_reply_not_found: Post, na który próbujesz odpowiedzieć, nie istnieje. - open_in_web: Otwórz w przeglÄ…darce over_character_limit: limit %{max} znaków przekroczony pin_errors: direct: Nie możesz przypiąć wpisu, który jest widoczny tylko dla wspomnianych użytkowników limit: PrzekroczyÅ‚eÅ› maksymalnÄ… liczbÄ™ przypiÄ™tych wpisów ownership: Nie możesz przypiąć cudzego wpisu reblog: Nie możesz przypiąć podbicia wpisu - poll: - total_people: - few: "%{count} osoby" - many: "%{count} osób" - one: "%{count} osoba" - other: "%{count} osoby" - total_votes: - few: "%{count} gÅ‚osy" - many: "%{count} gÅ‚osy" - one: "%{count} gÅ‚os" - other: "%{count} gÅ‚osy" - vote: GÅ‚osuj - show_more: Pokaż wiÄ™cej - show_thread: Pokaż wÄ…tek title: '%{name}: "%{quote}"' visibilities: direct: BezpoÅ›redni diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 864a8b4d91..d1140f3645 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -7,7 +7,6 @@ pt-BR: hosted_on: Mastodon hospedado em %{domain} title: Sobre accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1740,23 +1739,12 @@ pt-BR: edited_at_html: Editado em %{date} errors: in_reply_not_found: A publicação que você quer responder parece não existir. - open_in_web: Abrir no navegador over_character_limit: limite de caracteres de %{max} excedido pin_errors: direct: Publicações visÃveis apenas para usuários mencionados não podem ser fixadas limit: Você alcançou o número limite de publicações fixadas ownership: As publicações dos outros não podem ser fixadas reblog: Um impulso não pode ser fixado - poll: - total_people: - one: "%{count} pessoa" - other: "%{count} pessoas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Votar - show_more: Mostrar mais - show_thread: Mostrar conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 0f0d6f36ee..489fb2b89b 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -7,7 +7,6 @@ pt-PT: hosted_on: Mastodon alojado em %{domain} title: Sobre accounts: - follow: Seguir followers: one: Seguidor other: Seguidores @@ -1683,23 +1682,12 @@ pt-PT: edited_at_html: Editado em %{date} errors: in_reply_not_found: A publicação a que está a tentar responder parece não existir. - open_in_web: Abrir na web over_character_limit: limite de caracter excedeu %{max} pin_errors: direct: Publicações visÃveis apenas para utilizadores mencionados não podem ser afixadas limit: Já afixaste a quantidade máxima de publicações ownership: Não podem ser afixadas publicações doutras pessoas reblog: Não pode afixar um reforço - poll: - total_people: - one: "%{count} pessoa" - other: "%{count} pessoas" - total_votes: - one: "%{count} voto" - other: "%{count} votos" - vote: Votar - show_more: Mostrar mais - show_thread: Mostrar conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 52982ead2d..d4f202637b 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -7,7 +7,6 @@ ro: hosted_on: Mastodon găzduit de %{domain} title: Despre accounts: - follow: UrmăreÈ™te followers: few: Urmăritori one: Urmăritor @@ -681,24 +680,11 @@ ro: other: 'conÈ›inea aceste hashtag-uri nepermise: %{tags}' errors: in_reply_not_found: Postarea la care încercaÈ›i să răspundeÈ›i nu pare să existe. - open_in_web: Deschide pe web over_character_limit: s-a depășit limita de caracter %{max} pin_errors: limit: Deja ai fixat numărul maxim de postări ownership: Postarea altcuiva nu poate fi fixată reblog: Un impuls nu poate fi fixat - poll: - total_people: - few: "%{count} persoane" - one: "%{count} persoană" - other: "%{count} de persoane" - total_votes: - few: "%{count} voturi" - one: "%{count} vot" - other: "%{count} de voturi" - vote: Votează - show_more: Arată mai mult - show_thread: Arată discuÈ›ia visibilities: private: Doar urmăritorii private_long: Arată doar urmăritorilor diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 9d6b2946ac..d66dded89b 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -7,7 +7,6 @@ ru: hosted_on: Ð’Ñ‹ получили Ñто Ñообщение, так как зарегиÑтрированы на %{domain} title: О проекте accounts: - follow: ПодпиÑатьÑÑ followers: few: подпиÑчика many: подпиÑчиков @@ -1692,27 +1691,12 @@ ru: edited_at_html: Редактировано %{date} errors: in_reply_not_found: ПоÑÑ‚, на который вы пытаетеÑÑŒ ответить, не ÑущеÑтвует или удалён. - open_in_web: Открыть в веб-верÑии over_character_limit: превышен лимит Ñимволов (%{max}) pin_errors: direct: СообщениÑ, видимые только упомÑнутым пользователÑм, не могут быть закреплены limit: Ð’Ñ‹ закрепили макÑимально возможное чиÑло поÑтов ownership: ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°ÐºÑ€ÐµÐ¿Ð¸Ñ‚ÑŒ чужой поÑÑ‚ reblog: ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°ÐºÑ€ÐµÐ¿Ð¸Ñ‚ÑŒ продвинутый поÑÑ‚ - poll: - total_people: - few: "%{count} человека" - many: "%{count} человек" - one: "%{count} человек" - other: "%{count} человек" - total_votes: - few: "%{count} голоÑа" - many: "%{count} голоÑов" - one: "%{count} голоÑ" - other: "%{count} голоÑов" - vote: ГолоÑовать - show_more: Развернуть - show_thread: Открыть обÑуждение title: '%{name}: "%{quote}"' visibilities: direct: ÐдреÑованный diff --git a/config/locales/ry.yml b/config/locales/ry.yml index e384b7f1b7..dd1b78600c 100644 --- a/config/locales/ry.yml +++ b/config/locales/ry.yml @@ -1,7 +1,6 @@ --- ry: accounts: - follow: ПудпиÑати ÑÑ following: ПудпиÑкы posts: few: Публикації diff --git a/config/locales/sc.yml b/config/locales/sc.yml index fee79a1325..435749f470 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -7,7 +7,6 @@ sc: hosted_on: Mastodon allogiadu in %{domain} title: Informatziones accounts: - follow: Sighi followers: one: Sighidura other: Sighiduras @@ -1111,22 +1110,11 @@ sc: other: 'cuntenet is etichetas non permìtidas: %{tags}' errors: in_reply_not_found: Ses chirchende de rispòndere a unu tut chi no esistit prus. - open_in_web: Aberi in sa web over_character_limit: lìmite de carà teres de %{max} superadu pin_errors: limit: As giai apicadu su nùmeru mà ssimu de tuts ownership: Is tuts de à tere non podent èssere apicados reblog: Is cumpartziduras non podent èssere apicadas - poll: - total_people: - one: "%{count} persone" - other: "%{count} persones" - total_votes: - one: "%{count} votu" - other: "%{count} votos" - vote: Vota - show_more: Ammustra·nde prus - show_thread: Ammustra su tema title: '%{name}: "%{quote}"' visibilities: direct: Deretu diff --git a/config/locales/sco.yml b/config/locales/sco.yml index 967706f03a..70143a968e 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -7,7 +7,6 @@ sco: hosted_on: Mastodon hostit on %{domain} title: Aboot accounts: - follow: Follae followers: one: Follaer other: Follaers @@ -1394,23 +1393,12 @@ sco: edited_at_html: Editit %{date} errors: in_reply_not_found: The post thit ye'r trying tae reply tae disnae appear tae exist. - open_in_web: Open in wab over_character_limit: chairacter limit o %{max} exceedit pin_errors: direct: Posts thit's ainly visible tae menshied uisers cannae be preent limit: Ye awriddy preent the maximum nummer o posts ownership: Somebody else's post cannae be preent reblog: A heeze cannae be preent - poll: - total_people: - one: "%{count} person" - other: "%{count} fowk" - total_votes: - one: "%{count} vote" - other: "%{count} votes" - vote: Vote - show_more: Shaw mair - show_thread: Shaw threid title: '%{name}: "%{quote}"' visibilities: direct: Direck diff --git a/config/locales/si.yml b/config/locales/si.yml index c7968e2479..135a99ceb2 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -7,7 +7,6 @@ si: hosted_on: "%{domain} හරහ෠සà¶à·Šà¶šà·à¶»à¶šà¶à·Šâ€à·€à¶º ලබයි" title: පිළිබඳව accounts: - follow: අනුගමනය followers: one: අනුගà·à¶¸à·’කය෠other: අනුගà·à¶¸à·’කයින් @@ -1267,22 +1266,11 @@ si: edited_at_html: සංස්කරණය %{date} errors: in_reply_not_found: ඔබ à¶´à·’à·…à·’à¶à·”රු දීමට à¶à·à¶à·Š කරන ලිපිය නොපවà¶à·’à¶± à¶¶à·€ පෙනෙයි. - open_in_web: වෙබයේ විවෘචකරන්න over_character_limit: à¶…à¶šà·Šà·‚à¶» සීමà·à·€ %{max} ඉක්මව෠ඇචpin_errors: direct: සඳහන් à¶šà·… අයට පමණක් පෙනෙන ලිපි ඇමිණීමට නොහà·à¶šà·’ය limit: දà·à¶±à¶§à¶¸à¶à·Š මුදුනට ඇමිණිමට à·„à·à¶šà·’ ලිපි සීමà·à·€à¶§ ළඟ෠වී ඇචownership: වෙනà¶à·Š අයගේ ලිපි ඇමිණීමට නොහà·à¶šà·’ය - poll: - total_people: - one: පුද්ගලයින් %{count} - other: පුද්ගලයින් %{count} - total_votes: - one: ඡන්ද %{count} යි - other: ඡන්ද %{count} යි - vote: ඡන්දය - show_more: à¶à·€ පෙන්වන්න - show_thread: නූල් පෙන්වන්න title: '%{name}: "%{quote}"' visibilities: direct: සෘජු diff --git a/config/locales/sk.yml b/config/locales/sk.yml index c49da0fc38..d7eacb6850 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -7,7 +7,6 @@ sk: hosted_on: Mastodon hostovaný na %{domain} title: Ohľadom accounts: - follow: Nasleduj followers: few: Sledovateľov many: Sledovateľov @@ -1259,26 +1258,11 @@ sk: edited_at_html: Upravené %{date} errors: in_reply_not_found: PrÃspevok, na ktorý sa snažÃÅ¡ odpovedaÅ¥, pravdepodobne neexistuje. - open_in_web: Otvor v okne na webe over_character_limit: limit %{max} znakov bol presiahnutý pin_errors: limit: Už si si pripol ten najvyššà možný poÄet hlášok ownership: Nieje možné pripnúť hlášku od niekoho iného reblog: Vyzdvihnutie sa nedá pripnúť - poll: - total_people: - few: "%{count} ľudÃ" - many: "%{count} ľudia" - one: "%{count} Älovek" - other: "%{count} ľudÃ" - total_votes: - few: "%{count} hlasov" - many: "%{count} hlasov" - one: "%{count} hlas" - other: "%{count} hlasy" - vote: Hlasuj - show_more: Ukáž viac - show_thread: Ukáž diskusné vlákno title: '%{name}: „%{quote}"' visibilities: direct: Súkromne diff --git a/config/locales/sl.yml b/config/locales/sl.yml index d0440abb00..ef6d00b8d3 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -7,7 +7,6 @@ sl: hosted_on: Mastodon gostuje na %{domain} title: O programu accounts: - follow: Sledi followers: few: Sledilci one: Sledilec @@ -1785,27 +1784,12 @@ sl: edited_at_html: Urejeno %{date} errors: in_reply_not_found: Objava, na katero želite odgovoriti, ne obstaja. - open_in_web: Odpri na spletu over_character_limit: omejitev %{max} znakov je presežena pin_errors: direct: Objav, ki so vidne samo omenjenum uporabnikom, ni mogoÄe pripenjati limit: Pripeli ste najveÄje Å¡tevilo objav ownership: Objava nekoga drugega ne more biti pripeta reblog: Izpostavitev ne more biti pripeta - poll: - total_people: - few: "%{count} osebe" - one: "%{count} Oseba" - other: "%{count} oseb" - two: "%{count} osebi" - total_votes: - few: "%{count} glasovi" - one: "%{count} glas" - other: "%{count} glasov" - two: "%{count} glasova" - vote: Glasuj - show_more: Pokaži veÄ - show_thread: Pokaži nit title: "%{name}: »%{quote}«" visibilities: direct: Neposredno diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 241dc08b22..70d20592a5 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -7,7 +7,6 @@ sq: hosted_on: Server Mastodon i strehuar në %{domain} title: Mbi accounts: - follow: Ndiqeni followers: one: Ndjekës other: Ndjekës @@ -1732,23 +1731,12 @@ sq: edited_at_html: Përpunuar më %{date} errors: in_reply_not_found: Gjendja të cilës po provoni t’i përgjigjeni s’duket se ekziston. - open_in_web: Hape në internet over_character_limit: u tejkalua kufi shenjash prej %{max} pin_errors: direct: Postimet që janë të dukshme vetëm për përdoruesit e përmendur s’mund të fiksohen limit: Keni fiksuar tashmë numrin maksimum të mesazheve ownership: S’mund të fiksohen mesazhet e të tjerëve reblog: S’mund të fiksohet një përforcim - poll: - total_people: - one: "%{count} person" - other: "%{count} vetë" - total_votes: - one: "%{count} votë" - other: "%{count} vota" - vote: Votë - show_more: Shfaq më tepër - show_thread: Shfaq rrjedhën title: '%{name}: "%{quote}"' visibilities: direct: I drejtpërdrejtë diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 428b9cb084..91f0933398 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -7,7 +7,6 @@ sr-Latn: hosted_on: Mastodon hostovan na %{domain} title: O instanci accounts: - follow: Zaprati followers: few: Pratioca one: Pratilac @@ -1670,25 +1669,12 @@ sr-Latn: edited_at_html: Izmenjeno %{date} errors: in_reply_not_found: Objava na koju pokuÅ¡avate da odgovorite naizgled ne postoji. - open_in_web: Otvori u vebu over_character_limit: ograniÄenje od %{max} karaktera prekoraÄeno pin_errors: direct: Objave koje su vidljive samo pomenutim korisnicima ne mogu biti prikaÄene limit: Već ste zakaÄili maksimalan broj objava ownership: TuÄ‘a objava se ne može zakaÄiti reblog: PodrÅ¡ka ne može da se prikaÄi - poll: - total_people: - few: "%{count} osobe" - one: "%{count} osoba" - other: "%{count} ljudi" - total_votes: - few: "%{count} glasa" - one: "%{count} glas" - other: "%{count} glasova" - vote: Glasajte - show_more: Prikaži joÅ¡ - show_thread: Prikaži niz title: "%{name}: „%{quote}â€" visibilities: direct: Direktno diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 08fbf39fb8..67aee931be 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -7,7 +7,6 @@ sr: hosted_on: Mastodon хоÑтован на %{domain} title: О инÑтанци accounts: - follow: Запрати followers: few: Пратиоца one: Пратилац @@ -1700,25 +1699,12 @@ sr: edited_at_html: Уређено %{date} errors: in_reply_not_found: Објава на коју покушавате да одговорите наизглед не поÑтоји. - open_in_web: Отвори у вебу over_character_limit: ограничење од %{max} карактера прекорачено pin_errors: direct: Објаве које Ñу видљиве Ñамо поменутим кориÑницима не могу бити прикачене limit: Већ Ñте закачили макÑималан број објава ownership: Туђа објава Ñе не може закачити reblog: Подршка не може да Ñе прикачи - poll: - total_people: - few: "%{count} оÑобе" - one: "%{count} оÑоба" - other: "%{count} људи" - total_votes: - few: "%{count} глаÑа" - one: "%{count} глаÑ" - other: "%{count} глаÑова" - vote: ГлаÑајте - show_more: Прикажи још - show_thread: Прикажи низ title: "%{name}: „%{quote}â€" visibilities: direct: Директно diff --git a/config/locales/sv.yml b/config/locales/sv.yml index c8ddc346a5..99b7ec9b3a 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -7,7 +7,6 @@ sv: hosted_on: Mastodon-värd pÃ¥ %{domain} title: Om accounts: - follow: Följa followers: one: Följare other: Följare @@ -1693,23 +1692,12 @@ sv: edited_at_html: 'Ändrad: %{date}' errors: in_reply_not_found: Inlägget du försöker svara pÃ¥ verkar inte existera. - open_in_web: Öppna pÃ¥ webben over_character_limit: teckengräns pÃ¥ %{max} har överskridits pin_errors: direct: Inlägg som endast är synliga för nämnda användare kan inte fästas limit: Du har redan fäst det maximala antalet inlägg ownership: NÃ¥gon annans inlägg kan inte fästas reblog: En boost kan inte fästas - poll: - total_people: - one: "%{count} person" - other: "%{count} personer" - total_votes: - one: "%{count} röst" - other: "%{count} röster" - vote: Rösta - show_more: Visa mer - show_thread: Visa trÃ¥d title: '%{name}: "%{quote}"' visibilities: direct: Direkt diff --git a/config/locales/ta.yml b/config/locales/ta.yml index c73148eaca..3a98b6a25d 100644 --- a/config/locales/ta.yml +++ b/config/locales/ta.yml @@ -6,7 +6,6 @@ ta: contact_unavailable: பொ/இ hosted_on: மாஸà¯à®Ÿà¯‹à®Ÿà®¾à®£à¯ %{domain} இனையதà¯à®¤à®¿à®²à¯ இயஙà¯à®•à¯à®•ிறத௠accounts: - follow: பினà¯à®¤à¯Šà®Ÿà®°à¯ followers: one: பினà¯à®¤à¯Šà®Ÿà®°à¯à®ªà®µà®°à¯ other: பினà¯à®¤à¯Šà®Ÿà®°à¯à®ªà®µà®°à¯à®•ள௠@@ -220,4 +219,3 @@ ta: other: "%{count} ஒலிகளà¯" errors: in_reply_not_found: நீஙà¯à®•ள௠மறà¯à®®à¯Šà®´à®¿ அளிகà¯à®• à®®à¯à®¯à®²à¯à®®à¯ பதிவ௠இரà¯à®ªà¯à®ªà®¤à¯à®ªà¯‹à®²à¯ தெரியவிலà¯à®²à¯ˆ. - show_thread: தொடரைக௠காடà¯à®Ÿà¯ diff --git a/config/locales/te.yml b/config/locales/te.yml index a5eb8d7794..84697a4aef 100644 --- a/config/locales/te.yml +++ b/config/locales/te.yml @@ -6,7 +6,6 @@ te: contact_unavailable: వరà±à°¤à°¿à°‚చదౠhosted_on: మాసà±à°Ÿà±Šà°¡à°¾à°¨à± %{domain} లో హోసà±à°Ÿà± చేయబడింది accounts: - follow: à°…à°¨à±à°¸à°°à°¿à°‚à°šà± followers: one: à°…à°¨à±à°šà°°à°¿ other: à°…à°¨à±à°šà°°à±à°²à± diff --git a/config/locales/th.yml b/config/locales/th.yml index d1de9fd818..cbacdfac48 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -7,7 +7,6 @@ th: hosted_on: Mastodon ที่โฮสต์ที่ %{domain} title: เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸š accounts: - follow: ติดตาม followers: other: ผู้ติดตาม following: à¸à¸³à¸¥à¸±à¸‡à¸•ิดตาม @@ -1703,21 +1702,12 @@ th: edited_at_html: à¹à¸à¹‰à¹„ขเมื่ภ%{date} errors: in_reply_not_found: ดูเหมืà¸à¸™à¸§à¹ˆà¸²à¸ˆà¸°à¹„ม่มีโพสต์ที่คุณà¸à¸³à¸¥à¸±à¸‡à¸žà¸¢à¸²à¸¢à¸²à¸¡à¸•à¸à¸šà¸à¸¥à¸±à¸šà¸à¸¢à¸¹à¹ˆ - open_in_web: เปิดในเว็บ over_character_limit: เà¸à¸´à¸™à¸‚ีดจำà¸à¸±à¸”ตัวà¸à¸±à¸à¸©à¸£à¸—ี่ %{max} à¹à¸¥à¹‰à¸§ pin_errors: direct: ไม่สามารถปัà¸à¸«à¸¡à¸¸à¸”โพสต์ที่ปราà¸à¸à¹à¸à¹ˆà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—ี่à¸à¸¥à¹ˆà¸²à¸§à¸–ึงเท่านั้น limit: คุณได้ปัà¸à¸«à¸¡à¸¸à¸”โพสต์ถึงจำนวนสูงสุดไปà¹à¸¥à¹‰à¸§ ownership: ไม่สามารถปัà¸à¸«à¸¡à¸¸à¸”โพสต์ขà¸à¸‡à¸„นà¸à¸·à¹ˆà¸™ reblog: ไม่สามารถปัà¸à¸«à¸¡à¸¸à¸”à¸à¸²à¸£à¸”ัน - poll: - total_people: - other: "%{count} คน" - total_votes: - other: "%{count} à¸à¸²à¸£à¸¥à¸‡à¸„ะà¹à¸™à¸™" - vote: ลงคะà¹à¸™à¸™ - show_more: à¹à¸ªà¸”งเพิ่มเติม - show_thread: à¹à¸ªà¸”งà¸à¸£à¸°à¸—ู้ title: '%{name}: "%{quote}"' visibilities: direct: โดยตรง diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 785be3caf4..d6ca6b4276 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -7,7 +7,6 @@ tr: hosted_on: Mastodon %{domain} üzerinde barındırılıyor title: Hakkında accounts: - follow: Takip et followers: one: Takipçi other: Takipçiler @@ -1740,23 +1739,12 @@ tr: edited_at_html: "%{date} tarihinde düzenlendi" errors: in_reply_not_found: Yanıtlamaya çalıştığınız durum yok gibi görünüyor. - open_in_web: Web sayfasında aç over_character_limit: "%{max} karakter limiti aşıldı" pin_errors: direct: Sadece deÄŸinilen kullanıcıların görebileceÄŸi gönderiler üstte tutulamaz limit: Halihazırda maksimum sayıda gönderi sabitlediniz ownership: BaÅŸkasının gönderisi sabitlenemez reblog: Bir gönderi sabitlenemez - poll: - total_people: - one: "%{count} kiÅŸi" - other: "%{count} kiÅŸiler" - total_votes: - one: "%{count} oy" - other: "%{count} oylar" - vote: Oy Ver - show_more: Daha fazlasını göster - show_thread: Konuyu göster title: '%{name}: "%{quote}"' visibilities: direct: DoÄŸrudan diff --git a/config/locales/tt.yml b/config/locales/tt.yml index 3a0d9d9ce8..7847d636eb 100644 --- a/config/locales/tt.yml +++ b/config/locales/tt.yml @@ -4,7 +4,6 @@ tt: contact_unavailable: Юк title: Проект турында accounts: - follow: Языл followers: other: Ñзылучы following: ЯзылганÑыз @@ -519,12 +518,6 @@ tt: video: other: "%{count} видео" edited_at_html: "%{date} көнне төзәтте" - open_in_web: Веб-та ачу - poll: - total_people: - other: "%{count} кеше" - vote: Тавыш бирү - show_more: Күбрәк күрÑәтү title: '%{name}: "%{quote}"' visibilities: private: ИÑртүчеләр генә diff --git a/config/locales/uk.yml b/config/locales/uk.yml index f5cd40bad7..e8c4e68998 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -7,7 +7,6 @@ uk: hosted_on: Mastodon розміщено на %{domain} title: Про програму accounts: - follow: ПідпиÑатиÑÑ followers: few: ПідпиÑники many: ПідпиÑників @@ -1800,27 +1799,12 @@ uk: edited_at_html: Відредаговано %{date} errors: in_reply_not_found: ДопиÑу, на Ñкий ви намагаєтеÑÑ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ñти, не Ñ–Ñнує. - open_in_web: Відкрити у вебі over_character_limit: перевищено ліміт Ñимволів %{max} pin_errors: direct: Ðе можливо прикріпити допиÑи, Ñкі видимі лише згаданим кориÑтувачам limit: Ви вже закріпили макÑимальну кількіÑть допиÑів ownership: Ðе можна закріпити чужий Ð´Ð¾Ð¿Ð¸Ñ reblog: Ðе можна закріпити проÑунутий Ð´Ð¾Ð¿Ð¸Ñ - poll: - total_people: - few: "%{count} людей" - many: "%{count} людей" - one: "%{count} людина" - other: "%{count} людей" - total_votes: - few: "%{count} голоÑа" - many: "%{count} голоÑів" - one: "%{count} голоÑ" - other: "%{count} голоÑи" - vote: ПроголоÑувати - show_more: Розгорнути - show_thread: Відкрити Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ title: '%{name}: "%{quote}"' visibilities: direct: ОÑобиÑто diff --git a/config/locales/uz.yml b/config/locales/uz.yml index 403ffd33cf..9215a0f0e8 100644 --- a/config/locales/uz.yml +++ b/config/locales/uz.yml @@ -2,8 +2,6 @@ uz: about: title: Haqida - accounts: - follow: Obuna bo‘lish admin: accounts: display_name: Ko'rsatiladigan nom diff --git a/config/locales/vi.yml b/config/locales/vi.yml index dfb36c02da..a03b46c911 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -7,7 +7,6 @@ vi: hosted_on: "%{domain} váºn hà nh nhá» Mastodon" title: Giá»›i thiệu accounts: - follow: Theo dõi followers: other: Ngưá»i theo dõi following: Theo dõi @@ -1703,21 +1702,12 @@ vi: edited_at_html: Sá»a %{date} errors: in_reply_not_found: Bạn Ä‘ang trả lá»i má»™t tút không còn tồn tại. - open_in_web: Xem trong web over_character_limit: vượt quá giá»›i hạn %{max} ký tá»± pin_errors: direct: Không thể ghim những tút nhắn riêng limit: Bạn đã ghim quá số lượng tút cho phép ownership: Không thể ghim tút cá»§a ngưá»i khác reblog: Không thể ghim tút đăng lại - poll: - total_people: - other: "%{count} ngưá»i bình chá»n" - total_votes: - other: "%{count} ngưá»i bình chá»n" - vote: Bình chá»n - show_more: Äá»c thêm - show_thread: Ná»™i dung gốc title: '%{name}: "%{quote}"' visibilities: direct: Nhắn riêng diff --git a/config/locales/zgh.yml b/config/locales/zgh.yml index 180fcf2f16..cbd0bc961b 100644 --- a/config/locales/zgh.yml +++ b/config/locales/zgh.yml @@ -1,7 +1,6 @@ --- zgh: accounts: - follow: ⴹⴼⵕ followers: one: ⴰⵎⴹⴼⴰⵕ other: ⵉⵎⴹⴼⴰⵕⵠdiff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 747dcf3738..277785f683 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -7,7 +7,6 @@ zh-CN: hosted_on: è¿è¡Œåœ¨ %{domain} 上的 Mastodon 实例 title: 关于本站 accounts: - follow: 关注 followers: other: 关注者 following: æ£åœ¨å…³æ³¨ @@ -1710,21 +1709,12 @@ zh-CN: edited_at_html: 编辑于 %{date} errors: in_reply_not_found: ä½ å›žå¤çš„嘟文似乎ä¸å˜åœ¨ - open_in_web: 在站内打开 over_character_limit: 超过了 %{max} å—çš„é™åˆ¶ pin_errors: direct: 仅对被æåŠçš„用户å¯è§çš„帖åä¸èƒ½è¢«ç½®é¡¶ limit: ä½ æ‰€å›ºå®šçš„å˜Ÿæ–‡æ•°é‡å·²è¾¾åˆ°ä¸Šé™ ownership: ä¸èƒ½ç½®é¡¶åˆ«äººçš„嘟文 reblog: ä¸èƒ½ç½®é¡¶è½¬å˜Ÿ - poll: - total_people: - other: "%{count} 人" - total_votes: - other: "%{count} 票" - vote: 投票 - show_more: 显示更多 - show_thread: æ˜¾ç¤ºå…¨éƒ¨å¯¹è¯ title: "%{name}:“%{quote}â€" visibilities: direct: ç§ä¿¡ diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 90227b911d..7682712759 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -7,7 +7,6 @@ zh-HK: hosted_on: 在 %{domain} é‹ä½œçš„ Mastodon 伺æœå™¨ title: 關於 accounts: - follow: 關注 followers: other: 關注者 following: æ£åœ¨é—œæ³¨ @@ -1607,21 +1606,12 @@ zh-HK: edited_at_html: 編輯於 %{date} errors: in_reply_not_found: ä½ æ‰€å›žè¦†çš„å˜Ÿæ–‡ä¸¦ä¸å˜åœ¨ã€‚ - open_in_web: 開啟網é over_character_limit: è¶…éŽäº† %{max} å—çš„é™åˆ¶ pin_errors: direct: ç„¡æ³•å°‡åªæœ‰è¢«æåŠä½¿ç”¨è€…å¯è¦‹çš„å¸–æ–‡ç½®é ‚ limit: ä½ æ‰€ç½®é ‚çš„æ–‡ç« æ•¸é‡å·²ç¶“é”åˆ°ä¸Šé™ ownership: ä¸èƒ½ç½®é ‚ä»–äººçš„æ–‡ç« reblog: ä¸èƒ½ç½®é ‚轉推 - poll: - total_people: - other: "%{count} 人" - total_votes: - other: "%{count} 票" - vote: 投票 - show_more: 顯示更多 - show_thread: 顯示討論串 title: "%{name}:「%{quote}ã€" visibilities: direct: ç§äººè¨Šæ¯ diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 8eab176d7d..35f000b601 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -7,7 +7,6 @@ zh-TW: hosted_on: æ–¼ %{domain} 託管之 Mastodon 站點 title: 關於本站 accounts: - follow: 跟隨 followers: other: 跟隨者 following: æ£åœ¨è·Ÿéš¨ @@ -1712,21 +1711,12 @@ zh-TW: edited_at_html: 編輯於 %{date} errors: in_reply_not_found: 您嘗試回覆的嘟文看起來ä¸å˜åœ¨ã€‚ - open_in_web: 以網é 開啟 over_character_limit: å·²è¶…éŽ %{max} å—çš„é™åˆ¶ pin_errors: direct: 無法釘é¸åªæœ‰åƒ…æåŠä½¿ç”¨è€…å¯è¦‹ä¹‹å˜Ÿæ–‡ limit: 釘é¸å˜Ÿæ–‡çš„æ•¸é‡å·²é”ä¸Šé™ ownership: ä¸èƒ½é‡˜é¸ä»–人的嘟文 reblog: ä¸èƒ½é‡˜é¸è½‰å˜Ÿ - poll: - total_people: - other: "%{count} 個人" - total_votes: - other: "%{count} 票" - vote: 投票 - show_more: 顯示更多 - show_thread: 顯示討論串 title: "%{name}:「%{quote}ã€" visibilities: direct: ç§è¨Š diff --git a/public/embed.js b/public/embed.js index f8e6a22db4..3fb57469a9 100644 --- a/public/embed.js +++ b/public/embed.js @@ -1,5 +1,7 @@ // @ts-check +const allowedPrefixes = (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.dataset.allowedPrefixes) ? document.currentScript.dataset.allowedPrefixes.split(' ') : []; + (function () { 'use strict'; @@ -18,45 +20,102 @@ } }; + /** + * @param {Map} map + */ + var generateId = function (map) { + var id = 0, failCount = 0, idBuffer = new Uint32Array(1); + + while (id === 0 || map.has(id)) { + id = crypto.getRandomValues(idBuffer)[0]; + failCount++; + + if (failCount > 100) { + // give up and assign (easily guessable) unique number if getRandomValues is broken or no luck + id = -(map.size + 1); + break; + } + } + + return id; + }; + ready(function () { - /** @type {Map<number, HTMLIFrameElement>} */ - var iframes = new Map(); + /** @type {Map<number, HTMLQuoteElement | HTMLIFrameElement>} */ + var embeds = new Map(); window.addEventListener('message', function (e) { var data = e.data || {}; - if (typeof data !== 'object' || data.type !== 'setHeight' || !iframes.has(data.id)) { + if (typeof data !== 'object' || data.type !== 'setHeight' || !embeds.has(data.id)) { return; } - var iframe = iframes.get(data.id); - - if(!iframe) return; + var embed = embeds.get(data.id); - if ('source' in e && iframe.contentWindow !== e.source) { - return; + if (embed instanceof HTMLIFrameElement) { + embed.height = data.height; } - iframe.height = data.height; - }); + if (embed instanceof HTMLQuoteElement) { + var iframe = embed.querySelector('iframe'); - document.querySelectorAll('iframe.mastodon-embed').forEach(iframe => { - // select unique id for each iframe - var id = 0, failCount = 0, idBuffer = new Uint32Array(1); - while (id === 0 || iframes.has(id)) { - id = crypto.getRandomValues(idBuffer)[0]; - failCount++; - if (failCount > 100) { - // give up and assign (easily guessable) unique number if getRandomValues is broken or no luck - id = -(iframes.size + 1); - break; + if (!iframe || ('source' in e && iframe.contentWindow !== e.source)) { + return; } + + iframe.height = data.height; + + var placeholder = embed.querySelector('a'); + + if (!placeholder) return; + + embed.removeChild(placeholder); } + }); + + // Legacy embeds + document.querySelectorAll('iframe.mastodon-embed').forEach(iframe => { + var id = generateId(embeds); + + embeds.set(id, iframe); + + iframe.allow = 'fullscreen'; + iframe.sandbox = 'allow-scripts allow-same-origin'; + iframe.style.border = 0; + iframe.style.overflow = 'hidden'; + iframe.style.display = 'block'; + + iframe.onload = function () { + iframe.contentWindow.postMessage({ + type: 'setHeight', + id: id, + }, '*'); + }; + + iframe.onload(); // In case the script is executing after the iframe has already loaded + }); + + // New generation of embeds + document.querySelectorAll('blockquote.mastodon-embed').forEach(container => { + var id = generateId(embeds); + + embeds.set(id, container); + + var iframe = document.createElement('iframe'); + var embedUrl = new URL(container.getAttribute('data-embed-url')); - iframes.set(id, iframe); + if (embedUrl.protocol !== 'https:' && embedUrl.protocol !== 'http:') return; + if (allowedPrefixes.every((allowedPrefix) => !embedUrl.toString().startsWith(allowedPrefix))) return; - iframe.scrolling = 'no'; + iframe.src = embedUrl.toString(); + iframe.width = container.clientWidth; + iframe.height = 0; + iframe.allow = 'fullscreen'; + iframe.sandbox = 'allow-scripts allow-same-origin'; + iframe.style.border = 0; iframe.style.overflow = 'hidden'; + iframe.style.display = 'block'; iframe.onload = function () { iframe.contentWindow.postMessage({ @@ -65,7 +124,7 @@ }, '*'); }; - iframe.onload(); + container.appendChild(iframe); }); }); })(); diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index 2d5ff0135b..5042523df8 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -781,7 +781,6 @@ RSpec.describe StatusesController do 'Cache-Control' => include('public'), 'Link' => satisfy { |header| header.to_s.include?('activity+json') } ) - expect(response.body).to include status.text end end diff --git a/spec/helpers/media_component_helper_spec.rb b/spec/helpers/media_component_helper_spec.rb index ec87a707cb..a44b9b8415 100644 --- a/spec/helpers/media_component_helper_spec.rb +++ b/spec/helpers/media_component_helper_spec.rb @@ -32,28 +32,6 @@ RSpec.describe MediaComponentHelper do end end - describe 'render_card_component' do - let(:status) { Fabricate(:status) } - let(:result) { helper.render_card_component(status) } - - before do - PreviewCardsStatus.create(status: status, preview_card: Fabricate(:preview_card)) - end - - it 'returns the correct react component markup' do - expect(parsed_html.div['data-component']).to eq('Card') - end - end - - describe 'render_poll_component' do - let(:status) { Fabricate(:status, poll: Fabricate(:poll)) } - let(:result) { helper.render_poll_component(status) } - - it 'returns the correct react component markup' do - expect(parsed_html.div['data-component']).to eq('Poll') - end - end - private def parsed_html -- GitLab