diff --git a/Dockerfile b/Dockerfile index 1c9c956b72..c64d529918 100644 --- a/Dockerfile +++ b/Dockerfile @@ -183,7 +183,7 @@ FROM build AS libvips # libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"] # renovate: datasource=github-releases depName=libvips packageName=libvips/libvips -ARG VIPS_VERSION=8.17.2 +ARG VIPS_VERSION=8.17.3 # libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"] ARG VIPS_URL=https://github.com/libvips/libvips/releases/download diff --git a/Gemfile b/Gemfile index 7d219344b6..f5b1753aa6 100644 --- a/Gemfile +++ b/Gemfile @@ -138,7 +138,7 @@ group :test do # Browser integration testing gem 'capybara', '~> 3.39' gem 'capybara-playwright-driver' - gem 'playwright-ruby-client', '1.55.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package + gem 'playwright-ruby-client', '1.56.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package # Used to reset the database between system tests gem 'database_cleaner-active_record' diff --git a/Gemfile.lock b/Gemfile.lock index 2a0da53d4b..82473c8a32 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -346,7 +346,7 @@ GEM azure-blob (~> 0.5.2) hashie (~> 5.0) jmespath (1.6.2) - json (2.15.1) + json (2.15.2) json-canonicalization (1.0.0) json-jwt (1.17.0) activesupport (>= 4.2) @@ -465,7 +465,7 @@ GEM nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.11) + oj (3.16.12) bigdecimal (>= 3.0) ostruct (>= 0.2) omniauth (2.1.4) @@ -581,7 +581,7 @@ GEM ox (2.14.23) bigdecimal (>= 3.0) parallel (1.27.0) - parser (3.3.9.0) + parser (3.3.10.0) ast (~> 2.4.1) racc parslet (2.0.0) @@ -590,7 +590,7 @@ GEM pg (1.6.2) pghero (3.7.0) activerecord (>= 7.1) - playwright-ruby-client (1.55.0) + playwright-ruby-client (1.56.0) concurrent-ruby (>= 1.1.6) mime-types (>= 3.0) pp (0.6.3) @@ -745,7 +745,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 9) rspec-support (3.13.6) - rubocop (1.81.6) + rubocop (1.81.7) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -911,7 +911,7 @@ GEM activesupport faraday (~> 2.0) faraday-follow_redirects - webmock (3.26.0) + webmock (3.26.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -1028,7 +1028,7 @@ DEPENDENCIES parslet pg (~> 1.5) pghero - playwright-ruby-client (= 1.55.0) + playwright-ruby-client (= 1.56.0) premailer-rails prometheus_exporter (~> 2.2) propshaft diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 84ba142b70..b0eb6b0af7 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -128,10 +128,11 @@ class Api::V1::StatusesController < Api::BaseController @status = Status.where(account: current_account).find(params[:id]) authorize @status, :destroy? + json = render_to_body json: @status, serializer: REST::StatusSerializer, source_requested: true + @status.discard_with_reblogs StatusPin.find_by(status: @status)&.destroy @status.account.statuses_count = @status.account.statuses_count - 1 - json = render_to_body json: @status, serializer: REST::StatusSerializer, source_requested: true RemovalWorker.perform_async(@status.id, { 'redraft' => !truthy_param?(:delete_media) }) diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index b6f43cb82a..909129c11b 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -7,6 +7,7 @@ class FollowerAccountsController < ApplicationController vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' } before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? } + before_action :protect_hidden_collections, if: -> { request.format.json? } skip_around_action :set_locale, if: -> { request.format == :json } skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -18,8 +19,6 @@ class FollowerAccountsController < ApplicationController end format.json do - raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? - expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) render json: collection_presenter, @@ -41,6 +40,10 @@ class FollowerAccountsController < ApplicationController @follows = scope.recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account) end + def protect_hidden_collections + raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? + end + def page_requested? params[:page].present? end diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 803d6e342a..7a0f37887d 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -7,6 +7,7 @@ class FollowingAccountsController < ApplicationController vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' } before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? } + before_action :protect_hidden_collections, if: -> { request.format.json? } skip_around_action :set_locale, if: -> { request.format == :json } skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -18,11 +19,6 @@ class FollowingAccountsController < ApplicationController end format.json do - if page_requested? && @account.hide_collections? - forbidden - next - end - expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) render json: collection_presenter, @@ -44,6 +40,10 @@ class FollowingAccountsController < ApplicationController @follows = scope.recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account) end + def protect_hidden_collections + raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? + end + def page_requested? params[:page].present? end diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index b85c0dc509..da03ddb5a6 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -5,6 +5,7 @@ import { throttle } from 'lodash'; import api from 'mastodon/api'; import { browserHistory } from 'mastodon/components/router'; +import { countableText } from 'mastodon/features/compose/util/counter'; import { search as emojiSearch } from 'mastodon/features/emoji/emoji_mart_search_light'; import { tagHistory } from 'mastodon/settings'; @@ -88,6 +89,7 @@ const messages = defineMessages({ open: { id: 'compose.published.open', defaultMessage: 'Open' }, published: { id: 'compose.published.body', defaultMessage: 'Post published.' }, saved: { id: 'compose.saved.body', defaultMessage: 'Post saved.' }, + blankPostError: { id: 'compose.error.blank_post', defaultMessage: 'Post can\'t be blank.' }, }); export const ensureComposeIsVisible = (getState) => { @@ -197,7 +199,15 @@ export function submitCompose(successCallback) { const hasQuote = !!getState().getIn(['compose', 'quoted_status_id']); const spoiler_text = getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : ''; - if (!(status?.length || media.size !== 0 || (hasQuote && spoiler_text?.length))) { + const fulltext = `${spoiler_text ?? ''}${countableText(status ?? '')}`; + const hasText = fulltext.trim().length > 0; + + if (!(hasText || media.size !== 0 || (hasQuote && spoiler_text?.length))) { + dispatch(showAlert({ + message: messages.blankPostError, + })); + dispatch(focusCompose()); + return; } diff --git a/app/javascript/mastodon/components/carousel/carousel.stories.tsx b/app/javascript/mastodon/components/carousel/carousel.stories.tsx new file mode 100644 index 0000000000..5117bc08e3 --- /dev/null +++ b/app/javascript/mastodon/components/carousel/carousel.stories.tsx @@ -0,0 +1,126 @@ +import type { FC } from 'react'; + +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { fn, userEvent, expect } from 'storybook/test'; + +import type { CarouselProps } from './index'; +import { Carousel } from './index'; + +interface TestSlideProps { + id: number; + text: string; + color: string; +} + +const TestSlide: FC = ({ + active, + text, + color, +}) => ( +
+ {text} +
+); + +const slides: TestSlideProps[] = [ + { + id: 1, + text: 'first', + color: 'red', + }, + { + id: 2, + text: 'second', + color: 'pink', + }, + { + id: 3, + text: 'third', + color: 'orange', + }, +]; + +type StoryProps = Pick< + CarouselProps, + 'items' | 'renderItem' | 'emptyFallback' | 'onChangeSlide' +>; + +const meta = { + title: 'Components/Carousel', + args: { + items: slides, + renderItem(item, active) { + return ; + }, + onChangeSlide: fn(), + emptyFallback: 'No slides available', + }, + render(args) { + return ( + <> + + + + ); + }, + argTypes: { + emptyFallback: { + type: 'string', + }, + }, + tags: ['test'], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + async play({ args, canvas }) { + const nextButton = await canvas.findByRole('button', { name: /next/i }); + const slides = await canvas.findAllByRole('group'); + await expect(slides).toHaveLength(slides.length); + + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(1, slides[1]); + + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(2, slides[2]); + + // Wrap around + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(0, slides[0]); + }, +}; + +export const DifferentHeights: Story = { + args: { + items: slides.map((props, index) => ({ + ...props, + styles: { height: 100 + index * 100 }, + })), + }, +}; + +export const NoSlides: Story = { + args: { + items: [], + }, +}; diff --git a/app/javascript/mastodon/components/carousel/index.tsx b/app/javascript/mastodon/components/carousel/index.tsx new file mode 100644 index 0000000000..f5d772fd38 --- /dev/null +++ b/app/javascript/mastodon/components/carousel/index.tsx @@ -0,0 +1,244 @@ +import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import type { + ComponentPropsWithoutRef, + ComponentType, + ReactElement, + ReactNode, +} from 'react'; + +import type { MessageDescriptor } from 'react-intl'; +import { defineMessages, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import { usePrevious } from '@dnd-kit/utilities'; +import { animated, useSpring } from '@react-spring/web'; +import { useDrag } from '@use-gesture/react'; + +import type { CarouselPaginationProps } from './pagination'; +import { CarouselPagination } from './pagination'; + +import './styles.scss'; + +const defaultMessages = defineMessages({ + previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, + next: { id: 'lightbox.next', defaultMessage: 'Next' }, + current: { + id: 'carousel.current', + defaultMessage: 'Slide {current, number} / {max, number}', + }, + slide: { + id: 'carousel.slide', + defaultMessage: 'Slide {current, number} of {max, number}', + }, +}); + +export type MessageKeys = keyof typeof defaultMessages; + +export interface CarouselSlideProps { + id: string | number; +} + +export type RenderSlideFn< + SlideProps extends CarouselSlideProps = CarouselSlideProps, +> = (item: SlideProps, active: boolean, index: number) => ReactElement; + +export interface CarouselProps< + SlideProps extends CarouselSlideProps = CarouselSlideProps, +> { + items: SlideProps[]; + renderItem: RenderSlideFn; + onChangeSlide?: (index: number, ref: Element) => void; + paginationComponent?: ComponentType | null; + paginationProps?: Partial; + messages?: Record; + emptyFallback?: ReactNode; + classNamePrefix?: string; + slideClassName?: string; +} + +export const Carousel = < + SlideProps extends CarouselSlideProps = CarouselSlideProps, +>({ + items, + renderItem, + onChangeSlide, + paginationComponent: Pagination = CarouselPagination, + paginationProps = {}, + messages = defaultMessages, + children, + emptyFallback = null, + className, + classNamePrefix = 'carousel', + slideClassName, + ...wrapperProps +}: CarouselProps & ComponentPropsWithoutRef<'div'>) => { + // Handle slide change + const [slideIndex, setSlideIndex] = useState(0); + const wrapperRef = useRef(null); + const handleSlideChange = useCallback( + (direction: number) => { + setSlideIndex((prev) => { + const max = items.length - 1; + let newIndex = prev + direction; + if (newIndex < 0) { + newIndex = max; + } else if (newIndex > max) { + newIndex = 0; + } + + const slide = wrapperRef.current?.children[newIndex]; + if (slide) { + setCurrentSlideHeight(slide.scrollHeight); + if (slide instanceof HTMLElement) { + onChangeSlide?.(newIndex, slide); + } + } + + return newIndex; + }); + }, + [items.length, onChangeSlide], + ); + + // Handle slide heights + const [currentSlideHeight, setCurrentSlideHeight] = useState( + wrapperRef.current?.scrollHeight ?? 0, + ); + const previousSlideHeight = usePrevious(currentSlideHeight); + const observerRef = useRef( + new ResizeObserver(() => { + handleSlideChange(0); + }), + ); + const wrapperStyles = useSpring({ + x: `-${slideIndex * 100}%`, + height: currentSlideHeight, + // Don't animate from zero to the height of the initial slide + immediate: !previousSlideHeight, + }); + useLayoutEffect(() => { + // Update slide height when the component mounts + if (currentSlideHeight === 0) { + handleSlideChange(0); + } + }, [currentSlideHeight, handleSlideChange]); + + // Handle swiping animations + const bind = useDrag( + ({ swipe: [swipeX] }) => { + handleSlideChange(swipeX * -1); // Invert swipe as swiping left loads the next slide. + }, + { pointer: { capture: false } }, + ); + const handlePrev = useCallback(() => { + handleSlideChange(-1); + // We're focusing on the wrapper as the child slides can potentially be inert. + // Because of that, only the active slide can be focused anyway. + wrapperRef.current?.focus(); + }, [handleSlideChange]); + const handleNext = useCallback(() => { + handleSlideChange(1); + wrapperRef.current?.focus(); + }, [handleSlideChange]); + + const intl = useIntl(); + + if (items.length === 0) { + return emptyFallback; + } + + return ( +
+
+ {children} + {Pagination && items.length > 1 && ( + + )} +
+ + + {items.map((itemsProps, index) => ( + + item={itemsProps} + renderItem={renderItem} + observer={observerRef.current} + index={index} + key={`slide-${itemsProps.id}`} + className={classNames(`${classNamePrefix}__slide`, slideClassName, { + active: index === slideIndex, + })} + active={index === slideIndex} + /> + ))} + +
+ ); +}; + +type CarouselSlideWrapperProps = { + observer: ResizeObserver; + className: string; + active: boolean; + item: SlideProps; + index: number; +} & Pick, 'renderItem'>; + +const CarouselSlideWrapper = ({ + observer, + className, + active, + renderItem, + item, + index, +}: CarouselSlideWrapperProps) => { + const handleRef = useCallback( + (instance: HTMLDivElement | null) => { + if (instance) { + observer.observe(instance); + } + }, + [observer], + ); + + const children = useMemo( + () => renderItem(item, active, index), + [renderItem, item, active, index], + ); + + return ( +
+ {children} +
+ ); +}; diff --git a/app/javascript/mastodon/components/carousel/pagination.tsx b/app/javascript/mastodon/components/carousel/pagination.tsx new file mode 100644 index 0000000000..a2666f486f --- /dev/null +++ b/app/javascript/mastodon/components/carousel/pagination.tsx @@ -0,0 +1,54 @@ +import type { FC, MouseEventHandler } from 'react'; + +import type { MessageDescriptor } from 'react-intl'; +import { useIntl } from 'react-intl'; + +import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; + +import { IconButton } from '../icon_button'; + +import type { MessageKeys } from './index'; + +export interface CarouselPaginationProps { + onNext: MouseEventHandler; + onPrev: MouseEventHandler; + current: number; + max: number; + className?: string; + messages: Record; +} + +export const CarouselPagination: FC = ({ + onNext, + onPrev, + current, + max, + className = '', + messages, +}) => { + const intl = useIntl(); + return ( +
+ + + {intl.formatMessage(messages.current, { + current: current + 1, + max, + sr: (chunk) => {chunk}, + })} + + +
+ ); +}; diff --git a/app/javascript/mastodon/components/carousel/styles.scss b/app/javascript/mastodon/components/carousel/styles.scss new file mode 100644 index 0000000000..bcd0bc7d3a --- /dev/null +++ b/app/javascript/mastodon/components/carousel/styles.scss @@ -0,0 +1,28 @@ +.carousel { + gap: 16px; + overflow: hidden; + touch-action: pan-y; + + &__header { + padding: 8px 16px; + } + + &__pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + } + + &__slides { + display: flex; + flex-wrap: nowrap; + align-items: start; + } + + &__slide { + flex: 0 0 100%; + width: 100%; + overflow: hidden; + } +} diff --git a/app/javascript/mastodon/components/featured_carousel.tsx b/app/javascript/mastodon/components/featured_carousel.tsx index df64c43b42..c35f2f37f0 100644 --- a/app/javascript/mastodon/components/featured_carousel.tsx +++ b/app/javascript/mastodon/components/featured_carousel.tsx @@ -1,38 +1,43 @@ -import type { ComponentPropsWithRef } from 'react'; -import { - useCallback, - useEffect, - useLayoutEffect, - useRef, - useState, - useId, -} from 'react'; +import { useCallback, useEffect, useId } from 'react'; -import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; +import { defineMessages, FormattedMessage } from 'react-intl'; import type { Map as ImmutableMap } from 'immutable'; import { List as ImmutableList } from 'immutable'; -import type { AnimatedProps } from '@react-spring/web'; -import { animated, useSpring } from '@react-spring/web'; -import { useDrag } from '@use-gesture/react'; - import { expandAccountFeaturedTimeline } from '@/mastodon/actions/timelines'; import { Icon } from '@/mastodon/components/icon'; -import { IconButton } from '@/mastodon/components/icon_button'; import { StatusQuoteManager } from '@/mastodon/components/status_quoted'; -import { usePrevious } from '@/mastodon/hooks/usePrevious'; -import { useAppDispatch, useAppSelector } from '@/mastodon/store'; -import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; -import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; +import { + createAppSelector, + useAppDispatch, + useAppSelector, +} from '@/mastodon/store'; import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react'; +import { Carousel } from './carousel'; + +const pinnedStatusesSelector = createAppSelector( + [ + (state, accountId: string, tagged?: string) => + (state.timelines as ImmutableMap).getIn( + [`account:${accountId}:pinned${tagged ? `:${tagged}` : ''}`, 'items'], + ImmutableList(), + ) as ImmutableList, + ], + (items) => items.toArray().map((id) => ({ id })), +); + const messages = defineMessages({ - previous: { id: 'featured_carousel.previous', defaultMessage: 'Previous' }, - next: { id: 'featured_carousel.next', defaultMessage: 'Next' }, + previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, + next: { id: 'lightbox.next', defaultMessage: 'Next' }, + current: { + id: 'featured_carousel.current', + defaultMessage: 'Post {current, number} / {max, number}', + }, slide: { id: 'featured_carousel.slide', - defaultMessage: '{index} of {total}', + defaultMessage: 'Post {current, number} of {max, number}', }, }); @@ -40,7 +45,6 @@ export const FeaturedCarousel: React.FC<{ accountId: string; tagged?: string; }> = ({ accountId, tagged }) => { - const intl = useIntl(); const accessibilityId = useId(); // Load pinned statuses @@ -50,175 +54,37 @@ export const FeaturedCarousel: React.FC<{ void dispatch(expandAccountFeaturedTimeline(accountId, { tagged })); } }, [accountId, dispatch, tagged]); - const pinnedStatuses = useAppSelector( - (state) => - (state.timelines as ImmutableMap).getIn( - [`account:${accountId}:pinned${tagged ? `:${tagged}` : ''}`, 'items'], - ImmutableList(), - ) as ImmutableList, + const pinnedStatuses = useAppSelector((state) => + pinnedStatusesSelector(state, accountId, tagged), ); - // Handle slide change - const [slideIndex, setSlideIndex] = useState(0); - const wrapperRef = useRef(null); - const handleSlideChange = useCallback( - (direction: number) => { - setSlideIndex((prev) => { - const max = pinnedStatuses.size - 1; - let newIndex = prev + direction; - if (newIndex < 0) { - newIndex = max; - } else if (newIndex > max) { - newIndex = 0; - } - const slide = wrapperRef.current?.children[newIndex]; - if (slide) { - setCurrentSlideHeight(slide.scrollHeight); - } - return newIndex; - }); - }, - [pinnedStatuses.size], + const renderSlide = useCallback( + ({ id }: { id: string }) => ( + + ), + [], ); - // Handle slide heights - const [currentSlideHeight, setCurrentSlideHeight] = useState( - wrapperRef.current?.scrollHeight ?? 0, - ); - const previousSlideHeight = usePrevious(currentSlideHeight); - const observerRef = useRef( - new ResizeObserver(() => { - handleSlideChange(0); - }), - ); - const wrapperStyles = useSpring({ - x: `-${slideIndex * 100}%`, - height: currentSlideHeight, - // Don't animate from zero to the height of the initial slide - immediate: !previousSlideHeight, - }); - useLayoutEffect(() => { - // Update slide height when the component mounts - if (currentSlideHeight === 0) { - handleSlideChange(0); - } - }, [currentSlideHeight, handleSlideChange]); - - // Handle swiping animations - const bind = useDrag(({ swipe: [swipeX] }) => { - handleSlideChange(swipeX * -1); // Invert swipe as swiping left loads the next slide. - }); - const handlePrev = useCallback(() => { - handleSlideChange(-1); - }, [handleSlideChange]); - const handleNext = useCallback(() => { - handleSlideChange(1); - }, [handleSlideChange]); - - if (!accountId || pinnedStatuses.isEmpty()) { + if (!accountId || pinnedStatuses.length === 0) { return null; } return ( -
-
-

- - -

- {pinnedStatuses.size > 1 && ( - <> - - - - {(text) => {text}} - - {slideIndex + 1} / {pinnedStatuses.size} - - - - )} -
- - {pinnedStatuses.map((statusId, index) => ( - - ))} - -
- ); -}; - -interface FeaturedCarouselItemProps { - statusId: string; - active: boolean; - observer: ResizeObserver; -} - -const FeaturedCarouselItem: React.FC< - FeaturedCarouselItemProps & AnimatedProps> -> = ({ statusId, active, observer, ...props }) => { - const handleRef = useCallback( - (instance: HTMLDivElement | null) => { - if (instance) { - observer.observe(instance); - } - }, - [observer], - ); - - return ( - - - +

+ + +

+
); }; diff --git a/app/javascript/mastodon/features/about/components/rules.tsx b/app/javascript/mastodon/features/about/components/rules.tsx index e413adb310..078fb68c08 100644 --- a/app/javascript/mastodon/features/about/components/rules.tsx +++ b/app/javascript/mastodon/features/about/components/rules.tsx @@ -32,16 +32,38 @@ interface Rule extends BaseRule { translations?: Record; } +function getDefaultSelectedLocale( + currentUiLocale: string, + localeOptions: SelectItem[], +) { + const preciseMatch = localeOptions.find( + (option) => option.value === currentUiLocale, + ); + if (preciseMatch) { + return preciseMatch.value; + } + + const partialLocale = currentUiLocale.split('-')[0]; + const partialMatch = localeOptions.find( + (option) => option.value.split('-')[0] === partialLocale, + ); + + return partialMatch?.value ?? 'default'; +} + export const RulesSection: FC = ({ isLoading = false }) => { const intl = useIntl(); - const [locale, setLocale] = useState(intl.locale); - const rules = useAppSelector((state) => rulesSelector(state, locale)); const localeOptions = useAppSelector((state) => localeOptionsSelector(state, intl), ); + const [selectedLocale, setSelectedLocale] = useState(() => + getDefaultSelectedLocale(intl.locale, localeOptions), + ); + const rules = useAppSelector((state) => rulesSelector(state, selectedLocale)); + const handleLocaleChange: ChangeEventHandler = useCallback( (e) => { - setLocale(e.currentTarget.value); + setSelectedLocale(e.currentTarget.value); }, [], ); @@ -74,25 +96,27 @@ export const RulesSection: FC = ({ isLoading = false }) => { ))} -
- - -
+ {localeOptions.length > 1 && ( +
+ + +
+ )} ); }; diff --git a/app/javascript/mastodon/features/compose/components/compose_form.jsx b/app/javascript/mastodon/features/compose/components/compose_form.jsx index ac0a496939..299de12e7e 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.jsx +++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx @@ -123,11 +123,10 @@ class ComposeForm extends ImmutablePureComponent { }; canSubmit = () => { - const { isSubmitting, isChangingUpload, isUploading, anyMedia, maxChars } = this.props; + const { isSubmitting, isChangingUpload, isUploading, maxChars } = this.props; const fulltext = this.getFulltextForCharacterCounting(); - const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0; - return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia)); + return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars); }; handleSubmit = (e) => { diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx index 8513e6169b..39d3c881b0 100644 --- a/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx @@ -15,24 +15,24 @@ export interface IAnnouncement extends ApiAnnouncementJSON { interface AnnouncementProps { announcement: IAnnouncement; - selected: boolean; + active?: boolean; } export const Announcement: FC = ({ announcement, - selected, + active, }) => { const [unread, setUnread] = useState(!announcement.read); useEffect(() => { // Only update `unread` marker once the announcement is out of view - if (!selected && unread !== !announcement.read) { + if (!active && unread !== !announcement.read) { setUnread(!announcement.read); } - }, [announcement.read, selected, unread]); + }, [announcement.read, active, unread]); return ( - - + + = ({ - {unread && } + {unread && } ); }; diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx index 335e0f1a38..cb44e1d075 100644 --- a/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx @@ -1,63 +1,50 @@ -import { useCallback, useState } from 'react'; +import { useCallback } from 'react'; import type { FC } from 'react'; -import { defineMessages, useIntl } from 'react-intl'; - import type { Map, List } from 'immutable'; -import ReactSwipeableViews from 'react-swipeable-views'; - import elephantUIPlane from '@/images/elephant_ui_plane.svg'; +import type { RenderSlideFn } from '@/mastodon/components/carousel'; +import { Carousel } from '@/mastodon/components/carousel'; import { CustomEmojiProvider } from '@/mastodon/components/emoji/context'; -import { IconButton } from '@/mastodon/components/icon_button'; -import { mascot, reduceMotion } from '@/mastodon/initial_state'; +import { mascot } from '@/mastodon/initial_state'; import { createAppSelector, useAppSelector } from '@/mastodon/store'; -import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; -import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import type { IAnnouncement } from './announcement'; import { Announcement } from './announcement'; -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, - previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, - next: { id: 'lightbox.next', defaultMessage: 'Next' }, -}); - const announcementSelector = createAppSelector( [(state) => state.announcements as Map>>], (announcements) => - (announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? [], + ((announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? []) + .map((announcement) => ({ announcement, id: announcement.id })) + .toReversed(), ); export const Announcements: FC = () => { - const intl = useIntl(); - const announcements = useAppSelector(announcementSelector); const emojis = useAppSelector((state) => state.custom_emojis); - const [index, setIndex] = useState(0); - const handleChangeIndex = useCallback( - (idx: number) => { - setIndex(idx % announcements.length); - }, - [announcements.length], + const renderSlide: RenderSlideFn<{ + id: string; + announcement: IAnnouncement; + }> = useCallback( + (item, active) => ( + + ), + [], ); - const handleNextIndex = useCallback(() => { - setIndex((prevIndex) => (prevIndex + 1) % announcements.length); - }, [announcements.length]); - const handlePrevIndex = useCallback(() => { - setIndex((prevIndex) => - prevIndex === 0 ? announcements.length - 1 : prevIndex - 1, - ); - }, [announcements.length]); if (announcements.length === 0) { return null; } return ( -
+
{ src={mascot ?? elephantUIPlane} /> -
- - - {announcements - .map((announcement, idx) => ( - - )) - .reverse()} - - - - {announcements.length > 1 && ( -
- - - {index + 1} / {announcements.length} - - -
- )} -
+ + +
); }; diff --git a/app/javascript/mastodon/features/ui/components/link_footer.tsx b/app/javascript/mastodon/features/ui/components/link_footer.tsx index cbfb6a3114..df153b2258 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.tsx +++ b/app/javascript/mastodon/features/ui/components/link_footer.tsx @@ -21,7 +21,10 @@ export const LinkFooter: React.FC<{

{domain}:{' '} - + {statusPageUrl && ( <> diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 514a8d7f28..0471131678 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -347,10 +347,6 @@ "explore.trending_statuses": "المنشورات", "explore.trending_tags": "وُسُوم", "featured_carousel.header": "{count, plural, zero {}one {منشور معروض} two {منشور معروضَين} few {منشورات معروضة} many {منشورات معروضة} other {منشورات معروضة}}", - "featured_carousel.next": "التالي", - "featured_carousel.post": "منشور", - "featured_carousel.previous": "السابق", - "featured_carousel.slide": "{index} من {total}", "filter_modal.added.context_mismatch_explanation": "فئة عامل التصفية هذه لا تنطبق على السياق الذي وصلت فيه إلى هذه المشاركة. إذا كنت ترغب في تصفية المنشور في هذا السياق أيضا، فسيتعين عليك تعديل عامل التصفية.", "filter_modal.added.context_mismatch_title": "عدم تطابق السياق!", "filter_modal.added.expired_explanation": "انتهت صلاحية فئة عامل التصفية هذه، سوف تحتاج إلى تغيير تاريخ انتهاء الصلاحية لتطبيقها.", diff --git a/app/javascript/mastodon/locales/az.json b/app/javascript/mastodon/locales/az.json index 720719d84d..24c101c338 100644 --- a/app/javascript/mastodon/locales/az.json +++ b/app/javascript/mastodon/locales/az.json @@ -339,10 +339,6 @@ "explore.trending_statuses": "Göndərişlər", "explore.trending_tags": "Mövzu etiketləri", "featured_carousel.header": "{count, plural, one {Sancılmış göndəriş} other {Sancılmış göndərişlər}}", - "featured_carousel.next": "Növbəti", - "featured_carousel.post": "Göndəriş", - "featured_carousel.previous": "Əvvəlki", - "featured_carousel.slide": "{index}/{total}", "filter_modal.added.context_mismatch_explanation": "Bu filtr kateqoriyası, bu göndərişdə erişdiyiniz kontekstə aid deyil. Əgər göndərişin bu kontekstdə də filtrlənməsini istəyirsinizsə, filtrə düzəliş etməyiniz lazımdır.", "filter_modal.added.context_mismatch_title": "Kontekst uyuşmur!", "filter_modal.added.expired_explanation": "Bu filtr kateqoriyasının vaxtı bitib, filtri tətbiq etmək üçün bitmə tarixini dəyişdirməlisiniz.", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index d257ed9f4d..461d69353f 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Закрыць", "bundle_modal_error.message": "Падчас загрузкі гэтага экрана штосьці пайшло не так.", "bundle_modal_error.retry": "Паспрабуйце зноў", + "carousel.current": "Слайд {current, number} з {max, number}", + "carousel.slide": "Слайд {current, number} з {max, number}", "closed_registrations.other_server_instructions": "Паколькі Mastodon дэцэнтралізаваны, вы можаце стварыць уліковы запіс на іншым серверы і працягваць узаемадзейнічаць з ім.", "closed_registrations_modal.description": "Стварэнне ўліковага запісу на {domain} цяпер немагчыма. Заўважце, што няма неабходнасці мець уліковы запіс менавіта на {domain}, каб выкарыстоўваць Mastodon.", "closed_registrations_modal.find_another_server": "Знайсці іншы сервер", @@ -360,11 +362,9 @@ "explore.trending_links": "Навіны", "explore.trending_statuses": "Допісы", "explore.trending_tags": "Хэштэгі", + "featured_carousel.current": "Допіс {current, number} з {max, number}", "featured_carousel.header": "{count, plural,one {Замацаваны допіс} other {Замацаваныя допісы}}", - "featured_carousel.next": "Далей", - "featured_carousel.post": "Допіс", - "featured_carousel.previous": "Назад", - "featured_carousel.slide": "{index} з {total}", + "featured_carousel.slide": "Допіс {current, number} з {max, number}", "filter_modal.added.context_mismatch_explanation": "Гэтая катэгорыя фільтра не прымяняецца да кантэксту, у якім Вы адкрылі гэты допіс. Калі Вы хочаце, каб паведамленне таксама было адфільтраванае ў гэтым кантэксце, Вам трэба будзе адрэдагаваць фільтр.", "filter_modal.added.context_mismatch_title": "Неадпаведны кантэкст!", "filter_modal.added.expired_explanation": "Тэрмін дзеяння гэтай катэгорыі фільтраў скончыўся, вам трэба будзе змяніць дату заканчэння тэрміну дзеяння, каб яна прымянялася", @@ -911,9 +911,12 @@ "status.pin": "Замацаваць у профілі", "status.quote": "Цытаваць", "status.quote.cancel": "Адмяніць цытаванне", + "status.quote_error.blocked_account_hint.title": "Гэты допіс схаваны, бо Вы заблакіравалі @{name}.", + "status.quote_error.blocked_domain_hint.title": "Гэты допіс схаваны, бо Вы заблакіравалі @{domain}.", "status.quote_error.filtered": "Схавана адным з Вашых фільтраў", "status.quote_error.limited_account_hint.action": "Усё адно паказаць", "status.quote_error.limited_account_hint.title": "Гэты ўліковы запіс быў схаваны мадэратарамі {domain}.", + "status.quote_error.muted_account_hint.title": "Гэты допіс схаваны, бо Вы вырашылі ігнараваць @{name}.", "status.quote_error.not_available": "Допіс недаступны", "status.quote_error.pending_approval": "Допіс чакае пацвярджэння", "status.quote_error.pending_approval_popout.body": "У Mastodon можна кантраляваць магчымасць іншых цытаваць Вас. Гэты допіс будзе знаходзіцца ў стане чакання, пакуль мы не атрымаем ухваленне на цытаванне ад аўтара арыгінальнага допісу.", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 88df24cbb4..72c511bf74 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -352,10 +352,6 @@ "explore.trending_statuses": "Публикации", "explore.trending_tags": "Хаштагове", "featured_carousel.header": "{count, plural, one {закачена публикация} other {закачени публикации}}", - "featured_carousel.next": "Напред", - "featured_carousel.post": "Публикация", - "featured_carousel.previous": "Назад", - "featured_carousel.slide": "{index} от {total}", "filter_modal.added.context_mismatch_explanation": "Тази категория филтър не е приложима към контекста, в който достъпвате тази публикация. Ако желаете да филтрирате публикациите в този контекст, трябва да изберете друг филтър.", "filter_modal.added.context_mismatch_title": "Несъвпадащ контекст!", "filter_modal.added.expired_explanation": "Валидността на тази категория филтър е изтекла. Сменете срока на валидност, за да я приложите.", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 3d87c0fd93..d58e8764ed 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -300,10 +300,6 @@ "explore.trending_links": "Keleier", "explore.trending_statuses": "Embannadurioù", "explore.trending_tags": "Gerioù-klik", - "featured_carousel.next": "War-raok", - "featured_carousel.post": "Embannadur", - "featured_carousel.previous": "War-gil", - "featured_carousel.slide": "{index} diwar {total}", "filter_modal.added.context_mismatch_title": "Kenarroud digenglotus !", "filter_modal.added.expired_title": "Sil deuet d'e dermen !", "filter_modal.added.review_and_configure_title": "Arventennoù ar sil", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 555f2a4599..62384b8090 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -356,10 +356,6 @@ "explore.trending_statuses": "Tuts", "explore.trending_tags": "Etiquetes", "featured_carousel.header": "{count, plural, one {Publicació fixada} other {Publicacions fixades}}", - "featured_carousel.next": "Següent", - "featured_carousel.post": "Publicació", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Aquesta categoria de filtre no s'aplica al context en què has accedit a aquest tut. Si també vols que el tut es filtri en aquest context, hauràs d'editar el filtre.", "filter_modal.added.context_mismatch_title": "El context no coincideix!", "filter_modal.added.expired_explanation": "La categoria d'aquest filtre ha caducat, necessitaràs canviar la seva data de caducitat per a aplicar-la.", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 3531a64227..bf5b67ed5e 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Zavřít", "bundle_modal_error.message": "Něco se pokazilo při načítání této obrazovky.", "bundle_modal_error.retry": "Zkusit znovu", + "carousel.current": "Snímek {current, number}/{max, number}", + "carousel.slide": "Snímek {current, number} z {max, number}", "closed_registrations.other_server_instructions": "Protože Mastodon je decentralizovaný, můžete si vytvořit účet na jiném serveru a přesto komunikovat s tímto serverem.", "closed_registrations_modal.description": "V současné době není možné vytvořit účet na {domain}, ale mějte prosím na paměti, že k používání Mastodonu nepotřebujete účet konkrétně na {domain}.", "closed_registrations_modal.find_another_server": "Najít jiný server", @@ -173,6 +175,8 @@ "column.edit_list": "Upravit seznam", "column.favourites": "Oblíbené", "column.firehose": "Živé kanály", + "column.firehose_local": "Živý kanál pro tento server", + "column.firehose_singular": "Živý kanál", "column.follow_requests": "Žádosti o sledování", "column.home": "Domů", "column.list_members": "Spravovat členy seznamu", @@ -358,11 +362,9 @@ "explore.trending_links": "Zprávy", "explore.trending_statuses": "Příspěvky", "explore.trending_tags": "Hashtagy", + "featured_carousel.current": "Příspěvek {current, number}/{max, number}", "featured_carousel.header": "{count, plural, one {{counter} zvýrazněný příspěvek} few {{counter} zvýrazněné příspěvky} many {{counter} zvýrazněných příspěvků} other {{counter} zvýrazněných příspěvků}}", - "featured_carousel.next": "Další", - "featured_carousel.post": "Příspěvek", - "featured_carousel.previous": "Předchozí", - "featured_carousel.slide": "{index} z {total}", + "featured_carousel.slide": "Příspěvek {current, number} z {max, number}", "filter_modal.added.context_mismatch_explanation": "Tato kategorie filtrů se nevztahuje na kontext, ve kterém jste tento příspěvek otevřeli. Pokud chcete, aby byl příspěvek filtrován i v tomto kontextu, budete muset filtr upravit.", "filter_modal.added.context_mismatch_title": "Kontext se neshoduje!", "filter_modal.added.expired_explanation": "Tato kategorie filtrů vypršela, budete muset změnit datum vypršení platnosti, aby mohla být použita.", @@ -909,9 +911,12 @@ "status.pin": "Připnout na profil", "status.quote": "Citovat", "status.quote.cancel": "Zrušit citování", + "status.quote_error.blocked_account_hint.title": "Tento příspěvek je skryt, protože jste zablokovali @{name}.", + "status.quote_error.blocked_domain_hint.title": "Tento příspěvek je skryt, protože jste zablokovali {domain}.", "status.quote_error.filtered": "Skryté kvůli jednomu z vašich filtrů", "status.quote_error.limited_account_hint.action": "Přesto zobrazit", "status.quote_error.limited_account_hint.title": "Tento účet byl skryt moderátory {domain}.", + "status.quote_error.muted_account_hint.title": "Tento příspěvek je skryt, protože jste ztišili @{name}.", "status.quote_error.not_available": "Příspěvek není dostupný", "status.quote_error.pending_approval": "Příspěvek čeká na schválení", "status.quote_error.pending_approval_popout.body": "Na Mastodonu můžete kontrolovat, zda vás někdo může citovat. Tento příspěvek čeká, dokud neobdržíme schválení od původního autora.", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 614348d36f..eb3fb66a08 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Postiadau", "explore.trending_tags": "Hashnodau", "featured_carousel.header": "{count, plural, one {Postiad wedi'i binio} other {Postiadau wedi'u pinio}}", - "featured_carousel.next": "Nesaf", - "featured_carousel.post": "Postiad", - "featured_carousel.previous": "Blaenorol", - "featured_carousel.slide": "{index} o {total}", "filter_modal.added.context_mismatch_explanation": "Dyw'r categori hidlo hwn ddim yn berthnasol i'r cyd-destun yr ydych wedi cyrchu'r postiad hwn ynddo. Os ydych chi am i'r postiad gael ei hidlo yn y cyd-destun hwn hefyd, bydd yn rhaid i chi olygu'r hidlydd.", "filter_modal.added.context_mismatch_title": "Diffyg cyfatebiaeth cyd-destun!", "filter_modal.added.expired_explanation": "Mae'r categori hidlydd hwn wedi dod i ben, bydd angen i chi newid y dyddiad dod i ben er mwyn iddo fod yn berthnasol.", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 0e7733196e..3baa9b0d97 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Luk", "bundle_modal_error.message": "Noget gik galt under indlæsningen af denne skærm.", "bundle_modal_error.retry": "Forsøg igen", + "carousel.current": "Dias {current, number} / {max, number}", + "carousel.slide": "Dias {current, number} af {max, number}", "closed_registrations.other_server_instructions": "Da Mastodon er decentraliseret, kan du oprette en konto på en anden server og stadig interagere med denne.", "closed_registrations_modal.description": "Oprettelse af en konto på {domain} er i øjeblikket ikke muligt, men husk på, at du ikke behøver en konto specifikt på {domain} for at bruge Mastodon.", "closed_registrations_modal.find_another_server": "Find en anden server", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Kun lokalt", "community.column_settings.media_only": "Kun medier", "community.column_settings.remote_only": "Kun udefra", + "compose.error.blank_post": "Indlæg kan ikke være tomt.", "compose.language.change": "Skift sprog", "compose.language.search": "Søg efter sprog...", "compose.published.body": "Indlæg udgivet.", @@ -360,11 +363,9 @@ "explore.trending_links": "Nyheder", "explore.trending_statuses": "Indlæg", "explore.trending_tags": "Hashtags", + "featured_carousel.current": "Indlæg {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Fastgjort indlæg} other {Fastgjorte indlæg}}", - "featured_carousel.next": "Næste", - "featured_carousel.post": "Indlæg", - "featured_carousel.previous": "Foregående", - "featured_carousel.slide": "{index} af {total}", + "featured_carousel.slide": "Indlæg {current, number} af {max, number}", "filter_modal.added.context_mismatch_explanation": "Denne filterkategori omfatter ikke konteksten, hvorunder dette indlæg er tilgået. Redigér filteret, hvis indlægget også ønskes filtreret i denne kontekst.", "filter_modal.added.context_mismatch_title": "Kontekstmisforhold!", "filter_modal.added.expired_explanation": "Denne filterkategori er udløbet. Ændr dens udløbsdato, for at anvende den.", @@ -911,9 +912,12 @@ "status.pin": "Fastgør til profil", "status.quote": "Citér", "status.quote.cancel": "Annullér citat", + "status.quote_error.blocked_account_hint.title": "Dette indlæg er skjult, fordi du har blokeret @{name}.", + "status.quote_error.blocked_domain_hint.title": "Dette indlæg er skjult, fordi du har blokeret @{domain}.", "status.quote_error.filtered": "Skjult grundet et af filterne", "status.quote_error.limited_account_hint.action": "Vis alligevel", "status.quote_error.limited_account_hint.title": "Denne profil er blevet skjult af {domain}-moderatorerne.", + "status.quote_error.muted_account_hint.title": "Dette indlæg er skjult, fordi du har skjult @{name}.", "status.quote_error.not_available": "Indlæg utilgængeligt", "status.quote_error.pending_approval": "Afventende indlæg", "status.quote_error.pending_approval_popout.body": "På Mastodon kan du kontrollere, om nogen kan citere dig. Dette indlæg afventer, mens vi får den oprindelige forfatters godkendelse.", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 86826091fa..fb9c815d2d 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Schließen", "bundle_modal_error.message": "Beim Laden des Inhalts ist etwas schiefgelaufen.", "bundle_modal_error.retry": "Erneut versuchen", + "carousel.current": "Seite {current, number}/{max, number}", + "carousel.slide": "Seite {current, number} von {max, number}", "closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, kannst du ein Konto auf einem anderen Server erstellen und trotzdem mit diesem Server interagieren.", "closed_registrations_modal.description": "Das Anlegen eines Kontos auf {domain} ist derzeit nicht möglich, aber bedenke, dass du kein extra Konto auf {domain} benötigst, um Mastodon nutzen zu können.", "closed_registrations_modal.find_another_server": "Einen anderen Server auswählen", @@ -173,6 +175,8 @@ "column.edit_list": "Liste bearbeiten", "column.favourites": "Favoriten", "column.firehose": "Live-Feeds", + "column.firehose_local": "Live-Feed für diesen Server", + "column.firehose_singular": "Live-Feed", "column.follow_requests": "Follower-Anfragen", "column.home": "Startseite", "column.list_members": "Listenmitglieder verwalten", @@ -192,6 +196,7 @@ "community.column_settings.local_only": "Nur lokal", "community.column_settings.media_only": "Nur Beiträge mit Medien", "community.column_settings.remote_only": "Nur andere Mastodon-Server", + "compose.error.blank_post": "Beitrag muss einen Inhalt haben.", "compose.language.change": "Sprache festlegen", "compose.language.search": "Sprachen suchen …", "compose.published.body": "Beitrag veröffentlicht.", @@ -257,8 +262,8 @@ "confirmations.revoke_quote.confirm": "Beitrag entfernen", "confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.", "confirmations.revoke_quote.title": "Beitrag entfernen?", - "confirmations.unblock.confirm": "Entsperren", - "confirmations.unblock.title": "{name} entsperren?", + "confirmations.unblock.confirm": "Nicht mehr blockieren", + "confirmations.unblock.title": "{name} nicht mehr blockieren?", "confirmations.unfollow.confirm": "Entfolgen", "confirmations.unfollow.title": "{name} entfolgen?", "confirmations.withdraw_request.confirm": "Anfrage zurückziehen", @@ -358,11 +363,9 @@ "explore.trending_links": "Neuigkeiten", "explore.trending_statuses": "Beiträge", "explore.trending_tags": "Hashtags", + "featured_carousel.current": "Beitrag {current, number}/{max, number}", "featured_carousel.header": "{count, plural, one {Angehefteter Beitrag} other {Angeheftete Beiträge}}", - "featured_carousel.next": "Vor", - "featured_carousel.post": "Beitrag", - "featured_carousel.previous": "Zurück", - "featured_carousel.slide": "{index} von {total}", + "featured_carousel.slide": "Beitrag {current, number} von {max, number}", "filter_modal.added.context_mismatch_explanation": "Diese Filterkategorie gilt nicht für den Kontext, in welchem du auf diesen Beitrag zugegriffen hast. Wenn der Beitrag auch in diesem Kontext gefiltert werden soll, musst du den Filter bearbeiten.", "filter_modal.added.context_mismatch_title": "Kontext stimmt nicht überein!", "filter_modal.added.expired_explanation": "Diese Filterkategorie ist abgelaufen. Du musst das Ablaufdatum für diese Kategorie ändern.", @@ -909,9 +912,12 @@ "status.pin": "Im Profil anheften", "status.quote": "Zitieren", "status.quote.cancel": "Zitat abbrechen", + "status.quote_error.blocked_account_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du @{name} blockiert hast.", + "status.quote_error.blocked_domain_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du {domain} blockiert hast.", "status.quote_error.filtered": "Ausgeblendet wegen eines deiner Filter", "status.quote_error.limited_account_hint.action": "Trotzdem anzeigen", "status.quote_error.limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen von {domain} ausgeblendet.", + "status.quote_error.muted_account_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du @{name} stummgeschaltet hast.", "status.quote_error.not_available": "Beitrag nicht verfügbar", "status.quote_error.pending_approval": "Beitragsveröffentlichung ausstehend", "status.quote_error.pending_approval_popout.body": "Auf Mastodon kann festgelegt werden, ob man zitiert werden möchte. Wir warten auf die Genehmigung des ursprünglichen Profils. Bis dahin steht deine Beitragsveröffentlichung noch aus.", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 62e3467a93..3c20a810b8 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Κλείσιμο", "bundle_modal_error.message": "Κάτι πήγε στραβά κατά τη φόρτωση αυτής της οθόνης.", "bundle_modal_error.retry": "Δοκίμασε ξανά", + "carousel.current": "Διαφάνεια {current, number} / {max, number}", + "carousel.slide": "Διαφάνεια {current, number} από {max, number}", "closed_registrations.other_server_instructions": "Καθώς το Mastodon είναι αποκεντρωμένο, μπορείς να δημιουργήσεις λογαριασμό σε άλλον διακομιστή αλλά να συνεχίσεις να αλληλεπιδράς με αυτόν.", "closed_registrations_modal.description": "Η δημιουργία λογαριασμού στον {domain} προς το παρόν δεν είναι δυνατή, αλλά λάβε υπόψη ότι δεν χρειάζεσαι λογαριασμό ειδικά στον {domain} για να χρησιμοποιήσεις το Mastodon.", "closed_registrations_modal.find_another_server": "Βρες άλλον διακομιστή", @@ -360,11 +362,9 @@ "explore.trending_links": "Νέα", "explore.trending_statuses": "Αναρτήσεις", "explore.trending_tags": "Ετικέτες", + "featured_carousel.current": "Ανάρτηση {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Καρφιτσωμένη Ανάρτηση} other {Καρφιτσωμένες Αναρτήσεις}}", - "featured_carousel.next": "Επόμενο", - "featured_carousel.post": "Ανάρτηση", - "featured_carousel.previous": "Προηγούμενο", - "featured_carousel.slide": "{index} από {total}", + "featured_carousel.slide": "Ανάρτηση {current, number} από {max, number}", "filter_modal.added.context_mismatch_explanation": "Αυτή η κατηγορία φίλτρων δεν ισχύει για το περιεχόμενο εντός του οποίου προσπελάσατε αυτή την ανάρτηση. Αν θέλετε να φιλτραριστεί η ανάρτηση και εντός αυτού του πλαισίου, θα πρέπει να τροποποιήσετε το φίλτρο.", "filter_modal.added.context_mismatch_title": "Ασυμφωνία περιεχομένου!", "filter_modal.added.expired_explanation": "Αυτή η κατηγορία φίλτρων έχει λήξει, πρέπει να αλλάξετε την ημερομηνία λήξης για να ισχύσει.", @@ -911,9 +911,12 @@ "status.pin": "Καρφίτσωσε στο προφίλ", "status.quote": "Παράθεση", "status.quote.cancel": "Ακύρωση παράθεσης", + "status.quote_error.blocked_account_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε μπλοκάρει τον/την @{name}.", + "status.quote_error.blocked_domain_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε μπλοκάρει το {domain}.", "status.quote_error.filtered": "Κρυφό λόγω ενός από τα φίλτρα σου", "status.quote_error.limited_account_hint.action": "Εμφάνιση ούτως ή άλλως", "status.quote_error.limited_account_hint.title": "Αυτό το προφίλ έχει αποκρυφτεί από τους διαχειριστές του διακομιστή {domain}.", + "status.quote_error.muted_account_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε κάνει σίγαση τον/την @{name}.", "status.quote_error.not_available": "Ανάρτηση μη διαθέσιμη", "status.quote_error.pending_approval": "Ανάρτηση σε αναμονή", "status.quote_error.pending_approval_popout.body": "Στο Mastodon, μπορείς να ελέγξεις αν κάποιος μπορεί να σε παραθέσει. Αυτή η ανάρτηση εκκρεμεί ενώ λαμβάνουμε την έγκριση του αρχικού συντάκτη.", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 908c0509ef..8c55c9ad46 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -339,10 +339,6 @@ "explore.trending_statuses": "Posts", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Pinned Post} other {Pinned Posts}}", - "featured_carousel.next": "Next", - "featured_carousel.post": "Post", - "featured_carousel.previous": "Previous", - "featured_carousel.slide": "{index} of {total}", "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.", "filter_modal.added.context_mismatch_title": "Context mismatch!", "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 0481eb7c0c..ec33821722 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Close", "bundle_modal_error.message": "Something went wrong while loading this screen.", "bundle_modal_error.retry": "Try again", + "carousel.current": "Slide {current, number} / {max, number}", + "carousel.slide": "Slide {current, number} of {max, number}", "closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.", "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.", "closed_registrations_modal.find_another_server": "Find another server", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Local only", "community.column_settings.media_only": "Media Only", "community.column_settings.remote_only": "Remote only", + "compose.error.blank_post": "Post can't be blank.", "compose.language.change": "Change language", "compose.language.search": "Search languages...", "compose.published.body": "Post published.", @@ -360,11 +363,9 @@ "explore.trending_links": "News", "explore.trending_statuses": "Posts", "explore.trending_tags": "Hashtags", + "featured_carousel.current": "Post {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Pinned Post} other {Pinned Posts}}", - "featured_carousel.next": "Next", - "featured_carousel.post": "Post", - "featured_carousel.previous": "Previous", - "featured_carousel.slide": "{index} of {total}", + "featured_carousel.slide": "Post {current, number} of {max, number}", "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.", "filter_modal.added.context_mismatch_title": "Context mismatch!", "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.", @@ -407,6 +408,7 @@ "follow_suggestions.who_to_follow": "Who to follow", "followed_tags": "Followed hashtags", "footer.about": "About", + "footer.about_this_server": "About", "footer.directory": "Profiles directory", "footer.get_app": "Get the app", "footer.keyboard_shortcuts": "Keyboard shortcuts", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 6ce220a538..7091cfd191 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -342,10 +342,6 @@ "explore.trending_statuses": "Afiŝoj", "explore.trending_tags": "Kradvortoj", "featured_carousel.header": "{count, plural, one {Alpinglita afiŝo} other {Alpinglitaj afiŝoj}}", - "featured_carousel.next": "Antaŭen", - "featured_carousel.post": "Afiŝi", - "featured_carousel.previous": "Malantaŭen", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Ĉi tiu filtrilkategorio ne kongruas kun la kunteksto en kiu vi akcesis ĉi tiun afiŝon. Se vi volas ke la afiŝo estas ankaŭ filtrita en ĉi tiu kunteksto, vi devus redakti la filtrilon.", "filter_modal.added.context_mismatch_title": "Ne kongruas la kunteksto!", "filter_modal.added.expired_explanation": "Ĉi tiu filtrilkategorio eksvalidiĝis, vu bezonos ŝanĝi la eksvaliddaton por ĝi.", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index bc07edbd7b..4652873139 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Cerrar", "bundle_modal_error.message": "Algo salió mal al cargar esta pantalla.", "bundle_modal_error.retry": "Intentá de nuevo", + "carousel.current": "Diapositiva {current, number} / {max, number}", + "carousel.slide": "Diapositiva {current, number} de {max, number}", "closed_registrations.other_server_instructions": "Ya que Mastodon es descentralizado, podés crearte una cuenta en otro servidor y todavía interactuar con éste.", "closed_registrations_modal.description": "Actualmente no es posible crearte una cuenta en {domain}. pero recordá que no necesitás tener una cuenta puntualmente dentro de {domain} para poder usar Mastodon.", "closed_registrations_modal.find_another_server": "Buscar otro servidor", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Sólo local", "community.column_settings.media_only": "Sólo medios", "community.column_settings.remote_only": "Sólo remoto", + "compose.error.blank_post": "El mensaje no puede estar en blanco.", "compose.language.change": "Cambiar idioma", "compose.language.search": "Buscar idiomas…", "compose.published.body": "Mensaje publicado.", @@ -360,11 +363,9 @@ "explore.trending_links": "Noticias", "explore.trending_statuses": "Mensajes", "explore.trending_tags": "Etiquetas", + "featured_carousel.current": "Mensaje {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Mensaje fijado} other {Mensajes fijados}}", - "featured_carousel.next": "Siguiente", - "featured_carousel.post": "Mensaje", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", + "featured_carousel.slide": "Mensaje {current, number} de {max, number}", "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que accediste a este mensaje. Si querés que el mensaje sea filtrado también en este contexto, vas a tener que editar el filtro.", "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!", "filter_modal.added.expired_explanation": "Esta categoría de filtro caducó; vas a necesitar cambiar la fecha de caducidad para que se aplique.", @@ -911,9 +912,12 @@ "status.pin": "Fijar en el perfil", "status.quote": "Citar", "status.quote.cancel": "Cancelar cita", + "status.quote_error.blocked_account_hint.title": "Este mensaje está oculto porque bloqueaste a @{name}.", + "status.quote_error.blocked_domain_hint.title": "Este mensaje está oculto porque bloqueaste {domain}.", "status.quote_error.filtered": "Oculto debido a uno de tus filtros", "status.quote_error.limited_account_hint.action": "Mostrar de todos modos", "status.quote_error.limited_account_hint.title": "Esta cuenta fue ocultada por los moderadores de {domain}.", + "status.quote_error.muted_account_hint.title": "Este mensaje está oculto porque silenciaste a @{name}.", "status.quote_error.not_available": "Mensaje no disponible", "status.quote_error.pending_approval": "Mensaje pendiente", "status.quote_error.pending_approval_popout.body": "En Mastodon, podés controlar si alguien te puede citar. Este mensaje está pendiente hasta obtener la aprobación del autor original.", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index b340851d0f..11324b59ee 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Cerrar", "bundle_modal_error.message": "Algo ha fallado al cargar esta pantalla.", "bundle_modal_error.retry": "Inténtalo de nuevo", + "carousel.current": "Diapositiva {current, number} / {max, number}", + "carousel.slide": "Diapositiva {current, number} de {max, number}", "closed_registrations.other_server_instructions": "Como Mastodon es descentralizado, puedes crear una cuenta en otro servidor y seguir interactuando con este.", "closed_registrations_modal.description": "La creación de una cuenta en {domain} no es posible actualmente, pero ten en cuenta que no necesitas una cuenta específicamente en {domain} para usar Mastodon.", "closed_registrations_modal.find_another_server": "Buscar otro servidor", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Solo local", "community.column_settings.media_only": "Solo media", "community.column_settings.remote_only": "Solo remoto", + "compose.error.blank_post": "El mensaje no puede estar en blanco.", "compose.language.change": "Cambiar idioma", "compose.language.search": "Buscar idiomas...", "compose.published.body": "Publicado.", @@ -360,11 +363,9 @@ "explore.trending_links": "Noticias", "explore.trending_statuses": "Publicaciones", "explore.trending_tags": "Etiquetas", + "featured_carousel.current": "Publicación {current, number} / {max, number}", "featured_carousel.header": "{count, plural,one {Publicación fijada}other {Publicaciones fijadas}}", - "featured_carousel.next": "Siguiente", - "featured_carousel.post": "Publicar", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", + "featured_carousel.slide": "Publicación {current, number} de {max, number}", "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que has accedido a esta publlicación. Si quieres que la publicación sea filtrada también en este contexto, tendrás que editar el filtro.", "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!", "filter_modal.added.expired_explanation": "Esta categoría de filtro ha caducado, necesitaras cambiar la fecha de caducidad para que se aplique.", @@ -911,9 +912,12 @@ "status.pin": "Fijar", "status.quote": "Citar", "status.quote.cancel": "Cancelar cita", + "status.quote_error.blocked_account_hint.title": "Esta publicación está oculta porque has bloqueado a @{name}.", + "status.quote_error.blocked_domain_hint.title": "Esta publicación está oculta porque has bloqueado @{domain}.", "status.quote_error.filtered": "Oculto debido a uno de tus filtros", "status.quote_error.limited_account_hint.action": "Mostrar de todas formas", "status.quote_error.limited_account_hint.title": "Esta cuenta ha sido ocultada por los moderadores de {domain}.", + "status.quote_error.muted_account_hint.title": "Esta publicación está oculta porque has silenciado a @{name}.", "status.quote_error.not_available": "Publicación no disponible", "status.quote_error.pending_approval": "Publicación pendiente", "status.quote_error.pending_approval_popout.body": "En Mastodon, puedes controlar si alguien puede citarte. Esta publicación está pendiente mientras obtenemos la aprobación del autor original.", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 77d0f9f93a..be4d7869b4 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Cerrar", "bundle_modal_error.message": "Ha habido algún error mientras cargábamos esta pantalla.", "bundle_modal_error.retry": "Inténtalo de nuevo", + "carousel.current": "Diapositiva {current, number} / {max, number}", + "carousel.slide": "Diapositiva {current, number} de {max, number}", "closed_registrations.other_server_instructions": "Como Mastodon es descentralizado, puedes crear una cuenta en otro servidor y seguir interactuando con este.", "closed_registrations_modal.description": "La creación de una cuenta en {domain} no es posible actualmente, pero ten en cuenta que no necesitas una cuenta específicamente en {domain} para usar Mastodon.", "closed_registrations_modal.find_another_server": "Buscar otro servidor", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Solo local", "community.column_settings.media_only": "Solo multimedia", "community.column_settings.remote_only": "Solo remoto", + "compose.error.blank_post": "El mensaje no puede estar en blanco.", "compose.language.change": "Cambiar idioma", "compose.language.search": "Buscar idiomas...", "compose.published.body": "Publicado.", @@ -360,11 +363,9 @@ "explore.trending_links": "Noticias", "explore.trending_statuses": "Publicaciones", "explore.trending_tags": "Etiquetas", + "featured_carousel.current": "Publicación {current, number} / {max, number}", "featured_carousel.header": "{count, plural,one {Publicación fijada} other {Publicaciones fijadas}}", - "featured_carousel.next": "Siguiente", - "featured_carousel.post": "Publicación", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", + "featured_carousel.slide": "Publicación {current, number} de {max, number}", "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que ha accedido a esta publlicación. Si quieres que la publicación sea filtrada también en este contexto, tendrás que editar el filtro.", "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!", "filter_modal.added.expired_explanation": "Esta categoría de filtro ha caducado, tendrás que cambiar la fecha de caducidad para que se aplique.", @@ -911,9 +912,12 @@ "status.pin": "Fijar", "status.quote": "Citar", "status.quote.cancel": "Cancelar cita", + "status.quote_error.blocked_account_hint.title": "Esta publicación está oculta porque has bloqueado a @{name}.", + "status.quote_error.blocked_domain_hint.title": "Esta publicación está oculta porque has bloqueado @{domain}.", "status.quote_error.filtered": "Oculto debido a uno de tus filtros", "status.quote_error.limited_account_hint.action": "Mostrar de todos modos", "status.quote_error.limited_account_hint.title": "Esta cuenta ha sido ocultada por los moderadores de {domain}.", + "status.quote_error.muted_account_hint.title": "Esta publicación está oculta porque has silenciado a @{name}.", "status.quote_error.not_available": "Publicación no disponible", "status.quote_error.pending_approval": "Publicación pendiente", "status.quote_error.pending_approval_popout.body": "En Mastodon, puedes controlar si alguien puede citarte. Esta publicación está pendiente mientras obtenemos la aprobación del autor original.", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index f777e47943..b4d19326ef 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Postitused", "explore.trending_tags": "Sildid", "featured_carousel.header": "{count, plural, one {Esiletõstetud postitus} other {Esiletõstetud postitust}}", - "featured_carousel.next": "Järgmine", - "featured_carousel.post": "Postita", - "featured_carousel.previous": "Eelmine", - "featured_carousel.slide": "{index} / {total}", "filter_modal.added.context_mismatch_explanation": "See filtrikategooria ei rakendu kontekstis, kuidas postituseni jõudsid. Kui tahad postitust ka selles kontekstis filtreerida, pead muutma filtrit.", "filter_modal.added.context_mismatch_title": "Konteksti mittesobivus!", "filter_modal.added.expired_explanation": "Selle filtri kategooria on aegunud. pead muutma aegumiskuupäeva, kui tahad, et filter kehtiks.", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 945ae1cd27..02b85e977f 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -332,10 +332,6 @@ "explore.trending_links": "Berriak", "explore.trending_statuses": "Tutak", "explore.trending_tags": "Traolak", - "featured_carousel.next": "Hurrengoa", - "featured_carousel.post": "Argitaratu", - "featured_carousel.previous": "Aurrekoa", - "featured_carousel.slide": "{total}-tik {index}", "filter_modal.added.context_mismatch_explanation": "Iragazki-kategoria hau ez zaio aplikatzen bidalketa honetara sartzeko erabili duzun testuinguruari. Bidalketa testuinguru horretan ere iragaztea nahi baduzu, iragazkia editatu beharko duzu.", "filter_modal.added.context_mismatch_title": "Testuingurua ez dator bat!", "filter_modal.added.expired_explanation": "Iragazki kategoria hau iraungi da, eragina izan dezan bere iraungitze-data aldatu beharko duzu.", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 48d686a4d6..1efdbcc61d 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -343,10 +343,6 @@ "explore.trending_statuses": "فرسته‌ها", "explore.trending_tags": "برچسب‌ها", "featured_carousel.header": "{count, plural, one {فرسته سنجاق‌شده} other {فرسته‌های سنجاق‌شده}}", - "featured_carousel.next": "بعدی", - "featured_carousel.post": "فرسته", - "featured_carousel.previous": "قبلی", - "featured_carousel.slide": "{index} از {total}", "filter_modal.added.context_mismatch_explanation": "این دستهٔ پالایه به بافتاری که در آن به این فرسته دسترسی دارید اعمال نمی‌شود. اگر می‌خواهید فرسته در این بافتار هم پالوده شود، باید پالایه را ویرایش کنید.", "filter_modal.added.context_mismatch_title": "بافتار نامطابق!", "filter_modal.added.expired_explanation": "این دستهٔ پالایه منقضی شده است. برای اعمالش باید تاریخ انقضا را عوض کنید.", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 3e73a6e75d..c13936e15b 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -3,7 +3,7 @@ "about.contact": "Yhteydenotto:", "about.default_locale": "Oletus", "about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.", - "about.domain_blocks.no_reason_available": "Syytä ei ole ilmoitettu", + "about.domain_blocks.no_reason_available": "Syy ei ole tiedossa", "about.domain_blocks.preamble": "Mastodonin avulla voi yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä ja olla yhteyksissä eri palvelinten käyttäjien kanssa. Nämä poikkeukset koskevat yksin tätä palvelinta.", "about.domain_blocks.silenced.explanation": "Et yleensä näe tämän palvelimen profiileja ja sisältöä, jollet erityisesti etsi juuri sitä tai liity siihen seuraamalla.", "about.domain_blocks.silenced.title": "Rajoitettu", @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Sulje", "bundle_modal_error.message": "Jotain meni pieleen tätä näyttöä ladattaessa.", "bundle_modal_error.retry": "Yritä uudelleen", + "carousel.current": "Dia {current, number} / {max, number}", + "carousel.slide": "Dia {current, number} / {max, number}", "closed_registrations.other_server_instructions": "Koska Mastodon on hajautettu, voit luoda tilin toiselle palvelimelle ja olla silti vuorovaikutuksessa tämän kanssa.", "closed_registrations_modal.description": "Tilin luonti palvelimelle {domain} ei tällä hetkellä ole mahdollista, mutta ota huomioon, ettei Mastodonin käyttö edellytä juuri kyseisen palvelimen tiliä.", "closed_registrations_modal.find_another_server": "Etsi toinen palvelin", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Vain paikalliset", "community.column_settings.media_only": "Vain media", "community.column_settings.remote_only": "Vain etätilit", + "compose.error.blank_post": "Julkaisu ei voi olla tyhjä.", "compose.language.change": "Vaihda kieli", "compose.language.search": "Hae kieliä…", "compose.published.body": "Julkaisu lähetetty.", @@ -360,11 +363,9 @@ "explore.trending_links": "Uutiset", "explore.trending_statuses": "Julkaisut", "explore.trending_tags": "Aihetunnisteet", + "featured_carousel.current": "Julkaisu {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Kiinnitetty julkaisu} other {Kiinnitetyt julkaisut}}", - "featured_carousel.next": "Seuraava", - "featured_carousel.post": "Julkaisu", - "featured_carousel.previous": "Edellinen", - "featured_carousel.slide": "{index} / {total}", + "featured_carousel.slide": "Julkaisu {current, number} / {max, number}", "filter_modal.added.context_mismatch_explanation": "Tämä suodatinluokka ei koske asiayhteyttä, jossa olet tarkastellut tätä julkaisua. Jos haluat julkaisun suodatettavan myös tässä asiayhteydessä, muokkaa suodatinta.", "filter_modal.added.context_mismatch_title": "Asiayhteys ei täsmää!", "filter_modal.added.expired_explanation": "Tämä suodatinluokka on vanhentunut, joten sinun on muutettava viimeistä voimassaolopäivää, jotta suodatusta käytettäisiin.", @@ -911,9 +912,12 @@ "status.pin": "Kiinnitä profiiliin", "status.quote": "Lainaa", "status.quote.cancel": "Peruuta lainaus", + "status.quote_error.blocked_account_hint.title": "Tämä julkaisu on piilotettu, koska olet estänyt käyttäjän @{name}.", + "status.quote_error.blocked_domain_hint.title": "Tämä julkaisu on piilotettu, koska olet estänyt verkkotunnuksen {domain}.", "status.quote_error.filtered": "Piilotettu jonkin asettamasi suodattimen takia", "status.quote_error.limited_account_hint.action": "Näytä kuitenkin", "status.quote_error.limited_account_hint.title": "Palvelimen {domain} moderaattorit ovat piilottaneet tämän profiilin.", + "status.quote_error.muted_account_hint.title": "Tämä julkaisu on piilotettu, koska olet mykistänyt käyttäjän @{name}.", "status.quote_error.not_available": "Julkaisu ei saatavilla", "status.quote_error.pending_approval": "Julkaisu odottaa", "status.quote_error.pending_approval_popout.body": "Mastodonissa voit hallita, voiko joku lainata sinua. Tämä julkaisu on vireillä siihen asti, että saamme alkuperäisen tekijän hyväksynnän.", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 3a407e7cb6..cfe79274f8 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -173,6 +173,8 @@ "column.edit_list": "Broyt lista", "column.favourites": "Dámdir postar", "column.firehose": "Beinleiðis rásir", + "column.firehose_local": "Beinleiðis rás hjá hesum ambætaranum", + "column.firehose_singular": "Beinleiðis rás", "column.follow_requests": "Umbønir at fylgja", "column.home": "Heim", "column.list_members": "Rætta limalista", @@ -359,10 +361,6 @@ "explore.trending_statuses": "Postar", "explore.trending_tags": "Frámerki", "featured_carousel.header": "{count, plural, one {festur postur} other {festir postar}}", - "featured_carousel.next": "Næsta", - "featured_carousel.post": "Postur", - "featured_carousel.previous": "Fyrra", - "featured_carousel.slide": "{index} av {total}", "filter_modal.added.context_mismatch_explanation": "Hesin filturbólkurin viðvíkur ikki kontekstinum, sum tú hevur fingið atgongd til hendan postin. Ynskir tú at posturin verður filtreraður í hesum kontekstinum eisini, so er neyðugt at tú rættar filtrið.", "filter_modal.added.context_mismatch_title": "Ósamsvar við kontekst!", "filter_modal.added.expired_explanation": "Hesin filturbólkurin er útgingin, og tú mást broyta dagfestingina fyri at hann skal virka.", @@ -909,9 +907,12 @@ "status.pin": "Ger fastan í vangan", "status.quote": "Sitat", "status.quote.cancel": "Ógilda sitat", + "status.quote_error.blocked_account_hint.title": "Hesin posturin er fjaldur, tí tú hevur blokerað @{name}.", + "status.quote_error.blocked_domain_hint.title": "Hesin posturin er fjaldur, tí tú hevur blokerað @{domain}.", "status.quote_error.filtered": "Eitt av tínum filtrum fjalir hetta", "status.quote_error.limited_account_hint.action": "Vís kortini", "status.quote_error.limited_account_hint.title": "Hendan kontan er fjald av kjakleiðarunum á {domain}.", + "status.quote_error.muted_account_hint.title": "Hesin posturin er fjaldur, tí tú hevur doyvt @{name}.", "status.quote_error.not_available": "Postur ikki tøkur", "status.quote_error.pending_approval": "Postur bíðar", "status.quote_error.pending_approval_popout.body": "Á Mastodon kanst tú avgera, um onkur kann sitera teg. Hesin posturin bíðar eftir góðkenning frá upprunahøvundinum.", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index e749caf875..df0a516efa 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -352,10 +352,6 @@ "explore.trending_statuses": "Messages", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Pinned Post} other {Pinned Posts}}", - "featured_carousel.next": "Suivant", - "featured_carousel.post": "Poste", - "featured_carousel.previous": "Précédent", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Cette catégorie de filtre ne s'applique pas au contexte dans lequel vous avez accédé à cette publication. Si vous voulez que la publication soit filtrée dans ce contexte également, vous devrez modifier le filtre.", "filter_modal.added.context_mismatch_title": "Incompatibilité du contexte!", "filter_modal.added.expired_explanation": "Cette catégorie de filtre a expiré, vous devrez modifier la date d'expiration pour qu'elle soit appliquée.", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 91cf65835b..31ccae5971 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -352,10 +352,6 @@ "explore.trending_statuses": "Messages", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Pinned Post} other {Pinned Posts}}", - "featured_carousel.next": "Suivant", - "featured_carousel.post": "Poste", - "featured_carousel.previous": "Précédent", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Cette catégorie de filtre ne s'applique pas au contexte dans lequel vous avez accédé à ce message. Si vous voulez que le message soit filtré dans ce contexte également, vous devrez modifier le filtre.", "filter_modal.added.context_mismatch_title": "Incompatibilité du contexte !", "filter_modal.added.expired_explanation": "Cette catégorie de filtre a expiré, vous devrez modifier la date d'expiration pour qu'elle soit appliquée.", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 032cdd870f..e965dc645d 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -339,10 +339,6 @@ "explore.trending_statuses": "Berjochten", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Fêstset berjocht} other {Fêstsette berjochten}}", - "featured_carousel.next": "Folgjende", - "featured_carousel.post": "Berjocht", - "featured_carousel.previous": "Foarige", - "featured_carousel.slide": "{index} fan {total}", "filter_modal.added.context_mismatch_explanation": "Dizze filterkategory is net fan tapassing op de kontekst wêryn jo dit berjocht benadere hawwe. As jo wolle dat it berjocht ek yn dizze kontekst filtere wurdt, moatte jo it filter bewurkje.", "filter_modal.added.context_mismatch_title": "Kontekst komt net oerien!", "filter_modal.added.expired_explanation": "Dizze filterkategory is ferrûn. Jo moatte de ferrindatum wizigje om de kategory tapasse te kinnen.", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 0bf6beecdc..83ff290fb3 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Dún", "bundle_modal_error.message": "Tharla earráid agus an scáileán seo á lódáil.", "bundle_modal_error.retry": "Bain triail as arís", + "carousel.current": "Sleamhnán {current, number} / {max, number}", + "carousel.slide": "Sleamhnán {current, number} of {max, number}", "closed_registrations.other_server_instructions": "Mar rud díláraithe Mastodon, is féidir leat cuntas a chruthú ar seirbheálaí eile ach fós idirghníomhaigh leis an ceann seo.", "closed_registrations_modal.description": "Ní féidir cuntas a chruthú ar {domain} faoi láthair, ach cuimhnigh nach gá go mbeadh cuntas agat go sonrach ar {domain} chun Mastodon a úsáid.", "closed_registrations_modal.find_another_server": "Faigh freastalaí eile", @@ -173,6 +175,8 @@ "column.edit_list": "Cuir liosta in eagar", "column.favourites": "Ceanáin", "column.firehose": "Fothaí beo", + "column.firehose_local": "Fotha beo don fhreastalaí seo", + "column.firehose_singular": "Beo-bheatha", "column.follow_requests": "Iarratais leanúnaí", "column.home": "Baile", "column.list_members": "Bainistigh baill liosta", @@ -358,11 +362,9 @@ "explore.trending_links": "Nuacht", "explore.trending_statuses": "Postálacha", "explore.trending_tags": "Haischlibeanna", + "featured_carousel.current": "Post {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Postáil phinnáilte} two {Poist Phionáilte} few {Poist Phionáilte} many {Poist Phionáilte} other {Poist Phionáilte}}", - "featured_carousel.next": "Ar Aghaidh", - "featured_carousel.post": "Post", - "featured_carousel.previous": "Roimhe Seo", - "featured_carousel.slide": "{index} de {total}", + "featured_carousel.slide": "Post {current, number} of {max, number}", "filter_modal.added.context_mismatch_explanation": "Ní bhaineann an chatagóir scagaire seo leis an gcomhthéacs ina bhfuair tú rochtain ar an bpostáil seo. Más mian leat an postáil a scagadh sa chomhthéacs seo freisin, beidh ort an scagaire a chur in eagar.", "filter_modal.added.context_mismatch_title": "Neamhréir comhthéacs!", "filter_modal.added.expired_explanation": "Tá an chatagóir scagaire seo imithe in éag, beidh ort an dáta éaga a athrú chun é a chur i bhfeidhm.", @@ -909,9 +911,12 @@ "status.pin": "Pionnáil ar do phróifíl", "status.quote": "Luachan", "status.quote.cancel": "Cealaigh an luachan", + "status.quote_error.blocked_account_hint.title": "Tá an post seo i bhfolach mar gur chuir tú bac ar @{name}.", + "status.quote_error.blocked_domain_hint.title": "Tá an post seo i bhfolach mar gur chuir tú bac ar {domain}.", "status.quote_error.filtered": "I bhfolach mar gheall ar cheann de do scagairí", "status.quote_error.limited_account_hint.action": "Taispeáin ar aon nós", "status.quote_error.limited_account_hint.title": "Tá an cuntas seo i bhfolach ag modhnóirí {domain}.", + "status.quote_error.muted_account_hint.title": "Tá an post seo i bhfolach mar gur chuir tú @{name} ar neamhní.", "status.quote_error.not_available": "Níl an postáil ar fáil", "status.quote_error.pending_approval": "Post ar feitheamh", "status.quote_error.pending_approval_popout.body": "Ar Mastodon, is féidir leat a rialú an féidir le duine tú a lua nó nach féidir. Tá an post seo ar feitheamh fad is atá ceadú an údair bhunaidh á fháil againn.", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 00d5629dfe..3a570a3dfd 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Dùin", "bundle_modal_error.message": "Chaidh rudeigin ceàrr le luchdadh na sgrìn seo.", "bundle_modal_error.retry": "Feuch ris a-rithist", + "carousel.current": "Sleamhnag {current, number} / {max, number}", + "carousel.slide": "Sleamhnag {current, number} à {max, number}", "closed_registrations.other_server_instructions": "Air sgàth ’s gu bheil Mastodon sgaoilte, ’s urrainn dhut cunntas a chruthachadh air frithealaiche eile agus conaltradh ris an fhrithealaiche seo co-dhiù.", "closed_registrations_modal.description": "Cha ghabh cunntas a chruthachadh air {domain} aig an àm seo ach thoir an aire nach fheum thu cunntas air {domain} gu sònraichte airson Mastodon a chleachdadh.", "closed_registrations_modal.find_another_server": "Lorg frithealaiche eile", @@ -173,6 +175,8 @@ "column.edit_list": "Deasaich an liosta", "column.favourites": "Annsachdan", "column.firehose": "An saoghal beò", + "column.firehose_local": "Loidhne-ama bheò an fhrithealaiche seo", + "column.firehose_singular": "Loidhne-ama bheò beò", "column.follow_requests": "Iarrtasan leantainn", "column.home": "Dachaigh", "column.list_members": "Stiùir buill na liosta", @@ -247,7 +251,7 @@ "confirmations.quiet_post_quote_info.dismiss": "Na cuiribh seo ’nam chuimhne a-rithist", "confirmations.quiet_post_quote_info.got_it": "Tha mi agaibh", "confirmations.quiet_post_quote_info.message": "Nuair a luaidheas tu post a tha poblach ach sàmhach, thèid am post agad fhalach o loidhnichean-ama nan treandaichean.", - "confirmations.quiet_post_quote_info.title": "Luaidh air postaichean poblach ach sàmhach", + "confirmations.quiet_post_quote_info.title": "Luaidh air postaichean sàmhach", "confirmations.redraft.confirm": "Sguab às ⁊ dèan dreachd ùr", "confirmations.redraft.message": "A bheil thu cinnteach gu bheil thu airson am post seo a sguabadh às agus dreachd ùr a thòiseachadh? Caillidh tu gach annsachd is brosnachadh air agus thèid freagairtean dhan phost thùsail ’nan dìlleachdanan.", "confirmations.redraft.title": "A bheil thu airson am post a sguabadh às ⁊ dreachd ùr a dhèanamh dheth?", @@ -333,6 +337,7 @@ "empty_column.bookmarked_statuses": "Chan eil comharra-lìn ri post agad fhathast. Nuair a nì thu comharra-lìn de dh’fhear, nochdaidh e an-seo.", "empty_column.community": "Tha an loidhne-ama ionadail falamh. Sgrìobh rudeigin gu poblach airson toiseach-tòiseachaidh a dhèanamh!", "empty_column.direct": "Chan eil iomradh prìobhaideach agad fhathast. Nuair a chuireas no a gheibh thu tè, nochdaidh i an-seo.", + "empty_column.disabled_feed": "Chaidh an loidhne-ama seo a chur à comas le rianairean an fhrithealaiche agad.", "empty_column.domain_blocks": "Cha deach àrainn sam bith a bhacadh fhathast.", "empty_column.explore_statuses": "Chan eil dad a’ treandadh an-dràsta fhèin. Thoir sùil a-rithist an ceann greis!", "empty_column.favourited_statuses": "Chan eil annsachd air post agad fhathast. Nuair a nì thu annsachd de dh’fhear, nochdaidh e an-seo.", @@ -357,11 +362,9 @@ "explore.trending_links": "Naidheachdan", "explore.trending_statuses": "Postaichean", "explore.trending_tags": "Tagaichean hais", + "featured_carousel.current": "Post {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Post prìnichte} two {Postaichean prìnichte} few {Postaichean prìnichte} other {Postaichean prìnichte}}", - "featured_carousel.next": "Air adhart", - "featured_carousel.post": "Post", - "featured_carousel.previous": "Air ais", - "featured_carousel.slide": "{index} à {total}", + "featured_carousel.slide": "Post {current, number} à {max, number}", "filter_modal.added.context_mismatch_explanation": "Chan eil an roinn-seòrsa criathraidh iom seo chaidh dhan cho-theacs san do dh’inntrig thu am post seo. Ma tha thu airson am post a chriathradh sa cho-theacs seo cuideachd, feumaidh tu a’ chriathrag a dheasachadh.", "filter_modal.added.context_mismatch_title": "Co-theacsa neo-iomchaidh!", "filter_modal.added.expired_explanation": "Dh’fhalbh an ùine air an roinn-seòrsa criathraidh seo agus feumaidh tu an ceann-là crìochnachaidh atharrachadh mus cuir thu an sàs i.", @@ -745,12 +748,12 @@ "privacy.private.short": "Luchd-leantainn", "privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon", "privacy.public.short": "Poblach", - "privacy.quote.anyone": "{visibility}, luaidhidh neach sam bith e", + "privacy.quote.anyone": "{visibility}, luaidhean fosgailte", "privacy.quote.disabled": "{visibility}, luaidh à comas", "privacy.quote.limited": "{visibility}, luaidh cuingichte", "privacy.unlisted.additional": "Tha seo coltach ris an fhaicsinneachd phoblach ach cha nochd am post air loidhnichean-ama an t-saoghail phoblaich, nan tagaichean hais no an rùrachaidh no ann an toraidhean luirg Mhastodon fiù ’s ma thug thu ro-aonta airson sin seachad.", - "privacy.unlisted.long": "Falaichte o na toraidhean-luirg, na treandaichean ’s na loichnichean-ama poblach", - "privacy.unlisted.short": "Poblach ach sàmhach", + "privacy.unlisted.long": "Poblach ach falaichte o na toraidhean-luirg, na treandaichean ’s na loichnichean-ama poblach", + "privacy.unlisted.short": "Sàmhach", "privacy_policy.last_updated": "An t-ùrachadh mu dheireadh {date}", "privacy_policy.title": "Poileasaidh prìobhaideachd", "quote_error.edit": "Chan urrainn dhut luaidh a chur ris nuair a bhios tu ri deasachadh puist.", @@ -908,9 +911,12 @@ "status.pin": "Prìnich ris a’ phròifil", "status.quote": "Luaidh", "status.quote.cancel": "Sguir dhen luaidh", + "status.quote_error.blocked_account_hint.title": "Tha am post seo falaichte on a bhac thu @{name}.", + "status.quote_error.blocked_domain_hint.title": "Tha am post seo falaichte on a bhac thu {domain}.", "status.quote_error.filtered": "Falaichte le criathrag a th’ agad", "status.quote_error.limited_account_hint.action": "Seall e co-dhiù", "status.quote_error.limited_account_hint.title": "Chaidh an cunntas seo fhalach le maoir {domain}.", + "status.quote_error.muted_account_hint.title": "Tha am post seo falaichte on a mhùch thu @{name}.", "status.quote_error.not_available": "Chan eil am post ri fhaighinn", "status.quote_error.pending_approval": "Cha deach dèiligeadh ris a’ phost fhathast", "status.quote_error.pending_approval_popout.body": "Air Mastodon, ’s urrainn dhut stiùireadh am faod cuideigin do luaidh gus nach fhaod. Tha am post seo a’ feitheamh air aonta an ùghdair thùsail.", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 6ce9544cb1..ab59689ad2 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -173,6 +173,8 @@ "column.edit_list": "Editar lista", "column.favourites": "Favoritas", "column.firehose": "O que acontece", + "column.firehose_local": "Acontece agora neste servidor", + "column.firehose_singular": "O que acontece", "column.follow_requests": "Peticións de seguimento", "column.home": "Inicio", "column.list_members": "Xestionar membros da lista", @@ -359,10 +361,6 @@ "explore.trending_statuses": "Publicacións", "explore.trending_tags": "Cancelos", "featured_carousel.header": "{count, plural, one {Publicación fixada} other {Publicacións fixadas}}", - "featured_carousel.next": "Seguinte", - "featured_carousel.post": "Publicación", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro non se aplica ao contexto no que accedeches a esta publicación. Se queres que a publicación se filtre nese contexto tamén, terás que editar o filtro.", "filter_modal.added.context_mismatch_title": "Non concorda o contexto!", "filter_modal.added.expired_explanation": "Esta categoría de filtro caducou, terás que cambiar a data de caducidade para que se aplique.", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 47f4ee9149..32ec1fcc0a 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -361,10 +361,6 @@ "explore.trending_statuses": "הודעות", "explore.trending_tags": "תגיות", "featured_carousel.header": "{count, plural, one {הודעה אחת נעוצה} two {הודעותיים נעוצות} many {הודעות נעוצות} other {הודעות נעוצות}}", - "featured_carousel.next": "הבא", - "featured_carousel.post": "הודעה", - "featured_carousel.previous": "הקודם", - "featured_carousel.slide": "{index} מתוך {total}", "filter_modal.added.context_mismatch_explanation": "קטגוריית הסנן הזאת לא חלה על ההקשר שממנו הגעת אל ההודעה הזו. אם תרצה/י שההודעה תסונן גם בהקשר זה, תצטרך/י לערוך את הסנן.", "filter_modal.added.context_mismatch_title": "אין התאמה להקשר!", "filter_modal.added.expired_explanation": "פג תוקפה של קטגוריית הסינון הזו, יש צורך לשנות את תאריך התפוגה כדי שהסינון יוחל.", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 67c9dcddc7..e16e9e957a 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Bezárás", "bundle_modal_error.message": "Hiba történt a képernyő betöltésekor.", "bundle_modal_error.retry": "Próbáld újra", + "carousel.current": "{current, number}. dia / {max, number}", + "carousel.slide": "{current, number}. dia / {max, number}", "closed_registrations.other_server_instructions": "Mivel a Mastdon decentralizált, létrehozhatsz egy fiókot egy másik kiszolgálón és mégis kapcsolódhatsz ehhez.", "closed_registrations_modal.description": "Fiók létrehozása a {domain} kiszolgálón jelenleg nem lehetséges, de jó, ha tudod, hogy nem szükséges fiókkal rendelkezni pont a {domain} kiszolgálón, hogy használhasd a Mastodont.", "closed_registrations_modal.find_another_server": "Másik kiszolgáló keresése", @@ -173,6 +175,8 @@ "column.edit_list": "Lista módosítása", "column.favourites": "Kedvencek", "column.firehose": "Hírfolyamok", + "column.firehose_local": "Élő hírfolyam a kiszolgálóhoz", + "column.firehose_singular": "Élő hírfolyam", "column.follow_requests": "Követési kérések", "column.home": "Kezdőlap", "column.list_members": "Listatagok kezelése", @@ -192,6 +196,7 @@ "community.column_settings.local_only": "Csak helyi", "community.column_settings.media_only": "Csak média", "community.column_settings.remote_only": "Csak távoli", + "compose.error.blank_post": "A bejegyzés nem lehet üres.", "compose.language.change": "Nyelv megváltoztatása", "compose.language.search": "Nyelvek keresése…", "compose.published.body": "A bejegyzés publikálásra került.", @@ -358,11 +363,9 @@ "explore.trending_links": "Hírek", "explore.trending_statuses": "Bejegyzések", "explore.trending_tags": "Hashtagek", + "featured_carousel.current": "{current, number}. bejegyzés / {max, number}", "featured_carousel.header": "{count, plural, one {Kiemelt bejegyzés} other {Kiemelt bejegyzések}}", - "featured_carousel.next": "Következő", - "featured_carousel.post": "Bejegyzés", - "featured_carousel.previous": "Előző", - "featured_carousel.slide": "{index} / {total}", + "featured_carousel.slide": "{current, number}. bejegyzés / {max, number}", "filter_modal.added.context_mismatch_explanation": "Ez a szűrőkategória nem érvényes abban a környezetben, amelyből elérted ezt a bejegyzést. Ha ebben a környezetben is szűrni szeretnéd a bejegyzést, akkor szerkesztened kell a szűrőt.", "filter_modal.added.context_mismatch_title": "Környezeti eltérés.", "filter_modal.added.expired_explanation": "Ez a szűrőkategória elévült, a használatához módosítanod kell az elévülési dátumot.", @@ -909,9 +912,12 @@ "status.pin": "Kitűzés a profilodra", "status.quote": "Idézés", "status.quote.cancel": "Idézés elvetése", + "status.quote_error.blocked_account_hint.title": "Ez a bejegyzés rejtett, mert blokkoltad @{name} felhasználót.", + "status.quote_error.blocked_domain_hint.title": "Ez a bejegyzés rejtett, mert blokkoltad a(z) {domain} domaint.", "status.quote_error.filtered": "A szűrőid miatt rejtett", "status.quote_error.limited_account_hint.action": "Megjelenítés mindenképp", "status.quote_error.limited_account_hint.title": "Ezt a fiókot elrejtették a(z) {domain} moderátorai.", + "status.quote_error.muted_account_hint.title": "Ez a bejegyzés rejtett, mert némítottad @{name} felhasználót.", "status.quote_error.not_available": "A bejegyzés nem érhető el", "status.quote_error.pending_approval": "A bejegyzés függőben van", "status.quote_error.pending_approval_popout.body": "A Mastodonon te mondod meg, hogy valaki idézhet-e. Ez a bejegyzés addig függőben marad, amíg az eredeti szerző nem engedélyezi azt.", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 1b5aaa39bf..eee89144d4 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Messages", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Message fixate} other {Messages fixate}}", - "featured_carousel.next": "Sequente", - "featured_carousel.post": "Message", - "featured_carousel.previous": "Precedente", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Iste categoria de filtros non se applica al contexto in le qual tu ha accedite a iste message. Pro filtrar le message in iste contexto tamben, modifica le filtro.", "filter_modal.added.context_mismatch_title": "Contexto incoherente!", "filter_modal.added.expired_explanation": "Iste categoria de filtros ha expirate. Tu debe modificar le data de expiration pro applicar lo.", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 3f43cfb897..5c51b9fd36 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Loka", "bundle_modal_error.message": "Eitthvað fór úrskeiðis við að hlaða inn þessum skjá.", "bundle_modal_error.retry": "Reyndu aftur", + "carousel.current": "Skyggna {current, number} / {max, number}", + "carousel.slide": "Skyggna {current, number} af {max, number}", "closed_registrations.other_server_instructions": "Þar sem Mastodon er ekki miðstýrt, þá getur þú búið til aðgang á öðrum þjóni, en samt haft samskipti við þennan.", "closed_registrations_modal.description": "Að búa til aðgang á {domain} er ekki mögulegt eins og er, en vinsamlegast hafðu í huga að þú þarft ekki aðgang sérstaklega á {domain} til að nota Mastodon.", "closed_registrations_modal.find_another_server": "Finna annan netþjón", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Einungis staðvært", "community.column_settings.media_only": "Einungis myndskrár", "community.column_settings.remote_only": "Einungis fjartengt", + "compose.error.blank_post": "Færsla má ekki vera auð.", "compose.language.change": "Skipta um tungumál", "compose.language.search": "Leita að tungumálum...", "compose.published.body": "Færsla birt.", @@ -360,11 +363,9 @@ "explore.trending_links": "Fréttir", "explore.trending_statuses": "Færslur", "explore.trending_tags": "Myllumerki", + "featured_carousel.current": "Færsla {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Fest færsla} other {Festar færslur}}", - "featured_carousel.next": "Næsta", - "featured_carousel.post": "Færsla", - "featured_carousel.previous": "Fyrra", - "featured_carousel.slide": "{index} af {total}", + "featured_carousel.slide": "Færsla {current, number} af {max, number}", "filter_modal.added.context_mismatch_explanation": "Þessi síuflokkur á ekki við í því samhengi sem aðgangur þinn að þessari færslu felur í sér. Ef þú vilt að færslan sé einnig síuð í þessu samhengi, þá þarftu að breyta síunni.", "filter_modal.added.context_mismatch_title": "Misræmi í samhengi!", "filter_modal.added.expired_explanation": "Þessi síuflokkur er útrunninn, þú þarft að breyta gidistímanum svo hann geti átt við.", @@ -911,9 +912,12 @@ "status.pin": "Festa á notandasnið", "status.quote": "Tilvitnun", "status.quote.cancel": "Hætta við tilvitnun", + "status.quote_error.blocked_account_hint.title": "Þessi færsla er falin vegna þess að ú hefur lokað á @{name}.", + "status.quote_error.blocked_domain_hint.title": "Þessi færsla er falin vegna þess að ú hefur lokað á {domain}.", "status.quote_error.filtered": "Falið vegna einnar síu sem er virk", "status.quote_error.limited_account_hint.action": "Birta samt", "status.quote_error.limited_account_hint.title": "Þessi notandaaðgangur hefur verið falinn af stjórnendum á {domain}.", + "status.quote_error.muted_account_hint.title": "Þessi færsla er falin vegna þess að ú hefur þaggað niður í @{name}.", "status.quote_error.not_available": "Færsla ekki tiltæk", "status.quote_error.pending_approval": "Færsla í bið", "status.quote_error.pending_approval_popout.body": "Á Mastodon geturðu stjórnað því hvort aðrir geti vitnað í þig. Þessi færsla bíður eftir samþykki upprunalegs höfundar.", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 9e57f42fc9..735dbcde69 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Post", "explore.trending_tags": "Hashtag", "featured_carousel.header": "{count, plural, one {Post appuntato} other {Post appuntati}}", - "featured_carousel.next": "Successivo", - "featured_carousel.post": "Post", - "featured_carousel.previous": "Precedente", - "featured_carousel.slide": "{index} di {total}", "filter_modal.added.context_mismatch_explanation": "La categoria di questo filtro non si applica al contesto in cui hai acceduto a questo post. Se desideri che il post sia filtrato anche in questo contesto, dovrai modificare il filtro.", "filter_modal.added.context_mismatch_title": "Contesto non corrispondente!", "filter_modal.added.expired_explanation": "La categoria di questo filtro è scaduta, dovrvai modificarne la data di scadenza per applicarlo.", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index ee4cc5c7b3..e5aac78f07 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -342,10 +342,6 @@ "explore.trending_statuses": "投稿", "explore.trending_tags": "ハッシュタグ", "featured_carousel.header": "{count, plural, other {固定された投稿}}", - "featured_carousel.next": "次へ", - "featured_carousel.post": "投稿", - "featured_carousel.previous": "前へ", - "featured_carousel.slide": "{index} / {total}", "filter_modal.added.context_mismatch_explanation": "このフィルターカテゴリーはあなたがアクセスした投稿のコンテキストには適用されません。この投稿のコンテキストでもフィルターを適用するにはフィルターを編集する必要があります。", "filter_modal.added.context_mismatch_title": "コンテキストが一致しません!", "filter_modal.added.expired_explanation": "このフィルターカテゴリーは有効期限が切れています。適用するには有効期限を更新してください。", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 0add265b63..5e21b1aeb0 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -266,10 +266,6 @@ "explore.trending_statuses": "Tisuffaɣ", "explore.trending_tags": "Ihacṭagen", "featured_carousel.header": "{count, plural, one {n tsuffeɣt tunṭiḍt} other {n tsuffaɣ tunṭiḍin}}", - "featured_carousel.next": "Uḍfiṛ", - "featured_carousel.post": "Tasuffeɣt", - "featured_carousel.previous": "Uzwir", - "featured_carousel.slide": "{index} ɣef {total}", "filter_modal.added.review_and_configure_title": "Iɣewwaṛen n imzizdig", "filter_modal.added.settings_link": "asebter n yiɣewwaṛen", "filter_modal.added.short_explanation": "Tasuffeɣt-a tettwarna ɣer taggayt-a n yimsizdegen: {title}.", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 152061b557..ce35157854 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -24,7 +24,7 @@ "account.blocking": "차단함", "account.cancel_follow_request": "팔로우 취소", "account.copy": "프로필 링크 복사", - "account.direct": "@{name} 님에게 개인적으로 멘션", + "account.direct": "@{name} 님에게 개인 멘션", "account.disable_notifications": "@{name} 의 게시물 알림 끄기", "account.domain_blocking": "도메인 차단함", "account.edit_profile": "프로필 편집", @@ -157,6 +157,8 @@ "bundle_modal_error.close": "닫기", "bundle_modal_error.message": "이 화면을 불러오는 중 뭔가 잘못되었습니다.", "bundle_modal_error.retry": "다시 시도", + "carousel.current": "페이지 {current, number} / {max, number}", + "carousel.slide": "{max, number} 중 {current, number} 페이지", "closed_registrations.other_server_instructions": "마스토돈은 분산화 되어 있기 때문에, 다른 서버에서 계정을 만들더라도 이 서버와 상호작용 할 수 있습니다.", "closed_registrations_modal.description": "{domain}은 현재 가입이 불가능합니다. 하지만 마스토돈을 이용하기 위해 꼭 {domain}을 사용할 필요는 없다는 사실을 인지해 두세요.", "closed_registrations_modal.find_another_server": "다른 서버 찾기", @@ -167,7 +169,7 @@ "column.bookmarks": "북마크", "column.community": "로컬 타임라인", "column.create_list": "리스트 만들기", - "column.direct": "개인적인 멘션", + "column.direct": "개인 멘션", "column.directory": "프로필 둘러보기", "column.domain_blocks": "차단한 도메인", "column.edit_list": "리스트 편집", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "로컬만", "community.column_settings.media_only": "미디어만", "community.column_settings.remote_only": "원격지만", + "compose.error.blank_post": "빈 게시물은 게시할 수 없습니다.", "compose.language.change": "언어 변경", "compose.language.search": "언어 검색...", "compose.published.body": "게시하였습니다.", @@ -334,7 +337,7 @@ "empty_column.blocks": "아직 아무도 차단하지 않았습니다.", "empty_column.bookmarked_statuses": "아직 북마크에 저장한 게시물이 없습니다. 게시물을 북마크 지정하면 여기에 나타납니다.", "empty_column.community": "로컬 타임라인에 아무것도 없습니다. 아무거나 적어 보세요!", - "empty_column.direct": "개인적인 멘션이 없습니다. 보내거나 받으면 여기에 표시됩니다.", + "empty_column.direct": "개인 멘션이 없습니다. 보내거나 받으면 여기에 표시됩니다.", "empty_column.disabled_feed": "이 피드는 서버 관리자에 의해 비활성화되었습니다.", "empty_column.domain_blocks": "아직 차단한 도메인이 없습니다.", "empty_column.explore_statuses": "아직 유행하는 것이 없습니다. 나중에 다시 확인하세요!", @@ -360,11 +363,9 @@ "explore.trending_links": "소식", "explore.trending_statuses": "게시물", "explore.trending_tags": "해시태그", + "featured_carousel.current": "게시물 {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {고정된 게시물}}", - "featured_carousel.next": "다음", - "featured_carousel.post": "게시물", - "featured_carousel.previous": "이전", - "featured_carousel.slide": "{total} 중 {index}", + "featured_carousel.slide": "{max, number} 중 {current, number} 번째 게시물", "filter_modal.added.context_mismatch_explanation": "이 필터 카테고리는 당신이 이 게시물에 접근한 문맥에 적용되지 않습니다. 만약 이 문맥에서도 필터되길 원한다면, 필터를 수정해야 합니다.", "filter_modal.added.context_mismatch_title": "문맥 불일치!", "filter_modal.added.expired_explanation": "이 필터 카테고리는 만료되었습니다, 적용하려면 만료 일자를 변경할 필요가 있습니다.", @@ -427,7 +428,7 @@ "hashtag.column_settings.tag_mode.all": "모두", "hashtag.column_settings.tag_mode.any": "어느것이든", "hashtag.column_settings.tag_mode.none": "이것들을 제외하고", - "hashtag.column_settings.tag_toggle": "추가 해시태그를 이 컬럼에 추가합니다", + "hashtag.column_settings.tag_toggle": "추가 해시태그를 이 칼럼에 포함하기", "hashtag.counter_by_accounts": "{count, plural, other {참여자 {counter}명}}", "hashtag.counter_by_uses": "{count, plural, other {게시물 {counter}개}}", "hashtag.counter_by_uses_today": "오늘 {count, plural, other {{counter} 개의 게시물}}", @@ -479,7 +480,7 @@ "keyboard_shortcuts.column": "해당 컬럼에 포커스", "keyboard_shortcuts.compose": "작성창에 포커스", "keyboard_shortcuts.description": "설명", - "keyboard_shortcuts.direct": "개인적인 멘션 컬럼 열기", + "keyboard_shortcuts.direct": "개인 멘션 칼럼 열기", "keyboard_shortcuts.down": "리스트에서 아래로 이동", "keyboard_shortcuts.enter": "게시물 열기", "keyboard_shortcuts.favourite": "게시물 좋아요", @@ -567,7 +568,7 @@ "navigation_bar.automated_deletion": "게시물 자동 삭제", "navigation_bar.blocks": "차단한 사용자", "navigation_bar.bookmarks": "북마크", - "navigation_bar.direct": "개인적인 멘션", + "navigation_bar.direct": "개인 멘션", "navigation_bar.domain_blocks": "차단한 도메인", "navigation_bar.favourites": "좋아요", "navigation_bar.filters": "뮤트한 단어", @@ -673,7 +674,7 @@ "notifications.column_settings.push": "푸시 알림", "notifications.column_settings.quote": "인용:", "notifications.column_settings.reblog": "부스트:", - "notifications.column_settings.show": "컬럼에 표시", + "notifications.column_settings.show": "칼럼에 표시", "notifications.column_settings.sound": "효과음 재생", "notifications.column_settings.status": "새 게시물:", "notifications.column_settings.unread_notifications.category": "읽지 않은 알림", @@ -707,7 +708,7 @@ "notifications.policy.filter_not_following_hint": "내가 수동으로 승인하지 않는 한", "notifications.policy.filter_not_following_title": "내가 팔로우하지 않는 사람들", "notifications.policy.filter_private_mentions_hint": "내가 한 멘션에 단 답글이거나 내가 발신자를 팔로우 한 것이 아닌 이상 걸러집니다", - "notifications.policy.filter_private_mentions_title": "청하지 않은 개인적인 멘션", + "notifications.policy.filter_private_mentions_title": "청하지 않은 개인 멘션", "notifications.policy.title": "알림 조건 설정", "notifications_permission_banner.enable": "데스크탑 알림 활성화", "notifications_permission_banner.how_to_control": "마스토돈이 열려 있지 않을 때에도 알림을 받으려면, 데스크탑 알림을 활성화 하세요. 당신은 어떤 종류의 반응이 데스크탑 알림을 발생할 지를 {icon} 버튼을 통해 세세하게 설정할 수 있습니다.", @@ -887,8 +888,8 @@ "status.delete": "삭제", "status.delete.success": "게시물 삭제됨", "status.detailed_status": "대화 자세히 보기", - "status.direct": "@{name} 님에게 개인적으로 멘션", - "status.direct_indicator": "개인적인 멘션", + "status.direct": "@{name} 님에게 개인 멘션", + "status.direct_indicator": "개인 멘션", "status.edit": "수정", "status.edited": "{date}에 마지막으로 편집됨", "status.edited_x_times": "{count, plural, other {{count}}} 번 수정됨", @@ -910,11 +911,15 @@ "status.pin": "고정", "status.quote": "인용", "status.quote.cancel": "인용 취소", + "status.quote_error.blocked_account_hint.title": "@{name}을 차단했기 때문에 이 게시물은 숨겨졌습니다.", + "status.quote_error.blocked_domain_hint.title": "{domain}을 차단했기 때문에 이 게시물은 숨겨졌습니다.", "status.quote_error.filtered": "필터에 의해 가려짐", "status.quote_error.limited_account_hint.action": "그냥 보기", "status.quote_error.limited_account_hint.title": "이 계정은 {domain}의 중재자에 의해 숨겨진 상태입니다.", + "status.quote_error.muted_account_hint.title": "@{name}을 뮤트했기 때문에 이 게시물은 숨겨졌습니다.", "status.quote_error.not_available": "게시물 사용 불가", - "status.quote_error.pending_approval": "게시물 대기중", + "status.quote_error.pending_approval": "계류 중인 게시물", + "status.quote_error.pending_approval_popout.body": "Mastodon에서는 타인이 인용할 수 있는지 여부를 제어할 수 있습니다. 이 게시물은 원저자의 승인을 얻을 때까지 계류됩니다.", "status.quote_error.revoked": "원작성자에 의해 게시물 삭제됨", "status.quote_followers_only": "팔로워만 인용할 수 있는 게시물", "status.quote_manual_review": "작성자가 직접 검토합니다", @@ -924,6 +929,8 @@ "status.quote_private": "비공개 게시물은 인용할 수 없습니다", "status.quotes": "{count, plural, other {인용}}", "status.quotes.empty": "아직 아무도 이 게시물을 인용하지 않았습니다. 누군가 인용한다면 여기에 표시됩니다.", + "status.quotes.local_other_disclaimer": "원작자가 거부한 인용은 표시되지 않습니다.", + "status.quotes.remote_other_disclaimer": "{domain}의 인용만 여기에 확정적으로 보여집니다. 원작자가 거부한 인용은 보여지지 않습니다.", "status.read_more": "더 보기", "status.reblog": "부스트", "status.reblog_or_quote": "부스트 또는 인용", @@ -1005,6 +1012,8 @@ "video.volume_up": "음량 증가", "visibility_modal.button_title": "공개범위 설정", "visibility_modal.header": "공개범위와 반응", + "visibility_modal.helper.direct_quoting": "마스토돈에서 작성된 개인적인 멘션은 남들이 인용할 수 없습니다.", + "visibility_modal.helper.privacy_editing": "공개범위는 게시한 다음 수정할 수 없습니다.", "visibility_modal.helper.privacy_private_self_quote": "자신의 비공개 게시물을 공개 게시물로 인용할 수 없습니다.", "visibility_modal.helper.private_quoting": "마스토돈에서 작성된 팔로워 전용 게시물은 다른 사용자가 인용할 수 없습니다.", "visibility_modal.helper.unlisted_quoting": "사람들에게 인용된 경우, 인용한 게시물도 유행 타임라인에서 감추게 됩니다.", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 6a0bda0935..ec8464175a 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -311,9 +311,6 @@ "explore.trending_links": "Haberes", "explore.trending_statuses": "Publikasyones", "explore.trending_tags": "Etiketas", - "featured_carousel.next": "Sigiente", - "featured_carousel.post": "Puvlikasyon", - "featured_carousel.previous": "Anterior", "filter_modal.added.context_mismatch_explanation": "Esta kategoria del filtro no se aplika al konteksto en ke tienes aksesido esta publikasyon. Si keres ke la publikasyon sea filtrada en este konteksto tamyen, kale editar el filtro.", "filter_modal.added.context_mismatch_title": "El konteksto no koensida!", "filter_modal.added.expired_explanation": "Esta kategoria de filtros tiene kadukado. Kale ke trokar la data de kadukasion para aplikarla.", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 099b8eb142..502092f5f7 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -333,10 +333,6 @@ "explore.trending_links": "Jaunumi", "explore.trending_statuses": "Ieraksti", "explore.trending_tags": "Tēmturi", - "featured_carousel.next": "Tālāk", - "featured_carousel.post": "Ieraksts", - "featured_carousel.previous": "Atpakaļ", - "featured_carousel.slide": "{index} / {total}", "filter_modal.added.context_mismatch_explanation": "Šī atlases kategorija neattiecas uz kontekstu, kurā esi piekļuvis šim ierakstam. Ja vēlies, lai ieraksts tiktu atlasīts arī šajā kontekstā, Tev būs jālabo atlase.", "filter_modal.added.context_mismatch_title": "Konteksta neatbilstība!", "filter_modal.added.expired_explanation": "Šai atlases kategorijai ir beidzies derīguma termiņš. Lai to lietotu, Tev būs jāmaina derīguma termiņš.", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index db021f52eb..bb4b5f2fca 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "PO文", "explore.trending_tags": "Hashtag", "featured_carousel.header": "{count, plural, one {{counter} 篇} other {{counter} 篇}} 釘起來ê PO文", - "featured_carousel.next": "下tsi̍t ê", - "featured_carousel.post": "PO文", - "featured_carousel.previous": "頂tsi̍t ê", - "featured_carousel.slide": "{total} 內底ê {index}", "filter_modal.added.context_mismatch_explanation": "Tsit ê過濾器類別bē當適用佇lí所接近使用ê PO文ê情境。若是lí mā beh佇tsit ê情境過濾tsit ê PO文,lí著編輯過濾器。.", "filter_modal.added.context_mismatch_title": "本文無sio合!", "filter_modal.added.expired_explanation": "Tsit ê過濾器類別過期ah,lí需要改到期ê日期來繼續用。", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index fbc9a4ef2d..db980ddde7 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -361,10 +361,6 @@ "explore.trending_statuses": "Berichten", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Vastgezet bericht} other {Vastgezette berichten}}", - "featured_carousel.next": "Volgende", - "featured_carousel.post": "Bericht", - "featured_carousel.previous": "Vorige", - "featured_carousel.slide": "{index} van {total}", "filter_modal.added.context_mismatch_explanation": "Deze filtercategorie is niet van toepassing op de context waarin je dit bericht hebt benaderd. Als je wilt dat het bericht ook in deze context wordt gefilterd, moet je het filter bewerken.", "filter_modal.added.context_mismatch_title": "Context komt niet overeen!", "filter_modal.added.expired_explanation": "Deze filtercategorie is verlopen. Je moet de vervaldatum wijzigen om de categorie toe te kunnen passen.", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index bb1972f880..11c91b0e17 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -358,10 +358,6 @@ "explore.trending_statuses": "Innlegg", "explore.trending_tags": "Emneknaggar", "featured_carousel.header": "{count, plural, one {Festa innlegg} other {Festa innlegg}}", - "featured_carousel.next": "Neste", - "featured_carousel.post": "Innlegg", - "featured_carousel.previous": "Førre", - "featured_carousel.slide": "{index} av {total}", "filter_modal.added.context_mismatch_explanation": "Denne filterkategorien gjeld ikkje i den samanhengen du har lese dette innlegget. Viss du vil at innlegget skal filtrerast i denne samanhengen òg, må du endra filteret.", "filter_modal.added.context_mismatch_title": "Konteksten passar ikkje!", "filter_modal.added.expired_explanation": "Denne filterkategorien har gått ut på dato. Du må endre best før datoen for at den skal gjelde.", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 2ef8a7085a..8cb67c97b0 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -332,10 +332,6 @@ "explore.trending_statuses": "Innlegg", "explore.trending_tags": "Emneknagger", "featured_carousel.header": "{count, plural, one {{counter} festet innlegg} other {{counter} festede innlegg}}", - "featured_carousel.next": "Neste", - "featured_carousel.post": "Innlegg", - "featured_carousel.previous": "Forrige", - "featured_carousel.slide": "{index} av {total}", "filter_modal.added.context_mismatch_explanation": "Denne filterkategorien gjelder ikke for den konteksten du har åpnet dette innlegget i. Hvis du vil at innlegget skal filtreres i denne konteksten også, må du redigere filteret.", "filter_modal.added.context_mismatch_title": "Feil sammenheng!", "filter_modal.added.expired_explanation": "Denne filterkategorien er utløpt, du må endre utløpsdato for at den skal gjelde.", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index 760dff557f..64ef92dc9e 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -224,10 +224,6 @@ "explore.trending_statuses": "ਪੋਸਟਾਂ", "explore.trending_tags": "ਹੈਸ਼ਟੈਗ", "featured_carousel.header": "{count, plural, one {ਟੰਗੀ ਹੋਈ ਪੋਸਟ} other {ਟੰਗੀਆਂ ਹੋਈਆਂ ਪੋਸਟਾਂ}}", - "featured_carousel.next": "ਅੱਗੇ", - "featured_carousel.post": "ਪੋਸਟ", - "featured_carousel.previous": "ਪਿੱਛੇ", - "featured_carousel.slide": "{total} ਵਿੱਚੋਂ {index}", "filter_modal.added.expired_title": "ਫਿਲਟਰ ਦੀ ਮਿਆਦ ਪੁੱਗੀ!", "filter_modal.added.review_and_configure_title": "ਫਿਲਟਰ ਸੈਟਿੰਗਾਂ", "filter_modal.added.settings_link": "ਸੈਟਿੰਗਾਂ ਸਫ਼ਾ", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index e56369233f..13a38fa3e9 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Wpisy", "explore.trending_tags": "Hasztagi", "featured_carousel.header": "{count, plural, one {przypięty wpis} few {przypięte wpisy} many {przypięte wpisy} other {przypięte wpisy}}", - "featured_carousel.next": "Dalej", - "featured_carousel.post": "Opublikuj", - "featured_carousel.previous": "Wstecz", - "featured_carousel.slide": "{index} z {total}", "filter_modal.added.context_mismatch_explanation": "To filtrowanie nie dotyczy kategorii, w której pojawił się ten wpis. Jeśli chcesz, aby wpis był filtrowany również w tym kontekście, musisz edytować ustawienia filtrowania.", "filter_modal.added.context_mismatch_title": "Niewłaściwy kontekst!", "filter_modal.added.expired_explanation": "Ta kategoria filtrowania wygasła, aby ją zastosować, należy zmienić datę wygaśnięcia.", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index c80297f67d..09d5d54425 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -359,10 +359,6 @@ "explore.trending_statuses": "Publicações", "explore.trending_tags": "Hashtags", "featured_carousel.header": "{count, plural, one {Postagem fixada} other {Postagens fixadas}}", - "featured_carousel.next": "Próximo", - "featured_carousel.post": "Publicação", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Esta categoria de filtro não se aplica ao contexto no qual você acessou esta publicação. Se quiser que a publicação seja filtrada nesse contexto também, você terá que editar o filtro.", "filter_modal.added.context_mismatch_title": "Incompatibilidade de contexto!", "filter_modal.added.expired_explanation": "Esta categoria de filtro expirou, você precisará alterar a data de expiração para aplicar.", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index b08362d030..c1ea75d566 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -361,10 +361,6 @@ "explore.trending_statuses": "Publicações", "explore.trending_tags": "#Etiquetas", "featured_carousel.header": "{count, plural, one {Publicação Afixada} other {Publicações Afixadas}}", - "featured_carousel.next": "Seguinte", - "featured_carousel.post": "Publicação", - "featured_carousel.previous": "Anterior", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_explanation": "Esta categoria de filtro não se aplica ao contexto em que acedeste a esta publicação. Se pretenderes que esta publicação seja filtrada também neste contexto, terás que editar o filtro.", "filter_modal.added.context_mismatch_title": "O contexto não coincide!", "filter_modal.added.expired_explanation": "Esta categoria de filtro expirou, tens de alterar a data de validade para que ele seja aplicado.", @@ -911,9 +907,12 @@ "status.pin": "Afixar no perfil", "status.quote": "Citação", "status.quote.cancel": "Cancelar citação", + "status.quote_error.blocked_account_hint.title": "Esta publicação está oculta porque bloqueou @{name}.", + "status.quote_error.blocked_domain_hint.title": "Esta publicação está oculta porque bloqueou {domain}.", "status.quote_error.filtered": "Oculto devido a um dos seus filtros", "status.quote_error.limited_account_hint.action": "Mostrar na mesma", "status.quote_error.limited_account_hint.title": "Esta conta foi ocultada pelos moderadores de {domain}.", + "status.quote_error.muted_account_hint.title": "Esta publicação está oculta porque silenciou @{name}.", "status.quote_error.not_available": "Publicação indisponível", "status.quote_error.pending_approval": "Publicação pendente", "status.quote_error.pending_approval_popout.body": "No Mastodon, pode controlar se alguém pode citar as suas publicações. Esta publicação está pendente enquanto aguardamos a aprovação do autor original.", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 5571a68d76..ad28b1bef6 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -347,10 +347,6 @@ "explore.trending_statuses": "Посты", "explore.trending_tags": "Хештеги", "featured_carousel.header": "{count, plural, other {Закреплённые посты}}", - "featured_carousel.next": "Следующий", - "featured_carousel.post": "Пост", - "featured_carousel.previous": "Предыдущий", - "featured_carousel.slide": "{index} из {total}", "filter_modal.added.context_mismatch_explanation": "Этот фильтр не применяется в том контексте, в котором вы видели этот пост. Если вы хотите, чтобы пост был отфильтрован в текущем контексте, необходимо редактировать фильтр.", "filter_modal.added.context_mismatch_title": "Несоответствие контекста", "filter_modal.added.expired_explanation": "Этот фильтр истёк. Чтобы он был применён, вам нужно изменить срок действия фильтра.", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 254af6a601..4e2d40fe5c 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -292,7 +292,6 @@ "explore.trending_links": "Noas", "explore.trending_statuses": "Publicatziones", "explore.trending_tags": "Etichetas", - "featured_carousel.slide": "{index} de {total}", "filter_modal.added.context_mismatch_title": "Su cuntestu non currispondet.", "filter_modal.added.expired_title": "Filtru iscadidu.", "filter_modal.added.review_and_configure_title": "Cunfiguratziones de filtru", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 2e368444ee..2a6101e981 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -153,6 +153,8 @@ "bundle_modal_error.close": "Mbylle", "bundle_modal_error.message": "Diç shkoi ters, teksa ngarkohej kjo skenë.", "bundle_modal_error.retry": "Riprovoni", + "carousel.current": "Diapozitivi {current, number} / {max, number}", + "carousel.slide": "Diapozitivi {current, number} nga {max, number} gjithsej", "closed_registrations.other_server_instructions": "Ngaqë Mastodon-i është i decentralizuar, mund të krijoni një llogari në një tjetër shërbyes dhe prapë të ndëveproni me këtë këtu.", "closed_registrations_modal.description": "Krijimi i një llogarie te {domain} aktualisht është i pamundur, por kini parasysh se s’keni nevojë për një llogari posaçërisht në {domain} që të përdorni Mastodon-in.", "closed_registrations_modal.find_another_server": "Gjeni shërbyes tjetër", @@ -169,6 +171,8 @@ "column.edit_list": "Përpunoni listën", "column.favourites": "Të parapëlqyer", "column.firehose": "Prurje “live”", + "column.firehose_local": "Prurje “live” për këtë shërbyes", + "column.firehose_singular": "Prurje “live”", "column.follow_requests": "Kërkesa për ndjekje", "column.home": "Kreu", "column.list_members": "Administroni anëtarë liste", @@ -354,11 +358,9 @@ "explore.trending_links": "Lajme", "explore.trending_statuses": "Postime", "explore.trending_tags": "Hashtagë", + "featured_carousel.current": "Postimi {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {Postim i Fiksuar} other {Postime të Fiksuar}}", - "featured_carousel.next": "Pasuesi", - "featured_carousel.post": "Postim", - "featured_carousel.previous": "I mëparshmi", - "featured_carousel.slide": "{index} nga {total}", + "featured_carousel.slide": "Postimi {current, number} nga {max, number} gjithsej", "filter_modal.added.context_mismatch_explanation": "Kjo kategori filtrash nuk aplikohet për kontekstin nën të cilin po merreni me këtë postim. Nëse doni që postimi të filtrohet edhe në këtë kontekst, do t’ju duhet të përpunoni filtrin.", "filter_modal.added.context_mismatch_title": "Mospërputhje kontekstesh!", "filter_modal.added.expired_explanation": "Kjo kategori filtrash ka skaduar, do t’ju duhet të ndryshoni datën e skadimit për të, pa të aplikohet.", @@ -905,9 +907,12 @@ "status.pin": "Fiksoje në profil", "status.quote": "Citojeni", "status.quote.cancel": "Anuloje citimin", + "status.quote_error.blocked_account_hint.title": "Ky postim është i fshehur, ngaqë keni bllokuar @{name}.", + "status.quote_error.blocked_domain_hint.title": "Ky postim është i fshehur, ngaqë keni bllokuar {domain}.", "status.quote_error.filtered": "Fshehur për shkak të njërit nga filtrat tuaj", "status.quote_error.limited_account_hint.action": "Shfaqe, sido qoftë", "status.quote_error.limited_account_hint.title": "Kjo llogari është fshehur nga moderatorët e {domain}.", + "status.quote_error.muted_account_hint.title": "Ky postim është i fshehur, ngaqë keni heshtuar @{name}.", "status.quote_error.not_available": "Postim që s’mund të kihet", "status.quote_error.pending_approval": "Postim pezull", "status.quote_error.pending_approval_popout.body": "Në Mastodon mundeni të kontrolloni nëse dikush ju citon a jo. Ky postim është pezull, teksa po marrim miratimin e autorit origjinal.", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index e341889041..3883eeb3d9 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -344,10 +344,6 @@ "explore.trending_statuses": "Inlägg", "explore.trending_tags": "Hashtaggar", "featured_carousel.header": "{count, plural,one {Fäst inlägg} other {Fästa inlägg}}", - "featured_carousel.next": "Nästa", - "featured_carousel.post": "Inlägg", - "featured_carousel.previous": "Föregående", - "featured_carousel.slide": "{index} av {total}", "filter_modal.added.context_mismatch_explanation": "Denna filterkategori gäller inte för det sammanhang där du har tillgång till det här inlägget. Om du vill att inlägget ska filtreras även i detta sammanhang måste du redigera filtret.", "filter_modal.added.context_mismatch_title": "Misspassning av sammanhang!", "filter_modal.added.expired_explanation": "Denna filterkategori har utgått, du måste ändra utgångsdatum för att den ska kunna tillämpas.", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 63df997694..4cba56bd9f 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -28,6 +28,7 @@ "account.disable_notifications": "หยุดแจ้งเตือนฉันเมื่อ @{name} โพสต์", "account.domain_blocking": "กำลังปิดกั้นโดเมน", "account.edit_profile": "แก้ไขโปรไฟล์", + "account.edit_profile_short": "แก้ไข", "account.enable_notifications": "แจ้งเตือนฉันเมื่อ @{name} โพสต์", "account.endorse": "แสดงในโปรไฟล์", "account.featured": "น่าสนใจ", @@ -37,6 +38,11 @@ "account.featured_tags.last_status_never": "ไม่มีโพสต์", "account.follow": "ติดตาม", "account.follow_back": "ติดตามกลับ", + "account.follow_back_short": "ติดตามกลับ", + "account.follow_request": "ขอติดตาม", + "account.follow_request_cancel": "ยกเลิกคำขอ", + "account.follow_request_cancel_short": "ยกเลิก", + "account.follow_request_short": "ขอ", "account.followers": "ผู้ติดตาม", "account.followers.empty": "ยังไม่มีใครติดตามผู้ใช้นี้", "account.followers_counter": "{count, plural, other {{counter} ผู้ติดตาม}}", @@ -63,6 +69,7 @@ "account.open_original_page": "เปิดหน้าดั้งเดิม", "account.posts": "โพสต์", "account.posts_with_replies": "โพสต์และการตอบกลับ", + "account.remove_from_followers": "เอา {name} ออกจากผู้ติดตาม", "account.report": "รายงาน @{name}", "account.requested_follow": "{name} ได้ขอติดตามคุณ", "account.share": "แชร์โปรไฟล์ของ @{name}", @@ -158,6 +165,8 @@ "column.edit_list": "แก้ไขรายการ", "column.favourites": "รายการโปรด", "column.firehose": "ฟีดสด", + "column.firehose_local": "ฟีดสดสำหรับเซิร์ฟเวอร์นี้", + "column.firehose_singular": "ฟีดสด", "column.follow_requests": "คำขอติดตาม", "column.home": "หน้าแรก", "column.list_members": "จัดการสมาชิกของรายการ", @@ -209,6 +218,8 @@ "confirmations.delete_list.confirm": "ลบ", "confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?", "confirmations.delete_list.title": "ลบรายการ?", + "confirmations.discard_draft.confirm": "ละทิ้งและดำเนินการต่อ", + "confirmations.discard_draft.post.title": "ละทิ้งโพสต์แบบร่างของคุณ?", "confirmations.discard_edit_media.confirm": "ละทิ้ง", "confirmations.discard_edit_media.message": "คุณมีการเปลี่ยนแปลงคำอธิบายหรือตัวอย่างสื่อที่ยังไม่ได้บันทึก ละทิ้งการเปลี่ยนแปลงเหล่านั้นต่อไป?", "confirmations.follow_to_list.confirm": "ติดตามและเพิ่มไปยังรายการ", @@ -221,10 +232,20 @@ "confirmations.missing_alt_text.secondary": "โพสต์ต่อไป", "confirmations.missing_alt_text.title": "เพิ่มข้อความแสดงแทน?", "confirmations.mute.confirm": "ซ่อน", + "confirmations.quiet_post_quote_info.dismiss": "ไม่ต้องเตือนฉันอีก", + "confirmations.quiet_post_quote_info.got_it": "เข้าใจแล้ว", "confirmations.redraft.confirm": "ลบแล้วร่างใหม่", "confirmations.redraft.message": "คุณแน่ใจหรือไม่ว่าต้องการลบโพสต์นี้แล้วร่างโพสต์ใหม่? รายการโปรดและการดันจะสูญหาย และการตอบกลับโพสต์ดั้งเดิมจะไม่มีความเกี่ยวพัน", "confirmations.redraft.title": "ลบแล้วร่างโพสต์ใหม่?", + "confirmations.remove_from_followers.confirm": "เอาผู้ติดตามออก", + "confirmations.remove_from_followers.title": "เอาผู้ติดตามออก?", + "confirmations.revoke_quote.confirm": "เอาโพสต์ออก", + "confirmations.revoke_quote.title": "เอาโพสต์ออก?", + "confirmations.unblock.confirm": "เลิกปิดกั้น", + "confirmations.unblock.title": "เลิกปิดกั้น {name}?", "confirmations.unfollow.confirm": "เลิกติดตาม", + "confirmations.unfollow.title": "เลิกติดตาม {name}?", + "confirmations.withdraw_request.confirm": "ถอนคำขอ", "content_warning.hide": "ซ่อนโพสต์", "content_warning.show": "แสดงต่อไป", "content_warning.show_more": "แสดงเพิ่มเติม", @@ -265,6 +286,7 @@ "domain_pill.your_handle": "นามของคุณ:", "domain_pill.your_server": "บ้านดิจิทัลของคุณ ที่ซึ่งโพสต์ทั้งหมดของคุณอาศัยอยู่ ไม่ชอบเซิร์ฟเวอร์นี้? ถ่ายโอนเซิร์ฟเวอร์เมื่อใดก็ได้และนำผู้ติดตามของคุณไปด้วยเช่นกัน", "domain_pill.your_username": "ตัวระบุที่ไม่ซ้ำกันของคุณในเซิร์ฟเวอร์นี้ เป็นไปได้ที่จะค้นหาผู้ใช้ที่มีชื่อผู้ใช้เดียวกันในเซิร์ฟเวอร์ที่แตกต่างกัน", + "dropdown.empty": "เลือกตัวเลือก", "embed.instructions": "ฝังโพสต์นี้ในเว็บไซต์ของคุณโดยคัดลอกโค้ดด้านล่าง", "embed.preview": "นี่คือลักษณะของการฝังที่จะปรากฏ:", "emoji_button.activity": "กิจกรรม", @@ -314,10 +336,9 @@ "explore.trending_links": "ข่าว", "explore.trending_statuses": "โพสต์", "explore.trending_tags": "แฮชแท็ก", - "featured_carousel.next": "ถัดไป", - "featured_carousel.post": "โพสต์", - "featured_carousel.previous": "ก่อนหน้า", - "featured_carousel.slide": "{index} จาก {total}", + "featured_carousel.current": "โพสต์ {current, number} / {max, number}", + "featured_carousel.header": "{count, plural, other {โพสต์ที่ปักหมุด}}", + "featured_carousel.slide": "โพสต์ {current, number} จาก {max, number}", "filter_modal.added.context_mismatch_explanation": "หมวดหมู่ตัวกรองนี้ไม่นำไปใช้กับบริบทที่คุณได้เข้าถึงโพสต์นี้ หากคุณต้องการกรองโพสต์ในบริบทนี้ด้วย คุณจะต้องแก้ไขตัวกรอง", "filter_modal.added.context_mismatch_title": "บริบทไม่ตรงกัน!", "filter_modal.added.expired_explanation": "หมวดหมู่ตัวกรองนี้หมดอายุแล้ว คุณจะต้องเปลี่ยนวันหมดอายุสำหรับหมวดหมู่เพื่อนำไปใช้", @@ -370,6 +391,8 @@ "generic.saved": "บันทึกแล้ว", "getting_started.heading": "เริ่มต้นใช้งาน", "hashtag.admin_moderation": "เปิดส่วนติดต่อการกลั่นกรองสำหรับ #{name}", + "hashtag.browse": "เรียกดูโพสต์ใน #{hashtag}", + "hashtag.browse_from_account": "เรียกดูโพสต์จาก @{name} ใน #{hashtag}", "hashtag.column_header.tag_mode.all": "และ {additional}", "hashtag.column_header.tag_mode.any": "หรือ {additional}", "hashtag.column_header.tag_mode.none": "โดยไม่มี {additional}", @@ -417,7 +440,7 @@ "interaction_modal.no_account_yet": "ยังไม่มีบัญชี?", "interaction_modal.on_another_server": "ในเซิร์ฟเวอร์อื่น", "interaction_modal.on_this_server": "ในเซิร์ฟเวอร์นี้", - "interaction_modal.title": "ลงชื่อเข้า", + "interaction_modal.title": "ลงชื่อเข้าเพื่อดำเนินการต่อ", "interaction_modal.username_prompt": "เช่น {example}", "intervals.full.days": "{number, plural, other {# วัน}}", "intervals.full.hours": "{number, plural, other {# ชั่วโมง}}", @@ -457,6 +480,8 @@ "keyboard_shortcuts.translate": "เพื่อแปลโพสต์", "keyboard_shortcuts.unfocus": "เลิกโฟกัสพื้นที่เขียนข้อความ/การค้นหา", "keyboard_shortcuts.up": "ย้ายขึ้นในรายการ", + "learn_more_link.got_it": "เข้าใจแล้ว", + "learn_more_link.learn_more": "เรียนรู้เพิ่มเติม", "lightbox.close": "ปิด", "lightbox.next": "ถัดไป", "lightbox.previous": "ก่อนหน้า", @@ -529,6 +554,8 @@ "navigation_bar.preferences": "การกำหนดลักษณะ", "navigation_bar.privacy_and_reach": "ความเป็นส่วนตัวและการเข้าถึง", "navigation_bar.search": "ค้นหา", + "navigation_panel.collapse_lists": "ยุบเมนูรายการ", + "navigation_panel.expand_lists": "ขยายเมนูรายการ", "not_signed_in_indicator.not_signed_in": "คุณจำเป็นต้องเข้าสู่ระบบเพื่อเข้าถึงทรัพยากรนี้", "notification.admin.report": "{name} ได้รายงาน {target}", "notification.admin.report_account": "{name} ได้รายงาน {count, plural, other {# โพสต์}}จาก {target} สำหรับ {category}", @@ -700,6 +727,7 @@ "relative_time.minutes": "{number} นาที", "relative_time.seconds": "{number} วินาที", "relative_time.today": "วันนี้", + "remove_quote_hint.button_label": "เข้าใจแล้ว", "reply_indicator.attachments": "{count, plural, other {# ไฟล์แนบ}}", "reply_indicator.cancel": "ยกเลิก", "reply_indicator.poll": "การสำรวจความคิดเห็น", @@ -794,9 +822,12 @@ "status.bookmark": "เพิ่มที่คั่นหน้า", "status.cancel_reblog_private": "เลิกดัน", "status.cannot_reblog": "ไม่สามารถดันโพสต์นี้", + "status.context.retry": "ลองใหม่", + "status.context.show": "แสดง", "status.continued_thread": "กระทู้ต่อเนื่อง", "status.copy": "คัดลอกลิงก์ไปยังโพสต์", "status.delete": "ลบ", + "status.delete.success": "ลบโพสต์แล้ว", "status.detailed_status": "มุมมองการสนทนาโดยละเอียด", "status.direct": "กล่าวถึง @{name} แบบส่วนตัว", "status.direct_indicator": "การกล่าวถึงแบบส่วนตัว", @@ -827,6 +858,7 @@ "status.redraft": "ลบแล้วร่างใหม่", "status.remove_bookmark": "เอาที่คั่นหน้าออก", "status.remove_favourite": "เอาออกจากรายการโปรด", + "status.remove_quote": "เอาออก", "status.replied_in_thread": "ตอบกลับในกระทู้", "status.replied_to": "ตอบกลับ {name}", "status.reply": "ตอบกลับ", @@ -885,5 +917,6 @@ "video.mute": "ปิดเสียง", "video.pause": "หยุดชั่วคราว", "video.play": "เล่น", - "video.unmute": "เลิกปิดเสียง" + "video.unmute": "เลิกปิดเสียง", + "visibility_modal.save": "บันทึก" } diff --git a/app/javascript/mastodon/locales/tok.json b/app/javascript/mastodon/locales/tok.json index d21058a67b..221c215887 100644 --- a/app/javascript/mastodon/locales/tok.json +++ b/app/javascript/mastodon/locales/tok.json @@ -327,10 +327,6 @@ "explore.trending_statuses": "toki", "explore.trending_tags": "kulupu pi lipu suli", "featured_carousel.header": "{count, plural, other {toki sewi}}", - "featured_carousel.next": "kama", - "featured_carousel.post": "toki", - "featured_carousel.previous": "pini", - "featured_carousel.slide": "lipu {total} la lipu nanpa {index}", "filter_modal.added.settings_link": "lipu lawa", "filter_modal.select_filter.expired": "tenpo pini", "filter_modal.select_filter.search": "o alasa anu pali", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index e71cae2865..c1004da893 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Kapat", "bundle_modal_error.message": "Bu ekran yüklenirken bir şeyler ters gitti.", "bundle_modal_error.retry": "Tekrar deneyin", + "carousel.current": "Slayt {current, number} / {max, number}", + "carousel.slide": "Slayt {current, number} / {max, number}", "closed_registrations.other_server_instructions": "Mastodon merkeziyetsiz olduğu için, başka bir sunucuda bir hesap oluşturabilir ve bu sunucuyla etkileşimde bulunmaya devam edebilirsiniz.", "closed_registrations_modal.description": "{domain} adresinde hesap oluşturmak şu an mümkün değil ancak unutmayın ki Mastodon kullanmak için özellikle {domain} adresinde hesap oluşturmanız gerekmez.", "closed_registrations_modal.find_another_server": "Başka sunucu bul", @@ -173,6 +175,8 @@ "column.edit_list": "Listeyi düzenle", "column.favourites": "Gözdelerin", "column.firehose": "Anlık Akışlar", + "column.firehose_local": "Bu sunucunun canlı akışı", + "column.firehose_singular": "Canlı akış", "column.follow_requests": "Takip istekleri", "column.home": "Anasayfa", "column.list_members": "Liste üyelerini yönet", @@ -333,6 +337,7 @@ "empty_column.bookmarked_statuses": "Henüz yer imine eklediğin toot yok. Bir tanesi yer imine eklendiğinde burada görünür.", "empty_column.community": "Yerel zaman çizelgesi boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın!", "empty_column.direct": "Henüz doğrudan değinmeniz yok. Bir tane gönderdiğinizde veya aldığınızda burada listelenecek.", + "empty_column.disabled_feed": "Bu akış sunucu yöneticileri tarafından devre dışı bırakılmıştır.", "empty_column.domain_blocks": "Henüz engellenmiş bir alan adı yok.", "empty_column.explore_statuses": "Şu an öne çıkan birşey yok. Daha sonra tekrar bakın!", "empty_column.favourited_statuses": "Henüz bir gönderiyi favorilerinize eklememişsiniz. Bir gönderiyi favorilerinize eklediğinizde burada görünecek.", @@ -357,11 +362,9 @@ "explore.trending_links": "Haberler", "explore.trending_statuses": "Gönderiler", "explore.trending_tags": "Etiketler", + "featured_carousel.current": "Gönderi {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {{counter} Sabitlenmiş Gönderi} other {{counter} Sabitlenmiş Gönderi}}", - "featured_carousel.next": "Sonraki", - "featured_carousel.post": "Gönderi", - "featured_carousel.previous": "Önceki", - "featured_carousel.slide": "{index}/{total}", + "featured_carousel.slide": "Gönderi {current, number} / {max, number}", "filter_modal.added.context_mismatch_explanation": "Bu süzgeç kategorisi, bu gönderide eriştiğin bağlama uymuyor. Eğer gönderinin bu bağlamda da filtrelenmesini istiyorsanız, süzgeci düzenlemeniz gerekiyor.", "filter_modal.added.context_mismatch_title": "Bağlam uyumsuzluğu!", "filter_modal.added.expired_explanation": "Bu süzgeç kategorisinin süresi dolmuş, süzgeci uygulamak için bitiş tarihini değiştirmeniz gerekiyor.", @@ -908,9 +911,12 @@ "status.pin": "Profile sabitle", "status.quote": "Teklif", "status.quote.cancel": "Teklifi iptal et", + "status.quote_error.blocked_account_hint.title": "Bu gönderi @{name} kişisini engellediğiniz için gizlenmiştir.", + "status.quote_error.blocked_domain_hint.title": "Bu gönderi {domain} adresini engellediğiniz için gizlenmiştir.", "status.quote_error.filtered": "Bazı filtrelerinizden dolayı gizlenmiştir", "status.quote_error.limited_account_hint.action": "Yine de göster", "status.quote_error.limited_account_hint.title": "Bu hesap {domain} moderatörleri tarafından gizlendi.", + "status.quote_error.muted_account_hint.title": "Bu gönderi @{name} kişisini sessize aldığınız için gizlenmiştir.", "status.quote_error.not_available": "Gönderi kullanılamıyor", "status.quote_error.pending_approval": "Gönderi beklemede", "status.quote_error.pending_approval_popout.body": "Mastodon'da, birinin sizi alıntılayıp alıntılayamayacağını kontrol edebilirsiniz. Bu gönderi, orijinal yazarın onayını alma sürecinde beklemede.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 45f5b3f458..39260765c2 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -322,7 +322,6 @@ "explore.trending_links": "Новини", "explore.trending_statuses": "Дописи", "explore.trending_tags": "Хештеґи", - "featured_carousel.next": "Далі", "filter_modal.added.context_mismatch_explanation": "Ця категорія фільтра не застосовується до контексту, в якому ви отримали доступ до цього допису. Якщо ви хочете, щоб дописи також фільтрувалися за цим контекстом, вам доведеться редагувати фільтр.", "filter_modal.added.context_mismatch_title": "Невідповідність контексту!", "filter_modal.added.expired_explanation": "Категорія цього фільтра застаріла, Вам потрібно змінити дату закінчення терміну дії, щоб застосувати її.", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 8c475d5480..3de176f495 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "Đóng", "bundle_modal_error.message": "Đã có lỗi xảy ra trong khi tải màn hình này.", "bundle_modal_error.retry": "Thử lại", + "carousel.current": "Slide {current, number} / {max, number}", + "carousel.slide": "Slide {current, number} trong {max, number}", "closed_registrations.other_server_instructions": "Tạo tài khoản trên máy chủ khác và vẫn tương tác với máy chủ này.", "closed_registrations_modal.description": "{domain} hiện tắt đăng ký, nhưng hãy lưu ý rằng bạn không cần một tài khoản riêng trên {domain} để sử dụng Mastodon.", "closed_registrations_modal.find_another_server": "Tìm máy chủ khác", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "Chỉ máy chủ của bạn", "community.column_settings.media_only": "Chỉ hiện tút có media", "community.column_settings.remote_only": "Chỉ người ở máy chủ khác", + "compose.error.blank_post": "Không thể để trống.", "compose.language.change": "Chọn ngôn ngữ tút", "compose.language.search": "Tìm ngôn ngữ...", "compose.published.body": "Tút đã được đăng.", @@ -360,11 +363,9 @@ "explore.trending_links": "Tin tức", "explore.trending_statuses": "Tút", "explore.trending_tags": "Hashtag", + "featured_carousel.current": "Tút {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {Tút đã ghim}}", - "featured_carousel.next": "Sau", - "featured_carousel.post": "Tút", - "featured_carousel.previous": "Trước", - "featured_carousel.slide": "{index} trong {total}", + "featured_carousel.slide": "Tút {current, number} trong {max, number}", "filter_modal.added.context_mismatch_explanation": "Danh mục bộ lọc này không áp dụng cho ngữ cảnh mà bạn đã truy cập tút này. Nếu bạn muốn tút cũng được lọc trong ngữ cảnh này, bạn sẽ phải chỉnh sửa bộ lọc.", "filter_modal.added.context_mismatch_title": "Bối cảnh không phù hợp!", "filter_modal.added.expired_explanation": "Danh mục bộ lọc này đã hết hạn, bạn sẽ cần thay đổi ngày hết hạn để áp dụng.", @@ -911,9 +912,12 @@ "status.pin": "Ghim lên hồ sơ", "status.quote": "Trích dẫn", "status.quote.cancel": "Bỏ trích dẫn", + "status.quote_error.blocked_account_hint.title": "Tút này bị ẩn vì bạn đã chặn @{name}.", + "status.quote_error.blocked_domain_hint.title": "Tút này bị ẩn vì bạn đã chặn {domain}.", "status.quote_error.filtered": "Bị ẩn vì một bộ lọc của bạn", "status.quote_error.limited_account_hint.action": "Vẫn xem", "status.quote_error.limited_account_hint.title": "Người này đã bị ẩn bởi quản trị viên {domain}.", + "status.quote_error.muted_account_hint.title": "Tút này bị ẩn vì bạn đã ẩn @{name}.", "status.quote_error.not_available": "Tút không khả dụng", "status.quote_error.pending_approval": "Tút đang chờ duyệt", "status.quote_error.pending_approval_popout.body": "Trên Mastodon, bạn có thể kiểm soát việc ai đó có thể trích dẫn tút của bạn hay không. Tút này đang chờ phê duyệt từ tác giả gốc.", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 5cf3dbff9b..fc1c5f7965 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "关闭", "bundle_modal_error.message": "加载此页面时发生了错误。", "bundle_modal_error.retry": "重试", + "carousel.current": "幻灯片 {current, number} / {max, number}", + "carousel.slide": "第 {current, number} 张幻灯片,共 {max, number} 张", "closed_registrations.other_server_instructions": "基于 Mastodon 去中心化的特性,你可以其他服务器上创建账号,并继续与此服务器互动。", "closed_registrations_modal.description": "你目前无法在 {domain} 上创建账号,但请注意,使用 Mastodon 并非需要专门在 {domain} 上注册账号。", "closed_registrations_modal.find_another_server": "查找其他服务器", @@ -173,6 +175,8 @@ "column.edit_list": "编辑列表", "column.favourites": "喜欢", "column.firehose": "实时动态", + "column.firehose_local": "此服务器的实时动态", + "column.firehose_singular": "实时动态", "column.follow_requests": "关注请求", "column.home": "主页", "column.list_members": "管理列表成员", @@ -333,6 +337,7 @@ "empty_column.bookmarked_statuses": "你还没有给任何嘟文添加书签。添加书签后的嘟文会显示在这里。", "empty_column.community": "本站时间线还没有内容,写点什么并公开发布,让它活跃起来吧!", "empty_column.direct": "你还未使用过私下提及。当你发出或者收到私下提及时,它将显示在此。", + "empty_column.disabled_feed": "此动态已被您的服务器管理员禁用。", "empty_column.domain_blocks": "暂且没有被屏蔽的站点。", "empty_column.explore_statuses": "目前没有热门内容,稍后再来看看吧!", "empty_column.favourited_statuses": "你没有喜欢过任何嘟文。喜欢过的嘟文会显示在这里。", @@ -357,11 +362,9 @@ "explore.trending_links": "新闻", "explore.trending_statuses": "嘟文", "explore.trending_tags": "话题", + "featured_carousel.current": "嘟文 {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {# 条置顶嘟文}}", - "featured_carousel.next": "下一步", - "featured_carousel.post": "发嘟", - "featured_carousel.previous": "上一步", - "featured_carousel.slide": "第 {index} 共 {total}", + "featured_carousel.slide": "第 {current, number} 条嘟文,共 {max, number} 条", "filter_modal.added.context_mismatch_explanation": "这条过滤规则不适用于你当前访问此嘟文的场景。要在此场景下过滤嘟文,你必须编辑此过滤规则。", "filter_modal.added.context_mismatch_title": "场景不匹配!", "filter_modal.added.expired_explanation": "此过滤规则类别已过期,你需要修改到期日期才能应用。", @@ -908,9 +911,12 @@ "status.pin": "在个人资料页面置顶", "status.quote": "引用", "status.quote.cancel": "取消引用", + "status.quote_error.blocked_account_hint.title": "由于你已屏蔽@{name},此嘟文已隐藏。", + "status.quote_error.blocked_domain_hint.title": "由于你已屏蔽{domain},此嘟文已隐藏。", "status.quote_error.filtered": "已根据你的筛选器过滤", "status.quote_error.limited_account_hint.action": "仍然显示", "status.quote_error.limited_account_hint.title": "此账号已被 {domain} 管理员隐藏。", + "status.quote_error.muted_account_hint.title": "由于你已设置隐藏@{name},此嘟文已隐藏。", "status.quote_error.not_available": "嘟文不可用", "status.quote_error.pending_approval": "嘟文待发布", "status.quote_error.pending_approval_popout.body": "在Mastodon上,你可以控制其他人引用你嘟文的权限。此嘟文在得到原作者的同意后就会发布。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 7525498c2a..5e78303833 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -157,6 +157,8 @@ "bundle_modal_error.close": "關閉", "bundle_modal_error.message": "載入此畫面時發生錯誤。", "bundle_modal_error.retry": "重試", + "carousel.current": "頁面 {current, number} / {max, number}", + "carousel.slide": "{max, number} 頁中之第 {current, number} 頁", "closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。", "closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon。", "closed_registrations_modal.find_another_server": "尋找另一個伺服器", @@ -194,6 +196,7 @@ "community.column_settings.local_only": "只顯示本站", "community.column_settings.media_only": "只顯示媒體", "community.column_settings.remote_only": "只顯示遠端", + "compose.error.blank_post": "嘟文無法為空白。", "compose.language.change": "變更語言", "compose.language.search": "搜尋語言...", "compose.published.body": "發嘟成功。", @@ -360,11 +363,9 @@ "explore.trending_links": "最新消息", "explore.trending_statuses": "嘟文", "explore.trending_tags": "主題標籤", + "featured_carousel.current": "嘟文 {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {# 則釘選嘟文}}", - "featured_carousel.next": "下一個", - "featured_carousel.post": "嘟文", - "featured_carousel.previous": "上一個", - "featured_carousel.slide": "{total} 中的 {index}", + "featured_carousel.slide": "{max, number} 則嘟文中之第 {current, number} 則", "filter_modal.added.context_mismatch_explanation": "此過濾器類別不是用您所存取嘟文的情境。若您想要此嘟文被於此情境被過濾,您必須編輯過濾器。", "filter_modal.added.context_mismatch_title": "不符合情境!", "filter_modal.added.expired_explanation": "此過濾器類別已失效,您需要更新過期日期以套用。", @@ -911,9 +912,12 @@ "status.pin": "釘選至個人檔案頁面", "status.quote": "引用", "status.quote.cancel": "取消引用嘟文", + "status.quote_error.blocked_account_hint.title": "由於您已封鎖 @{name},此嘟文已被隱藏。", + "status.quote_error.blocked_domain_hint.title": "由於您已封鎖 {domain},此嘟文已被隱藏。", "status.quote_error.filtered": "由於您的過濾器,該嘟文被隱藏", "status.quote_error.limited_account_hint.action": "仍要顯示", "status.quote_error.limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。", + "status.quote_error.muted_account_hint.title": "由於您已靜音 @{name},此嘟文已被隱藏。", "status.quote_error.not_available": "無法取得該嘟文", "status.quote_error.pending_approval": "嘟文正在等候審核中", "status.quote_error.pending_approval_popout.body": "您能於 Mastodon 控制是否允許引用您的嘟文。此嘟文正在等待原始作者審核。", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 0ef95b0146..bd09f3b8b0 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1362,7 +1362,7 @@ } } -.announcements__item__content { +.announcements__content { overflow-wrap: break-word; overflow-y: auto; @@ -8931,10 +8931,21 @@ noscript { } .announcements { - background: lighten($ui-base-color, 8%); - font-size: 13px; - display: flex; - align-items: flex-end; + width: calc(100% - 124px); + flex: 0 0 auto; + position: relative; + overflow: hidden; + + @media screen and (max-width: (124px + 300px)) { + width: 100%; + } + + &__root { + background: lighten($ui-base-color, 8%); + font-size: 13px; + display: flex; + align-items: flex-end; + } &__mastodon { width: 124px; @@ -8945,19 +8956,16 @@ noscript { } } - &__container { - width: calc(100% - 124px); - flex: 0 0 auto; - position: relative; - - @media screen and (max-width: (124px + 300px)) { - width: 100%; - } + &__slides { + display: flex; + flex-wrap: nowrap; + align-items: start; } - &__item { + &__slide { box-sizing: border-box; width: 100%; + flex: 0 0 100%; padding: 15px; position: relative; font-size: 15px; @@ -8966,26 +8974,25 @@ noscript { font-weight: 400; max-height: 50vh; overflow: hidden; - display: flex; flex-direction: column; + } - &__range { - display: block; - font-weight: 500; - margin-bottom: 10px; - padding-inline-end: 18px; - } + &__range { + display: block; + font-weight: 500; + margin-bottom: 10px; + padding-inline-end: 18px; + } - &__unread { - position: absolute; - top: 19px; - inset-inline-end: 19px; - display: block; - background: $highlight-text-color; - border-radius: 50%; - width: 0.625rem; - height: 0.625rem; - } + &__unread { + position: absolute; + top: 19px; + inset-inline-end: 19px; + display: block; + background: $highlight-text-color; + border-radius: 50%; + width: 0.625rem; + height: 0.625rem; } &__pagination { @@ -8996,6 +9003,7 @@ noscript { inset-inline-end: 0; display: flex; align-items: center; + z-index: 1; } } @@ -11587,4 +11595,10 @@ noscript { height: 16px; } } + + &__pagination { + display: flex; + align-items: center; + gap: 4px; + } } diff --git a/app/javascript/testing/api.ts b/app/javascript/testing/api.ts index dd45b7e7b6..096d2ce30e 100644 --- a/app/javascript/testing/api.ts +++ b/app/javascript/testing/api.ts @@ -53,6 +53,7 @@ export const mockHandlers = { const locale = toSupportedLocale(params.locale); action('fetching emoji data')(locale); const { default: data } = (await import( + /* @vite-ignore */ `emojibase-data/${locale}/compact.json` )) as { default: CompactEmoji[]; diff --git a/app/javascript/types/dom.d.ts b/app/javascript/types/dom.d.ts new file mode 100644 index 0000000000..fcb1b0346f --- /dev/null +++ b/app/javascript/types/dom.d.ts @@ -0,0 +1,6 @@ +declare namespace React { + interface HTMLAttributes extends AriaAttributes, DOMAttributes { + // Add inert attribute support, which is only in React 19.2. See: https://github.com/facebook/react/pull/24730 + inert?: ''; + } +} diff --git a/app/lib/request.rb b/app/lib/request.rb index 4858aa4bc2..dd65b481d8 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -65,6 +65,7 @@ class Request # and 5s timeout on the TLS handshake, meaning the worst case should take # about 15s in total TIMEOUT = { connect_timeout: 5, read_timeout: 10, write_timeout: 10, read_deadline: 30 }.freeze + SAFE_PRESERVED_CHARS = '+,' include RoutingHelper @@ -72,7 +73,7 @@ class Request raise ArgumentError if url.blank? @verb = verb - @url = Addressable::URI.parse(url).normalize + @url = normalize_preserving_url_encodings(url, SAFE_PRESERVED_CHARS) @http_client = options.delete(:http_client) @allow_local = options.delete(:allow_local) @options = { @@ -148,6 +149,34 @@ class Request private + # Using code from https://github.com/sporkmonger/addressable/blob/3450895887d0a1770660d8831d1b6fcfed9bd9d6/lib/addressable/uri.rb#L1609-L1635 + # to preserve some URL Encodings while normalizing + def normalize_preserving_url_encodings(url, preserved_chars = SAFE_PRESERVED_CHARS, *flags) + original_uri = Addressable::URI.parse(url) + normalized_uri = original_uri.normalize + + if original_uri.query + modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup + modified_query_class.sub!('\\&', '').sub!('\\;', '') + + pairs = original_uri.query.split('&', -1) + pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted) + pairs.sort! if flags.include?(:sorted) + + normalized_query = pairs.map do |pair| + Addressable::URI.normalize_component( + pair, + modified_query_class, + preserved_chars + ) + end.join('&') + + normalized_uri.query = normalized_query == '' ? nil : normalized_query + end + + normalized_uri + end + def set_common_headers! @headers['User-Agent'] = Mastodon::Version.user_agent @headers['Host'] = @url.host diff --git a/config/locales/de.yml b/config/locales/de.yml index e4a579575f..4b2c10fa31 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -796,6 +796,8 @@ de: view_dashboard_description: Gewährt Benutzer*innen den Zugriff auf das Dashboard und verschiedene Metriken view_devops: DevOps view_devops_description: Erlaubt es Benutzer*innen, auf die Sidekiq- und pgHero-Dashboards zuzugreifen + view_feeds: Live-Feeds und Hashtags anzeigen + view_feeds_description: Ermöglicht Nutzer*innen unabhängig von den Servereinstellungen den Zugriff auf die Live-Feeds und Hashtags title: Rollen rules: add_new: Regel hinzufügen @@ -851,10 +853,13 @@ de: feed_access: modes: authenticated: Nur authentifizierte Nutzer*innen + disabled: Bestimmte Rolle erforderlich public: Alle landing_page: values: about: Über + local_feed: Lokaler Feed + trends: Trends registrations: moderation_recommandation: Bitte vergewissere dich, dass du ein geeignetes und reaktionsschnelles Moderationsteam hast, bevor du die Registrierungen uneingeschränkt zulässt! preamble: Lege fest, wer auf deinem Server ein Konto erstellen darf. @@ -1193,7 +1198,8 @@ de: appearance: advanced_settings: Erweiterte Einstellungen animations_and_accessibility: Animationen und Barrierefreiheit - boosting_preferences: Teilen-Einstellungen + boosting_preferences: Teilen + boosting_preferences_info_html: "Tipp: Shift + Klick beim %{icon} Teilen-Symbol wird den Beitrag immer sofort teilen." discovery: Entdecken localization: body: Mastodon wird von Freiwilligen übersetzt. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 8649426129..e8c9a2568a 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -839,12 +839,12 @@ fi: title: Jätä käyttäjät oletusarvoisesti hakukoneindeksoinnin ulkopuolelle discovery: follow_recommendations: Seurantasuositukset - preamble: Mielenkiintoisen sisällön esille tuominen on keskeistä uusien käyttäjien perehdyttämisessä, jotka eivät ehkä tunne ketään Mastodonissa. Hallitse, miten eri löydettävyysominaisuudet toimivat palvelimellasi. + preamble: Mielenkiintoisen sisällön esille tuominen on keskeistä perehdyttäessä uusia käyttäjiä, jotka eivät ehkä tunne ketään Mastodonissa. Hallitse, miten eri löydettävyysominaisuudet toimivat palvelimellasi. privacy: Yksityisyys profile_directory: Profiilihakemisto public_timelines: Julkiset aikajanat publish_statistics: Julkaise tilastot - title: Löytäminen + title: Löydettävyys trends: Trendit domain_blocks: all: Kaikille @@ -1200,7 +1200,7 @@ fi: animations_and_accessibility: Animaatiot ja saavutettavuus boosting_preferences: Tehostusasetukset boosting_preferences_info_html: "Vihje: Asetuksista riippumatta Vaihto + napsautus %{icon} Tehosta-kuvakkeeseen tehostaa välittömästi." - discovery: Löytäminen + discovery: Löydettävyys localization: body: Mastodonin ovat kääntäneet vapaaehtoiset. guide_link: https://crowdin.com/project/mastodon @@ -2085,7 +2085,7 @@ fi: disable: Et voi enää käyttää tiliäsi, mutta profiilisi ja muut tiedot pysyvät muuttumattomina. Voit pyytää varmuuskopiota tiedoistasi, vaihtaa tilin asetuksia tai poistaa tilisi. mark_statuses_as_sensitive: Palvelimen %{instance} moderaattorit ovat merkinneet osan julkaisuistasi arkaluonteisiksi. Tämä tarkoittaa sitä, että mediaa täytyy napauttaa ennen kuin sen esikatselu näytetään. Voit merkitä median itse arkaluonteiseksi, kun julkaiset tulevaisuudessa. sensitive: Tästä lähtien kaikki lähetetyt mediatiedostot merkitään arkaluonteisiksi ja piilotetaan napsautusvaroituksen taakse. - silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat käyttäjät näkevät julkaisusi tällä palvelimella ja sinut voidaan sulkea pois eri löytämisominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti. + silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat käyttäjät näkevät julkaisusi tällä palvelimella ja sinut voidaan sulkea pois eri löydettävyysominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti. suspend: Et voi enää käyttää tiliäsi, eivätkä profiilisi ja muut tiedot ole enää käytettävissä. Voit silti kirjautua sisään pyytääksesi tietojesi varmuuskopiota, kunnes tiedot on poistettu kokonaan noin 30 päivän kuluttua. Säilytämme kuitenkin joitain perustietoja, jotka estävät sinua kiertämästä jäädytystä. reason: 'Syy:' statuses: 'Julkaisuja lainattu:' diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 3b1f956fe1..5406b6411c 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -824,6 +824,8 @@ gd: view_dashboard_description: Leigidh seo le cleachdaichean an deas-bhòrd agus meatrachdan inntrigeadh view_devops: DevOps view_devops_description: Leigidh seo le cleachdaichean na deas-bhùird aig Sidekiq is pgHero inntrigeadh + view_feeds: Seall loidhnichean-ama beòtha ’s nan cuspairean + view_feeds_description: Leigidh seo le cleachdaichean loidhnichean-ama beòtha ’s nan cuspairean inntrigeadh ge b’ e dè roghainnean an fhrithealaiche title: Dreuchdan rules: add_new: Cuir riaghailt ris @@ -879,7 +881,13 @@ gd: feed_access: modes: authenticated: Cleachdaichean a chlàraich a-steach a-mhàin + disabled: Iarr dreuchd shònraichte a’ chleachdaiche public: A h-uile duine + landing_page: + values: + about: Mu dhèidhinn + local_feed: Loidhne-ama ionadail + trends: Treandaichean registrations: moderation_recommandation: Dèan cinnteach gu bheil sgioba maoir deiseil is deònach agad mus fhosgail thu an clàradh dhan a h-uile duine! preamble: Stiùirich cò dh’fhaodas cunntas a chruthachadh air an fhrithealaiche agad. @@ -2028,7 +2036,7 @@ gd: private: Luchd-leantainn a-mhàin public: Poblach public_long: Neach sam bith taobh a-staigh no a-muigh Mhastodon - unlisted: Poblach ach sàmhach + unlisted: Sàmhach unlisted_long: Falaichte o na toraidhean-luirg, na treandaichean ’s na loichnichean-ama poblach statuses_cleanup: enabled: Sguab às seann-phostaichean gu fèin-obrachail diff --git a/config/locales/hu.yml b/config/locales/hu.yml index a90e8a5c2c..ca3f337f46 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -855,6 +855,11 @@ hu: authenticated: Csak hitelesített felhasználók disabled: Konkrét felhasználói szerepkör megkövetelése public: Mindenki + landing_page: + values: + about: Névjegy + local_feed: Helyi idővonal + trends: Trendek registrations: moderation_recommandation: Győződj meg arról, hogy megfelelő és gyors reagálású moderátor csapatod van, mielőtt mindenki számára megnyitod a regisztrációt! preamble: Szabályozd, hogy ki hozhat létre fiókot a kiszolgálón. diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 118f7ed905..eda169a28a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1895,7 +1895,7 @@ ko: reblog: 부스트는 고정될 수 없습니다 quote_error: not_available: 게시물 사용 불가 - pending_approval: 게시물 대기중 + pending_approval: 계류 중인 게시물 revoked: 원작성자에 의해 게시물 삭제됨 quote_policies: followers: 팔로워만 diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index 74b6e5d9ef..1085626e48 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -54,8 +54,10 @@ de: password: Verwende mindestens 8 Zeichen phrase: Wird unabhängig von der Groß- und Kleinschreibung im Text oder der Inhaltswarnung eines Beitrags abgeglichen scopes: Welche Schnittstellen der Applikation erlaubt sind. Wenn du einen Top-Level-Scope auswählst, dann musst du nicht jeden einzelnen darunter auswählen. + setting_advanced_layout: Dadurch wird Mastodon in mehrere Spalten aufgeteilt, womit du deine Timeline, Benachrichtigungen und eine dritte Spalte deiner Wahl nebeneinander siehst. Nicht bei einem kleinen Bildschirm empfohlen. setting_aggregate_reblogs: Beiträge, die erst kürzlich geteilt wurden, werden nicht noch einmal angezeigt (betrifft nur zukünftig geteilte Beiträge) setting_always_send_emails: Normalerweise werden Benachrichtigungen nicht per E-Mail versendet, wenn du gerade auf Mastodon aktiv bist + setting_boost_modal: Dadurch wird beim Teilen ein Bestätigungsdialog angezeigt, um die Sichtbarkeit anzupassen. setting_default_quote_policy_private: Beiträge, die nur für deine Follower bestimmt sind und auf Mastodon verfasst wurden, können nicht von anderen zitiert werden. setting_default_quote_policy_unlisted: Sollten dich andere zitieren, werden ihre zitierten Beiträge ebenfalls nicht in den Trends und öffentlichen Timelines angezeigt. setting_default_sensitive: Medien, die mit einer Inhaltswarnung versehen worden sind, werden – je nach Einstellung – erst nach einem zusätzlichen Klick angezeigt @@ -63,6 +65,7 @@ de: setting_display_media_hide_all: Medien immer ausblenden setting_display_media_show_all: Medien mit Inhaltswarnung immer anzeigen setting_emoji_style: 'Wie Emojis dargestellt werden: „Automatisch“ verwendet native Emojis, für veraltete Browser wird jedoch Twemoji verwendet.' + setting_quick_boosting_html: Dadurch wird der Beitrag beim Anklicken des %{boost_icon} Teilen-Symbols sofort geteilt, anstatt das Drop-down-Menü zu öffnen. Die Möglichkeit zum Zitieren wird dabei in %{options_icon} Mehr verschoben. setting_system_scrollbars_ui: Betrifft nur Desktop-Browser, die auf Chrome oder Safari basieren setting_use_blurhash: Der Farbverlauf basiert auf den Farben der ausgeblendeten Medien, verschleiert aber jegliche Details setting_use_pending_items: Neue Beiträge hinter einem Klick verstecken, anstatt automatisch zu scrollen @@ -90,6 +93,7 @@ de: content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Diese Option richtet sich ausschließlich an Server mit speziellen Zwecken und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist. custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. favicon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Symbol. + landing_page: Legt fest, welche Seite neue Besucher*innen sehen, wenn sie zum ersten Mal auf deinem Server ankommen. Für „Trends“ müssen die Trends in den Entdecken-Einstellungen aktiviert sein. Für „Lokaler Feed“ muss „Zugriff auf Live-Feeds, die lokale Beiträge beinhalten“ in den Entdecken-Einstellungen auf „Alle“ gesetzt werden. mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche. media_cache_retention_period: Mediendateien aus Beiträgen von externen Nutzer*innen werden auf deinem Server zwischengespeichert. Wenn ein positiver Wert gesetzt ist, werden die Medien nach der festgelegten Anzahl von Tagen gelöscht. Sollten die Medien nach dem Löschvorgang wieder angefragt werden, werden sie erneut heruntergeladen, sofern der ursprüngliche Inhalt noch vorhanden ist. Es wird empfohlen, diesen Wert auf mindestens 14 Tage festzulegen, da die Häufigkeit der Abfrage von Linkvorschaukarten für Websites von Dritten begrenzt ist und die Linkvorschaukarten sonst nicht vor Ablauf dieser Zeit aktualisiert werden. min_age: Nutzer*innen werden bei der Registrierung aufgefordert, ihr Geburtsdatum zu bestätigen @@ -233,10 +237,12 @@ de: setting_aggregate_reblogs: Geteilte Beiträge in den Timelines gruppieren setting_always_send_emails: Benachrichtigungen immer senden setting_auto_play_gif: Animierte GIFs automatisch abspielen + setting_boost_modal: Sichtbarkeit für geteilte Beiträge anpassen setting_default_language: Beitragssprache setting_default_privacy: Beitragssichtbarkeit setting_default_quote_policy: Wer zitieren darf setting_default_sensitive: Medien immer mit einer Inhaltswarnung versehen + setting_delete_modal: Vor dem Löschen bestätigen setting_disable_hover_cards: Profilvorschau deaktivieren, wenn die Maus über das Profil bewegt wird setting_disable_swiping: Wischgesten deaktivieren setting_display_media: Darstellung von Medien @@ -246,7 +252,8 @@ de: setting_emoji_style: Emoji-Stil setting_expand_spoilers: Beiträge mit Inhaltswarnung immer ausklappen setting_hide_network: Follower und „Folge ich“ nicht anzeigen - setting_quick_boosting: Schnelles Boosten aktivieren + setting_missing_alt_text_modal: Erinnerung für Bildbeschreibung anzeigen + setting_quick_boosting: Schnelles Teilen aktivieren setting_reduce_motion: Bewegung in Animationen verringern setting_system_font_ui: Standardschriftart des Browsers verwenden setting_system_scrollbars_ui: Bildlaufleiste des Betriebssystems verwenden @@ -280,6 +287,7 @@ de: content_cache_retention_period: Aufbewahrungsfrist für externe Inhalte custom_css: Eigenes CSS favicon: Favicon + landing_page: Landingpage für neue Besucher*innen local_live_feed_access: Zugriff auf Live-Feeds, die lokale Beiträge beinhalten local_topic_feed_access: Zugriff auf Hashtags und Links, die lokale Beiträge beinhalten mascot: Benutzerdefiniertes Maskottchen (Legacy) diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 296d5def5b..048c27e987 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -93,7 +93,7 @@ fi: content_cache_retention_period: Kaikki muiden palvelinten julkaisut (mukaan lukien tehostukset ja vastaukset) poistuvat, kun määritetty määrä päiviä on kulunut, lukuun ottamatta paikallisen käyttäjän vuorovaikutusta näiden julkaisujen kanssa. Tämä sisältää julkaisut, jotka paikallinen käyttäjä on merkinnyt kirjanmerkiksi tai suosikiksi. Myös yksityismaininnat eri palvelinten käyttäjien välillä menetetään, eikä niitä voi palauttaa. Tämä asetus on tarkoitettu käytettäväksi erityistapauksissa ja rikkoo monia käyttäjien odotuksia, kun sitä sovelletaan yleiskäyttöön. custom_css: Voit käyttää mukautettuja tyylejä Mastodonin selainversiossa. favicon: WEBP, PNG, GIF tai JPG. Korvaa oletusarvoisen Mastodonin sivustokuvakkeen haluamallasi kuvakkeella. - landing_page: Valitsee mitä sivua uudet kävijät näkevät saapuessaan palvelimellesi. Jos valitset "Trendit", trendien tulee olla käytössä Löytöasetuksissa. Jos valitset "Paikallinen syöte", "Pääsy paikallisten julkaisujen live-syötteisiin" tulee asettaa "Kaikille" Löytöasetuksissa. + landing_page: Valitsee, minkä sivun uudet kävijät näkevät saapuessaan palvelimellesi. Jos valitset ”Trendit”, trendien tulee olla käytössä Löydettävyys-asetuksissa. Jos valitset ”Paikallinen syöte”, kohta ”Pääsy paikallisia julkaisuja esitteleviin livesyötteisiin” tulee asettaa arvoon ”Kaikki” Löydettävyys-asetuksissa. mascot: Korvaa kuvituksen edistyneessä selainkäyttöliittymässä. media_cache_retention_period: Etäkäyttäjien tekemien julkaisujen mediatiedostot ovat välimuistissa palvelimellasi. Kun kentän arvo on positiivinen, media poistuu, kun määritetty määrä päiviä on kulunut. Jos mediaa pyydetään sen poistamisen jälkeen, se ladataan uudelleen, jos lähdesisältö on vielä saatavilla. Koska linkkien esikatselun kyselyitä kolmansien osapuolien sivustoille on rajoitettu, on suositeltavaa asettaa tämä arvo vähintään 14 päivään, tai linkkien kortteja ei päivitetä pyynnöstä ennen tätä ajankohtaa. min_age: Käyttäjiä pyydetään rekisteröitymisen aikana vahvistamaan syntymäpäivänsä @@ -145,7 +145,7 @@ fi: admin_email: Oikeudellisiin ilmoituksiin kuuluvat vastailmoitukset, oikeuden määräykset, poistopyynnöt ja lainvalvontaviranomaisten pyynnöt. arbitration_address: Voi olla sama kuin edellä mainittu Fyysinen osoite tai ”N/A”, jos käytät sähköpostia. arbitration_website: Voi olla verkkolomake tai ”N/A”, jos käytät sähköpostia. - choice_of_law: Kaupunki, alue, territoriumi tai valtio, jonka sisäiset substantiiviset lait säätelevät kaikkia vaateita. + choice_of_law: Kaupunki, alue, territorio tai valtio, jonka sisäinen aineellinen oikeus säätelee kaikkia vaatimuksia. dmca_address: Yhdysvaltalaisten operaattoreiden on käytettävä DMCA Designated Agent Directory -luetteloon rekisteröityä osoitetta. Postilokeroluettelo on saatavissa suoralla pyynnöllä, joten käytä DMCA Designated Agent Post Office Box Waiver Request -lomaketta lähettääksesi sähköpostia tekijänoikeusvirastolle ja kuvaile, että olet kotona toimiva sisältömoderaattori, joka pelkää kostoa tai rangaistusta toimistaan ja tarvitsee postilokeroa pitääkseen kotiosoitteensa poissa julkisuudesta. dmca_email: Voi olla sama kuin edellä mainittu ”Sähköpostiosoite oikeudellisille ilmoituksille”. domain: Tarjoamasi verkkopalvelun yksilöllinen tunniste. @@ -174,7 +174,7 @@ fi: labels: account: attribution_domains: Verkkosivustot, jotka voivat antaa sinulle tunnustusta - discoverable: Pidä profiiliasi ja julkaisujasi esillä löytämisalgoritmeissa + discoverable: Pidä profiiliasi ja julkaisujasi esillä löydettävyysalgoritmeissa fields: name: Nimike value: Sisältö diff --git a/config/locales/simple_form.gd.yml b/config/locales/simple_form.gd.yml index bc4c3b7f0a..3f918c2eb4 100644 --- a/config/locales/simple_form.gd.yml +++ b/config/locales/simple_form.gd.yml @@ -65,7 +65,7 @@ gd: setting_display_media_hide_all: Falaich na meadhanan an-còmhnaidh setting_display_media_show_all: Seall na meadhanan an-còmhnaidh setting_emoji_style: An dòigh air an dèid emojis a shealltainn. Feuchaidh “Fèin-obrachail” ris na h-emojis tùsail a chleachdadh ach thèid Twemoji a chleachdadh ’nan àite air seann-bhrabhsairean. - setting_quick_boosting_html: Ma tha seo an comas, ma nì thu briogadh air ìomhaigheag %{boost_icon} a’ bhrosnachaidh, thèid a bhriosnachadh sa bhad seach a bhith a’ fosgladh clàr-taice teàrnach a’ bhrosnachaidh/luaidh. Thèid gnìomh an luaidh a ghluasad gu clàr-taice nan %{options_icon} (roghainnean). + setting_quick_boosting_html: Ma tha seo an comas, ma nì thu briogadh air ìomhaigheag %{boost_icon} a’ bhrosnachaidh, thèid a bhrosnachadh sa bhad seach a bhith a’ fosgladh clàr-taice teàrnach a’ bhrosnachaidh/luaidh. Thèid gnìomh an luaidh a ghluasad gu clàr-taice %{options_icon} nan roghainnean. setting_system_scrollbars_ui: Chan obraich seo ach air brabhsairean desktop stèidhichte air Safari ’s Chrome setting_use_blurhash: Tha caiseadan stèidhichte air dathan nan nithean lèirsinneach a chaidh fhalach ach chan fhaicear am mion-fhiosrachadh setting_use_pending_items: Falaich ùrachaidhean na loidhne-ama air cùlaibh briogaidh seach a bhith a’ sgroladh nam postaichean gu fèin-obrachail @@ -93,6 +93,7 @@ gd: content_cache_retention_period: Thèid a h-uile post o fhrithealaiche sam bith eile (a’ gabhail a-staigh brosnachaidhean is freagairtean) a sguabadh às às dèidh na h-àireimh de làithean a shònraich thu ’s gun diù a chon air eadar-ghabhail ionadail air na postaichean ud. Gabhaidh seo a-steach na postaichean a chuir cleachdaiche ionadail ris na h-annsachdan aca no comharran-lìn riutha. Thèid iomraidhean prìobhaideach eadar cleachdaichean o ionstansan diofraichte air chall cuideachd agus cha ghabh an aiseag idir. Tha an roghainn seo do dh’ionstansan sònraichte a-mhàin agus briseadh e dùilean an luchd-cleachdaidh nuair a rachadh a chleachdadh gu coitcheann. custom_css: "’S urrainn dhut stoidhlean gnàthaichte a chur an sàs air an tionndadh-lìn de Mhastodon." favicon: WEBP, PNG, GIF no JPG. Tar-àithnidh seo favicon bunaiteach Mhastodon le ìomhaigheag ghnàthaichte. + landing_page: Taghaidh seo an duilleag a chì aoighean ùra nuair a thadhlas air an fhrithealaiche agad a’ chiad turas. ma thaghas tu “Treandaichean”, feumaidh tu na treandaichean a chur an comas ann ann roghainnean an rùrachaidh. Ma thaghas tu “Loidhne-ama ionadail”, feumaidh tu “Inntrigeadh dhan t-saoghal bheò sa bheil postaichean ionadail” a shuidheachadh air “A h-uile duine” ann an roghainnean an rùrachaidh. mascot: Tar-àithnidh seo an sgead-dhealbh san eadar-aghaidh-lìn adhartach. media_cache_retention_period: Thèid faidhlichean meadhain o phostaichean a chruthaich cleachdaichean cèine a chur ri tasgadan an fhrithealaiche agad. Nuair a shuidhicheas tu seo air luach dearbh, thèid na meadhanan a sguabadh às às dèidh na h-àireimh de làithean a shònraich thu. Ma tha dàta meadhain ga iarraidh às dèidh a sguabaidh às, thèid a luchdadh a-nuas a-rithist ma tha susbaint an tùis ri fhaighinn fhathast. Ri linn cuingeachaidhean air mar a cheasnaicheas cairtean ro-sheallaidh làraichean threas-phàrtaidhean, mholamaid gun suidhich thu an luach seo air 14 làithean ar a char as giorra no cha dèid an ùrachadh nuair a thèid an iarraidh ron àm sin. min_age: Thèid iarraidh air an luchd-cleachdaidh gun dearbh iad an là-breith rè a’ chlàraidh @@ -288,6 +289,7 @@ gd: content_cache_retention_period: Ùine glèidhidh aig susbaint chèin custom_css: CSS gnàthaichte favicon: Favicon + landing_page: An duilleag-laighe do dh’aoighean ùra local_live_feed_access: Inntrigeadh dhan t-saoghal bheò sa bheil postaichean ionadail local_topic_feed_access: Inntrigeadh dha loidhnichean-ama nan tagaichean hais is ceanglaichean sa bheil postaichean ionadail mascot: Suaichnean gnàthaichte (dìleabach) diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml index 0e41641d61..b1e05c672f 100644 --- a/config/locales/simple_form.hu.yml +++ b/config/locales/simple_form.hu.yml @@ -93,6 +93,7 @@ hu: content_cache_retention_period: Minden más kiszolgálóról származó bejegyzés (megtolásokkal és válaszokkal együtt) törölve lesz a megadott számú nap elteltével, függetlenül a helyi felhasználók ezekkel a bejegyzésekkel történő interakcióitól. Ebben azok a bejegyzések is benne vannak, melyeket a helyi felhasználó könyvjelzőzött vagy kedvencnek jelölt. A különböző kiszolgálók felhasználói közötti privát üzenetek is el fognak veszni visszaállíthatatlanul. Ennek a beállításnak a használata különleges felhasználási esetekre javasolt, mert számos felhasználói elvárás fog eltörni, ha általános céllal használják. custom_css: A Mastodon webes verziójában használhatsz egyéni stílusokat. favicon: WEBP, PNG, GIF vagy JPG. Az alapértelmezett Mastodon favicont felülírja egy egyéni ikonnal. + landing_page: Kiválasztja, hogy a webhely új látogatói mit látnak, amikor először érkeznek a kiszolgálóra. Ha a „Trendek” lehetőséget választod, akkor engedélyezni kell a trendeket a Felfedezési beállításokban. Ha a „Helyi hírfolyamot” választod, akkor a „Helyi bejegyzéseket tartalmazó helyi élő idővonalak elérése” lehetőséget „Mindenki” értékre kell állítani a Felfedezési beállításokban. mascot: Felülbírálja a speciális webes felületen található illusztrációt. media_cache_retention_period: A távoli felhasználók bejegyzéseinek médiatartalmait a kiszolgálód gyorsítótárazza. Ha pozitív értékre állítják, ezek a médiatartalmak a megadott számú nap után törölve lesznek. Ha a médiát újra lekérik, miután törlődött, újra le fogjuk tölteni, ha az eredeti még elérhető. A hivatkozások előnézeti kártyáinak harmadik fél weboldalai felé történő hivatkozásaira alkalmazott megkötései miatt javasolt, hogy ezt az értéket legalább 14 napra állítsuk, ellenkező esetben a hivatkozások előnézeti kártyái szükség esetén nem fognak tudni frissülni ezen idő előtt. min_age: A felhasználók a regisztráció során arra lesznek kérve, hogy erősítsek meg a születési dátumukat @@ -286,6 +287,7 @@ hu: content_cache_retention_period: Távoli tartalmak megtartási időszaka custom_css: Egyéni CSS favicon: Könyvjelzőikon + landing_page: Kezdőoldal az új látogatóknak local_live_feed_access: Helyi bejegyzéseket bemutató élő hírfolyamok elérése local_topic_feed_access: Helyi bejegyzéseket bemutató hashtagek és hivatkozásfolyamok elérése mascot: Egyéni kabala (örökölt) diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index 5b7c6f33e0..b8348032f4 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -89,7 +89,7 @@ ko: backups_retention_period: 사용자들은 나중에 다운로드하기 위해 게시물 아카이브를 생성할 수 있습니다. 양수로 설정된 경우 이 아카이브들은 지정된 일수가 지난 후에 저장소에서 자동으로 삭제될 것입니다. bootstrap_timeline_accounts: 이 계정들은 팔로우 추천 목록 상단에 고정됩니다. closed_registrations_message: 새 가입을 차단했을 때 표시됩니다 - content_cache_retention_period: 다른 서버의 모든 게시물(부스트 및 답글 포함)은 해당 게시물에 대한 로컬 사용자의 상호 작용과 관계없이 지정된 일수가 지나면 삭제됩니다. 여기에는 로컬 사용자가 북마크 또는 즐겨찾기로 표시한 게시물도 포함됩니다. 다른 인스턴스 사용자와 주고 받은 비공개 멘션도 손실되며 복원할 수 없습니다. 이 설정은 특수 목적의 인스턴스를 위한 것이며 일반적인 용도의 많은 사용자의 예상이 빗나가게 됩니다. + content_cache_retention_period: "(부스트 및 답글 포함) 다른 서버의 모든 게시물은 해당 게시물에 대한 로컬 사용자의 상호 작용과 관계없이 지정된 일수가 지나면 삭제됩니다. 여기에는 로컬 사용자가 북마크 또는 즐겨찾기로 표시한 게시물도 포함됩니다. 다른 인스턴스 사용자와 주고 받은 개인 멘션도 손실되며 복원할 수 없습니다. 이 설정은 특수 목적의 인스턴스를 위한 것이며 일반적인 용도의 많은 사용자의 예상이 빗나가게 됩니다." custom_css: 사용자 지정 스타일을 웹 버전의 마스토돈에 지정할 수 있습니다. favicon: WEBP, PNG, GIF 또는 JPG. 기본 파비콘을 대체합니다. mascot: 고급 웹 인터페이스의 그림을 대체합니다. diff --git a/config/locales/th.yml b/config/locales/th.yml index 202e2c0035..58fbfa65c1 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -187,6 +187,7 @@ th: create_relay: สร้างรีเลย์ create_unavailable_domain: สร้างโดเมนที่ไม่พร้อมใช้งาน create_user_role: สร้างบทบาท + create_username_block: สร้างกฎชื่อผู้ใช้ demote_user: ลดขั้นผู้ใช้ destroy_announcement: ลบประกาศ destroy_canonical_email_block: ลบการปิดกั้นอีเมล @@ -200,6 +201,7 @@ th: destroy_status: ลบโพสต์ destroy_unavailable_domain: ลบโดเมนที่ไม่พร้อมใช้งาน destroy_user_role: ทำลายบทบาท + destroy_username_block: ลบกฎชื่อผู้ใช้ disable_2fa_user: ปิดใช้งาน 2FA disable_custom_emoji: ปิดใช้งานอีโมจิที่กำหนดเอง disable_relay: ปิดใช้งานรีเลย์ @@ -234,6 +236,7 @@ th: update_report: อัปเดตรายงาน update_status: อัปเดตโพสต์ update_user_role: อัปเดตบทบาท + update_username_block: อัปเดตกฎชื่อผู้ใช้ actions: approve_appeal_html: "%{name} ได้อนุมัติการอุทธรณ์การตัดสินใจในการกลั่นกรองจาก %{target}" approve_user_html: "%{name} ได้อนุมัติการลงทะเบียนจาก %{target}" @@ -481,6 +484,7 @@ th: save: บันทึก sign_in: ลงชื่อเข้า status: สถานะ + title: FASP follow_recommendations: description_html: "คำแนะนำการติดตามช่วยให้ผู้ใช้ใหม่ค้นหาเนื้อหาที่น่าสนใจได้อย่างรวดเร็ว เมื่อผู้ใช้ไม่ได้โต้ตอบกับผู้อื่นมากพอที่จะสร้างคำแนะนำการติดตามเฉพาะบุคคล จะแนะนำบัญชีเหล่านี้แทน จะคำนวณคำแนะนำใหม่เป็นประจำทุกวันจากบัญชีต่าง ๆ ที่มีการมีส่วนร่วมล่าสุดสูงสุดและจำนวนผู้ติดตามในเซิร์ฟเวอร์สูงสุดสำหรับภาษาที่กำหนด" language: สำหรับภาษา @@ -792,6 +796,9 @@ th: all: ให้กับทุกคน disabled: ให้กับไม่มีใคร users: ให้กับผู้ใช้ในเซิร์ฟเวอร์ที่เข้าสู่ระบบ + landing_page: + values: + about: เกี่ยวกับ registrations: moderation_recommandation: โปรดตรวจสอบให้แน่ใจว่าคุณมีทีมการกลั่นกรองที่เพียงพอและมีปฏิกิริยาตอบสนองก่อนที่คุณจะเปิดการลงทะเบียนให้กับทุกคน! preamble: ควบคุมผู้ที่สามารถสร้างบัญชีในเซิร์ฟเวอร์ของคุณ @@ -1019,6 +1026,14 @@ th: other: ใช้โดย %{count} คนในช่วงสัปดาห์ที่ผ่านมา title: คำแนะนำและแนวโน้ม trending: กำลังนิยม + username_blocks: + delete: ลบ + edit: + title: แก้ไขกฎชื่อผู้ใช้ + new: + create: สร้างกฎ + title: สร้างกฎชื่อผู้ใช้ใหม่ + title: กฎชื่อผู้ใช้ warning_presets: add_new: เพิ่มใหม่ delete: ลบ @@ -1090,6 +1105,7 @@ th: hint_html: หากคุณต้องการย้ายจากบัญชีอื่นไปยังบัญชีนี้ ที่นี่คุณสามารถสร้างนามแฝง ซึ่งจำเป็นก่อนที่คุณจะสามารถดำเนินการต่อด้วยการย้ายผู้ติดตามจากบัญชีเก่าไปยังบัญชีนี้ การกระทำนี้โดยตัวการกระทำเอง ไม่เป็นอันตรายและย้อนกลับได้ การโยกย้ายบัญชีเริ่มต้นจากบัญชีเก่า remove: เลิกเชื่อมโยงนามแฝง appearance: + advanced_settings: การตั้งค่าขั้นสูง animations_and_accessibility: ภาพเคลื่อนไหวและการช่วยการเข้าถึง discovery: การค้นพบ localization: @@ -1465,6 +1481,11 @@ th: expires_at: หมดอายุเมื่อ uses: การใช้งาน title: เชิญผู้คน + link_preview: + author_html: โดย %{name} + potentially_sensitive_content: + action: คลิกเพื่อแสดง + hide_button: ซ่อน lists: errors: limit: คุณมีรายการถึงจำนวนสูงสุดแล้ว @@ -1765,6 +1786,9 @@ th: other: "%{count} วิดีโอ" boosted_from_html: ดันจาก %{acct_link} content_warning: 'คำเตือนเนื้อหา: %{warning}' + content_warnings: + hide: ซ่อนโพสต์ + show: แสดงเพิ่มเติม default_language: เหมือนกับภาษาส่วนติดต่อ disallowed_hashtags: other: 'มีแฮชแท็กที่ไม่อนุญาต: %{tags}' diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index e7385e392e..ea98c6e736 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -782,6 +782,8 @@ zh-CN: view_dashboard_description: 允许用户访问信息面板和各种指标 view_devops: 开发运维 view_devops_description: 允许用户访问 Sidekiq 和 pgHero 控制面板 + view_feeds: 查看实时动态和话题 + view_feeds_description: 允许用户无视服务器设置访问实时动态和话题 title: 角色 rules: add_new: 添加规则 @@ -837,6 +839,7 @@ zh-CN: feed_access: modes: authenticated: 仅已登录用户 + disabled: 需要特定的用户角色 public: 所有人 landing_page: values: diff --git a/lib/mastodon/email_configuration_helper.rb b/lib/mastodon/email_configuration_helper.rb index af86472786..be017a4a1f 100644 --- a/lib/mastodon/email_configuration_helper.rb +++ b/lib/mastodon/email_configuration_helper.rb @@ -8,25 +8,23 @@ module Mastodon # `config/email.yml`) into the format that `ActionMailer` understands def convert_smtp_settings(config) enable_starttls = nil - enable_starttls_auto = nil case config[:enable_starttls] when 'always' - enable_starttls = true - when 'never' + enable_starttls = :always + when 'never', 'false' enable_starttls = false when 'auto' - enable_starttls_auto = true + enable_starttls = :auto else - enable_starttls_auto = config[:enable_starttls_auto] != 'false' + enable_starttls = config[:enable_starttls_auto] ? :auto : false unless config[:tls] || config[:ssl] end authentication = config[:authentication] == 'none' ? nil : (config[:authentication] || 'plain') - config.merge( + config.without(:enable_starttls_auto).merge( authentication:, - enable_starttls:, - enable_starttls_auto: + enable_starttls: ) end end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 8f5f0f9c9c..9ac54d1b7c 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,7 +9,7 @@ module Mastodon end def minor - 5 + 6 end def patch @@ -17,7 +17,7 @@ module Mastodon end def default_prerelease - 'rc.1' + 'alpha.1' end def prerelease diff --git a/package.json b/package.json index 5288335b0f..e52235ede9 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "eslint-import-resolver-typescript": "^4.2.5", "eslint-plugin-formatjs": "^5.3.1", "eslint-plugin-import": "~2.32.0", - "eslint-plugin-jsdoc": "^60.0.0", + "eslint-plugin-jsdoc": "^61.1.11", "eslint-plugin-jsx-a11y": "~6.10.2", "eslint-plugin-promise": "~7.2.1", "eslint-plugin-react": "^7.37.4", @@ -185,7 +185,7 @@ "lint-staged": "^16.0.0", "msw": "^2.10.2", "msw-storybook-addon": "^2.0.5", - "playwright": "^1.54.1", + "playwright": "^1.56.1", "prettier": "^3.3.3", "react-test-renderer": "^18.2.0", "storybook": "^9.1.1", @@ -194,6 +194,7 @@ "stylelint-config-standard-scss": "^16.0.0", "typescript": "~5.9.0", "typescript-eslint": "^8.45.0", + "typescript-plugin-css-modules": "^5.2.0", "vitest": "^3.2.4" }, "resolutions": { diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index dab6aadbaa..d996761169 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -57,6 +57,17 @@ RSpec.describe FollowerAccountsController do ) end + context 'when account hides their network' do + before { alice.update(hide_collections: true) } + + it 'returns forbidden response' do + expect(response) + .to have_http_status(403) + expect(response.parsed_body) + .to include(error: /forbidden/i) + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index 666c655d74..576d25d93c 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -57,6 +57,17 @@ RSpec.describe FollowingAccountsController do ) end + context 'when account hides their network' do + before { alice.update(hide_collections: true) } + + it 'returns forbidden response' do + expect(response) + .to have_http_status(403) + expect(response.parsed_body) + .to include(error: /forbidden/i) + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/lib/mastodon/email_configuration_helper_spec.rb b/spec/lib/mastodon/email_configuration_helper_spec.rb index db513672f0..2894699d05 100644 --- a/spec/lib/mastodon/email_configuration_helper_spec.rb +++ b/spec/lib/mastodon/email_configuration_helper_spec.rb @@ -21,8 +21,9 @@ RSpec.describe Mastodon::EmailConfigurationHelper do base_configuration.merge({ enable_starttls: 'always' }) end - it 'converts this to `true`' do - expect(converted_settings[:enable_starttls]).to be true + it 'converts this to `:always`' do + expect(converted_settings[:enable_starttls]).to eq :always + expect(converted_settings[:enable_starttls_auto]).to be_nil end end @@ -33,6 +34,7 @@ RSpec.describe Mastodon::EmailConfigurationHelper do it 'converts this to `false`' do expect(converted_settings[:enable_starttls]).to be false + expect(converted_settings[:enable_starttls_auto]).to be_nil end end @@ -41,28 +43,43 @@ RSpec.describe Mastodon::EmailConfigurationHelper do base_configuration.merge({ enable_starttls: 'auto' }) end - it 'sets `enable_starttls_auto` instead' do - expect(converted_settings[:enable_starttls]).to be_nil - expect(converted_settings[:enable_starttls_auto]).to be true + it 'sets `enable_starttls` to `:auto`' do + expect(converted_settings[:enable_starttls]).to eq :auto + expect(converted_settings[:enable_starttls_auto]).to be_nil end end context 'when `enable_starttls` is unset' do - context 'when `enable_starttls_auto` is unset' do - let(:configuration) { base_configuration } + context 'when `enable_starttls_auto` is true' do + let(:configuration) do + base_configuration.merge({ enable_starttls_auto: true }) + end - it 'sets `enable_starttls_auto` to `true`' do - expect(converted_settings[:enable_starttls_auto]).to be true + it 'sets `enable_starttls` to `:auto`' do + expect(converted_settings[:enable_starttls]).to eq :auto + expect(converted_settings[:enable_starttls_auto]).to be_nil end end - context 'when `enable_starttls_auto` is set to "false"' do + context 'when `tls` is set to true' do let(:configuration) do - base_configuration.merge({ enable_starttls_auto: 'false' }) + base_configuration.merge({ tls: true }) end - it 'sets `enable_starttls_auto` to `false`' do - expect(converted_settings[:enable_starttls_auto]).to be false + it 'sets `enable_starttls` to `nil`' do + expect(converted_settings[:enable_starttls]).to be_nil + expect(converted_settings[:enable_starttls_auto]).to be_nil + end + end + + context 'when `enable_starttls_auto` is set to false' do + let(:configuration) do + base_configuration.merge({ enable_starttls_auto: false }) + end + + it 'sets `enable_starttls` to `false`' do + expect(converted_settings[:enable_starttls]).to be false + expect(converted_settings[:enable_starttls_auto]).to be_nil end end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 82021cd3d0..153de1ef1c 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -27,6 +27,7 @@ RSpec.describe UserMailer do address: 'localhost', port: 25, authentication: 'none', + enable_starttls_auto: true, } end @@ -44,8 +45,7 @@ RSpec.describe UserMailer do address: 'localhost', port: 25, authentication: nil, - enable_starttls: nil, - enable_starttls_auto: true, + enable_starttls: :auto, }) end end diff --git a/streaming/metrics.js b/streaming/metrics.js index 263339a1ca..d84aa0c28d 100644 --- a/streaming/metrics.js +++ b/streaming/metrics.js @@ -9,7 +9,7 @@ import metrics from 'prom-client'; * @property {metrics.Gauge} redisSubscriptions * @property {metrics.Counter} redisMessagesReceived * @property {metrics.Counter<"type">} messagesSent - * @property {import('express').RequestHandler<{}>} requestHandler + * @property {import('express').RequestHandler} requestHandler */ /** @@ -93,7 +93,7 @@ export function setupMetrics(channels, pgPool) { messagesSent.inc({ type: 'eventsource' }, 0); /** - * @type {import('express').RequestHandler<{}>} + * @type {import('express').RequestHandler} */ const requestHandler = (req, res) => { metrics.register.metrics().then((output) => { diff --git a/tsconfig.json b/tsconfig.json index 3948210956..5663aeada4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,8 @@ "flavours/glitch/*": ["app/javascript/flavours/glitch/*"], "images/*": ["app/javascript/images/*"], "styles/*": ["app/javascript/styles/*"] - } + }, + "plugins": [{ "name": "typescript-plugin-css-modules" }] }, "include": [ "vite.config.mts", diff --git a/vite.config.mts b/vite.config.mts index 263b3d7959..e43ff00e7d 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -27,6 +27,8 @@ import { MastodonAssetsManifest } from './config/vite/plugin-assets-manifest'; const jsRoot = path.resolve(__dirname, 'app/javascript'); +const cssAliasClasses: ReadonlyArray = ['components', 'features']; + export const config: UserConfigFnPromise = async ({ mode, command }) => { const isProdBuild = mode === 'production' && command === 'build'; @@ -49,6 +51,45 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => { }, }, css: { + modules: { + generateScopedName(name, filename) { + let prefix = ''; + + // Use the top two segments of the path as the prefix. + const [parentDirName, dirName] = path + .dirname(filename) + .split(path.sep) + .slice(-2) + .map((dir) => dir.toLowerCase()); + + // If the parent directory is in the cssAliasClasses list, use + // the first four letters of it as the prefix, otherwise use the full name. + if (parentDirName) { + if (cssAliasClasses.includes(parentDirName)) { + prefix = parentDirName.slice(0, 4); + } else { + prefix = parentDirName; + } + } + + // If we have a directory name, append it to the prefix. + if (dirName) { + prefix = `${prefix}_${dirName}`; + } + + // If the file is not styles.module.scss or style.module.scss, + // append the file base name to the prefix. + const baseName = path.basename( + filename, + `.module${path.extname(filename)}`, + ); + if (baseName !== 'styles' && baseName !== 'style') { + prefix = `${prefix}_${baseName}`; + } + + return `_${prefix}__${name}`; + }, + }, postcss: { plugins: [ postcssPresetEnv({ diff --git a/yarn.lock b/yarn.lock index 32be7911d0..8d8f5d3f15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,6 +19,13 @@ __metadata: languageName: node linkType: hard +"@adobe/css-tools@npm:~4.3.1": + version: 4.3.3 + resolution: "@adobe/css-tools@npm:4.3.3" + checksum: 10c0/e76e712df713964b87cdf2aca1f0477f19bebd845484d5fcba726d3ec7782366e2f26ec8cb2dcfaf47081a5c891987d8a9f5c3f30d11e1eb3c1848adc27fcb24 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.3.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" @@ -2054,16 +2061,23 @@ __metadata: languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.71.0": - version: 0.71.0 - resolution: "@es-joy/jsdoccomment@npm:0.71.0" +"@es-joy/jsdoccomment@npm:~0.76.0": + version: 0.76.0 + resolution: "@es-joy/jsdoccomment@npm:0.76.0" dependencies: "@types/estree": "npm:^1.0.8" "@typescript-eslint/types": "npm:^8.46.0" comment-parser: "npm:1.4.1" esquery: "npm:^1.6.0" - jsdoc-type-pratt-parser: "npm:~6.6.0" - checksum: 10c0/fe64b729c18238c7e83f8fab30eab8ce97da6565adbb963011463f9abedef5393972ac1eeebd04b17b189e94bc389274dcb8f707023e96fd922d12dc608b5409 + jsdoc-type-pratt-parser: "npm:~6.10.0" + checksum: 10c0/8fe4edec7d60562787ea8c77193ebe8737a9e28ec3143d383506b63890d0ffd45a2813e913ad1f00f227cb10e3a1fb913e5a696b33d499dc564272ff1a6f3fdb + languageName: node + linkType: hard + +"@es-joy/resolve.exports@npm:1.2.0": + version: 1.2.0 + resolution: "@es-joy/resolve.exports@npm:1.2.0" + checksum: 10c0/7e4713471f5eccb17a925a12415a2d9e372a42376813a19f6abd9c35e8d01ab1403777265817da67c6150cffd4f558d9ad51e26a8de6911dad89d9cb7eedacd8 languageName: node linkType: hard @@ -2858,7 +2872,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^4.2.5" eslint-plugin-formatjs: "npm:^5.3.1" eslint-plugin-import: "npm:~2.32.0" - eslint-plugin-jsdoc: "npm:^60.0.0" + eslint-plugin-jsdoc: "npm:^61.1.11" eslint-plugin-jsx-a11y: "npm:~6.10.2" eslint-plugin-promise: "npm:~7.2.1" eslint-plugin-react: "npm:^7.37.4" @@ -2884,7 +2898,7 @@ __metadata: msw: "npm:^2.10.2" msw-storybook-addon: "npm:^2.0.5" path-complete-extname: "npm:^1.0.0" - playwright: "npm:^1.54.1" + playwright: "npm:^1.56.1" postcss-preset-env: "npm:^10.1.5" prettier: "npm:^3.3.3" prop-types: "npm:^15.8.1" @@ -2925,6 +2939,7 @@ __metadata: twitter-text: "npm:3.1.0" typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.45.0" + typescript-plugin-css-modules: "npm:^5.2.0" use-debounce: "npm:^10.0.0" vite: "npm:^7.1.1" vite-plugin-manifest-sri: "npm:^0.2.0" @@ -3646,6 +3661,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/base62@npm:^1.0.0": + version: 1.0.0 + resolution: "@sindresorhus/base62@npm:1.0.0" + checksum: 10c0/9a14df0f058fdf4731c30f0f05728a4822144ee42236030039d7fa5a1a1072c2879feba8091fd4a17c8922d1056bc07bada77c31fddc3e15836fc05a266fd918 + languageName: node + linkType: hard + "@standard-schema/spec@npm:^1.0.0": version: 1.0.0 resolution: "@standard-schema/spec@npm:1.0.0" @@ -4346,6 +4368,24 @@ __metadata: languageName: node linkType: hard +"@types/postcss-modules-local-by-default@npm:^4.0.2": + version: 4.0.2 + resolution: "@types/postcss-modules-local-by-default@npm:4.0.2" + dependencies: + postcss: "npm:^8.0.0" + checksum: 10c0/af13e40673abf96f1427c467bc9d96986fc0fb702f65ef702de05f70e51af2212bc0bdf177bfd817e418f2238bf210fdee3541dd2d939fde9a4df5f8972ad716 + languageName: node + linkType: hard + +"@types/postcss-modules-scope@npm:^3.0.4": + version: 3.0.4 + resolution: "@types/postcss-modules-scope@npm:3.0.4" + dependencies: + postcss: "npm:^8.0.0" + checksum: 10c0/6364674e429143fd686e0238d071377cf9ae1780a77f99e99292a06adc93057609146aaf55c09310ae99526c37e56be5a8a843086c0ff95513bd34c6bc4c7480 + languageName: node + linkType: hard + "@types/prop-types@npm:*, @types/prop-types@npm:^15.7.5": version: 15.7.15 resolution: "@types/prop-types@npm:15.7.15" @@ -4659,14 +4699,14 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.45.0": +"@typescript-eslint/types@npm:8.45.0": version: 8.45.0 resolution: "@typescript-eslint/types@npm:8.45.0" checksum: 10c0/0213a0573c671d13bc91961a2b2e814ec7f6381ff093bce6704017bd96b2fc7fee25906c815cedb32a0601cf5071ca6c7c5f940d087c3b0d3dd7d4bc03478278 languageName: node linkType: hard -"@typescript-eslint/types@npm:^8.46.0": +"@typescript-eslint/types@npm:^8.45.0, @typescript-eslint/types@npm:^8.46.0": version: 8.46.1 resolution: "@typescript-eslint/types@npm:8.46.1" checksum: 10c0/90887acaa5b33b45af20cf7f87ec4ae098c0daa88484245473e73903fa6e542f613247c22148132167891ca06af6549a60b9d2fd14a65b22871e016901ce3756 @@ -5473,13 +5513,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.13.0 - resolution: "axios@npm:1.13.0" + version: 1.13.1 + resolution: "axios@npm:1.13.1" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.4" proxy-from-env: "npm:^1.1.0" - checksum: 10c0/2af09f8ad9db9565bf97055eb0ddd2fd4abd9a03d23157b409348c9589370a88c3ede02e11fd1268becb780a77b62bdf9488650dd7208eda57edceca1d65622e + checksum: 10c0/de9c3c6de43d3ee1146d3afe78645f19450cac6a5d7235bef8b8e8eeb705c2e47e2d231dea99cecaec4dae1897c521118ca9413b9d474063c719c4d94c5b9adc languageName: node linkType: hard @@ -6116,6 +6156,15 @@ __metadata: languageName: node linkType: hard +"copy-anything@npm:^2.0.1": + version: 2.0.6 + resolution: "copy-anything@npm:2.0.6" + dependencies: + is-what: "npm:^3.14.1" + checksum: 10c0/2702998a8cc015f9917385b7f16b0d85f1f6e5e2fd34d99f14df584838f492f49aa0c390d973684c687e895c5c58d08b308a0400ac3e1e3d6fa1e5884a5402ad + languageName: node + linkType: hard + "core-js-compat@npm:^3.43.0": version: 3.44.0 resolution: "core-js-compat@npm:3.44.0" @@ -6590,6 +6639,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.4.2": + version: 16.6.1 + resolution: "dotenv@npm:16.6.1" + checksum: 10c0/15ce56608326ea0d1d9414a5c8ee6dcf0fffc79d2c16422b4ac2268e7e2d76ff5a572d37ffe747c377de12005f14b3cc22361e79fc7f1061cce81f77d2c973dc + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -6757,6 +6813,17 @@ __metadata: languageName: node linkType: hard +"errno@npm:^0.1.1": + version: 0.1.8 + resolution: "errno@npm:0.1.8" + dependencies: + prr: "npm:~1.0.1" + bin: + errno: cli.js + checksum: 10c0/83758951967ec57bf00b5f5b7dc797e6d65a6171e57ea57adcf1bd1a0b477fd9b5b35fae5be1ff18f4090ed156bce1db749fe7e317aac19d485a5d150f6a4936 + languageName: node + linkType: hard + "error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" @@ -7151,11 +7218,12 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^60.0.0": - version: 60.8.3 - resolution: "eslint-plugin-jsdoc@npm:60.8.3" +"eslint-plugin-jsdoc@npm:^61.1.11": + version: 61.1.11 + resolution: "eslint-plugin-jsdoc@npm:61.1.11" dependencies: - "@es-joy/jsdoccomment": "npm:~0.71.0" + "@es-joy/jsdoccomment": "npm:~0.76.0" + "@es-joy/resolve.exports": "npm:1.2.0" are-docs-informative: "npm:^0.0.2" comment-parser: "npm:1.4.1" debug: "npm:^4.4.3" @@ -7163,13 +7231,14 @@ __metadata: espree: "npm:^10.4.0" esquery: "npm:^1.6.0" html-entities: "npm:^2.6.0" - object-deep-merge: "npm:^1.0.5" + object-deep-merge: "npm:^2.0.0" parse-imports-exports: "npm:^0.2.4" - semver: "npm:^7.7.2" + semver: "npm:^7.7.3" spdx-expression-parse: "npm:^4.0.0" + to-valid-identifier: "npm:^1.0.0" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/2c5aa623a3e5f7410b36464df759ae5e7265ba6f9aaf67f7c16f9033c4a699532a3de702afe5bd6132717a61196be44aff170db36b71600278800770a9cd88ab + checksum: 10c0/bdc5353eddd40440924aa9b908289ab7d5f50bd64585a9ac1d49be56a22af802b90648e9e0fd27729f38508aee3f6c3437330d98be4c6398aa2dfd7a3fcd5028 languageName: node linkType: hard @@ -8053,7 +8122,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -8270,7 +8339,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -8279,6 +8348,15 @@ __metadata: languageName: node linkType: hard +"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": + version: 5.1.0 + resolution: "icss-utils@npm:5.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/39c92936fabd23169c8611d2b5cc39e39d10b19b0d223352f20a7579f75b39d5f786114a6b8fc62bee8c5fed59ba9e0d38f7219a4db383e324fb3061664b043d + languageName: node + linkType: hard + "idb-keyval@npm:^6.2.0": version: 6.2.1 resolution: "idb-keyval@npm:6.2.1" @@ -8314,6 +8392,15 @@ __metadata: languageName: node linkType: hard +"image-size@npm:~0.5.0": + version: 0.5.5 + resolution: "image-size@npm:0.5.5" + bin: + image-size: bin/image-size.js + checksum: 10c0/655204163af06732f483a9fe7cce9dff4a29b7b2e88f5c957a5852e8143fa750f5e54b1955a2ca83de99c5220dbd680002d0d4e09140b01433520f4d5a0b1f4c + languageName: node + linkType: hard + "immer@npm:^10.0.3": version: 10.0.3 resolution: "immer@npm:10.0.3" @@ -8791,6 +8878,13 @@ __metadata: languageName: node linkType: hard +"is-what@npm:^3.14.1": + version: 3.14.1 + resolution: "is-what@npm:3.14.1" + checksum: 10c0/4b770b85454c877b6929a84fd47c318e1f8c2ff70fd72fd625bc3fde8e0c18a6e57345b6e7aa1ee9fbd1c608d27cfe885df473036c5c2e40cd2187250804a2c7 + languageName: node + linkType: hard + "is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" @@ -8940,10 +9034,10 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~6.6.0": - version: 6.6.0 - resolution: "jsdoc-type-pratt-parser@npm:6.6.0" - checksum: 10c0/3cb9c28a945a66a925ebe40fd752113af01e655a0a0fedc6b1702e23c8f9ed187c45caf6cf94f009bde6cf5c98562524aa7a74ebb4571fca6d3ee5bef0344ec1 +"jsdoc-type-pratt-parser@npm:~6.10.0": + version: 6.10.0 + resolution: "jsdoc-type-pratt-parser@npm:6.10.0" + checksum: 10c0/8ea395df0cae0e41d4bdba5f8d81b8d3e467fe53d1e4182a5d4e653235a5f17d60ed137343d68dbc74fa10e767f1c58fb85b1f6d5489c2cf16fc7216cc6d3e1a languageName: node linkType: hard @@ -9181,6 +9275,41 @@ __metadata: languageName: node linkType: hard +"less@npm:^4.2.0": + version: 4.4.2 + resolution: "less@npm:4.4.2" + dependencies: + copy-anything: "npm:^2.0.1" + errno: "npm:^0.1.1" + graceful-fs: "npm:^4.1.2" + image-size: "npm:~0.5.0" + make-dir: "npm:^2.1.0" + mime: "npm:^1.4.1" + needle: "npm:^3.1.0" + parse-node-version: "npm:^1.0.1" + source-map: "npm:~0.6.0" + tslib: "npm:^2.3.0" + dependenciesMeta: + errno: + optional: true + graceful-fs: + optional: true + image-size: + optional: true + make-dir: + optional: true + mime: + optional: true + needle: + optional: true + source-map: + optional: true + bin: + lessc: bin/lessc + checksum: 10c0/f8b796e45ef171adc390b5250f3018922cd046c256181dd9d4cbcbbdc5d6de7cb88c8327741c10eff7ff76421cd826fd95a664ea1b88fbf6f31742428d4a2dab + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -9198,6 +9327,13 @@ __metadata: languageName: node linkType: hard +"lilconfig@npm:^2.0.5": + version: 2.1.0 + resolution: "lilconfig@npm:2.1.0" + checksum: 10c0/64645641aa8d274c99338e130554abd6a0190533c0d9eb2ce7ebfaf2e05c7d9961f3ffe2bfa39efd3b60c521ba3dd24fa236fe2775fc38501bf82bf49d4678b8 + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -9254,6 +9390,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: 10c0/fcba15d21a458076dd309fce6b1b4bf611d84a0ec252cb92447c948c533ac250b95d2e00955801ebc367e5af5ed288b996d75d37d2035260a937008e14eaf432 + languageName: node + linkType: hard + "lodash.debounce@npm:^4.0.8": version: 4.0.8 resolution: "lodash.debounce@npm:4.0.8" @@ -9404,6 +9547,16 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^2.1.0": + version: 2.1.0 + resolution: "make-dir@npm:2.1.0" + dependencies: + pify: "npm:^4.0.1" + semver: "npm:^5.6.0" + checksum: 10c0/ada869944d866229819735bee5548944caef560d7a8536ecbc6536edca28c72add47cc4f6fc39c54fb25d06b58da1f8994cf7d9df7dadea047064749efc085d8 + languageName: node + linkType: hard + "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -9535,7 +9688,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.6.0": +"mime@npm:1.6.0, mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" bin: @@ -9782,6 +9935,18 @@ __metadata: languageName: node linkType: hard +"needle@npm:^3.1.0": + version: 3.3.1 + resolution: "needle@npm:3.3.1" + dependencies: + iconv-lite: "npm:^0.6.3" + sax: "npm:^1.2.4" + bin: + needle: bin/needle + checksum: 10c0/233b9315d47b735867d03e7a018fb665ee6cacf3a83b991b19538019cf42b538a3e85ca745c840b4c5e9a0ffdca76472f941363bf7c166214ae8cbc650fd4d39 + languageName: node + linkType: hard + "negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -9899,12 +10064,10 @@ __metadata: languageName: node linkType: hard -"object-deep-merge@npm:^1.0.5": - version: 1.0.5 - resolution: "object-deep-merge@npm:1.0.5" - dependencies: - type-fest: "npm:4.2.0" - checksum: 10c0/6664ecb43a2519c9b101f1c3b130dfc73e108d86ec06fbe7261505e1522cf8b69b10dd53b8cbb4cde35cca9d44d349667e2404f06fff85cf9f50b825bb6d1839 +"object-deep-merge@npm:^2.0.0": + version: 2.0.0 + resolution: "object-deep-merge@npm:2.0.0" + checksum: 10c0/69e8741131ad49fa8720fb96007a3c82dca1119b5d874151d2ecbcc3b44ccd46e8553c7a30b0abcba752c099ba361bbba97f33a68c9ae54c57eed7be116ffc97 languageName: node linkType: hard @@ -10156,6 +10319,13 @@ __metadata: languageName: node linkType: hard +"parse-node-version@npm:^1.0.1": + version: 1.0.1 + resolution: "parse-node-version@npm:1.0.1" + checksum: 10c0/999cd3d7da1425c2e182dce82b226c6dc842562d3ed79ec47f5c719c32a7f6c1a5352495b894fc25df164be7f2ede4224758255da9902ddef81f2b77ba46bb2c + languageName: node + linkType: hard + "parse-statements@npm:1.0.11": version: 1.0.11 resolution: "parse-statements@npm:1.0.11" @@ -10386,6 +10556,13 @@ __metadata: languageName: node linkType: hard +"pify@npm:^4.0.1": + version: 4.0.1 + resolution: "pify@npm:4.0.1" + checksum: 10c0/6f9d404b0d47a965437403c9b90eca8bb2536407f03de165940e62e72c8c8b75adda5516c6b9b23675a5877cc0bcac6bdfb0ef0e39414cd2476d5495da40e7cf + languageName: node + linkType: hard + "pino-abstract-transport@npm:^2.0.0": version: 2.0.0 resolution: "pino-abstract-transport@npm:2.0.0" @@ -10467,7 +10644,7 @@ __metadata: languageName: node linkType: hard -"playwright@npm:^1.54.1": +"playwright@npm:^1.56.1": version: 1.56.1 resolution: "playwright@npm:1.56.1" dependencies: @@ -10684,6 +10861,24 @@ __metadata: languageName: node linkType: hard +"postcss-load-config@npm:^3.1.4": + version: 3.1.4 + resolution: "postcss-load-config@npm:3.1.4" + dependencies: + lilconfig: "npm:^2.0.5" + yaml: "npm:^1.10.2" + peerDependencies: + postcss: ">=8.0.9" + ts-node: ">=9.0.0" + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + checksum: 10c0/7d2cc6695c2fc063e4538316d651a687fdb55e48db453ff699de916a6ee55ab68eac2b120c28a6b8ca7aa746a588888351b810a215b5cd090eabea62c5762ede + languageName: node + linkType: hard + "postcss-logical@npm:^8.1.0": version: 8.1.0 resolution: "postcss-logical@npm:8.1.0" @@ -10702,6 +10897,39 @@ __metadata: languageName: node linkType: hard +"postcss-modules-extract-imports@npm:^3.0.0": + version: 3.1.0 + resolution: "postcss-modules-extract-imports@npm:3.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/402084bcab376083c4b1b5111b48ec92974ef86066f366f0b2d5b2ac2b647d561066705ade4db89875a13cb175b33dd6af40d16d32b2ea5eaf8bac63bd2bf219 + languageName: node + linkType: hard + +"postcss-modules-local-by-default@npm:^4.0.4": + version: 4.2.0 + resolution: "postcss-modules-local-by-default@npm:4.2.0" + dependencies: + icss-utils: "npm:^5.0.0" + postcss-selector-parser: "npm:^7.0.0" + postcss-value-parser: "npm:^4.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/b0b83feb2a4b61f5383979d37f23116c99bc146eba1741ca3cf1acca0e4d0dbf293ac1810a6ab4eccbe1ee76440dd0a9eb2db5b3bba4f99fc1b3ded16baa6358 + languageName: node + linkType: hard + +"postcss-modules-scope@npm:^3.1.1": + version: 3.2.1 + resolution: "postcss-modules-scope@npm:3.2.1" + dependencies: + postcss-selector-parser: "npm:^7.0.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/bd2d81f79e3da0ef6365b8e2c78cc91469d05b58046b4601592cdeef6c4050ed8fe1478ae000a1608042fc7e692cb51fecbd2d9bce3f4eace4d32e883ffca10b + languageName: node + linkType: hard + "postcss-nesting@npm:^13.0.2": version: 13.0.2 resolution: "postcss-nesting@npm:13.0.2" @@ -10898,14 +11126,14 @@ __metadata: languageName: node linkType: hard -"postcss-value-parser@npm:^4.2.0": +"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": version: 4.2.0 resolution: "postcss-value-parser@npm:4.2.0" checksum: 10c0/f4142a4f56565f77c1831168e04e3effd9ffcc5aebaf0f538eee4b2d465adfd4b85a44257bb48418202a63806a7da7fe9f56c330aebb3cac898e46b4cbf49161 languageName: node linkType: hard -"postcss@npm:^8.5.6": +"postcss@npm:^8.0.0, postcss@npm:^8.4.35, postcss@npm:^8.5.6": version: 8.5.6 resolution: "postcss@npm:8.5.6" dependencies: @@ -11059,6 +11287,13 @@ __metadata: languageName: node linkType: hard +"prr@npm:~1.0.1": + version: 1.0.1 + resolution: "prr@npm:1.0.1" + checksum: 10c0/5b9272c602e4f4472a215e58daff88f802923b84bc39c8860376bb1c0e42aaf18c25d69ad974bd06ec6db6f544b783edecd5502cd3d184748d99080d68e4be5f + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -11775,6 +12010,20 @@ __metadata: languageName: node linkType: hard +"reserved-identifiers@npm:^1.0.0": + version: 1.2.0 + resolution: "reserved-identifiers@npm:1.2.0" + checksum: 10c0/b82651b12e6c608e80463c3753d275bc20fd89294d0415f04e670aeec3611ae3582ddc19e8fedd497e7d0bcbfaddab6a12823ec86e855b1e6a245e0a734eb43d + languageName: node + linkType: hard + +"reserved-words@npm:^0.1.2": + version: 0.1.2 + resolution: "reserved-words@npm:0.1.2" + checksum: 10c0/88360388d88f4b36c1f5d47f8d596936dbf950bddd642c04ce940f1dab1fa58ef6fec23f5fab81a1bfe5cd0f223b2b635311496fcf0ef3db93ad4dfb6d7be186 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -12084,7 +12333,7 @@ __metadata: languageName: node linkType: hard -"sass@npm:^1.62.1": +"sass@npm:^1.62.1, sass@npm:^1.70.0": version: 1.93.2 resolution: "sass@npm:1.93.2" dependencies: @@ -12101,6 +12350,20 @@ __metadata: languageName: node linkType: hard +"sax@npm:^1.2.4": + version: 1.4.1 + resolution: "sax@npm:1.4.1" + checksum: 10c0/6bf86318a254c5d898ede6bd3ded15daf68ae08a5495a2739564eb265cd13bcc64a07ab466fb204f67ce472bb534eb8612dac587435515169593f4fffa11de7c + languageName: node + linkType: hard + +"sax@npm:~1.3.0": + version: 1.3.0 + resolution: "sax@npm:1.3.0" + checksum: 10c0/599dbe0ba9d8bd55e92d920239b21d101823a6cedff71e542589303fa0fa8f3ece6cf608baca0c51be846a2e88365fac94a9101a9c341d94b98e30c4deea5bea + languageName: node + linkType: hard + "saxes@npm:^6.0.0": version: 6.0.0 resolution: "saxes@npm:6.0.0" @@ -12144,6 +12407,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.6.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 + languageName: node + linkType: hard + "semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -12153,7 +12425,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1, semver@npm:^7.7.2": +"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: @@ -12162,6 +12434,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.7.3": + version: 7.7.3 + resolution: "semver@npm:7.7.3" + bin: + semver: bin/semver.js + checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e + languageName: node + linkType: hard + "send@npm:0.19.0": version: 0.19.0 resolution: "send@npm:0.19.0" @@ -12433,7 +12714,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf @@ -12464,13 +12745,20 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:~0.6.1": +"source-map@npm:^0.6.0, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 languageName: node linkType: hard +"source-map@npm:^0.7.3": + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10c0/59f6f05538539b274ba771d2e9e32f6c65451982510564438e048bc1352f019c6efcdc6dd07909b1968144941c14015c2c7d4369fb7c4d7d53ae769716dcc16c + languageName: node + linkType: hard + "source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" @@ -13018,6 +13306,21 @@ __metadata: languageName: node linkType: hard +"stylus@npm:^0.62.0": + version: 0.62.0 + resolution: "stylus@npm:0.62.0" + dependencies: + "@adobe/css-tools": "npm:~4.3.1" + debug: "npm:^4.3.2" + glob: "npm:^7.1.6" + sax: "npm:~1.3.0" + source-map: "npm:^0.7.3" + bin: + stylus: bin/stylus + checksum: 10c0/62afe3a6d781f66d7d283e8218dc1a15530d7d89fc2f09457a723975b2073e96e0d32c61d7f0dd1bd2686aae4ab6cc6933dc85e1b72eebab8aa30167bd16962b + languageName: node + linkType: hard + "substring-trie@npm:^1.0.2": version: 1.0.2 resolution: "substring-trie@npm:1.0.2" @@ -13285,6 +13588,16 @@ __metadata: languageName: node linkType: hard +"to-valid-identifier@npm:^1.0.0": + version: 1.0.0 + resolution: "to-valid-identifier@npm:1.0.0" + dependencies: + "@sindresorhus/base62": "npm:^1.0.0" + reserved-identifiers: "npm:^1.0.0" + checksum: 10c0/569b49f43b5aaaa20677e67f0f1cdcff344855149934cfb80c793c7ac7c30e191b224bc81cab40fb57641af9ca73795c78053c164a2addc617671e2d22c13a4a + languageName: node + linkType: hard + "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -13393,7 +13706,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.8.0": +"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -13428,13 +13741,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:4.2.0": - version: 4.2.0 - resolution: "type-fest@npm:4.2.0" - checksum: 10c0/75e0c112ae91d3b68c75da9b7563cf393f91ebdfca5d53d0b3f0405690217eadca318f9ddb89d58ee6ed67b8e32d23a4eae2aabc4e351e5ae184d610247bf772 - languageName: node - linkType: hard - "type-fest@npm:^0.16.0": version: 0.16.0 resolution: "type-fest@npm:0.16.0" @@ -13534,6 +13840,35 @@ __metadata: languageName: node linkType: hard +"typescript-plugin-css-modules@npm:^5.2.0": + version: 5.2.0 + resolution: "typescript-plugin-css-modules@npm:5.2.0" + dependencies: + "@types/postcss-modules-local-by-default": "npm:^4.0.2" + "@types/postcss-modules-scope": "npm:^3.0.4" + dotenv: "npm:^16.4.2" + icss-utils: "npm:^5.1.0" + less: "npm:^4.2.0" + lodash.camelcase: "npm:^4.3.0" + postcss: "npm:^8.4.35" + postcss-load-config: "npm:^3.1.4" + postcss-modules-extract-imports: "npm:^3.0.0" + postcss-modules-local-by-default: "npm:^4.0.4" + postcss-modules-scope: "npm:^3.1.1" + reserved-words: "npm:^0.1.2" + sass: "npm:^1.70.0" + source-map-js: "npm:^1.0.2" + stylus: "npm:^0.62.0" + tsconfig-paths: "npm:^4.2.0" + peerDependencies: + typescript: ">=4.0.0" + dependenciesMeta: + stylus: + optional: true + checksum: 10c0/7cd024f7145c0a29d9b78f2fb49c42cdf1747b50a43391f9993132ba42a727266f9b544fd868d905d5352e0a8676a19ae7a9aa56d516cc819c3ab39d66aa25e4 + languageName: node + linkType: hard + "typescript@npm:^5.6.0, typescript@npm:~5.9.0": version: 5.9.2 resolution: "typescript@npm:5.9.2" @@ -14623,7 +14958,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.10.0": +"yaml@npm:^1.10.0, yaml@npm:^1.10.2": version: 1.10.2 resolution: "yaml@npm:1.10.2" checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f