Merge branch 'main' into shuuji3/feat/emoji-reactions

# Conflicts:
#	package.json
#	pnpm-lock.yaml
This commit is contained in:
TAKAHASHI Shuuji 2025-05-19 01:19:25 +09:00
commit a7baf1863d
119 changed files with 9827 additions and 7792 deletions

View file

@ -18,11 +18,13 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: corepack enable # workaround for npm registry key change
- uses: actions/setup-node@v4 # ref. `pnpm@10.1.0` / `pnpm@9.15.4` cannot be installed due to key id mismatch · Issue #612 · nodejs/corepack
# - https://github.com/nodejs/corepack/issues/612#issuecomment-2629496091
- run: npm i -g corepack@latest && corepack enable
- uses: actions/setup-node@v4.4.0
with: with:
node-version: 20 node-version-file: .nvmrc
cache: pnpm
- name: 📦 Install dependencies - name: 📦 Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile

View file

@ -19,7 +19,7 @@ jobs:
- name: Set node - name: Set node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version-file: .nvmrc
- run: npx changelogithub - run: npx changelogithub
env: env:

2
.nvmrc
View file

@ -1 +1 @@
20 22

View file

@ -6,19 +6,13 @@ Refer also to https://github.com/antfu/contribute.
For guidelines on contributing to the documentation, refer to the [docs README](./docs/README.md). For guidelines on contributing to the documentation, refer to the [docs README](./docs/README.md).
### Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)
### Local Setup ### Local Setup
To develop and test the Elk package: To develop and test the Elk package:
1. Fork the Elk repository to your own GitHub account and then clone it to your local device. 1. Fork the Elk repository to your own GitHub account and then clone it to your local device.
2. Ensure using the latest Node.js (20.x). 2. Ensure using the LTS version of Node.js.
If you have [nvm](https://github.com/nvm-sh/nvm), you can run `nvm i` to install the required version. If you have [nvm](https://github.com/nvm-sh/nvm), you can run `nvm i` to install the required version.
3. The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/) v9. To use it you must first enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. (Note: on Linux in a standard Node 20+ environment, you should follow the instructions to install via Node's `corepack` rather than using the `curl` command) 3. The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/) v9. To use it you must first enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. (Note: on Linux in a standard Node 20+ environment, you should follow the instructions to install via Node's `corepack` rather than using the `curl` command)
@ -92,7 +86,7 @@ We've added some `UnoCSS` utilities styles to help you with that:
We are using [vue-i18n](https://vue-i18n.intlify.dev/) via [nuxt-i18n](https://i18n.nuxtjs.org/) to handle internationalization. We are using [vue-i18n](https://vue-i18n.intlify.dev/) via [nuxt-i18n](https://i18n.nuxtjs.org/) to handle internationalization.
You can check the current [translation status](https://docs.elk.zone/docs/guide/contributing#translation-status): more instructions on the table caption. You can check the current [translation status](https://docs.elk.zone/guide/contributing#translation-status): more instructions on the table caption.
If you are updating a translation in your local environment, you can run the following commands to check the status: If you are updating a translation in your local environment, you can run the following commands to check the status:
- from root folder: `nr prepare-translation-status` - from root folder: `nr prepare-translation-status`

View file

@ -6,7 +6,10 @@ WORKDIR /elk
FROM base AS builder FROM base AS builder
# Prepare pnpm https://pnpm.io/installation#using-corepack # Prepare pnpm https://pnpm.io/installation#using-corepack
RUN corepack enable # workaround for npm registry key change
# ref. `pnpm@10.1.0` / `pnpm@9.15.4` cannot be installed due to key id mismatch · Issue #612 · nodejs/corepack
# - https://github.com/nodejs/corepack/issues/612#issuecomment-2629496091
RUN npm i -g corepack@latest && corepack enable
# Prepare deps # Prepare deps
RUN apk update RUN apk update

View file

@ -13,7 +13,6 @@ A nimble Mastodon web client
<br/> <br/>
<p align="center"> <p align="center">
<a href="https://chat.elk.zone"><img src="https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord" alt="discord chat"></a> <a href="https://chat.elk.zone"><img src="https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord" alt="discord chat"></a>
<a href="https://pr.new/elk-zone/elk"><img src="https://developer.stackblitz.com/img/start_pr_dark_small.svg" alt="Start new PR in StackBlitz Codeflow"></a>
<a href="https://volta.net/elk-zone/elk?utm_source=elk_readme"><img src="https://user-images.githubusercontent.com/904724/209143798-32345f6c-3cf8-4e06-9659-f4ace4a6acde.svg" alt="Open board on Volta"></a> <a href="https://volta.net/elk-zone/elk?utm_source=elk_readme"><img src="https://user-images.githubusercontent.com/904724/209143798-32345f6c-3cf8-4e06-9659-f4ace4a6acde.svg" alt="Open board on Volta"></a>
</p> </p>
<br/> <br/>
@ -56,6 +55,7 @@ One could put Elk behind popular reverse proxies with SSL Handling like Traefik,
These are known deployments using Elk as an alternative Web client for Mastodon servers or as a base for other projects in the fediverse: These are known deployments using Elk as an alternative Web client for Mastodon servers or as a base for other projects in the fediverse:
- [elk.fedified.com](https://elk.fedified.com) - Use Elk to log into any compatible instance - [elk.fedified.com](https://elk.fedified.com) - Use Elk to log into any compatible instance
- [elk.mastodon.com.pl](https://elk.mastodon.com.pl) - Use Elk for the `mastodon.com.pl` Server
- [elk.me.uk](https://elk.me.uk) - Use Elk to log into any compatible instance, hosted on Google Cloud Run with no Cloudflare proxy - [elk.me.uk](https://elk.me.uk) - Use Elk to log into any compatible instance, hosted on Google Cloud Run with no Cloudflare proxy
- [elk.h4.io](https://elk.h4.io) - Use Elk for the `h4.io` Server - [elk.h4.io](https://elk.h4.io) - Use Elk for the `h4.io` Server
- [elk.universeodon.com](https://elk.universeodon.com) - Use Elk for the Universeodon Server - [elk.universeodon.com](https://elk.universeodon.com) - Use Elk for the Universeodon Server
@ -104,12 +104,6 @@ We would also appreciate sponsoring other contributors to the Elk project. If so
We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide. We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide.
### Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)
### Local Setup ### Local Setup
Clone the repository and run on the root folder: Clone the repository and run on the root folder:

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { account } = defineProps<{
account: mastodon.v1.Account account: mastodon.v1.Account
square?: boolean square?: boolean
}>() }>()
@ -11,22 +11,22 @@ const error = ref(false)
const preferredMotion = usePreferredReducedMotion() const preferredMotion = usePreferredReducedMotion()
const accountAvatarSrc = computed(() => { const accountAvatarSrc = computed(() => {
return preferredMotion.value === 'reduce' ? (props.account?.avatarStatic ?? props.account.avatar) : props.account.avatar return preferredMotion.value === 'reduce' ? (account?.avatarStatic ?? account.avatar) : account.avatar
}) })
</script> </script>
<template> <template>
<img <img
:key="props.account.avatar" :key="account.avatar"
width="400" width="400"
height="400" height="400"
select-none select-none
:src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : accountAvatarSrc" :src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : accountAvatarSrc"
:alt="$t('account.avatar_description', [props.account.username])" :alt="$t('account.avatar_description', [account.username])"
loading="lazy" loading="lazy"
class="account-avatar" class="account-avatar object-cover"
:class="(loaded ? 'bg-base' : 'bg-gray:10') + (props.square ? ' ' : ' rounded-full')" :class="(loaded ? 'bg-base' : 'bg-gray:10') + (square ? ' ' : ' rounded-full')"
:style="{ 'clip-path': props.square ? `url(#avatar-mask)` : 'none' }" :style="{ 'clip-path': square ? `url(#avatar-mask)` : 'none' }"
v-bind="$attrs" v-bind="$attrs"
@load="loaded = true" @load="loaded = true"
@error="error = true" @error="error = true"

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { account, hideEmojis = false } = defineProps<{ const { hideEmojis = false } = defineProps<{
account: mastodon.v1.Account account: mastodon.v1.Account
hideEmojis?: boolean hideEmojis?: boolean
}>() }>()

View file

@ -2,7 +2,7 @@
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import { toggleFollowAccount, useRelationship } from '~~/composables/masto/relationship' import { toggleFollowAccount, useRelationship } from '~~/composables/masto/relationship'
const { account, command, context, ...props } = defineProps<{ const { account, context, command, ...props } = defineProps<{
account: mastodon.v1.Account account: mastodon.v1.Account
relationship?: mastodon.v1.Relationship relationship?: mastodon.v1.Relationship
context?: 'followedBy' | 'following' context?: 'followedBy' | 'following'

View file

@ -12,7 +12,7 @@ const relationship = useRelationship(account)
<div v-show="relationship" flex="~ col gap2" rounded min-w-90 max-w-120 z-100 overflow-hidden p-4> <div v-show="relationship" flex="~ col gap2" rounded min-w-90 max-w-120 z-100 overflow-hidden p-4>
<div flex="~ gap2" items-center> <div flex="~ gap2" items-center>
<NuxtLink :to="getAccountRoute(account)" flex-auto rounded-full hover:bg-active transition-100 pe5 me-a> <NuxtLink :to="getAccountRoute(account)" flex-auto rounded-full hover:bg-active transition-100 pe5 me-a>
<AccountInfo :account="account" :hover-card="true" /> <AccountInfo :account="account" :hover-card="false" />
</NuxtLink> </NuxtLink>
<AccountFollowButton text-sm :account="account" :relationship="relationship" /> <AccountFollowButton text-sm :account="account" :relationship="relationship" />
</div> </div>

View file

@ -5,7 +5,7 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const { account, as = 'div' } = defineProps<{ const { as = 'div' } = defineProps<{
account: mastodon.v1.Account account: mastodon.v1.Account
as?: string as?: string
hoverCard?: boolean hoverCard?: boolean

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { paginator, account, context } = defineProps<{ const { account, context } = defineProps<{
paginator: mastodon.Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams | undefined> paginator: mastodon.Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams | undefined>
context?: 'following' | 'followers' context?: 'following' | 'followers'
account?: mastodon.v1.Account account?: mastodon.v1.Account

View file

@ -5,7 +5,7 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const { tagName, disabled } = defineProps<{ const { tagName } = defineProps<{
tagName?: string tagName?: string
disabled?: boolean disabled?: boolean
}>() }>()

View file

@ -1,17 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AriaLive } from '~/composables/aria' import type { AriaLive } from '~/composables/aria'
// tsc complaining when using $defineProps const {
withDefaults(defineProps<{ ariaLive = 'polite',
title: string heading = 'h2',
messageKey = (message: any) => message,
} = defineProps<{
ariaLive?: AriaLive ariaLive?: AriaLive
messageKey?: (message: any) => any
heading?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6' heading?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
}>(), { title: string
heading: 'h2', messageKey?: (message: any) => any
messageKey: (message: any) => message, }>()
ariaLive: 'polite',
})
const { announceLogs, appendLogs, clearLogs, logs } = useAriaLog() const { announceLogs, appendLogs, clearLogs, logs } = useAriaLog()

View file

@ -1,12 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AriaLive } from '~/composables/aria' import type { AriaLive } from '~/composables/aria'
// tsc complaining when using $defineProps const { ariaLive = 'polite' } = defineProps<{
withDefaults(defineProps<{
ariaLive?: AriaLive ariaLive?: AriaLive
}>(), { }>()
ariaLive: 'polite',
})
const { announceStatus, clearStatus, status } = useAriaStatus() const { announceStatus, clearStatus, status } = useAriaStatus()

View file

@ -1,11 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ResolvedCommand } from '~/composables/command' import type { ResolvedCommand } from '~/composables/command'
const { const { active = false } = defineProps<{
cmd,
index,
active = false,
} = defineProps<{
cmd: ResolvedCommand cmd: ResolvedCommand
index: number index: number
active?: boolean active?: boolean

View file

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const { name } = defineProps<{
name: string name: string
}>() }>()
const isMac = useIsMac() const isMac = useIsMac()
const keys = computed(() => props.name.toLowerCase().split('+')) const keys = computed(() => name.toLowerCase().split('+'))
</script> </script>
<template> <template>

View file

@ -3,7 +3,7 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const { blurhash = '', src, srcset, shouldLoadImage = true } = defineProps<{ const { blurhash = '', shouldLoadImage = true } = defineProps<{
blurhash?: string blurhash?: string
src: string src: string
srcset?: string srcset?: string

View file

@ -3,25 +3,18 @@ import type { Boundaries } from 'vue-advanced-cropper'
import { Cropper } from 'vue-advanced-cropper' import { Cropper } from 'vue-advanced-cropper'
import 'vue-advanced-cropper/dist/style.css' import 'vue-advanced-cropper/dist/style.css'
export interface Props { const { stencilAspectRatio = 1 / 1, stencilSizePercentage = 0.9 } = defineProps<{
/** Crop frame aspect ratio (width/height), default 1/1 */ /** Crop frame aspect ratio (width/height), default 1/1 */
stencilAspectRatio?: number stencilAspectRatio?: number
/** The ratio of the longest edge of the cut box to the length of the cut screen, default 0.9, not more than 1 */ /** The ratio of the longest edge of the cut box to the length of the cut screen, default 0.9, not more than 1 */
stencilSizePercentage?: number stencilSizePercentage?: number
} }>()
const props = withDefaults(defineProps<Props>(), {
stencilAspectRatio: 1 / 1,
stencilSizePercentage: 0.9,
})
const file = defineModel<File | null>() const file = defineModel<File | null>()
const cropperDialog = ref(false) const cropperDialog = ref(false)
const cropper = ref<InstanceType<typeof Cropper>>() const cropper = ref<InstanceType<typeof Cropper>>()
const cropperFlag = ref(false) const cropperFlag = ref(false)
const cropperImage = reactive({ const cropperImage = reactive({
src: '', src: '',
type: 'image/jpg', type: 'image/jpg',
@ -29,8 +22,8 @@ const cropperImage = reactive({
function stencilSize({ boundaries }: { boundaries: Boundaries }) { function stencilSize({ boundaries }: { boundaries: Boundaries }) {
return { return {
width: boundaries.width * props.stencilSizePercentage, width: boundaries.width * stencilSizePercentage,
height: boundaries.height * props.stencilSizePercentage, height: boundaries.height * stencilSizePercentage,
} }
} }
@ -82,7 +75,7 @@ function cropImage() {
}" }"
:stencil-size="stencilSize" :stencil-size="stencilSize"
:stencil-props="{ :stencil-props="{
aspectRatio: props.stencilAspectRatio, aspectRatio: stencilAspectRatio,
movable: false, movable: false,
resizable: false, resizable: false,
handlers: {}, handlers: {},

View file

@ -2,21 +2,21 @@
import type { FileWithHandle } from 'browser-fs-access' import type { FileWithHandle } from 'browser-fs-access'
import { fileOpen } from 'browser-fs-access' import { fileOpen } from 'browser-fs-access'
const props = withDefaults(defineProps<{ const {
original,
allowedFileTypes = ['image/jpeg', 'image/png'],
allowedFileSize = 1024 * 1024 * 5, // 5 MB
} = defineProps<{
/** The image src before change */ /** The image src before change */
original?: string original?: string
/** Allowed file types */ /** Allowed file types */
allowedFileTypes?: string[] allowedFileTypes?: string[]
/** Allowed file size */ /** Allowed file size */
allowedFileSize?: number allowedFileSize?: number
imgClass?: string imgClass?: string
loading?: boolean loading?: boolean
}>(), { }>()
allowedFileTypes: () => ['image/jpeg', 'image/png'],
allowedFileSize: 1024 * 1024 * 5, // 5 MB
})
const emit = defineEmits<{ const emit = defineEmits<{
(event: 'pick', value: FileWithHandle): void (event: 'pick', value: FileWithHandle): void
(event: 'error', code: number, message: string): void (event: 'error', code: number, message: string): void
@ -26,7 +26,7 @@ const file = defineModel<FileWithHandle | null>()
const { t } = useI18n() const { t } = useI18n()
const defaultImage = computed(() => props.original || '') const defaultImage = computed(() => original || '')
/** Preview of selected images */ /** Preview of selected images */
const previewImage = ref('') const previewImage = ref('')
/** The current images on display */ /** The current images on display */
@ -37,14 +37,14 @@ async function pickImage() {
return return
const image = await fileOpen({ const image = await fileOpen({
description: 'Image', description: 'Image',
mimeTypes: props.allowedFileTypes, mimeTypes: allowedFileTypes,
}) })
if (!props.allowedFileTypes.includes(image.type)) { if (!allowedFileTypes.includes(image.type)) {
emit('error', 1, t('error.unsupported_file_format')) emit('error', 1, t('error.unsupported_file_format'))
return return
} }
else if (image.size > props.allowedFileSize) { else if (image.size > allowedFileSize) {
emit('error', 2, t('error.file_size_cannot_exceed_n_mb', [5])) emit('error', 2, t('error.file_size_cannot_exceed_n_mb', [5]))
return return
} }

View file

@ -2,7 +2,7 @@
const { const {
zIndex = 100, zIndex = 100,
background = 'transparent', background = 'transparent',
} = $defineProps<{ } = defineProps<{
zIndex?: number zIndex?: number
background?: string background?: string
}>() }>()

View file

@ -6,10 +6,10 @@ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const { const {
paginator, paginator,
stream,
eventType,
keyProp = 'id', keyProp = 'id',
virtualScroller = false, virtualScroller = false,
stream,
eventType,
preprocess, preprocess,
endMessage = true, endMessage = true,
} = defineProps<{ } = defineProps<{

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CommonRouteTabMoreOption, CommonRouteTabOption } from '~/types' import type { CommonRouteTabMoreOption, CommonRouteTabOption } from '~/types'
const { options, command, replace, preventScrollTop = false, moreOptions } = defineProps<{ const { options, command, preventScrollTop = false } = defineProps<{
options: CommonRouteTabOption[] options: CommonRouteTabOption[]
moreOptions?: CommonRouteTabMoreOption moreOptions?: CommonRouteTabMoreOption
command?: boolean command?: boolean

View file

@ -3,16 +3,16 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = defineProps<{ const { count } = defineProps<{
count: number count: number
keypath: string keypath: string
}>() }>()
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber() const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
const useSR = computed(() => forSR(props.count)) const useSR = computed(() => forSR(count))
const rawNumber = computed(() => formatNumber(props.count)) const rawNumber = computed(() => formatNumber(count))
const humanReadableNumber = computed(() => formatHumanReadableNumber(props.count)) const humanReadableNumber = computed(() => formatHumanReadableNumber(count))
</script> </script>
<template> <template>

View file

@ -4,7 +4,6 @@ const {
text, text,
description, description,
icon, icon,
checked,
command, command,
} = defineProps<{ } = defineProps<{
is?: string is?: string

View file

@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const { code, lang } = defineProps<{
code: string code: string
lang?: string lang?: string
}>() }>()
const raw = computed(() => decodeURIComponent(props.code).replace(/&#39;/g, '\'')) const raw = computed(() => decodeURIComponent(code).replace(/&#39;/g, '\''))
const langMap: Record<string, string> = { const langMap: Record<string, string> = {
js: 'javascript', js: 'javascript',
@ -13,7 +13,7 @@ const langMap: Record<string, string> = {
} }
const highlighted = computed(() => { const highlighted = computed(() => {
return props.lang ? highlightCode(raw.value, (langMap[props.lang] || props.lang) as any) : raw return lang ? highlightCode(raw.value, (langMap[lang] || lang) as any) : raw
}) })
</script> </script>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { paginator } = defineProps<{ defineProps<{
paginator: mastodon.Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams> paginator: mastodon.Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams>
}>() }>()

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const { as, alt, dataEmojiId } = defineProps<{ const { alt, dataEmojiId } = defineProps<{
as: string as: string
alt?: string alt?: string
dataEmojiId?: string dataEmojiId?: string

View file

@ -44,6 +44,7 @@ async function edit() {
<button <button
text-sm p2 border-1 transition-colors text-sm p2 border-1 transition-colors
border-dark border-dark
bg-base
btn-action-icon btn-action-icon
@click="edit" @click="edit"
> >

View file

@ -0,0 +1,23 @@
<script setup lang="ts">
import type { SearchResult } from '~/composables/masto/search'
defineProps<{
result: SearchResult
active: boolean
}>()
</script>
<template>
<CommonScrollIntoView
as="div"
:active="active"
py2 block px2
:aria-selected="active"
:class="{ 'bg-active': active }"
>
<AccountInfo
v-if="result.type === 'account'"
:account="result.data"
/>
</CommonScrollIntoView>
</template>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ConfirmDialogChoice, ConfirmDialogOptions } from '~/types' import type { ConfirmDialogChoice, ConfirmDialogOptions } from '~/types'
const props = defineProps<ConfirmDialogOptions>() const { extraOptionType } = defineProps<ConfirmDialogOptions>()
const emit = defineEmits<{ const emit = defineEmits<{
(evt: 'choice', choice: ConfirmDialogChoice): void (evt: 'choice', choice: ConfirmDialogChoice): void
@ -11,7 +11,7 @@ const hasDuration = ref(false)
const isValidDuration = ref(true) const isValidDuration = ref(true)
const duration = ref(60 * 60) // default to 1 hour const duration = ref(60 * 60) // default to 1 hour
const shouldMuteNotifications = ref(true) const shouldMuteNotifications = ref(true)
const isMute = computed(() => props.extraOptionType === 'mute') const isMute = computed(() => extraOptionType === 'mute')
function handleChoice(choice: ConfirmDialogChoice['choice']) { function handleChoice(choice: ConfirmDialogChoice['choice']) {
const dialogChoice = { const dialogChoice = {
@ -40,7 +40,7 @@ function handleChoice(choice: ConfirmDialogChoice['choice']) {
</div> </div>
<div v-if="isMute" flex-col flex gap-4> <div v-if="isMute" flex-col flex gap-4>
<CommonCheckbox v-model="hasDuration" :label="$t('confirm.mute_account.specify_duration')" prepend-checkbox checked-icon-color="text-primary" /> <CommonCheckbox v-model="hasDuration" :label="$t('confirm.mute_account.specify_duration')" prepend-checkbox checked-icon-color="text-primary" />
<DurationPicker v-if="hasDuration" v-model="duration" v-model:is-valid="isValidDuration" /> <ModalDurationPicker v-if="hasDuration" v-model="duration" v-model:is-valid="isValidDuration" />
<CommonCheckbox v-model="shouldMuteNotifications" :label="$t('confirm.mute_account.notifications')" prepend-checkbox checked-icon-color="text-primary" /> <CommonCheckbox v-model="shouldMuteNotifications" :label="$t('confirm.mute_account.notifications')" prepend-checkbox checked-icon-color="text-primary" />
</div> </div>

View file

@ -1,51 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap' import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
export interface Props {
/**
* level of depth
*
* @default 100
*/
zIndex?: number
/**
* whether to allow close dialog by clicking mask layer
*
* @default true
*/
closeByMask?: boolean
/**
* use v-if, destroy all the internal elements after closed
*
* @default true
*/
useVIf?: boolean
/**
* keep the dialog opened even when in other views
*
* @default false
*/
keepAlive?: boolean
/**
* The aria-labelledby id for the dialog.
*/
dialogLabelledBy?: string
}
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults(defineProps<Props>(), { const {
zIndex: 100, zIndex = 100,
closeByMask: true, closeByMask = true,
useVIf: true, useVIf = true,
keepAlive: false, keepAlive = false,
}) } = defineProps<{
// level of depth
zIndex?: number
// whether to allow close dialog by clicking mask layer
closeByMask?: boolean
// use v-if, destroy all the internal elements after closed
useVIf?: boolean
// keep the dialog opened even when in other views
keepAlive?: boolean
// The aria-labelledby id for the dialog.
dialogLabelledBy?: string
}>()
const emit = defineEmits<{ const emit = defineEmits<{
/** v-model dialog visibility */ /** v-model dialog visibility */
@ -85,7 +61,7 @@ function close() {
} }
function clickMask() { function clickMask() {
if (props.closeByMask) if (closeByMask)
close() close()
} }
@ -97,7 +73,7 @@ watch(visible, (value) => {
const notInCurrentPage = computed(() => deactivated.value || routePath.value !== route.path) const notInCurrentPage = computed(() => deactivated.value || routePath.value !== route.path)
watch(notInCurrentPage, (value) => { watch(notInCurrentPage, (value) => {
if (props.keepAlive) if (keepAlive)
return return
if (value) if (value)
close() close()
@ -106,7 +82,7 @@ watch(notInCurrentPage, (value) => {
// controls the state of v-if. // controls the state of v-if.
// when useVIf is toggled, v-if has the same state as modelValue, otherwise v-if is true // when useVIf is toggled, v-if has the same state as modelValue, otherwise v-if is true
const isVIf = computed(() => { const isVIf = computed(() => {
return props.useVIf return useVIf
? visible.value ? visible.value
: true : true
}) })
@ -114,7 +90,7 @@ const isVIf = computed(() => {
// controls the state of v-show. // controls the state of v-show.
// when useVIf is toggled, v-show is true, otherwise it has the same state as modelValue // when useVIf is toggled, v-show is true, otherwise it has the same state as modelValue
const isVShow = computed(() => { const isVShow = computed(() => {
return !props.useVIf return !useVIf
? visible.value ? visible.value
: true : true
}) })

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { STORAGE_KEY_LAST_ACCESSED_EXPLORE_ROUTE, STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants' import { STORAGE_KEY_LAST_ACCESSED_EXPLORE_ROUTE, STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants'
const { command } = defineProps<{ defineProps<{
command?: boolean command?: boolean
}>() }>()
const { notifications } = useNotifications() const { notifications } = useNotifications()

View file

@ -1,13 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
const props = withDefaults(defineProps<{ const { text, icon, to, userOnly = false, command } = defineProps<{
text?: string text?: string
icon: string icon: string
to: string | Record<string, string> to: string | Record<string, string>
userOnly?: boolean userOnly?: boolean
command?: boolean command?: boolean
}>(), { }>()
userOnly: false,
})
defineSlots<{ defineSlots<{
icon: (props: object) => void icon: (props: object) => void
@ -19,12 +17,12 @@ const router = useRouter()
useCommand({ useCommand({
scope: 'Navigation', scope: 'Navigation',
name: () => props.text ?? (typeof props.to === 'string' ? props.to as string : props.to.name), name: () => text ?? (typeof to === 'string' ? to as string : to.name),
icon: () => props.icon, icon: () => icon,
visible: () => props.command, visible: () => command,
onActivate() { onActivate() {
router.push(props.to) router.push(to)
}, },
}) })
@ -39,8 +37,8 @@ onHydrated(async () => {
// Optimize rendering for the common case of being logged in, only show visual feedback for disabled user-only items // Optimize rendering for the common case of being logged in, only show visual feedback for disabled user-only items
// when we know there is no user. // when we know there is no user.
const noUserDisable = computed(() => !isHydrated.value || (props.userOnly && !currentUser.value)) const noUserDisable = computed(() => !isHydrated.value || (userOnly && !currentUser.value))
const noUserVisual = computed(() => isHydrated.value && props.userOnly && !currentUser.value) const noUserVisual = computed(() => isHydrated.value && userOnly && !currentUser.value)
</script> </script>
<template> <template>

View file

@ -4,6 +4,7 @@ import { STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants'
defineProps<{ defineProps<{
activeClass: string activeClass: string
}>() }>()
const { notifications } = useNotifications() const { notifications } = useNotifications()
const lastAccessedNotificationRoute = useLocalStorage(STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE, '') const lastAccessedNotificationRoute = useLocalStorage(STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE, '')
</script> </script>

View file

@ -33,6 +33,9 @@ const unsupportedEmojiReactionTypes = ['pleroma:emoji_reaction', 'reaction']
if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotificationTypes.includes(notification.type)) { if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotificationTypes.includes(notification.type)) {
console.warn(`[DEV] ${t('notification.missing_type')} '${notification.type}' (notification.id: ${notification.id})`) console.warn(`[DEV] ${t('notification.missing_type')} '${notification.type}' (notification.id: ${notification.id})`)
} }
const timeAgoOptions = useTimeAgoOptions(true)
const timeAgo = useTimeAgo(() => notification.createdAt, timeAgoOptions)
</script> </script>
<template> <template>
@ -49,6 +52,9 @@ if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotif
<AccountDisplayName :account="notification.account" text-primary me-1 font-bold line-clamp-1 ws-pre-wrap break-all /> <AccountDisplayName :account="notification.account" text-primary me-1 font-bold line-clamp-1 ws-pre-wrap break-all />
<span ws-nowrap> <span ws-nowrap>
{{ $t('notification.followed_you') }} {{ $t('notification.followed_you') }}
<time text-secondary :datetime="notification.createdAt">
{{ timeAgo }}
</time>
</span> </span>
</div> </div>
<AccountBigCard <AccountBigCard
@ -65,7 +71,11 @@ if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotif
:account="notification.account" :account="notification.account"
text-purple me-1 font-bold line-clamp-1 ws-pre-wrap break-all text-purple me-1 font-bold line-clamp-1 ws-pre-wrap break-all
/> />
<span>{{ $t("notification.signed_up") }}</span> <span>{{ $t("notification.signed_up") }}
<time text-secondary :datetime="notification.createdAt">
{{ timeAgo }}
</time>
</span>
</div> </div>
</NuxtLink> </NuxtLink>
</template> </template>
@ -95,6 +105,9 @@ if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotif
/> />
<span me-1 ws-nowrap> <span me-1 ws-nowrap>
{{ $t('notification.request_to_follow') }} {{ $t('notification.request_to_follow') }}
<time text-secondary :datetime="notification.createdAt">
{{ timeAgo }}
</time>
</span> </span>
</div> </div>
<AccountCard p="s-2 e-4 b-2" hover-card :account="notification.account"> <AccountCard p="s-2 e-4 b-2" hover-card :account="notification.account">
@ -109,6 +122,9 @@ if (unsupportedEmojiReactionTypes.includes(notification.type) || !supportedNotif
<AccountInlineInfo :account="notification.account" me1 /> <AccountInlineInfo :account="notification.account" me1 />
<span ws-nowrap> <span ws-nowrap>
{{ $t('notification.update_status') }} {{ $t('notification.update_status') }}
<time text-secondary :datetime="notification.createdAt">
{{ timeAgo }}
</time>
</span> </span>
</div> </div>
</template> </template>

View file

@ -5,11 +5,19 @@ const { items } = defineProps<{
items: GroupedNotifications items: GroupedNotifications
}>() }>()
const count = computed(() => items.items.length) const maxVisibleFollows = 5
const follows = computed(() => items.items)
const visibleFollows = computed(() => follows.value.slice(0, maxVisibleFollows))
const count = computed(() => follows.value.length)
const countPlus = computed(() => Math.max(count.value - maxVisibleFollows, 0))
const isExpanded = ref(false) const isExpanded = ref(false)
const lang = computed(() => { const lang = computed(() => {
return (count.value > 1 || count.value === 0) ? undefined : items.items[0].status?.language return (count.value > 1 || count.value === 0) ? undefined : items.items[0].status?.language
}) })
const timeAgoOptions = useTimeAgoOptions(true)
const timeAgoCreatedAt = computed(() => follows.value[0].createdAt)
const timeAgo = useTimeAgo(() => timeAgoCreatedAt.value, timeAgoOptions)
</script> </script>
<template> <template>
@ -17,40 +25,75 @@ const lang = computed(() => {
<div flex items-center top-0 left-2 pt-2 px-3> <div flex items-center top-0 left-2 pt-2 px-3>
<div :class="count > 1 ? 'i-ri-group-line' : 'i-ri-user-3-line'" me-3 color-blue text-xl aria-hidden="true" /> <div :class="count > 1 ? 'i-ri-group-line' : 'i-ri-user-3-line'" me-3 color-blue text-xl aria-hidden="true" />
<template v-if="count > 1"> <template v-if="count > 1">
<CommonLocalizedNumber <AccountHoverWrapper
keypath="notification.followed_you_count" :account="follows[0].account"
:count="count" >
<NuxtLink :to="getAccountRoute(follows[0].account)">
<AccountDisplayName
:account="follows[0].account"
text-primary font-bold line-clamp-1 ws-pre-wrap break-all hover:underline
/> />
</NuxtLink>
</AccountHoverWrapper>
&nbsp;{{ $t('notification.and') }}&nbsp;
<CommonLocalizedNumber
keypath="notification.others"
:count="count - 1"
text-primary font-bold line-clamp-1 ws-pre-wrap break-all
/>
&nbsp;{{ $t('notification.followed_you') }}
<time text-secondary :datetime="timeAgoCreatedAt">
{{ timeAgo }}
</time>
</template> </template>
<template v-else-if="count === 1"> <template v-else-if="count === 1">
<NuxtLink :to="getAccountRoute(items.items[0].account)"> <NuxtLink :to="getAccountRoute(follows[0].account)">
<AccountDisplayName <AccountDisplayName
:account="items.items[0].account" :account="follows[0].account"
text-primary me-1 font-bold line-clamp-1 ws-pre-wrap break-all text-primary me-1 font-bold line-clamp-1 ws-pre-wrap break-all hover:underline
/> />
</NuxtLink> </NuxtLink>
<span me-1 ws-nowrap> <span me-1 ws-nowrap>
{{ $t('notification.followed_you') }} {{ $t('notification.followed_you') }}
<time text-secondary :datetime="timeAgoCreatedAt">
{{ timeAgo }}
</time>
</span> </span>
</template> </template>
</div> </div>
<div pb-2 ps8> <div pb-2 ps8>
<div v-if="isExpanded"> <div
<AccountCard v-if="!isExpanded && count > 1"
v-for="item in items.items" flex="~ wrap gap-1.75" p4 items-center cursor-pointer
:key="item.id" @click="isExpanded = !isExpanded"
:account="item.account"
p3
/>
</div>
<div v-else flex="~ wrap gap-1.75" p4>
<AccountHoverWrapper
v-for="item in items.items"
:key="item.id"
:account="item.account"
> >
<NuxtLink :to="getAccountRoute(item.account)"> <AccountHoverWrapper
<AccountAvatar :account="item.account" w-12 h-12 /> v-for="follow in visibleFollows"
:key="follow.id"
:account="follow.account"
>
<NuxtLink :to="getAccountRoute(follow.account)">
<AccountAvatar :account="follow.account" w-12 h-12 />
</NuxtLink>
</AccountHoverWrapper>
<div flex="~ 1" items-center>
<span v-if="countPlus > 0" ps-2 text="base lg">+{{ countPlus }}</span>
<div i-ri:arrow-down-s-line mx-1 text-secondary text-xl aria-hidden="true" />
</div>
</div>
<div v-else>
<div v-if="count > 1" flex p-4 pb-2 cursor-pointer @click="isExpanded = !isExpanded">
<div i-ri:arrow-up-s-line ms-2 text-secondary text-xl aria-hidden="true" />
<span ps-2 text-base>Hide</span>
</div>
<AccountHoverWrapper
v-for="follow in follows"
:key="follow.id"
:account="follow.account"
>
<NuxtLink :to="getAccountRoute(follow.account)" flex gap-4 px-4 py-2>
<AccountAvatar :account="follow.account" w-12 h-12 />
<StatusAccountDetails :account="follow.account" />
</NuxtLink> </NuxtLink>
</AccountHoverWrapper> </AccountHoverWrapper>
</div> </div>

View file

@ -8,6 +8,12 @@ const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon')
const reblogs = computed(() => group.likes.filter(i => i.reblog)) const reblogs = computed(() => group.likes.filter(i => i.reblog))
const likes = computed(() => group.likes.filter(i => i.favourite && !i.reblog)) const likes = computed(() => group.likes.filter(i => i.favourite && !i.reblog))
const timeAgoOptions = useTimeAgoOptions(true)
const reblogsTimeAgoCreatedAt = computed(() => reblogs.value[0].reblog?.createdAt)
const reblogsTimeAgo = useTimeAgo(() => reblogsTimeAgoCreatedAt.value ?? '', timeAgoOptions)
const likesTimeAgoCreatedAt = computed(() => likes.value[0].favourite?.createdAt)
const likesTimeAgo = useTimeAgo(() => likesTimeAgoCreatedAt.value ?? '', timeAgoOptions)
</script> </script>
<template> <template>
@ -25,6 +31,9 @@ const likes = computed(() => group.likes.filter(i => i.favourite && !i.reblog))
</template> </template>
<div ml1> <div ml1>
{{ $t('notification.reblogged_post') }} {{ $t('notification.reblogged_post') }}
<time text-secondary :datetime="reblogsTimeAgoCreatedAt">
{{ reblogsTimeAgo }}
</time>
</div> </div>
</div> </div>
<div v-if="likes.length" flex="~ gap-1 wrap"> <div v-if="likes.length" flex="~ gap-1 wrap">
@ -38,6 +47,9 @@ const likes = computed(() => group.likes.filter(i => i.favourite && !i.reblog))
</template> </template>
<div ms-4> <div ms-4>
{{ $t('notification.favourited_post') }} {{ $t('notification.favourited_post') }}
<time text-secondary :datetime="likesTimeAgoCreatedAt">
{{ likesTimeAgo }}
</time>
</div> </div>
</div> </div>
</div> </div>

View file

@ -4,7 +4,7 @@ import type { GroupedAccountLike, NotificationSlot } from '~/types'
// @ts-expect-error missing types // @ts-expect-error missing types
import { DynamicScrollerItem } from 'vue-virtual-scroller' import { DynamicScrollerItem } from 'vue-virtual-scroller'
const { paginator, stream } = defineProps<{ defineProps<{
paginator: mastodon.Paginator<mastodon.v1.Notification[], mastodon.rest.v1.ListNotificationsParams> paginator: mastodon.Paginator<mastodon.v1.Notification[], mastodon.rest.v1.ListNotificationsParams>
stream?: mastodon.streaming.Subscription stream?: mastodon.streaming.Subscription
}>() }>()

View file

@ -1,14 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = withDefaults(defineProps<{ const { attachment, removable = true } = defineProps<{
attachment: mastodon.v1.MediaAttachment attachment: mastodon.v1.MediaAttachment
alt?: string alt?: string
removable?: boolean removable?: boolean
dialogLabelledBy?: string dialogLabelledBy?: string
}>(), { }>()
removable: true,
})
const emit = defineEmits<{ const emit = defineEmits<{
(evt: 'remove'): void (evt: 'remove'): void
@ -19,7 +17,7 @@ const emit = defineEmits<{
const maxDescriptionLength = 1500 const maxDescriptionLength = 1500
const isEditDialogOpen = ref(false) const isEditDialogOpen = ref(false)
const description = ref(props.attachment.description ?? '') const description = ref(attachment.description ?? '')
function toggleApply() { function toggleApply() {
isEditDialogOpen.value = false isEditDialogOpen.value = false

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Editor } from '@tiptap/core' import type { Editor } from '@tiptap/core'
const { editor } = defineProps<{ defineProps<{
editor: Editor editor: Editor
}>() }>()
</script> </script>

View file

@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const { draftKey, draftItemIndex } = defineProps<{
draftKey: string draftKey: string
draftItemIndex: number draftItemIndex: number
}>() }>()
const { threadIsActive, addThreadItem, threadItems, removeThreadItem } = useThreadComposer(props.draftKey) const { threadIsActive, addThreadItem, threadItems, removeThreadItem } = useThreadComposer(draftKey)
const isRemovableItem = computed(() => threadIsActive.value && props.draftItemIndex < threadItems.value.length - 1) const isRemovableItem = computed(() => threadIsActive.value && draftItemIndex < threadItems.value.length - 1)
function addOrRemoveItem() { function addOrRemoveItem() {
if (isRemovableItem.value) if (isRemovableItem.value)
removeThreadItem(props.draftItemIndex) removeThreadItem(draftItemIndex)
else else
addThreadItem() addThreadItem()
@ -19,7 +19,7 @@ function addOrRemoveItem() {
const { t } = useI18n() const { t } = useI18n()
const label = computed(() => { const label = computed(() => {
if (!isRemovableItem.value && props.draftItemIndex === 0) if (!isRemovableItem.value && draftItemIndex === 0)
return t('tooltip.start_thread') return t('tooltip.start_thread')
return isRemovableItem.value ? t('tooltip.remove_thread_item') : t('tooltip.add_thread_item') return isRemovableItem.value ? t('tooltip.remove_thread_item') : t('tooltip.add_thread_item')

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const { editing } = defineProps<{ defineProps<{
editing?: boolean editing?: boolean
}>() }>()

View file

@ -10,7 +10,6 @@ const {
draftItemIndex, draftItemIndex,
expanded = false, expanded = false,
placeholder, placeholder,
dialogLabelledBy,
initial = getDefaultDraftItem, initial = getDefaultDraftItem,
} = defineProps<{ } = defineProps<{
draftKey: string draftKey: string
@ -196,6 +195,9 @@ async function toggleSensitive() {
} }
async function publish() { async function publish() {
if (isPublishDisabled.value || isExceedingCharacterLimit.value)
return
const publishResult = await (threadIsActive.value ? publishThread() : publishDraft()) const publishResult = await (threadIsActive.value ? publishThread() : publishDraft())
if (publishResult) { if (publishResult) {
if (Array.isArray(publishResult)) if (Array.isArray(publishResult))

View file

@ -6,10 +6,6 @@ const {
draftKey, draftKey,
initial = getDefaultDraftItem, initial = getDefaultDraftItem,
expanded = false, expanded = false,
placeholder,
dialogLabelledBy,
inReplyToId,
inReplyToVisibility,
} = defineProps<{ } = defineProps<{
draftKey: string draftKey: string
initial?: () => DraftItem initial?: () => DraftItem

View file

@ -91,7 +91,7 @@ function activate() {
</div> </div>
<!-- Results --> <!-- Results -->
<div left-0 top-11 absolute w-full z-10 group-focus-within="pointer-events-auto visible" invisible pointer-events-none> <div left-0 top-11 absolute w-full z-10 group-focus-within="pointer-events-auto visible" invisible pointer-events-none>
<div w-full bg-base border="~ base" rounded-3 max-h-100 overflow-auto py2> <div w-full bg-base border="~ base" rounded-3 max-h-100 overflow-auto :class="results.length === 0 ? 'py2' : null">
<span v-if="query.trim().length === 0" block text-center text-sm text-secondary> <span v-if="query.trim().length === 0" block text-center text-sm text-secondary>
{{ t('search.search_desc') }} {{ t('search.search_desc') }}
</span> </span>

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const { text, description, icon, to, command, external, target } = defineProps<{
text?: string text?: string
content?: string content?: string
description?: string description?: string
@ -14,24 +14,24 @@ const props = defineProps<{
}>() }>()
const router = useRouter() const router = useRouter()
const scrollOnClick = computed(() => props.to && !(props.target === '_blank' || props.external)) const scrollOnClick = computed(() => to && !(target === '_blank' || external))
useCommand({ useCommand({
scope: 'Settings', scope: 'Settings',
name: () => props.text name: () => text
?? (props.to ?? (to
? typeof props.to === 'string' ? typeof to === 'string'
? props.to ? to
: props.to.name : to.name
: '' : ''
), ),
description: () => props.description, description: () => description,
icon: () => props.icon || '', icon: () => icon || '',
visible: () => props.command && props.to, visible: () => command && to,
onActivate() { onActivate() {
router.push(props.to!) router.push(to!)
}, },
}) })
</script> </script>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { account, link = true } = defineProps<{ const { link = true } = defineProps<{
account: mastodon.v1.Account account: mastodon.v1.Account
link?: boolean link?: boolean
}>() }>()

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { details, command, ...props } = defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
details?: boolean details?: boolean
command?: boolean command?: boolean
@ -9,8 +9,6 @@ const props = defineProps<{
const focusEditor = inject<typeof noop>('focus-editor', noop) const focusEditor = inject<typeof noop>('focus-editor', noop)
const { details, command } = props // TODO
const userSettings = useUserSettings() const userSettings = useUserSettings()
const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon') const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon')
@ -21,7 +19,7 @@ const {
toggleBookmark, toggleBookmark,
toggleFavourite, toggleFavourite,
toggleReblog, toggleReblog,
} = useStatusActions(props) } = useStatusActions({ status: props.status })
function reply() { function reply() {
if (!checkLogin()) if (!checkLogin())

View file

@ -2,7 +2,7 @@
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import { toggleBlockAccount, toggleMuteAccount, useRelationship } from '~~/composables/masto/relationship' import { toggleBlockAccount, toggleMuteAccount, useRelationship } from '~~/composables/masto/relationship'
const props = defineProps<{ const { details, ...props } = defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
details?: boolean details?: boolean
command?: boolean command?: boolean
@ -22,7 +22,7 @@ const {
togglePin, togglePin,
toggleReblog, toggleReblog,
toggleMute, toggleMute,
} = useStatusActions(props) } = useStatusActions({ status: props.status })
const clipboard = useClipboard() const clipboard = useClipboard()
const router = useRouter() const router = useRouter()
@ -109,7 +109,7 @@ async function deleteAndRedraft() {
function reply() { function reply() {
if (!checkLogin()) if (!checkLogin())
return return
if (props.details) { if (details) {
focusEditor() focusEditor()
} }
else { else {

View file

@ -71,6 +71,7 @@ const isVideo = computed(() => attachment.type === 'video')
const isGif = computed(() => attachment.type === 'gifv') const isGif = computed(() => attachment.type === 'gifv')
const enableAutoplay = usePreferences('enableAutoplay') const enableAutoplay = usePreferences('enableAutoplay')
const unmuteVideos = usePreferences('unmuteVideos')
useIntersectionObserver(video, (entries) => { useIntersectionObserver(video, (entries) => {
const ready = video.value?.dataset.ready === 'true' const ready = video.value?.dataset.ready === 'true'
@ -132,7 +133,7 @@ watch(shouldLoadAttachment, () => {
ref="video" ref="video"
preload="none" preload="none"
:poster="videoThumbnail" :poster="videoThumbnail"
muted :muted="!unmuteVideos"
loop loop
playsinline playsinline
:controls="shouldLoadAttachment" :controls="shouldLoadAttachment"
@ -172,7 +173,7 @@ watch(shouldLoadAttachment, () => {
ref="video" ref="video"
preload="none" preload="none"
:poster="videoThumbnail" :poster="videoThumbnail"
muted :muted="!unmuteVideos"
loop loop
playsinline playsinline
rounded-lg rounded-lg

View file

@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = withDefaults( const { actions = true, older, newer, hasOlder, hasNewer, main, ...props } = defineProps<{
defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
followedTag?: string | null
actions?: boolean actions?: boolean
context?: mastodon.v2.FilterContext context?: mastodon.v2.FilterContext
hover?: boolean hover?: boolean
@ -20,9 +20,7 @@ const props = withDefaults(
// When looking into a detailed view of a post, we can simplify the replying badges // When looking into a detailed view of a post, we can simplify the replying badges
// to the main expanded post // to the main expanded post
main?: mastodon.v1.Status main?: mastodon.v1.Status
}>(), }>()
{ actions: true },
)
const userSettings = useUserSettings() const userSettings = useUserSettings()
@ -33,11 +31,11 @@ const status = computed(() => {
}) })
// Use original status, avoid connecting a reblog // Use original status, avoid connecting a reblog
const directReply = computed(() => props.hasNewer || (!!status.value.inReplyToId && (status.value.inReplyToId === props.newer?.id || status.value.inReplyToId === props.newer?.reblog?.id))) const directReply = computed(() => hasNewer || (!!status.value.inReplyToId && (status.value.inReplyToId === newer?.id || status.value.inReplyToId === newer?.reblog?.id)))
// Use reblogged status, connect it to further replies // Use reblogged status, connect it to further replies
const connectReply = computed(() => props.hasOlder || status.value.id === props.older?.inReplyToId || status.value.id === props.older?.reblog?.inReplyToId) const connectReply = computed(() => hasOlder || status.value.id === older?.inReplyToId || status.value.id === older?.reblog?.inReplyToId)
// Open a detailed status, the replies directly to it // Open a detailed status, the replies directly to it
const replyToMain = computed(() => props.main && props.main.id === status.value.inReplyToId) const replyToMain = computed(() => main && main.id === status.value.inReplyToId)
const rebloggedBy = computed(() => props.status.reblog ? props.status.account : null) const rebloggedBy = computed(() => props.status.reblog ? props.status.account : null)
@ -64,7 +62,7 @@ const collapseRebloggedBy = computed(() => rebloggedBy.value?.id === status.valu
const isDM = computed(() => status.value.visibility === 'direct') const isDM = computed(() => status.value.visibility === 'direct')
const isPinned = computed(() => status.value.pinned) const isPinned = computed(() => status.value.pinned)
const showUpperBorder = computed(() => props.newer && !directReply.value) const showUpperBorder = computed(() => newer && !directReply.value)
const showReplyTo = computed(() => !replyToMain.value && !directReply.value) const showReplyTo = computed(() => !replyToMain.value && !directReply.value)
const forceShow = ref(false) const forceShow = ref(false)
@ -76,6 +74,20 @@ const forceShow = ref(false)
<div :h="showUpperBorder ? '1px' : '0'" w-auto bg-border mb-1 z--1 /> <div :h="showUpperBorder ? '1px' : '0'" w-auto bg-border mb-1 z--1 />
<slot name="meta"> <slot name="meta">
<!-- followed hashtag badge -->
<div flex="~ col" justify-between>
<div
v-if="!!followedTag && followedTag !== ''"
flex="~ gap2" items-center h-auto text-sm text-orange
m="is-5" p="t-1 is-5"
relative text-secondary ws-nowrap
>
<div i-ri:hashtag />
<!-- show first hit followed tag -->
<span>{{ followedTag }}</span>
</div>
</div>
<!-- Pinned status --> <!-- Pinned status -->
<div flex="~ col" justify-between> <div flex="~ col" justify-between>
<div <div

View file

@ -1,14 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = withDefaults(defineProps<{ const { actions = true, ...props } = defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
newer?: mastodon.v1.Status newer?: mastodon.v1.Status
command?: boolean command?: boolean
actions?: boolean actions?: boolean
}>(), { }>()
actions: true,
})
defineEmits<{ defineEmits<{
(event: 'refetchStatus'): void (event: 'refetchStatus'): void

View file

@ -1,14 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { status } = defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
hover?: boolean hover?: boolean
}>() }>()
const el = ref<HTMLElement>() const el = ref<HTMLElement>()
const router = useRouter() const router = useRouter()
const statusRoute = computed(() => getStatusRoute(props.status)) const statusRoute = computed(() => getStatusRoute(status))
function onclick(evt: MouseEvent | KeyboardEvent) { function onclick(evt: MouseEvent | KeyboardEvent) {
const path = evt.composedPath() as HTMLElement[] const path = evt.composedPath() as HTMLElement[]
@ -24,7 +24,7 @@ function go(evt: MouseEvent | KeyboardEvent) {
window.open(statusRoute.value.href) window.open(statusRoute.value.href)
} }
else { else {
cacheStatus(props.status) cacheStatus(status)
router.push(statusRoute.value) router.push(statusRoute.value)
} }
} }

View file

@ -14,6 +14,7 @@ const timeAgoOptions = useTimeAgoOptions()
const expiredTimeAgo = useTimeAgo(poll.expiresAt!, timeAgoOptions) const expiredTimeAgo = useTimeAgo(poll.expiresAt!, timeAgoOptions)
const expiredTimeFormatted = useFormattedDateTime(poll.expiresAt!) const expiredTimeFormatted = useFormattedDateTime(poll.expiresAt!)
const { formatPercentage } = useHumanReadableNumber() const { formatPercentage } = useHumanReadableNumber()
const loading = ref(false)
const { client } = useMasto() const { client } = useMasto()
@ -39,6 +40,25 @@ async function vote(e: Event) {
await client.value.v1.polls.$select(poll.id).votes.create({ choices }) await client.value.v1.polls.$select(poll.id).votes.create({ choices })
} }
async function refresh() {
if (loading.value) {
return
}
loading.value = true
try {
const newPoll = await client.value.v1.polls.$select(poll.id).fetch()
Object.assign(poll, newPoll)
cacheStatus({ ...status, poll: newPoll }, undefined, true)
}
catch (e) {
console.error(e)
}
finally {
loading.value = false
}
}
const votersCount = computed(() => poll.votersCount ?? poll.votesCount ?? 0) const votersCount = computed(() => poll.votersCount ?? poll.votesCount ?? 0)
</script> </script>
@ -71,15 +91,27 @@ const votersCount = computed(() => poll.votersCount ?? poll.votesCount ?? 0)
</div> </div>
</div> </div>
</template> </template>
<div text-sm flex="~ inline" gap-x-1 text-secondary> <div text-sm text-secondary flex justify-between items-center gap-3>
<div flex gap-x-1 flex-wrap>
<div inline-block>
<CommonLocalizedNumber <CommonLocalizedNumber
keypath="status.poll.count" keypath="status.poll.count"
:count="poll.votesCount" :count="poll.votesCount"
/> />
</div>
&middot; &middot;
<div inline-block>
<CommonTooltip v-if="poll.expiresAt" :content="expiredTimeFormatted" class="inline-block" placement="right"> <CommonTooltip v-if="poll.expiresAt" :content="expiredTimeFormatted" class="inline-block" placement="right">
<time :datetime="poll.expiresAt!">{{ $t(poll.expired ? 'status.poll.finished' : 'status.poll.ends', [expiredTimeAgo]) }}</time> <time :datetime="poll.expiresAt!">{{ $t(poll.expired ? 'status.poll.finished' : 'status.poll.ends', [expiredTimeAgo]) }}</time>
</CommonTooltip> </CommonTooltip>
</div> </div>
</div> </div>
<div v-if="!poll.expired">
<button whitespace-nowrap flex gap-1 items-center hover:text-primary @click="refresh">
<div text-xs :class="loading ? 'animate-spin' : ''" i-ri:loop-right-line />
{{ $t('status.poll.update') }}
</button>
</div>
</div>
</div>
</template> </template>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { card } = defineProps<{
card: mastodon.v1.PreviewCard card: mastodon.v1.PreviewCard
/** For the preview image, only the small image mode is displayed */ /** For the preview image, only the small image mode is displayed */
smallPictureOnly?: boolean smallPictureOnly?: boolean
@ -9,7 +9,7 @@ const props = defineProps<{
root?: boolean root?: boolean
}>() }>()
const providerName = props.card.providerName const providerName = card.providerName
const gitHubCards = usePreferences('experimentalGitHubCards') const gitHubCards = usePreferences('experimentalGitHubCards')
</script> </script>

View file

@ -11,9 +11,10 @@ defineProps<{
max-h-2xl max-h-2xl
flex gap-2 flex gap-2
my-auto my-auto
bg-gray-300 p-4 py-2
light:bg-gray-3 dark:bg-gray-8
> >
<span z-0>More from</span> <span z-0>More from</span>
<AccountInlineInfo :account="account" hover:bg-gray-300 /> <AccountInlineInfo :account="account" hover:bg-inherit ps-0 ms-0 />
</div> </div>
</template> </template>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { card, smallPictureOnly } = defineProps<{
card: mastodon.v1.PreviewCard card: mastodon.v1.PreviewCard
/** For the preview image, only the small image mode is displayed */ /** For the preview image, only the small image mode is displayed */
smallPictureOnly?: boolean smallPictureOnly?: boolean
@ -12,14 +12,14 @@ const props = defineProps<{
// mastodon's default max og image width // mastodon's default max og image width
const ogImageWidth = 400 const ogImageWidth = 400
const alt = computed(() => `${props.card.title} - ${props.card.title}`) const alt = computed(() => `${card.title} - ${card.title}`)
const isSquare = computed(() => ( const isSquare = computed(() => (
props.smallPictureOnly smallPictureOnly
|| props.card.width === props.card.height || card.width === card.height
|| Number(props.card.width || 0) < ogImageWidth || Number(card.width || 0) < ogImageWidth
|| Number(props.card.height || 0) < ogImageWidth / 2 || Number(card.height || 0) < ogImageWidth / 2
)) ))
const providerName = computed(() => props.card.providerName ? props.card.providerName : new URL(props.card.url).hostname) const providerName = computed(() => card.providerName ? card.providerName : new URL(card.url).hostname)
// TODO: handle card.type: 'photo' | 'video' | 'rich'; // TODO: handle card.type: 'photo' | 'video' | 'rich';
const cardTypeIconMap: Record<mastodon.v1.PreviewCardType, string> = { const cardTypeIconMap: Record<mastodon.v1.PreviewCardType, string> = {
@ -45,13 +45,15 @@ function loadAttachment() {
bg-card bg-card
hover:bg-active hover:bg-active
:class="{ :class="{
'flex': isSquare, 'flex flex-col': isSquare,
'p-4': root, 'p-4': root,
'rounded-lg': !root, 'rounded-lg': !root,
}" }"
target="_blank" target="_blank"
external external
> >
<div :class="isSquare ? 'flex' : ''">
<!-- image -->
<div <div
v-if="card.image" v-if="card.image"
flex flex-col flex flex-col
@ -103,11 +105,12 @@ function loadAttachment() {
> >
<div :class="cardTypeIconMap[card.type]" w="30%" h="30%" text-secondary /> <div :class="cardTypeIconMap[card.type]" w="30%" h="30%" text-secondary />
</div> </div>
<!-- description -->
<StatusPreviewCardInfo :p="isSquare ? 'x-4' : '4'" :root="root" :card="card" :provider="providerName" /> <StatusPreviewCardInfo :p="isSquare ? 'x-4' : '4'" :root="root" :card="card" :provider="providerName" />
</div>
<StatusPreviewCardMoreFromAuthor <StatusPreviewCardMoreFromAuthor
v-if="card?.authors?.[0].account" v-if="card?.authors?.[0]?.account"
:account="card.authors[0].account" :account="card.authors[0].account"
p-4 py-2
/> />
</NuxtLink> </NuxtLink>
</template> </template>

View file

@ -2,7 +2,7 @@
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import reservedNames from 'github-reserved-names' import reservedNames from 'github-reserved-names'
const props = defineProps<{ const { card } = defineProps<{
card: mastodon.v1.PreviewCard card: mastodon.v1.PreviewCard
}>() }>()
@ -30,7 +30,7 @@ interface Meta {
const supportedReservedRoutes = ['sponsors'] const supportedReservedRoutes = ['sponsors']
const meta = computed(() => { const meta = computed(() => {
const { url } = props.card const { url } = card
const path = url.split('https://github.com/')[1] const path = url.split('https://github.com/')[1]
const [firstName, secondName] = path?.split('/') || [] const [firstName, secondName] = path?.split('/') || []
if (!firstName || (reservedNames.check(firstName) && !supportedReservedRoutes.includes(firstName))) if (!firstName || (reservedNames.check(firstName) && !supportedReservedRoutes.includes(firstName)))
@ -42,7 +42,7 @@ const meta = computed(() => {
let type: UrlType = repo ? 'repo' : 'user' let type: UrlType = repo ? 'repo' : 'user'
let number: string | undefined let number: string | undefined
let details = (props.card.title ?? '').replace('GitHub - ', '').split(' · ')[0] let details = (card.title ?? '').replace('GitHub - ', '').split(' · ')[0]
if (repo) { if (repo) {
const repoPath = `${user}/${repo}` const repoPath = `${user}/${repo}`
@ -63,7 +63,7 @@ const meta = computed(() => {
const avatar = `https://github.com/${user}.png?size=256` const avatar = `https://github.com/${user}.png?size=256`
const author = props.card.authorName const author = card.authorName
return { return {
type, type,
user, user,

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const props = defineProps<{ const { card } = defineProps<{
card: mastodon.v1.PreviewCard card: mastodon.v1.PreviewCard
/** For the preview image, only the small image mode is displayed */ /** For the preview image, only the small image mode is displayed */
smallPictureOnly?: boolean smallPictureOnly?: boolean
@ -20,12 +20,12 @@ interface Meta {
const maxLines = 20 const maxLines = 20
const meta = computed(() => { const meta = computed(() => {
const { description } = props.card const { description } = card
const meta = description.match(/.*Code Snippet from (.+), lines (\S+)\n\n(.+)/s) const meta = description.match(/.*Code Snippet from (.+), lines (\S+)\n\n(.+)/s)
const file = meta?.[1] const file = meta?.[1]
const lines = meta?.[2] const lines = meta?.[2]
const code = meta?.[3].split('\n').slice(0, maxLines).join('\n') const code = meta?.[3].split('\n').slice(0, maxLines).join('\n')
const project = props.card.title?.replace(' - StackBlitz', '') const project = card.title?.replace(' - StackBlitz', '')
return { return {
file, file,
lines, lines,

View file

@ -4,15 +4,15 @@ import { fetchAccountById } from '~/composables/cache'
type WatcherType = [status?: mastodon.v1.Status, v?: boolean] type WatcherType = [status?: mastodon.v1.Status, v?: boolean]
const props = defineProps<{ const { status } = defineProps<{
status: mastodon.v1.Status status: mastodon.v1.Status
isSelfReply: boolean isSelfReply: boolean
}>() }>()
const link = ref() const link = ref()
const targetIsVisible = ref(false) const targetIsVisible = ref(false)
const isSelf = computed(() => props.status.inReplyToAccountId === props.status.account.id) const isSelf = computed(() => status.inReplyToAccountId === status.account.id)
const account = ref<mastodon.v1.Account | null | undefined>(isSelf.value ? props.status.account : undefined) const account = ref<mastodon.v1.Account | null | undefined>(isSelf.value ? status.account : undefined)
useIntersectionObserver( useIntersectionObserver(
link, link,
@ -22,7 +22,7 @@ useIntersectionObserver(
) )
watch( watch(
() => [props.status, targetIsVisible.value] satisfies WatcherType, () => [status, targetIsVisible.value] satisfies WatcherType,
([newStatus, newVisible]) => { ([newStatus, newVisible]) => {
if (newStatus.account && newStatus.inReplyToAccountId === newStatus.account.id) { if (newStatus.account && newStatus.inReplyToAccountId === newStatus.account.id) {
account.value = newStatus.account account.value = newStatus.account
@ -36,7 +36,7 @@ watch(
if (newId) { if (newId) {
fetchAccountById(newStatus.inReplyToAccountId).then((acc) => { fetchAccountById(newStatus.inReplyToAccountId).then((acc) => {
if (newId === props.status.inReplyToAccountId) if (newId === status.inReplyToAccountId)
account.value = acc account.value = acc
}) })
return return

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const { enabled, filter, sensitiveNonSpoiler } = defineProps<{
enabled?: boolean enabled?: boolean
filter?: boolean filter?: boolean
isDM?: boolean isDM?: boolean
@ -10,12 +10,12 @@ const expandSpoilers = computed(() => {
const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false
const expandMedia = currentUser.value ? getExpandMediaByDefault(currentUser.value.account) : false const expandMedia = currentUser.value ? getExpandMediaByDefault(currentUser.value.account) : false
return !props.filter // always prevent expansion if filtered return !filter // always prevent expansion if filtered
&& ((props.sensitiveNonSpoiler && expandMedia) && ((sensitiveNonSpoiler && expandMedia)
|| (!props.sensitiveNonSpoiler && expandCW)) || (!sensitiveNonSpoiler && expandCW))
}) })
const hideContent = props.enabled || props.sensitiveNonSpoiler const hideContent = enabled || sensitiveNonSpoiler
const showContent = ref(expandSpoilers.value ? true : !hideContent) const showContent = ref(expandSpoilers.value ? true : !hideContent)
const toggleContent = useToggle(showContent) const toggleContent = useToggle(showContent)
@ -23,9 +23,9 @@ watchEffect(() => {
showContent.value = expandSpoilers.value ? true : !hideContent showContent.value = expandSpoilers.value ? true : !hideContent
}) })
function getToggleText() { function getToggleText() {
if (props.sensitiveNonSpoiler) if (sensitiveNonSpoiler)
return 'status.spoiler_media_hidden' return 'status.spoiler_media_hidden'
return props.filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more' return filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more'
} }
</script> </script>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { edit } = defineProps<{ defineProps<{
edit: mastodon.v1.StatusEdit edit: mastodon.v1.StatusEdit
}>() }>()
</script> </script>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
const { paginator } = defineProps<{ defineProps<{
paginator: mastodon.Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams> paginator: mastodon.Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams>
}>() }>()
</script> </script>

View file

@ -10,12 +10,17 @@ const stream = useStreaming(client => client.user.subscribe())
function reorderAndFilter(items: mastodon.v1.Status[]) { function reorderAndFilter(items: mastodon.v1.Status[]) {
return reorderedTimeline(items, 'home') return reorderedTimeline(items, 'home')
} }
let followedTags: mastodon.v1.Tag[] | undefined
if (currentUser.value !== undefined) {
followedTags = (await useMasto().client.value.v1.followedTags.list({ limit: 0 }))
}
</script> </script>
<template> <template>
<div> <div>
<PublishWidgetList draft-key="home" /> <PublishWidgetList draft-key="home" />
<div h="1px" w-auto bg-border mb-3 /> <div h="1px" w-auto bg-border mb-3 />
<TimelinePaginator v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="home" /> <TimelinePaginator :followed-tags="followedTags" v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="home" />
</div> </div>
</template> </template>

View file

@ -4,11 +4,12 @@ import type { mastodon } from 'masto'
import { DynamicScrollerItem } from 'vue-virtual-scroller' import { DynamicScrollerItem } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css' import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const { paginator, stream, account, buffer = 10, endMessage = true } = defineProps<{ const { account, buffer = 10, endMessage = true, followedTags = [] } = defineProps<{
paginator: mastodon.Paginator<mastodon.v1.Status[], mastodon.rest.v1.ListAccountStatusesParams> paginator: mastodon.Paginator<mastodon.v1.Status[], mastodon.rest.v1.ListAccountStatusesParams>
stream?: mastodon.streaming.Subscription stream?: mastodon.streaming.Subscription
context?: mastodon.v2.FilterContext context?: mastodon.v2.FilterContext
account?: mastodon.v1.Account account?: mastodon.v1.Account
followedTags?: mastodon.v1.Tag[]
preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[] preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[]
buffer?: number buffer?: number
endMessage?: boolean | string endMessage?: boolean | string
@ -20,6 +21,12 @@ const virtualScroller = usePreferences('experimentalVirtualScroller')
const showOriginSite = computed(() => const showOriginSite = computed(() =>
account && account.id !== currentUser.value?.account.id && getServerName(account) !== currentServer.value, account && account.id !== currentUser.value?.account.id && getServerName(account) !== currentServer.value,
) )
function getFollowedTag(status: mastodon.v1.Status): string | null {
const followedTagNames = followedTags.map(tag => tag.name)
const followedStatusTags = status.tags.filter(tag => followedTagNames.includes(tag.name))
return followedStatusTags.length > 0 ? followedStatusTags[0]?.name : null
}
</script> </script>
<template> <template>
@ -32,11 +39,11 @@ const showOriginSite = computed(() =>
<template #default="{ item, older, newer, active }"> <template #default="{ item, older, newer, active }">
<template v-if="virtualScroller"> <template v-if="virtualScroller">
<DynamicScrollerItem :item="item" :active="active" tag="article"> <DynamicScrollerItem :item="item" :active="active" tag="article">
<StatusCard :status="item" :context="context" :older="older" :newer="newer" /> <StatusCard :followed-tag="getFollowedTag(item)" :status="item" :context="context" :older="older" :newer="newer" />
</DynamicScrollerItem> </DynamicScrollerItem>
</template> </template>
<template v-else> <template v-else>
<StatusCard :status="item" :context="context" :older="older" :newer="newer" /> <StatusCard :followed-tag="getFollowedTag(item)" :status="item" :context="context" :older="older" :newer="newer" />
</template> </template>
</template> </template>
<template v-if="context === 'account' " #done="{ items }"> <template v-if="context === 'account' " #done="{ items }">

View file

@ -6,10 +6,15 @@ const stream = useStreaming(client => client.public.subscribe())
function reorderAndFilter(items: mastodon.v1.Status[]) { function reorderAndFilter(items: mastodon.v1.Status[]) {
return reorderedTimeline(items, 'public') return reorderedTimeline(items, 'public')
} }
let followedTags: mastodon.v1.Tag[] | undefined
if (currentUser.value !== undefined) {
followedTags = (await useMasto().client.value.v1.followedTags.list({ limit: 0 }))
}
</script> </script>
<template> <template>
<div> <div>
<TimelinePaginator v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="public" /> <TimelinePaginator :followed-tags="followedTags" v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="public" />
</div> </div>
</template> </template>

View file

@ -6,10 +6,15 @@ const stream = useStreaming(client => client.public.local.subscribe())
function reorderAndFilter(items: mastodon.v1.Status[]) { function reorderAndFilter(items: mastodon.v1.Status[]) {
return reorderedTimeline(items, 'public') return reorderedTimeline(items, 'public')
} }
let followedTags: mastodon.v1.Tag[] | undefined
if (currentUser.value !== undefined) {
followedTags = (await useMasto().client.value.v1.followedTags.list({ limit: 0 }))
}
</script> </script>
<template> <template>
<div> <div>
<TimelinePaginator v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="public" /> <TimelinePaginator :followed-tags="followedTags" v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="public" />
</div> </div>
</template> </template>

View file

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3' import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3'
const props = defineProps(nodeViewProps) const { node, updateAttributes } = defineProps(nodeViewProps)
const languages = [ const languages = [
'c', 'c',
@ -26,10 +26,10 @@ const languages = [
const selectedLanguage = computed({ const selectedLanguage = computed({
get() { get() {
return props.node.attrs.language return node.attrs.language
}, },
set(language) { set(language) {
props.updateAttributes({ language }) updateAttributes({ language })
}, },
}) })
</script> </script>

View file

@ -60,7 +60,8 @@ export function nodeToVNode(node: Node): VNode | string | null {
} }
if ('children' in node) { if ('children' in node) {
if (node.name === 'a' && (node.attributes.href?.startsWith('/') || node.attributes.href?.startsWith('.'))) { if (node.name === 'a') {
if (node.attributes.href?.startsWith('/') || node.attributes.href?.startsWith('.')) {
node.attributes.to = node.attributes.href node.attributes.to = node.attributes.href
const { href: _href, target: _target, ...attrs } = node.attributes const { href: _href, target: _target, ...attrs } = node.attributes
@ -70,6 +71,29 @@ export function nodeToVNode(node: Node): VNode | string | null {
() => node.children.map(treeToVNode), () => node.children.map(treeToVNode),
) )
} }
// fix #3122
return h(
node.name,
node.attributes,
node.children.map((n: Node) => {
// replace span.ellipsis with bdi.ellipsis inside links
if (n && n.type === ELEMENT_NODE && n.name !== 'bdi' && n.attributes?.class?.includes('ellipsis')) {
const children = n.children.splice(0, n.children.length)
const bdi = {
...n,
name: 'bdi',
children,
} satisfies ElementNode
children.forEach((n: Node) => n.parent = bdi)
return treeToVNode(bdi)
}
return treeToVNode(n)
}),
)
}
return h( return h(
node.name, node.name,
node.attributes, node.attributes,

View file

@ -1,6 +1,5 @@
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import type { ConfirmDialogChoice, ConfirmDialogOptions, DraftItem, ErrorDialogData } from '~/types' import type { ConfirmDialogChoice, ConfirmDialogOptions, DraftItem, ErrorDialogData } from '~/types'
import { STORAGE_KEY_FIRST_VISIT } from '~/constants'
export const confirmDialogChoice = ref<ConfirmDialogChoice>() export const confirmDialogChoice = ref<ConfirmDialogChoice>()
export const confirmDialogLabel = ref<ConfirmDialogOptions>() export const confirmDialogLabel = ref<ConfirmDialogOptions>()
@ -17,14 +16,12 @@ export const reportStatus = ref<mastodon.v1.Status>()
export const commandPanelInput = ref('') export const commandPanelInput = ref('')
export const isFirstVisit = useLocalStorage(STORAGE_KEY_FIRST_VISIT, !process.mock)
export const isSigninDialogOpen = ref(false) export const isSigninDialogOpen = ref(false)
export const isPublishDialogOpen = ref(false) export const isPublishDialogOpen = ref(false)
export const isKeyboardShortcutsDialogOpen = ref(false) export const isKeyboardShortcutsDialogOpen = ref(false)
export const isMediaPreviewOpen = ref(false) export const isMediaPreviewOpen = ref(false)
export const isEditHistoryDialogOpen = ref(false) export const isEditHistoryDialogOpen = ref(false)
export const isPreviewHelpOpen = ref(isFirstVisit.value) export const isPreviewHelpOpen = ref(false)
export const isCommandPanelOpen = ref(false) export const isCommandPanelOpen = ref(false)
export const isConfirmDialogOpen = ref(false) export const isConfirmDialogOpen = ref(false)
export const isErrorDialogOpen = ref(false) export const isErrorDialogOpen = ref(false)
@ -77,12 +74,6 @@ export async function openFavoridedBoostedByDialog(statusId: string) {
favouritedBoostedByStatusId.value = statusId favouritedBoostedByStatusId.value = statusId
} }
if (isPreviewHelpOpen.value) {
watch(isPreviewHelpOpen, () => {
isFirstVisit.value = false
})
}
function restoreMediaPreviewFromState() { function restoreMediaPreviewFromState() {
mediaPreviewList.value = JSON.parse(history.state?.mediaPreviewList ?? '[]') mediaPreviewList.value = JSON.parse(history.state?.mediaPreviewList ?? '[]')
mediaPreviewIndex.value = history.state?.mediaPreviewIndex ?? 0 mediaPreviewIndex.value = history.state?.mediaPreviewIndex ?? 0

View file

@ -3,7 +3,7 @@ import type { mastodon } from 'masto'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import type { ElkInstance } from '../users' import type { ElkInstance } from '../users'
import type { UserLogin } from '~/types' import type { UserLogin } from '~/types'
import { createRestAPIClient, createStreamingAPIClient } from 'masto' import { createRestAPIClient, createStreamingAPIClient, MastoHttpError } from 'masto'
export function createMasto() { export function createMasto() {
return { return {
@ -30,15 +30,47 @@ export function mastoLogin(masto: ElkMasto, user: Pick<UserLogin, 'server' | 'to
return streamingApiUrl ? createStreamingAPIClient({ streamingApiUrl, accessToken, implementation: globalThis.WebSocket }) : undefined return streamingApiUrl ? createStreamingAPIClient({ streamingApiUrl, accessToken, implementation: globalThis.WebSocket }) : undefined
} }
const streamingApiUrl = instance?.urls?.streamingApi const streamingApiUrl = instance?.configuration?.urls?.streaming
masto.client.value = createRestAPIClient({ url, accessToken }) masto.client.value = createRestAPIClient({ url, accessToken })
masto.streamingClient.value = createStreamingClient(streamingApiUrl) masto.streamingClient.value = createStreamingClient(streamingApiUrl)
// Refetch instance info in the background on login // Refetch instance info in the background on login
masto.client.value.v1.instance.fetch().then((newInstance) => { masto.client.value.v2.instance.fetch().catch(error => new Promise<mastodon.v2.Instance>((resolve, reject) => {
if (error instanceof MastoHttpError && error.statusCode === 404) {
return masto.client.value.v1.instance.fetch().then((newInstance) => {
console.warn(`Instance ${server} on version ${newInstance.version} does not support "GET /api/v2/instance" API, try converting to v2 instance... expect some errors`)
const v2Instance = {
...newInstance,
domain: newInstance.uri,
sourceUrl: '',
usage: {
users: {
activeMonth: 0,
},
},
icon: [],
apiVersions: {
mastodon: newInstance.version,
},
contact: {
email: newInstance.email,
},
configuration: {
...(newInstance.configuration ?? {}),
urls: {
streaming: newInstance.urls.streamingApi,
},
},
} as unknown as mastodon.v2.Instance
return resolve(v2Instance)
}).catch(reject)
}
return reject(error)
})).then((newInstance) => {
Object.assign(instance, newInstance) Object.assign(instance, newInstance)
if (newInstance.urls.streamingApi !== streamingApiUrl) if (newInstance.configuration.urls.streaming !== streamingApiUrl)
masto.streamingClient.value = createStreamingClient(newInstance.urls.streamingApi) masto.streamingClient.value = createStreamingClient(newInstance.configuration.urls.streaming)
instanceStorage.value[server] = newInstance instanceStorage.value[server] = newInstance
}) })

View file

@ -40,7 +40,7 @@ export function useStatusActions(props: StatusActionsProps) {
if (isCancel && countField && prevCount === newStatus[countField]) if (isCancel && countField && prevCount === newStatus[countField])
newStatus[countField] -= 1 newStatus[countField] -= 1
Object.assign(status, newStatus) Object.assign(status.value, newStatus)
cacheStatus(newStatus, undefined, true) cacheStatus(newStatus, undefined, true)
}).finally(() => { }).finally(() => {
isLoading.value[action] = false isLoading.value[action] = false

View file

@ -30,7 +30,7 @@ export function noop() {}
export function useIsMac() { export function useIsMac() {
const headers = useRequestHeaders(['user-agent']) const headers = useRequestHeaders(['user-agent'])
return computed(() => headers['user-agent']?.includes('Macintosh') return computed(() => headers['user-agent']?.includes('Macintosh')
?? navigator?.platform?.includes('Mac') ?? false) ?? navigator?.userAgent?.includes('Mac') ?? false)
} }
export function isEmptyObject(object: object) { export function isEmptyObject(object: object) {

View file

@ -23,6 +23,7 @@ export interface PreferencesSettings {
hideNews: boolean hideNews: boolean
grayscaleMode: boolean grayscaleMode: boolean
enableAutoplay: boolean enableAutoplay: boolean
unmuteVideos: boolean
optimizeForLowPerformanceDevice: boolean optimizeForLowPerformanceDevice: boolean
enableDataSaving: boolean enableDataSaving: boolean
enablePinchToZoom: boolean enablePinchToZoom: boolean
@ -79,6 +80,7 @@ export const DEFAULT__PREFERENCES_SETTINGS: PreferencesSettings = {
hideNews: false, hideNews: false,
grayscaleMode: false, grayscaleMode: false,
enableAutoplay: true, enableAutoplay: true,
unmuteVideos: false,
optimizeForLowPerformanceDevice: false, optimizeForLowPerformanceDevice: false,
enableDataSaving: false, enableDataSaving: false,
enablePinchToZoom: false, enablePinchToZoom: false,

View file

@ -1,5 +1,6 @@
import type { Parser } from 'prosemirror-highlight/shiki'
import type { BuiltinLanguage } from 'shiki' import type { BuiltinLanguage } from 'shiki'
import { createParser, type Parser } from 'prosemirror-highlight/shiki' import { createParser } from 'prosemirror-highlight/shiki'
let parser: Parser | undefined let parser: Parser | undefined

View file

@ -20,14 +20,13 @@ const mock = process.mock
const users: Ref<UserLogin[]> | RemovableRef<UserLogin[]> = import.meta.server ? ref<UserLogin[]>([]) : ref<UserLogin[]>([]) as RemovableRef<UserLogin[]> const users: Ref<UserLogin[]> | RemovableRef<UserLogin[]> = import.meta.server ? ref<UserLogin[]>([]) : ref<UserLogin[]>([]) as RemovableRef<UserLogin[]>
const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true }) const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true })
export const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '') export const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '')
export const instanceStorage = useLocalStorage<Record<string, mastodon.v1.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true }) export const instanceStorage = useLocalStorage<Record<string, mastodon.v2.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true })
export type ElkInstance = Partial<mastodon.v1.Instance> & { export type ElkInstance = Partial<mastodon.v2.Instance> & {
uri: string
/** support GoToSocial */ /** support GoToSocial */
accountDomain?: string | null accountDomain?: string | null
} }
export function getInstanceCache(server: string): mastodon.v1.Instance | undefined { export function getInstanceCache(server: string): mastodon.v2.Instance | undefined {
return instanceStorage.value[server] return instanceStorage.value[server]
} }
@ -52,7 +51,7 @@ export const currentInstance = computed<null | ElkInstance>(() => {
}) })
export function getInstanceDomain(instance: ElkInstance) { export function getInstanceDomain(instance: ElkInstance) {
return instance.accountDomain || withoutProtocol(instance.uri) return instance.accountDomain || withoutProtocol(instance.domain || '')
} }
export const publicServer = ref('') export const publicServer = ref('')

View file

@ -257,6 +257,11 @@ const locales: LocaleObjectData[] = [
file: 'vi-VN.json', file: 'vi-VN.json',
name: 'Tiếng Việt', name: 'Tiếng Việt',
}, },
{
code: 'cy',
file: 'cy.json',
name: 'Cymraeg',
},
] ]
function buildLocales() { function buildLocales() {

View file

@ -13,7 +13,6 @@ export const STORAGE_KEY_SERVERS = 'elk-servers'
export const STORAGE_KEY_NODES = 'elk-nodes' export const STORAGE_KEY_NODES = 'elk-nodes'
export const STORAGE_KEY_CURRENT_USER_HANDLE = 'elk-current-user-handle' export const STORAGE_KEY_CURRENT_USER_HANDLE = 'elk-current-user-handle'
export const STORAGE_KEY_NOTIFY_TAB = 'elk-notify-tab' export const STORAGE_KEY_NOTIFY_TAB = 'elk-notify-tab'
export const STORAGE_KEY_FIRST_VISIT = 'elk-first-visit'
export const STORAGE_KEY_SETTINGS = 'elk-settings' export const STORAGE_KEY_SETTINGS = 'elk-settings'
export const STORAGE_KEY_CUSTOM_EMOJIS = 'elk-custom-emojis' export const STORAGE_KEY_CUSTOM_EMOJIS = 'elk-custom-emojis'
export const STORAGE_KEY_HIDE_EXPLORE_POSTS_TIPS = 'elk-hide-explore-posts-tips' export const STORAGE_KEY_HIDE_EXPLORE_POSTS_TIPS = 'elk-hide-explore-posts-tips'

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const { copy } = defineProps<{ defineProps<{
copy?: boolean copy?: boolean
}>() }>()
</script> </script>

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const { up } = defineProps<{ defineProps<{
up?: boolean up?: boolean
}>() }>()
</script> </script>

View file

@ -76,18 +76,7 @@ async function copyToClipboard() {
<caption> <caption>
<div>You can see the detail (missing and outdated keys) by clicking on the corresponding row.</div> <div>You can see the detail (missing and outdated keys) by clicking on the corresponding row.</div>
<div> <div>
If you want to send a PR, click on <strong>Edit</strong> link on the corresponding translation file, it will open <strong>Codeflow</strong>: If you want to send a PR, click on <strong>Edit</strong> link on the corresponding translation file, it will open the translation file in GitHub
<NuxtLink
class="inline"
target="_blank"
href="https://developer.stackblitz.com/codeflow/working-in-codeflow-ide#making-a-pr-with-codeflow-ide"
title="How to make a PR with Codeflow IDE (opens in new window)"
>
read the following guide
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
<path fill="currentColor" d="M5 21q-.825 0-1.413-.587Q3 19.825 3 19V5q0-.825.587-1.413Q4.175 3 5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413Q19.825 21 19 21Zm4.7-5.3l-1.4-1.4L17.6 5H14V3h7v7h-2V6.4Z" />
</svg>
</NuxtLink>
</div> </div>
</caption> </caption>
<thead> <thead>
@ -128,10 +117,10 @@ async function copyToClipboard() {
</td> </td>
<td> <td>
<NuxtLink <NuxtLink
:href="`https://pr.new/github.com/elk-zone/elk/tree/main/locales/${useFile}`" :href="`https://github.com/elk-zone/elk/tree/main/locales/${useFile}`"
target="_blank" target="_blank"
class="codeflow" class="edit-in-github"
title="Raise a PR with Codeflow (opens in new window)" title="Edit Translation File (opens in new window)"
@click.stop @click.stop
> >
Edit Edit
@ -154,10 +143,10 @@ async function copyToClipboard() {
<td><strong>{{ `${total}` }}</strong></td> <td><strong>{{ `${total}` }}</strong></td>
<td> <td>
<NuxtLink <NuxtLink
:href="`https://pr.new/github.com/elk-zone/elk/tree/main/locales/${useFile}`" :href="`https://github.com/elk-zone/elk/tree/main/locales/${useFile}`"
target="_blank" target="_blank"
class="codeflow" class="edit-in-github"
title="Raise a PR with Codeflow (opens in new window)" title="Edit Translation File (opens in new window)"
@click.stop @click.stop
> >
Edit Edit
@ -255,7 +244,7 @@ tr.expandable, tr.expandable td {
cursor: pointer; cursor: pointer;
} }
a.codeflow, a.edit-in-github,
a.inline, a.inline,
td.expandable div { td.expandable div {
display: flex; display: flex;

View file

@ -2,12 +2,6 @@
We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide. We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide.
## Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)
## Local Setup ## Local Setup
Clone the repository and run on the root folder: Clone the repository and run on the root folder:

View file

@ -13,6 +13,6 @@
}, },
"devDependencies": { "devDependencies": {
"@nuxt-themes/docus": "^1.15.1", "@nuxt-themes/docus": "^1.15.1",
"nuxt": "^3.14.1592" "nuxt": "^3.17.0"
} }
} }

View file

@ -12,6 +12,7 @@ const showUserPicker = logicAnd(
) )
const isGrayscale = usePreferences('grayscaleMode') const isGrayscale = usePreferences('grayscaleMode')
const instance = instanceStorage.value[currentServer.value]
</script> </script>
<template> <template>
@ -63,8 +64,17 @@ const isGrayscale = usePreferences('grayscaleMode')
<div sticky top-0 h-100dvh flex="~ col" gap-2 py3 ms-2> <div sticky top-0 h-100dvh flex="~ col" gap-2 py3 ms-2>
<slot name="right"> <slot name="right">
<SearchWidget mt-4 mx-1 hidden xl:block /> <SearchWidget mt-4 mx-1 hidden xl:block />
<div flex-auto />
<!-- server info -->
<div v-if="!currentUser" grid gap-3 m3>
<span text-size-lg text-primary font-bold>{{ instance.title }}</span>
<img rounded-3 :src="instance.thumbnail.url">
<p text-secondary>
{{ instance.description }}
</p>
</div>
<div flex-auto />
<PwaPrompt /> <PwaPrompt />
<PwaInstallPrompt /> <PwaInstallPrompt />
<LazyCommonPreviewPrompt v-if="info.env === 'preview'" /> <LazyCommonPreviewPrompt v-if="info.env === 'preview'" />

View file

@ -108,8 +108,8 @@
"desc3": "No inicies sessió amb el teu compte real." "desc3": "No inicies sessió amb el teu compte real."
}, },
"desc_highlight": "Espereu trobar alguns errors i que falten funcions ací i allà.", "desc_highlight": "Espereu trobar alguns errors i que falten funcions ací i allà.",
"desc_para1": "Gràcies pel teu interès en provar Elk, el nostre client web Mastodon en procés", "desc_para1": "Gràcies pel teu interès en provar Elk, el nostre client web Mastodon en proves!",
"desc_para2": "estem treballant de valent en el desenvolupament i en millorar-lo.", "desc_para2": "Estem treballant de valent en el desenvolupament i en millorar-lo.",
"desc_para3": "Per a impulsar el desenvolupament, pots patrocinar l'equip a través dels patrocis de GitHub. Esperem que gaudisques d'Elk!", "desc_para3": "Per a impulsar el desenvolupament, pots patrocinar l'equip a través dels patrocis de GitHub. Esperem que gaudisques d'Elk!",
"desc_para4": "Elk és de codi obert. Si vols ajudar amb proves, comentaris o contribucions,", "desc_para4": "Elk és de codi obert. Si vols ajudar amb proves, comentaris o contribucions,",
"desc_para5": "troba'ns a GitHub", "desc_para5": "troba'ns a GitHub",
@ -275,7 +275,7 @@
"hide_alt_indi_on_posts": "Amaga l'indicador «alt» a les publicacions", "hide_alt_indi_on_posts": "Amaga l'indicador «alt» a les publicacions",
"hide_boost_count": "Amaga el nombre d'impulsos", "hide_boost_count": "Amaga el nombre d'impulsos",
"hide_favorite_count": "Amaga el nombre de preferits", "hide_favorite_count": "Amaga el nombre de preferits",
"hide_follower_count": "Amaga el nombre seguidors", "hide_follower_count": "Amaga el nombre de seguidors",
"hide_reply_count": "Amaga el nombre de respostes", "hide_reply_count": "Amaga el nombre de respostes",
"hide_username_emojis": "Amaga els emojis dels noms d'usuari", "hide_username_emojis": "Amaga els emojis dels noms d'usuari",
"label": "Configuració", "label": "Configuració",
@ -352,16 +352,16 @@
"second_future": "ara|en {n} segon|en {n} segons", "second_future": "ara|en {n} segon|en {n} segons",
"second_past": "ara|fa {n} segon|fa {n} segons", "second_past": "ara|fa {n} segon|fa {n} segons",
"short_day_future": "en {n} d", "short_day_future": "en {n} d",
"short_day_past": "{n} d", "short_day_past": "fa {n} d",
"short_hour_future": "en {n} h", "short_hour_future": "en {n} h",
"short_hour_past": "{n} h", "short_hour_past": "fa {n} h",
"short_minute_future": "en {n} min", "short_minute_future": "en {n} min",
"short_minute_past": "{n} min", "short_minute_past": "fa {n} min",
"short_month_future": "en {n} mes", "short_month_future": "en {n} mes",
"short_month_past": "{n} mes", "short_month_past": "fa {n} mes",
"short_week_past": "{n}w", "short_week_past": "fa {n} set",
"short_year_future": "en {n} a", "short_year_future": "en {n} a",
"short_year_past": "{n} a", "short_year_past": "fa {n} a",
"week_future": "en 0 setmanes|la setmana que ve|en {n} setmanes", "week_future": "en 0 setmanes|la setmana que ve|en {n} setmanes",
"year_future": "en 0 anys|l'any que ve|en {n} anys" "year_future": "en 0 anys|l'any que ve|en {n} anys"
}, },

481
locales/cy.json Normal file
View file

@ -0,0 +1,481 @@
{
"a11y": {
"loading_page": "Wrthi'n llwytho'r dudalen...",
"loading_titled_page": "Wrthi'n llwytho {0}",
"locale_changed": "Iaith wedi'i newid i {0}",
"locale_changing": "Wrthi'n newid yr iaith...",
"route_loaded": "Wedi llwytho {0}"
},
"account": {
"avatar_description": "Rhithffurf {0}",
"blocked_by": "Mae'r defnyddiwr yma'n eich blocio.",
"blocked_domains": "Blociau parth",
"blocked_users": "Defnyddwyr wedi'u blocio",
"blocking": "Wedi'i blocio",
"bot": "BOT",
"favourites": "Ffefrynnau",
"follow": "Dilyn",
"follow_back": "Dilyn yn ôl",
"follow_requested": "Wedi gofyn i ddilyn",
"followers": "Dilynwyr",
"followers_count": "{0} Dilynwr",
"following": "Yn dilyn",
"following_count": "Yn dilyn {0}",
"follows_you": "Yn eich dilyn",
"go_to_profile": "I'r proffil",
"joined": "Wedi ymuno",
"moved_title": "has indicated that their new account is now:",
"muted_users": "Defnyddwyr wedi'i tawelu",
"muting": "Wedi tawelu",
"mutuals": "Cyd-ddilynwyr",
"pinned": "Wedi'i pinio",
"posts": "Tŵtiau",
"posts_count": "{0} tŵt",
"profile_description": "Pennyn proffil {0}",
"profile_unavailable": "Nid yw'r proffil ar gael",
"unblock": "Dad-flocio",
"unfollow": "Dad-ddilyn",
"unmute": "Dad-daweli",
"view_other_followers": "Mae'n bosibl na fydd dilynwyr o weinyddion eraill yn cael eu harddangos.",
"view_other_following": "Mae'n bosibl na fydd cyfrifon o weinyddion eraill â dilynwyd yn cael eu harddangos."
},
"action": {
"apply": "Cadw",
"bookmark": "Nodi",
"bookmarked": "Wedi nodi",
"boost": "Bŵst",
"boost_count": "{0}",
"boosted": "Bŵstiodd",
"clear_upload_failed": "Clirio gwallau uwchlwytho",
"close": "Cau",
"compose": "Ysgrifennu",
"confirm": "Cadarnhau",
"edit": "Golygu",
"enter_app": "I'r ap",
"favourite": "Hoffi",
"favourite_count": "{0}",
"favourited": "Hoffodd",
"more": "Mwy",
"next": "Nesaf",
"prev": "Yn ôl",
"publish": "Tŵt",
"reply": "Ymateb",
"reply_count": "{0}",
"reset": "Ailosod",
"save": "Cadw",
"save_changes": "Cadw newidiadau",
"sign_in": "Mewngofnodi",
"switch_account": "Newid cyfrif",
"vote": "Pleidleisio"
},
"app_desc_short": "Cleient gwe ystwyth ar gyfer Mastodon",
"app_logo": "Logo Elk",
"app_name": "Elk",
"attachment": {
"edit_title": "Disgrifiad",
"remove_label": "Tunnu atodiad"
},
"command": {
"activate": "Actifadu",
"complete": "Cwblhau",
"compose_desc": "Ysgrifennu tŵt",
"n-people-in-the-past-n-days": "{0} person yn y {1} diwrnod diwethaf",
"select_lang": "Dewis iaith",
"sign_in_desc": "Ychwanegu cyfrif",
"switch_account": "Newid i {0}",
"switch_account_desc": "Newid cyfrif",
"toggle_dark_mode": "Toglo modd tywyll",
"toggle_zen_mode": "Toglo modd zen"
},
"common": {
"confirm_dialog": {
"cancel": "Ie",
"confirm": "Na",
"title": "Ydych chi'n siŵr?"
},
"end_of_list": "Diwedd y rhestr",
"error": "GWALL",
"in": "mewn",
"not_found": "404 Ni chafwyd",
"offline_desc": "Rydych yn ymddangos i fod all-lein. Gwiriwch eich cysylltiad os gwelwch yn dda."
},
"compose": {
"draft_title": "Drafft {0}",
"drafts": "Drafftiau ({v})"
},
"conversation": {
"with": "gyda"
},
"error": {
"account_not_found": "Ni chafwyd cyfrif {0}",
"explore-list-empty": "Nid oes unrhywbeth yn boblogaidd ar hyn o bryd. Dewch yn ôl yn hwyrach!",
"file_size_cannot_exceed_n_mb": "Ni all maint ffeil fod yn fwy na {0}MB",
"sign_in_error": "Ni allwn gysylltu i'r gweinydd.",
"status_not_found": "Ni chafwyd y tŵt",
"unsupported_file_format": "Math ffeil anghynaledig"
},
"help": {
"desc_highlight": "Expect some bugs and missing features here and there.",
"desc_para1": "Diolch am eich diddordeb mewn rhoi cynnig ar Elk, ein cleient gwe Mastodon yr ydym yn gweithio ar!",
"desc_para2": "Rydym yn gweithio'n galed arno ac yn ei wellau dros amser.",
"desc_para3": "I hybu datblygiad, gallwch noddi'r tîm trwy Noddwyr GitHub. Gobeithio y gwnewch chi fwynhau Elk!",
"desc_para4": "Mae Elk yn gôd agored. Os hoffech helpu gyda phrofi, rhoi adborth, neu gyfrannu,",
"desc_para5": "siaradwch a ni ar GitHub",
"desc_para6": "a chymrwch rhan.",
"title": "Mae Elk yn feddalwedd rhagoledig!"
},
"language": {
"search": "Chwilio"
},
"menu": {
"block_account": "Blocio {0}",
"block_domain": "Blocio parth {0}",
"copy_link_to_post": "Copïo cyswllt i'r tŵt hwn",
"delete": "Dileu",
"delete_and_redraft": "Dileu ac ail-drafftio",
"delete_confirm": {
"cancel": "Canslo",
"confirm": "Dileu",
"title": "Ydych yn siŵr eich fod eisiau dileu'r tŵt?"
},
"direct_message_account": "Direct message {0}",
"edit": "Golygu",
"hide_reblogs": "Cuddio bŵstiau gan {0}",
"mention_account": "Sôn am {0}",
"mute_account": "Taweli {0}",
"mute_conversation": "Taweli'r sgwrs",
"open_in_original_site": "Agor ar y wefan gwreiddiol",
"pin_on_profile": "Pinio i fy mhroffil",
"share_post": "Rhannu'r tŵt",
"show_favourited_and_boosted_by": "Dango pwy hoffodd a bŵstiodd",
"show_reblogs": "Dangos bŵstiau gan {0}",
"show_untranslated": "Dangos heb ei gyfieithu",
"toggle_theme": {
"dark": "Toglo modd tywyll",
"light": "Toglo modd golau"
},
"translate_post": "Cyfieuthu tŵt",
"unblock_account": "Dad-flocio {0}",
"unblock_domain": "Dad-flocio parth {0}",
"unmute_account": "Dad-daweli {0}",
"unmute_conversation": "Dad-daweli'r sgwrs",
"unpin_on_profile": "Dad-binio o fy mhroffil"
},
"nav": {
"back": "Yn ôl",
"blocked_domains": "Parthau wedi'u blocio",
"blocked_users": "Defnyddwyr wedi'u blocio",
"bookmarks": "Llyfrnodau",
"built_at": "Wedi'i adeiladu {0}",
"conversations": "Sgwrsiau",
"explore": "Archwilio",
"favourites": "Ffefrynnau",
"federated": "O'r ffedysawd",
"home": "Cartref",
"local": "Lleol",
"muted_users": "Defnyddwyr wedi'u tawelu",
"notifications": "Hysbysiadau",
"profile": "Proffil",
"search": "Chwilio",
"select_feature_flags": "Toglo nodweddion",
"select_font_size": "Maint ffont",
"select_language": "Iaith rhyngwyneb",
"settings": "Gosodiadau",
"show_intro": "Dangos cyflwyniad",
"toggle_theme": "Toglo thema",
"zen_mode": "Modd zen"
},
"notification": {
"favourited_post": "hofodd eich tŵt",
"followed_you": "yn eich dilyn",
"followed_you_count": "Gwnaeth {0} person eich dilyn",
"missing_type": "HEB notification.type:",
"reblogged_post": "bŵstiodd eich tŵt",
"request_to_follow": "gofynwyd i eich dilyn",
"signed_up": "wedi ymuno",
"update_status": "wedi golygu ei tŵt"
},
"placeholder": {
"content_warning": "Ysgrifennwch eich rhybudd yma",
"default_1": "Beth sydd ar eich meddwl?",
"reply_to_account": "Yn ymateb i {0}",
"replying": "Yn ymateb",
"the_thread": "y sgwrs"
},
"pwa": {
"dismiss": "Diystyru",
"title": "Mae diweddariad newydd o Elk ar gael!",
"update": "Diweddaru",
"update_available_short": "Diweddaru Elk",
"webmanifest": {
"canary": {
"description": "Cleient gwe ystwyth ar gyfer Mastodon (caneri)",
"name": "Elk (caneri)",
"short_name": "Elk (caneri)"
},
"dev": {
"description": "Cleient gwe ystwyth ar gyfer Mastodon (datblygu)",
"name": "Elk (datblygu)",
"short_name": "Elk (datblygu)"
},
"preview": {
"description": "Cleient gwe ystwyth ar gyfer Mastodon (rhagolwg)",
"name": "Elk (rhagolwg)",
"short_name": "Elk (rhadolwg)"
},
"release": {
"description": "Cleient gwe ystwyth ar gyfer Mastodon",
"name": "Elk",
"short_name": "Elk"
}
}
},
"search": {
"search_desc": "Chwilio am bobl a hashnodau",
"search_empty": "Ni chafwyd unrhyw beth am y termau chwilio yma"
},
"settings": {
"about": {
"label": "Ynglŷn",
"meet_the_team": "Cwrdd a'r tîm",
"sponsor_action": "Noddi ni",
"sponsor_action_desc": "I helpu'r tîm sy'n creu Elk",
"sponsors": "Noddwyr",
"sponsors_body_1": "Mae Elk wedi'i wneud yn bosibl gan noddiant hael:",
"sponsors_body_2": "A phob cwmni a pherson sy'n noddi tîm Elk a'i aelodau.",
"sponsors_body_3": "Os ydych yn mwynhau'r ap, efallai hoffwch ein noddi:"
},
"account_settings": {
"description": "Newid gosodiadau eich cyfrif yn rhyngwyneb Mastodon",
"label": "Gosodiadau cyfrif"
},
"interface": {
"color_mode": "Modd lliw",
"dark_mode": "Modd tywyll",
"default": " (rhagosodedig)",
"font_size": "Maint ffont",
"label": "Rhyngwyneb",
"light_mode": "Modd golau",
"size_label": {
"lg": "Mawr",
"md": "Canolig",
"sm": "Bach",
"xl": "Mawr iawn",
"xs": "Bach iawn"
},
"system_mode": "System",
"theme_color": "Lliw thema"
},
"language": {
"display_language": "Iaith rhyngwyneb",
"label": "Iaith"
},
"notifications": {
"label": "Hysbysiadau",
"notifications": {
"label": "Gosodiadau hysbysu"
},
"push_notifications": {
"alerts": {
"favourite": "Ffefrynnu",
"follow": "Dilynwyr newydd",
"mention": "Sôn amdanoch",
"poll": "Pleidleisiadau",
"reblog": "Bŵstio",
"title": "Pa hysbysiadau i'w dderbyn?"
},
"description": "Derbyn hysbysiadau hyd yn oed pan nad ydych yn defnyddio Elk.",
"instructions": "Peidiwch anghofio cadw eich newidiadau gyda'r botwm @:settings.notifications.push_notifications.save_settings!",
"label": "Dewisiadau hysbysiadau gwthiadwy",
"policy": {
"all": "Gan bawb",
"followed": "Gan bobl dwi'n dilyn",
"follower": "Gan bobl sy'n fy nilyn",
"none": "Gan neb",
"title": "Gan bwy allaf dderbyn hysbysiadau?"
},
"save_settings": "Cadw gosodiadau",
"subscription_error": {
"clear_error": "Cau",
"permission_denied": "Gwrthodwyd caniatâd: trowch hysbysiadau ymlaen yn eich porwr.",
"request_error": "Roedd gwall wrth ofyn am y tanysgrifiad, ceisiwch eto ac os yw'r gwall yn parhau, rhowch wybod i Elk am y mater.",
"title": "Ni allwyd tanysgrifio i hysbysiadau gwthiadwy",
"too_many_registrations": "Oherwydd cyfyngiadau eich porwr, ni all Elk ddefnyddio'r gwasanaeth hysbysiadau gwthiadwy ar gyfer sawl cyfrif ar wahanol weinyddion. Dylech ddad-danysgrifio o hysbysiadau gwthiadwy ar gyfrifon eraill a cheisio eto."
},
"title": "Gosodiadau hysbysiadau gwthiadwy",
"undo_settings": "Dad-wneud newidiadau",
"unsubscribe": "Troi hyssbysiadau gwthiadwy i ffwrdd",
"unsupported": "Nid yw'ch porwr yn gallu gerbyn hysbysiadau gwthiadwy.",
"warning": {
"enable_close": "Cau",
"enable_description": "I dderbyn hysbysiadau pam nad yw Elk ar agor, trowch hysbysiadau gwthiadwy ymlaen. Gallwch reoli pa rhyngweithradiadau sy'n creu hysbysiadau gwthiadwy trwy'r botwn \"@:settings.notifications.show_btn{'\"'} pan y maent ymlaen.",
"enable_description_desktop": "I dderbyn hysbysiadau pam nad yw Elk ar agor, trowch hysbysiadau gwthiadwy ymlaen. Gallwch reoli pa rhyngweithradiadau sy'n creu hysbysiadau gwthiadwy yn \"Gosodiadau > Hysbysiadau > Dewisiadau hysbysiadau gwthadwy\" pan y maent ymlaen.",
"enable_description_mobile": "Gallwch hefyd gael mynediad i'r gosodiadau yn \"Gosodiadau > Hysbysiadau > Dewisiadau hysbysiadau gwthadwy\".",
"enable_description_settings": "I dderbyn hysbysiadau pam nad yw Elk ar agor, trowch hysbysiadau gwthiadwy ymlaen. Gallwch reoli pa rhyngweithradiadau sy'n creu hysbysiadau gwthiadwy pan y maent ymlaen.",
"enable_desktop": "Troi hysbysiadau gwthiadwy ymlaen",
"enable_title": "Byddwch byth yn colli unrhywbeth",
"re_auth": "Ni'd yw'ch gweinydd yn gallu danfon hysbysiadau gwthiadwy. Ymgesiwch allgofnodi a mewngofnodi eto, os mae'r neges yma'n parhau siaradwch a'ch rheolwr gweinydd."
}
},
"show_btn": "Mynd i osodiadau hysbysiadau"
},
"notifications_settings": "Hysbysiadau",
"preferences": {
"github_cards": "Cerdiau GitHub",
"hide_boost_count": "Cuddio cyfrif bŵstiadau",
"hide_favorite_count": "Cuddio cyfrif ffefrynniadau",
"hide_follower_count": "Cuddio cyfrif dilynwyr",
"label": "Gosodiadau",
"user_picker": "Dewisiwr defnyddwyr",
"virtual_scroll": "Rhith sgrolio"
},
"profile": {
"appearance": {
"bio": "Bywgraffiad",
"description": "Newid rhithffurf, enw defnyddiwr, proffil, a.y.y.b.",
"display_name": "Enw dangos",
"label": "Rhithffurf",
"profile_metadata": "Metadata proffil",
"profile_metadata_desc": "Gallwch ddangos hyd at {0} eitem ar eich proffil",
"title": "Golygu proffil"
},
"featured_tags": {
"description": "Gall pobl arychwilio eich tŵtiau cyhoeddus o dan y hashnodion yma.",
"label": "Hashnodion wedi'i nohweddi"
},
"label": "Proffil"
},
"select_a_settings": "Dewis gosodiad",
"users": {
"export": "Allforio tocynnau defnyddiwr",
"import": "Mewnforio tocynnau defnyddiwr",
"label": "Defnyddwyr wedi'i mewngodnoi"
}
},
"state": {
"attachments_exceed_server_limit": "The number of attachments exceeded the limit per post.",
"attachments_limit_error": "Limit per post exceeded",
"edited": "(Wedi'i olygu)",
"editing": "Wrthi'n golygu",
"loading": "Wrthi'n llwytho...",
"publishing": "Wrthi'n cyhoeddi",
"upload_failed": "Uwchlwytho wedi methu",
"uploading": "Wrthi'n uwchlywtho..."
},
"status": {
"boosted_by": "Wedi'i bŵstio gan",
"edited": "Wedi'i olygu {0}",
"favourited_by": "Wedi'i ffefrynnu gan",
"filter_hidden_phrase": "Wedi'i hidlo gan",
"filter_removed_phrase": "Wedi'i hidlo",
"filter_show_anyway": "Dangos bethbynnag",
"img_alt": {
"desc": "Disgrifiad",
"dismiss": "Cau"
},
"poll": {
"count": "{0} pleidlais",
"ends": "Yn gorffen {0}",
"finished": "Wedi gorffen {0}"
},
"reblogged": "Bŵstiodd {0}",
"replying_to": "Yn ateb i {0}",
"show_full_thread": "Dangos y sgwrs cyfan",
"someone": "rhywun",
"spoiler_show_less": "Dangos llai",
"spoiler_show_more": "Dangos mwy",
"thread": "Sgwrs",
"try_original_site": "Ymgesio ar y wefan gwreiddiol"
},
"status_history": {
"created": "crëwyd {0}",
"edited": "golygwyd {0}"
},
"tab": {
"for_you": "I chi",
"hashtags": "Hashnodion",
"media": "Cyfryngau",
"news": "Newyddion",
"notifications_all": "Popeth",
"notifications_mention": "Yn sôn amdanoch",
"posts": "Tŵtiau",
"posts_with_replies": "Tŵtiau ac ymatebion"
},
"tag": {
"follow": "Dilyn",
"follow_label": "Dilyn hashnod {0}",
"unfollow": "Dad-dilyn",
"unfollow_label": "Dad-dilyn hashnod {0}"
},
"time_ago_options": {
"day_future": "heddiw|trannoeth|trenydd|tradwy|mewn {n} diwrnod",
"day_past": "heddiw|ddoe|echddoe|{n} diwrnod yn ôl",
"hour_future": "mewn {n} awr",
"hour_past": "{n} awr yn ôl",
"just_now": "nawr",
"minute_future": "mewn {n} munud",
"minute_past": "{n} munud yn ôl",
"month_future": "mewn {n} mis",
"month_past": "{n} mis yn ôl",
"second_future": "nawr|mewn {n} eiliad",
"second_past": "nawr|{n} eiliad yn ôl",
"short_day_future": "mewn {n}d",
"short_day_past": "{n}d",
"short_hour_future": "mewn {n}h",
"short_hour_past": "{n}h",
"short_minute_future": "mewn {n}mun",
"short_minute_past": "{n}mun",
"short_month_future": "mewn {n}mi",
"short_month_past": "{n}mi",
"short_second_future": "mewn {n}e",
"short_second_past": "{n}e",
"short_week_future": "mewn {n}w",
"short_week_past": "{n}w",
"short_year_future": "mewn {n}b",
"short_year_past": "{n}b",
"week_future": "wythnos yma|wythnos nesaf|mewn {n} wythnos",
"week_past": "wythnos yma|wythnos diwethaf|{n} wythnos yn ôl",
"year_future": "flywddyn yma|flywddyn nesaf|mewn {n} blynedd",
"year_past": "flywddyn yma|flywddyn diwethaf|{n} blynedd yn ôl"
},
"timeline": {
"show_new_items": "Dangos {v} eiem newydd",
"view_older_posts": "Mae'n bosibl na fydd tŵtiau hen o weinyddion eraill yn cael eu ddangos."
},
"title": {
"federated_timeline": "Amserlin y ffedysawd",
"local_timeline": "Amserlin lleol"
},
"tooltip": {
"add_content_warning": "Ychwanegu rhybydd cynnwys",
"add_emojis": "Ychwanegu emoji",
"add_media": "Ychwanegu lluniau, fideos, neu sain",
"add_publishable_content": "Ychwaneu cynnwys i gyhoeddu",
"change_content_visibility": "Newid gweladwyedd cynnwys",
"change_language": "Newid iaith",
"emoji": "Emoji",
"explore_links_intro": "Mae'r storion newyddion yma'n cael eu sôn amdano yn awr gan bobl ar y gweinydd yma ac eraill.",
"explore_posts_intro": "Mae'r tŵtiau yma'n boblogaidd yn awr ar y gweinydd yma ac eraill.",
"explore_tags_intro": "Mae'r hashnodion yam'n boblogaidd yn awr ar y gweinydd yma ac eraill.",
"toggle_code_block": "Toglo bloc côd"
},
"user": {
"add_existing": "Ychwanegu defnyddiwr",
"server_address_label": "Cyfeiriad gweinydd Mastodon",
"sign_in_desc": "Mewngofnodwch i ddilyn defnyddwyr neu hashnodion; hoffi, rhannu, ac ymateb i dŵtiau, neu rhyngweithio o'ch cyfrif ar weinydd gwahanol.",
"sign_in_notice_title": "Yn gweld data cyhoeddus {0}",
"sign_out_account": "Allgofnodi o {0}",
"tip_no_account": "Os nas oes genych gyfrif Mastodon eto, {0}.",
"tip_register_account": "dewiswch eich gweinydd a chofrestrwch"
},
"visibility": {
"direct": "Uniongyrchol",
"direct_desc": "Yn weladwy i ddefnyddwyr a sônwyd am yn unig",
"private": "Dilynwyr yn unig",
"private_desc": "Yn weladwy i dilynwyr yn unig",
"public": "Cyhoeddus",
"public_desc": "Yn weladwy i bawb",
"unlisted": "Anrhestredig",
"unlisted_desc": "Yn weladwy i bawb, ond heb ei ddangos mewn nodweddion darganfod"
}
}

View file

@ -86,6 +86,9 @@
"switch_account": "Account wechseln", "switch_account": "Account wechseln",
"vote": "Abstimmen" "vote": "Abstimmen"
}, },
"actions": {
"more": "Mehr"
},
"app_desc_short": "Ein flinker Mastodon Web-Client", "app_desc_short": "Ein flinker Mastodon Web-Client",
"app_logo": "Elk Logo", "app_logo": "Elk Logo",
"app_name": "Elk", "app_name": "Elk",
@ -654,6 +657,10 @@
"list": "Liste", "list": "Liste",
"media": "Medien", "media": "Medien",
"news": "Nachrichten", "news": "Nachrichten",
"notifications_admin": {
"report": "Meldung",
"sign_up": "Registrierung"
},
"notifications_all": "Alle", "notifications_all": "Alle",
"notifications_favourite": "Favorisiert", "notifications_favourite": "Favorisiert",
"notifications_follow": "Folgen", "notifications_follow": "Folgen",
@ -722,6 +729,7 @@
"change_content_visibility": "Sichtbarkeit von Inhalten ändern", "change_content_visibility": "Sichtbarkeit von Inhalten ändern",
"change_language": "Sprache ändern", "change_language": "Sprache ändern",
"emoji": "Emoji", "emoji": "Emoji",
"emojis": "Emojis",
"explore_links_intro": "Diese Nachrichten werden gerade von Leuten auf diesem und anderen Servern des dezentralen Netzwerks besprochen.", "explore_links_intro": "Diese Nachrichten werden gerade von Leuten auf diesem und anderen Servern des dezentralen Netzwerks besprochen.",
"explore_posts_intro": "Diese Beiträge von diesem Server gewinnen gerade unter den Leuten von diesem und anderen Servern des dezentralen Netzwerks an Reichweite.", "explore_posts_intro": "Diese Beiträge von diesem Server gewinnen gerade unter den Leuten von diesem und anderen Servern des dezentralen Netzwerks an Reichweite.",
"explore_tags_intro": "Diese Hashtags gewinnen gerade unter den Leuten von diesem und anderen Servern des dezentralen Netzweks an Reichweite.", "explore_tags_intro": "Diese Hashtags gewinnen gerade unter den Leuten von diesem und anderen Servern des dezentralen Netzweks an Reichweite.",

View file

@ -226,7 +226,9 @@
"manage": "Manage lists", "manage": "Manage lists",
"modify_account": "Modify lists with account", "modify_account": "Modify lists with account",
"remove_account": "Remove account from list", "remove_account": "Remove account from list",
"save": "Save changes" "save": "Save changes",
"search_following_desc": "Search for people you are following",
"search_following_placeholder": "Search among people you follow"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Keyboard shortcuts", "dialog_header": "Keyboard shortcuts",
@ -334,10 +336,12 @@
"zen_mode": "Zen Mode" "zen_mode": "Zen Mode"
}, },
"notification": { "notification": {
"and": "and",
"favourited_post": "favorited your post", "favourited_post": "favorited your post",
"followed_you": "followed you", "followed_you": "followed you",
"followed_you_count": "{0} people followed you|{0} person followed you|{0} people followed you", "followed_you_count": "{0} people followed you|{0} person followed you|{0} people followed you",
"missing_type": "MISSING notification.type:", "missing_type": "MISSING notification.type:",
"others": "{0} others|{0} other|{0} others",
"reblogged_post": "boosted your post", "reblogged_post": "boosted your post",
"reported": "{0} reported {1}", "reported": "{0} reported {1}",
"request_to_follow": "requested to follow you", "request_to_follow": "requested to follow you",
@ -559,6 +563,7 @@
"label": "Preferences", "label": "Preferences",
"optimize_for_low_performance_device": "Optimize for low performance device", "optimize_for_low_performance_device": "Optimize for low performance device",
"title": "Experimental Features", "title": "Experimental Features",
"unmute_videos": "Video sound on by default",
"use_star_favorite_icon": "Use star favorite icon", "use_star_favorite_icon": "Use star favorite icon",
"user_picker": "User Picker", "user_picker": "User Picker",
"user_picker_description": "Displays all avatars of logged accounts in the bottom-left so you can switch quickly between them.", "user_picker_description": "Displays all avatars of logged accounts in the bottom-left so you can switch quickly between them.",
@ -637,7 +642,8 @@
"poll": { "poll": {
"count": "{0} votes|{0} vote|{0} votes", "count": "{0} votes|{0} vote|{0} votes",
"ends": "ends {0}", "ends": "ends {0}",
"finished": "finished {0}" "finished": "finished {0}",
"update": "Update poll"
}, },
"replying_to": "Replying to {0}", "replying_to": "Replying to {0}",
"show_full_thread": "Show Full thread", "show_full_thread": "Show Full thread",

View file

@ -188,6 +188,7 @@
"attachments_limit_video_error": "Tamaño máximo de video excedido: {0}" "attachments_limit_video_error": "Tamaño máximo de video excedido: {0}"
}, },
"status": { "status": {
"pinned": "Publicaciones ancladas",
"spoiler_show_less": "Menos" "spoiler_show_less": "Menos"
}, },
"tab": { "tab": {

View file

@ -633,6 +633,7 @@
"dismiss": "Descartar", "dismiss": "Descartar",
"read": "Leer la descripción de la imagen {0}" "read": "Leer la descripción de la imagen {0}"
}, },
"pinned": "Publicaciones fijadas",
"poll": { "poll": {
"count": "{0} votos|{0} voto|{0} votos", "count": "{0} votos|{0} voto|{0} votos",
"ends": "finaliza {0}", "ends": "finaliza {0}",
@ -713,6 +714,7 @@
"year_past": "hace 0 años|el año pasado|hace {n} años" "year_past": "hace 0 años|el año pasado|hace {n} años"
}, },
"timeline": { "timeline": {
"no_posts": "¡No hay publicaciones aquí!",
"show_new_items": "Mostrar {v} nuevas publicaciones|Mostrar {v} nueva publicación|Mostrar {v} nuevas publicaciones", "show_new_items": "Mostrar {v} nuevas publicaciones|Mostrar {v} nueva publicación|Mostrar {v} nuevas publicaciones",
"view_older_posts": "Es posible que no se muestren las publicaciones antiguas de otras instancias." "view_older_posts": "Es posible que no se muestren las publicaciones antiguas de otras instancias."
}, },

View file

@ -226,7 +226,9 @@
"manage": "Kudeatu zerrendak", "manage": "Kudeatu zerrendak",
"modify_account": "Aldatu honako kontua duten zerrendak:", "modify_account": "Aldatu honako kontua duten zerrendak:",
"remove_account": "Kendu kontua zerrendatik", "remove_account": "Kendu kontua zerrendatik",
"save": "Gorde aldaketak" "save": "Gorde aldaketak",
"search_following_desc": "Egin bilaketa jarraitzen ari zatzaien jendearen artean",
"search_following_placeholder": "Bilatu jarraitzen dituzunen artean"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Teklatuaren lasterbideak", "dialog_header": "Teklatuaren lasterbideak",
@ -334,10 +336,12 @@
"zen_mode": "ZEN modua" "zen_mode": "ZEN modua"
}, },
"notification": { "notification": {
"and": "eta",
"favourited_post": "(e)k zure bidalketa gogoko egin du", "favourited_post": "(e)k zure bidalketa gogoko egin du",
"followed_you": "(e)k jarraitu dizu", "followed_you": "(e)k jarraitu dizu",
"followed_you_count": "{0} pertsonak jarraitu dizute|pertsona {0}ek jarraitu dizu|{0} pertsonak jarraitu dizute", "followed_you_count": "{0} pertsonak jarraitu dizute|pertsona {0}ek jarraitu dizu|{0} pertsonak jarraitu dizute",
"missing_type": "MISSING notification.type:", "missing_type": "MISSING notification.type:",
"others": "beste {0}(e)k|beste {0}ek|beste {0}(e)k",
"reblogged_post": "(e)k zure bidalketari bultzada eman dio", "reblogged_post": "(e)k zure bidalketari bultzada eman dio",
"reported": "{0}(e)k {1} salatu du", "reported": "{0}(e)k {1} salatu du",
"request_to_follow": "(e)k jarraipen-eskaera bidali dizu", "request_to_follow": "(e)k jarraipen-eskaera bidali dizu",
@ -444,7 +448,7 @@
"sponsor_action": "Eman babesa", "sponsor_action": "Eman babesa",
"sponsor_action_desc": "Elk garatzen duen taldeari babesa emateko", "sponsor_action_desc": "Elk garatzen duen taldeari babesa emateko",
"sponsors": "Babesleak", "sponsors": "Babesleak",
"sponsors_body_1": "Elk ondorengoen babes eskuzabalari eta laguntzari esker izan da posible egitea:", "sponsors_body_1": "Elk honakoen babes eskuzabalari eta laguntzari esker izan da posible egitea:",
"sponsors_body_2": "Baita Elk taldea eta bere kideak babesten dituzten enpresa eta norbanakoei esker.", "sponsors_body_2": "Baita Elk taldea eta bere kideak babesten dituzten enpresa eta norbanakoei esker.",
"sponsors_body_3": "Aplikazioa gogoko baduzu, agian babesa eman diezagukezu:", "sponsors_body_3": "Aplikazioa gogoko baduzu, agian babesa eman diezagukezu:",
"version": "Bertsioa" "version": "Bertsioa"
@ -475,7 +479,7 @@
"add": "Gehitu", "add": "Gehitu",
"choose_language": "Hautatu hizkuntza", "choose_language": "Hautatu hizkuntza",
"heading": "Itzulpenak", "heading": "Itzulpenak",
"hide_specific": "Ezkutatu itzulpena ondorengo hizkuntzetarako:", "hide_specific": "Ezkutatu itzulpena honako hizkuntzetarako:",
"remove": "Kendu" "remove": "Kendu"
} }
}, },
@ -550,7 +554,7 @@
"hide_favorite_count": "Ezkutatu gogokoen kopurua", "hide_favorite_count": "Ezkutatu gogokoen kopurua",
"hide_follower_count": "Ezkutatu jarraitzaileen kopurua", "hide_follower_count": "Ezkutatu jarraitzaileen kopurua",
"hide_gif_indi_on_posts": "Ezkutatu GIF adierazlea bidalketetan", "hide_gif_indi_on_posts": "Ezkutatu GIF adierazlea bidalketetan",
"hide_news": "Ezkutatu berriak", "hide_news": "Ezkutatu albisteak",
"hide_reply_count": "Ezkutatu erantzunen kopurua", "hide_reply_count": "Ezkutatu erantzunen kopurua",
"hide_tag_hover_card": "Ezkutatu traolen aurrebista-txartelak sagua gainetik pasatzean", "hide_tag_hover_card": "Ezkutatu traolen aurrebista-txartelak sagua gainetik pasatzean",
"hide_translation": "Ezkutatu itzulpenak", "hide_translation": "Ezkutatu itzulpenak",
@ -559,6 +563,7 @@
"label": "Hobespenak", "label": "Hobespenak",
"optimize_for_low_performance_device": "Optimizatu errendimendu baxuko gailuetarako", "optimize_for_low_performance_device": "Optimizatu errendimendu baxuko gailuetarako",
"title": "Ezaugarri esperimentalak", "title": "Ezaugarri esperimentalak",
"unmute_videos": "Bideoek soinua defektuz",
"use_star_favorite_icon": "Erabili izarraren ikonoa gogokoetarako", "use_star_favorite_icon": "Erabili izarraren ikonoa gogokoetarako",
"user_picker": "Erabiltzaile-hautatzailea", "user_picker": "Erabiltzaile-hautatzailea",
"user_picker_description": "Beheko ezkerreko aldean saioa hasia duten kontuen abatar guztiak erakusten ditu, haien artean azkar aldatu ahal dezazun.", "user_picker_description": "Beheko ezkerreko aldean saioa hasia duten kontuen abatar guztiak erakusten ditu, haien artean azkar aldatu ahal dezazun.",
@ -633,17 +638,19 @@
"dismiss": "Baztertu", "dismiss": "Baztertu",
"read": "Irakurri {0} deskribapena" "read": "Irakurri {0} deskribapena"
}, },
"pinned": "Finkatutako bidalketa",
"poll": { "poll": {
"count": "{0} boto|boto {0}|{0} boto", "count": "{0} boto|boto {0}|{0} boto",
"ends": "epemuga: {0}", "ends": "epemuga: {0}",
"finished": "amaiera: {0}" "finished": "amaiera: {0}",
"update": "Freskatu"
}, },
"replying_to": "{0}(r)i erantzunez", "replying_to": "{0}(r)i erantzunez",
"show_full_thread": "Erakutsi hari osoa", "show_full_thread": "Erakutsi hari osoa",
"someone": "norbait", "someone": "norbait",
"spoiler_media_hidden": "Multimedia ezkutatuta dago", "spoiler_media_hidden": "Multimedia ezkutatuta dago",
"spoiler_show_less": "Erakutsi gutxiago", "spoiler_show_less": "Ezkutatu",
"spoiler_show_more": "Erakutsi gehiago", "spoiler_show_more": "Erakutsi",
"thread": "Haria", "thread": "Haria",
"try_original_site": "Probatu jatorrizko orrialdea" "try_original_site": "Probatu jatorrizko orrialdea"
}, },
@ -714,7 +721,7 @@
}, },
"timeline": { "timeline": {
"no_posts": "Ez dago bidalketarik!", "no_posts": "Ez dago bidalketarik!",
"show_new_items": "Erakutsi {v} elementu berri|Erakutsi elementu berri {v}|Erakutsi {v} elementu berri", "show_new_items": "Erakutsi {v} bidalketa berria|Erakutsi bidalketa berri {v}|Erakutsi {v} bidalketa berri",
"view_older_posts": "Oso litekeena da beste instantziatako bidalketa zaharragoak ikusgai ez egotea." "view_older_posts": "Oso litekeena da beste instantziatako bidalketa zaharragoak ikusgai ez egotea."
}, },
"title": { "title": {

View file

@ -585,7 +585,8 @@
"poll": { "poll": {
"count": "{0} votes", "count": "{0} votes",
"ends": "se clôt {0}", "ends": "se clôt {0}",
"finished": "clos {0}" "finished": "clos {0}",
"update": "Mettre à jour les résultats"
}, },
"replying_to": "Répondre à {0}", "replying_to": "Répondre à {0}",
"show_full_thread": "Voir le fil de discussion complet", "show_full_thread": "Voir le fil de discussion complet",

View file

@ -124,7 +124,7 @@
"block_account": { "block_account": {
"cancel": "Mégsem", "cancel": "Mégsem",
"confirm": "Blokkol", "confirm": "Blokkol",
"description": "Biztosan blokkolod {0}?", "description": "Biztosan blokkolod, {0}?",
"title": "Hozzáférés blokkolása" "title": "Hozzáférés blokkolása"
}, },
"block_domain": { "block_domain": {
@ -226,7 +226,9 @@
"manage": "Listák kezelése", "manage": "Listák kezelése",
"modify_account": "Listák módosítása fiókkal", "modify_account": "Listák módosítása fiókkal",
"remove_account": "Fiók eltávolítása a listáról", "remove_account": "Fiók eltávolítása a listáról",
"save": "Változtatások mentése" "save": "Változtatások mentése",
"search_following_desc": "Követők keresése",
"search_following_placeholder": "Keresés az emberek között, akiket követsz"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Gyorsbillentyűk", "dialog_header": "Gyorsbillentyűk",
@ -265,7 +267,7 @@
"sequence_then": "miután" "sequence_then": "miután"
}, },
"menu": { "menu": {
"add_personal_note": "Személyes megjegyzés hozzáfőzése: {0}", "add_personal_note": "Személyes megjegyzés hozzáfűzése: {0}",
"block_account": "Blokkol {0}", "block_account": "Blokkol {0}",
"block_domain": "Domaint blokkol {0}", "block_domain": "Domaint blokkol {0}",
"copy_link_to_post": "A bejegyzés hivatkozásának másolása", "copy_link_to_post": "A bejegyzés hivatkozásának másolása",
@ -334,10 +336,12 @@
"zen_mode": "Zen mód" "zen_mode": "Zen mód"
}, },
"notification": { "notification": {
"and": "és",
"favourited_post": "hozzáaadta a bejegyésed a kedvenceihez", "favourited_post": "hozzáaadta a bejegyésed a kedvenceihez",
"followed_you": "mostantól követ téged", "followed_you": "mostantól követ téged",
"followed_you_count": "{0} ember követ téged|{0} ember követ téged|{0} ember követ téged", "followed_you_count": "{0} ember követ téged|{0} ember követ téged|{0} ember követ téged",
"missing_type": "HIÁNYZÓ éresítés típus:", "missing_type": "HIÁNYZÓ éresítés típus:",
"others": "{0} mások|{0} más|{0} mások",
"reblogged_post": "kiemelte a bejegyzésedet", "reblogged_post": "kiemelte a bejegyzésedet",
"reported": "{0} jelentette {1}", "reported": "{0} jelentette {1}",
"request_to_follow": "kérte hogy kövessen", "request_to_follow": "kérte hogy kövessen",
@ -559,6 +563,7 @@
"label": "Preferenciák", "label": "Preferenciák",
"optimize_for_low_performance_device": "Alacsony teljesítményre optimalizálás", "optimize_for_low_performance_device": "Alacsony teljesítményre optimalizálás",
"title": "Kísérleti képességek", "title": "Kísérleti képességek",
"unmute_videos": "Videó hangok bekapcsolva alapértelemezésként",
"use_star_favorite_icon": "Használja a csillag favikont", "use_star_favorite_icon": "Használja a csillag favikont",
"user_picker": "Felhasználók váltása", "user_picker": "Felhasználók váltása",
"user_picker_description": "Megjeleníti a naplózott fiókok összes avatarját a bal alsó sarokban, így gyorsan válthat közöttük.", "user_picker_description": "Megjeleníti a naplózott fiókok összes avatarját a bal alsó sarokban, így gyorsan válthat közöttük.",
@ -633,12 +638,14 @@
"dismiss": "Elvetés", "dismiss": "Elvetés",
"read": "Olvassa el a {0} leírását" "read": "Olvassa el a {0} leírását"
}, },
"pinned": "Kitűzött bejegyzés",
"poll": { "poll": {
"count": "{0} szavazat|{0} szavazat|{0} szavazat", "count": "{0} szavazat|{0} szavazat|{0} szavazat",
"ends": "véget ér {0}", "ends": "véget ér {0}",
"finished": "véget ért {0}" "finished": "véget ért {0}",
"update": "Szavazás frissítése"
}, },
"replying_to": "Válasz {0}-nak", "replying_to": "Válasz: {0}",
"show_full_thread": "Teljes szál megjelenítése", "show_full_thread": "Teljes szál megjelenítése",
"someone": "valaki", "someone": "valaki",
"spoiler_media_hidden": "Média elrejtve", "spoiler_media_hidden": "Média elrejtve",
@ -662,7 +669,7 @@
"report": "Jelentés", "report": "Jelentés",
"sign_up": "Feliratkozás" "sign_up": "Feliratkozás"
}, },
"notifications_all": "Összes értesítés", "notifications_all": "Összes",
"notifications_favourite": "Kedvencek", "notifications_favourite": "Kedvencek",
"notifications_follow": "Követés", "notifications_follow": "Követés",
"notifications_follow_request": "Követés kérése", "notifications_follow_request": "Követés kérése",
@ -682,7 +689,7 @@
"unfollow_label": "Követés vége {0} címke" "unfollow_label": "Követés vége {0} címke"
}, },
"time_ago_options": { "time_ago_options": {
"day_future": "in 0 nap múlva|holnap|{n} napon belül", "day_future": "0 nap múlva|holnap|{n} napon belül",
"day_past": "0 napja|tegnap|{n} nappal korábban", "day_past": "0 napja|tegnap|{n} nappal korábban",
"hour_future": "0 órá múlva|1 óra múlva|{n} óra múlva", "hour_future": "0 órá múlva|1 óra múlva|{n} óra múlva",
"hour_past": "0 órája|1 órája|{n} órája", "hour_past": "0 órája|1 órája|{n} órája",
@ -714,7 +721,7 @@
}, },
"timeline": { "timeline": {
"no_posts": "Itt nincsenek bejegyzések.", "no_posts": "Itt nincsenek bejegyzések.",
"show_new_items": "{v} új elem megjelenítése|{v} új elem megjelenítése|{v} új elem megjelenítése", "show_new_items": "{v} új elemek megjelenítése|{v} új elemek megjelenítése|{v} új elemek megjelenítése",
"view_older_posts": "Előfordulhat, hogy más instancekről származó régebbi bejegyzések nem jelennek meg." "view_older_posts": "Előfordulhat, hogy más instancekről származó régebbi bejegyzések nem jelennek meg."
}, },
"title": { "title": {
@ -739,18 +746,18 @@
"remove_thread_item": "Elem eltávolítása a szálból", "remove_thread_item": "Elem eltávolítása a szálból",
"start_thread": "Szál megkezdése", "start_thread": "Szál megkezdése",
"toggle_bold": "Váltás félkövérre", "toggle_bold": "Váltás félkövérre",
"toggle_code_block": "Kódblokk váltása", "toggle_code_block": "Kód blokkra váltás",
"toggle_italic": "Váltás dőltbetűssé" "toggle_italic": "Váltás dőlt betűsre"
}, },
"user": { "user": {
"add_existing": "Egy látező fiók hozzáadása", "add_existing": "Egy létező fiók hozzáadása",
"server_address_label": "Mastodon szerver címe", "server_address_label": "Mastodon szerver címe",
"sign_in_desc": "Jelentkezzen be profilok vagy címkék követéséhez, kedvencekhez, bejegyzések megosztásához és megválaszolásához, vagy egy másik szerveren lévő fiókjából való interakcióhoz.", "sign_in_desc": "Jelentkezzen be profilok vagy címkék követéséhez, kedvencekhez, bejegyzések megosztásához és megválaszolásához, vagy egy másik szerveren lévő fiókjából való interakcióhoz.",
"sign_in_notice_title": "{0} nyilvános adat megtekintése", "sign_in_notice_title": "{0} nyilvános adatok megtekintése",
"sign_out_account": "Kijelentkezés {0}", "sign_out_account": "Kijelentkezés {0}",
"single_instance_sign_in_desc": "Jelentkezzen be profilok vagy címkék követéséhez, kedvencei közé, bejegyzések megosztásához és megválaszolásához.", "single_instance_sign_in_desc": "Jelentkezzen be profilok vagy címkék követéséhez, kedvencei közé, bejegyzések megosztásához és megválaszolásához.",
"tip_no_account": "Ha még nincs Mastodon fiókod: {0}.", "tip_no_account": "Ha még nincs Mastodon fiókod: {0}.",
"tip_register_account": "válassz egy szervert és regisztrált egyet" "tip_register_account": "válassz egy szervert és regisztrálj egyet"
}, },
"visibility": { "visibility": {
"direct": "Direkt", "direct": "Direkt",

View file

@ -55,9 +55,9 @@
"apply": "Applica", "apply": "Applica",
"bookmark": "Aggiungi ai segnalibri", "bookmark": "Aggiungi ai segnalibri",
"bookmarked": "Aggiunto ai segnalibri", "bookmarked": "Aggiunto ai segnalibri",
"boost": "Potenzia", "boost": "Reblogga",
"boost_count": "{0}", "boost_count": "{0}",
"boosted": "Potenziato", "boosted": "Rebloggato",
"clear": "Cancella", "clear": "Cancella",
"clear_publish_failed": "Cancella errori di pubblicazione", "clear_publish_failed": "Cancella errori di pubblicazione",
"clear_save_failed": "Cancella errori di salvataggio", "clear_save_failed": "Cancella errori di salvataggio",
@ -163,8 +163,8 @@
"show_reblogs": { "show_reblogs": {
"cancel": "Annulla", "cancel": "Annulla",
"confirm": "Mostra", "confirm": "Mostra",
"description": "Mostrare i post potenziati da {0}?", "description": "Mostrare i post rebloggati da {0}?",
"title": "Mostra potenziamenti" "title": "Mostra reblog"
}, },
"unfollow": { "unfollow": {
"cancel": "Annulla", "cancel": "Annulla",
@ -226,13 +226,15 @@
"manage": "Gestisci liste", "manage": "Gestisci liste",
"modify_account": "Modifica liste con account", "modify_account": "Modifica liste con account",
"remove_account": "Rimuovi account dalla lista", "remove_account": "Rimuovi account dalla lista",
"save": "Salva modifiche" "save": "Salva modifiche",
"search_following_desc": "Cerca le persone che segui",
"search_following_placeholder": "Cerca fra le persone che segui"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Scorciatoie da tastiera", "dialog_header": "Scorciatoie da tastiera",
"groups": { "groups": {
"actions": { "actions": {
"boost": "Potenzia", "boost": "Reblogga",
"command_mode": "Modalità comando", "command_mode": "Modalità comando",
"compose": "Componi", "compose": "Componi",
"favourite": "Apprezza", "favourite": "Apprezza",
@ -274,7 +276,7 @@
"delete_and_redraft": "Elimina e riscrivi", "delete_and_redraft": "Elimina e riscrivi",
"direct_message_account": "Scrivi in privato a {0}", "direct_message_account": "Scrivi in privato a {0}",
"edit": "Modifica", "edit": "Modifica",
"hide_reblogs": "Nascondi potenziamenti da {0}", "hide_reblogs": "Nascondi reblog da {0}",
"mention_account": "Menziona {0}", "mention_account": "Menziona {0}",
"mute_account": "Silenzia {0}", "mute_account": "Silenzia {0}",
"mute_conversation": "Silenzia questo post", "mute_conversation": "Silenzia questo post",
@ -284,8 +286,8 @@
"report_account": "Segnala {0}", "report_account": "Segnala {0}",
"share_account": "Condividi {0}", "share_account": "Condividi {0}",
"share_post": "Condividi questo post", "share_post": "Condividi questo post",
"show_favourited_and_boosted_by": "Mostra chi ha apprezzato e potenziato", "show_favourited_and_boosted_by": "Mostra chi ha apprezzato e rebloggato",
"show_reblogs": "Mostra potenziamenti da {0}", "show_reblogs": "Mostra reblog da {0}",
"show_untranslated": "Mostra versione originale", "show_untranslated": "Mostra versione originale",
"toggle_theme": { "toggle_theme": {
"dark": "Usa aspetto scuro", "dark": "Usa aspetto scuro",
@ -334,11 +336,13 @@
"zen_mode": "Modalità zen" "zen_mode": "Modalità zen"
}, },
"notification": { "notification": {
"and": "e",
"favourited_post": "ha apprezzato il tuo post", "favourited_post": "ha apprezzato il tuo post",
"followed_you": "ti ha iniziato a seguire", "followed_you": "ti ha iniziato a seguire",
"followed_you_count": "{0} persone ti hanno cominciato a seguire|{0} persona ti ha cominciato a seguire|{0} persone ti hanno cominciato a seguire", "followed_you_count": "{0} persone ti hanno cominciato a seguire|{0} persona ti ha cominciato a seguire|{0} persone ti hanno cominciato a seguire",
"missing_type": "notification.type MANCANTE:", "missing_type": "notification.type MANCANTE:",
"reblogged_post": "ha potenziato il tuo post", "others": "{0} altri|{0} altro|{0} altri",
"reblogged_post": "ha rebloggato il tuo post",
"reported": "{0} ha segnalato {1}", "reported": "{0} ha segnalato {1}",
"request_to_follow": "ti ha chiesto di seguirti", "request_to_follow": "ti ha chiesto di seguirti",
"signed_up": "ha effettuato l'iscrizione", "signed_up": "ha effettuato l'iscrizione",
@ -490,7 +494,7 @@
"follow": "Nuovi seguaci", "follow": "Nuovi seguaci",
"mention": "Menzioni", "mention": "Menzioni",
"poll": "Risultati dei sondaggi", "poll": "Risultati dei sondaggi",
"reblog": "Potenziamenti", "reblog": "Reblog",
"title": "Quali notifiche vuoi ricevere?" "title": "Quali notifiche vuoi ricevere?"
}, },
"description": "Ricevi notifiche anche quando non stai utilizzando Elk.", "description": "Ricevi notifiche anche quando non stai utilizzando Elk.",
@ -542,11 +546,11 @@
"enable_data_saving_description": "Risparmia dati disattivando il download automatico degli allegati.", "enable_data_saving_description": "Risparmia dati disattivando il download automatico degli allegati.",
"enable_pinch_to_zoom": "Pizzica per ingrandire", "enable_pinch_to_zoom": "Pizzica per ingrandire",
"github_cards": "GitHub Cards", "github_cards": "GitHub Cards",
"github_cards_description": "Quando viene pubblicato un link GitHub, viene mostrato un riquadro HTML accessibile usando i metadati del grafico sociale invece dell'immmagine.", "github_cards_description": "Quando viene pubblicato un link GitHub, viene mostrato un riquadro HTML accessibile usando i metadati del grafico sociale invece dell'immagine.",
"grayscale_mode": "Modalità scala di grigi", "grayscale_mode": "Modalità scala di grigi",
"hide_account_hover_card": "Nascondi anteprima profilo al passaggio del mouse", "hide_account_hover_card": "Nascondi anteprima profilo al passaggio del mouse",
"hide_alt_indi_on_posts": "Nascondi indicatore testo alternativo sui post", "hide_alt_indi_on_posts": "Nascondi indicatore testo alternativo sui post",
"hide_boost_count": "Nascondi contatore potenziamenti", "hide_boost_count": "Nascondi contatore reblog",
"hide_favorite_count": "Nascondi contatore apprezzamenti", "hide_favorite_count": "Nascondi contatore apprezzamenti",
"hide_follower_count": "Nascondi contatore seguaci/seguiti", "hide_follower_count": "Nascondi contatore seguaci/seguiti",
"hide_gif_indi_on_posts": "Nascondi indicatore gif sui post", "hide_gif_indi_on_posts": "Nascondi indicatore gif sui post",
@ -559,6 +563,7 @@
"label": "Preferenze", "label": "Preferenze",
"optimize_for_low_performance_device": "Ottimizza per dispositivi a basse prestazioni", "optimize_for_low_performance_device": "Ottimizza per dispositivi a basse prestazioni",
"title": "Funzionalità sperimentali", "title": "Funzionalità sperimentali",
"unmute_videos": "Riproduci video con volume attivo di default",
"use_star_favorite_icon": "Usa icona stella per apprezzamenti", "use_star_favorite_icon": "Usa icona stella per apprezzamenti",
"user_picker": "Selettore utente", "user_picker": "Selettore utente",
"user_picker_description": "Mostra gli avatar di tutti gli account connessi in basso a sinistra così da poter cambiare account in un attimo.", "user_picker_description": "Mostra gli avatar di tutti gli account connessi in basso a sinistra così da poter cambiare account in un attimo.",
@ -620,7 +625,7 @@
"suspended_message": "L'account di questo post è stato sospeso.", "suspended_message": "L'account di questo post è stato sospeso.",
"suspended_show": "Mostra comunque contenuto?" "suspended_show": "Mostra comunque contenuto?"
}, },
"boosted_by": "Potenziato da", "boosted_by": "Rebloggato da",
"edited": "Modificato {0}", "edited": "Modificato {0}",
"embedded_warning": "La riproduzione di questo contenuto potrebbe rivelare il tuo indirizzo IP ad altri.", "embedded_warning": "La riproduzione di questo contenuto potrebbe rivelare il tuo indirizzo IP ad altri.",
"favourited_by": "Apprezzato da", "favourited_by": "Apprezzato da",
@ -637,7 +642,8 @@
"poll": { "poll": {
"count": "{0} voti|{0} voto|{0} voti", "count": "{0} voti|{0} voto|{0} voti",
"ends": "termina {0}", "ends": "termina {0}",
"finished": "terminato {0}" "finished": "terminato {0}",
"update": "Aggiorna sondaggio"
}, },
"replying_to": "In risposta a {0}", "replying_to": "In risposta a {0}",
"show_full_thread": "Mostra discussione", "show_full_thread": "Mostra discussione",
@ -670,7 +676,7 @@
"notifications_mention": "Menzioni", "notifications_mention": "Menzioni",
"notifications_more_tooltip": "Filtra notifiche per tipo", "notifications_more_tooltip": "Filtra notifiche per tipo",
"notifications_poll": "Sondaggio", "notifications_poll": "Sondaggio",
"notifications_reblog": "Potenziamento", "notifications_reblog": "Reblog",
"notifications_status": "Stato", "notifications_status": "Stato",
"notifications_update": "Aggiornamento", "notifications_update": "Aggiornamento",
"posts": "Post", "posts": "Post",
@ -747,7 +753,7 @@
"add_existing": "Aggiungi account esistente", "add_existing": "Aggiungi account esistente",
"server_address_label": "Indirizzo istanza Mastodon", "server_address_label": "Indirizzo istanza Mastodon",
"sign_in_desc": "Accedi per seguire profili o hashtag, apprezzare, condividere e rispondere a post o interagire dal tuo account su un'altra istanza.", "sign_in_desc": "Accedi per seguire profili o hashtag, apprezzare, condividere e rispondere a post o interagire dal tuo account su un'altra istanza.",
"sign_in_notice_title": "Visualizzando {0} dati pubblici", "sign_in_notice_title": "Visualizzando i dati pubblici di {0}",
"sign_out_account": "Esci {0}", "sign_out_account": "Esci {0}",
"single_instance_sign_in_desc": "Accedi per seguire profili o hastag, apprezzare condividere o rispondere a post.", "single_instance_sign_in_desc": "Accedi per seguire profili o hastag, apprezzare condividere o rispondere a post.",
"tip_no_account": "Se ancora non hai un account Mastodon, {0}.", "tip_no_account": "Se ancora non hai un account Mastodon, {0}.",

View file

@ -7,6 +7,8 @@
"route_loaded": "ページ{0}を読み込みました" "route_loaded": "ページ{0}を読み込みました"
}, },
"account": { "account": {
"authorize": "フォローを承認",
"authorized": "リクエストを承認しました",
"avatar_description": "{0}さんのアバター", "avatar_description": "{0}さんのアバター",
"blocked_by": "あなたはこのユーザーからブロックされています。", "blocked_by": "あなたはこのユーザーからブロックされています。",
"blocked_domains": "ブロックしたドメイン", "blocked_domains": "ブロックしたドメイン",
@ -38,7 +40,10 @@
"profile_description": "{0}さんのプロフィールヘッダー", "profile_description": "{0}さんのプロフィールヘッダー",
"profile_personal_note": "個人メモ", "profile_personal_note": "個人メモ",
"profile_unavailable": "プロフィールが利用できません", "profile_unavailable": "プロフィールが利用できません",
"reject": "フォローを拒否",
"rejected": "リクエストを拒否しました",
"request_follow": "フォローをリクエスト", "request_follow": "フォローをリクエスト",
"requested": "{0}さんがフォローをリクエストしました",
"unblock": "ブロック解除", "unblock": "ブロック解除",
"unfollow": "フォロー解除", "unfollow": "フォロー解除",
"unmute": "ミュート解除", "unmute": "ミュート解除",
@ -53,6 +58,7 @@
"boost": "ブースト", "boost": "ブースト",
"boost_count": "{0}", "boost_count": "{0}",
"boosted": "ブースト済み", "boosted": "ブースト済み",
"clear": "クリア",
"clear_publish_failed": "投稿エラーをクリア", "clear_publish_failed": "投稿エラーをクリア",
"clear_save_failed": "保存エラーをクリア", "clear_save_failed": "保存エラーをクリア",
"clear_upload_failed": "ファイルアップロードエラーをクリア", "clear_upload_failed": "ファイルアップロードエラーをクリア",
@ -67,8 +73,10 @@
"favourited": "お気に入り済み", "favourited": "お気に入り済み",
"more": "さらに表示", "more": "さらに表示",
"next": "次へ", "next": "次へ",
"open_image_preview_dialog": "画像をプレビューダイアログで開く",
"prev": "前へ", "prev": "前へ",
"publish": "投稿", "publish": "投稿",
"publish_thread": "スレッドを投稿",
"reply": "返信", "reply": "返信",
"reply_count": "{0}", "reply_count": "{0}",
"reset": "リセット", "reset": "リセット",
@ -116,12 +124,14 @@
"block_account": { "block_account": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "ブロック", "confirm": "ブロック",
"description": "{0}さんを本当にミュートしますか?" "description": "{0}さんを本当にミュートしますか?",
"title": "アカウントのブロック"
}, },
"block_domain": { "block_domain": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "ブロック", "confirm": "ブロック",
"description": "{0}さんを本当にブロックしますか?" "description": "{0}さんを本当にブロックしますか?",
"title": "ドメインのブロック"
}, },
"common": { "common": {
"cancel": "いいえ", "cancel": "いいえ",
@ -130,27 +140,37 @@
"delete_list": { "delete_list": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "削除", "confirm": "削除",
"description": "リスト \"{0}\" を本当に削除しますか?" "description": "リスト \"{0}\" を本当に削除しますか?",
"title": "リストの削除"
}, },
"delete_posts": { "delete_posts": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "削除", "confirm": "削除",
"description": "この投稿を本当に削除しますか?" "description": "この投稿を本当に削除しますか?",
"title": "投稿の削除"
}, },
"mute_account": { "mute_account": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "ミュート", "confirm": "ミュート",
"description": "{0}さんを本当にミュートしますか?" "days": "日",
"description": "{0}さんを本当にミュートしますか?",
"hours": "時間",
"minute": "分",
"notifications": "通知をミュートする",
"specify_duration": "ミュート期間を指定する",
"title": "アカウントのミュート"
}, },
"show_reblogs": { "show_reblogs": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "表示", "confirm": "表示",
"description": "{0}さんのブーストを本当に表示しますか?" "description": "{0}さんのブーストを本当に表示しますか?",
"title": "ブーストの表示"
}, },
"unfollow": { "unfollow": {
"cancel": "キャンセル", "cancel": "キャンセル",
"confirm": "フォロー解除", "confirm": "フォロー解除",
"description": "本当にフォローを解除しますか?" "description": "本当にフォローを解除しますか?",
"title": "フォロー解除"
} }
}, },
"conversation": { "conversation": {
@ -203,6 +223,7 @@
"error": "リストの作成中にエラーが発生しました", "error": "リストの作成中にエラーが発生しました",
"error_prefix": "エラー: ", "error_prefix": "エラー: ",
"list_title_placeholder": "リストのタイトル", "list_title_placeholder": "リストのタイトル",
"manage": "リストを管理",
"modify_account": "このアカウントでリストを編集", "modify_account": "このアカウントでリストを編集",
"remove_account": "アカウントをリストから削除", "remove_account": "アカウントをリストから削除",
"save": "変更を保存" "save": "変更を保存"
@ -216,14 +237,25 @@
"compose": "投稿", "compose": "投稿",
"favourite": "お気に入り", "favourite": "お気に入り",
"search": "検索", "search": "検索",
"show_new_items": "新しいアイテムを表示",
"title": "アクション" "title": "アクション"
}, },
"media": { "media": {
"title": "メディア" "title": "メディア"
}, },
"navigation": { "navigation": {
"go_to_bookmarks": "ブックマーク",
"go_to_conversations": "会話",
"go_to_explore": "話題の投稿",
"go_to_favourites": "お気に入り",
"go_to_federated": "連合",
"go_to_home": "ホーム", "go_to_home": "ホーム",
"go_to_lists": "リスト",
"go_to_local": "ローカル",
"go_to_notifications": "通知", "go_to_notifications": "通知",
"go_to_profile": "プロフィール",
"go_to_search": "検索",
"go_to_settings": "設定",
"next_status": "次の投稿", "next_status": "次の投稿",
"previous_status": "前の投稿", "previous_status": "前の投稿",
"shortcut_help": "ショートカットのヘルプ", "shortcut_help": "ショートカットのヘルプ",
@ -278,13 +310,16 @@
"built_at": "ビルド {0}", "built_at": "ビルド {0}",
"compose": "投稿", "compose": "投稿",
"conversations": "会話", "conversations": "会話",
"docs": "ドキュメント",
"explore": "話題の投稿", "explore": "話題の投稿",
"favourites": "お気に入り", "favourites": "お気に入り",
"federated": "連合", "federated": "連合",
"hashtags": "ハッシュタグ",
"home": "ホーム", "home": "ホーム",
"list": "リスト", "list": "リスト",
"lists": "リスト", "lists": "リスト",
"local": "ローカル", "local": "ローカル",
"more_menu": "その他のメニュー",
"muted_users": "ミュートしたユーザー", "muted_users": "ミュートしたユーザー",
"notifications": "通知", "notifications": "通知",
"privacy": "プライバシー", "privacy": "プライバシー",
@ -419,6 +454,8 @@
"label": "アカウント設定" "label": "アカウント設定"
}, },
"interface": { "interface": {
"bottom_nav": "下部ナビゲーション",
"bottom_nav_instructions": "下部ナビゲーションに表示するお気に入りのナビゲーションボタンを5つまで選択してください。「その他のメニュー」ボタンは必ず含める必要があります。",
"color_mode": "カラーモード", "color_mode": "カラーモード",
"dark_mode": "ダークモード", "dark_mode": "ダークモード",
"default": " (デフォルト)", "default": " (デフォルト)",
@ -430,6 +467,7 @@
}, },
"language": { "language": {
"display_language": "表示言語", "display_language": "表示言語",
"how_to_contribute": "貢献するには?",
"label": "言語", "label": "言語",
"post_language": "投稿言語", "post_language": "投稿言語",
"status": "翻訳状況: {0}/{1} ({2}%)", "status": "翻訳状況: {0}/{1} ({2}%)",
@ -474,7 +512,7 @@
"repo_link": "ElkのGitHubリポジトリ", "repo_link": "ElkのGitHubリポジトリ",
"request_error": "登録のリクエスト中にエラーが発生しました。再試行してもエラーが解消しない場合、Elkリポジトリにissueを報告してください。", "request_error": "登録のリクエスト中にエラーが発生しました。再試行してもエラーが解消しない場合、Elkリポジトリにissueを報告してください。",
"title": "プッシュ通知を登録できませんでした", "title": "プッシュ通知を登録できませんでした",
"too_many_registrations": "ブラウザの制限により、Elkは異なるサーバー上の複数アカウントに対してプッシュ通知サービスを使用できません。他のアカウントのプッシュ通知の登録を解除して、再登録する必要があります。", "too_many_registrations": "ブラウザの制限により、Elkは異なるサーバー上の複数アカウントに対してプッシュ通知サービスを使用できません。他のアカウントのプッシュ通知の登録を解除して、再登録する必要があります。",
"vapid_not_supported": "このブラウザはWeb Push通知をサポートしていませんが、VAPIDプロトコルをサポートしているようです。" "vapid_not_supported": "このブラウザはWeb Push通知をサポートしていませんが、VAPIDプロトコルをサポートしているようです。"
}, },
"title": "プッシュ通知の設定", "title": "プッシュ通知の設定",
@ -497,6 +535,8 @@
}, },
"notifications_settings": "通知", "notifications_settings": "通知",
"preferences": { "preferences": {
"embedded_media": "埋め込みメディアプレイヤー",
"embedded_media_description": "メディアストリーミングの共有リンクを展開する際に、通常のプレビューカードではなく埋め込みメディアプレイヤーを表示します。",
"enable_autoplay": "自動再生を有効化", "enable_autoplay": "自動再生を有効化",
"enable_data_saving": "データセーバーを有効にする", "enable_data_saving": "データセーバーを有効にする",
"enable_data_saving_description": "添付の自動読み込みを防止してデータを節約します。", "enable_data_saving_description": "添付の自動読み込みを防止してデータを節約します。",
@ -505,12 +545,14 @@
"github_cards_description": "GitHubリンクが投稿されたとき、ソーシャル画像の代わりにソーシャルグラフのメタデータを使用してアクセシブルなHTMLカードを表示します。", "github_cards_description": "GitHubリンクが投稿されたとき、ソーシャル画像の代わりにソーシャルグラフのメタデータを使用してアクセシブルなHTMLカードを表示します。",
"grayscale_mode": "グレースケールモード", "grayscale_mode": "グレースケールモード",
"hide_account_hover_card": "アカウントのホバーカードを隠す", "hide_account_hover_card": "アカウントのホバーカードを隠す",
"hide_alt_indi_on_posts": "投稿上のalt表示を隠す", "hide_alt_indi_on_posts": "投稿上のALTを隠す",
"hide_boost_count": "ブーストの数を隠す", "hide_boost_count": "ブーストの数を隠す",
"hide_favorite_count": "お気に入りの数を隠す", "hide_favorite_count": "お気に入りの数を隠す",
"hide_follower_count": "フォロワーの数を隠す", "hide_follower_count": "フォロワーの数を隠す",
"hide_gif_indi_on_posts": "投稿上のGIF表示を隠す",
"hide_news": "ニュースを隠す", "hide_news": "ニュースを隠す",
"hide_reply_count": "リプライの数を隠す", "hide_reply_count": "リプライの数を隠す",
"hide_tag_hover_card": "タグのホバーカードを隠す",
"hide_translation": "翻訳を隠す", "hide_translation": "翻訳を隠す",
"hide_username_emojis": "ユーザー名の絵文字を隠す", "hide_username_emojis": "ユーザー名の絵文字を隠す",
"hide_username_emojis_description": "タイムライン上でユーザー名に含まれる絵文字を隠します。プロフィールでは絵文字は引き続き表示されます。", "hide_username_emojis_description": "タイムライン上でユーザー名に含まれる絵文字を隠します。プロフィールでは絵文字は引き続き表示されます。",
@ -559,7 +601,11 @@
}, },
"state": { "state": {
"attachments_exceed_server_limit": "添付の数が投稿ごとの上限を超えています。", "attachments_exceed_server_limit": "添付の数が投稿ごとの上限を超えています。",
"attachments_limit_audio_error": "音声の最大サイズを超えています: {0}",
"attachments_limit_error": "投稿ごとの上限を超えています", "attachments_limit_error": "投稿ごとの上限を超えています",
"attachments_limit_image_error": "画像の最大サイズを超えています: {0}",
"attachments_limit_unknown_error": "ファイルの最大サイズを超えています: {0}",
"attachments_limit_video_error": "動画の最大サイズを超えています: {0}",
"edited": "(編集済み)", "edited": "(編集済み)",
"editing": "編集中", "editing": "編集中",
"loading": "読込中...", "loading": "読込中...",
@ -576,15 +622,18 @@
}, },
"boosted_by": "ブーストしたユーザー", "boosted_by": "ブーストしたユーザー",
"edited": "編集済み {0}", "edited": "編集済み {0}",
"embedded_warning": "再生するとあなたのIPアドレスがサードパーティに知られる可能性があります。",
"favourited_by": "お気に入りしたユーザー", "favourited_by": "お気に入りしたユーザー",
"filter_hidden_phrase": "フィルター", "filter_hidden_phrase": "フィルター",
"filter_show_anyway": "とにかく表示", "filter_show_anyway": "とにかく表示",
"gif": "GIF",
"img_alt": { "img_alt": {
"ALT": "ALT", "ALT": "ALT",
"desc": "説明文", "desc": "説明文",
"dismiss": "閉じる", "dismiss": "閉じる",
"read": "{0} の説明文を読む" "read": "{0} の説明文を読む"
}, },
"pinned": "固定された投稿",
"poll": { "poll": {
"count": "{0} 票", "count": "{0} 票",
"ends": "{0}に終了", "ends": "{0}に終了",
@ -665,6 +714,7 @@
"year_past": "0年前|去年|{n}年前" "year_past": "0年前|去年|{n}年前"
}, },
"timeline": { "timeline": {
"no_posts": "ここには投稿がありません!",
"show_new_items": "{v}件の新しい投稿", "show_new_items": "{v}件の新しい投稿",
"view_older_posts": "他のインスタンスの古い投稿は表示されないことがあります。" "view_older_posts": "他のインスタンスの古い投稿は表示されないことがあります。"
}, },
@ -677,6 +727,7 @@
"add_emojis": "絵文字を追加", "add_emojis": "絵文字を追加",
"add_media": "画像、動画、音声ファイルを追加", "add_media": "画像、動画、音声ファイルを追加",
"add_publishable_content": "公開するコンテンツを追加", "add_publishable_content": "公開するコンテンツを追加",
"add_thread_item": "投稿をスレッドに追加",
"change_content_visibility": "公開範囲を変更", "change_content_visibility": "公開範囲を変更",
"change_language": "言語を変更", "change_language": "言語を変更",
"emoji": "絵文字", "emoji": "絵文字",
@ -686,6 +737,8 @@
"open_editor_tools": "エディタツール", "open_editor_tools": "エディタツール",
"pick_an_icon": "アイコンの選択", "pick_an_icon": "アイコンの選択",
"publish_failed": "投稿の再公開時にエディタ上部のエラーメッセージを閉じる", "publish_failed": "投稿の再公開時にエディタ上部のエラーメッセージを閉じる",
"remove_thread_item": "投稿をスレッドから削除",
"start_thread": "スレッドを開始",
"toggle_bold": "太字", "toggle_bold": "太字",
"toggle_code_block": "コードブロック", "toggle_code_block": "コードブロック",
"toggle_italic": "斜体" "toggle_italic": "斜体"

View file

@ -7,6 +7,8 @@
"route_loaded": "Pagina {0} geladen" "route_loaded": "Pagina {0} geladen"
}, },
"account": { "account": {
"authorize": "Autoriseer",
"authorized": "Geautoriseerd",
"avatar_description": "{0}'s avatar", "avatar_description": "{0}'s avatar",
"blocked_by": "Je bent geblokkeerd door deze gebruiker.", "blocked_by": "Je bent geblokkeerd door deze gebruiker.",
"blocked_domains": "Geblokkeerde domeinen", "blocked_domains": "Geblokkeerde domeinen",
@ -25,6 +27,7 @@
"follows_you": "Volgt jou", "follows_you": "Volgt jou",
"go_to_profile": "Ga naar profiel", "go_to_profile": "Ga naar profiel",
"joined": "Lid geworden", "joined": "Lid geworden",
"lock": "Gesloten account",
"moved_title": "heeft het account verplaatst naar:", "moved_title": "heeft het account verplaatst naar:",
"muted_users": "Gedempte gebruikers", "muted_users": "Gedempte gebruikers",
"muting": "Gedempt", "muting": "Gedempt",
@ -37,12 +40,16 @@
"profile_description": "{0}'s profiel koptekst", "profile_description": "{0}'s profiel koptekst",
"profile_personal_note": "Persoonlijke Nota", "profile_personal_note": "Persoonlijke Nota",
"profile_unavailable": "Profiel niet beschikbaar", "profile_unavailable": "Profiel niet beschikbaar",
"reject": "Weigeren",
"rejected": "Geweigerd",
"request_follow": "Verzoek om te volgen", "request_follow": "Verzoek om te volgen",
"requested": "{0} heeft je verzocht om je te volgen",
"unblock": "Deblokkeren", "unblock": "Deblokkeren",
"unfollow": "Ontvolgen", "unfollow": "Ontvolgen",
"unmute": "Ontdempen", "unmute": "Ontdempen",
"view_other_followers": "Volgers van andere servers worden mogelijk niet getoond.", "view_other_followers": "Volgers van andere servers worden mogelijk niet getoond.",
"view_other_following": "Volgend van andere servers worden mogelijk niet getoond." "view_other_following": "Volgend van andere servers worden mogelijk niet getoond.",
"withdraw_follow_request": "Volgverzoek Intrekken"
}, },
"action": { "action": {
"apply": "Toepassen", "apply": "Toepassen",
@ -51,10 +58,14 @@
"boost": "Boost", "boost": "Boost",
"boost_count": "{0}", "boost_count": "{0}",
"boosted": "Geboost", "boosted": "Geboost",
"clear": "Wissen",
"clear_publish_failed": "Wis publicatie fouten",
"clear_save_failed": "Wis opslaan fouten",
"clear_upload_failed": "Wis bestand upload fouten", "clear_upload_failed": "Wis bestand upload fouten",
"close": "Sluit", "close": "Sluiten",
"compose": "Schrijven", "compose": "Schrijven",
"confirm": "Bevestigen", "confirm": "Bevestigen",
"done": "Klaar",
"edit": "Aanpassen", "edit": "Aanpassen",
"enter_app": "Ga naar App", "enter_app": "Ga naar App",
"favourite": "Als favoriet opslaan", "favourite": "Als favoriet opslaan",
@ -62,16 +73,19 @@
"favourited": "Als favoriet opgeslagen", "favourited": "Als favoriet opgeslagen",
"more": "Meer", "more": "Meer",
"next": "Volgende", "next": "Volgende",
"open_image_preview_dialog": "Open afbeelding voorbeeld dialoog",
"prev": "Vorige", "prev": "Vorige",
"publish": "Publiceer", "publish": "Publiceren",
"reply": "Beantwoord", "publish_thread": "Draadje publiceren",
"reply": "Beantwoorden",
"reply_count": "{0}", "reply_count": "{0}",
"reset": "Herstellen", "reset": "Herstellen",
"save": "Opslaan", "save": "Opslaan",
"save_changes": "Aanpassingen opslaan", "save_changes": "Aanpassingen opslaan",
"sign_in": "Inloggen", "sign_in": "Inloggen",
"sign_in_to": "Inloggen bij {0}",
"switch_account": "Wissel van account", "switch_account": "Wissel van account",
"vote": "Stem" "vote": "Stemmen"
}, },
"app_desc_short": "Een vlotte Mastodon web client", "app_desc_short": "Een vlotte Mastodon web client",
"app_logo": "Elk Logo", "app_logo": "Elk Logo",
@ -95,13 +109,80 @@
"common": { "common": {
"end_of_list": "Einde van de lijst", "end_of_list": "Einde van de lijst",
"error": "FOUT", "error": "FOUT",
"fetching": "Ophalen...",
"in": "in", "in": "in",
"no_bookmarks": "Geen bladwijzers",
"no_favourites": "Geen favorieten",
"not_found": "404 Niet Gevonden", "not_found": "404 Niet Gevonden",
"offline_desc": "Zo te zien ben je offline. Controleer je internet verbinding." "offline_desc": "Zo te zien ben je offline. Controleer je internet verbinding."
}, },
"compose": {
"drafs": "Concepten",
"draft_title": "Concept"
},
"confirm": {
"block_account": {
"cancel": "Annuleren",
"confirm": "Blokkeer",
"description": "Weet je zeker dat je {0} wilt blokkeren?",
"title": "Blokkeer account"
},
"block_domain": {
"cancel": "Annuleren",
"confirm": "Blokkeer",
"description": "Weet je zeker dat je {0} wilt blokkeren?",
"title": "Blokkeer domein"
},
"common": {
"cancel": "Nee",
"confirm": "Ja"
},
"delete_list": {
"cancel": "Annuleren",
"confirm": "Verwijderen",
"description": "Weet je zeker dat je de lijst '{0}' wilt verwijderen?",
"title": "Verwijder lijst"
},
"delete_posts": {
"cancel": "Annuleren",
"confirm": "Verwijderen",
"description": "Weet je zeker dat je deze post wilt verwijderen?",
"title": "Verwijder post"
},
"mute_account": {
"cancel": "Annuleren",
"confirm": "Demp",
"days": "dagen|dag|dagen",
"description": "Weet je zeker dat je {0} wilt dempen?",
"hours": "uren|uur|uren",
"minute": "minuten|minuut|minuten",
"notifications": "Demp meldingen",
"specify_duration": "Specificeer duur",
"title": "Demp account"
},
"show_reblogs": {
"cancel": "Annuleren",
"confirm": "Toon boosts",
"description": "Weet je zeker dat je alle boosts van deze post wilt tonen?",
"title": "Toon boosts"
},
"unfollow": {
"cancel": "Annuleren",
"confirm": "Ontvolgen",
"description": "Weet je zeker dat je {0} wilt ontvolgen?",
"title": "Ontvolgen"
}
},
"conversation": { "conversation": {
"with": "met" "with": "met"
}, },
"custom_cards": {
"stackblitz": {
"lines": "Regels {0}",
"open": "Openen",
"snippet_from": "Snippet van {0}"
}
},
"error": { "error": {
"account_not_found": "Account {0} niet gevonden", "account_not_found": "Account {0} niet gevonden",
"explore_list_empty": "Er is nu niets trending. Kom later terug!", "explore_list_empty": "Er is nu niets trending. Kom later terug!",
@ -111,6 +192,12 @@
"unsupported_file_format": "Bestandstype niet ondersteund" "unsupported_file_format": "Bestandstype niet ondersteund"
}, },
"help": { "help": {
"build_preview": {
"desc1": "Je bekijkt momenteel een voorlopige versie van Elk van de community. - {0}",
"desc2": "Het kan ongecontroleerde of zelfs kwaadaardige wijzigingen bevatten.",
"desc3": "Log niet in met je echte account.",
"title": "Preview versie"
},
"desc_highlight": "Je kunt hier en daar wat bugs of ontbrekende features verwachten.", "desc_highlight": "Je kunt hier en daar wat bugs of ontbrekende features verwachten.",
"desc_para1": "Bedankt voor je interesse in het uitproberen van Elk, onze Mastodon web client in-wording!", "desc_para1": "Bedankt voor je interesse in het uitproberen van Elk, onze Mastodon web client in-wording!",
"desc_para2": "we werken hard aan nieuwe ontwikkelingen en verbeteringen in de loop van de tijd.", "desc_para2": "we werken hard aan nieuwe ontwikkelingen en verbeteringen in de loop van de tijd.",
@ -118,25 +205,87 @@
"desc_para4": "Elk is Open Source. Wil je meehelpen met testen, feedback of bijdragen,", "desc_para4": "Elk is Open Source. Wil je meehelpen met testen, feedback of bijdragen,",
"desc_para5": "zoek ons op via GitHub", "desc_para5": "zoek ons op via GitHub",
"desc_para6": "en doe met ons mee.", "desc_para6": "en doe met ons mee.",
"footer_team": "Het Elk Team",
"title": "Elk is in Preview!" "title": "Elk is in Preview!"
}, },
"language": { "language": {
"search": "Opzoeken" "search": "Opzoeken"
}, },
"list": {
"add_account": "Voeg account toe",
"cancel_edit": "Annuleren",
"clear_error": "Wis error",
"create": "Toevoegen",
"delete": "Verwijderen",
"delete_error": "Verwijder fout",
"edit": "Aanpassen",
"edit_error": "Aanpassen fout",
"error": "Fout",
"error_prefix": "Fout:",
"list_title_placeholder": "Titel",
"manage": "Beheer",
"modify_account": "Pas account aan",
"remove_account": "Verwijder account",
"save": "Opslaan"
},
"magic_keys": {
"dialog_header": "Sneltoetsen",
"groups": {
"actions": {
"boost": "Boost",
"command_mode": "Commando modus",
"compose": "Schrijven",
"favourite": "Favoriet",
"search": "Zoeken",
"show_new_items": "Toon nieuwe items",
"title": "Acties"
},
"media": {
"title": "Media"
},
"navigation": {
"go_to_bookmarks": "Ga naar bladwijzers",
"go_to_conversations": "Ga naar conversaties",
"go_to_explore": "Ga naar Ontdekken",
"go_to_favourites": "Ga naar favorieten",
"go_to_federated": "Ga naar Gefedereerd",
"go_to_home": "Ga naar Home",
"go_to_lists": "Ga naar lijsten",
"go_to_local": "Ga naar Lokaal",
"go_to_notifications": "Ga naar meldingen",
"go_to_profile": "Ga naar profiel",
"go_to_search": "Ga naar zoeken",
"go_to_settings": "Ga naar instellingen",
"next_status": "Volgende post",
"previous_status": "Vorige post",
"shortcut_help": "Sneltoetsen help",
"title": "Navigatie"
}
},
"sequence_then": "dan"
},
"menu": { "menu": {
"add_personal_note": "Voeg persoonlijke notitie toe",
"block_account": "Blokkeer {0}", "block_account": "Blokkeer {0}",
"block_domain": "Blokkeer domein {0}", "block_domain": "Blokkeer domein {0}",
"copy_link_to_post": "Kopieer link naar deze post", "copy_link_to_post": "Kopieer link naar deze post",
"copy_original_link_to_post": "Kopieer originele link naar deze post",
"delete": "Verwijder", "delete": "Verwijder",
"delete_and_redraft": "Verwijder & Opnieuw opstellen", "delete_and_redraft": "Verwijder & Opnieuw opstellen",
"direct_message_account": "Direct bericht naar {0}", "direct_message_account": "Direct bericht naar {0}",
"edit": "Aanpassen", "edit": "Aanpassen",
"hide_reblogs": "Verberg boosts",
"mention_account": "Noem {0}", "mention_account": "Noem {0}",
"mute_account": "Demp {0}", "mute_account": "Demp {0}",
"mute_conversation": "Demp deze post", "mute_conversation": "Demp deze post",
"open_in_original_site": "Open in originele site", "open_in_original_site": "Open in originele site",
"pin_on_profile": "Pin op profiel", "pin_on_profile": "Pin op profiel",
"remove_personal_note": "Verwijder persoonlijke notitie {0}",
"report_account": "Rapporteer {0}",
"share_account": "Deel {0}",
"share_post": "Deel deze post", "share_post": "Deel deze post",
"show_favourited_and_boosted_by": "Toon wie deze post leuk vindt en geboost heeft",
"show_reblogs": "Toon boosts",
"show_untranslated": "Laat onvertaalde versie zien", "show_untranslated": "Laat onvertaalde versie zien",
"toggle_theme": { "toggle_theme": {
"dark": "Donkere modus wisselen", "dark": "Donkere modus wisselen",
@ -145,20 +294,35 @@
"translate_post": "Vertaal post", "translate_post": "Vertaal post",
"unblock_account": "Deblokkeer {0}", "unblock_account": "Deblokkeer {0}",
"unblock_domain": "Deblokkeer domein {0}", "unblock_domain": "Deblokkeer domein {0}",
"unfollow_account": "Ontvolg {0}",
"unmute_account": "Ontdemp {0}", "unmute_account": "Ontdemp {0}",
"unmute_conversation": "Ontdemp deze post", "unmute_conversation": "Ontdemp deze post",
"unpin_on_profile": "Ontpin op profiel" "unpin_on_profile": "Ontpin op profiel"
}, },
"modals": {
"aria_label_close": "Sluiten"
},
"nav": { "nav": {
"bookmarks": "Bookmarks", "back": "Terug",
"blocked_domains": "Geblokkeerde domeinen",
"blocked_users": "Geblokkeerde gebruikers",
"bookmarks": "Bladwijzers",
"built_at": "Gebouwd {0}", "built_at": "Gebouwd {0}",
"compose": "Schrijven",
"conversations": "Conversaties", "conversations": "Conversaties",
"docs": "Documentatie",
"explore": "Ontdekken", "explore": "Ontdekken",
"favourites": "Favorieten", "favourites": "Favorieten",
"federated": "Gefedereerd", "federated": "Gefedereerd",
"hashtags": "Hashtags",
"home": "Home", "home": "Home",
"list": "Lijst",
"lists": "Lijsten",
"local": "Lokaal", "local": "Lokaal",
"more_menu": "Meer",
"muted_users": "Gedempte gebruikers",
"notifications": "Meldingen", "notifications": "Meldingen",
"privacy": "Privacy",
"profile": "Profiel", "profile": "Profiel",
"search": "Zoeken", "search": "Zoeken",
"select_feature_flags": "Selecteer Feature Vlaggen", "select_feature_flags": "Selecteer Feature Vlaggen",
@ -174,7 +338,8 @@
"followed_you": "volgt jou", "followed_you": "volgt jou",
"followed_you_count": "{0} mensen hebben je gevolgd|{0} persoon heeft je gevold|{0} mensen hebben je gevolgd", "followed_you_count": "{0} mensen hebben je gevolgd|{0} persoon heeft je gevold|{0} mensen hebben je gevolgd",
"missing_type": "MISSEND notificatie.type:", "missing_type": "MISSEND notificatie.type:",
"reblogged_post": "herblogt je post", "reblogged_post": "boost je post",
"reported": "{0} heeft {1} gerapporteerd",
"request_to_follow": "vraagt om jou te volgen", "request_to_follow": "vraagt om jou te volgen",
"signed_up": "ingeschreven", "signed_up": "ingeschreven",
"update_status": "heeft hun post aangepast" "update_status": "heeft hun post aangepast"
@ -185,11 +350,87 @@
"reply_to_account": "Reageer op {0}", "reply_to_account": "Reageer op {0}",
"replying": "Reageren" "replying": "Reageren"
}, },
"polls": {
"allow_multiple": "Multiple choice",
"cancel": "Annuleren",
"create": "Peiling maken",
"disallow_multiple": "Eén optie kiezen",
"expiration": "Vervaldatum",
"hide_votes": "Stemmen verbergen",
"option_placeholder": "Optie {current}/{max}",
"remove_option": "Verwijder optie",
"settings": "Instellingen",
"show_votes": "Stemmen tonen"
},
"pwa": { "pwa": {
"dismiss": "Afwijzen", "dismiss": "Afwijzen",
"install": "Installeren",
"install_title": "Elk installeren",
"screenshots": {
"dark": "Schermafbeelding van Elk in donkere modus",
"light": "Schermafbeelding van Elk in lichte modus"
},
"title": "Er is een nieuwe Elk update!", "title": "Er is een nieuwe Elk update!",
"update": "Update", "update": "Bijwerken",
"update_available_short": "Update Elk" "update_available_short": "Elk bijwerken",
"webmanifest": {
"canary": {
"description:": "Een vlotte Mastodon web client (canary versie)",
"name": "Elk (canary)",
"short_name": "Elk (canary)"
},
"dev": {
"description:": "Een vlotte Mastodon web client (dev versie)",
"name": "Elk (dev)",
"short_name": "Elk (dev)"
},
"preview": {
"description:": "Een vlotte Mastodon web client (preview versie)",
"name": "Elk (preview)",
"short_name": "Elk (preview)"
},
"release": {
"description:": "Een vlotte Mastodon web client",
"name": "Elk",
"short_name": "Elk"
}
}
},
"report": {
"additional_comments": "Extra opmerkingen",
"another_server": "De gebruiker die je rapporteert behoort tot een andere server.",
"anything_else": "Is er nog iets dat we moeten weten?",
"block_desc": "Je zult niet langer de berichten van deze gebruiker kunnen zien. Ze zullen jouw berichten niet meer kunnen zien en je niet meer kunnen volgen. Ze zullen je vertellen dat ze geblokkeerd zijn",
"dontlike": "Ik vind het niet leuk",
"dontlike_desc": "Het is iets wat je niet wilt zien",
"forward": "Ja, stuur dit rapport naar {0}",
"forward_question": "Wilt je ook een anonieme kopie van dit rapport naar die server sturen?",
"further_actions": {
"limit": {
"description": "Dit zijn de opties om te bepalen wat je ziet:",
"title": "Wil je dit niet meer zien?"
},
"report": {
"description": "Terwijl we het herzien, zijn hier de acties die je kunt ondernemen:",
"title": "Bedankt voor je rapport. We zullen het bekijken."
}
},
"limiting": "Beperken tot {0}",
"mute_desc": "Je zult niet langer de berichten van deze gebruiker kunnen zien. Ze kunnen je nog steeds volgen en je berichten zien. Ze zullen niet weten dat ze gedempt zijn",
"other": "Het is iets anders",
"other_desc": "Het probleem valt niet onder de genoemde categorieën",
"reporting": "Rapporteren aan {0}",
"select_many": "Selecteer alle opties die van toepassing zijn",
"select_one": "Selecteer de optie die het meest van toepassing is",
"select_posts": "Zijn er ondersteunende publicaties voor dit rapport?",
"select_posts_other": "Zijn er andere ondersteunende publicaties voor dit rapport?",
"spam": "Het is spam",
"spam_desc": "Kwaadaardige links, nepbetrokkenheid of herhalende antwoorden",
"submit": "Rapport verzenden",
"unfollow_desc": "e zult de berichten van deze gebruiker niet langer op je tijdlijn zien. Je kunt hun berichten nog wel op andere plaatsen zien.",
"violation": "Het is een schending van de regels van de server",
"whats_wrong_account": "Wat is er mis met dit account?",
"whats_wrong_post": "Wat is er mis met deze post?"
}, },
"search": { "search": {
"search_desc": "Zoek naar mensen & hashtags", "search_desc": "Zoek naar mensen & hashtags",
@ -197,19 +438,38 @@
}, },
"settings": { "settings": {
"about": { "about": {
"label": "Over" "built_at": "Gebouwd",
"label": "Over",
"meet_the_team": "Ontmoet het team",
"sponsor_action": "Sponsor ons",
"sponsor_action_desc": "Steun de ontwikkeling van Elk",
"sponsors": "Sponsors",
"sponsors_body_1": "Elk wordt mogelijk gemaakt dankzij de gulle sponsoring en hulp van:",
"sponsors_body_2": "En alle bedrijven en individuen die het Elk Team en de leden sponsoren.",
"sponsors_body_3": "Als je de app leuk vindt, overweeg dan om ons te sponsoren:",
"version": "Versie"
},
"account_settings": {
"description": "Bewerk je account instellingen bij je mastodon server",
"label": "Account Instellingen"
}, },
"interface": { "interface": {
"bottom_nav": "Onderste navigatie",
"bottom_nav_instructions": "Kies je favoriete navigatieknoppen. Moet de 'Meer...' knop bevatten",
"color_mode": "Kleur Modus", "color_mode": "Kleur Modus",
"dark_mode": "Donkere Modus", "dark_mode": "Donkere Modus",
"default": " (standaard)", "default": " (standaard)",
"font_size": "Letter Grootte", "font_size": "Lettergrootte",
"label": "Interface", "label": "Interface",
"light_mode": "Lichte Modus" "light_mode": "Lichte Modus",
"system_mode": "Systeem Modus",
"theme_color": "Thema Kleur"
}, },
"language": { "language": {
"display_language": "Weergave taal", "display_language": "Weergave taal",
"how_to_contribute": "Hoe kan ik bijdragen aan vertalingen?",
"label": "Taal", "label": "Taal",
"post_language": "Taal van posts",
"status": "Vertalingsstatus: {0}/{1} ({2}%)", "status": "Vertalingsstatus: {0}/{1} ({2}%)",
"translations": { "translations": {
"add": "Toevoegen", "add": "Toevoegen",
@ -230,7 +490,7 @@
"follow": "Nieuwe volgers", "follow": "Nieuwe volgers",
"mention": " Vermeldingen", "mention": " Vermeldingen",
"poll": "Peilingen", "poll": "Peilingen",
"reblog": "Herblogt jou post", "reblog": "Boost jouw post",
"title": "Welke notificaties wil je krijgen?" "title": "Welke notificaties wil je krijgen?"
}, },
"description": "Ontvang meldingen zelfs wanneer je Elk niet gebruikt.", "description": "Ontvang meldingen zelfs wanneer je Elk niet gebruikt.",
@ -243,19 +503,24 @@
"none": "Van niemand", "none": "Van niemand",
"title": "Van wie kan ik meldingen krijgen?" "title": "Van wie kan ik meldingen krijgen?"
}, },
"save_settings": "Instellingen aanpassingen opslaan", "save_settings": "Instellingen opslaan",
"subscription_error": { "subscription_error": {
"clear_error": "Wis error", "clear_error": "Wis error",
"permission_denied": "Geen toestemming: zet notificaties aan in je browser.", "permission_denied": "Geen toestemming: zet notificaties aan in je browser.",
"request_error": "Er is een error tijdens het ophalen van het abonnement, probeer opnieuw en als de error blijft, raporteer het probleem naar de Elk repository.", "repo_link": "Elk repository op GitHub",
"title": "Kon niet abonneren op de pushnotificaties" "request_error": "Er is een fout opgetreden tijdens het ophalen van het abonnement, probeer opnieuw en als de error blijft, raporteer het probleem naar de Elk repository.",
"title": "Kon niet abonneren op de pushnotificaties",
"too_many_registrations": "Te veel registraties: je hebt te veel apparaten geregistreerd voor pushnotificaties. Verwijder een paar apparaten en probeer het opnieuw.",
"vapid_not_supported": "VAPID wordt niet ondersteund: je browser ondersteunt geen pushnotificaties. Probeer een andere browser."
}, },
"title": "Pushnotificaties",
"undo_settings": "Veranderde instellingen ongedaan maken", "undo_settings": "Veranderde instellingen ongedaan maken",
"unsubscribe": "Zet pushnotificaties uit", "unsubscribe": "Zet pushnotificaties uit",
"unsupported": "Je browser ondersteunt geen pushnotificaties.", "unsupported": "Je browser ondersteunt geen pushnotificaties.",
"warning": { "warning": {
"enable_close": "Sluit", "enable_close": "Sluit",
"enable_description": "Om meldingen te krijgen terwijl Elk niet actief is, zet pushnotificaties aan. Je kan precies instellen wat voor type interacties pushnotificaties genereren via de \"@:notification.settings.show_btn{'\"'} knop hierboven wanneer ze aan staan.", "enable_description": "Om meldingen te krijgen terwijl Elk niet actief is, zet pushnotificaties aan. Je kan precies instellen wat voor type interacties pushnotificaties genereren via de \"@:notification.settings.show_btn{'\"'} knop hierboven wanneer ze aan staan.",
"enable_description_desktop": "Om meldingen te ontvangen wanneer Elk niet actief is, schakel pushnotificaties in. Je kunt precies instellen welke soorten interacties pushnotificaties genereren in dit venster zodra je ze hebt inschakelt.",
"enable_description_settings": "Om meldingen te ontvangen wanneer Elk niet actief is, schakel pushnotificaties in. Je kunt precies instellen welke soorten interacties pushnotificaties genereren in dit venster zodra je ze hebt inschakelt.", "enable_description_settings": "Om meldingen te ontvangen wanneer Elk niet actief is, schakel pushnotificaties in. Je kunt precies instellen welke soorten interacties pushnotificaties genereren in dit venster zodra je ze hebt inschakelt.",
"enable_desktop": "Zet pushnotificaties aan", "enable_desktop": "Zet pushnotificaties aan",
"enable_title": "Mis niets", "enable_title": "Mis niets",
@ -266,7 +531,39 @@
}, },
"notifications_settings": "Meldingen", "notifications_settings": "Meldingen",
"preferences": { "preferences": {
"label": "Voorkeuren" "embedded_media": "Ingesloten mediaspeler",
"embedded_media_description": "Toon ingesloten media in posts in plaats van de normale preview kaart bij het openen van gedeelde media streaming links",
"enable_autoplay": "Automatisch afspelen",
"enable_data_saving": "Gegevensbesparing",
"enable_data_saving_description": "Bespaar gegevens door media niet automatisch te laden",
"enable_pinch_to_zoom": "Knijpen om in te zoomen",
"github_cards": "GitHub kaarten",
"github_cards_description": "Als een GitHub link wordt gedeeld, toon een klikbare kaart in plaats van een afbeelding",
"grayscale_mode": "Grijze modus",
"hide_account_hover_card": "Verberg account kaart bij muisover",
"hide_alt_indi_on_posts": "Verberg alt tekst indicator op posts",
"hide_boost_count": "Verberg boosts teller",
"hide_favorite_count": "Verberg favorieten teller",
"hide_follower_count": "Verberg volgend/volgers teller",
"hide_gif_indi_on_posts": "Verberg GIF indicator op posts",
"hide_news": "Verberg nieuws",
"hide_reply_count": "Verberg antwoorden teller",
"hide_tag_hover_card": "Verberg tag kaart bij muisover",
"hide_translation": "Verberg vertalingen",
"hide_username_emojis": "Verberg gebruikersnaam emojis",
"hide_username_emojis_description": "Verberg emojis in gebruikersnamen in de tijdlijnen. Emojis blijven zichtbaar in het profiel",
"label": "Voorkeuren",
"optimize_for_low_performance_device": "Optimaliseer voor apparaten met lage prestaties",
"title": "Experimentele instellingen",
"unmute_videos": "Video geluid standaard aan",
"use_star_favorite_icon": "Gebruik ster als favoriet icoon",
"user_picker": "Toon alle accounts",
"user_picker_description": "Toon alle ingelogde accounts linksonderin het scherm om makkelijk te wisselen",
"virtual_scroll": "Virtueel scrolling",
"virtual_scroll_description": "Gebruik virtueel scrollen voor betere prestaties",
"wellbeing": "Geestelijk welzijn",
"zen_mode": "Zen modus",
"zen_mode_description": "Verberg menu's tenzij je er met de muis overheen gaat. Ook worden sommige elementen verwijderd uit posts"
}, },
"profile": { "profile": {
"appearance": { "appearance": {
@ -293,29 +590,51 @@
}, },
"state": { "state": {
"attachments_exceed_server_limit": "De hoeveelheid bijlagen is meer dan het limiet per post.", "attachments_exceed_server_limit": "De hoeveelheid bijlagen is meer dan het limiet per post.",
"attachments_limit_audio_error": "Limiet per post voor audio bestanden overschreden {0}",
"attachments_limit_error": "Limiet per post overschreden", "attachments_limit_error": "Limiet per post overschreden",
"attachments_limit_image_error": "Limiet per post voor afbeeldingen overschreden {0}",
"attachments_limit_unknown_error": "Limiet per post voor attachments overschreden {0}",
"attachments_limit_video_error": "Limiet per post voor video bestanden overschreden {0}",
"edited": "(Aangepast)", "edited": "(Aangepast)",
"editing": "Aanpassen", "editing": "Aanpassen",
"loading": "Laden...", "loading": "Laden...",
"publish_failed": "Publiceren mislukt",
"publishing": "Publiceren...",
"save_failed": "Opslaan mislukt",
"upload_failed": "Upload mislukt", "upload_failed": "Upload mislukt",
"uploading": "Uploading..." "uploading": "Uploading..."
}, },
"status": { "status": {
"account": {
"suspended_message": "Dit account is geschorst",
"suspended_show": "Geschorst account tonen?"
},
"boosted_by": "Geboost door",
"edited": "Aangepast {0}", "edited": "Aangepast {0}",
"embedded_warning": "Door dit te boosten kan je IP adres worden gelekt",
"favourited_by": "Als favoriet opgeslagen door",
"filter_hidden_phrase": "Gefilterd door", "filter_hidden_phrase": "Gefilterd door",
"filter_show_anyway": "Laat toch zien", "filter_show_anyway": "Laat toch zien",
"gif": "GIF",
"img_alt": { "img_alt": {
"ALT": "ALT",
"desc": "Omschrijving", "desc": "Omschrijving",
"dismiss": "Afwijzen" "dismiss": "Afwijzen",
"read": "Lees de ALT tekst {0}"
}, },
"pinned": "Vastgezette posts",
"poll": { "poll": {
"count": "{0} stemmen|{0} stem|{0} stemmen", "count": "{0} stemmen|{0} stem|{0} stemmen",
"ends": "eindigt {0}", "ends": "eindigt {0}",
"finished": "geëindigd {0}" "finished": "geëindigd {0}"
}, },
"replying_to": "Antwoord aan {0}",
"show_full_thread": "Toon volledig draadje",
"someone": "Iemand", "someone": "Iemand",
"spoiler_media_hidden": "Media verborgen",
"spoiler_show_less": "Minder zien", "spoiler_show_less": "Minder zien",
"spoiler_show_more": "Meer zien", "spoiler_show_more": "Meer zien",
"thread": "draadje",
"try_original_site": "Probeer originele site" "try_original_site": "Probeer originele site"
}, },
"status_history": { "status_history": {
@ -323,12 +642,26 @@
"edited": "aangepast {0}" "edited": "aangepast {0}"
}, },
"tab": { "tab": {
"accounts": "Accounts",
"for_you": "Voor jou", "for_you": "Voor jou",
"hashtags": "Hashtags", "hashtags": "Hashtags",
"list": "Lijst",
"media": "Media", "media": "Media",
"news": "Nieuws", "news": "Nieuws",
"notifications_admin": {
"report": "Rapporteer",
"sign_up": "Inschrijven"
},
"notifications_all": "Alles", "notifications_all": "Alles",
"notifications_mention": "Vermelding", "notifications_favourite": "Favorieten",
"notifications_follow": "Volgers",
"notifications_follow_request": "Volgverzoeken",
"notifications_mention": "Vermeldingen",
"notifications_poll": "Peilingen",
"notifications_reblog": "Boosts",
"notifications_status": "Status",
"notifications_update": "Wijzigingen",
"notitications_more_tooltip": "Filter notificaties per type",
"posts": "Posts", "posts": "Posts",
"posts_with_replies": "Posts & Reacties" "posts_with_replies": "Posts & Reacties"
}, },
@ -370,7 +703,9 @@
"year_past": "0 jaar geleden|vorig jaar|{n} jaar geleden" "year_past": "0 jaar geleden|vorig jaar|{n} jaar geleden"
}, },
"timeline": { "timeline": {
"show_new_items": "Laat {v} nieuwe artikelen zien|Laat {v} nieuw artikel zien|Laat {v} nieuwe artikelen zien" "no_posts": "Geen posts",
"show_new_items": "Laat {v} nieuwe artikelen zien|Laat {v} nieuw artikel zien|Laat {v} nieuwe artikelen zien",
"view_older_posts": "Bekijk oudere posts"
}, },
"title": { "title": {
"federated_timeline": "Gefedereerde Tijdlijn", "federated_timeline": "Gefedereerde Tijdlijn",
@ -378,14 +713,24 @@
}, },
"tooltip": { "tooltip": {
"add_content_warning": "Voeg inhoud waarschuwing toe", "add_content_warning": "Voeg inhoud waarschuwing toe",
"add_emojis": "Voeg emojis toe",
"add_media": "Voeg fotos, een video of een audio bestand toe", "add_media": "Voeg fotos, een video of een audio bestand toe",
"add_publishable_content": "Voeg publiceerbare inhoud toe",
"add_thread_item": "Voeg een item toe aan het draadje",
"change_content_visibility": "Verander inhoud zichtbaarheid", "change_content_visibility": "Verander inhoud zichtbaarheid",
"change_language": "Verander taal", "change_language": "Verander taal",
"emoji": "Emoji", "emoji": "Emoji",
"explore_links_intro": "Over deze nieuws artikelen wordt veel gepraat op deze en anderen servers op het decentralized network op dit moment.", "explore_links_intro": "Over deze nieuws artikelen wordt veel gepraat op deze en anderen servers op het decentralized network op dit moment.",
"explore_posts_intro": "Deze posts van deze en andere servers op het decentralized network krijgen veel aandacht op deze server op dit moment.", "explore_posts_intro": "Deze posts van deze en andere servers op het decentralized network krijgen veel aandacht op deze server op dit moment.",
"explore_tags_intro": "Deze hashtags krijgen veel aandacht op dit moment op deze en andere servers op het decentralized network.", "explore_tags_intro": "Deze hashtags krijgen veel aandacht op dit moment op deze en andere servers op het decentralized network.",
"toggle_code_block": "Zet code blok aan/uit" "open_editor_tools": "Opmaak",
"pick_an_icon": "Kies een icoon",
"publish_failed": "Publiceren mislukt",
"remove_thread_item": "Verwijder item uit draadje",
"start_thread": "Start een draadje",
"toggle_bold": "Zet vet aan/uit",
"toggle_code_block": "Zet code blok aan/uit",
"toggle_italic": "Zet cursief aan/uit"
}, },
"user": { "user": {
"add_existing": "Voeg een bestaand account toe", "add_existing": "Voeg een bestaand account toe",
@ -393,6 +738,7 @@
"sign_in_desc": "Log in om profielen te volgen of hashtags, markeer posts als favoriet, deel en reageer op posts, of reageer vanaf je account op een andere server.", "sign_in_desc": "Log in om profielen te volgen of hashtags, markeer posts als favoriet, deel en reageer op posts, of reageer vanaf je account op een andere server.",
"sign_in_notice_title": "Je bekijkt {0} publieke data", "sign_in_notice_title": "Je bekijkt {0} publieke data",
"sign_out_account": "Uitloggen {0}", "sign_out_account": "Uitloggen {0}",
"single_instance_sign_in_desc": "Log in om profielen of tags te volgen, te bookmarken, te delen en te reageren op berichten.",
"tip_no_account": "Als je nog geen Mastodon account hebt, {0}.", "tip_no_account": "Als je nog geen Mastodon account hebt, {0}.",
"tip_register_account": "kies jouw server en registreer een account" "tip_register_account": "kies jouw server en registreer een account"
}, },

View file

@ -226,7 +226,9 @@
"manage": "Gerir listas", "manage": "Gerir listas",
"modify_account": "Modificar listas com a conta", "modify_account": "Modificar listas com a conta",
"remove_account": "Remover conta da lista", "remove_account": "Remover conta da lista",
"save": "Salvar alterações" "save": "Salvar alterações",
"search_following_desc": "Pesquisar por pessoas que está a seguir",
"search_following_placeholder": "Pesquisar de entre as pessoas que segue"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Atalhos de teclado", "dialog_header": "Atalhos de teclado",
@ -334,10 +336,12 @@
"zen_mode": "Modo Zen" "zen_mode": "Modo Zen"
}, },
"notification": { "notification": {
"and": "e",
"favourited_post": "adicionou a sua publicação aos favoritos", "favourited_post": "adicionou a sua publicação aos favoritos",
"followed_you": "começou a segui-lo", "followed_you": "começou a segui-lo",
"followed_you_count": "{0} pessoas seguem-no|{0} pessoa segue-o|{0} pessoas seguem-no", "followed_you_count": "{0} pessoas seguem-no|{0} pessoa segue-o|{0} pessoas seguem-no",
"missing_type": "notification.type em FALTA:", "missing_type": "notification.type em FALTA:",
"others": "{0} outros|{0} outro|{0} outros",
"reblogged_post": "partilhou a sua publicação", "reblogged_post": "partilhou a sua publicação",
"reported": "{0} denunciou {1}", "reported": "{0} denunciou {1}",
"request_to_follow": "pediu para segui-lo", "request_to_follow": "pediu para segui-lo",
@ -489,7 +493,7 @@
"favourite": "Favoritos", "favourite": "Favoritos",
"follow": "Novos seguidores", "follow": "Novos seguidores",
"mention": "Menções", "mention": "Menções",
"poll": "Votações", "poll": "Sondagens",
"reblog": "Partilha das sua publicação", "reblog": "Partilha das sua publicação",
"title": "Que notificações quer receber?" "title": "Que notificações quer receber?"
}, },
@ -559,6 +563,7 @@
"label": "Preferências", "label": "Preferências",
"optimize_for_low_performance_device": "Otimizar para dispositivos de menor desempenho", "optimize_for_low_performance_device": "Otimizar para dispositivos de menor desempenho",
"title": "Funcionalidades Experimentais", "title": "Funcionalidades Experimentais",
"unmute_videos": "Som de vídeo ativado por predefinição",
"use_star_favorite_icon": "Utilizar estrela como ícone de favoritos", "use_star_favorite_icon": "Utilizar estrela como ícone de favoritos",
"user_picker": "Selecionador de Utilizador", "user_picker": "Selecionador de Utilizador",
"user_picker_description": "Exibe as imagens de perfil de todas as contas registadas no canto inferior esquerdo para que possa alternar rapidamente entre elas.", "user_picker_description": "Exibe as imagens de perfil de todas as contas registadas no canto inferior esquerdo para que possa alternar rapidamente entre elas.",
@ -637,7 +642,8 @@
"poll": { "poll": {
"count": "{0} votos|{0} voto|{0} votos", "count": "{0} votos|{0} voto|{0} votos",
"ends": "termina {0}", "ends": "termina {0}",
"finished": "terminou {0}" "finished": "terminou {0}",
"update": "Atualizar sondagem"
}, },
"replying_to": "Em resposta a {0}", "replying_to": "Em resposta a {0}",
"show_full_thread": "Mostrar toda a conversa", "show_full_thread": "Mostrar toda a conversa",

View file

@ -58,6 +58,7 @@
"boost": "I-boost", "boost": "I-boost",
"boost_count": "{0} nag-boost", "boost_count": "{0} nag-boost",
"boosted": "Nai-boost na", "boosted": "Nai-boost na",
"clear": "I-clear",
"clear_publish_failed": "I-clear ang mga error sa pag-publish", "clear_publish_failed": "I-clear ang mga error sa pag-publish",
"clear_save_failed": "I-clear ang mga error sa pag-save", "clear_save_failed": "I-clear ang mga error sa pag-save",
"clear_upload_failed": "I-clear ang mga error sa pag-upload ng file", "clear_upload_failed": "I-clear ang mga error sa pag-upload ng file",
@ -72,8 +73,10 @@
"favourited": "Nai-favorite na", "favourited": "Nai-favorite na",
"more": "Iba pa", "more": "Iba pa",
"next": "Susunod", "next": "Susunod",
"open_image_preview_dialog": "Buksan ang image preview",
"prev": "Nakaraan", "prev": "Nakaraan",
"publish": "I-publish", "publish": "I-publish",
"publish_thread": "I-publish ang thread",
"reply": "Sumagot", "reply": "Sumagot",
"reply_count": "{0} sumagot", "reply_count": "{0} sumagot",
"reset": "I-reset", "reset": "I-reset",
@ -220,6 +223,7 @@
"error": "Mayroong error sa paglikha ng listahan", "error": "Mayroong error sa paglikha ng listahan",
"error_prefix": "Error: ", "error_prefix": "Error: ",
"list_title_placeholder": "Pangalan ng listahan", "list_title_placeholder": "Pangalan ng listahan",
"manage": "I-manage",
"modify_account": "Baguhin ang mga listahan sa account", "modify_account": "Baguhin ang mga listahan sa account",
"remove_account": "Tanggalin ang account sa listahan", "remove_account": "Tanggalin ang account sa listahan",
"save": "I-save ang mga pagbabago" "save": "I-save ang mga pagbabago"
@ -306,6 +310,7 @@
"built_at": "Build version mula noong {0}", "built_at": "Build version mula noong {0}",
"compose": "Lumikha ng Mensahe", "compose": "Lumikha ng Mensahe",
"conversations": "Mga Usapang Pribado", "conversations": "Mga Usapang Pribado",
"docs": "Dokumentasyon",
"explore": "Mag-Explore", "explore": "Mag-Explore",
"favourites": "Mga Paborito", "favourites": "Mga Paborito",
"federated": "Pederal", "federated": "Pederal",
@ -314,6 +319,7 @@
"list": "Listahan", "list": "Listahan",
"lists": "Mga Listahan", "lists": "Mga Listahan",
"local": "Lokal", "local": "Lokal",
"more_menu": "Higit pang menu",
"muted_users": "Mga Naka-Mute na User", "muted_users": "Mga Naka-Mute na User",
"notifications": "Mga Abiso", "notifications": "Mga Abiso",
"privacy": "Privacy", "privacy": "Privacy",
@ -328,11 +334,14 @@
"zen_mode": "Zen Mode" "zen_mode": "Zen Mode"
}, },
"notification": { "notification": {
"and": "at",
"favourited_post": "nag-favorite ng iyong post", "favourited_post": "nag-favorite ng iyong post",
"followed_you": "nag-follow sa iyo", "followed_you": "nag-follow sa iyo",
"followed_you_count": "{0} na tao ang nag-follow sa iyo|{0} na tao ang nag-follow sa iyo|{0} na tao ang nag-follow sa iyo", "followed_you_count": "{0} na tao ang nag-follow sa iyo|{0} na tao ang nag-follow sa iyo|{0} na tao ang nag-follow sa iyo",
"missing_type": "MISSING notification.type:", "missing_type": "MISSING notification.type:",
"others": "{0} iba pa|{0} iba pa|{0} iba pa",
"reblogged_post": "bumoost ng iyong post", "reblogged_post": "bumoost ng iyong post",
"reported": "ni-report ni {0} si {1}",
"request_to_follow": "humiling na sumunod sa iyo", "request_to_follow": "humiling na sumunod sa iyo",
"signed_up": "nag-sign up", "signed_up": "nag-sign up",
"update_status": "nag-update ng kanilang post" "update_status": "nag-update ng kanilang post"
@ -447,6 +456,8 @@
"label": "Mga account setting" "label": "Mga account setting"
}, },
"interface": { "interface": {
"bottom_nav": "Ibabang Nabigasyon",
"bottom_nav_instructions": "Pumili ng hanggang limang navigation button para sa ibabang nabigasyon. Dapat isama ang button na \"Higit pang menu.\"",
"color_mode": "Mode ng Kulay", "color_mode": "Mode ng Kulay",
"dark_mode": "Madilim", "dark_mode": "Madilim",
"default": " (default)", "default": " (default)",
@ -458,6 +469,7 @@
}, },
"language": { "language": {
"display_language": "Ipakita ang Wika", "display_language": "Ipakita ang Wika",
"how_to_contribute": "Paano mag-contribute?",
"label": "Wika", "label": "Wika",
"post_language": "Posting Language", "post_language": "Posting Language",
"status": "Kalagayan ng Pagsasalin: {0}/{1} ({2}%)", "status": "Kalagayan ng Pagsasalin: {0}/{1} ({2}%)",
@ -539,6 +551,7 @@
"hide_boost_count": "Itago ang boost count", "hide_boost_count": "Itago ang boost count",
"hide_favorite_count": "Itago ang favorite count", "hide_favorite_count": "Itago ang favorite count",
"hide_follower_count": "Itago ang following/follower count", "hide_follower_count": "Itago ang following/follower count",
"hide_gif_indi_on_posts": "Itago ang indicator ng mga GIF",
"hide_news": "Itago ang mga balita", "hide_news": "Itago ang mga balita",
"hide_reply_count": "Itago ang reply count", "hide_reply_count": "Itago ang reply count",
"hide_tag_hover_card": "Itago ang tag hover card", "hide_tag_hover_card": "Itago ang tag hover card",
@ -552,6 +565,7 @@
"user_picker": "Pagpipilian na mga Account", "user_picker": "Pagpipilian na mga Account",
"user_picker_description": "Ipakita ang mga avatar ng mga naka-login na account sa kaliwang ibaba para makalipat sa mga ito.", "user_picker_description": "Ipakita ang mga avatar ng mga naka-login na account sa kaliwang ibaba para makalipat sa mga ito.",
"virtual_scroll": "Virtual na Scrolling", "virtual_scroll": "Virtual na Scrolling",
"virtual_scroll_description": "Gumamit ng isang virtual list sa mga timeline, upang ang mas marami pang mga items ang mai-render nang mas mabilis.",
"wellbeing": "Kalusugan at Kagalingan", "wellbeing": "Kalusugan at Kagalingan",
"zen_mode": "Modong Zen", "zen_mode": "Modong Zen",
"zen_mode_description": "Itago ang ibang mga elemento sa timeline at mga asides maliban kung naka-focus ang mouse cursor sa kanila." "zen_mode_description": "Itago ang ibang mga elemento sa timeline at mga asides maliban kung naka-focus ang mouse cursor sa kanila."
@ -589,7 +603,11 @@
}, },
"state": { "state": {
"attachments_exceed_server_limit": "Nalagpasan na ang bilang ng mga attachments na pinapayagan bawat post.", "attachments_exceed_server_limit": "Nalagpasan na ang bilang ng mga attachments na pinapayagan bawat post.",
"attachments_limit_audio_error": "Lumagpas sa limit ng audio file size: {0}",
"attachments_limit_error": "Lumagpas sa limitasyon bawat post", "attachments_limit_error": "Lumagpas sa limitasyon bawat post",
"attachments_limit_image_error": "Lumagpas sa limit ng image file size: {0}",
"attachments_limit_unknown_error": "Lumagpas sa limit ng file size: {0}",
"attachments_limit_video_error": "Lumagpas sa limit ng video file size: {0}",
"edited": "(Naedit)", "edited": "(Naedit)",
"editing": "Pinaeedit", "editing": "Pinaeedit",
"loading": "Nagloload...", "loading": "Nagloload...",
@ -610,16 +628,19 @@
"favourited_by": "Pumaborito si", "favourited_by": "Pumaborito si",
"filter_hidden_phrase": "Nakafilter dahil sa", "filter_hidden_phrase": "Nakafilter dahil sa",
"filter_show_anyway": "Ipakita pa rin", "filter_show_anyway": "Ipakita pa rin",
"gif": "GIF",
"img_alt": { "img_alt": {
"ALT": "ALT", "ALT": "ALT",
"desc": "Paglalarawan", "desc": "Paglalarawan",
"dismiss": "I-dismiss", "dismiss": "I-dismiss",
"read": "Basahin ang {0} paglalarawan" "read": "Basahin ang {0} paglalarawan"
}, },
"pinned": "Naka-pin",
"poll": { "poll": {
"count": "{0} boto|{0} boto|{0} mga boto", "count": "{0} boto|{0} boto|{0} mga boto",
"ends": "magtatapos {0}", "ends": "magtatapos {0}",
"finished": "natapos {0}" "finished": "natapos {0}",
"update": "I-update ang poll"
}, },
"replying_to": "Sumasagot kay {0}", "replying_to": "Sumasagot kay {0}",
"show_full_thread": "Ipakita ang buong thread", "show_full_thread": "Ipakita ang buong thread",
@ -696,6 +717,7 @@
"year_past": "0 taon na ang nakalipas|nakaraang taon|{n} taon na ang nakalipas" "year_past": "0 taon na ang nakalipas|nakaraang taon|{n} taon na ang nakalipas"
}, },
"timeline": { "timeline": {
"no_posts": "Walang mga post dito!",
"show_new_items": "Ipakita ang {v} bagong item|Ipakita ang {v} bagong item|Ipakita ang {v} bagong item", "show_new_items": "Ipakita ang {v} bagong item|Ipakita ang {v} bagong item|Ipakita ang {v} bagong item",
"view_older_posts": "Maaaring hindi ipakita ang mga lumang post mula sa ibang pagkakataon." "view_older_posts": "Maaaring hindi ipakita ang mga lumang post mula sa ibang pagkakataon."
}, },
@ -708,6 +730,7 @@
"add_emojis": "Magdagdag ng mga emoji", "add_emojis": "Magdagdag ng mga emoji",
"add_media": "Magdagdag ng mga larawan, isang video o isang audio file", "add_media": "Magdagdag ng mga larawan, isang video o isang audio file",
"add_publishable_content": "Magdagdag ng nilalamang ilalathala", "add_publishable_content": "Magdagdag ng nilalamang ilalathala",
"add_thread_item": "Magdagdag ng item sa thread",
"change_content_visibility": "Baguhin ang visibility ng nilalaman", "change_content_visibility": "Baguhin ang visibility ng nilalaman",
"change_language": "Baguhin ang wika", "change_language": "Baguhin ang wika",
"emoji": "Emoji", "emoji": "Emoji",
@ -717,6 +740,8 @@
"open_editor_tools": "Mga tool sa editor", "open_editor_tools": "Mga tool sa editor",
"pick_an_icon": "Pumili ng icon", "pick_an_icon": "Pumili ng icon",
"publish_failed": "Isara ang mga nabigong mensahe sa tuktok ng editor upang muling i-publish ang mga post", "publish_failed": "Isara ang mga nabigong mensahe sa tuktok ng editor upang muling i-publish ang mga post",
"remove_thread_item": "Mag-tanggal ng item sa thread",
"start_thread": "Magsimula ng thread",
"toggle_bold": "I-toggle ang bold", "toggle_bold": "I-toggle ang bold",
"toggle_code_block": "I-toggle ang block ng code", "toggle_code_block": "I-toggle ang block ng code",
"toggle_italic": "I-toggle ang italic" "toggle_italic": "I-toggle ang italic"

View file

@ -54,10 +54,10 @@
"action": { "action": {
"apply": "Áp dụng", "apply": "Áp dụng",
"bookmark": "Lưu", "bookmark": "Lưu",
"bookmarked": "Đã lưu", "bookmarked": "Bỏ lưu",
"boost": "Đăng lại", "boost": "Đăng lại",
"boost_count": "{0}", "boost_count": "{0}",
"boosted": "Đã đăng lại", "boosted": "Bỏ đăng lại",
"clear": "Xóa", "clear": "Xóa",
"clear_publish_failed": "Xóa lỗi khi đăng tút", "clear_publish_failed": "Xóa lỗi khi đăng tút",
"clear_save_failed": "Xóa lỗi khi lưu tút", "clear_save_failed": "Xóa lỗi khi lưu tút",
@ -226,7 +226,9 @@
"manage": "Quản lý danh sách", "manage": "Quản lý danh sách",
"modify_account": "Sửa danh sách có người này", "modify_account": "Sửa danh sách có người này",
"remove_account": "Xóa người ra khỏi danh sách", "remove_account": "Xóa người ra khỏi danh sách",
"save": "Lưu thay đổi" "save": "Lưu thay đổi",
"search_following_desc": "Tìm trong những người bạn theo dõi",
"search_following_placeholder": "Tìm trong những người bạn theo dõi"
}, },
"magic_keys": { "magic_keys": {
"dialog_header": "Phím tắt", "dialog_header": "Phím tắt",
@ -334,14 +336,16 @@
"zen_mode": "Tập Trung" "zen_mode": "Tập Trung"
}, },
"notification": { "notification": {
"favourited_post": "thích tút của bạn", "and": "và",
"followed_you": "theo dõi bạn", "favourited_post": "đã thích tút của bạn",
"followed_you": "đang theo dõi bạn",
"followed_you_count": "{0} người theo dõi bạn|{0} người theo dõi bạn|{0} người theo dõi bạn", "followed_you_count": "{0} người theo dõi bạn|{0} người theo dõi bạn|{0} người theo dõi bạn",
"missing_type": "THIẾU notification.type:", "missing_type": "THIẾU notification.type:",
"reblogged_post": "đăng lại tút của bạn", "others": "{0} người khác|{0} người khác|{0} người khác",
"reblogged_post": "đã đăng lại tút của bạn",
"reported": "{0} báo cáo {1}", "reported": "{0} báo cáo {1}",
"request_to_follow": "yêu cầu theo dõi bạn", "request_to_follow": "yêu cầu theo dõi bạn",
"signed_up": "tham gia máy chủ", "signed_up": "đã tham gia máy chủ",
"update_status": "cập nhật tút" "update_status": "cập nhật tút"
}, },
"placeholder": { "placeholder": {
@ -401,8 +405,8 @@
"another_server": "Người bạn báo cáo thuộc ở máy chủ khác", "another_server": "Người bạn báo cáo thuộc ở máy chủ khác",
"anything_else": "Có điều gì mà chúng tôi cần biết không?", "anything_else": "Có điều gì mà chúng tôi cần biết không?",
"block_desc": "Bạn sẽ không còn thấy tút của người này. Họ sẽ không thể thấy tút của bạn hoặc theo dõi bạn. Họ biết là bạn đã chặn họ.", "block_desc": "Bạn sẽ không còn thấy tút của người này. Họ sẽ không thể thấy tút của bạn hoặc theo dõi bạn. Họ biết là bạn đã chặn họ.",
"dontlike": "Tôi không thích", "dontlike": "Tôi không thích",
"dontlike_desc": ó không phải là thứ gì mà bạn muốn thấy", "dontlike_desc": ây không phải thứ mà bạn muốn thấy",
"forward": "Gửi luôn báo cáo đến {0}", "forward": "Gửi luôn báo cáo đến {0}",
"forward_question": "Bạn có chắc muốn gửi luôn báo cáo đến máy chủ của người này?", "forward_question": "Bạn có chắc muốn gửi luôn báo cáo đến máy chủ của người này?",
"further_actions": { "further_actions": {
@ -417,8 +421,8 @@
}, },
"limiting": "Hạn chế {0}", "limiting": "Hạn chế {0}",
"mute_desc": "Bạn sẽ không còn thấy tút của người này. Họ vẫn có thể thấy tút của bạn hoặc theo dõi bạn. Họ không biết là bạn đã chặn họ.", "mute_desc": "Bạn sẽ không còn thấy tút của người này. Họ vẫn có thể thấy tút của bạn hoặc theo dõi bạn. Họ không biết là bạn đã chặn họ.",
"other": "Một lý do khác", "other": "Lý do khác",
"other_desc": "Vấn đề không nằm trong những mục trên", "other_desc": "Vấn đề không thuộc những mục trên",
"reporting": "Báo cáo {0}", "reporting": "Báo cáo {0}",
"select_many": "Chọn tất cả lý do phù hợp:", "select_many": "Chọn tất cả lý do phù hợp:",
"select_one": "Chọn lý do phù hợp nhất:", "select_one": "Chọn lý do phù hợp nhất:",
@ -537,7 +541,7 @@
"preferences": { "preferences": {
"embedded_media": "Trình Phát Media Dạng Nhúng", "embedded_media": "Trình Phát Media Dạng Nhúng",
"embedded_media_description": "Khi chia sẻ một liên kết media, hiển thị trình phát dạng nhúng thay vì ảnh mặc định.", "embedded_media_description": "Khi chia sẻ một liên kết media, hiển thị trình phát dạng nhúng thay vì ảnh mặc định.",
"enable_autoplay": "Tự động phát", "enable_autoplay": "Tự động phát video/GIF",
"enable_data_saving": "Tiết kiệm dữ liệu mạng", "enable_data_saving": "Tiết kiệm dữ liệu mạng",
"enable_data_saving_description": "Không cho tự động tải file đính kèm.", "enable_data_saving_description": "Không cho tự động tải file đính kèm.",
"enable_pinch_to_zoom": "Chụm 2 ngón tay để thu phóng", "enable_pinch_to_zoom": "Chụm 2 ngón tay để thu phóng",
@ -559,6 +563,7 @@
"label": "Thiết lập", "label": "Thiết lập",
"optimize_for_low_performance_device": "Tối ưu cho thiết bị yếu", "optimize_for_low_performance_device": "Tối ưu cho thiết bị yếu",
"title": "Tính năng thử nghiệm", "title": "Tính năng thử nghiệm",
"unmute_videos": "Mặc định bật âm thanh video",
"use_star_favorite_icon": "Dùng biểu tượng thích ngôi sao", "use_star_favorite_icon": "Dùng biểu tượng thích ngôi sao",
"user_picker": "Chuyển Đổi Tài Khoản", "user_picker": "Chuyển Đổi Tài Khoản",
"user_picker_description": "Hiển thị danh sách tài khoản đã đăng nhập ở góc dưới bên trái để nhanh chóng chuyển đổi qua lại.", "user_picker_description": "Hiển thị danh sách tài khoản đã đăng nhập ở góc dưới bên trái để nhanh chóng chuyển đổi qua lại.",
@ -637,9 +642,10 @@
"poll": { "poll": {
"count": "{0} bình chọn|{0} bình chọn|{0} bình chọn", "count": "{0} bình chọn|{0} bình chọn|{0} bình chọn",
"ends": "đóng {0}", "ends": "đóng {0}",
"finished": "kết thúc {0}" "finished": "kết thúc {0}",
"update": "Làm mới"
}, },
"replying_to": "Trả lời {0}", "replying_to": "Trả lời đến {0}",
"show_full_thread": "Chuỗi tút liên quan", "show_full_thread": "Chuỗi tút liên quan",
"someone": "ai đó", "someone": "ai đó",
"spoiler_media_hidden": "Media ẩn", "spoiler_media_hidden": "Media ẩn",
@ -668,7 +674,7 @@
"notifications_follow": "Theo dõi", "notifications_follow": "Theo dõi",
"notifications_follow_request": "Yêu cầu theo dõi", "notifications_follow_request": "Yêu cầu theo dõi",
"notifications_mention": "Lượt nhắc", "notifications_mention": "Lượt nhắc",
"notifications_more_tooltip": "Lọc loại thông báo", "notifications_more_tooltip": "Lọc theo loại thông báo",
"notifications_poll": "Bình chọn", "notifications_poll": "Bình chọn",
"notifications_reblog": "Đăng lại", "notifications_reblog": "Đăng lại",
"notifications_status": "Tút mới", "notifications_status": "Tút mới",
@ -708,10 +714,10 @@
"short_week_past": "{n} tuần", "short_week_past": "{n} tuần",
"short_year_future": "sau {n} năm", "short_year_future": "sau {n} năm",
"short_year_past": "{n} năm", "short_year_past": "{n} năm",
"week_future": "sau 0 tuần|tuần sau|trong {n} tuần", "week_future": "sau 0 tuần|tuần tới|trong {n} tuần",
"week_past": "0 tuần trước|tuần trước|{n} tuần trước", "week_past": "0 tuần trước|tuần trước|{n} tuần trước",
"year_future": "sau 0 năm|năm sau|in {n} năm sau", "year_future": "sau 0 năm|năm tới|sau {n} năm sau",
"year_past": "0 năm trước|năm trước|{n} năm trước" "year_past": "0 năm trước|năm ngoái|{n} năm trước"
}, },
"timeline": { "timeline": {
"no_posts": "Chưa có tút!", "no_posts": "Chưa có tút!",

Some files were not shown because too many files have changed in this diff Show more