Merge branch 'develop' into drive-bulk
This commit is contained in:
commit
f2f3fea68a
|
@ -165,6 +165,11 @@ id: 'aidx'
|
|||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
|
|
|
@ -177,6 +177,11 @@ id: 'aidx'
|
|||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
|
|
|
@ -259,6 +259,11 @@ id: 'aidx'
|
|||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
"workspaceFolder": "/workspace",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "22.11.0"
|
||||
"version": "22.15.0"
|
||||
},
|
||||
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
||||
"version": "10.6.1"
|
||||
"version": "10.10.0"
|
||||
}
|
||||
},
|
||||
"forwardPorts": [3000],
|
||||
|
|
|
@ -152,6 +152,11 @@ id: 'aidx'
|
|||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
20.10.0
|
|
@ -22,7 +22,7 @@ jobs:
|
|||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.2.0
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
- name: Checkout head
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.2.0
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
|
||||
- name: setup node
|
||||
id: setup-node
|
||||
uses: actions/setup-node@v4.2.0
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: pnpm
|
||||
|
|
|
@ -17,7 +17,6 @@ jobs:
|
|||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
api-json-name: [api-base.json, api-head.json]
|
||||
include:
|
||||
- api-json-name: api-base.json
|
||||
|
@ -32,10 +31,10 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
|
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
- uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
@ -69,13 +69,13 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
- uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Restore eslint cache
|
||||
uses: actions/cache@v4.2.2
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
path: ${{ env.eslint-cache-path }}
|
||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
|
@ -99,7 +99,7 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
- uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- uses: actions/setup-node@v4.2.0
|
||||
- uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
|
|
@ -15,22 +15,17 @@ jobs:
|
|||
contents: read
|
||||
id-token: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- name: Publish package
|
||||
run: |
|
||||
pnpm i --frozen-lockfile
|
||||
|
|
|
@ -11,13 +11,10 @@ on:
|
|||
# Storybook CI is checked on the "push" event of "develop" branch so it would cause a duplicate build.
|
||||
# This is a waste of chromatic build quota, so we don't run storybook CI on pull requests targets master.
|
||||
- master
|
||||
# Neither Dependabot nor Renovate will change the actual behavior for components.
|
||||
- dependabot/**
|
||||
- renovate/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
||||
# Chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
||||
if: github.repository == 'misskey-dev/misskey'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
@ -38,14 +35,11 @@ jobs:
|
|||
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||
- name: Checkout actual HEAD
|
||||
if: github.event_name == 'pull_request_target'
|
||||
id: rev
|
||||
run: |
|
||||
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
||||
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
||||
run: git checkout "$(git rev-list --parents -n1 HEAD | cut -d" " -f3)"
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
@ -84,21 +78,16 @@ jobs:
|
|||
if: github.event_name == 'pull_request_target'
|
||||
id: chromatic_pull_request
|
||||
run: |
|
||||
DIFF="${{ steps.rev.outputs.base }} HEAD"
|
||||
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
|
||||
DIFF="HEAD"
|
||||
fi
|
||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
|
||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff --name-only origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF} | xargs))"
|
||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
BRANCH="${{ github.event.pull_request.head.user.login }}:$HEAD_REF"
|
||||
if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then
|
||||
BRANCH="$HEAD_REF"
|
||||
BRANCH="${{ github.event.pull_request.head.user.login }}:$GITHUB_HEAD_REF"
|
||||
if [ "$BRANCH" = "misskey-dev:$GITHUB_HEAD_REF" ]; then
|
||||
BRANCH="$GITHUB_HEAD_REF"
|
||||
fi
|
||||
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER")
|
||||
env:
|
||||
HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
- name: Notify that Chromatic detects changes
|
||||
uses: actions/github-script@v7.0.1
|
||||
|
|
|
@ -22,10 +22,11 @@ jobs:
|
|||
unit:
|
||||
name: Unit tests (backend)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
|
||||
services:
|
||||
postgres:
|
||||
|
@ -61,10 +62,10 @@ jobs:
|
|||
exit 1
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
|
@ -84,10 +85,11 @@ jobs:
|
|||
e2e:
|
||||
name: E2E tests (backend)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
|
||||
services:
|
||||
postgres:
|
||||
|
@ -108,10 +110,10 @@ jobs:
|
|||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
|
|
|
@ -21,7 +21,9 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
@ -43,10 +45,10 @@ jobs:
|
|||
exit 1
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- name: Build Misskey
|
||||
run: |
|
||||
|
@ -54,6 +56,7 @@ jobs:
|
|||
pnpm build
|
||||
- name: Setup
|
||||
run: |
|
||||
echo "NODE_VERSION=$(cat ${{ matrix.node-version-file }})" >> $GITHUB_ENV
|
||||
cd packages/backend/test-federation
|
||||
bash ./setup.sh
|
||||
sudo chmod 644 ./certificates/*.test.key
|
||||
|
@ -71,18 +74,16 @@ jobs:
|
|||
docker compose logs | tail -n 300
|
||||
exit 1
|
||||
- name: Test
|
||||
id: test
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose run --no-deps tester
|
||||
- name: Log
|
||||
if: ${{ steps.test.outcome == 'failure' }}
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose logs
|
||||
exit 1
|
||||
- name: Stop servers
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose down
|
||||
|
|
|
@ -27,20 +27,16 @@ jobs:
|
|||
name: Unit tests (frontend)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
|
@ -64,7 +60,6 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
browser: [chrome]
|
||||
|
||||
services:
|
||||
|
@ -92,10 +87,10 @@ jobs:
|
|||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Copy Configure
|
||||
|
|
|
@ -20,11 +20,6 @@ jobs:
|
|||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
@ -32,10 +27,10 @@ jobs:
|
|||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
|
|
@ -15,20 +15,16 @@ jobs:
|
|||
name: Production build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
|
|
|
@ -16,20 +16,16 @@ jobs:
|
|||
validate-api-json:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22.11.0]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.2.0
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- name: Install Redocly CLI
|
||||
run: npm i -g @redocly/cli
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.11.0
|
||||
22.15.0
|
||||
|
|
125
CHANGELOG.md
125
CHANGELOG.md
|
@ -1,7 +1,105 @@
|
|||
## 2025.3.2
|
||||
## 2025.5.1
|
||||
|
||||
### General
|
||||
- Feat: チャットがリニューアルして復活しました(beta)
|
||||
- Feat: 非ログインでサーバーを閲覧された際に、サーバー内のコンテンツを非公開にすることができるようになりました
|
||||
- モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます
|
||||
- 「全て公開(今までの挙動)」「ローカルのコンテンツだけ公開(=サーバー内で受信されたリモートのコンテンツは公開しない)」「何も公開しない」から選択できます
|
||||
- デフォルト値は「ローカルのコンテンツだけ公開」になっています
|
||||
|
||||
### Client
|
||||
- Feat: サーバー初期設定ウィザードが実装されました
|
||||
- 簡単なウィザードに従うだけで、サーバーに最適な設定が適用されます
|
||||
- Feat: Websocket接続を行わずにMisskeyを利用するNo Websocketモードが実装されました(beta)
|
||||
- サーバーのパフォーマンス向上に寄与することが期待されます
|
||||
- 何らの理由によりWebsocket接続が行えない環境でも快適に利用可能です
|
||||
- 従来のWebsocket接続を行うモードはリアルタイムモードとして再定義されました
|
||||
- チャットなど、一部の機能は引き続き設定に関わらずWebsocket接続が行われます
|
||||
- Enhance: メモリ使用量を軽減しました
|
||||
- Enhance: 招待されているが参加していないルームを開いたときに、招待を承認するかどうか尋ねるように
|
||||
- Enhance: リプライ元にアンケートがあることが表示されるように
|
||||
- Enhance: ノートのサーバー情報のデザインを改善・パフォーマンス向上
|
||||
(Based on https://github.com/taiyme/misskey/pull/198, https://github.com/taiyme/misskey/pull/211, https://github.com/taiyme/misskey/pull/283)
|
||||
- Fix: "時計"ウィジェット(Clock)において、Transparent設定が有効でも、その背景が透過されない問題を修正
|
||||
|
||||
### Server
|
||||
- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加
|
||||
- Enhance: チャットルームのレスポンスに招待されているかどうかを示すフラグ`invitationExists`を追加
|
||||
- Fix: チャットルームが削除された場合・チャットルームから抜けた場合に、未読状態が残り続けることがあるのを修正
|
||||
- Fix: ユーザ除外アンテナをインポートできない問題を修正
|
||||
- Fix: アンテナのセンシティブなチャンネルのノートを含むかどうかの情報がエクスポートされない問題を修正
|
||||
|
||||
|
||||
## 2025.5.0
|
||||
|
||||
### Note
|
||||
- DockerのNode.jsが22.15.0に更新されました
|
||||
|
||||
### Client
|
||||
- Feat: マウスで中ボタンドラッグによりタイムラインを引っ張って更新できるように
|
||||
- アクセシビリティ設定からオフにすることもできます
|
||||
- Enhance: タイムラインのパフォーマンスを向上
|
||||
- Enhance: バックアップされた設定のプロファイルを削除できるように
|
||||
- Fix: 一部のブラウザでアコーディオンメニューのアニメーションが動作しない問題を修正
|
||||
- Fix: ダイアログのお知らせが画面からはみ出ることがある問題を修正
|
||||
- Fix: ユーザーポップアップでエラーが生じてもインジケーターが表示され続けてしまう問題を修正
|
||||
|
||||
### Server
|
||||
- Enhance: 凍結されたユーザのノートが各種タイムラインで表示されないように `#15775`
|
||||
- Enhance: 連合先のソフトウェア及びバージョン名により配信停止を行えるように `#15727`
|
||||
- Enhance: 2025.4.1 で追加されたインデックスの再生成をノートの追加しながら行えるようになりました。 `#15915`
|
||||
- `MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY` 環境変数を `1` にセットしていると、巨大なテーブルの既存のカラムに関するインデックス再生成が`CREATE INDEX CONCURRENTLY`を使用するようになりました。
|
||||
- 複数のサーバープロセスをクラスタリングしているサーバーにおいて、一部のプロセスが起動している状態でこのオプションを有効にしてマイグレーションすることにより、ダウンタイムを削減することができます。
|
||||
- ただし、このオプションを有効にする場合、インデックスの作成にかかる時間が倍~3倍以上になることがあります。
|
||||
- また、大きなインスタンスである場合にはインデックスの作成に失敗し、複数回再試行する必要がある可能性があります。
|
||||
- Fix: チャンネルのフォロー一覧の結果が一部正しくないのを修正 (#12175)
|
||||
- Fix: ファイルをアップロードした際にファイル名が常に untitled になる問題を修正
|
||||
- Fix: ファイルのアップロードに失敗することがある問題を修正
|
||||
- 投稿フォーム上で画像のクロップを行うと、`Invalid Param.`エラーでノートが投稿出来なくなる問題も解決されます。
|
||||
- この事象によって既にノートが投稿出来ない状態になっている場合は、投稿フォーム右上のメニューから、下書きデータの「リセット」を行ってください。
|
||||
|
||||
## 2025.4.1
|
||||
|
||||
### General
|
||||
- Feat: bull-boardに代わるジョブキューの管理ツールが実装されました
|
||||
- Feat: アップロード可能な最大ファイルサイズをロールごとに設定可能に
|
||||
- デフォルトで10MBになっています
|
||||
- Enhance: チャットの新規メッセージをプッシュ通知するように
|
||||
- Enhance: サーバーブロックの対象になっているサーバーについて、当該サーバーのユーザーや既知投稿を見えないように
|
||||
- Enhance: 依存関係の更新
|
||||
- Enhance: 翻訳の更新
|
||||
- Fix: セキュリティに関する修正
|
||||
|
||||
### Client
|
||||
- Feat: チャットウィジェットを追加
|
||||
- Feat: デッキにチャットカラムを追加
|
||||
- Feat: タイトルバーを表示できるように
|
||||
- Enhance: Unicode絵文字をslugから入力する際に`:ok:`のように最後の`:`を入力したあとにUnicode絵文字に変換できるように
|
||||
- Enhance: コントロールパネルでジョブキューをクリアできるように
|
||||
- Enhance: テーマでページヘッダーの色を変更できるように
|
||||
- Enhance: スワイプでのタブ切り替えを強化
|
||||
- Enhance: デザインのブラッシュアップ
|
||||
- Fix: ログアウトした際に処理が終了しない問題を修正
|
||||
- Fix: 自動バックアップが設定されている環境でログアウト直前に設定をバックアップするように
|
||||
- Fix: フォルダを開いた状態でメニューからアップロードしてもルートフォルダにアップロードされる問題を修正 #15836
|
||||
- Fix: タイムラインのスクロール位置を記憶するように修正
|
||||
- Fix: ノートの直後のノートを表示する機能で表示が逆順になっていた問題を修正 #15841
|
||||
- Fix: アカウントの移行時にアンテナのフィルターのユーザが更新されない問題を修正 #15843
|
||||
- Fix: タイムラインでノートが重複して表示されることがあるのを修正
|
||||
|
||||
### Server
|
||||
- Enhance: ジョブキューの成功/失敗したジョブも一定数・一定期間保存するようにし、後から問題を調査することを容易に
|
||||
- Enhance: フォローしているユーザーならフォロワー限定投稿のノートでもアンテナで検知できるように
|
||||
(Cherry-picked from https://github.com/yojo-art/cherrypick/pull/568 and https://github.com/team-shahu/misskey/pull/38)
|
||||
- Enhance: ユーザーごとにノートの表示が高速化するように
|
||||
- Fix: システムアカウントの名前がサーバー名と同期されない問題を修正
|
||||
- Fix: 大文字を含むユーザの URL で照会された場合に 404 エラーを返す問題 #15813
|
||||
- Fix: リードレプリカ設定時にレコードの追加・更新・削除を伴うクエリを発行した際はmasterノードで実行されるように調整( #10897 )
|
||||
- Fix: ファイルアップロード時の挙動を一部調整(#15895)
|
||||
|
||||
## 2025.4.0
|
||||
|
||||
### General
|
||||
- Feat: チャット(ダイレクトメッセージ)がリニューアルして復活しました
|
||||
- 既存のDM機能よりも便利で効率的な実装になっています
|
||||
- チャットを受け付ける相手を制限可能です
|
||||
- 誰でも / フォローユーザーのみ / フォロワーのみ / 相互のみ / 受け付けない から選択できます
|
||||
|
@ -11,9 +109,17 @@
|
|||
- 過去自分が送ったメッセージ・自分に送られたメッセージの検索が可能です
|
||||
- 参加中のルームをミュートして通知が来ないように設定可能です
|
||||
- メッセージにはリアクションも可能です
|
||||
- 現在、リモートユーザーがチャットを受け付ける設定になっているかどうかを取得する術がないため、ローカルユーザー間でのみ利用可能です
|
||||
- Feat: アカウントの移行時に古いアカウントからあたらしいアカウントにロールをコピーできるようになりました。
|
||||
- 管理者がロールの設定でマイグレーション時にコピーするかを指定できるようになります。
|
||||
- Enhance: セキュリティを強化するため、ジョブキューのダッシュボード(bull-board)統合が削除されました。
|
||||
- Misskeyネイティブでダッシュボードを実装予定です
|
||||
- Enhance: フロントエンドのエラートラッキングができるように
|
||||
- `.config/default.yml`中の項目`sentryForFrontend`を適宜設定してください。
|
||||
- 外部サービスであるSentryへエラー情報が送信されます。ご利用の地域の法令に従い、適切なプライバシーポリシーを策定の上で運用してください。
|
||||
- Enhance: ミュートしているユーザーをユーザー検索の結果から除外するように
|
||||
- Enhance: アンテナでセンシティブなチャンネルのノートを除外できるように `#14177`
|
||||
- Fix: 通知のページネーションで2つ以上読み込めなくなることがある問題を修正
|
||||
|
||||
### Client
|
||||
- Feat: 設定の管理が強化されました
|
||||
|
@ -22,7 +128,7 @@
|
|||
- プラグイン、テーマ、クライアントに追加されたすべてのアカウント情報も含まれるようになりました
|
||||
- 自動で設定データをサーバーにバックアップできるように
|
||||
- 設定→設定のプロファイル→自動バックアップ で有効にできます
|
||||
- 新しいデバイスからログインしたり、ブラウザから設定データが消えてしまったときに自動で復元されます(復元をスキップすることも可能)
|
||||
- ログインしたとき、ブラウザから設定データが消えてしまったときに自動で復元されます(復元をスキップすることも可能)
|
||||
- 任意の設定項目をデバイス間で同期できるように
|
||||
- 設定項目の「...」メニュー→「デバイス間で同期」
|
||||
- 同期をオンにした際にサーバーに保存された値とローカルの値が競合する場合はどちらを優先するか選択できます
|
||||
|
@ -31,14 +137,18 @@
|
|||
- アカウントごとに設定値が分離される設定とそうでないクライアント設定が混在していた(かつ分離するかどうかを設定不可だった)のを、基本的に一律でクライアント全体に適用されるようにし、個別でアカウントごとに異なる設定を行えるように
|
||||
- 設定項目の「...」メニュー→「アカウントで上書き」をオンにすることで、設定値をそのアカウントでだけ適用するようにできます
|
||||
- ログアウトすると設定データもブラウザから消去されるようになりプライバシーが向上しました
|
||||
- 再度ログインすればサーバーのバックアップから設定データを復元可能です
|
||||
- バックアップを有効にしている場合、ログインした後にバックアップから設定データを復元可能です
|
||||
- エクスポートした設定データを他のサーバーでインポートして適用すること(設定の持ち運び)が可能になりました
|
||||
- 設定情報の移行は自動で行われますが、何らかの理由で失敗した場合、設定→その他→旧設定情報を移行 で再試行可能です
|
||||
- 過去に作成されたバックアップデータとは現在互換性がありませんのでご注意ください
|
||||
- Feat: 画面を重ねて表示するオプションを実装(実験的)
|
||||
- 設定 → その他 → 実験的機能 → Enable stacking router view
|
||||
- Enhance: プラグインの管理が強化されました
|
||||
- インストール/アンインストール/設定の変更時にリロード不要になりました
|
||||
- Enhance: ログアウト時、ブラウザに保存されたWebクライアントのデータを全て消去するように
|
||||
- Enhance: デッキUIでカラム間のマージンを設定できるように
|
||||
- Enhance: デッキUIでデッキメニューの位置を設定できるように
|
||||
- Enhance: デッキUIでナビゲーションバーの位置を設定できるように
|
||||
- Enhance: アイコンのスクロール追従を無効化してパフォーマンス向上できるように
|
||||
- Enhance: CWの注釈テキストが入力されていない場合, Postボタンを非アクティブに
|
||||
- Enhance: CWを無効にした場合, 注釈テキストが最大入力文字数を超えていても投稿できるように
|
||||
|
@ -49,11 +159,13 @@
|
|||
- Enhance: 2段階認証時のリカバリーコードのファイル名にサーバーURLを含めるように
|
||||
- Enhance: 全体的なブラッシュアップ
|
||||
- Enhance 全体的なパフォーマンス向上
|
||||
- Enhance: ファイルのアップロードでデフォルトで圧縮するかどうかのオプションが廃止され、アップロード時に圧縮するかどうかを選択するようになりました
|
||||
- 画像データの貼り付け、ドロップ時は圧縮されるようになりました
|
||||
- Fix: 読み込み直後にスクロールしようとすると途中で止まる場合があるのを修正
|
||||
- Fix: テーマ切り替え時に一部の色が変わらない問題を修正
|
||||
- Fix: iPadOSでdeck uiをマウスカーソルによってスクロールできない問題を修正
|
||||
- NOTE: 構造上クラシックUIを新しいデザインシステムに移行することが困難なため、クラシックUIが削除されました
|
||||
- デッキUIでカラムを中央寄せにし、メインカラムの左右にウィジェットカラムを配置することである程度クラシックUIを再現できます
|
||||
- また、デッキでナビゲーションバーを上部に表示するオプションを実装予定です
|
||||
- デッキUIでカラムを中央寄せにし、メインカラムの左右にウィジェットカラムを配置し、ナビゲーションバーを上部に表示することである程度クラシックUIを再現できます
|
||||
|
||||
### Server
|
||||
- Enhance 全体的なパフォーマンス向上
|
||||
|
@ -61,6 +173,7 @@
|
|||
- Fix: ActivityPubリクエストURLチェック実装は仕様に従っていないのを修正
|
||||
- Fix: 連合無しモードでも外部から照会可能だった問題を修正
|
||||
- Fix: テスト用WebHookのペイロードの`emojis`パラメータが実際のものと異なる問題を修正
|
||||
- Fix: 非ログインでタイムラインのストリームに接続した際、表示にログイン必須のノートが流れる場合がある問題を修正
|
||||
|
||||
## 2025.3.1
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# syntax = docker/dockerfile:1.4
|
||||
|
||||
ARG NODE_VERSION=22.11.0-bookworm
|
||||
ARG NODE_VERSION=22.15.0-bookworm
|
||||
|
||||
# build assets & compile TypeScript
|
||||
|
||||
|
|
Binary file not shown.
|
@ -173,6 +173,11 @@ id: "aidx"
|
|||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
|
|
|
@ -2,11 +2,6 @@ import { defineConfig } from 'cypress'
|
|||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
baseUrl: 'http://localhost:61812',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -31,6 +31,15 @@ describe('Before setup instance', () => {
|
|||
// なぜか動かない
|
||||
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
||||
cy.wait('@signup');
|
||||
|
||||
cy.intercept('POST', '/api/admin/update-meta').as('update-meta');
|
||||
|
||||
cy.get('[data-cy-next]').click();
|
||||
cy.get('[data-cy-next]').click();
|
||||
cy.get('[data-cy-server-name] input').type('Testskey');
|
||||
cy.get('[data-cy-server-setup-wizard-apply]').click();
|
||||
|
||||
cy.wait('@update-meta');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
|
@ -215,7 +215,6 @@ noUsers: "ليس هناك مستخدمون"
|
|||
editProfile: "تعديل الملف التعريفي"
|
||||
noteDeleteConfirm: "هل تريد حذف هذه الملاحظة؟"
|
||||
pinLimitExceeded: "لا يمكنك تثبيت الملاحظات بعد الآن."
|
||||
intro: "لقد انتهت عملية تنصيب Misskey. الرجاء إنشاء حساب إداري."
|
||||
done: "تمّ"
|
||||
processing: "المعالجة جارية"
|
||||
preview: "معاينة"
|
||||
|
@ -676,7 +675,6 @@ experimental: "اختباري"
|
|||
developer: "المطور"
|
||||
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
||||
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
||||
showGapBetweenNotesInTimeline: "أظهر فجوات بين المشاركات في الخيط الزمني"
|
||||
left: "يسار"
|
||||
center: "وسط"
|
||||
wide: "عريض"
|
||||
|
@ -1240,7 +1238,6 @@ _theme:
|
|||
shadow: "الظل"
|
||||
navBg: "خلفية الشريط الجانبي"
|
||||
navFg: "نص الشريط الجانبي"
|
||||
navHoverFg: "نص الشريط الجانبي (عند التمرير فوقه)"
|
||||
link: "رابط"
|
||||
hashtag: "وسم"
|
||||
mention: "أشر الى"
|
||||
|
|
|
@ -215,7 +215,6 @@ noUsers: "কোন ব্যাবহারকারী নেই"
|
|||
editProfile: "প্রোফাইল সম্পাদনা করুন"
|
||||
noteDeleteConfirm: "আপনি কি নোট ডিলিট করার ব্যাপারে নিশ্চিত?"
|
||||
pinLimitExceeded: "আপনি আর কোন নোট পিন করতে পারবেন না"
|
||||
intro: "Misskey এর ইন্সটলেশন সম্পন্ন হয়েছে!দয়া করে অ্যাডমিন ইউজার তৈরি করুন।"
|
||||
done: "সম্পন্ন"
|
||||
processing: "প্রক্রিয়াধীন..."
|
||||
preview: "পূর্বরূপ দেখুন"
|
||||
|
@ -673,7 +672,6 @@ experimentalFeatures: "পরীক্ষামূলক বৈশিষ্ট
|
|||
developer: "ডেভেলপার"
|
||||
makeExplorable: "অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় দেখান"
|
||||
makeExplorableDescription: "আপনি এটি বন্ধ করলে, আপনার অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় প্রদর্শিত হবে না।"
|
||||
showGapBetweenNotesInTimeline: "টাইমলাইন এবং নোটের মাঝে ফাকা জায়গা রাখুন"
|
||||
duplicate: "প্রতিরূপ"
|
||||
left: "বাম"
|
||||
center: "মাঝখান"
|
||||
|
@ -998,7 +996,6 @@ _theme:
|
|||
header: "হেডার"
|
||||
navBg: "সাইডবারের পটভূমি"
|
||||
navFg: "সাইডবারের পাঠ্য"
|
||||
navHoverFg: "সাইডবারের পাঠ্য (হভার)"
|
||||
navActive: "সাইডবারের পাঠ্য (অ্যাকটিভ)"
|
||||
navIndicator: "সাইডবারের ইনডিকেটর"
|
||||
link: "লিংক"
|
||||
|
@ -1021,11 +1018,8 @@ _theme:
|
|||
buttonHoverBg: "বাটনের পটভূমি (হভার)"
|
||||
inputBorder: "ইনপুট ফিল্ডের বর্ডার"
|
||||
driveFolderBg: "ড্রাইভ ফোল্ডারের পটভূমি"
|
||||
wallpaperOverlay: "ওয়ালপেপার ওভারলে"
|
||||
badge: "ব্যাজ"
|
||||
messageBg: "চ্যাটের পটভূমি"
|
||||
accentDarken: "অ্যাকসেন্ট (গাঢ়)"
|
||||
accentLighten: "অ্যাকসেন্ট (হাল্কা)"
|
||||
fgHighlighted: "হাইলাইট করা পাঠ্য"
|
||||
_sfx:
|
||||
note: "নোটগুলি"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "Silencia aquesta instància "
|
|||
mediaSilenceThisInstance: "Silenciar els arxius d'aquesta instància "
|
||||
operations: "Accions"
|
||||
software: "Programari"
|
||||
softwareName: "Nom del programari"
|
||||
version: "Versió"
|
||||
metadata: "Metadades"
|
||||
withNFiles: "{n} fitxer(s)"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "No hi ha usuaris"
|
|||
editProfile: "Edita el perfil"
|
||||
noteDeleteConfirm: "Segur que voleu eliminar aquesta publicació?"
|
||||
pinLimitExceeded: "No podeu fixar més publicacions"
|
||||
intro: "La instal·lació de Misskey ha acabat! Crea un usuari d'administrador."
|
||||
done: "Fet"
|
||||
processing: "S'està processant..."
|
||||
preview: "Vista prèvia"
|
||||
|
@ -280,7 +280,7 @@ featured: "Destacat"
|
|||
usernameOrUserId: "Nom o ID d'usuari"
|
||||
noSuchUser: "No s'ha trobat l'usuari"
|
||||
lookup: "Cerca"
|
||||
announcements: "Anuncis"
|
||||
announcements: "Avisos"
|
||||
imageUrl: "URL de la imatge"
|
||||
remove: "Eliminar"
|
||||
removed: "Eliminat"
|
||||
|
@ -356,7 +356,7 @@ banner: "Bàner"
|
|||
displayOfSensitiveMedia: "Visualització de contingut sensible"
|
||||
whenServerDisconnected: "Quan es perdi la connexió al servidor"
|
||||
disconnectedFromServer: "Desconnectat pel servidor"
|
||||
reload: "Actualitza"
|
||||
reload: "Actualitzar"
|
||||
doNothing: "Ignora"
|
||||
reloadConfirm: "Vols recarregar?"
|
||||
watch: "Veure"
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "Exclou els bots"
|
|||
antennaKeywordsDescription: "Separar amb espais per la condició AND o amb salts de línia per la condició OR."
|
||||
notifyAntenna: "Notifica'm les publicacions noves"
|
||||
withFileAntenna: "Només les publicacions amb fitxers"
|
||||
excludeNotesInSensitiveChannel: "Excloure notes a canals sensibles"
|
||||
enableServiceworker: "Activar les notificacions al navegador"
|
||||
antennaUsersDescription: "Llistar un nom d'usuari per línia"
|
||||
caseSensitive: "Sensible a majúscules i minúscules "
|
||||
|
@ -536,7 +537,7 @@ mediaListWithOneImageAppearance: "Altura de la llista de fitxers amb una única
|
|||
limitTo: "Limita a {x}"
|
||||
noFollowRequests: "No tens sol·licituds de seguiment"
|
||||
openImageInNewTab: "Obre imatges a una nova pestanya"
|
||||
dashboard: "Taulell de control"
|
||||
dashboard: "Tauler de control"
|
||||
local: "Local"
|
||||
remote: "Remot"
|
||||
total: "Total"
|
||||
|
@ -651,7 +652,7 @@ manage: "Administració"
|
|||
plugins: "Extensions"
|
||||
preferencesBackups: "Configuracions de les Còpies de seguretat"
|
||||
deck: "Escriptori"
|
||||
undeck: "Tanca l'escriptori"
|
||||
undeck: "Tanca el tauler"
|
||||
useBlurEffectForModal: "Utilitzar l'efecte de difuminació a modals"
|
||||
useFullReactionPicker: "Utilitza el cercador de reaccions d'escala sencera"
|
||||
width: "Amplada"
|
||||
|
@ -707,7 +708,7 @@ notificationSetting: "Paràmetres de notificacions"
|
|||
notificationSettingDesc: "Selecciona els tipus de notificacions que es mostraran"
|
||||
useGlobalSetting: "Fer servir la configuració global"
|
||||
useGlobalSettingDesc: "Si s'activa, es farà servir la configuració de notificacions del teu comte. Si no s'activa es poden fer configuracions individuals."
|
||||
other: "Altre"
|
||||
other: "Altres"
|
||||
regenerateLoginToken: "Regenerar clau de seguretat d'inici de sessió"
|
||||
regenerateLoginTokenDescription: "Regenera la clau de seguretat que es fa servir internament durant l'inici de sessió. Normalment aquesta acció no és necessària. Si es regenera es tancarà la sessió a tots els dispositius amb una sessió activa."
|
||||
theKeywordWhenSearchingForCustomEmoji: "Cercar un emoji personalitzat "
|
||||
|
@ -783,7 +784,6 @@ thisIsExperimentalFeature: "Aquesta és una característica experimental. La sev
|
|||
developer: "Programador"
|
||||
makeExplorable: "Fes que el compte sigui visible a la secció \"Explorar\""
|
||||
makeExplorableDescription: "Si desactives aquesta opció, el teu compte no sortirà a la secció \"Explorar\""
|
||||
showGapBetweenNotesInTimeline: "Notes separades a la línia de temps"
|
||||
duplicate: "Duplicat"
|
||||
left: "Esquerra"
|
||||
center: "Centre"
|
||||
|
@ -870,7 +870,7 @@ gallery: "Galeria"
|
|||
recentPosts: "Articles recents"
|
||||
popularPosts: "Articles populars"
|
||||
shareWithNote: "Comparteix amb una nota"
|
||||
ads: "Anuncis"
|
||||
ads: "Publicitat "
|
||||
expiration: ""
|
||||
startingperiod: "Inici"
|
||||
memo: "Recordatori"
|
||||
|
@ -914,7 +914,7 @@ off: "Desactivar"
|
|||
emailRequiredForSignup: "Demanar correu electrònic per registrar-se "
|
||||
unread: "Sense llegir"
|
||||
filter: "Filtrar"
|
||||
controlPanel: "Taulell de control"
|
||||
controlPanel: "Tauler de control"
|
||||
manageAccounts: "Gestionar comptes"
|
||||
makeReactionsPublic: "Reaccions públiques "
|
||||
makeReactionsPublicDescription: "Això fa que totes les teves reaccions siguin visibles públicament "
|
||||
|
@ -978,6 +978,7 @@ document: "Documentació"
|
|||
numberOfPageCache: "Nombre de pàgines a la memòria cau"
|
||||
numberOfPageCacheDescription: "Incrementant aquest nombre farà que millori l'experiència de l'usuari, però es farà servir més memòria al dispositiu de l'usuari."
|
||||
logoutConfirm: "Vols sortir?"
|
||||
logoutWillClearClientData: "En tancar la sessió, la informació del client al navegador s'esborrarà. Per garantir que la informació de configuració es pugui restaurar en tornar a iniciar sessió activa la còpia de seguretat automàtica de la configuració."
|
||||
lastActiveDate: "Fet servir per última vegada"
|
||||
statusbar: "Barra d'estat"
|
||||
pleaseSelect: "Selecciona una opció"
|
||||
|
@ -1108,7 +1109,7 @@ accountMigration: "Migració del compte"
|
|||
accountMoved: "Aquest usuari té un compte nou:"
|
||||
accountMovedShort: "Aquest compte ha sigut migrat"
|
||||
operationForbidden: "Operació no permesa "
|
||||
forceShowAds: "Mostra els anuncis sempre "
|
||||
forceShowAds: "Mostrar publicitat sempre "
|
||||
addMemo: "Afegir recordatori"
|
||||
editMemo: "Editar recordatori"
|
||||
reactionsList: "Reaccions"
|
||||
|
@ -1128,7 +1129,7 @@ pleaseAgreeAllToContinue: "Has d'acceptar tots els camps de dalt per poder conti
|
|||
continue: "Continuar"
|
||||
preservedUsernames: "Noms d'usuaris reservats"
|
||||
preservedUsernamesDescription: "Llistat de noms d'usuaris que no es poden fer servir separats per salts de linia. Aquests noms d'usuaris no estaran disponibles quan es creï un compte d'usuari normal, però els administradors els poden fer servir per crear comptes manualment. Per altre banda els comptes ja creats amb aquests noms d'usuari no es veure'n afectats."
|
||||
createNoteFromTheFile: "Compon una nota des d'aquest fitxer"
|
||||
createNoteFromTheFile: "Escriu una nota incloent aquest fitxer"
|
||||
archive: "Arxiu"
|
||||
archived: "Arxivat"
|
||||
unarchive: "Desarxivar"
|
||||
|
@ -1183,8 +1184,8 @@ iHaveReadXCarefullyAndAgree: "He llegit {x} i estic d'acord."
|
|||
dialog: "Diàleg "
|
||||
icon: "Icona"
|
||||
forYou: "Per a tu"
|
||||
currentAnnouncements: "Informes actuals"
|
||||
pastAnnouncements: "Informes passats"
|
||||
currentAnnouncements: "Avisos actuals"
|
||||
pastAnnouncements: "Avisos passats"
|
||||
youHaveUnreadAnnouncements: "Tens informes per llegir."
|
||||
useSecurityKey: "Segueix les instruccions del teu navegador O dispositiu per fer servir el teu passkey."
|
||||
replies: "Respostes"
|
||||
|
@ -1235,7 +1236,6 @@ showAvatarDecorations: "Mostrar les decoracions dels avatars"
|
|||
releaseToRefresh: "Deixar anar per actualitzar"
|
||||
refreshing: "Recarregant..."
|
||||
pullDownToRefresh: "Llisca cap a baix per recarregar"
|
||||
disableStreamingTimeline: "Desactivar l'actualització en temps real de les línies de temps"
|
||||
useGroupedNotifications: "Mostrar les notificacions agrupades "
|
||||
signupPendingError: "Hi ha hagut un problema verificant l'adreça de correu electrònic. L'enllaç pot haver caducat."
|
||||
cwNotationRequired: "Si està activat \"Amagar contingut\" s'ha d'escriure una descripció "
|
||||
|
@ -1333,9 +1333,19 @@ postForm: "Formulari de publicació"
|
|||
textCount: "Nombre de caràcters "
|
||||
information: "Informació"
|
||||
chat: "Xat"
|
||||
migrateOldSettings: "Migració de la configuració antiga "
|
||||
migrateOldSettings: "Migrar la configuració anterior"
|
||||
migrateOldSettings_description: "Normalment això es fa automàticament, però si la transició no es fa, el procés es pot iniciar manualment. S'esborrarà la configuració actual."
|
||||
compress: "Comprimir "
|
||||
right: "Dreta"
|
||||
bottom: "A baix "
|
||||
top: "A dalt "
|
||||
embed: "Incrustar"
|
||||
settingsMigrating: "Estem migrant la teva configuració. Si us plau espera un moment... (També pots fer la migració més tard, manualment, anant a Preferències → Altres → Migrar configuració antiga)"
|
||||
readonly: "Només lectura"
|
||||
goToDeck: "Tornar al tauler"
|
||||
federationJobs: "Treballs sindicats "
|
||||
driveAboutTip: "Al Disc veure's una llista de tots els arxius que has anat pujant.<br>\nPots tornar-los a fer servir adjuntant-los a notes noves o pots adelantar-te i pujar arxius per publicar-los més tard!<br>\n<b>Tingués en compte que si esborres un arxiu també desapareixerà de tots els llocs on l'has fet servir (notes, pàgines, avatars, imatges de capçalera, etc.)</b><br>\nTambé pots crear carpetes per organitzar les."
|
||||
scrollToClose: "Desplaçar per tancar"
|
||||
_chat:
|
||||
noMessagesYet: "Encara no tens missatges "
|
||||
newMessage: "Missatge nou"
|
||||
|
@ -1351,7 +1361,7 @@ _chat:
|
|||
noInvitations: "No tens cap invitació "
|
||||
history: "Historial de converses "
|
||||
noHistory: "No hi ha un registre previ"
|
||||
noRooms: "No hi ha habitacions"
|
||||
noRooms: "No hi ha cap sala"
|
||||
inviteUser: "Invitar usuaris"
|
||||
sentInvitations: "Enviar invitacions"
|
||||
join: "Afegir-se "
|
||||
|
@ -1365,6 +1375,7 @@ _chat:
|
|||
muteThisRoom: "Silenciar aquesta sala"
|
||||
deleteRoom: "Esborrar la sala"
|
||||
chatNotAvailableForThisAccountOrServer: "El xat no està disponible per aquest servidor o aquest compte."
|
||||
chatIsReadOnlyForThisAccountOrServer: "El xat és només de lectura en aquest servidor o compte. No es poden escriure nous missatges ni crear o unir-se a sales de xat."
|
||||
chatNotAvailableInOtherAccount: "La funció de xat es troba desactivada al compte de l'altre usuari."
|
||||
cannotChatWithTheUser: "No pots xatejar amb aquest usuari"
|
||||
cannotChatWithTheUser_description: "El xat està desactivat o l'altra part encara no l'ha obert."
|
||||
|
@ -1408,8 +1419,11 @@ _settings:
|
|||
makeEveryTextElementsSelectable_description: "L'activació pot reduir la usabilitat en determinades ocasions."
|
||||
useStickyIcons: "Utilitza icones fixes"
|
||||
showNavbarSubButtons: "Mostrar sub botons a la barra de navegació "
|
||||
ifOn: "Quan s'encén "
|
||||
ifOff: "Quan s'apaga "
|
||||
ifOn: "Quan s'activa"
|
||||
ifOff: "Quan es desactiva"
|
||||
enableSyncThemesBetweenDevices: "Sincronitzar els temes instal·lats entre dispositius"
|
||||
enablePullToRefresh: "Lliscar i actualitzar "
|
||||
enablePullToRefresh_description: "Amb el ratolí, llisca mentre prems la roda."
|
||||
_chat:
|
||||
showSenderName: "Mostrar el nom del remitent"
|
||||
sendOnEnter: "Introdueix per enviar"
|
||||
|
@ -1417,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Nom del perfil"
|
||||
profileNameDescription: "Estableix un nom que identifiqui aquest dispositiu."
|
||||
profileNameDescription2: "Per exemple: \"PC Principal\", \"Smartphone\", etc"
|
||||
manageProfiles: "Gestionar perfils"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Còpia de seguretat automàtica "
|
||||
restoreFromBackup: "Restaurar des d'una còpia de seguretat"
|
||||
|
@ -1455,6 +1470,7 @@ _delivery:
|
|||
manuallySuspended: "Suspendre manualment"
|
||||
goneSuspended: "Servidor suspès perquè el servidor s'ha esborrat"
|
||||
autoSuspendedForNotResponding: "Servidor suspès perquè el servidor no respon"
|
||||
softwareSuspended: "Suspès perquè el programari ha deixat de desenvolupar-se "
|
||||
_bubbleGame:
|
||||
howToPlay: "Com es juga"
|
||||
hold: "Mantenir"
|
||||
|
@ -1476,7 +1492,7 @@ _announcement:
|
|||
needConfirmationToRead: "Es necessita confirmació de lectura de la notificació "
|
||||
needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació. A més aquesta notificació serà exclosa de qualsevol funcionalitat com \"Marcar tot com a llegit\"."
|
||||
end: "Final de la notificació "
|
||||
tooManyActiveAnnouncementDescription: "Tenir massa notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els anuncis que siguin antics."
|
||||
tooManyActiveAnnouncementDescription: "Tenir massa notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els avisos que siguin antics."
|
||||
readConfirmTitle: "Marcar com llegida?"
|
||||
readConfirmText: "Això marcarà el contingut de \"{title}\" com llegit."
|
||||
shouldNotBeUsedToPresentPermanentInfo: "Ja que l'ús de notificacions pot impactar l'experiència dels nous usuaris, és recomanable fer servir les notificacions amb el flux d'informació en comptes de fer-les servir en un únic bloc."
|
||||
|
@ -1586,6 +1602,8 @@ _serverSettings:
|
|||
openRegistration: "Registres oberts"
|
||||
openRegistrationWarning: "Obrir els registres és arriscat. Es recomana obrir-los només si el servidor és monitorat constantment i per respondre immediatament davant qualsevol problema."
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Si no es detecta activitat per part del moderador durant un període de temps, aquesta opció es desactiva automàticament per evitar el correu brossa."
|
||||
deliverSuspendedSoftware: "Programari que ja no es distribueix"
|
||||
deliverSuspendedSoftwareDescription: "Pots especificar un rang de noms i versions del programari del servidor per detenir l'entrega, per exemple, degut a vulnerabilitats. Aquesta informació la proporciona el servidor i la seva fiabilitat no es garantitzada. Es pot fer servir una especificació de rang sencer per especificar una versió, però es recomana especificar una versió anterior, com >= 2024.3.1-0, perquè especificar >= 2024.3.1 no incloure versions personalitzades com 2024.3.1-custom.0."
|
||||
_accountMigration:
|
||||
moveFrom: "Migrar un altre compte a aquest"
|
||||
moveFromSub: "Crear un àlies per un altre compte"
|
||||
|
@ -1594,7 +1612,7 @@ _accountMigration:
|
|||
moveTo: "Migrar aquest compte a un altre"
|
||||
moveToLabel: "Compte al qual es vol migrar:"
|
||||
moveCannotBeUndone: "Les migracions dels comptes no es poden desfer."
|
||||
moveAccountDescription: "Això migrarà la teva compte a un altre diferent.\n ・Els seguidors d'aquest compte és passaran al compte nou de forma automàtica\n ・Es deixaran de seguir a tots els usuaris que es segueixen actualment en aquest compte\n ・No es poden crear notes noves, etc. en aquest compte\n\nSi bé la migració de seguidors es automàtica, has de preparar alguns pasos manualment per migrar la llista d'usuaris que segueixes. Per fer això has d'exportar els seguidors que després importaraes al compte nou mitjançant el menú de configuració. El mateix procediment s'ha de seguir per less teves llistes i els teus usuaris silenciats i bloquejats.\n\n(Aquesta explicació s'aplica a Misskey v13.12.0 i posteriors. Altres aplicacions, com Mastodon, poden funcionar diferent.)"
|
||||
moveAccountDescription: "Això migrarà el teu compte a un altre diferent.\n ・Els seguidors d'aquest compte és passaran al compte nou de forma automàtica\n ・Es deixaran de seguir a tots els usuaris que es segueixen actualment en aquest compte\n ・No es poden crear notes noves, etc. en aquest compte\n\nSi bé la migració de seguidors es automàtica, has de preparar alguns pasos manualment per migrar la llista d'usuaris que segueixes. Per fer això has d'exportar els seguidors que després importaraes al compte nou mitjançant el menú de configuració. El mateix procediment s'ha de seguir per less teves llistes i els teus usuaris silenciats i bloquejats.\n\n(Aquesta explicació s'aplica a Misskey v13.12.0 i posteriors. Altres aplicacions, com Mastodon, poden funcionar diferent.)"
|
||||
moveAccountHowTo: "Per fer la migració, primer has de crear un àlies per aquest compte al compte al qual vols migrar.\nDesprés de crear l'àlies, introdueix el compte al qual vols migrar amb el format següent: @nomusuari@servidor.exemple.com"
|
||||
startMigration: "Migrar"
|
||||
migrationConfirm: "Vols migrar aquest compte a {account}? Una vegada comenci la migració no es podrà parar O fer marxa enrere i no podràs tornar a fer servir aquest compte mai més."
|
||||
|
@ -1882,6 +1900,8 @@ _role:
|
|||
descriptionOfIsExplorable: "La línia de temps d'aquest rol i la llista d'usuaris seran públics si s'activa."
|
||||
displayOrder: "Posició "
|
||||
descriptionOfDisplayOrder: "Com més gran és el número, més dalt la seva posició a la interfície."
|
||||
preserveAssignmentOnMoveAccount: "L'estat de l'assignació també es trasllada amb el compte migrat"
|
||||
preserveAssignmentOnMoveAccount_description: "Si s'activa quan es migra un compte amb aquest rol, el compte migrat també heretarà aquest rol."
|
||||
canEditMembersByModerator: "Permetre que els moderadors editin la llista d'usuaris en aquest rol"
|
||||
descriptionOfCanEditMembersByModerator: "Quan s'activa, els moderadors, així com els administradors, podran afegir i treure usuaris d'aquest rol. Si es troba desactivat, només els administradors poden assignar usuaris."
|
||||
priority: "Prioritat"
|
||||
|
@ -1901,6 +1921,7 @@ _role:
|
|||
canManageCustomEmojis: "Gestiona els emojis personalitzats"
|
||||
canManageAvatarDecorations: "Gestiona les decoracions dels avatars "
|
||||
driveCapacity: "Capacitat del disc"
|
||||
maxFileSize: "Mida màxima de l'arxiu que es pot carregar"
|
||||
alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles"
|
||||
canUpdateBioMedia: "Permet l'edició d'una icona o un bàner"
|
||||
pinMax: "Nombre màxim de notes fixades"
|
||||
|
@ -1913,7 +1934,7 @@ _role:
|
|||
userEachUserListsMax: "Nombre màxim d'usuaris dintre d'una llista d'usuaris "
|
||||
rateLimitFactor: "Limitador"
|
||||
descriptionOfRateLimitFactor: "Límits baixos són menys restrictius, límits alts són més restrictius."
|
||||
canHideAds: "Pot amagar els anuncis"
|
||||
canHideAds: "Pot amagar la publicitat"
|
||||
canSearchNotes: "Pot cercar notes"
|
||||
canUseTranslator: "Pot fer servir el traductor"
|
||||
avatarDecorationLimit: "Nombre màxim de decoracions que es poden aplicar els avatars"
|
||||
|
@ -1922,7 +1943,7 @@ _role:
|
|||
canImportFollowing: "Autoritza la importació de seguidors"
|
||||
canImportMuting: "Autoritza la importació de silenciats"
|
||||
canImportUserLists: "Autoritza la importació de llistes d'usuaris "
|
||||
canChat: "Pot xatejar"
|
||||
chatAvailability: "Es permet xatejar"
|
||||
_condition:
|
||||
roleAssignedTo: "Assignat a rols manuals"
|
||||
isLocal: "Usuari local"
|
||||
|
@ -1978,8 +1999,8 @@ _ad:
|
|||
reduceFrequencyOfThisAd: "Mostrar menys aquest anunci"
|
||||
hide: "No mostrar mai"
|
||||
timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor."
|
||||
adsSettings: "Configuració d'anuncis "
|
||||
notesPerOneAd: "Interval d'emplaçament d'anuncis en temps real (Notes per anuncis)"
|
||||
adsSettings: "Configurar la publicitat"
|
||||
notesPerOneAd: "Interval d'emplaçament publicitari en temps real (Notes per anuncis)"
|
||||
setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització d'anuncis en temps real"
|
||||
adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix."
|
||||
_forgotPassword:
|
||||
|
@ -2114,12 +2135,11 @@ _theme:
|
|||
fg: "Text"
|
||||
focus: "Enfocament"
|
||||
indicator: "Indicador"
|
||||
panel: "Taulell "
|
||||
panel: "Tauler"
|
||||
shadow: "Ombra"
|
||||
header: "Capçalera"
|
||||
navBg: "Fons de la barra lateral"
|
||||
navFg: "Text de la barra lateral"
|
||||
navHoverFg: "Text barra lateral (en passar per sobre)"
|
||||
navActive: "Text barra lateral (actiu)"
|
||||
navIndicator: "Indicador barra lateral"
|
||||
link: "Enllaç"
|
||||
|
@ -2142,11 +2162,8 @@ _theme:
|
|||
buttonHoverBg: "Fons botó (en passar-hi per sobre)"
|
||||
inputBorder: "Contorn del cap d'introducció "
|
||||
driveFolderBg: "Fons de la carpeta Disc"
|
||||
wallpaperOverlay: "Superposició del fons de pantalla "
|
||||
badge: "Insígnia "
|
||||
messageBg: "Fons del xat"
|
||||
accentDarken: "Accent (fosc)"
|
||||
accentLighten: "Accent (clar)"
|
||||
fgHighlighted: "Text ressaltat"
|
||||
_sfx:
|
||||
note: "Notes"
|
||||
|
@ -2360,6 +2377,7 @@ _widgets:
|
|||
chooseList: "Tria una llista"
|
||||
clicker: "Clicker"
|
||||
birthdayFollowings: "Usuaris que fan l'aniversari avui"
|
||||
chat: "Xat"
|
||||
_cw:
|
||||
hide: "Amagar"
|
||||
show: "Carregar més"
|
||||
|
@ -2593,7 +2611,10 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "Mostrar sempre la columna principal"
|
||||
columnAlign: "Alinea les columnes"
|
||||
addColumn: "Afig una columna"
|
||||
columnGap: "Espai entre columnes"
|
||||
deckMenuPosition: "Posició del menú del tauler"
|
||||
navbarPosition: "Posició de la barra de navegació "
|
||||
addColumn: "Afegeix una columna"
|
||||
newNoteNotificationSettings: "Configuració de notificacions per a notes noves"
|
||||
configureColumn: "Configuració de columnes"
|
||||
swapLeft: "Mou a l’esquerra"
|
||||
|
@ -2623,6 +2644,7 @@ _deck:
|
|||
mentions: "Mencions"
|
||||
direct: "Publicacions directes"
|
||||
roleTimeline: "Línia de temps dels rols"
|
||||
chat: "Xat"
|
||||
_dialog:
|
||||
charactersExceeded: "Has arribat al màxim de caràcters! Actualment és {current} de {max}"
|
||||
charactersBelow: "Ets per sota del mínim de caràcters! Actualment és {current} de {min}"
|
||||
|
@ -2788,7 +2810,7 @@ _hemisphere:
|
|||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Opcions del joc"
|
||||
chooseBoard: "Escull un taulell"
|
||||
chooseBoard: "Escull un tauler"
|
||||
blackOrWhite: "Negres/Blanques"
|
||||
blackIs: "{name} juga amb negres "
|
||||
rules: "Regles"
|
||||
|
|
|
@ -228,7 +228,6 @@ noUsers: "Žádní uživatelé"
|
|||
editProfile: "Upravit můj profil"
|
||||
noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?"
|
||||
pinLimitExceeded: "Nemůžete připnout další poznámky."
|
||||
intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina."
|
||||
done: "Hotovo"
|
||||
processing: "Zpracovávám"
|
||||
preview: "Náhled"
|
||||
|
@ -726,7 +725,6 @@ thisIsExperimentalFeature: "Tohle je experimentální funkce. Její funkce se m
|
|||
developer: "Vývojář"
|
||||
makeExplorable: "Udělat účet viditelný v \"Objevit\""
|
||||
makeExplorableDescription: "Pokud tohle vypnete, tak se účet přestane zobrazovat v sekci \"Objevit\"."
|
||||
showGapBetweenNotesInTimeline: "Zobrazit mezeru mezi příspěvkama na časové ose"
|
||||
duplicate: "Duplikovat"
|
||||
left: "Vlevo"
|
||||
center: "Uprostřed"
|
||||
|
@ -1626,7 +1624,6 @@ _theme:
|
|||
header: "Nadpis"
|
||||
navBg: "Pozadí postranního panelu"
|
||||
navFg: "Text na postranním panelu"
|
||||
navHoverFg: "Text na postranním panelu (Hover)"
|
||||
navActive: "Text na postranním panelu (Aktivní)"
|
||||
navIndicator: "Indikátor na postranním panelu"
|
||||
link: "Odkaz"
|
||||
|
@ -1649,11 +1646,8 @@ _theme:
|
|||
buttonHoverBg: "Pozadí tlačítka (Hover)"
|
||||
inputBorder: "Ohraničení vstupního pole"
|
||||
driveFolderBg: "Pozadí složky disku"
|
||||
wallpaperOverlay: "Překrytí tapety"
|
||||
badge: "Odznak"
|
||||
messageBg: "Pozadí chatu"
|
||||
accentDarken: "Akcent (Ztmavený)"
|
||||
accentLighten: "Akcent (Zesvětlený)"
|
||||
fgHighlighted: "Zvýrazněný text"
|
||||
_sfx:
|
||||
note: "Poznámky"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "Instanz stummschalten"
|
|||
mediaSilenceThisInstance: "Medien dieses Servers stummschalten"
|
||||
operations: "Aktionen"
|
||||
software: "Software"
|
||||
softwareName: "Software Name"
|
||||
version: "Version"
|
||||
metadata: "Metadaten"
|
||||
withNFiles: "{n} Datei(en)"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "Keine Benutzer gefunden"
|
|||
editProfile: "Profil bearbeiten"
|
||||
noteDeleteConfirm: "Möchtest du diese Notiz wirklich löschen?"
|
||||
pinLimitExceeded: "Du kannst nicht noch mehr Notizen anheften."
|
||||
intro: "Misskey ist installiert! Lass uns nun ein Administratorkonto einrichten."
|
||||
done: "Fertig"
|
||||
processing: "In Bearbeitung …"
|
||||
preview: "Vorschau"
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "Bot-Accounts ausschließen"
|
|||
antennaKeywordsDescription: "Zum Nutzen einer \"UND\"-Verknüpfung Einträge mit Leerzeichen trennen, zum Nutzen einer \"ODER\"-Verknüpfung Einträge mit einem Zeilenumbruch trennen"
|
||||
notifyAntenna: "Über neue Notizen benachrichtigen"
|
||||
withFileAntenna: "Nur Notizen mit Dateien"
|
||||
excludeNotesInSensitiveChannel: "Schließe Notizen von sensitive Kanäle aus"
|
||||
enableServiceworker: "Push-Benachrichtigungen im Browser aktivieren"
|
||||
antennaUsersDescription: "Benutzernamen getrennt durch Zeilenumbrüche angeben"
|
||||
caseSensitive: "Groß-/Kleinschreibung unterscheiden"
|
||||
|
@ -783,7 +784,6 @@ thisIsExperimentalFeature: "Dies ist eine experimentelle Funktion. Änderungen a
|
|||
developer: "Entwickler"
|
||||
makeExplorable: "Benutzerkonto in „Erkunden“ sichtbar machen"
|
||||
makeExplorableDescription: "Wenn diese Option deaktiviert ist, ist dein Benutzerkonto nicht im „Erkunden“-Bereich sichtbar."
|
||||
showGapBetweenNotesInTimeline: "Abstände zwischen Notizen auf der Chronik anzeigen"
|
||||
duplicate: "Duplizieren"
|
||||
left: "Links"
|
||||
center: "Mittig"
|
||||
|
@ -962,8 +962,8 @@ cropImageAsk: "Möchtest du das Bild zuschneiden?"
|
|||
cropYes: "Zuschneiden"
|
||||
cropNo: "Unbearbeitet verwenden"
|
||||
file: "Datei"
|
||||
recentNHours: "Letzten {n} Stunden"
|
||||
recentNDays: "Letzten {n} Tage"
|
||||
recentNHours: "Letzte {n} Stunden"
|
||||
recentNDays: "Letzte {n} Tage"
|
||||
noEmailServerWarning: "Es ist kein Email-Server konfiguriert."
|
||||
thereIsUnresolvedAbuseReportWarning: "Es liegen ungelöste Meldungen vor."
|
||||
recommended: "Empfehlung"
|
||||
|
@ -971,13 +971,14 @@ check: "Check"
|
|||
driveCapOverrideLabel: "Die Drive-Kapazität dieses Nutzers verändern"
|
||||
driveCapOverrideCaption: "Gib einen Wert von 0 oder weniger ein, um die Kapazität auf den Standard zurückzusetzen."
|
||||
requireAdminForView: "Melde dich mit einem Administratorkonto an, um dies einzusehen."
|
||||
isSystemAccount: "Ein Benutzerkonto, dass durch das System erstellt und automatisch kontrolliert wird."
|
||||
isSystemAccount: "Ein Benutzerkonto, das durch das System erstellt und automatisch verwaltet wird."
|
||||
typeToConfirm: "Bitte gib zur Bestätigung {x} ein"
|
||||
deleteAccount: "Benutzerkonto löschen"
|
||||
document: "Dokumentation"
|
||||
numberOfPageCache: "Seitencachegröße"
|
||||
numberOfPageCacheDescription: "Das Erhöhen dieses Caches führt zu einer angenehmerern Benutzererfahrung, aber erhöht Last und Arbeitsspeicherauslastung auf dem Nutzergerät."
|
||||
logoutConfirm: "Wirklich abmelden?"
|
||||
logoutWillClearClientData: "Beim Abmelden werden die Konfigurationsdaten des Clients aus dem Browser gelöscht. Um sicherzustellen, dass die Konfigurationsdaten beim erneuten Einloggen wiederhergestellt werden können, aktivieren Sie bitte die automatische Sicherung der Konfiguration."
|
||||
lastActiveDate: "Zuletzt verwendet am"
|
||||
statusbar: "Statusleiste"
|
||||
pleaseSelect: "Wähle eine Option"
|
||||
|
@ -1235,7 +1236,6 @@ showAvatarDecorations: "Profilbilddekoration anzeigen"
|
|||
releaseToRefresh: "Zum Aktualisieren loslassen"
|
||||
refreshing: "Wird aktualisiert..."
|
||||
pullDownToRefresh: "Zum Aktualisieren ziehen"
|
||||
disableStreamingTimeline: "Echtzeitaktualisierung der Chronik deaktivieren"
|
||||
useGroupedNotifications: "Benachrichtigungen gruppieren"
|
||||
signupPendingError: "Beim Überprüfen der Mailadresse ist etwas schiefgelaufen. Der Link könnte abgelaufen sein."
|
||||
cwNotationRequired: "Ist \"Inhaltswarnung verwenden\" aktiviert, muss eine Beschreibung gegeben werden."
|
||||
|
@ -1304,6 +1304,7 @@ thisContentsAreMarkedAsSigninRequiredByAuthor: "Logge dich ein, um weitere Inhal
|
|||
lockdown: "Sperren"
|
||||
pleaseSelectAccount: "Bitte Konto auswählen"
|
||||
availableRoles: "Verfügbare Rollen"
|
||||
acknowledgeNotesAndEnable: "Schalten Sie dies erst ein, wenn Sie die Vorsichtsmaßnahmen verstanden haben."
|
||||
federationSpecified: "Dieser Server arbeitet mit Whitelist-Föderation. Er kann nicht mit anderen als den vom Administrator angegebenen Servern interagieren."
|
||||
federationDisabled: "Föderation ist auf diesem Server deaktiviert. Es ist nicht möglich, mit Benutzern auf anderen Servern zu interagieren."
|
||||
confirmOnReact: "Reagieren bestätigen"
|
||||
|
@ -1311,9 +1312,11 @@ reactAreYouSure: "Willst du eine \"{emoji}\"-Reaktion hinzufügen?"
|
|||
markAsSensitiveConfirm: "Möchtest du dieses Medium als sensibel kennzeichnen?"
|
||||
unmarkAsSensitiveConfirm: "Möchtest du die Kennzeichnung dieses Mediums als sensibel aufheben?"
|
||||
preferences: "Einstellungen"
|
||||
accessibility: "Eingabehilfe"
|
||||
preferencesProfile: "Einstellungsprofil"
|
||||
copyPreferenceId: "Kopiere die Einstellungs-ID"
|
||||
resetToDefaultValue: "Auf Standard zurücksetzen"
|
||||
overrideByAccount: "Überschreibung durch das Konto"
|
||||
untitled: "Unbenannt"
|
||||
noName: "Kein Name"
|
||||
skip: "Überspringen"
|
||||
|
@ -1333,15 +1336,27 @@ chat: "Chat"
|
|||
migrateOldSettings: "Alte Client-Einstellungen migrieren"
|
||||
migrateOldSettings_description: "Dies sollte normalerweise automatisch geschehen, aber wenn die Migration aus irgendeinem Grund nicht erfolgreich war, kannst du den Migrationsprozess selbst manuell auslösen. Die aktuellen Konfigurationsinformationen werden dabei überschrieben."
|
||||
compress: "Komprimieren"
|
||||
right: "Rechts"
|
||||
bottom: "Unten"
|
||||
top: "Oben"
|
||||
embed: "Einbetten"
|
||||
settingsMigrating: "Ihre Einstellungen werden gerade migriert, Bitte warten Sie einen Moment... (Sie können die Einstellungen später auch manuell migrieren, indem Sie zu Einstellungen → Sonstiges → Alte Einstellungen migrieren gehen)"
|
||||
readonly: "Nur Lesezugriff"
|
||||
goToDeck: "Zurück zum Deck"
|
||||
federationJobs: "Föderation Jobs"
|
||||
driveAboutTip: "In Drive sehen Sie eine Liste der Dateien, die Sie in der Vergangenheit hochgeladen haben. <br>\nSie können diese Dateien wiederverwenden um sie zu beispiel an Notizen anzuhängen, oder sie können Dateien vorab hochzuladen, um sie später zu versenden! <br>\n<b>Wenn Sie eine Datei löschen, verschwindet sie auch von allen Stellen, an denen Sie sie verwendet haben (Notizen, Seiten, Avatare, Banner usw.).</b><br>\nSie können auch Ordner erstellen, um sie zu organisieren."
|
||||
scrollToClose: "Zum Schließen scrollen"
|
||||
_chat:
|
||||
noMessagesYet: "Noch keine Nachrichten"
|
||||
newMessage: "Neue Nachricht"
|
||||
individualChat: "Privater Chat"
|
||||
individualChat_description: "Führe einen privaten Chat mit einer anderen Person."
|
||||
roomChat: "Chatraum"
|
||||
roomChat_description: "Ein Chat-Raum, an dem mehrere Personen teilnehmen können.\nDu kannst auch Personen einladen, die keine privaten Chats zulassen, wenn sie die Einladung annehmen."
|
||||
createRoom: "Raum erstellen"
|
||||
inviteUserToChat: "Lade Benutzer ein, um mit dem Chatten zu beginnen"
|
||||
yourRooms: "Erstellte Räume"
|
||||
joiningRooms: "Raum beitreten"
|
||||
invitations: "Einladen"
|
||||
noInvitations: "Keine Einladungen"
|
||||
history: "Verlauf"
|
||||
|
@ -1360,6 +1375,7 @@ _chat:
|
|||
muteThisRoom: "Raum stummschalten"
|
||||
deleteRoom: "Raum löschen"
|
||||
chatNotAvailableForThisAccountOrServer: "Der Chat ist auf diesem Server oder für dieses Konto nicht aktiviert."
|
||||
chatIsReadOnlyForThisAccountOrServer: "Der Chat ist auf dieser Instanz oder diesem Konto nur zum Lesen freigegeben. Es ist nicht möglich, neue Nachrichten zu schreiben oder Chaträume zu erstellen oder zu betreten."
|
||||
chatNotAvailableInOtherAccount: "Die Chatfunktion wurde vom anderen Benutzer deaktiviert."
|
||||
cannotChatWithTheUser: "Starten eines Chats mit diesem Benutzer nicht möglich"
|
||||
cannotChatWithTheUser_description: "Der Chat ist entweder nicht verfügbar oder die andere Seite hat den Chat nicht aktiviert."
|
||||
|
@ -1384,8 +1400,10 @@ _emojiPalette:
|
|||
_settings:
|
||||
driveBanner: "Du kannst den Drive verwalten und konfigurieren, die Auslastung überprüfen und Einstellungen für das Hochladen von Dateien vornehmen."
|
||||
pluginBanner: "Du kannst die Funktionen des Clients mit Plugins erweitern. Plugins können installiert, individuell konfiguriert und verwaltet werden."
|
||||
notificationsBanner: "Sie können die Arten und den Umfang der Benachrichtigungen vom Server und der Push- Mitteilungen konfigurieren."
|
||||
api: "API"
|
||||
webhook: "Webhook"
|
||||
serviceConnection: "Integrierte Dienste"
|
||||
serviceConnectionBanner: "Du kannst Zugriffstoken und Webhooks für die Integration mit externen Anwendungen und Diensten verwalten und konfigurieren."
|
||||
accountData: "Kontodaten"
|
||||
accountDataBanner: "Export/Import und Verwaltung von Kontodatenarchiven."
|
||||
|
@ -1393,13 +1411,19 @@ _settings:
|
|||
accessibilityBanner: "Die Clients können personalisiert und für eine optimale Nutzung im Hinblick auf ihre Darstellung und ihr Verhalten eingerichtet werden."
|
||||
privacyBanner: "Du kannst Einstellungen für die Privatsphäre deines Kontos vornehmen, z. B. inwieweit Inhalte veröffentlicht werden, wie leicht sie zu finden sind und ob Follower genehmigt werden müssen."
|
||||
securityBanner: "Du kannst Einstellungen für die Kontosicherheit konfigurieren, z. B. Passwörter, Anmeldemethoden, Authentifizierungs-Apps und Passkeys."
|
||||
preferencesBanner: "Sie können das Gesamtverhalten des Clients nach Ihren Wünschen konfigurieren."
|
||||
appearanceBanner: "Du kannst das Erscheinungsbild und die Anzeigeeinstellungen für den Client nach deinen Wünschen konfigurieren."
|
||||
soundsBanner: "Du kannst die Einstellungen für die Wiedergabe von Klängen im Client konfigurieren."
|
||||
timelineAndNote: "Chroniken und Notizen"
|
||||
makeEveryTextElementsSelectable: "Alle Textelemente auswählbar machen"
|
||||
makeEveryTextElementsSelectable_description: "Die Aktivierung kann in manchen Situationen die Benutzerfreundlichkeit beeinträchtigen."
|
||||
useStickyIcons: "Icons beim Scrollen folgen lassen"
|
||||
showNavbarSubButtons: "Unterschaltflächen in der Navigationsleiste anzeigen"
|
||||
ifOn: "Wenn eingeschaltet"
|
||||
ifOff: "Wenn ausgeschaltet"
|
||||
enableSyncThemesBetweenDevices: "Synchronisierung von installierten Themen auf verschiedenen Endgeräten"
|
||||
enablePullToRefresh: "Ziehen zum Aktualisieren"
|
||||
enablePullToRefresh_description: "Bei Benutzung einer Maus, mit gedrücktem Mausrad ziehen"
|
||||
_chat:
|
||||
showSenderName: "Name des Absenders anzeigen"
|
||||
sendOnEnter: "Eingabetaste sendet Nachricht"
|
||||
|
@ -1407,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Profilname"
|
||||
profileNameDescription: "Lege einen Namen fest, der dieses Gerät identifiziert."
|
||||
profileNameDescription2: "Beispiel: \"Haupt-PC\", \"Smartphone\""
|
||||
manageProfiles: "Profile verwalten"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Automatische Sicherung"
|
||||
restoreFromBackup: "Wiederherstellen aus der Sicherung"
|
||||
|
@ -1427,6 +1452,7 @@ _accountSettings:
|
|||
makeNotesHiddenBeforeDescription: ""
|
||||
mayNotEffectForFederatedNotes: "Dies hat möglicherweise keine Auswirkungen auf Notizen, die an andere Server föderiert werden."
|
||||
mayNotEffectSomeSituations: "Diese Einschränkungen sind vereinfacht. Sie gelten möglicherweise nicht in allen Situationen, z. B. bei der Anzeige auf einem fremden Server oder während der Moderation."
|
||||
notesHavePassedSpecifiedPeriod: "Notizen die nach der folgenden Zeit veröffentlicht worden"
|
||||
notesOlderThanSpecifiedDateAndTime: "Notizen vor einem bestimmtem Datum und Uhrzeit"
|
||||
_abuseUserReport:
|
||||
forward: "Weiterleiten"
|
||||
|
@ -1438,11 +1464,13 @@ _abuseUserReport:
|
|||
_delivery:
|
||||
status: "Auslieferungsstatus"
|
||||
stop: "Gesperrt"
|
||||
resume: "Zustellung wieder fortsetzen"
|
||||
_type:
|
||||
none: "Wird veröffentlicht"
|
||||
manuallySuspended: "Manuell gesperrt"
|
||||
goneSuspended: "Gesperrt wegen Löschung des Servers"
|
||||
autoSuspendedForNotResponding: "Gesperrt, weil der Server nicht antwortet"
|
||||
softwareSuspended: "Ausgesetzt, weil die Software nicht mehr beliefert wird"
|
||||
_bubbleGame:
|
||||
howToPlay: "Wie man spielt"
|
||||
hold: "Halten"
|
||||
|
@ -1519,6 +1547,7 @@ _initialTutorial:
|
|||
description2: "Du kannst jederzeit am oberen Rand des Bildschirms zwischen den jeweiligen Chroniken wechseln."
|
||||
description3: "Darüber hinaus gibt es Listen-Chroniken und Kanal-Chroniken. Weitere Einzelheiten findest du unter {link}."
|
||||
_postNote:
|
||||
title: "Optionen bei Abschicken einer Notiz"
|
||||
description1: "Wenn du eine Notiz auf Misskey veröffentlichst, stehen dir verschiedene Optionen zur Verfügung. Die Oberfläche sieht folgendermaßen aus."
|
||||
_visibility:
|
||||
description: "Du kannst einschränken, wer deine Notiz sehen kann."
|
||||
|
@ -1573,6 +1602,8 @@ _serverSettings:
|
|||
openRegistration: "Registrierung von Konten aktivieren"
|
||||
openRegistrationWarning: "Das Aktivieren von Registrierungen ist riskant. Es wird empfohlen, sie nur dann zu aktivieren, wenn der Server ständig überwacht wird und im Falle eines Problems sofort reagiert werden kann."
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Wenn über einen bestimmten Zeitraum keine Moderatorenaktivität festgestellt wird, wird diese Einstellung automatisch deaktiviert, um Spam zu verhindern."
|
||||
deliverSuspendedSoftware: "Software, die nicht mehr beliefert wird"
|
||||
deliverSuspendedSoftwareDescription: "Sie können eine Auswahl von Namen und Versionen verschiedener Serversoftware angeben, um die Zustellung zu stoppen, z. B. aufgrund von Sicherheitslücken. Diese Versionsinformationen werden vom Server bereitgestellt und ihre Zuverlässigkeit ist nicht garantiert. Es wird jedoch empfohlen, eine Vorabversion anzugeben, wie z. B. >= 2024.3.1-0, da die Angabe >= 2024.3.1 keine benutzerdefinierten Versionen wie 2024.3.1-custom.0 einschließt."
|
||||
_accountMigration:
|
||||
moveFrom: "Von einem anderen Konto zu diesem migrieren"
|
||||
moveFromSub: "Alias für ein anderes Konto erstellen"
|
||||
|
@ -1839,6 +1870,7 @@ _achievements:
|
|||
_bubbleGameDoubleExplodingHead:
|
||||
title: "Doppel🤯"
|
||||
description: "Zwei der größten Objekte im Bubble Game zur gleichen Zeit"
|
||||
flavor: "Eine Lunchbox kann man auch mit etwas mehr 🤯 🤯 füllen"
|
||||
_role:
|
||||
new: "Rolle erstellen"
|
||||
edit: "Rolle bearbeiten"
|
||||
|
@ -1868,6 +1900,8 @@ _role:
|
|||
descriptionOfIsExplorable: "Ist dies aktiviert, so ist die Chronik dieser Rolle, sowie eine Liste der Benutzer mit dieser Rolle, frei zugänglich."
|
||||
displayOrder: "Position"
|
||||
descriptionOfDisplayOrder: "Je höher die Nummer, desto höher die UI-Position."
|
||||
preserveAssignmentOnMoveAccount: "Rolle übertragbar machen"
|
||||
preserveAssignmentOnMoveAccount_description: "Wenn diese Option aktiviert ist, wird diese Rolle bei der Migration mit übertragen."
|
||||
canEditMembersByModerator: "Moderatoren können Benutzern diese Rolle zuweisen"
|
||||
descriptionOfCanEditMembersByModerator: "Wenn aktiviert, so können Moderatoren und Adminstratoren anderen Benutzern diese Rolle zuweisen bzw. diese Zuweisung aufheben. Wenn deaktiviert, so ist es nur Administratoren möglich, Zuweisungen dieser Rolle zu verwalten."
|
||||
priority: "Priorität"
|
||||
|
@ -1887,6 +1921,7 @@ _role:
|
|||
canManageCustomEmojis: "Benutzerdefinierte Emojis verwalten"
|
||||
canManageAvatarDecorations: "Profilbilddekorationen verwalten"
|
||||
driveCapacity: "Drive-Kapazität"
|
||||
maxFileSize: "Maximale Dateigröße, die hochgeladen werden kann"
|
||||
alwaysMarkNsfw: "Dateien immer als NSFW markieren"
|
||||
canUpdateBioMedia: "Kann ein Profil- oder ein Bannerbild bearbeiten"
|
||||
pinMax: "Maximale Anzahl an angehefteten Notizen"
|
||||
|
@ -1908,7 +1943,7 @@ _role:
|
|||
canImportFollowing: "Importieren von Gefolgten zulassen"
|
||||
canImportMuting: "Importieren von Stummgeschalteten zulassen"
|
||||
canImportUserLists: "Importieren von Listen erlauben"
|
||||
canChat: "Chatten erlauben"
|
||||
chatAvailability: "Chatten erlauben"
|
||||
_condition:
|
||||
roleAssignedTo: "Manuellen Rollen zugewiesen"
|
||||
isLocal: "Lokaler Benutzer"
|
||||
|
@ -2105,7 +2140,6 @@ _theme:
|
|||
header: "Kopfzeile"
|
||||
navBg: "Hintergrund der Seitenleiste"
|
||||
navFg: "Text der Seitenleiste"
|
||||
navHoverFg: "Text der Seitenleiste (Mouseover)"
|
||||
navActive: "Text der Seitenleiste (Aktiv)"
|
||||
navIndicator: "Indikator der Seitenleiste"
|
||||
link: "Link"
|
||||
|
@ -2128,11 +2162,8 @@ _theme:
|
|||
buttonHoverBg: "Hintergrund von Schaltflächen (Mouseover)"
|
||||
inputBorder: "Rahmen von Eingabefeldern"
|
||||
driveFolderBg: "Hintergrund von Drive-Ordnern"
|
||||
wallpaperOverlay: "Hintergrundbild-Overlay"
|
||||
badge: "Wappen"
|
||||
messageBg: "Hintergrund von Chats"
|
||||
accentDarken: "Akzent (Verdunkelt)"
|
||||
accentLighten: "Akzent (Erhellt)"
|
||||
fgHighlighted: "Hervorgehobener Text"
|
||||
_sfx:
|
||||
note: "Notizen"
|
||||
|
@ -2267,12 +2298,14 @@ _permissions:
|
|||
"read:admin:announcements": "Ankündigungen einsehen"
|
||||
"write:admin:avatar-decorations": "Kann Avatar-Dekorationen verwalten"
|
||||
"read:admin:avatar-decorations": "Avatar-Dekorationen ansehen"
|
||||
"write:admin:federation": "Informationen über Föderationen bearbeiten oder löschen"
|
||||
"write:admin:account": "Benutzerkonten verwalten"
|
||||
"read:admin:account": "Benutzerkonten anzeigen"
|
||||
"write:admin:emoji": "Emojis verwalten"
|
||||
"read:admin:emoji": "Emojis anzeigen"
|
||||
"write:admin:queue": "Job-Warteschlange verwalten"
|
||||
"read:admin:queue": "Job-Warteschlange anzeigen"
|
||||
"write:admin:promo": "Moderationsnotiz hinzufügen"
|
||||
"write:admin:drive": "Benutzer-Drive verwalten"
|
||||
"read:admin:drive": "Benutzer-Drive ansehen"
|
||||
"read:admin:stream": "Verwendung der Websocket-API für Administratoren"
|
||||
|
@ -2280,6 +2313,8 @@ _permissions:
|
|||
"read:admin:ad": "Werbung ansehen"
|
||||
"write:invite-codes": "Einladungscodes erstellen"
|
||||
"read:invite-codes": "Einladungscodes anzeigen"
|
||||
"write:clip-favorite": "Clip-Likes bearbeiten oder löschen"
|
||||
"read:clip-favorite": "Clip-Likes ansehen"
|
||||
"read:federation": "Informationen zur Föderation einsehen"
|
||||
"write:report-abuse": "Verstöße melden"
|
||||
"write:chat": "Chats bedienen"
|
||||
|
@ -2294,6 +2329,7 @@ _auth:
|
|||
callback: "Es wird zur Anwendung zurückgekehrt"
|
||||
accepted: "Zugriff gewährt"
|
||||
denied: "Zugriff verweigert"
|
||||
scopeUser: "Als folgender Benutzer agieren"
|
||||
pleaseLogin: "Bitte logge dich ein, um Apps zu authorisieren."
|
||||
byClickingYouWillBeRedirectedToThisUrl: "Wenn der Zugang gewährt wird, wirst du automatisch zu folgender URL weitergeleitet"
|
||||
_antennaSources:
|
||||
|
@ -2341,6 +2377,7 @@ _widgets:
|
|||
chooseList: "Liste auswählen"
|
||||
clicker: "Klickzähler"
|
||||
birthdayFollowings: "Nutzer, die heute Geburtstag haben"
|
||||
chat: "Chat"
|
||||
_cw:
|
||||
hide: "Inhalt verbergen"
|
||||
show: "Inhalt anzeigen"
|
||||
|
@ -2546,6 +2583,7 @@ _notification:
|
|||
exportOfXCompleted: "Der Export von {x} ist abgeschlossen"
|
||||
login: "Neue Anmeldung erfolgt"
|
||||
createToken: "Ein Zugangstoken wurde erstellt"
|
||||
createTokenDescription: "Wenn Sie keine Ahnung haben, löschen Sie das Zugriffstoken über \"{text}\""
|
||||
_types:
|
||||
all: "Alle"
|
||||
note: "Neue Notizen"
|
||||
|
@ -2573,6 +2611,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "Hauptspalte immer zeigen"
|
||||
columnAlign: "Spaltenausrichtung"
|
||||
columnGap: "Spaltenabstand"
|
||||
deckMenuPosition: "Position des Deck-Menüs"
|
||||
navbarPosition: "Position der Navigationsleiste"
|
||||
addColumn: "Spalte hinzufügen"
|
||||
newNoteNotificationSettings: "Benachrichtigungseinstellungen für neue Notizen"
|
||||
configureColumn: "Spalteneinstellungen"
|
||||
|
@ -2603,6 +2644,7 @@ _deck:
|
|||
mentions: "Erwähnungen"
|
||||
direct: "Direktnachrichten"
|
||||
roleTimeline: "Rollenchronik"
|
||||
chat: "Chat"
|
||||
_dialog:
|
||||
charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}"
|
||||
charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}"
|
||||
|
@ -2795,6 +2837,9 @@ _reversi:
|
|||
allGames: "Alle Runden"
|
||||
ended: "Beendet"
|
||||
playing: "Partie läuft"
|
||||
isLlotheo: "Der mit weniger Steinen gewinnt (Llotheo)"
|
||||
loopedMap: "Wiederholendes Spielbrett"
|
||||
canPutEverywhere: "Steine können überall platziert werden"
|
||||
timeLimitForEachTurn: "Zeitlimit eines Zugs"
|
||||
freeMatch: "Freies Spiel"
|
||||
lookingForPlayer: "Gegner werden gesucht..."
|
||||
|
@ -2845,6 +2890,7 @@ _customEmojisManager:
|
|||
copySelectionRows: "Ausgewählte Zeilen kopieren"
|
||||
copySelectionRanges: "Auswahl kopieren"
|
||||
deleteSelectionRows: "Ausgewählte Zeilen löschen"
|
||||
deleteSelectionRanges: "Zeilen in der Auswahl löschen"
|
||||
searchSettings: "Sucheinstellungen"
|
||||
searchSettingCaption: "Detaillierte Suchkriterien festlegen."
|
||||
searchLimit: "Anzahl der Ergebnisse"
|
||||
|
@ -2853,10 +2899,12 @@ _customEmojisManager:
|
|||
registrationLogsCaption: "Protokolle werden beim Aktualisieren oder Löschen von Emojis angezeigt. Sie verschwinden nach dem Aktualisieren oder Löschen, dem Wechsel zu einer neuen Seite oder dem Neuladen."
|
||||
alertEmojisRegisterFailedDescription: "Emoji konnte nicht aktualisiert oder gelöscht werden. Bitte prüfe das Registrierungsprotokoll für Details."
|
||||
_logs:
|
||||
showSuccessLogSwitch: "Erfolgsprotokoll zeigen"
|
||||
failureLogNothing: "Es gibt kein Fehlerprotokoll."
|
||||
logNothing: "Keine Protokoll-Einträge."
|
||||
_remote:
|
||||
selectionRowDetail: "Details der ausgewählten Zeile"
|
||||
importSelectionRows: "Ausgewählte Zeilen importieren"
|
||||
importSelectionRangesRows: "Zeilen in der Auswahl importieren"
|
||||
importEmojisButton: "Ausgewählte Emojis importieren"
|
||||
confirmImportEmojisTitle: "Emojis importieren"
|
||||
|
@ -2866,15 +2914,23 @@ _customEmojisManager:
|
|||
tabTitleRegister: "Emojis hinzufügen"
|
||||
_list:
|
||||
emojisNothing: "Es wurden keine Emojis hinzugefügt."
|
||||
markAsDeleteTargetRows: "Ausgewählte Zeilen als zu löschendes Element markieren"
|
||||
markAsDeleteTargetRanges: "Zeilen in der Auswahl als zu löschendes Element markieren"
|
||||
alertUpdateEmojisNothingDescription: "Es wurden keine Emojis geändert."
|
||||
alertDeleteEmojisNothingDescription: "Es gibt keine zu löschenden Emojis."
|
||||
confirmMovePage: "Möchten Sie die Seiten verschieben?"
|
||||
confirmChangeView: "Möchten Sie die Darstellung wechseln?"
|
||||
confirmUpdateEmojisDescription: "Aktualisiere {count} Emoji(s). Willst du fortfahren?"
|
||||
confirmDeleteEmojisDescription: "Lösche {count} ausgewählte Emoji(s). Willst du fortfahren?"
|
||||
confirmResetDescription: "Alle bisher vorgenommenen Änderungen werden zurückgesetzt."
|
||||
confirmMovePageDesciption: "An den Emojis auf dieser Seite wurden Änderungen vorgenommen.\nWenn du die Seite verlässt, ohne zu speichern, werden alle auf dieser Seite vorgenommenen Änderungen verworfen."
|
||||
dialogSelectRoleTitle: "Suche nach dem Rollensatz in Emojis"
|
||||
_register:
|
||||
uploadSettingTitle: "Upload-Einstellungen"
|
||||
uploadSettingDescription: "Hier kannst du das Verhalten beim Hochladen von Emojis konfigurieren."
|
||||
directoryToCategoryLabel: "Gib den Namen des Verzeichnisses in das Feld „Kategorie“ ein"
|
||||
directoryToCategoryCaption: "Wenn du ein Verzeichnis ziehst und ablegst, gib den Verzeichnisnamen in das Feld „Kategorie“ ein."
|
||||
emojiInputAreaCaption: "Wählen Sie die Emojis aus, die Sie mit einer der folgenden Methoden speichern möchten."
|
||||
emojiInputAreaList1: "Ziehe Bilddateien oder Verzeichnisse per Drag-and-drop in diesen Rahmen"
|
||||
emojiInputAreaList2: "Klicke auf diesen Link, um von deinem PC aus zu wählen"
|
||||
emojiInputAreaList3: "Klicke auf diesen Link, um vom Drive aus zu wählen"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "Silence this instance"
|
|||
mediaSilenceThisInstance: "Media-silence this server"
|
||||
operations: "Operations"
|
||||
software: "Software"
|
||||
softwareName: "Software"
|
||||
version: "Version"
|
||||
metadata: "Metadata"
|
||||
withNFiles: "{n} file(s)"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "There are no users"
|
|||
editProfile: "Edit profile"
|
||||
noteDeleteConfirm: "Are you sure you want to delete this note?"
|
||||
pinLimitExceeded: "You cannot pin any more notes"
|
||||
intro: "Installation of Misskey has been finished! Please create an admin user."
|
||||
done: "Done"
|
||||
processing: "Processing..."
|
||||
preview: "Preview"
|
||||
|
@ -345,7 +345,7 @@ emptyDrive: "Your Drive is empty"
|
|||
emptyFolder: "This folder is empty"
|
||||
unableToDelete: "Unable to delete"
|
||||
inputNewFileName: "Enter a new filename"
|
||||
inputNewDescription: "Enter new caption"
|
||||
inputNewDescription: "Enter new alt text"
|
||||
inputNewFolderName: "Enter a new folder name"
|
||||
circularReferenceFolder: "The destination folder is a subfolder of the folder you wish to move."
|
||||
hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted."
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "Exclude bot accounts"
|
|||
antennaKeywordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition."
|
||||
notifyAntenna: "Notify about new notes"
|
||||
withFileAntenna: "Only notes with files"
|
||||
excludeNotesInSensitiveChannel: "Exclude notes from sensitive channels"
|
||||
enableServiceworker: "Enable Push-Notifications for your Browser"
|
||||
antennaUsersDescription: "List one username per line"
|
||||
caseSensitive: "Case sensitive"
|
||||
|
@ -643,8 +644,8 @@ disablePlayer: "Close video player"
|
|||
expandTweet: "Expand post"
|
||||
themeEditor: "Theme editor"
|
||||
description: "Description"
|
||||
describeFile: "Add caption"
|
||||
enterFileDescription: "Enter caption"
|
||||
describeFile: "Add alt text"
|
||||
enterFileDescription: "Enter alt text"
|
||||
author: "Author"
|
||||
leaveConfirm: "There are unsaved changes. Do you want to discard them?"
|
||||
manage: "Management"
|
||||
|
@ -783,7 +784,6 @@ thisIsExperimentalFeature: "This is an experimental feature. Its functionality i
|
|||
developer: "Developer"
|
||||
makeExplorable: "Make account visible in \"Explore\""
|
||||
makeExplorableDescription: "If you turn this off, your account will not show up in the \"Explore\" section."
|
||||
showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline"
|
||||
duplicate: "Duplicate"
|
||||
left: "Left"
|
||||
center: "Center"
|
||||
|
@ -977,7 +977,8 @@ deleteAccount: "Delete account"
|
|||
document: "Documentation"
|
||||
numberOfPageCache: "Number of cached pages"
|
||||
numberOfPageCacheDescription: "Increasing this number will improve convenience for but cause more load as more memory usage on the user's device."
|
||||
logoutConfirm: "Really log out?"
|
||||
logoutConfirm: "Are you sure you want to log out?"
|
||||
logoutWillClearClientData: "Logging out will erase the settings of the client from the browser. In order to be able to restore the settings upon logging in again, you must enable automatic backup of your settings."
|
||||
lastActiveDate: "Last used at"
|
||||
statusbar: "Status bar"
|
||||
pleaseSelect: "Select an option"
|
||||
|
@ -1014,7 +1015,7 @@ sendPushNotificationReadMessageCaption: "This may increase the power consumption
|
|||
windowMaximize: "Maximize"
|
||||
windowMinimize: "Minimize"
|
||||
windowRestore: "Restore"
|
||||
caption: "Caption"
|
||||
caption: "Alt text"
|
||||
loggedInAsBot: "Currently logged in as bot"
|
||||
tools: "Tools"
|
||||
cannotLoad: "Unable to load"
|
||||
|
@ -1235,7 +1236,6 @@ showAvatarDecorations: "Show avatar decorations"
|
|||
releaseToRefresh: "Release to refresh"
|
||||
refreshing: "Refreshing..."
|
||||
pullDownToRefresh: "Pull down to refresh"
|
||||
disableStreamingTimeline: "Disable real-time timeline updates"
|
||||
useGroupedNotifications: "Display grouped notifications"
|
||||
signupPendingError: "There was a problem verifying the email address. The link may have expired."
|
||||
cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided."
|
||||
|
@ -1270,7 +1270,7 @@ notUsePleaseLeaveBlank: "Leave blank if not used"
|
|||
useTotp: "Enter the One-Time Password"
|
||||
useBackupCode: "Use the backup codes"
|
||||
launchApp: "Launch the app"
|
||||
useNativeUIForVideoAudioPlayer: "Use UI of browser when play video and audio"
|
||||
useNativeUIForVideoAudioPlayer: "Use UI of browser when play video and audio\n"
|
||||
keepOriginalFilename: "Keep original file name"
|
||||
keepOriginalFilenameDescription: "If you turn off this setting, files names will be replaced with random string automatically when you upload files."
|
||||
noDescription: "There is no explanation"
|
||||
|
@ -1336,6 +1336,16 @@ chat: "Chat"
|
|||
migrateOldSettings: "Migrate old client settings"
|
||||
migrateOldSettings_description: "This should be done automatically but if for some reason the migration was not successful, you can trigger the migration process yourself manually. The current configuration information will be overwritten."
|
||||
compress: "Compress"
|
||||
right: "Right"
|
||||
bottom: "Bottom"
|
||||
top: "Top"
|
||||
embed: "Embed"
|
||||
settingsMigrating: "Settings are being migrated, please wait a moment... (You can also migrate manually later by going to Settings→Others→Migrate old settings)"
|
||||
readonly: "Read only"
|
||||
goToDeck: "Return to Deck"
|
||||
federationJobs: "Federation Jobs"
|
||||
driveAboutTip: "In Drive, a list of files you've uploaded in the past will be displayed. <br> \nYou can reuse these files when attaching them to notes, or you can upload files in advance to post later. <br> \n<b>Be careful when deleting a file, as it will not be available in all places where it was used (such as notes, pages, avatars, banners, etc.).</b> <br> \nYou can also create folders to organize your files."
|
||||
scrollToClose: "Scroll to close"
|
||||
_chat:
|
||||
noMessagesYet: "No messages yet"
|
||||
newMessage: "New message"
|
||||
|
@ -1365,6 +1375,7 @@ _chat:
|
|||
muteThisRoom: "Mute room"
|
||||
deleteRoom: "Delete room"
|
||||
chatNotAvailableForThisAccountOrServer: "Chat is not enabled on this server or for this account."
|
||||
chatIsReadOnlyForThisAccountOrServer: "Chat is read-only on this instance or this account. You cannot write new messages or create/join chat rooms."
|
||||
chatNotAvailableInOtherAccount: "The chat function is disabled for the other user."
|
||||
cannotChatWithTheUser: "Cannot start a chat with this user"
|
||||
cannotChatWithTheUser_description: "Chat is either unavailable or the other party has not enabled chat."
|
||||
|
@ -1410,6 +1421,9 @@ _settings:
|
|||
showNavbarSubButtons: "Show sub-buttons on the navigation bar"
|
||||
ifOn: "When turned on"
|
||||
ifOff: "When turned off"
|
||||
enableSyncThemesBetweenDevices: "Synchronize installed themes across devices"
|
||||
enablePullToRefresh: "Pull to Refresh"
|
||||
enablePullToRefresh_description: "When using a mouse, drag while pressing in the scroll wheel."
|
||||
_chat:
|
||||
showSenderName: "Show sender's name"
|
||||
sendOnEnter: "Press Enter to send"
|
||||
|
@ -1417,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Profile name"
|
||||
profileNameDescription: "Set a name that identifies this device."
|
||||
profileNameDescription2: "Example: \"Main PC\", \"Smartphone\""
|
||||
manageProfiles: "Manage Profiles"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Auto backup"
|
||||
restoreFromBackup: "Restore from backup"
|
||||
|
@ -1455,6 +1470,7 @@ _delivery:
|
|||
manuallySuspended: "Manually suspended"
|
||||
goneSuspended: "Server is suspended due to server deletion"
|
||||
autoSuspendedForNotResponding: "Server is suspended due to no responding"
|
||||
softwareSuspended: "Suspended as this software is no longer being distributed to"
|
||||
_bubbleGame:
|
||||
howToPlay: "How to play"
|
||||
hold: "Hold"
|
||||
|
@ -1586,6 +1602,8 @@ _serverSettings:
|
|||
openRegistration: "Make the account creation open"
|
||||
openRegistrationWarning: "Opening registration carries risks. It is recommended to only enable it if you have a system in place to continuously monitor the server and respond immediately in case of any issues."
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "If no moderator activity is detected for a while, this setting will be automatically turned off to prevent spam."
|
||||
deliverSuspendedSoftware: "Suspended Software"
|
||||
deliverSuspendedSoftwareDescription: "You can specify a range of names and versions of the server's software to stop delivery for vulnerability or other reasons. This version information is provided by the server and is not guaranteed to be reliable. A semver range specification can be used to specify the version, but specifying >= 2024.3.1 will not include custom versions such as 2024.3.1-custom.0, so it is recommended that a prerelease specification be used, such as >= 2024.3.1-0"
|
||||
_accountMigration:
|
||||
moveFrom: "Migrate another account to this one"
|
||||
moveFromSub: "Create alias to another account"
|
||||
|
@ -1882,6 +1900,8 @@ _role:
|
|||
descriptionOfIsExplorable: "This role's timeline and the list of users with this will be made public if enabled."
|
||||
displayOrder: "Position"
|
||||
descriptionOfDisplayOrder: "The higher the number, the higher its UI position."
|
||||
preserveAssignmentOnMoveAccount: "Preserve role assignment during migration"
|
||||
preserveAssignmentOnMoveAccount_description: "When turned on, this role will be carried over to the destination account when an account with this role is migrated."
|
||||
canEditMembersByModerator: "Allow moderators to edit the list of members for this role"
|
||||
descriptionOfCanEditMembersByModerator: "When turned on, moderators as well as administrators will be able to assign and unassign users to this role. When turned off, only administrators will be able to assign users."
|
||||
priority: "Priority"
|
||||
|
@ -1901,6 +1921,7 @@ _role:
|
|||
canManageCustomEmojis: "Can manage custom emojis"
|
||||
canManageAvatarDecorations: "Manage avatar decorations"
|
||||
driveCapacity: "Drive capacity"
|
||||
maxFileSize: "Upload-able max file size"
|
||||
alwaysMarkNsfw: "Always mark files as NSFW"
|
||||
canUpdateBioMedia: "Can edit an icon or a banner image"
|
||||
pinMax: "Maximum number of pinned notes"
|
||||
|
@ -1922,7 +1943,7 @@ _role:
|
|||
canImportFollowing: "Allow importing following"
|
||||
canImportMuting: "Allow importing muting"
|
||||
canImportUserLists: "Allow importing lists"
|
||||
canChat: "Allow Chat"
|
||||
chatAvailability: "Allow Chat"
|
||||
_condition:
|
||||
roleAssignedTo: "Assigned to manual roles"
|
||||
isLocal: "Local user"
|
||||
|
@ -2119,7 +2140,6 @@ _theme:
|
|||
header: "Header"
|
||||
navBg: "Sidebar background"
|
||||
navFg: "Sidebar text"
|
||||
navHoverFg: "Sidebar text (Hover)"
|
||||
navActive: "Sidebar text (Active)"
|
||||
navIndicator: "Sidebar indicator"
|
||||
link: "Link"
|
||||
|
@ -2142,11 +2162,8 @@ _theme:
|
|||
buttonHoverBg: "Button background (Hover)"
|
||||
inputBorder: "Input field border"
|
||||
driveFolderBg: "Drive folder background"
|
||||
wallpaperOverlay: "Wallpaper overlay"
|
||||
badge: "Badge"
|
||||
messageBg: "Chat background"
|
||||
accentDarken: "Accent (Darkened)"
|
||||
accentLighten: "Accent (Lightened)"
|
||||
fgHighlighted: "Highlighted Text"
|
||||
_sfx:
|
||||
note: "New note"
|
||||
|
@ -2360,6 +2377,7 @@ _widgets:
|
|||
chooseList: "Select a list"
|
||||
clicker: "Clicker"
|
||||
birthdayFollowings: "Today's Birthdays"
|
||||
chat: "Chat"
|
||||
_cw:
|
||||
hide: "Hide"
|
||||
show: "Show content"
|
||||
|
@ -2593,6 +2611,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "Always show main column"
|
||||
columnAlign: "Align columns"
|
||||
columnGap: "Margin between columns"
|
||||
deckMenuPosition: "Deck menu position"
|
||||
navbarPosition: "Navigation bar position"
|
||||
addColumn: "Add column"
|
||||
newNoteNotificationSettings: "Notification setting for new notes"
|
||||
configureColumn: "Column settings"
|
||||
|
@ -2606,7 +2627,7 @@ _deck:
|
|||
newProfile: "New profile"
|
||||
deleteProfile: "Delete profile"
|
||||
introduction: "Create the perfect interface for you by arranging columns freely!"
|
||||
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
|
||||
introduction2: "Click on the + on the right of the screen to add new columns whenever you want."
|
||||
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
|
||||
useSimpleUiForNonRootPages: "Use simple UI for navigated pages"
|
||||
usedAsMinWidthWhenFlexible: "Minimum width will be used for this when the \"Auto-adjust width\" option is enabled"
|
||||
|
@ -2623,6 +2644,7 @@ _deck:
|
|||
mentions: "Mentions"
|
||||
direct: "Direct notes"
|
||||
roleTimeline: "Role Timeline"
|
||||
chat: "Chat"
|
||||
_dialog:
|
||||
charactersExceeded: "You've exceeded the maximum character limit! Currently at {current} of {max}."
|
||||
charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}."
|
||||
|
@ -2902,7 +2924,7 @@ _customEmojisManager:
|
|||
confirmDeleteEmojisDescription: "Delete checked {count} Emoji(s). Are you sure to continue?"
|
||||
confirmResetDescription: ""
|
||||
confirmMovePageDesciption: "Changes have been made to the Emojis on this page.\nIf you leave the page without saving, all changes made on this page will be discarded."
|
||||
dialogSelectRoleTitle: "Search by roll set in Emojis"
|
||||
dialogSelectRoleTitle: "Search by role set in Emojis"
|
||||
_register:
|
||||
uploadSettingTitle: "Upload settings"
|
||||
uploadSettingDescription: "On this screen, you can configure the behavior when uploading Emojis."
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "No hay usuarios"
|
|||
editProfile: "Editar perfil"
|
||||
noteDeleteConfirm: "¿Desea borrar esta nota?"
|
||||
pinLimitExceeded: "Ya no se pueden fijar más posts"
|
||||
intro: "¡La instalación de Misskey ha terminado! Crea el usuario administrador."
|
||||
done: "Terminado"
|
||||
processing: "Procesando"
|
||||
preview: "Vista previa"
|
||||
|
@ -301,6 +300,7 @@ uploadFromUrlMayTakeTime: "Subir el fichero puede tardar un tiempo."
|
|||
explore: "Explorar"
|
||||
messageRead: "Ya leído"
|
||||
noMoreHistory: "El historial se ha acabado"
|
||||
startChat: "Nuevo Chat"
|
||||
nUsersRead: "Leído por {n} personas"
|
||||
agreeTo: "De acuerdo con {0}"
|
||||
agree: "De acuerdo."
|
||||
|
@ -423,6 +423,7 @@ antennaExcludeBots: "Excluir bots"
|
|||
antennaKeywordsDescription: "Separar con espacios es una declaración AND, separar con una linea nueva es una declaración OR"
|
||||
notifyAntenna: "Notificar nueva nota"
|
||||
withFileAntenna: "Sólo notas con archivos adjuntados"
|
||||
excludeNotesInSensitiveChannel: "Excluir notas en canales sensibles"
|
||||
enableServiceworker: "Activar ServiceWorker"
|
||||
antennaUsersDescription: "Elegir nombres de usuarios separados por una linea nueva"
|
||||
caseSensitive: "Distinguir mayúsculas de minúsculas"
|
||||
|
@ -694,6 +695,7 @@ userSaysSomethingAbout: "{name} dijo algo sobre {word}"
|
|||
makeActive: "Activar"
|
||||
display: "Apariencia"
|
||||
copy: "Copiar"
|
||||
copiedToClipboard: "Texto copiado al portapapeles"
|
||||
metrics: "Métricas"
|
||||
overview: "Resumen"
|
||||
logs: "Registros"
|
||||
|
@ -781,7 +783,6 @@ thisIsExperimentalFeature: "Se trata de una función experimental. Las especific
|
|||
developer: "Desarrolladores"
|
||||
makeExplorable: "Hacer visible la cuenta en \"Explorar\""
|
||||
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"."
|
||||
showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo"
|
||||
duplicate: "Duplicar"
|
||||
left: "Izquierda"
|
||||
center: "Centrar"
|
||||
|
@ -976,6 +977,7 @@ document: "Documento"
|
|||
numberOfPageCache: "Cantidad de páginas cacheadas"
|
||||
numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien puede aumentar la carga y la memoria a usarse"
|
||||
logoutConfirm: "¿Cerrar sesión?"
|
||||
logoutWillClearClientData: "Al cerrar la sesión, la información de configuración del cliente se borra del navegador. Para garantizar que la información de configuración se pueda restaurar al volver a iniciar sesión, active la copia de seguridad automática de la configuración."
|
||||
lastActiveDate: "Utilizado por última vez el"
|
||||
statusbar: "Barra de estado"
|
||||
pleaseSelect: "Selecciona una opción"
|
||||
|
@ -1071,7 +1073,7 @@ reactionAcceptance: "Aceptación de reacciones"
|
|||
likeOnly: "Sólo 'me gusta'"
|
||||
likeOnlyForRemote: "Sólo reacciones de instancias remotas"
|
||||
nonSensitiveOnly: "Solo no sensible"
|
||||
nonSensitiveOnlyForLocalLikeOnlyForRemote: "Sólo no contenido sensible (sólo me gusta en remote)"
|
||||
nonSensitiveOnlyForLocalLikeOnlyForRemote: "Sólo no contenido sensible (sólo me gusta en remoto)"
|
||||
rolesAssignedToMe: "Roles asignados a mí"
|
||||
resetPasswordConfirm: "¿Realmente quieres cambiar la contraseña?"
|
||||
sensitiveWords: "Palabras sensibles"
|
||||
|
@ -1233,7 +1235,6 @@ showAvatarDecorations: "Mostrar decoraciones de avatar"
|
|||
releaseToRefresh: "Soltar para recargar"
|
||||
refreshing: "Recargando..."
|
||||
pullDownToRefresh: "Tira hacia abajo para recargar"
|
||||
disableStreamingTimeline: "Desactivar actualizaciones en tiempo real de la línea de tiempo"
|
||||
useGroupedNotifications: "Mostrar notificaciones agrupadas"
|
||||
signupPendingError: "Ha habido un problema al verificar tu dirección de correo electrónico. Es posible que el enlace haya caducado."
|
||||
cwNotationRequired: "Si se ha activado \"ocultar contenido\", es necesario proporcionar una descripción."
|
||||
|
@ -1293,18 +1294,120 @@ passkeyVerificationFailed: "La verificación de la clave de acceso ha fallado."
|
|||
passkeyVerificationSucceededButPasswordlessLoginDisabled: "La verificación de la clave de acceso ha sido satisfactoria pero se ha deshabilitado el inicio de sesión sin contraseña."
|
||||
messageToFollower: "Mensaje a seguidores"
|
||||
target: "Para"
|
||||
testCaptchaWarning: "Esta función está pensada para probar CAPTCHAs.<strong>No utilizar en un entorno de producción.</strong>"
|
||||
prohibitedWordsForNameOfUser: "Palabras prohibidas para nombres de usuario"
|
||||
prohibitedWordsForNameOfUserDescription: "Si alguna de las cadenas de esta lista está incluida en el nombre del usuario, el nombre será denegado. Los usuarios con privilegios de moderador no se ven afectados por esta restricción."
|
||||
yourNameContainsProhibitedWords: "Tu nombre contiene palabras prohibidas"
|
||||
yourNameContainsProhibitedWordsDescription: "Si deseas usar este nombre, por favor contacta con tu administrador/a de tu servidor"
|
||||
thisContentsAreMarkedAsSigninRequiredByAuthor: " Establecido por el autor: requiere iniciar sesión para ver"
|
||||
lockdown: "Bloqueo"
|
||||
pleaseSelectAccount: "Seleccione una cuenta, por favor."
|
||||
availableRoles: "Roles disponibles "
|
||||
acknowledgeNotesAndEnable: "Activar después de comprender las precauciones"
|
||||
federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador."
|
||||
federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores"
|
||||
confirmOnReact: "Confirmar la reacción"
|
||||
reactAreYouSure: "¿Quieres añadir una reacción «{emoji}»?"
|
||||
markAsSensitiveConfirm: "¿Desea establecer este medio multimedia(Imagen,vídeo...) como sensible?"
|
||||
unmarkAsSensitiveConfirm: "¿Desea eliminar la designación de sensible para este adjunto?"
|
||||
preferences: "Preferencias"
|
||||
accessibility: "Accesibilidad"
|
||||
preferencesProfile: "Configuración del perfil"
|
||||
copyPreferenceId: "Copiar ID de la configuración"
|
||||
resetToDefaultValue: "Revertir a valor predeterminado"
|
||||
overrideByAccount: "Anulado por la cuenta"
|
||||
untitled: "Sin título"
|
||||
noName: "No hay nombre."
|
||||
skip: "Saltar"
|
||||
restore: "Restaurar"
|
||||
syncBetweenDevices: "Sincronizar entre dispositivos"
|
||||
preferenceSyncConflictTitle: "Los valores configurados existen en el servidor."
|
||||
preferenceSyncConflictText: "Los ajustes de sincronización activados guardarán sus valores en el servidor. Sin embargo, hay valores existentes en el servidor. ¿Qué conjunto de valores desea sobrescribir?"
|
||||
preferenceSyncConflictChoiceServer: "Valores de configuración del servidor"
|
||||
preferenceSyncConflictChoiceDevice: "Valor configurado en el dispositivo"
|
||||
paste: "Pegar"
|
||||
emojiPalette: "Paleta emoji"
|
||||
postForm: "Formulario"
|
||||
information: "Información"
|
||||
chat: "Chat"
|
||||
migrateOldSettings: "Migrar la configuración anterior"
|
||||
right: "Derecha"
|
||||
bottom: "Abajo"
|
||||
top: "Arriba"
|
||||
embed: "Insertar"
|
||||
settingsMigrating: "La configuración está siendo migrada, por favor espera un momento... (También puedes migrar manualmente más tarde yendo a Ajustes otros migrar configuración antigua"
|
||||
readonly: "Solo Lectura"
|
||||
goToDeck: "Volver al Deck"
|
||||
federationJobs: "Trabajos de Federación"
|
||||
_chat:
|
||||
noMessagesYet: "Aún no hay mensajes"
|
||||
newMessage: "Mensajes nuevos"
|
||||
individualChat: "Chat individual"
|
||||
individualChat_description: "Mantén una conversación privada con otra persona."
|
||||
roomChat: "Sala de Chat"
|
||||
roomChat_description: "Una sala de chat que puede tener varias personas.\nTambién puedes invitar a personas que no permiten chats privados si aceptan la invitación."
|
||||
createRoom: "Crear sala"
|
||||
inviteUserToChat: "Invitar usuarios para empezar a chatear"
|
||||
yourRooms: "Salas creadas"
|
||||
joiningRooms: "Salas que te has unido"
|
||||
invitations: "Invitar"
|
||||
noInvitations: "No hay invitación."
|
||||
history: "Historial"
|
||||
noHistory: "No hay datos en el historial"
|
||||
noRooms: "Sala no encontrada"
|
||||
inviteUser: "Invitar usuarios"
|
||||
sentInvitations: "Invitaciones enviadas"
|
||||
join: "Unirse"
|
||||
ignore: "Ignorar"
|
||||
leave: "Dejar sala"
|
||||
members: "Miembros"
|
||||
searchMessages: "Buscar mensajes"
|
||||
home: "Inicio"
|
||||
send: "Enviar"
|
||||
newline: "Nueva línea"
|
||||
muteThisRoom: "Silenciar esta sala"
|
||||
deleteRoom: "Borrar sala"
|
||||
chatNotAvailableForThisAccountOrServer: "El chat no está habilitado en este servidor ni para esta cuenta."
|
||||
chatIsReadOnlyForThisAccountOrServer: "El chat es de sólo lectura en esta instancia o esta cuenta. No puedes escribir nuevos mensajes ni crear/unirte a salas de chat."
|
||||
chatNotAvailableInOtherAccount: "La función de chat está desactivada para el otro usuario."
|
||||
cannotChatWithTheUser: "No se puede iniciar un chat con este usuario"
|
||||
cannotChatWithTheUser_description: "El chat no está disponible o la otra parte no ha habilitado el chat."
|
||||
chatWithThisUser: "Chatear"
|
||||
thisUserAllowsChatOnlyFromFollowers: "Este usuario sólo acepta chats de seguidores."
|
||||
thisUserAllowsChatOnlyFromFollowing: "Este usuario sólo acepta chats de los usuarios a los que sigue."
|
||||
thisUserAllowsChatOnlyFromMutualFollowing: "Este usuario sólo acepta chats de usuarios que son seguidores mutuos."
|
||||
thisUserNotAllowedChatAnyone: "Este usuario no acepta chats de nadie."
|
||||
chatAllowedUsers: "A quién permitir chatear."
|
||||
chatAllowedUsers_note: "Puedes chatear con cualquier persona a la que hayas enviado un mensaje de chat, independientemente de esta configuración."
|
||||
_chatAllowedUsers:
|
||||
everyone: "Todos"
|
||||
followers: "Sólo sus propios seguidores."
|
||||
following: "Solo usuarios que sigues"
|
||||
mutual: "Solo seguidores mutuos"
|
||||
none: "Nadie"
|
||||
_emojiPalette:
|
||||
palettes: "Paleta\n"
|
||||
enableSyncBetweenDevicesForPalettes: "Activar la sincronización de paletas entre dispositivos"
|
||||
_settings:
|
||||
api: "API"
|
||||
webhook: "Webhook"
|
||||
timelineAndNote: "Líneas del tiempo y notas"
|
||||
makeEveryTextElementsSelectable_description: "Activar esta opción puede reducir la usabilidad en algunas situaciones."
|
||||
useStickyIcons: "Hacer que los iconos te sigan cuando desplaces"
|
||||
showNavbarSubButtons: "Mostrar los sub-botones en la barra de navegación."
|
||||
ifOn: "Si está activado"
|
||||
enableSyncThemesBetweenDevices: "Sincronizar los temas instalados entre dispositivos."
|
||||
_chat:
|
||||
showSenderName: "Mostrar el nombre del remitente"
|
||||
sendOnEnter: "Intro para enviar"
|
||||
_preferencesProfile:
|
||||
profileName: "Nombre de perfil"
|
||||
profileNameDescription: "Establece un nombre que identifique al dispositivo"
|
||||
profileNameDescription2: "Por ejemplo: \"PC Principal\",\"Teléfono\""
|
||||
_preferencesBackup:
|
||||
autoBackup: "Respaldo automático"
|
||||
restoreFromBackup: "Restaurar desde copia de seguridad"
|
||||
noBackupsFoundTitle: "No se encontró una copia de seguridad"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "Se requiere iniciar sesión para ver el contenido"
|
||||
requireSigninToViewContentsDescription1: "Requiere iniciar sesión para ver todas las notas y otros contenidos que hayas creado. Se espera que esto evite que los rastreadores recopilen información."
|
||||
|
@ -1964,7 +2067,6 @@ _theme:
|
|||
header: "Cabezal"
|
||||
navBg: "Fondo de la barra lateral"
|
||||
navFg: "Texto de la barra lateral"
|
||||
navHoverFg: "Texto de la barra lateral (hover)"
|
||||
navActive: "Texto de la barra lateral (activo)"
|
||||
navIndicator: "Indicador de la barra lateral"
|
||||
link: "Vínculo"
|
||||
|
@ -1987,11 +2089,8 @@ _theme:
|
|||
buttonHoverBg: "Fondo de botón (hover)"
|
||||
inputBorder: "Borde de los campos de entrada"
|
||||
driveFolderBg: "Fondo de capeta del drive"
|
||||
wallpaperOverlay: "Transparencia del fondo de pantalla"
|
||||
badge: "Medalla"
|
||||
messageBg: "Fondo de chat"
|
||||
accentDarken: "Acento (oscuro)"
|
||||
accentLighten: "Acento (claro)"
|
||||
fgHighlighted: "Texto resaltado"
|
||||
_sfx:
|
||||
note: "Notas"
|
||||
|
@ -2199,6 +2298,7 @@ _widgets:
|
|||
chooseList: "Seleccione una lista"
|
||||
clicker: "Cliqueador"
|
||||
birthdayFollowings: "Hoy cumplen años"
|
||||
chat: "Chat"
|
||||
_cw:
|
||||
hide: "Ocultar"
|
||||
show: "Ver más"
|
||||
|
@ -2446,6 +2546,7 @@ _deck:
|
|||
mentions: "Menciones"
|
||||
direct: "Notas directas"
|
||||
roleTimeline: "Linea de tiempo del rol"
|
||||
chat: "Chat"
|
||||
_dialog:
|
||||
charactersExceeded: "¡Has excedido el límite de caracteres! Actualmente {current} de {max}."
|
||||
charactersBelow: "¡Estás por debajo del límite de caracteres! Actualmente {current} de {min}."
|
||||
|
|
|
@ -238,7 +238,6 @@ noUsers: "Il n’y a pas d’utilisateur·rice·s"
|
|||
editProfile: "Modifier votre profil"
|
||||
noteDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note ?"
|
||||
pinLimitExceeded: "Vous ne pouvez plus épingler d’autres notes."
|
||||
intro: "L’installation de Misskey est terminée ! Veuillez créer un compte administrateur."
|
||||
done: "Terminé"
|
||||
processing: "Traitement en cours"
|
||||
preview: "Aperçu"
|
||||
|
@ -760,7 +759,6 @@ thisIsExperimentalFeature: "Ceci est une fonctionnalité expérimentale. Il y a
|
|||
developer: "Développeur"
|
||||
makeExplorable: "Rendre le compte visible sur la page \"Découvrir\"."
|
||||
makeExplorableDescription: "Si vous désactivez cette option, votre compte n'apparaîtra pas sur la page \"Découvrir\"."
|
||||
showGapBetweenNotesInTimeline: "Afficher un écart entre les notes sur la Timeline"
|
||||
duplicate: "Duliquer"
|
||||
left: "Gauche"
|
||||
center: "Centrer"
|
||||
|
@ -1209,7 +1207,6 @@ showAvatarDecorations: "Afficher les décorations d'avatar"
|
|||
releaseToRefresh: "Relâcher pour rafraîchir"
|
||||
refreshing: "Rafraîchissement..."
|
||||
pullDownToRefresh: "Tirer vers le bas pour rafraîchir"
|
||||
disableStreamingTimeline: "Désactiver les mises à jour en temps réel de la ligne du temps"
|
||||
useGroupedNotifications: "Grouper les notifications"
|
||||
signupPendingError: "Un problème est survenu lors de la vérification de votre adresse e-mail. Le lien a peut-être expiré."
|
||||
cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie."
|
||||
|
@ -1816,7 +1813,6 @@ _theme:
|
|||
header: "Entête"
|
||||
navBg: "Fond de la barre latérale"
|
||||
navFg: "Texte de la barre latérale"
|
||||
navHoverFg: "Texte de la barre latérale (survolé)"
|
||||
navActive: "Texte de la barre latérale (actif)"
|
||||
navIndicator: "Indicateur de barre latérale"
|
||||
link: "Lien"
|
||||
|
@ -1839,11 +1835,8 @@ _theme:
|
|||
buttonHoverBg: "Arrière-plan du bouton (survolé)"
|
||||
inputBorder: "Cadre de la zone de texte"
|
||||
driveFolderBg: "Arrière-plan du dossier de disque"
|
||||
wallpaperOverlay: "Superposition de fond d'écran"
|
||||
badge: "Badge"
|
||||
messageBg: "Arrière plan de la discussion"
|
||||
accentDarken: "Plus sombre"
|
||||
accentLighten: "Plus clair"
|
||||
fgHighlighted: "Texte mis en évidence"
|
||||
_sfx:
|
||||
note: "Nouvelle note"
|
||||
|
|
|
@ -241,7 +241,6 @@ noUsers: "Tidak ada pengguna"
|
|||
editProfile: "Sunting profil"
|
||||
noteDeleteConfirm: "Apakah kamu yakin ingin menghapus catatan ini?"
|
||||
pinLimitExceeded: "Kamu tidak dapat menyematkan catatan lagi"
|
||||
intro: "Instalasi Misskey telah selesai! Mohon untuk membuat pengguna admin."
|
||||
done: "Selesai"
|
||||
processing: "Memproses"
|
||||
preview: "Pratinjau"
|
||||
|
@ -761,7 +760,6 @@ thisIsExperimentalFeature: "Fitur ini eksperimental. Fungsionalitas dari fitur i
|
|||
developer: "Pengembang"
|
||||
makeExplorable: "Buat akun tampil di \"Jelajahi\""
|
||||
makeExplorableDescription: "Jika kamu mematikan ini, akun kamu tidak akan muncul di menu \"Jelajahi\""
|
||||
showGapBetweenNotesInTimeline: "Tampilkan jarak diantara catatan pada lini masa"
|
||||
duplicate: "Duplikat"
|
||||
left: "Kiri"
|
||||
center: "Tengah"
|
||||
|
@ -1206,7 +1204,6 @@ showAvatarDecorations: "Tampilkan dekorasi avatar"
|
|||
releaseToRefresh: "Lepaskan untuk memuat ulang"
|
||||
refreshing: "Sedang memuat ulang..."
|
||||
pullDownToRefresh: "Tarik ke bawah untuk memuat ulang"
|
||||
disableStreamingTimeline: "Nonaktifkan pembaharuan lini masa real-time"
|
||||
useGroupedNotifications: "Tampilkan notifikasi secara dikelompokkan"
|
||||
signupPendingError: "Terdapat masalah ketika memverifikasi alamat surel. Tautan kemungkinan telah kedaluwarsa."
|
||||
cwNotationRequired: "Jika \"Sembunyikan konten\" diaktifkan, deskripsi harus disediakan."
|
||||
|
@ -1931,7 +1928,6 @@ _theme:
|
|||
header: "Header"
|
||||
navBg: "Latar belakang bilah samping"
|
||||
navFg: "Teks bilah samping"
|
||||
navHoverFg: "Teks bilah samping (Mengambang)"
|
||||
navActive: "Teks bilah samping (Aktif)"
|
||||
navIndicator: "Indikator bilah samping"
|
||||
link: "Tautan"
|
||||
|
@ -1954,11 +1950,8 @@ _theme:
|
|||
buttonHoverBg: "Latar belakang tombol (Mengambang)"
|
||||
inputBorder: "Batas bidang masukan"
|
||||
driveFolderBg: "Latar belakang folder drive"
|
||||
wallpaperOverlay: "Lapisan wallpaper"
|
||||
badge: "Lencana"
|
||||
messageBg: "Latar belakang obrolan"
|
||||
accentDarken: "Aksen (Gelap)"
|
||||
accentLighten: "Aksen (Terang)"
|
||||
fgHighlighted: "Teks yang disorot"
|
||||
_sfx:
|
||||
note: "Catatan"
|
||||
|
|
|
@ -898,6 +898,10 @@ export interface Locale extends ILocale {
|
|||
* ソフトウェア
|
||||
*/
|
||||
"software": string;
|
||||
/**
|
||||
* ソフトウェア名
|
||||
*/
|
||||
"softwareName": string;
|
||||
/**
|
||||
* バージョン
|
||||
*/
|
||||
|
@ -1018,10 +1022,6 @@ export interface Locale extends ILocale {
|
|||
* これ以上ピン留めできません
|
||||
*/
|
||||
"pinLimitExceeded": string;
|
||||
/**
|
||||
* Misskeyのインストールが完了しました!管理者アカウントを作成しましょう。
|
||||
*/
|
||||
"intro": string;
|
||||
/**
|
||||
* 完了
|
||||
*/
|
||||
|
@ -1714,6 +1714,10 @@ export interface Locale extends ILocale {
|
|||
* ファイルが添付されたノートのみ
|
||||
*/
|
||||
"withFileAntenna": string;
|
||||
/**
|
||||
* センシティブなチャンネルのノートを除外
|
||||
*/
|
||||
"excludeNotesInSensitiveChannel": string;
|
||||
/**
|
||||
* ブラウザへのプッシュ通知を有効にする
|
||||
*/
|
||||
|
@ -2314,6 +2318,10 @@ export interface Locale extends ILocale {
|
|||
* 新しいノートがあります
|
||||
*/
|
||||
"newNoteRecived": string;
|
||||
/**
|
||||
* 新しいノート
|
||||
*/
|
||||
"newNote": string;
|
||||
/**
|
||||
* サウンド
|
||||
*/
|
||||
|
@ -3150,10 +3158,6 @@ export interface Locale extends ILocale {
|
|||
* オフにすると、「みつける」にアカウントが載らなくなります。
|
||||
*/
|
||||
"makeExplorableDescription": string;
|
||||
/**
|
||||
* タイムラインのノートを離して表示
|
||||
*/
|
||||
"showGapBetweenNotesInTimeline": string;
|
||||
/**
|
||||
* 複製
|
||||
*/
|
||||
|
@ -3930,6 +3934,10 @@ export interface Locale extends ILocale {
|
|||
* ログアウトしますか?
|
||||
*/
|
||||
"logoutConfirm": string;
|
||||
/**
|
||||
* ログアウトするとクライアントの設定情報がブラウザから消去されます。再ログイン時に設定情報を復元できるようにするためには、設定の自動バックアップを有効にしてください。
|
||||
*/
|
||||
"logoutWillClearClientData": string;
|
||||
/**
|
||||
* 最終利用日時
|
||||
*/
|
||||
|
@ -4958,10 +4966,6 @@ export interface Locale extends ILocale {
|
|||
* 引っ張ってリロード
|
||||
*/
|
||||
"pullDownToRefresh": string;
|
||||
/**
|
||||
* タイムラインのリアルタイム更新を無効にする
|
||||
*/
|
||||
"disableStreamingTimeline": string;
|
||||
/**
|
||||
* 通知をグルーピング
|
||||
*/
|
||||
|
@ -5362,6 +5366,65 @@ export interface Locale extends ILocale {
|
|||
* 圧縮
|
||||
*/
|
||||
"compress": string;
|
||||
/**
|
||||
* 右
|
||||
*/
|
||||
"right": string;
|
||||
/**
|
||||
* 下
|
||||
*/
|
||||
"bottom": string;
|
||||
/**
|
||||
* 上
|
||||
*/
|
||||
"top": string;
|
||||
/**
|
||||
* 埋め込み
|
||||
*/
|
||||
"embed": string;
|
||||
/**
|
||||
* 設定を移行しています。しばらくお待ちください... (後ほど、設定→その他→旧設定情報を移行 で手動で移行することもできます)
|
||||
*/
|
||||
"settingsMigrating": string;
|
||||
/**
|
||||
* 読み取り専用
|
||||
*/
|
||||
"readonly": string;
|
||||
/**
|
||||
* デッキへ戻る
|
||||
*/
|
||||
"goToDeck": string;
|
||||
/**
|
||||
* 連合ジョブ
|
||||
*/
|
||||
"federationJobs": string;
|
||||
/**
|
||||
* ドライブでは、過去にアップロードしたファイルの一覧が表示されます。<br>
|
||||
* ノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。<br>
|
||||
* <b>ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。</b><br>
|
||||
* フォルダを作って整理することもできます。
|
||||
*/
|
||||
"driveAboutTip": string;
|
||||
/**
|
||||
* スクロールして閉じる
|
||||
*/
|
||||
"scrollToClose": string;
|
||||
/**
|
||||
* アドバイス
|
||||
*/
|
||||
"advice": string;
|
||||
/**
|
||||
* リアルタイムモード
|
||||
*/
|
||||
"realtimeMode": string;
|
||||
/**
|
||||
* オンにする
|
||||
*/
|
||||
"turnItOn": string;
|
||||
/**
|
||||
* オフにする
|
||||
*/
|
||||
"turnItOff": string;
|
||||
"_chat": {
|
||||
/**
|
||||
* まだメッセージはありません
|
||||
|
@ -5476,6 +5539,10 @@ export interface Locale extends ILocale {
|
|||
* このサーバー、またはこのアカウントでチャットは有効化されていません。
|
||||
*/
|
||||
"chatNotAvailableForThisAccountOrServer": string;
|
||||
/**
|
||||
* このサーバー、またはこのアカウントでチャットは読み取り専用となっています。新たに書き込んだり、チャットルームを作成・参加したりすることはできません。
|
||||
*/
|
||||
"chatIsReadOnlyForThisAccountOrServer": string;
|
||||
/**
|
||||
* 相手のアカウントでチャット機能が使えない状態になっています。
|
||||
*/
|
||||
|
@ -5488,6 +5555,14 @@ export interface Locale extends ILocale {
|
|||
* チャットが使えない状態になっているか、相手がチャットを開放していません。
|
||||
*/
|
||||
"cannotChatWithTheUser_description": string;
|
||||
/**
|
||||
* あなたはこのルームの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。
|
||||
*/
|
||||
"youAreNotAMemberOfThisRoomButInvited": string;
|
||||
/**
|
||||
* 招待を承認しますか?
|
||||
*/
|
||||
"doYouAcceptInvitation": string;
|
||||
/**
|
||||
* チャットする
|
||||
*/
|
||||
|
@ -5497,7 +5572,7 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"thisUserAllowsChatOnlyFromFollowers": string;
|
||||
/**
|
||||
* このユーザーはフォローしているユーザーからのみチャットを受け付けています。
|
||||
* このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。
|
||||
*/
|
||||
"thisUserAllowsChatOnlyFromFollowing": string;
|
||||
/**
|
||||
|
@ -5650,6 +5725,34 @@ export interface Locale extends ILocale {
|
|||
* オフのとき
|
||||
*/
|
||||
"ifOff": string;
|
||||
/**
|
||||
* デバイス間でインストールしたテーマを同期
|
||||
*/
|
||||
"enableSyncThemesBetweenDevices": string;
|
||||
/**
|
||||
* ひっぱって更新
|
||||
*/
|
||||
"enablePullToRefresh": string;
|
||||
/**
|
||||
* マウスでは、ホイールを押し込みながらドラッグします。
|
||||
*/
|
||||
"enablePullToRefresh_description": string;
|
||||
/**
|
||||
* サーバーと接続を確立し、リアルタイムでコンテンツを更新します。通信量とバッテリーの消費が多くなる場合があります。
|
||||
*/
|
||||
"realtimeMode_description": string;
|
||||
/**
|
||||
* コンテンツの取得頻度
|
||||
*/
|
||||
"contentsUpdateFrequency": string;
|
||||
/**
|
||||
* 高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。
|
||||
*/
|
||||
"contentsUpdateFrequency_description": string;
|
||||
/**
|
||||
* リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。
|
||||
*/
|
||||
"contentsUpdateFrequency_description2": string;
|
||||
"_chat": {
|
||||
/**
|
||||
* 送信者の名前を表示
|
||||
|
@ -5674,6 +5777,10 @@ export interface Locale extends ILocale {
|
|||
* 例: 「メインPC」、「スマホ」など
|
||||
*/
|
||||
"profileNameDescription2": string;
|
||||
/**
|
||||
* プロファイルの管理
|
||||
*/
|
||||
"manageProfiles": string;
|
||||
};
|
||||
"_preferencesBackup": {
|
||||
/**
|
||||
|
@ -5816,6 +5923,10 @@ export interface Locale extends ILocale {
|
|||
* サーバー応答なしのため停止中
|
||||
*/
|
||||
"autoSuspendedForNotResponding": string;
|
||||
/**
|
||||
* 配信停止中のソフトウェアであるため停止中
|
||||
*/
|
||||
"softwareSuspended": string;
|
||||
};
|
||||
};
|
||||
"_bubbleGame": {
|
||||
|
@ -6301,6 +6412,48 @@ export interface Locale extends ILocale {
|
|||
* 一定期間モデレーターのアクティビティが検出されなかった場合、スパム防止のためこの設定は自動でオフになります。
|
||||
*/
|
||||
"thisSettingWillAutomaticallyOffWhenModeratorsInactive": string;
|
||||
/**
|
||||
* 配信停止中のソフトウェア
|
||||
*/
|
||||
"deliverSuspendedSoftware": string;
|
||||
/**
|
||||
* 脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。
|
||||
*/
|
||||
"deliverSuspendedSoftwareDescription": string;
|
||||
/**
|
||||
* お一人様モード
|
||||
*/
|
||||
"singleUserMode": string;
|
||||
/**
|
||||
* このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。
|
||||
*/
|
||||
"singleUserMode_description": string;
|
||||
/**
|
||||
* 非利用者に対するユーザー作成コンテンツの公開範囲
|
||||
*/
|
||||
"userGeneratedContentsVisibilityForVisitor": string;
|
||||
/**
|
||||
* モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます。
|
||||
*/
|
||||
"userGeneratedContentsVisibilityForVisitor_description": string;
|
||||
/**
|
||||
* サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。
|
||||
*/
|
||||
"userGeneratedContentsVisibilityForVisitor_description2": string;
|
||||
"_userGeneratedContentsVisibilityForVisitor": {
|
||||
/**
|
||||
* 全て公開
|
||||
*/
|
||||
"all": string;
|
||||
/**
|
||||
* ローカルコンテンツのみ公開し、リモートコンテンツは非公開
|
||||
*/
|
||||
"localOnly": string;
|
||||
/**
|
||||
* 全て非公開
|
||||
*/
|
||||
"none": string;
|
||||
};
|
||||
};
|
||||
"_accountMigration": {
|
||||
/**
|
||||
|
@ -7337,6 +7490,14 @@ export interface Locale extends ILocale {
|
|||
* 数値が大きいほどUI上で先頭に表示されます。
|
||||
*/
|
||||
"descriptionOfDisplayOrder": string;
|
||||
/**
|
||||
* アサイン状態を移行先アカウントにも引き継ぐ
|
||||
*/
|
||||
"preserveAssignmentOnMoveAccount": string;
|
||||
/**
|
||||
* オンにすると、このロールが付与されたアカウントが移行された際に、移行先アカウントにもこのロールが引き継がれるようになります。
|
||||
*/
|
||||
"preserveAssignmentOnMoveAccount_description": string;
|
||||
/**
|
||||
* モデレーターのメンバー編集を許可
|
||||
*/
|
||||
|
@ -7408,6 +7569,10 @@ export interface Locale extends ILocale {
|
|||
* ドライブ容量
|
||||
*/
|
||||
"driveCapacity": string;
|
||||
/**
|
||||
* アップロード可能な最大ファイルサイズ
|
||||
*/
|
||||
"maxFileSize": string;
|
||||
/**
|
||||
* ファイルにNSFWを常に付与
|
||||
*/
|
||||
|
@ -7495,7 +7660,7 @@ export interface Locale extends ILocale {
|
|||
/**
|
||||
* チャットを許可
|
||||
*/
|
||||
"canChat": string;
|
||||
"chatAvailability": string;
|
||||
};
|
||||
"_condition": {
|
||||
/**
|
||||
|
@ -8223,23 +8388,19 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"header": string;
|
||||
/**
|
||||
* サイドバーの背景
|
||||
* ナビゲーションバーの背景
|
||||
*/
|
||||
"navBg": string;
|
||||
/**
|
||||
* サイドバーの文字
|
||||
* ナビゲーションバーの文字
|
||||
*/
|
||||
"navFg": string;
|
||||
/**
|
||||
* サイドバー文字(ホバー)
|
||||
*/
|
||||
"navHoverFg": string;
|
||||
/**
|
||||
* サイドバー文字(アクティブ)
|
||||
* ナビゲーションバー文字(アクティブ)
|
||||
*/
|
||||
"navActive": string;
|
||||
/**
|
||||
* サイドバーのインジケーター
|
||||
* ナビゲーションバーのインジケーター
|
||||
*/
|
||||
"navIndicator": string;
|
||||
/**
|
||||
|
@ -8259,7 +8420,7 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"mentionMe": string;
|
||||
/**
|
||||
* Renote
|
||||
* リノート
|
||||
*/
|
||||
"renote": string;
|
||||
/**
|
||||
|
@ -8322,10 +8483,6 @@ export interface Locale extends ILocale {
|
|||
* ドライブフォルダーの背景
|
||||
*/
|
||||
"driveFolderBg": string;
|
||||
/**
|
||||
* 壁紙のオーバーレイ
|
||||
*/
|
||||
"wallpaperOverlay": string;
|
||||
/**
|
||||
* バッジ
|
||||
*/
|
||||
|
@ -8334,14 +8491,6 @@ export interface Locale extends ILocale {
|
|||
* チャットの背景
|
||||
*/
|
||||
"messageBg": string;
|
||||
/**
|
||||
* アクセント (暗め)
|
||||
*/
|
||||
"accentDarken": string;
|
||||
/**
|
||||
* アクセント (明るめ)
|
||||
*/
|
||||
"accentLighten": string;
|
||||
/**
|
||||
* 強調された文字
|
||||
*/
|
||||
|
@ -9171,6 +9320,10 @@ export interface Locale extends ILocale {
|
|||
* 今日誕生日のユーザー
|
||||
*/
|
||||
"birthdayFollowings": string;
|
||||
/**
|
||||
* チャット
|
||||
*/
|
||||
"chat": string;
|
||||
};
|
||||
"_cw": {
|
||||
/**
|
||||
|
@ -10065,6 +10218,18 @@ export interface Locale extends ILocale {
|
|||
* カラムの寄せ
|
||||
*/
|
||||
"columnAlign": string;
|
||||
/**
|
||||
* カラム間のマージン
|
||||
*/
|
||||
"columnGap": string;
|
||||
/**
|
||||
* デッキメニューの位置
|
||||
*/
|
||||
"deckMenuPosition": string;
|
||||
/**
|
||||
* ナビゲーションバーの位置
|
||||
*/
|
||||
"navbarPosition": string;
|
||||
/**
|
||||
* カラムを追加
|
||||
*/
|
||||
|
@ -10118,7 +10283,7 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"introduction": string;
|
||||
/**
|
||||
* 画面の右にある + を押して、いつでもカラムを追加できます。
|
||||
* カラムを追加するには、画面の + をクリックします。
|
||||
*/
|
||||
"introduction2": string;
|
||||
/**
|
||||
|
@ -10182,6 +10347,10 @@ export interface Locale extends ILocale {
|
|||
* ロールタイムライン
|
||||
*/
|
||||
"roleTimeline": string;
|
||||
/**
|
||||
* チャット
|
||||
*/
|
||||
"chat": string;
|
||||
};
|
||||
};
|
||||
"_dialog": {
|
||||
|
@ -11517,6 +11686,166 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"serverHostPlaceholder": string;
|
||||
};
|
||||
"_serverSetupWizard": {
|
||||
/**
|
||||
* Misskeyのインストールが完了しました!
|
||||
*/
|
||||
"installCompleted": string;
|
||||
/**
|
||||
* まずは、管理者アカウントを作成しましょう。
|
||||
*/
|
||||
"firstCreateAccount": string;
|
||||
/**
|
||||
* 管理者アカウントが作成されました!
|
||||
*/
|
||||
"accountCreated": string;
|
||||
/**
|
||||
* サーバーの設定
|
||||
*/
|
||||
"serverSetting": string;
|
||||
/**
|
||||
* このウィザードで簡単に最適なサーバーの設定が行えます。
|
||||
*/
|
||||
"youCanEasilyConfigureOptimalServerSettingsWithThisWizard": string;
|
||||
/**
|
||||
* ここでの設定は、あとからでも変更できます。
|
||||
*/
|
||||
"settingsYouMakeHereCanBeChangedLater": string;
|
||||
/**
|
||||
* Misskeyをどのように使いますか?
|
||||
*/
|
||||
"howWillYouUseMisskey": string;
|
||||
"_use": {
|
||||
/**
|
||||
* お一人様サーバー
|
||||
*/
|
||||
"single": string;
|
||||
/**
|
||||
* 自分専用のサーバーとして、一人で使う
|
||||
*/
|
||||
"single_description": string;
|
||||
/**
|
||||
* お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。
|
||||
*/
|
||||
"single_youCanCreateMultipleAccounts": string;
|
||||
/**
|
||||
* グループサーバー
|
||||
*/
|
||||
"group": string;
|
||||
/**
|
||||
* 信頼できる他の利用者を招待して、複数人で使う
|
||||
*/
|
||||
"group_description": string;
|
||||
/**
|
||||
* オープンサーバー
|
||||
*/
|
||||
"open": string;
|
||||
/**
|
||||
* 不特定多数の利用者を受け入れる運営を行う
|
||||
*/
|
||||
"open_description": string;
|
||||
};
|
||||
/**
|
||||
* 不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。
|
||||
*/
|
||||
"openServerAdvice": string;
|
||||
/**
|
||||
* 自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。
|
||||
*/
|
||||
"openServerAntiSpamAdvice": string;
|
||||
/**
|
||||
* どれくらいの人数を想定していますか?
|
||||
*/
|
||||
"howManyUsersDoYouExpect": string;
|
||||
"_scale": {
|
||||
/**
|
||||
* 100人以下 (小規模)
|
||||
*/
|
||||
"small": string;
|
||||
/**
|
||||
* 100人以上1000人以下 (中規模)
|
||||
*/
|
||||
"medium": string;
|
||||
/**
|
||||
* 1000人以上 (大規模)
|
||||
*/
|
||||
"large": string;
|
||||
};
|
||||
/**
|
||||
* 大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。
|
||||
*/
|
||||
"largeScaleServerAdvice": string;
|
||||
/**
|
||||
* Fediverseと接続しますか?
|
||||
*/
|
||||
"doYouConnectToFediverse": string;
|
||||
/**
|
||||
* 分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。
|
||||
*/
|
||||
"doYouConnectToFediverse_description1": string;
|
||||
/**
|
||||
* Fediverseと接続することは「連合」とも呼ばれます。
|
||||
*/
|
||||
"doYouConnectToFediverse_description2": string;
|
||||
/**
|
||||
* 連合可能なサーバーの指定など、高度な設定も後ほど可能です。
|
||||
*/
|
||||
"youCanConfigureMoreFederationSettingsLater": string;
|
||||
/**
|
||||
* 管理者情報
|
||||
*/
|
||||
"adminInfo": string;
|
||||
/**
|
||||
* 問い合わせを受け付けるために使用される管理者情報を設定します。
|
||||
*/
|
||||
"adminInfo_description": string;
|
||||
/**
|
||||
* オープンサーバー、または連合がオンの場合は必ず入力が必要です。
|
||||
*/
|
||||
"adminInfo_mustBeFilled": string;
|
||||
/**
|
||||
* 以下の設定が推奨されます
|
||||
*/
|
||||
"followingSettingsAreRecommended": string;
|
||||
/**
|
||||
* この設定を適用
|
||||
*/
|
||||
"applyTheseSettings": string;
|
||||
/**
|
||||
* 設定をスキップ
|
||||
*/
|
||||
"skipSettings": string;
|
||||
/**
|
||||
* 設定が完了しました!
|
||||
*/
|
||||
"settingsCompleted": string;
|
||||
/**
|
||||
* お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。
|
||||
*/
|
||||
"settingsCompleted_description": string;
|
||||
/**
|
||||
* 詳細なサーバー設定は、「コントロールパネル」から行えます。
|
||||
*/
|
||||
"settingsCompleted_description2": string;
|
||||
/**
|
||||
* 寄付のお願い
|
||||
*/
|
||||
"donationRequest": string;
|
||||
"_donationRequest": {
|
||||
/**
|
||||
* Misskeyは有志によって開発されている無料のソフトウェアです。
|
||||
*/
|
||||
"text1": string;
|
||||
/**
|
||||
* 今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。
|
||||
*/
|
||||
"text2": string;
|
||||
/**
|
||||
* 支援者向け特典もあります!
|
||||
*/
|
||||
"text3": string;
|
||||
};
|
||||
};
|
||||
}
|
||||
declare const locales: {
|
||||
[lang: string]: Locale;
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Non ci sono profili"
|
|||
editProfile: "Modifica profilo"
|
||||
noteDeleteConfirm: "Vuoi davvero eliminare questa Nota?"
|
||||
pinLimitExceeded: "Non puoi fissare altre note "
|
||||
intro: "L'installazione di Misskey è terminata! Si prega di creare il profilo amministratore."
|
||||
done: "Fine"
|
||||
processing: "In elaborazione"
|
||||
preview: "Anteprima"
|
||||
|
@ -382,7 +381,7 @@ disconnectService: "Disconnetti"
|
|||
enableLocalTimeline: "Abilita la timeline locale"
|
||||
enableGlobalTimeline: "Abilita la timeline federata"
|
||||
disablingTimelinesInfo: "Anche disabilitandole, gli Amministratori e i Moderatori potranno comunque accedervi."
|
||||
registration: "Iscriviti"
|
||||
registration: "Registrazione"
|
||||
invite: "Invita"
|
||||
driveCapacityPerLocalAccount: "Capienza del Drive per profilo locale"
|
||||
driveCapacityPerRemoteAccount: "Capienza del Drive per profilo remoto"
|
||||
|
@ -424,6 +423,7 @@ antennaExcludeBots: "Escludere i Bot"
|
|||
antennaKeywordsDescription: "Sparando con uno spazio indichi la condizione E (and). Separando con un a capo, indichi la condizione O (or)."
|
||||
notifyAntenna: "Invia notifiche delle nuove note"
|
||||
withFileAntenna: "Solo note con file in allegato"
|
||||
excludeNotesInSensitiveChannel: "Escludere le Note dai canali espliciti"
|
||||
enableServiceworker: "Abilita ServiceWorker"
|
||||
antennaUsersDescription: "Elenca un nome utente per riga"
|
||||
caseSensitive: "Sensibile alla distinzione tra maiuscole e minuscole"
|
||||
|
@ -522,7 +522,7 @@ showNoteActionsOnlyHover: "Mostra le azioni delle Note solo al passaggio del mou
|
|||
showReactionsCount: "Visualizza il numero di reazioni su una nota"
|
||||
noHistory: "Nessuna cronologia"
|
||||
signinHistory: "Storico degli accessi al profilo"
|
||||
enableAdvancedMfm: "Attiva MFM avanzati"
|
||||
enableAdvancedMfm: "Attivare i Misskey Flavoured Markdown (MFM) avanzati"
|
||||
enableAnimatedMfm: "Attiva MFM animati"
|
||||
doing: "In corso..."
|
||||
category: "Categoria"
|
||||
|
@ -605,7 +605,7 @@ uiInspector: "UI Inspector"
|
|||
uiInspectorDescription: "Puoi visualizzare un elenco di elementi UI presenti in memoria. I componenti dell'interfaccia utente vengono generati dalle funzioni Ui:C:."
|
||||
output: "Output"
|
||||
script: "Script"
|
||||
disablePagesScript: "Disabilita AiScript nelle pagine"
|
||||
disablePagesScript: "Disabilitare AiScript nelle pagine"
|
||||
updateRemoteUser: "Aggiorna dati dal profilo remoto"
|
||||
unsetUserAvatar: "Rimozione foto profilo"
|
||||
unsetUserAvatarConfirm: "Vuoi davvero rimuovere la foto profilo?"
|
||||
|
@ -663,7 +663,7 @@ generateAccessToken: "Genera token di accesso"
|
|||
permission: "Autorizzazioni "
|
||||
adminPermission: "Privilegi amministrativi"
|
||||
enableAll: "Abilita tutto"
|
||||
disableAll: "Disabilita tutto"
|
||||
disableAll: "Disabilitare tutto"
|
||||
tokenRequested: "Autorizza accesso al profilo"
|
||||
pluginTokenRequestedDescription: "Il plugin potrà utilizzare le autorizzazioni impostate qui."
|
||||
notificationType: "Tipo di notifiche"
|
||||
|
@ -727,7 +727,7 @@ reporterOrigin: "Segnalazione da"
|
|||
send: "Inviare"
|
||||
openInNewTab: "Apri in una nuova scheda"
|
||||
openInSideView: "Apri in vista laterale"
|
||||
defaultNavigationBehaviour: "Navigazione preimpostata"
|
||||
defaultNavigationBehaviour: "Tipo di navigazione predefinita"
|
||||
editTheseSettingsMayBreakAccount: "Modificare queste impostazioni può danneggiare il profilo"
|
||||
instanceTicker: "Informazioni sull'istanza da cui vengono le note"
|
||||
waitingFor: "Aspettando {x}"
|
||||
|
@ -766,7 +766,7 @@ noCrawleDescription: "Richiedi che i motori di ricerca non indicizzino la tua pa
|
|||
lockedAccountInfo: "A meno che non imposti la visibilità delle tue note su \"Solo ai follower\", le tue note sono visibili da tutti, anche se hai configurato l'account per confermare manualmente le richieste di follow."
|
||||
alwaysMarkSensitive: "Segnare automaticamente come espliciti gli allegati"
|
||||
loadRawImages: "Visualizza le intere immagini allegate invece delle miniature."
|
||||
disableShowingAnimatedImages: "Disabilita le immagini animate"
|
||||
disableShowingAnimatedImages: "Disabilitare le immagini animate"
|
||||
highlightSensitiveMedia: "Evidenzia i media espliciti"
|
||||
verificationEmailSent: "Una mail di verifica è stata inviata. Si prega di accedere al collegamento per compiere la verifica."
|
||||
notSet: "Non impostato"
|
||||
|
@ -783,7 +783,6 @@ thisIsExperimentalFeature: "Questa è una funzionalità sperimentale. Potrebbe e
|
|||
developer: "Sviluppatore"
|
||||
makeExplorable: "Profilo visibile pubblicamente nella pagina \"Esplora\""
|
||||
makeExplorableDescription: "Disabilitando questa opzione, il tuo profilo non verrà elencato nella pagina \"Esplora\"."
|
||||
showGapBetweenNotesInTimeline: "Mostrare un intervallo tra le note sulla timeline"
|
||||
duplicate: "Duplica"
|
||||
left: "Sinistra"
|
||||
center: "Centro"
|
||||
|
@ -866,7 +865,7 @@ noBotProtectionWarning: "Non è stata impostata alcuna protezione dai Bot"
|
|||
configure: "Imposta"
|
||||
postToGallery: "Pubblicare nella galleria"
|
||||
postToHashtag: "Pubblica a questo hashtag"
|
||||
gallery: "Galleria"
|
||||
gallery: "Gallerie"
|
||||
recentPosts: "Pubblicazioni recenti"
|
||||
popularPosts: "Le più visualizzate"
|
||||
shareWithNote: "Condividere in nota"
|
||||
|
@ -978,6 +977,7 @@ document: "Documentazione"
|
|||
numberOfPageCache: "Numero di pagine cache"
|
||||
numberOfPageCacheDescription: "Aumenta l'usabilità, ma aumenta anche il carico e l'utilizzo della memoria."
|
||||
logoutConfirm: "Vuoi davvero uscire da Misskey? "
|
||||
logoutWillClearClientData: "All'uscita, la configurazione del client viene rimossa dal browser. Per ripristinarla quando si effettua nuovamente l'accesso, abilitare il backup automatico."
|
||||
lastActiveDate: "Data dell'ultimo utilizzo"
|
||||
statusbar: "Barra di stato"
|
||||
pleaseSelect: "Scegli un'opzione"
|
||||
|
@ -1192,7 +1192,7 @@ renotes: "Rinota"
|
|||
loadReplies: "Leggi le risposte"
|
||||
loadConversation: "Leggi la conversazione"
|
||||
pinnedList: "Elenco in primo piano"
|
||||
keepScreenOn: "Mantieni lo schermo acceso"
|
||||
keepScreenOn: "Mantenere lo schermo acceso"
|
||||
verifiedLink: "Abbiamo confermato la validità di questo collegamento"
|
||||
notifyNotes: "Notifica nuove Note"
|
||||
unnotifyNotes: "Interrompi le notifiche di nuove Note"
|
||||
|
@ -1234,8 +1234,7 @@ flip: "Inverti"
|
|||
showAvatarDecorations: "Mostra decorazione della foto profilo"
|
||||
releaseToRefresh: "Rilascia per aggiornare"
|
||||
refreshing: "Aggiornamento..."
|
||||
pullDownToRefresh: "Trascina per aggiornare"
|
||||
disableStreamingTimeline: "Disabilitare gli aggiornamenti della TL in tempo reale"
|
||||
pullDownToRefresh: "Trascinare per aggiornare"
|
||||
useGroupedNotifications: "Mostra le notifiche raggruppate"
|
||||
signupPendingError: "Si è verificato un problema durante la verifica del tuo indirizzo email. Potrebbe essere scaduto il collegamento temporaneo."
|
||||
cwNotationRequired: "Devi indicare perché il contenuto è indicato come esplicito."
|
||||
|
@ -1262,7 +1261,7 @@ backToTitle: "Torna al titolo"
|
|||
hemisphere: "Geolocalizzazione"
|
||||
withSensitive: "Mostra le Note con allegati espliciti"
|
||||
userSaysSomethingSensitive: "Note da {name} con allegati espliciti"
|
||||
enableHorizontalSwipe: "Trascina per invertire i tab"
|
||||
enableHorizontalSwipe: "Trascinare per invertire le colonne"
|
||||
loading: "Caricamento"
|
||||
surrender: "Annulla"
|
||||
gameRetry: "Riprova"
|
||||
|
@ -1336,6 +1335,13 @@ chat: "Chat"
|
|||
migrateOldSettings: "Migrare le vecchie impostazioni"
|
||||
migrateOldSettings_description: "Di solito, viene fatto automaticamente. Se per qualche motivo non fossero migrate con successo, è possibile avviare il processo di migrazione manualmente, sovrascrivendo le configurazioni attuali."
|
||||
compress: "Comprimi"
|
||||
right: "Destra"
|
||||
bottom: "Sotto"
|
||||
top: "Sopra"
|
||||
embed: "Incorporare"
|
||||
settingsMigrating: "Migrazione delle impostazioni. Attendere prego ... (Puoi anche migrare manualmente in un secondo momento, nel menu: Impostazioni → Altro → Migrazione delle impostazioni)"
|
||||
readonly: "Sola lettura"
|
||||
goToDeck: "Torna al Deck"
|
||||
_chat:
|
||||
noMessagesYet: "Ancora nessun messaggio"
|
||||
newMessage: "Nuovo messaggio"
|
||||
|
@ -1365,6 +1371,7 @@ _chat:
|
|||
muteThisRoom: "Silenzia stanza"
|
||||
deleteRoom: "Elimina stanza"
|
||||
chatNotAvailableForThisAccountOrServer: "Questo server, o questo profilo ha disabilitato la chat."
|
||||
chatIsReadOnlyForThisAccountOrServer: "Le chat, su questo server o su questo profilo, sono di sola lettura. Impossibile scrivere in chat o creare e partecipare a stanze."
|
||||
chatNotAvailableInOtherAccount: "La chat non è disponibile nel profilo dell'altra persona."
|
||||
cannotChatWithTheUser: "Impossibile chattare con questa persona"
|
||||
cannotChatWithTheUser_description: "La chat potrebbe non essere disponibile, oppure l'altra persona potrebbe non esserlo."
|
||||
|
@ -1406,9 +1413,11 @@ _settings:
|
|||
timelineAndNote: "Note e Timeline"
|
||||
makeEveryTextElementsSelectable: "Imposta ogni elemento come selezionabile"
|
||||
makeEveryTextElementsSelectable_description: "Potrebbe ridurre l'usabilità in alcune situazioni."
|
||||
useStickyIcons: "Fissa le icone durante lo scorrimento"
|
||||
showNavbarSubButtons: "Mostra i pulsanti secondari nella barra di navigazione"
|
||||
ifOn: "Quando attivato"
|
||||
ifOff: "Quando disattivato"
|
||||
enableSyncThemesBetweenDevices: "Sincronizzare il tema tra i dispositivi"
|
||||
_chat:
|
||||
showSenderName: "Mostra il nome del mittente"
|
||||
sendOnEnter: "Invio spedisce"
|
||||
|
@ -1881,6 +1890,8 @@ _role:
|
|||
descriptionOfIsExplorable: "Selezionandolo, la timeline del ruolo diventerà accessibile pubblicamente. Tranne se il ruolo non è pubblico."
|
||||
displayOrder: "Ordine di visualizzazione"
|
||||
descriptionOfDisplayOrder: "I valori più alti vengono visualizzati per primi"
|
||||
preserveAssignmentOnMoveAccount: "Mantenere l'assegnazione alla migrazione del profilo"
|
||||
preserveAssignmentOnMoveAccount_description: "Attivando, il ruolo verrà portato sul profilo destinatario, durante la migrazione."
|
||||
canEditMembersByModerator: "Anche i Moderatori assegnano profili a questo ruolo"
|
||||
descriptionOfCanEditMembersByModerator: "Se disattivo, potranno farlo solamente gli Amministratori."
|
||||
priority: "Priorità"
|
||||
|
@ -1921,7 +1932,7 @@ _role:
|
|||
canImportFollowing: "Può importare Following"
|
||||
canImportMuting: "Può importare Silenziati"
|
||||
canImportUserLists: "Può importare liste di Profili"
|
||||
canChat: "Chat consentita"
|
||||
chatAvailability: "Chat consentita"
|
||||
_condition:
|
||||
roleAssignedTo: "Assegnato a ruoli manualmente"
|
||||
isLocal: "Profilo locale"
|
||||
|
@ -2118,14 +2129,13 @@ _theme:
|
|||
header: "Intestazione"
|
||||
navBg: "Sfondo della barra laterale"
|
||||
navFg: "Testo della barra laterale"
|
||||
navHoverFg: "Testo della barra laterale (al passaggio del mouse)"
|
||||
navActive: "Testo della barra laterale (attivo)"
|
||||
navIndicator: "Indicatore di barra laterale"
|
||||
link: "Link"
|
||||
hashtag: "Hashtag"
|
||||
mention: "Menzioni"
|
||||
mentionMe: "Menzioni (di me)"
|
||||
renote: "Rinota"
|
||||
renote: "Renota"
|
||||
modalBg: "Sfondo modale."
|
||||
divider: "Interruzione di linea"
|
||||
scrollbarHandle: "Maniglie della barra di scorrimento"
|
||||
|
@ -2141,11 +2151,8 @@ _theme:
|
|||
buttonHoverBg: "Sfondo del pulsante (sorvolato)"
|
||||
inputBorder: "Inquadra casella di testo"
|
||||
driveFolderBg: "Sfondo della cartella di disco"
|
||||
wallpaperOverlay: "Sovrapposizione dello sfondo"
|
||||
badge: "Distintivo"
|
||||
messageBg: "Sfondo della chat"
|
||||
accentDarken: "Temi (scuri)"
|
||||
accentLighten: "Temi (luminosi)"
|
||||
fgHighlighted: "Testo in evidenza."
|
||||
_sfx:
|
||||
note: "Nota"
|
||||
|
@ -2359,6 +2366,7 @@ _widgets:
|
|||
chooseList: "Seleziona una lista"
|
||||
clicker: "Cliccheria"
|
||||
birthdayFollowings: "Compleanni del giorno"
|
||||
chat: "Chat"
|
||||
_cw:
|
||||
hide: "Nascondere"
|
||||
show: "Continua la lettura..."
|
||||
|
@ -2591,7 +2599,10 @@ _notification:
|
|||
renote: "Rinota"
|
||||
_deck:
|
||||
alwaysShowMainColumn: "Mostra sempre la colonna principale"
|
||||
columnAlign: "Allineare colonne"
|
||||
columnAlign: "Allineamento delle colonne"
|
||||
columnGap: "Spessore del margine tra colonne"
|
||||
deckMenuPosition: "Posizione del menu Deck"
|
||||
navbarPosition: "Posizione barra di navigazione"
|
||||
addColumn: "Aggiungi colonna"
|
||||
newNoteNotificationSettings: "Preferenze per le notifiche di nuove Note"
|
||||
configureColumn: "Impostazioni colonna"
|
||||
|
@ -2618,10 +2629,11 @@ _deck:
|
|||
tl: "Timeline"
|
||||
antenna: "Antenne"
|
||||
list: "Liste"
|
||||
channel: "Canale"
|
||||
channel: "Canali"
|
||||
mentions: "Menzioni"
|
||||
direct: "Note Dirette"
|
||||
roleTimeline: "Timeline Ruolo"
|
||||
chat: "Chat"
|
||||
_dialog:
|
||||
charactersExceeded: "Hai superato il limite di {max} caratteri! ({current})"
|
||||
charactersBelow: "Sei al di sotto del minimo di {min} caratteri! ({current})"
|
||||
|
@ -2908,7 +2920,7 @@ _customEmojisManager:
|
|||
directoryToCategoryLabel: "Inseriscile in una cartella omonima alla categoria"
|
||||
directoryToCategoryCaption: "Crea il campo categoria in base alla cartella."
|
||||
emojiInputAreaCaption: "Seleziona l'emoji da registrare utilizzando uno dei metodi."
|
||||
emojiInputAreaList1: "Trascina una immagine o una cartella in quest'area"
|
||||
emojiInputAreaList1: "Trascinare una immagine o una cartella in quest'area"
|
||||
emojiInputAreaList2: "Clicca per scegliere file dal tuo dispositivo"
|
||||
emojiInputAreaList3: "Clicca per selezionare dal Drive"
|
||||
confirmRegisterEmojisDescription: "Registrazione delle emoji elencate come nuove emoji personalizzate. Vuoi davvero procedere? (Per evitare sovraccarichi, puoi registrare al massimo {count} emoji per volta)"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "サーバーをサイレンス"
|
|||
mediaSilenceThisInstance: "サーバーをメディアサイレンス"
|
||||
operations: "操作"
|
||||
software: "ソフトウェア"
|
||||
softwareName: "ソフトウェア名"
|
||||
version: "バージョン"
|
||||
metadata: "メタデータ"
|
||||
withNFiles: "{n}つのファイル"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "ユーザーはいません"
|
|||
editProfile: "プロフィールを編集"
|
||||
noteDeleteConfirm: "このノートを削除しますか?"
|
||||
pinLimitExceeded: "これ以上ピン留めできません"
|
||||
intro: "Misskeyのインストールが完了しました!管理者アカウントを作成しましょう。"
|
||||
done: "完了"
|
||||
processing: "処理中"
|
||||
preview: "プレビュー"
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "Botアカウントを除外"
|
|||
antennaKeywordsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
notifyAntenna: "新しいノートを通知する"
|
||||
withFileAntenna: "ファイルが添付されたノートのみ"
|
||||
excludeNotesInSensitiveChannel: "センシティブなチャンネルのノートを除外"
|
||||
enableServiceworker: "ブラウザへのプッシュ通知を有効にする"
|
||||
antennaUsersDescription: "ユーザー名を改行で区切って指定します"
|
||||
caseSensitive: "大文字小文字を区別する"
|
||||
|
@ -574,6 +575,7 @@ showFixedPostForm: "タイムライン上部に投稿フォームを表示する
|
|||
showFixedPostFormInChannel: "タイムライン上部に投稿フォームを表示する(チャンネル)"
|
||||
withRepliesByDefaultForNewlyFollowed: "フォローする際、デフォルトで返信をTLに含むようにする"
|
||||
newNoteRecived: "新しいノートがあります"
|
||||
newNote: "新しいノート"
|
||||
sounds: "サウンド"
|
||||
sound: "サウンド"
|
||||
listen: "聴く"
|
||||
|
@ -783,7 +785,6 @@ thisIsExperimentalFeature: "これは実験的な機能です。仕様が変更
|
|||
developer: "開発者"
|
||||
makeExplorable: "アカウントを見つけやすくする"
|
||||
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。"
|
||||
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "中央"
|
||||
|
@ -978,6 +979,7 @@ document: "ドキュメント"
|
|||
numberOfPageCache: "ページキャッシュ数"
|
||||
numberOfPageCacheDescription: "多くすると利便性が向上しますが、負荷とメモリ使用量が増えます。"
|
||||
logoutConfirm: "ログアウトしますか?"
|
||||
logoutWillClearClientData: "ログアウトするとクライアントの設定情報がブラウザから消去されます。再ログイン時に設定情報を復元できるようにするためには、設定の自動バックアップを有効にしてください。"
|
||||
lastActiveDate: "最終利用日時"
|
||||
statusbar: "ステータスバー"
|
||||
pleaseSelect: "選択してください"
|
||||
|
@ -1235,7 +1237,6 @@ showAvatarDecorations: "アイコンのデコレーションを表示"
|
|||
releaseToRefresh: "離してリロード"
|
||||
refreshing: "リロード中"
|
||||
pullDownToRefresh: "引っ張ってリロード"
|
||||
disableStreamingTimeline: "タイムラインのリアルタイム更新を無効にする"
|
||||
useGroupedNotifications: "通知をグルーピング"
|
||||
signupPendingError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。"
|
||||
cwNotationRequired: "「内容を隠す」がオンの場合は注釈の記述が必要です。"
|
||||
|
@ -1336,6 +1337,20 @@ chat: "チャット"
|
|||
migrateOldSettings: "旧設定情報を移行"
|
||||
migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。"
|
||||
compress: "圧縮"
|
||||
right: "右"
|
||||
bottom: "下"
|
||||
top: "上"
|
||||
embed: "埋め込み"
|
||||
settingsMigrating: "設定を移行しています。しばらくお待ちください... (後ほど、設定→その他→旧設定情報を移行 で手動で移行することもできます)"
|
||||
readonly: "読み取り専用"
|
||||
goToDeck: "デッキへ戻る"
|
||||
federationJobs: "連合ジョブ"
|
||||
driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。<br>\nノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。<br>\n<b>ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。</b><br>\nフォルダを作って整理することもできます。"
|
||||
scrollToClose: "スクロールして閉じる"
|
||||
advice: "アドバイス"
|
||||
realtimeMode: "リアルタイムモード"
|
||||
turnItOn: "オンにする"
|
||||
turnItOff: "オフにする"
|
||||
|
||||
_chat:
|
||||
noMessagesYet: "まだメッセージはありません"
|
||||
|
@ -1366,12 +1381,15 @@ _chat:
|
|||
muteThisRoom: "このルームをミュート"
|
||||
deleteRoom: "ルームを削除"
|
||||
chatNotAvailableForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは有効化されていません。"
|
||||
chatIsReadOnlyForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは読み取り専用となっています。新たに書き込んだり、チャットルームを作成・参加したりすることはできません。"
|
||||
chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えない状態になっています。"
|
||||
cannotChatWithTheUser: "このユーザーとのチャットを開始できません"
|
||||
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。"
|
||||
youAreNotAMemberOfThisRoomButInvited: "あなたはこのルームの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。"
|
||||
doYouAcceptInvitation: "招待を承認しますか?"
|
||||
chatWithThisUser: "チャットする"
|
||||
thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみチャットを受け付けています。"
|
||||
thisUserAllowsChatOnlyFromFollowing: "このユーザーはフォローしているユーザーからのみチャットを受け付けています。"
|
||||
thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。"
|
||||
thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのみチャットを受け付けています。"
|
||||
thisUserNotAllowedChatAnyone: "このユーザーは誰からもチャットを受け付けていません。"
|
||||
chatAllowedUsers: "チャットを許可する相手"
|
||||
|
@ -1413,6 +1431,13 @@ _settings:
|
|||
showNavbarSubButtons: "ナビゲーションバーに副ボタンを表示"
|
||||
ifOn: "オンのとき"
|
||||
ifOff: "オフのとき"
|
||||
enableSyncThemesBetweenDevices: "デバイス間でインストールしたテーマを同期"
|
||||
enablePullToRefresh: "ひっぱって更新"
|
||||
enablePullToRefresh_description: "マウスでは、ホイールを押し込みながらドラッグします。"
|
||||
realtimeMode_description: "サーバーと接続を確立し、リアルタイムでコンテンツを更新します。通信量とバッテリーの消費が多くなる場合があります。"
|
||||
contentsUpdateFrequency: "コンテンツの取得頻度"
|
||||
contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。"
|
||||
contentsUpdateFrequency_description2: "リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。"
|
||||
|
||||
_chat:
|
||||
showSenderName: "送信者の名前を表示"
|
||||
|
@ -1422,6 +1447,7 @@ _preferencesProfile:
|
|||
profileName: "プロファイル名"
|
||||
profileNameDescription: "このデバイスを識別する名前を設定してください。"
|
||||
profileNameDescription2: "例: 「メインPC」、「スマホ」など"
|
||||
manageProfiles: "プロファイルの管理"
|
||||
|
||||
_preferencesBackup:
|
||||
autoBackup: "自動バックアップ"
|
||||
|
@ -1464,6 +1490,7 @@ _delivery:
|
|||
manuallySuspended: "手動停止中"
|
||||
goneSuspended: "サーバー削除のため停止中"
|
||||
autoSuspendedForNotResponding: "サーバー応答なしのため停止中"
|
||||
softwareSuspended: "配信停止中のソフトウェアであるため停止中"
|
||||
|
||||
_bubbleGame:
|
||||
howToPlay: "遊び方"
|
||||
|
@ -1602,6 +1629,18 @@ _serverSettings:
|
|||
openRegistration: "アカウントの作成をオープンにする"
|
||||
openRegistrationWarning: "登録を開放することはリスクが伴います。サーバーを常に監視し、トラブルが発生した際にすぐに対応できる体制がある場合のみオンにすることを推奨します。"
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "一定期間モデレーターのアクティビティが検出されなかった場合、スパム防止のためこの設定は自動でオフになります。"
|
||||
deliverSuspendedSoftware: "配信停止中のソフトウェア"
|
||||
deliverSuspendedSoftwareDescription: "脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。"
|
||||
singleUserMode: "お一人様モード"
|
||||
singleUserMode_description: "このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。"
|
||||
userGeneratedContentsVisibilityForVisitor: "非利用者に対するユーザー作成コンテンツの公開範囲"
|
||||
userGeneratedContentsVisibilityForVisitor_description: "モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます。"
|
||||
userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。"
|
||||
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "全て公開"
|
||||
localOnly: "ローカルコンテンツのみ公開し、リモートコンテンツは非公開"
|
||||
none: "全て非公開"
|
||||
|
||||
_accountMigration:
|
||||
moveFrom: "別のアカウントからこのアカウントに移行"
|
||||
|
@ -1901,6 +1940,8 @@ _role:
|
|||
descriptionOfIsExplorable: "オンにすると、「みつける」でメンバー一覧が公開されるほか、ロールのタイムラインが利用可能になります。"
|
||||
displayOrder: "表示順"
|
||||
descriptionOfDisplayOrder: "数値が大きいほどUI上で先頭に表示されます。"
|
||||
preserveAssignmentOnMoveAccount: "アサイン状態を移行先アカウントにも引き継ぐ"
|
||||
preserveAssignmentOnMoveAccount_description: "オンにすると、このロールが付与されたアカウントが移行された際に、移行先アカウントにもこのロールが引き継がれるようになります。"
|
||||
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
|
||||
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになります。オフにすると管理者のみが行えます。"
|
||||
priority: "優先度"
|
||||
|
@ -1920,6 +1961,7 @@ _role:
|
|||
canManageCustomEmojis: "カスタム絵文字の管理"
|
||||
canManageAvatarDecorations: "アバターデコレーションの管理"
|
||||
driveCapacity: "ドライブ容量"
|
||||
maxFileSize: "アップロード可能な最大ファイルサイズ"
|
||||
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
||||
canUpdateBioMedia: "アイコンとバナーの更新を許可"
|
||||
pinMax: "ノートのピン留めの最大数"
|
||||
|
@ -1941,7 +1983,7 @@ _role:
|
|||
canImportFollowing: "フォローのインポートを許可"
|
||||
canImportMuting: "ミュートのインポートを許可"
|
||||
canImportUserLists: "リストのインポートを許可"
|
||||
canChat: "チャットを許可"
|
||||
chatAvailability: "チャットを許可"
|
||||
_condition:
|
||||
roleAssignedTo: "マニュアルロールにアサイン済み"
|
||||
isLocal: "ローカルユーザー"
|
||||
|
@ -2158,16 +2200,15 @@ _theme:
|
|||
panel: "パネル"
|
||||
shadow: "影"
|
||||
header: "ヘッダー"
|
||||
navBg: "サイドバーの背景"
|
||||
navFg: "サイドバーの文字"
|
||||
navHoverFg: "サイドバー文字(ホバー)"
|
||||
navActive: "サイドバー文字(アクティブ)"
|
||||
navIndicator: "サイドバーのインジケーター"
|
||||
navBg: "ナビゲーションバーの背景"
|
||||
navFg: "ナビゲーションバーの文字"
|
||||
navActive: "ナビゲーションバー文字(アクティブ)"
|
||||
navIndicator: "ナビゲーションバーのインジケーター"
|
||||
link: "リンク"
|
||||
hashtag: "ハッシュタグ"
|
||||
mention: "メンション"
|
||||
mentionMe: "あなた宛てメンション"
|
||||
renote: "Renote"
|
||||
renote: "リノート"
|
||||
modalBg: "モーダルの背景"
|
||||
divider: "分割線"
|
||||
scrollbarHandle: "スクロールバーの取っ手"
|
||||
|
@ -2183,11 +2224,8 @@ _theme:
|
|||
buttonHoverBg: "ボタンの背景 (ホバー)"
|
||||
inputBorder: "入力ボックスの縁取り"
|
||||
driveFolderBg: "ドライブフォルダーの背景"
|
||||
wallpaperOverlay: "壁紙のオーバーレイ"
|
||||
badge: "バッジ"
|
||||
messageBg: "チャットの背景"
|
||||
accentDarken: "アクセント (暗め)"
|
||||
accentLighten: "アクセント (明るめ)"
|
||||
fgHighlighted: "強調された文字"
|
||||
|
||||
_sfx:
|
||||
|
@ -2412,6 +2450,7 @@ _widgets:
|
|||
chooseList: "リストを選択"
|
||||
clicker: "クリッカー"
|
||||
birthdayFollowings: "今日誕生日のユーザー"
|
||||
chat: "チャット"
|
||||
|
||||
_cw:
|
||||
hide: "隠す"
|
||||
|
@ -2662,6 +2701,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "常にメインカラムを表示"
|
||||
columnAlign: "カラムの寄せ"
|
||||
columnGap: "カラム間のマージン"
|
||||
deckMenuPosition: "デッキメニューの位置"
|
||||
navbarPosition: "ナビゲーションバーの位置"
|
||||
addColumn: "カラムを追加"
|
||||
newNoteNotificationSettings: "新着ノート通知の設定"
|
||||
configureColumn: "カラムの設定"
|
||||
|
@ -2675,7 +2717,7 @@ _deck:
|
|||
newProfile: "新規プロファイル"
|
||||
deleteProfile: "プロファイルを削除"
|
||||
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
|
||||
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
|
||||
introduction2: "カラムを追加するには、画面の + をクリックします。"
|
||||
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
|
||||
useSimpleUiForNonRootPages: "非ルートページは簡易UIで表示"
|
||||
usedAsMinWidthWhenFlexible: "「幅を自動調整」が有効の場合、これが幅の最小値となります"
|
||||
|
@ -2693,6 +2735,7 @@ _deck:
|
|||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト"
|
||||
roleTimeline: "ロールタイムライン"
|
||||
chat: "チャット"
|
||||
|
||||
_dialog:
|
||||
charactersExceeded: "最大文字数を超えています! 現在 {current} / 制限 {max}"
|
||||
|
@ -3082,3 +3125,46 @@ _search:
|
|||
pleaseEnterServerHost: "サーバーのホストを入力してください"
|
||||
pleaseSelectUser: "ユーザーを選択してください"
|
||||
serverHostPlaceholder: "例: misskey.example.com"
|
||||
|
||||
_serverSetupWizard:
|
||||
installCompleted: "Misskeyのインストールが完了しました!"
|
||||
firstCreateAccount: "まずは、管理者アカウントを作成しましょう。"
|
||||
accountCreated: "管理者アカウントが作成されました!"
|
||||
serverSetting: "サーバーの設定"
|
||||
youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "このウィザードで簡単に最適なサーバーの設定が行えます。"
|
||||
settingsYouMakeHereCanBeChangedLater: "ここでの設定は、あとからでも変更できます。"
|
||||
howWillYouUseMisskey: "Misskeyをどのように使いますか?"
|
||||
_use:
|
||||
single: "お一人様サーバー"
|
||||
single_description: "自分専用のサーバーとして、一人で使う"
|
||||
single_youCanCreateMultipleAccounts: "お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。"
|
||||
group: "グループサーバー"
|
||||
group_description: "信頼できる他の利用者を招待して、複数人で使う"
|
||||
open: "オープンサーバー"
|
||||
open_description: "不特定多数の利用者を受け入れる運営を行う"
|
||||
openServerAdvice: "不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。"
|
||||
openServerAntiSpamAdvice: "自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。"
|
||||
howManyUsersDoYouExpect: "どれくらいの人数を想定していますか?"
|
||||
_scale:
|
||||
small: "100人以下 (小規模)"
|
||||
medium: "100人以上1000人以下 (中規模)"
|
||||
large: "1000人以上 (大規模)"
|
||||
largeScaleServerAdvice: "大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。"
|
||||
doYouConnectToFediverse: "Fediverseと接続しますか?"
|
||||
doYouConnectToFediverse_description1: "分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。"
|
||||
doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれます。"
|
||||
youCanConfigureMoreFederationSettingsLater: "連合可能なサーバーの指定など、高度な設定も後ほど可能です。"
|
||||
adminInfo: "管理者情報"
|
||||
adminInfo_description: "問い合わせを受け付けるために使用される管理者情報を設定します。"
|
||||
adminInfo_mustBeFilled: "オープンサーバー、または連合がオンの場合は必ず入力が必要です。"
|
||||
followingSettingsAreRecommended: "以下の設定が推奨されます"
|
||||
applyTheseSettings: "この設定を適用"
|
||||
skipSettings: "設定をスキップ"
|
||||
settingsCompleted: "設定が完了しました!"
|
||||
settingsCompleted_description: "お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。"
|
||||
settingsCompleted_description2: "詳細なサーバー設定は、「コントロールパネル」から行えます。"
|
||||
donationRequest: "寄付のお願い"
|
||||
_donationRequest:
|
||||
text1: "Misskeyは有志によって開発されている無料のソフトウェアです。"
|
||||
text2: "今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。"
|
||||
text3: "支援者向け特典もあります!"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "ユーザーはおらん"
|
|||
editProfile: "プロフィールをいじる"
|
||||
noteDeleteConfirm: "このノートをほかしてええか?"
|
||||
pinLimitExceeded: "これ以上ピン留めできひん"
|
||||
intro: "Misskeyのインストールが完了したで!管理者アカウントを作ってや。"
|
||||
done: "でけた"
|
||||
processing: "処理しとる"
|
||||
preview: "プレビュー"
|
||||
|
@ -781,7 +780,6 @@ thisIsExperimentalFeature: "これは実験的な機能やから、仕様が変
|
|||
developer: "開発者やで"
|
||||
makeExplorable: "アカウントを見つけやすくするで"
|
||||
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らんくなるで。"
|
||||
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示するで"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "真ん中"
|
||||
|
@ -1233,7 +1231,6 @@ showAvatarDecorations: "アイコンのデコレーション映す"
|
|||
releaseToRefresh: "離したらリロード"
|
||||
refreshing: "リロードしとる"
|
||||
pullDownToRefresh: "引っ張ってリロードするで"
|
||||
disableStreamingTimeline: "タイムラインのリアルタイム更新をやめるで"
|
||||
useGroupedNotifications: "通知をグループ分けして出すで"
|
||||
signupPendingError: "メアド確認してたらなんか変なことなったわ。リンクの期限切れてるかもしれん。"
|
||||
cwNotationRequired: "「内容を隠す」んやったら注釈書かなアカンで。"
|
||||
|
@ -2007,7 +2004,6 @@ _theme:
|
|||
header: "ヘッダー"
|
||||
navBg: "サイドバーの背景"
|
||||
navFg: "サイドバーの文字"
|
||||
navHoverFg: "サイドバー文字(ホバー)"
|
||||
navActive: "サイドバー文字(アクティブ)"
|
||||
navIndicator: "サイドバーのインジケーター"
|
||||
link: "リンク"
|
||||
|
@ -2030,11 +2026,8 @@ _theme:
|
|||
buttonHoverBg: "ボタンの背景 (ホバー)"
|
||||
inputBorder: "入力ボックスの縁取り"
|
||||
driveFolderBg: "ドライブフォルダーの背景"
|
||||
wallpaperOverlay: "壁紙のオーバーレイ"
|
||||
badge: "バッジ"
|
||||
messageBg: "チャットの背景"
|
||||
accentDarken: "アクセント (暗め)"
|
||||
accentLighten: "アクセント (明るめ)"
|
||||
fgHighlighted: "強調されとる文字"
|
||||
_sfx:
|
||||
note: "ノート"
|
||||
|
|
|
@ -224,7 +224,6 @@ noUsers: "사용자가 어ᇝ십니다"
|
|||
editProfile: "프로필 적기"
|
||||
noteDeleteConfirm: "요 노트럴 뭉캡니꺼?"
|
||||
pinLimitExceeded: "더 몬 붙입니다"
|
||||
intro: "Misskey럴 다 깔앗십니다! 간리자 게정얼 맨걸어 보입시다."
|
||||
done: "햇어예"
|
||||
processing: "처리하고 잇어예"
|
||||
preview: "미리보기"
|
||||
|
@ -747,6 +746,7 @@ _theme:
|
|||
description: "설멩"
|
||||
keys:
|
||||
mention: "멘션"
|
||||
renote: "리노트"
|
||||
_sfx:
|
||||
note: "새 노트"
|
||||
notification: "알림"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,7 @@ introMisskey: "Welkom! Misskey is een open source, gedecentraliseerde microblogd
|
|||
poweredByMisskeyDescription: "{name} is één van de services die door het open source platform <b>Misskey</b> wordt geleverd (het wordt ook wel een \"Misskey server genmoemd\")."
|
||||
monthAndDay: "{day} {month}"
|
||||
search: "Zoeken"
|
||||
reset: "Herstellen"
|
||||
notifications: "Meldingen"
|
||||
username: "Gebruikersnaam"
|
||||
password: "Wachtwoord"
|
||||
|
@ -48,6 +49,7 @@ pin: "Vastmaken aan profielpagina"
|
|||
unpin: "Losmaken van profielpagina"
|
||||
copyContent: "Kopiëren inhoud"
|
||||
copyLink: "Kopiëren link"
|
||||
copyRemoteLink: "Remote-link kopiëren"
|
||||
copyLinkRenote: ""
|
||||
delete: "Verwijderen"
|
||||
deleteAndEdit: "Verwijderen en bewerken"
|
||||
|
@ -63,6 +65,7 @@ copyFileId: "Kopieer veld ID"
|
|||
copyFolderId: "Kopieer folder ID"
|
||||
copyProfileUrl: "Kopieer profiel URL"
|
||||
searchUser: "Zoeken een gebruiker"
|
||||
searchThisUsersNotes: "Notities van deze gebruiker doorzoeken"
|
||||
reply: "Antwoord"
|
||||
loadMore: "Laad meer"
|
||||
showMore: "Toon meer"
|
||||
|
@ -115,6 +118,8 @@ renotedToX: "Renoted naar {name}"
|
|||
cantRenote: "Dit bericht kan niet worden herdeeld"
|
||||
cantReRenote: "Een herdeling kan niet worden herdeeld"
|
||||
quote: "Quote"
|
||||
inChannelRenote: "Alleen-kanaal Renote"
|
||||
inChannelQuote: "Alleen-kanaal Citaat"
|
||||
renoteToChannel: "Renote naar kanaal"
|
||||
renoteToOtherChannel: "Renote naar ander kanaal"
|
||||
pinnedNote: "Vastgemaakte notitie"
|
||||
|
@ -129,14 +134,19 @@ emojiPicker: "Emoji kiezer"
|
|||
pinnedEmojisForReactionSettingDescription: "Kies de emojis die als eerste getoond worden tijdens het reageren"
|
||||
pinnedEmojisSettingDescription: "Kies de emojis die als eerste getoond worden tijdens het reageren"
|
||||
emojiPickerDisplay: "Emoji kiezer weergave"
|
||||
overwriteFromPinnedEmojisForReaction: "Overschrijven met reactieinstellingen"
|
||||
overwriteFromPinnedEmojis: "Overschrijven met algemene instellingen"
|
||||
reactionSettingDescription2: "Sleep om opnieuw te ordenen, Klik om te verwijderen, Druk op \"+\" om toe te voegen"
|
||||
rememberNoteVisibility: "Vergeet niet de notitie zichtbaarheidsinstellingen"
|
||||
attachCancel: "Verwijder bijlage"
|
||||
deleteFile: "Bestand verwijderen"
|
||||
markAsSensitive: "Markeren als NSFW"
|
||||
unmarkAsSensitive: "Geen NSFW"
|
||||
enterFileName: "Invoeren bestandsnaam"
|
||||
mute: "Dempen"
|
||||
unmute: "Stop dempen"
|
||||
renoteMute: "Renotes dempen"
|
||||
renoteUnmute: "Dempen Renotes opheffen"
|
||||
block: "Blokkeren"
|
||||
unblock: "Deblokkeren"
|
||||
suspend: "Opschorten"
|
||||
|
@ -146,7 +156,11 @@ unblockConfirm: "Ben je zeker dat je deze account wil blokkeren?"
|
|||
suspendConfirm: "Ben je zeker dat je deze account wil suspenderen?"
|
||||
unsuspendConfirm: "Ben je zeker dat je deze account wil opnieuw aanstellen?"
|
||||
selectList: "Kies een lijst."
|
||||
editList: "Lijst bewerken"
|
||||
selectChannel: "Kanaal selecteren"
|
||||
selectAntenna: "Kies een antenne"
|
||||
editAntenna: "Antenne bewerken"
|
||||
createAntenna: "Antenne aanmaken"
|
||||
selectWidget: "Kies een widget"
|
||||
editWidgets: "Bewerk widgets"
|
||||
editWidgetsExit: "Klaar"
|
||||
|
@ -158,6 +172,10 @@ emojiUrl: "URL emoji"
|
|||
addEmoji: "Toevoegen emoji"
|
||||
settingGuide: "Aanbevolen instellingen"
|
||||
cacheRemoteFiles: "Externe bestanden cachen"
|
||||
cacheRemoteFilesDescription: "Als deze instelling uitgeschakeld is worden bestanden altijd direct van remote servers geladen. Hiermee wordt opslagruimte bespaard, maar doordat er geen thumbnails worden gegenereerd, zal netwerkverkeer toenemen."
|
||||
youCanCleanRemoteFilesCache: "Klik op de 🗑️ knop in de bestandsbeheerweergave om de cache te wissen."
|
||||
cacheRemoteSensitiveFiles: "Gevoelige bestanden van externe instances in de cache bewaren"
|
||||
cacheRemoteSensitiveFilesDescription: "Als deze instelling is uitgeschakeld, worden gevoelige bestanden op afstand direct vanuit de instantie op afstand geladen zonder caching."
|
||||
flagAsBot: "Markeer dit account als een robot."
|
||||
flagAsBotDescription: "Als dit account van een programma wordt beheerd, zet deze vlag aan. Het aanzetten helpt andere ontwikkelaars om bijvoorbeeld onbedoelde feedback loops te doorbreken of om Misskey meer geschikt te maken."
|
||||
flagAsCat: "Markeer dit account als een kat."
|
||||
|
@ -166,8 +184,13 @@ flagShowTimelineReplies: "Toon antwoorden op de tijdlijn."
|
|||
flagShowTimelineRepliesDescription: "Als je dit vlag aanzet, toont de tijdlijn ook antwoorden op andere en niet alleen jouw eigen notities."
|
||||
autoAcceptFollowed: "Accepteer verzoeken om jezelf te volgen vanzelf als je de verzoeker al volgt."
|
||||
addAccount: "Account toevoegen"
|
||||
reloadAccountsList: "Accountlijst opnieuw laden"
|
||||
loginFailed: "Aanmelding mislukt."
|
||||
showOnRemote: "Toon op de externe instantie."
|
||||
continueOnRemote: "Verder op remote server"
|
||||
chooseServerOnMisskeyHub: "Kies een server van de Misskey Hub"
|
||||
specifyServerHost: "Serverhost uitkiezen"
|
||||
inputHostName: "Domein invullen"
|
||||
general: "Algemeen"
|
||||
wallpaper: "Achtergrond"
|
||||
setWallpaper: "Achtergrond instellen"
|
||||
|
@ -178,6 +201,7 @@ followConfirm: "Weet je zeker dat je {name} wilt volgen?"
|
|||
proxyAccount: "Proxy account"
|
||||
proxyAccountDescription: "Een proxy-account is een account dat onder bepaalde voorwaarden fungeert als externe volger voor gebruikers. Als een gebruiker bijvoorbeeld een externe gebruiker aan de lijst toevoegt, wordt de activiteit van de externe gebruiker niet aan de server geleverd als geen lokale gebruiker die gebruiker volgt, dus het proxy-account volgt in plaats daarvan."
|
||||
host: "Server"
|
||||
selectSelf: "Mezelf kiezen"
|
||||
selectUser: "Kies een gebruiker"
|
||||
recipient: "Ontvanger"
|
||||
annotation: "Reacties"
|
||||
|
@ -192,6 +216,8 @@ perHour: "Per uur"
|
|||
perDay: "Per dag"
|
||||
stopActivityDelivery: "Stop met versturen activiteiten"
|
||||
blockThisInstance: "Blokkeer deze server"
|
||||
silenceThisInstance: "Instantie dempen"
|
||||
mediaSilenceThisInstance: "Media van deze server dempen"
|
||||
operations: "Verwerkingen"
|
||||
software: "Software"
|
||||
version: "Versie"
|
||||
|
@ -211,6 +237,12 @@ clearCachedFiles: "Cache opschonen"
|
|||
clearCachedFilesConfirm: "Weet je zeker dat je alle externe bestanden in de cache wilt verwijderen?"
|
||||
blockedInstances: "Geblokkeerde servers"
|
||||
blockedInstancesDescription: "Maak een lijst van de servers die moeten worden geblokkeerd, gescheiden door regeleinden. Geblokkeerde servers kunnen niet meer communiceren met deze server."
|
||||
silencedInstances: "Gedempte instanties"
|
||||
silencedInstancesDescription: "Geef de hostnamen van de servers die je wil dempen op, elk op hun eigen regel. Alle accounts die bij de opgegeven servers horen worden als gedempt behandeld, kunnen alleen maar volgverzoeken maken, en kunnen lokale accounts niet vermelden als ze niet gevolgd worden. Geblokkeerde servers worden hier niet door beïnvloed."
|
||||
mediaSilencedInstances: "Media-gedempte servers"
|
||||
mediaSilencedInstancesDescription: "Geef de hostnamen van de servers die je wil media-dempen op, elk op hun eigen regel. Alle accounts die bij de opgegeven servers horen worden als gedempt behandeld, en kunnen geen eigen emojis gebruiken. Geblokkeerde servers worden hier niet door beïnvloed."
|
||||
federationAllowedHosts: "Servers die mogen federeren "
|
||||
federationAllowedHostsDescription: "Geef de hostnamen van de servers die mogen federeren op, elk op hun eigen regel."
|
||||
muteAndBlock: "Gedempt en geblokkeerd"
|
||||
mutedUsers: "Gedempte gebruikers"
|
||||
blockedUsers: "Geblokkeerde gebruikers"
|
||||
|
@ -218,7 +250,6 @@ noUsers: "Er zijn geen gebruikers."
|
|||
editProfile: "Bewerk Profiel"
|
||||
noteDeleteConfirm: "Ben je zeker dat je dit bericht wil verwijderen?"
|
||||
pinLimitExceeded: "Je kunt geen berichten meer vastprikken"
|
||||
intro: "Installatie van Misskey geëindigd! Maak nu een beheerder aan."
|
||||
done: "Klaar"
|
||||
processing: "Bezig met verwerken"
|
||||
preview: "Voorbeeld"
|
||||
|
@ -255,6 +286,7 @@ removed: "Succesvol verwijderd"
|
|||
removeAreYouSure: "Weet je zeker dat je \"{x}\" wil verwijderen?"
|
||||
deleteAreYouSure: "Weet je zeker dat je \"{x}\" wil verwijderen?"
|
||||
resetAreYouSure: "Resetten?"
|
||||
areYouSure: "Weet je het zeker?"
|
||||
saved: "Opgeslagen"
|
||||
upload: "Uploaden"
|
||||
keepOriginalUploading: "Origineel beeld behouden."
|
||||
|
@ -268,8 +300,13 @@ uploadFromUrlMayTakeTime: "Het kan even duren voordat het uploaden voltooid is."
|
|||
explore: "Verkennen"
|
||||
messageRead: "Lezen"
|
||||
noMoreHistory: "Er is geen verdere geschiedenis"
|
||||
startChat: "Chat starten"
|
||||
nUsersRead: "gelezen door {n}"
|
||||
agreeTo: "Ik stem in met {0}"
|
||||
agree: "Akkoord"
|
||||
agreeBelow: "Ik ga akkoord met de volgende"
|
||||
basicNotesBeforeCreateAccount: "Belangrijke informatie"
|
||||
termsOfService: "Gebruiksvoorwaarden"
|
||||
start: "Aan de slag"
|
||||
home: "Startpagina"
|
||||
remoteUserCaution: "Aangezien deze gebruiker van een externe server afkomstig is, kan de weergegeven informatie onvolledig zijn."
|
||||
|
@ -294,12 +331,15 @@ selectFile: "Kies een bestand"
|
|||
selectFiles: "Selecteer bestanden"
|
||||
selectFolder: "Kies een map"
|
||||
selectFolders: "Kies mappen"
|
||||
fileNotSelected: "Geen bestand geselecteerd"
|
||||
renameFile: "Wijzig bestandsnaam"
|
||||
folderName: "Mapnaam"
|
||||
createFolder: "Map aanmaken"
|
||||
renameFolder: "Map hernoemen"
|
||||
deleteFolder: "Map verwijderen"
|
||||
folder: "Map"
|
||||
addFile: "Bestand toevoegen"
|
||||
showFile: "Bestanden weergeven"
|
||||
emptyDrive: "Jouw Drive is leeg."
|
||||
emptyFolder: "Deze map is leeg"
|
||||
unableToDelete: "Kan niet worden verwijderd"
|
||||
|
@ -312,6 +352,7 @@ copyUrl: "URL kopiëren"
|
|||
rename: "Hernoemen"
|
||||
avatar: "Avatar"
|
||||
banner: "Banner"
|
||||
displayOfSensitiveMedia: "Weergave van gevoelige media"
|
||||
whenServerDisconnected: "Wanneer de verbinding met de server wordt onderbroken"
|
||||
disconnectedFromServer: "Verbinding met de server onderbroken."
|
||||
reload: "Verversen"
|
||||
|
@ -349,14 +390,20 @@ bannerUrl: "Banner URL"
|
|||
backgroundImageUrl: "URL afbeelding"
|
||||
basicInfo: "Basisinformatie"
|
||||
pinnedUsers: "Vastgeprikte gebruikers"
|
||||
pinnedUsersDescription: "Een lijst met gebruikersnamen, gescheiden door regeleinden, die moet worden vastgemaakt in het tabblad “Verkennen”"
|
||||
pinnedPages: "Vastgeprikte pagina's"
|
||||
pinnedPagesDescription: "Voer de paden in van de Pagina's die je aan de bovenste pagina van deze instantie wilt vastmaken, gescheiden door regeleinden."
|
||||
pinnedClipId: "ID van de clip die moet worden vastgepind"
|
||||
pinnedNotes: "Vastgemaakte notitie"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Inschakelen hCaptcha"
|
||||
hcaptchaSiteKey: "Site sleutel"
|
||||
hcaptchaSecretKey: "Geheime sleutel"
|
||||
mcaptcha: "mCaptcha"
|
||||
enableMcaptcha: "mCaptcha activeren"
|
||||
mcaptchaSiteKey: "Site sleutel"
|
||||
mcaptchaSecretKey: "Geheime sleutel"
|
||||
mcaptchaInstanceUrl: "mCaptcha server-URL"
|
||||
recaptcha: "reCAPTCHA"
|
||||
enableRecaptcha: "Inschakelen reCAPTCHA"
|
||||
recaptchaSiteKey: "Site sleutel"
|
||||
|
@ -365,12 +412,21 @@ turnstile: "Tourniquet"
|
|||
enableTurnstile: "Inschakelen tourniquet"
|
||||
turnstileSiteKey: "Site sleutel"
|
||||
turnstileSecretKey: "Geheime sleutel"
|
||||
avoidMultiCaptchaConfirm: "Het gebruik van meerdere Captcha-systemen kan interferentie tussen deze systemen veroorzaken. Wil je de andere Captcha-systemen die momenteel actief zijn uitschakelen? Als je wilt dat ze ingeschakeld blijven, druk dan op annuleren."
|
||||
antennas: "Antennes"
|
||||
manageAntennas: "Antennes beheren"
|
||||
name: "Naam"
|
||||
antennaSource: "Bron antenne"
|
||||
antennaKeywords: "Sleutelwoorden"
|
||||
antennaExcludeKeywords: "Blokkeerwoorden"
|
||||
antennaExcludeBots: "Bot-accounts uitsluiten"
|
||||
antennaKeywordsDescription: "Scheid met spaties voor een EN-voorwaarde of met regeleinden voor een OF-voorwaarde."
|
||||
notifyAntenna: "Houd een notificatie bij nieuwe notities"
|
||||
withFileAntenna: "Alleen notities met bestanden"
|
||||
excludeNotesInSensitiveChannel: "Sluit notities uit van gevoelige kanalen"
|
||||
enableServiceworker: "Activeer pushmeldingen in de browser"
|
||||
antennaUsersDescription: "Lijst één gebruikersnaam per regel"
|
||||
caseSensitive: "Hoofdlettergevoelig"
|
||||
withReplies: "Antwoorden toevoegen"
|
||||
connectedTo: "De volgende accounts zijn verbonden"
|
||||
notesAndReplies: "Berichten en reacties"
|
||||
|
@ -391,18 +447,30 @@ about: "Over"
|
|||
aboutMisskey: "Over Misskey"
|
||||
administrator: "Beheerder"
|
||||
token: "Token"
|
||||
2fa: "Twee factor authenticatie"
|
||||
setupOf2fa: "Tweefactorauthenticatie instellen"
|
||||
totp: "Verificatie-App"
|
||||
totpDescription: "Log in via de verificatie-app met het eenmalige wachtwoord"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderatie"
|
||||
moderationNote: "Moderatienotitie"
|
||||
moderationNoteDescription: "Voer hier notities in. Deze zijn alleen zichtbaar voor de moderators."
|
||||
addModerationNote: "Moderatienotitie toevoegen"
|
||||
moderationLogs: "Moderatieprotocollen"
|
||||
nUsersMentioned: "Vermeld door {n} gebruikers"
|
||||
securityKeyAndPasskey: "Beveiligings- en pasjessleutels"
|
||||
securityKey: "Beveiligingssleutel"
|
||||
lastUsed: "Laatst gebruikt"
|
||||
lastUsedAt: "Laatst gebruikt: {t}"
|
||||
unregister: "Uitschrijven"
|
||||
passwordLessLogin: "Inloggen zonder wachtwoord"
|
||||
passwordLessLoginDescription: "Maakt aanmelden zonder wachtwoord mogelijk met een beveiligingstoken of -wachtsleutel"
|
||||
resetPassword: "Wachtwoord terugzetten"
|
||||
newPasswordIs: "Het nieuwe wachtwoord is „{password}”."
|
||||
reduceUiAnimation: "Verminder beweging in de UI"
|
||||
share: "Delen"
|
||||
notFound: "Niet gevonden"
|
||||
notFoundDescription: "Er is geen pagina gevonden onder deze URL."
|
||||
uploadFolder: "Standaardmap voor uploaden"
|
||||
markAsReadAllNotifications: "Markeer alle meldingen als gelezen"
|
||||
markAsReadAllUnreadNotes: "Markeer alle berichten als gelezen"
|
||||
|
@ -421,7 +489,53 @@ retype: "Opnieuw invoeren"
|
|||
noteOf: "Notitie van {user}"
|
||||
quoteAttached: "Citaat"
|
||||
quoteQuestion: "Toevoegen als citaat?"
|
||||
attachAsFileQuestion: "De tekst op het klembord is te lang. Wilt u het als een tekstbestand bijvoegen?"
|
||||
onlyOneFileCanBeAttached: "Per bericht kan slechts één bestand worden bijgevoegd"
|
||||
signinRequired: "Gelieve te registreren of in te loggen om verder te gaan"
|
||||
signinOrContinueOnRemote: "Ga naar je eigen instantie of registreer je/log in op deze server om door te gaan."
|
||||
invitations: "Uitnodigen"
|
||||
invitationCode: "Uitnodigingscode"
|
||||
checking: "Wordt gecheckt ..."
|
||||
available: "Beschikbaar"
|
||||
unavailable: "Onbeschikbaar"
|
||||
usernameInvalidFormat: "Je kunt kleine letters, hoofdletters, cijfers en onderstrepingstekens gebruiken."
|
||||
tooShort: "Te kort"
|
||||
tooLong: "Te lang"
|
||||
weakPassword: "Zwak wachtwoord"
|
||||
normalPassword: "Redelijke wachtwoord"
|
||||
strongPassword: "Sterk wachtwoord"
|
||||
passwordMatched: "Lucifers"
|
||||
passwordNotMatched: "Komt niet overeen"
|
||||
signinWith: "Aanmelden met {x}"
|
||||
signinFailed: "Inloggen mislukt. Controleer gebruikersnaam en wachtwoord."
|
||||
or: "Of"
|
||||
language: "Taal"
|
||||
uiLanguage: "Taal van gebruikersinterface"
|
||||
aboutX: "Over {x}"
|
||||
emojiStyle: "Emoji-stijl"
|
||||
native: "Inheems"
|
||||
menuStyle: "Menustijl"
|
||||
style: "Stijl"
|
||||
drawer: "Lade"
|
||||
popup: "Pop-up"
|
||||
showNoteActionsOnlyHover: "Toon notitiemenu alleen bij muisaanwijzer"
|
||||
showReactionsCount: "Zie het aantal reacties op notities"
|
||||
noHistory: "Geen geschiedenis gevonden"
|
||||
signinHistory: "Inloggeschiedenis"
|
||||
enableAdvancedMfm: "Uitgebreide MFM activeren"
|
||||
enableAnimatedMfm: "Geanimeerde MFM activeren"
|
||||
doing: "In uitvoering..."
|
||||
category: "Categorie"
|
||||
tags: "Aliassen"
|
||||
docSource: "Broncode van dit document"
|
||||
createAccount: "Gebruikersaccount maken"
|
||||
existingAccount: "Bestaand gebruikersaccount"
|
||||
regenerate: "Regenereer"
|
||||
fontSize: "Lettergrootte"
|
||||
mediaListWithOneImageAppearance: "Hoogte van medialijsten met slechts één afbeelding"
|
||||
limitTo: "Beperken tot {x}"
|
||||
noFollowRequests: "Je hebt geen lopende volgverzoeken"
|
||||
openImageInNewTab: "Afbeeldingen in nieuw tabblad openen"
|
||||
dashboard: "Overzicht"
|
||||
local: "Lokaal"
|
||||
remote: "Remote"
|
||||
|
@ -436,20 +550,395 @@ promote: "Promoot"
|
|||
numberOfDays: "Aantal dagen"
|
||||
hideThisNote: "Verberg deze notitie"
|
||||
showFeaturedNotesInTimeline: "Laat featured notities in tijdlijn zien"
|
||||
objectStorage: "Object Storage"
|
||||
useObjectStorage: "Object Storage gebruiken"
|
||||
objectStorageBaseUrl: "Basis-URL"
|
||||
objectStorageBaseUrlDesc: "De URL die wordt gebruikt als referentie. Als je een CDN of proxy gebruikt, voer dan de URL daarvan in. Gebruik voor S3 ‘https://<bucket>.s3.amazonaws.com’. Gebruik voor GCS of vergelijkbaar ‘https://storage.googleapis.com/<bucket>’."
|
||||
objectStorageBucket: "Bucket"
|
||||
objectStorageBucketDesc: "Geef de bucketnaam op die bij je provider wordt gebruikt."
|
||||
objectStoragePrefix: "Prefix"
|
||||
objectStoragePrefixDesc: "Bestanden worden opgeslagen in de mappen onder deze prefix."
|
||||
objectStorageEndpoint: "Endpoint"
|
||||
objectStorageEndpointDesc: "Laat dit leeg als je AWS S3 gebruikt, anders geef je het eindpunt op als ‘<host>’ of ‘<host>:<port>’, afhankelijk van de service die je gebruikt."
|
||||
objectStorageRegion: "Region"
|
||||
objectStorageRegionDesc: "Voer een regio in zoals “xx-east-1”. Als je provider geen onderscheid maakt tussen regio's, voer dan “us-east-1” in. Laat leeg als je AWS-configuratiebestanden of omgevingsvariabelen gebruikt."
|
||||
objectStorageUseSSL: "SSL gebruiken"
|
||||
objectStorageUseSSLDesc: "Deactiveer dit als u geen HTTPS gebruikt voor API-verbindingen"
|
||||
objectStorageUseProxy: "Verbinden via proxy"
|
||||
objectStorageUseProxyDesc: "Deactiveer dit als u geen proxy wilt gebruiken voor verbindingen met de API"
|
||||
objectStorageSetPublicRead: "Instellen op “public-read” op upload"
|
||||
s3ForcePathStyleDesc: "Als s3ForcePathStyle is geactiveerd, moet de bucketnaam niet worden opgegeven in de hostnaam van de URL, maar in het pad van de URL. Deze optie moet mogelijk worden geactiveerd als services zoals een zelfbediende Minio-instantie worden gebruikt."
|
||||
serverLogs: "Serverprotocollen"
|
||||
deleteAll: "Alles verwijderen"
|
||||
showFixedPostForm: "Het postingformulier bovenaan de tijdbalk weergeven"
|
||||
showFixedPostFormInChannel: "Het postingformulier bovenaan de tijdbalk weergeven (Kanalen)"
|
||||
withRepliesByDefaultForNewlyFollowed: "Toon replies van nieuw gevolgde gebruikers standaard in de tijdlijn"
|
||||
newNoteRecived: "Er zijn nieuwe notities"
|
||||
sounds: "Geluiden"
|
||||
sound: "Geluid"
|
||||
listen: "Luisteren"
|
||||
none: "Niets"
|
||||
showInPage: "Weergeven in een pagina"
|
||||
popout: "Pop-Up"
|
||||
volume: "Volume"
|
||||
masterVolume: "Hoofdvolume"
|
||||
notUseSound: "Geluid uitschakelen"
|
||||
useSoundOnlyWhenActive: "Geluid alleen inschakelen wanneer Misskey actief is"
|
||||
details: "Details"
|
||||
renoteDetails: "Renote Details"
|
||||
chooseEmoji: "Emoji selecteren"
|
||||
unableToProcess: "De operatie kan niet worden voltooid."
|
||||
recentUsed: "Recent gebruikt"
|
||||
install: "Installeren"
|
||||
uninstall: "Deinstalleren"
|
||||
installedApps: "Geautoriseerde toepassingen"
|
||||
nothing: "Niets te zien hier"
|
||||
installedDate: "Geautoriseerd at"
|
||||
lastUsedDate: "Laatst gebruikt at"
|
||||
state: "Status"
|
||||
sort: "Sorteren"
|
||||
ascendingOrder: "Oplopende volgorde"
|
||||
descendingOrder: "Aflopende volgorde"
|
||||
scratchpad: "Testomgeving"
|
||||
scratchpadDescription: "De testomgeving biedt een gebied voor AiScript experimenten. Daar kunt u AiScript schrijven en uitvoeren en de effecten ervan op Misskey controleren."
|
||||
uiInspector: "UI-inspecteur"
|
||||
uiInspectorDescription: "De lijst met servers van UI-componenten kan worden bekeken in de cache. De UI-component wordt gegenereerd door de functie Ui:C:"
|
||||
output: "Uitvoer"
|
||||
script: "Script"
|
||||
disablePagesScript: "AiScript uitschakelen op pagina's"
|
||||
updateRemoteUser: "Gebruikersinformatie bijwerken"
|
||||
unsetUserAvatar: "Avatar verwijderen"
|
||||
unsetUserAvatarConfirm: "Weet je zeker dat je je avatar wil verwijderen?"
|
||||
unsetUserBanner: "Banner verwijderen"
|
||||
unsetUserBannerConfirm: "Weet je zeker dat je je banner wil verwijderen?"
|
||||
deleteAllFiles: "Alle bestanden verwijderen"
|
||||
deleteAllFilesConfirm: "Wil je echt alle bestanden verwijderen?"
|
||||
removeAllFollowing: "Ontvolg alle gevolgde gebruikers"
|
||||
removeAllFollowingDescription: "Door dit uit te voeren worden alle accounts van {host} ontvolgd. Voer dit uit als de instantie bijvoorbeeld niet meer bestaat."
|
||||
userSuspended: "Deze gebruiker is geschorst."
|
||||
userSilenced: "Deze gebruiker is instantiebreed gedempt."
|
||||
yourAccountSuspendedTitle: "Deze account is geschorst"
|
||||
yourAccountSuspendedDescription: "Dit gebruikersaccount is geschorst omdat het de gebruiksvoorwaarden van deze server heeft geschonden. Neem contact op met de operator voor meer informatie. Maak geen nieuwe gebruikersaccount aan."
|
||||
tokenRevoked: "Ongeldig token"
|
||||
tokenRevokedDescription: "Het token is verlopen. Log opnieuw in."
|
||||
accountDeleted: "Het gebruikersaccount is verwijderd"
|
||||
accountDeletedDescription: "Deze account is verwijderd."
|
||||
menu: "Menu"
|
||||
divider: "Scheider"
|
||||
addItem: "Element toevoegen"
|
||||
rearrange: "Sorteren"
|
||||
relays: "Relays"
|
||||
addRelay: "Relay toevoegen"
|
||||
inboxUrl: "Inbox-URL"
|
||||
addedRelays: "Toegevoegd Relays"
|
||||
serviceworkerInfo: "Moet worden geactiveerd voor pushmeldingen."
|
||||
deletedNote: "Verwijderde notitie"
|
||||
invisibleNote: "Privé notitie"
|
||||
enableInfiniteScroll: "Automatisch meer laden"
|
||||
visibility: "Zichtbaarheid"
|
||||
poll: "Peiling"
|
||||
useCw: "Inhoudswaarschuwing gebruiken"
|
||||
enablePlayer: "Videospeler openen"
|
||||
disablePlayer: "Videospeler sluiten"
|
||||
expandTweet: "Notitie uitklappen"
|
||||
themeEditor: "Thema-editor"
|
||||
description: "Beschrijving"
|
||||
describeFile: "Beschrijving toevoegen"
|
||||
enterFileDescription: "Beschrijving invoeren"
|
||||
author: "Auteur"
|
||||
leaveConfirm: "Er zijn niet-opgeslagen wijzigingen. Wil je ze verwijderen?"
|
||||
manage: "Beheer"
|
||||
plugins: "Plugins"
|
||||
preferencesBackups: "Instellingen Back-ups"
|
||||
deck: "Dek"
|
||||
undeck: "Dek verlaten"
|
||||
useBlurEffectForModal: "Vervagingseffect gebruiken voor modals"
|
||||
useFullReactionPicker: "Volledige reaktieselectier gebruiken"
|
||||
width: "Breedte"
|
||||
height: "Hoogte"
|
||||
large: "Groot"
|
||||
medium: "Medium"
|
||||
small: "Klein"
|
||||
generateAccessToken: "Toegangstoken genereren"
|
||||
permission: "Machtigingen"
|
||||
adminPermission: "Administratorrechten"
|
||||
enableAll: "Alle activeren"
|
||||
disableAll: "Alle deactiveren"
|
||||
tokenRequested: "Toegang verlenen tot het gebruikersaccount"
|
||||
pluginTokenRequestedDescription: "Deze plugin kan de hier geconfigureerde autorisaties gebruiken."
|
||||
notificationType: "Type melding"
|
||||
edit: "Bewerken"
|
||||
emailServer: "Email-Server"
|
||||
enableEmail: "Email distributie inschakelen"
|
||||
emailConfigInfo: "Wordt gebruikt om je email te bevestigen tijdens het aanmelden of als je je wachtwoord bent vergeten"
|
||||
email: "Email"
|
||||
emailAddress: "Email adres"
|
||||
smtpConfig: "SMTP-server configuratie"
|
||||
smtpHost: "Server"
|
||||
smtpPort: "Poort"
|
||||
smtpUser: "Gebruikersnaam"
|
||||
smtpPass: "Wachtwoord"
|
||||
emptyToDisableSmtpAuth: "Laat gebruikersnaam en wachtwoord leeg om SMTP-authenticatie uit te schakelen."
|
||||
smtpSecure: "Impliciet SSL/TLS gebruiken voor SMTP-verbindingen"
|
||||
smtpSecureInfo: "Schakel dit uit bij gebruik van STARTTLS"
|
||||
testEmail: "Emailversand testen"
|
||||
wordMute: "Woord dempen"
|
||||
wordMuteDescription: "Minimaliseert notities die het gespecificeerde woord of zin bevatten. Geminimaliseerde notities kunnen worden weergegeven door er op te klikken."
|
||||
hardWordMute: "Harde woorddemping"
|
||||
showMutedWord: "Gedempte woorden weergeven"
|
||||
hardWordMuteDescription: "Verbert notities die het gespecificeerde woord of zin bevatten. In tegenstelling tot woorddemping wordt de notitie volledig verborgen."
|
||||
regexpError: "Fout in reguliere expressie"
|
||||
regexpErrorDescription: "Er is een fout opgetreden in de reguliere expressie op regel {line} van uw {tab} woord dempen:"
|
||||
instanceMute: "Instantie dempers"
|
||||
userSaysSomething: "{name} zei iets"
|
||||
userSaysSomethingAbout: "{name} zei iets over '{word}'"
|
||||
makeActive: "Activeren"
|
||||
display: "Weergave"
|
||||
copy: "Kopiëren"
|
||||
copiedToClipboard: "Naar het klembord gekopieerd"
|
||||
metrics: "Metrieken"
|
||||
overview: "Overzicht"
|
||||
logs: "Protocollen"
|
||||
delayed: "Vertraagd"
|
||||
database: "Database"
|
||||
channel: "Kanalen"
|
||||
create: "Creëer"
|
||||
notificationSetting: "Instellingen meldingen"
|
||||
notificationSettingDesc: "Selecteer het type meldingen dat moet worden weergegeven."
|
||||
useGlobalSetting: "Globale instelling gebruiken"
|
||||
useGlobalSettingDesc: "Als deze optie is ingeschakeld, worden de meldingsinstellingen van je account gebruikt. Als deze optie uitgeschakeld is, kunnen individuele configuraties worden gemaakt."
|
||||
other: "Ander"
|
||||
regenerateLoginToken: "Login token opnieuw genereren"
|
||||
regenerateLoginTokenDescription: "Regenereren van het token dat intern wordt gebruikt om in te loggen. Dit is normaal gezien niet nodig. Alle apparaten worden afgemeld tijdens het regenereren."
|
||||
theKeywordWhenSearchingForCustomEmoji: "Dit is het keyword dat gebruikt wordt bij het zoeken naar eigen emojis."
|
||||
setMultipleBySeparatingWithSpace: "Scheid elementen met een spatie om meerdere instellingen te configureren."
|
||||
fileIdOrUrl: "Bestands-ID of URL"
|
||||
behavior: "Gedrag"
|
||||
sample: "Voorbeeld"
|
||||
abuseReports: "Meldt"
|
||||
reportAbuse: "Meld"
|
||||
reportAbuseRenote: "Meld renote"
|
||||
reportAbuseOf: "Meld {name}"
|
||||
fillAbuseReportDescription: "Vul s.v.p. de details in over deze melding. Geef, als het over een specifieke notitie gaat, ook de URL op."
|
||||
abuseReported: "Uw rapport is verzonden. Hartelijk dank."
|
||||
reporter: "Verslaggever"
|
||||
reporteeOrigin: "Oorsprong van de gemelde persoon"
|
||||
reporterOrigin: "Verslaggever Oorsprong"
|
||||
send: "Stuur"
|
||||
openInNewTab: "In nieuw tabblad openen"
|
||||
openInSideView: "In zijaanzicht openen"
|
||||
defaultNavigationBehaviour: "Standaard navigatie gedrag"
|
||||
editTheseSettingsMayBreakAccount: "Het wijzigen van deze instellingen kan je account beschadigen."
|
||||
instanceTicker: "Instantie-informatie van notities"
|
||||
waitingFor: "Wachten op {x}"
|
||||
random: "Willekeurig"
|
||||
system: "Systeem"
|
||||
switchUi: "UI omschakelen"
|
||||
desktop: "Desktop"
|
||||
clip: "Clip aanmaken"
|
||||
createNew: "Nieuwe aanmaken"
|
||||
optional: "Optioneel"
|
||||
createNewClip: "Nieuwe clip aanmaken"
|
||||
unclip: "Van clip verwijderen"
|
||||
confirmToUnclipAlreadyClippedNote: "Deze notitie is al toegevoegd aan de clip “{name}”. Wil je deze uit deze clip verwijderen?"
|
||||
public: "Openbare"
|
||||
private: "Privé"
|
||||
i18nInfo: "Misskey wordt in veel verschillende talen vertaald door vrijwilligers. Je kunt helpen op {link}"
|
||||
manageAccessTokens: "Toegangstokens beheren"
|
||||
accountInfo: "Informatie over gebruikersaccount"
|
||||
notesCount: "Aantal notities"
|
||||
repliesCount: "Aantal verzonden replies"
|
||||
renotesCount: "Aantal verzonden renotes"
|
||||
repliedCount: "Aantal ontvangen replies"
|
||||
renotedCount: "Aantal ontvangen renotes"
|
||||
followingCount: "Aantal gevolgde accounts"
|
||||
followersCount: "Aantal volgers"
|
||||
sentReactionsCount: "Aantal verzonden reacties"
|
||||
receivedReactionsCount: "Aantal ontvangen reacties"
|
||||
pollVotesCount: "Aantal verzonden peiling stemmen"
|
||||
pollVotedCount: "Aantal ontvangen peiling stemmen"
|
||||
yes: "Ja"
|
||||
no: "Nee"
|
||||
driveFilesCount: "Aantal bestanden in station"
|
||||
driveUsage: "Schijfruimtegebruik"
|
||||
noCrawle: "Crawler-indexering verwerpen"
|
||||
noCrawleDescription: "Vraag zoekmachines om je eigen profielpagina, notities, pagina's, enz. niet te indexeren."
|
||||
lockedAccountInfo: "Tenzij je de zichtbaarheid van je notities instelt op “Alleen volgers”, zijn je notities zichtbaar voor iedereen, zelfs als je vereist dat volgers handmatig worden goedgekeurd."
|
||||
alwaysMarkSensitive: "Markeer media standaard als gevoelig"
|
||||
loadRawImages: "Toon altijd originele afbeeldingen in plaats van miniaturen"
|
||||
disableShowingAnimatedImages: "Speel geen geanimeerde afbeeldingen af"
|
||||
highlightSensitiveMedia: "Markeer gevoelige media"
|
||||
verificationEmailSent: "Er is een bevestigingsmail naar uw e-mailadres verzonden. Ga naar de link in de e-mail om het verificatieproces te voltooien."
|
||||
notSet: "Niet geconfigureerd"
|
||||
emailVerified: "Emailadres bevestigd"
|
||||
noteFavoritesCount: "Aantal notities gemarkeerd als favoriet"
|
||||
pageLikesCount: "Aantal gelikete pagina's"
|
||||
pageLikedCount: "Aantal ontvangen pagina-likes"
|
||||
contact: "Contact"
|
||||
useSystemFont: "Het standaardlettertype van het systeem gebruiken"
|
||||
clips: "Clips"
|
||||
experimentalFeatures: "Experimentele functionaliteiten"
|
||||
experimental: "Experimentele"
|
||||
thisIsExperimentalFeature: "Dit is een experimentele functie. De functionaliteit kan worden gewijzigd en werkt mogelijk niet zoals bedoeld."
|
||||
developer: "Ontwikkelaar"
|
||||
makeExplorable: "Gebruikersaccount zichtbaar maken in “Verkennen”"
|
||||
makeExplorableDescription: "Als deze optie is uitgeschakeld, is uw gebruikersaccount niet zichtbaar in het gedeelte “Verkennen”."
|
||||
duplicate: "Dupliceren"
|
||||
left: "Links"
|
||||
center: "Center"
|
||||
wide: "Breed"
|
||||
narrow: "Smal"
|
||||
reloadToApplySetting: "Deze instelling gaat pas in nadat de pagina herladen is. Nu herladen?"
|
||||
needReloadToApply: "Deze instelling wordt van kracht nadat de pagina is vernieuwd."
|
||||
showTitlebar: "Titelbalk weergeven"
|
||||
clearCache: "Cache opschonen"
|
||||
onlineUsersCount: "{n} Gebruikers zijn online"
|
||||
nUsers: "{n} Gebruikers"
|
||||
nNotes: "{n} Notities"
|
||||
sendErrorReports: "Foutrapporten sturen"
|
||||
sendErrorReportsDescription: "Als u deze optie inschakelt, wordt gedetailleerde foutinformatie met Misskey gedeeld wanneer zich een probleem voordoet. Dit helpt de kwaliteit van Misskey te verbeteren.\nDit omvat informatie zoals de versie van uw OS, welke browser u gebruikt, uw activiteit in Misskey, enz."
|
||||
myTheme: "Mijn thema"
|
||||
backgroundColor: "Achtergrondkleur"
|
||||
accentColor: "Accentkleur"
|
||||
textColor: "Tekstkleur"
|
||||
saveAs: "Opslaan als…"
|
||||
advanced: "Geavanceerd"
|
||||
advancedSettings: "Geavanceerde instellingen"
|
||||
value: "Waarde"
|
||||
createdAt: "Aangemaakt at"
|
||||
updatedAt: "Laatst gewijzigd at"
|
||||
saveConfirm: "Wijzigingen opslaan?"
|
||||
deleteConfirm: "Echt verwijderen?"
|
||||
invalidValue: "Ongeldige waarde."
|
||||
registry: "Registry"
|
||||
closeAccount: "Gebruikersaccount sluiten"
|
||||
currentVersion: "Huidige versie"
|
||||
latestVersion: "Nieuwste versie"
|
||||
youAreRunningUpToDateClient: "Je gebruikt de nieuwste versie van je client."
|
||||
newVersionOfClientAvailable: "Er is een nieuwere versie van je client beschikbaar."
|
||||
usageAmount: "Gebruik"
|
||||
capacity: "Capaciteit"
|
||||
inUse: "Gebruikt"
|
||||
editCode: "Code bewerken"
|
||||
apply: "Toepassen"
|
||||
receiveAnnouncementFromInstance: "Meldingen ontvangen van deze instantie"
|
||||
emailNotification: "E-mailmeldingen"
|
||||
publish: "Publiceren"
|
||||
inChannelSearch: "In kanaal zoeken"
|
||||
useReactionPickerForContextMenu: "Open reactieselectie door rechts te klikken"
|
||||
typingUsers: "{users} is/zijn aan het schrijven..."
|
||||
jumpToSpecifiedDate: "Naar een specifieke datum springen"
|
||||
showingPastTimeline: "Momenteel wordt een oude tijdlijn weergeven"
|
||||
clear: "Terugkeren"
|
||||
markAllAsRead: "Alles als gelezen markeren"
|
||||
goBack: "Terug"
|
||||
unlikeConfirm: "Wil je echt je like verwijderen?"
|
||||
fullView: "Volledig zicht"
|
||||
quitFullView: "Volledig zicht verlaten"
|
||||
addDescription: "Beschrijving toevoegen"
|
||||
userPagePinTip: "Je kunt hier notities tonen door “Vastmaken aan profiel” te selecteren in het menu van de individuele notities."
|
||||
notSpecifiedMentionWarning: "Deze notitie bevat verwijzingen naar gebruikers die niet zijn geselecteerd als ontvangers"
|
||||
info: "Over"
|
||||
userInfo: "Gebruikersinformatie"
|
||||
unknown: "Onbekend"
|
||||
onlineStatus: "Online status"
|
||||
hideOnlineStatus: "Online status verbergen"
|
||||
hideOnlineStatusDescription: "Het verbergen van je online status vermindert het nut van functies zoals zoeken."
|
||||
online: "Online"
|
||||
active: "Actief"
|
||||
offline: "Offline"
|
||||
notRecommended: "Niet aanbevolen"
|
||||
botProtection: "Beveiliging tegen bots"
|
||||
instanceBlocking: "Geblokkeerde/gedempte Instanties"
|
||||
selectAccount: "Gebruikersaccount selecteren"
|
||||
switchAccount: "Account wisselen"
|
||||
enabled: "Ingeschakeld"
|
||||
disabled: "Uitgeschakeld"
|
||||
quickAction: "Snelle acties"
|
||||
user: "Gebruikers"
|
||||
administration: "Beheer"
|
||||
accounts: "Gebruikersaccounts"
|
||||
switch: "Wissel"
|
||||
noMaintainerInformationWarning: "Operatorinformatie is niet geconfigureerd."
|
||||
noInquiryUrlWarning: "Contact-URL niet opgegeven"
|
||||
noBotProtectionWarning: "Bescherming tegen bots is niet geconfigureerd."
|
||||
configure: "Configureer"
|
||||
postToGallery: "Nieuw galerijbericht maken"
|
||||
postToHashtag: "Post naar deze hashtag"
|
||||
gallery: "Galerij"
|
||||
recentPosts: "Recente berichten"
|
||||
popularPosts: "Populair berichten"
|
||||
shareWithNote: "Delen met notitie"
|
||||
ads: "Advertenties"
|
||||
expiration: "Deadline"
|
||||
startingperiod: "Start"
|
||||
memo: "Memo"
|
||||
priority: "Prioriteit"
|
||||
high: "Hoge"
|
||||
middle: "Medium"
|
||||
low: "Lage"
|
||||
emailNotConfiguredWarning: "E-mailadres niet ingesteld."
|
||||
ratio: "Verhouding"
|
||||
previewNoteText: "Show voorproefje"
|
||||
customCss: "Aangepaste CSS"
|
||||
customCssWarn: "Gebruik deze instelling alleen als je weet wat het doet. Ongeldige invoer kan ertoe leiden dat de client niet meer normaal functioneert."
|
||||
global: "Globaal"
|
||||
squareAvatars: "Toon profielfoto's as vierkant"
|
||||
sent: "Verzonden"
|
||||
received: "Ontvangen"
|
||||
searchResult: "Zoekresultaten"
|
||||
hashtags: "Hashtags"
|
||||
troubleshooting: "Probleemoplossing"
|
||||
useBlurEffect: "Vervagingseffecten in de UI gebruike"
|
||||
learnMore: "Meer leren"
|
||||
misskeyUpdated: "Misskey is bijgewerkt!"
|
||||
whatIsNew: "Wijzigingen tonen"
|
||||
translate: "Vertalen"
|
||||
translatedFrom: "Vertaald uit {x}"
|
||||
accountDeletionInProgress: "De verwijdering van je gebruikersaccount wordt momenteel verwerkt."
|
||||
usernameInfo: "Een naam die kan worden gebruikt om je gebruikersaccount op deze server te identificeren. Je kunt het alfabet (a~z, A~Z), cijfers (0~9) of underscores (_) gebruiken. Gebruikersnamen kunnen later niet worden gewijzigd."
|
||||
aiChanMode: "Ai Mode"
|
||||
devMode: "Ontwikkelaar modus"
|
||||
keepCw: "Inhoudswaarschuwingen behouden"
|
||||
pubSub: "Pub/Sub Gebruikersaccounts"
|
||||
lastCommunication: "Laatste communicatie"
|
||||
resolved: "Opgelost"
|
||||
unresolved: "Onopgelost"
|
||||
breakFollow: "Volger verwijderen"
|
||||
breakFollowConfirm: "Deze volger echt weghalen?"
|
||||
itsOn: "Ingeschakeld"
|
||||
itsOff: "Uitgeschakeld"
|
||||
on: "Op"
|
||||
off: "Uit"
|
||||
emailRequiredForSignup: "Vereist e-mailadres voor aanmelding"
|
||||
unread: "Ongelezen"
|
||||
filter: "Filter"
|
||||
controlPanel: "Controlepaneel"
|
||||
manageAccounts: "Gebruikersaccounts beheren"
|
||||
makeReactionsPublic: "Reactiegeschiedenis publiceren"
|
||||
makeReactionsPublicDescription: "Hierdoor wordt de lijst met al je eerdere reacties openbaar."
|
||||
classic: "Classic"
|
||||
muteThread: "Discussies dempen "
|
||||
unmuteThread: "Dempen van discussie ongedaan maken"
|
||||
followingVisibility: "Zichtbaarheid van gevolgden"
|
||||
followersVisibility: "Zichtbaarheid van volgers"
|
||||
continueThread: "Bekijk draad voortzetting"
|
||||
deleteAccountConfirm: "Je gebruikersaccount wordt onherroepelijk verwijderd. Wil je nog steeds doorgaan?"
|
||||
incorrectPassword: "Onjuist wachtwoord."
|
||||
incorrectTotp: "Het eenmalige wachtwoord is incorrect of verlopen"
|
||||
voteConfirm: "Bevestig je je stem op “{choice}”?"
|
||||
hide: "Verbergen"
|
||||
useDrawerReactionPickerForMobile: "Toon reactiekiezer als lade op mobiel"
|
||||
welcomeBackWithName: "Welkom terug, {name}"
|
||||
clickToFinishEmailVerification: "Druk op [{ok}] om de e-mailbevestiging af te ronden."
|
||||
searchByGoogle: "Zoeken"
|
||||
threeMonths: "3 maanden"
|
||||
oneYear: "1 jaar"
|
||||
threeDays: "3 dagen"
|
||||
cropImage: "Afbeelding bijsnijden"
|
||||
cropImageAsk: "Bijsnijdengevraagd"
|
||||
file: "Bestanden"
|
||||
account: "Gebruikersaccounts"
|
||||
pushNotification: "Pushberichten"
|
||||
subscribePushNotification: "Push meldingen inschakelen"
|
||||
unsubscribePushNotification: "Pushberichten uitschakelen"
|
||||
|
@ -457,25 +946,59 @@ pushNotificationAlreadySubscribed: "Pushberichtrn al ingeschakeld"
|
|||
windowMaximize: "Maximaliseren"
|
||||
windowRestore: "Herstellen"
|
||||
loggedInAsBot: "Momenteel als bot ingelogd"
|
||||
show: "Weergave"
|
||||
correspondingSourceIsAvailable: "De bijbehorende broncode is beschikbaar bij {anchor}"
|
||||
invalidParamErrorDescription: "De aanvraagparameters zijn ongeldig. Dit komt meestal door een bug, maar kan ook omdat de invoer te lang is of iets dergelijks."
|
||||
collapseRenotes: "Renotes die je al gezien hebt, inklappen"
|
||||
collapseRenotesDescription: "Klapt notities in waar je al op gereageerd hebt of die je al gerenotet hebt."
|
||||
prohibitedWords: "Verboden woorden"
|
||||
prohibitedWordsDescription: "Activeert een foutmelding als er geprobeerd wordt een notitie met de ingestelde woorden te plaatsen. Meerdere woorden kunnen worden ingesteld, elk op hun eigen regel."
|
||||
hiddenTags: "Verborgen hashtags"
|
||||
hiddenTagsDescription: "Selecteer tags die niet worden weergegeven in de trends. Meerdere tags kunnen worden geregistreerd, elk op hun eigen regel."
|
||||
enableStatsForFederatedInstances: "Statistieken van remote servers ontvangen"
|
||||
limitWidthOfReaction: "Limiteert de maximale breedte van reacties en geef ze verkleind weer"
|
||||
audio: "Audio"
|
||||
audioFiles: "Audio"
|
||||
archived: "Gearchiveerd"
|
||||
unarchive: "Dearchiveren"
|
||||
lookupConfirm: "Weet je zeker dat je dit wil opzoeken?"
|
||||
openTagPageConfirm: "Wil je deze hashtagpagina openen?"
|
||||
specifyHost: "Specificeer host"
|
||||
icon: "Avatar"
|
||||
replies: "Antwoord"
|
||||
replies: "Antwoorden"
|
||||
renotes: "Herdelen"
|
||||
followingOrFollower: "Gevolgd of volger"
|
||||
confirmShowRepliesAll: "Dit is een onomkeerbare operatie. Weet je zeker dat reacties op anderen van iedereen die je volgt, wil weergeven in je tijdlijn?"
|
||||
information: "Over"
|
||||
_chat:
|
||||
invitations: "Uitnodigen"
|
||||
noHistory: "Geen geschiedenis gevonden"
|
||||
members: "Leden"
|
||||
home: "Startpagina"
|
||||
send: "Stuur"
|
||||
_delivery:
|
||||
stop: "Opgeschort"
|
||||
_type:
|
||||
none: "Publiceren"
|
||||
_role:
|
||||
priority: "Prioriteit"
|
||||
_priority:
|
||||
low: "Lage"
|
||||
middle: "Medium"
|
||||
high: "Hoge"
|
||||
_ffVisibility:
|
||||
public: "Publiceren"
|
||||
_ad:
|
||||
back: "Terug"
|
||||
_email:
|
||||
_follow:
|
||||
title: "volgde jou"
|
||||
_theme:
|
||||
description: "Beschrijving"
|
||||
keys:
|
||||
mention: "Vermelding"
|
||||
renote: "Herdelen"
|
||||
divider: "Scheider"
|
||||
_sfx:
|
||||
note: "Notities"
|
||||
notification: "Meldingen"
|
||||
|
@ -500,6 +1023,7 @@ _profile:
|
|||
name: "Naam"
|
||||
username: "Gebruikersnaam"
|
||||
_exportOrImport:
|
||||
clips: "Clip aanmaken"
|
||||
followingList: "Volgend"
|
||||
muteList: "Dempen"
|
||||
blockingList: "Blokkeren"
|
||||
|
@ -510,6 +1034,9 @@ _charts:
|
|||
federation: "Federatie"
|
||||
_timelines:
|
||||
home: "Startpagina"
|
||||
_play:
|
||||
script: "Script"
|
||||
summary: "Beschrijving"
|
||||
_pages:
|
||||
blocks:
|
||||
image: "Afbeeldingen"
|
||||
|
@ -532,9 +1059,15 @@ _deck:
|
|||
tl: "Tijdlijn"
|
||||
antenna: "Antennes"
|
||||
list: "Lijsten"
|
||||
channel: "Kanalen"
|
||||
mentions: "Vermeldingen"
|
||||
_webhookSettings:
|
||||
name: "Naam"
|
||||
active: "Ingeschakeld"
|
||||
_abuseReport:
|
||||
_notificationRecipient:
|
||||
_recipientType:
|
||||
mail: "Email"
|
||||
_moderationLogTypes:
|
||||
suspend: "Opschorten"
|
||||
resetPassword: "Wachtwoord terugzetten"
|
||||
|
|
|
@ -171,7 +171,6 @@ noUsers: "Det er ingen brukere"
|
|||
editProfile: "Rediger profil"
|
||||
noteDeleteConfirm: "Er du sikker på at du vil slette denne Noten?"
|
||||
pinLimitExceeded: "Du kan ikke feste flere."
|
||||
intro: "Installasjonen av Misskey er ferdig! Vennligst opprett en administratorkonto."
|
||||
done: "Ferdig"
|
||||
default: "Standard"
|
||||
defaultValueIs: "Standard: {value}"
|
||||
|
|
|
@ -230,7 +230,6 @@ noUsers: "Brak użytkowników"
|
|||
editProfile: "Edytuj profil"
|
||||
noteDeleteConfirm: "Czy na pewno chcesz usunąć ten wpis?"
|
||||
pinLimitExceeded: "Nie możesz przypiąć więcej wpisów."
|
||||
intro: "Zakończono instalację Misskey! Utwórz konto administratora."
|
||||
done: "Gotowe"
|
||||
processing: "Przetwarzanie"
|
||||
preview: "Podgląd"
|
||||
|
@ -749,7 +748,6 @@ thisIsExperimentalFeature: "Ta funkcja jest eksperymentalna. Jej funkcjonalnoś
|
|||
developer: "Programista"
|
||||
makeExplorable: "Pokazuj konto na stronie „Eksploruj”"
|
||||
makeExplorableDescription: "Jeżeli wyłączysz tę opcję, Twoje konto nie będzie wyświetlać się w sekcji „Eksploruj”."
|
||||
showGapBetweenNotesInTimeline: "Pokazuj odstęp między wpisami na osi czasu."
|
||||
duplicate: "Duplikuj"
|
||||
left: "Lewo"
|
||||
center: "Wyśsrodkuj"
|
||||
|
@ -1212,7 +1210,6 @@ _theme:
|
|||
header: "Nagłówek"
|
||||
navBg: "Tło paska bocznego"
|
||||
navFg: "Tekst paska bocznego"
|
||||
navHoverFg: "Tekst paska bocznego (zbliżenie)"
|
||||
navActive: "Tekst paska bocznego (aktywny)"
|
||||
navIndicator: "Wskaźnik paska bocznego"
|
||||
link: "Odnośnik"
|
||||
|
@ -1235,11 +1232,8 @@ _theme:
|
|||
buttonHoverBg: "Tło przycisku (po najechaniu)"
|
||||
inputBorder: "Obramowanie pola wejścia"
|
||||
driveFolderBg: "Tło folderu na dysku"
|
||||
wallpaperOverlay: "Nakładka tapety"
|
||||
badge: "Odznaka"
|
||||
messageBg: "Tło czatu"
|
||||
accentDarken: "Akcent (ciemniejszy)"
|
||||
accentLighten: "Akcent (jaśniejszy)"
|
||||
fgHighlighted: "Wyróżniony tekst"
|
||||
_sfx:
|
||||
note: "Wpisy"
|
||||
|
|
|
@ -5,6 +5,7 @@ introMisskey: "Bem-vindo! O Misskey é um serviço de microblog descentralizado
|
|||
poweredByMisskeyDescription: "{name} é uma instância da plataforma de código aberto <b>Misskey</b>."
|
||||
monthAndDay: "{day}/{month}"
|
||||
search: "Pesquisar"
|
||||
reset: "Redefinir"
|
||||
notifications: "Notificações"
|
||||
username: "Nome de usuário"
|
||||
password: "Senha"
|
||||
|
@ -48,6 +49,7 @@ pin: "Fixar no perfil"
|
|||
unpin: "Desafixar do perfil"
|
||||
copyContent: "Copiar conteúdos"
|
||||
copyLink: "Copiar link"
|
||||
copyRemoteLink: "Copiar endereço remoto"
|
||||
copyLinkRenote: "Copiar o link da repostagem"
|
||||
delete: "Excluir"
|
||||
deleteAndEdit: "Excluir e editar"
|
||||
|
@ -248,7 +250,6 @@ noUsers: "Sem usuários"
|
|||
editProfile: "Editar Perfil"
|
||||
noteDeleteConfirm: "Deseja excluir esta nota?"
|
||||
pinLimitExceeded: "Não é possível fixar novas notas"
|
||||
intro: "A instalação do Misskey está completa! Crie uma conta de administrador."
|
||||
done: "Concluído"
|
||||
processing: "Em Progresso"
|
||||
preview: "Pré-visualizar"
|
||||
|
@ -299,6 +300,7 @@ uploadFromUrlMayTakeTime: "Pode levar algum tempo para que o upload seja conclu
|
|||
explore: "Explorar"
|
||||
messageRead: "Lida"
|
||||
noMoreHistory: "Não existe histórico anterior"
|
||||
startChat: "Iniciar conversa"
|
||||
nUsersRead: "{n} pessoas leram"
|
||||
agreeTo: "Eu concordo com {0}"
|
||||
agree: "Concordar"
|
||||
|
@ -421,6 +423,7 @@ antennaExcludeBots: "Ignorar contas de bot"
|
|||
antennaKeywordsDescription: "Se você separá-lo com um espaço, será uma especificação AND, e se você separá-lo com uma quebra de linha, será uma especificação OR."
|
||||
notifyAntenna: "Notificar novas notas"
|
||||
withFileAntenna: "Apenas notas com arquivos anexados"
|
||||
excludeNotesInSensitiveChannel: "Excluir notas de canais sensíveis"
|
||||
enableServiceworker: "Ative as notificações push para o seu navegador"
|
||||
antennaUsersDescription: "Especificar nomes de utilizador separados por quebras de linha"
|
||||
caseSensitive: "Maiúsculas e minúsculas"
|
||||
|
@ -680,14 +683,19 @@ smtpSecure: "Use SSL/TLS implícito para conexões SMTP"
|
|||
smtpSecureInfo: "Desative esta opção ao utilizar STARTTLS."
|
||||
testEmail: "Testar envio de e-mail"
|
||||
wordMute: "Silenciar palavras"
|
||||
wordMuteDescription: "Minimizar notas que contêm a palavra ou frase especificada. Notas minimizadas são exibidas ao clicá-las."
|
||||
hardWordMute: "Silenciar palavras (esconder posts)"
|
||||
showMutedWord: "Exibir palavras silenciadas"
|
||||
hardWordMuteDescription: "Esconder notas que contêm a palavra ou frase especificada. Diferente do silenciamento de palavras, a nota será completamente escondida."
|
||||
regexpError: "Erro na expressão regular"
|
||||
regexpErrorDescription: "Ocorreu um erro na expressão regular na linha {line} da palavra mutada {tab}:"
|
||||
instanceMute: "Instâncias silenciadas"
|
||||
userSaysSomething: "{name} disse algo"
|
||||
userSaysSomethingAbout: "{name} disse algo sobre \"{word}\""
|
||||
makeActive: "Ativar"
|
||||
display: "Visualizar"
|
||||
copy: "Copiar"
|
||||
copiedToClipboard: "Copiado à área de transferência"
|
||||
metrics: "Métricas"
|
||||
overview: "Visão geral"
|
||||
logs: "Logs"
|
||||
|
@ -775,7 +783,6 @@ thisIsExperimentalFeature: "Este é um recurso experimental. As funções podem
|
|||
developer: "Programador"
|
||||
makeExplorable: "Deixe a sua conta encontrável em \"Explorar\"."
|
||||
makeExplorableDescription: "Se você desativá-lo, outros usuários não poderão encontrar a sua conta na aba Descoberta."
|
||||
showGapBetweenNotesInTimeline: "Mostrar um espaço entre as notas na linha de tempo"
|
||||
duplicate: "Duplicar"
|
||||
left: "Esquerda"
|
||||
center: "Centralizar"
|
||||
|
@ -970,6 +977,7 @@ document: "Documentação"
|
|||
numberOfPageCache: "Número de cache de página"
|
||||
numberOfPageCacheDescription: "Aumentar isso melhora a conveniência, mas também resulta em maior carga e uso de memória."
|
||||
logoutConfirm: "Gostaria de encerrar a sessão?"
|
||||
logoutWillClearClientData: "Sair irá remover as configurações do cliente do navegador. Para redefinir as configurações ao entrar, você deve habilitar o backup automático de configurações."
|
||||
lastActiveDate: "Última data de uso"
|
||||
statusbar: "Barra de status"
|
||||
pleaseSelect: "Por favor, selecione."
|
||||
|
@ -1227,7 +1235,6 @@ showAvatarDecorations: "Exibir decorações de avatar"
|
|||
releaseToRefresh: "Solte para atualizar"
|
||||
refreshing: "Atualizando..."
|
||||
pullDownToRefresh: "Puxe para baixo para atualizar"
|
||||
disableStreamingTimeline: "Desabilitar atualizações em tempo real da linha do tempo"
|
||||
useGroupedNotifications: "Agrupar notificações"
|
||||
signupPendingError: "Houve um problema ao verificar o endereço de email. O link pode ter expirado."
|
||||
cwNotationRequired: "Se \"Esconder conteúdo\" está habilitado, uma descrição deve ser adicionada."
|
||||
|
@ -1297,16 +1304,137 @@ lockdown: "Lockdown"
|
|||
pleaseSelectAccount: "Selecione uma conta"
|
||||
availableRoles: "Cargos disponíveis"
|
||||
acknowledgeNotesAndEnable: "Ative após compreender as precauções."
|
||||
federationSpecified: "Esse servidor opera com uma lista branca de federação. Interagir com servidores diferentes daqueles designados pela administração não é permitido."
|
||||
federationDisabled: "Federação está desabilitada nesse servidor. Você não pode interagir com usuários de outros servidores."
|
||||
confirmOnReact: "Confirmar ao reagir"
|
||||
reactAreYouSure: "Você deseja adicionar uma reação \"{emoji}\"?"
|
||||
markAsSensitiveConfirm: "Você deseja definir essa mídia como sensível?"
|
||||
unmarkAsSensitiveConfirm: "Você deseja remover a definição dessa mídia como sensível?"
|
||||
preferences: "Preferências"
|
||||
accessibility: "Acessibilidade"
|
||||
preferencesProfile: "Perfil de preferências"
|
||||
copyPreferenceId: "Copiar ID de preferências"
|
||||
resetToDefaultValue: "Reverter ao padrão"
|
||||
overrideByAccount: "Sobrescrever pela conta"
|
||||
untitled: "Sem título"
|
||||
noName: "Sem nome"
|
||||
skip: "Pular"
|
||||
restore: "Redefinir"
|
||||
syncBetweenDevices: "Sincronizar entre dispositivos"
|
||||
preferenceSyncConflictTitle: "O valor configurado já existe no servidor."
|
||||
preferenceSyncConflictText: "As preferências com a sincronização ativada irão salvar os seus valores no servidor. Porém, já existem valores no servidor. Qual conjunto de valores você deseja sobrescrever?"
|
||||
preferenceSyncConflictChoiceServer: "Valor configurado no servidor"
|
||||
preferenceSyncConflictChoiceDevice: "Valor configurado no dispositivo"
|
||||
preferenceSyncConflictChoiceCancel: "Cancelar a habilitação de sincronização"
|
||||
paste: "Colar"
|
||||
emojiPalette: "Paleta de emojis"
|
||||
postForm: "Campo de postagem"
|
||||
textCount: "Contagem de caracteres"
|
||||
information: "Informações"
|
||||
chat: "Conversas"
|
||||
migrateOldSettings: "Migrar configurações antigas de cliente"
|
||||
migrateOldSettings_description: "Isso deve ser feito automaticamente. Caso o processo de migração tenha falhado, você pode acioná-lo manualmente. As informações atuais de migração serão substituídas."
|
||||
compress: "Comprimir"
|
||||
right: "Direita"
|
||||
bottom: "Inferior"
|
||||
top: "Superior"
|
||||
embed: "Embed"
|
||||
settingsMigrating: "Configurações estão sendo migradas, aguarde... (Você pode migrar manualmente em Configurações→Outros→Migrar configurações antigas de cliente)"
|
||||
readonly: "Ler apenas"
|
||||
goToDeck: "Voltar ao Deck"
|
||||
federationJobs: "Tarefas de Federação"
|
||||
_chat:
|
||||
noMessagesYet: "Ainda não há mensagens"
|
||||
newMessage: "Nova mensagem"
|
||||
individualChat: "Conversa Particular"
|
||||
individualChat_description: "Ter uma conversa particular com outra pessoa."
|
||||
roomChat: "Conversa de Grupo"
|
||||
roomChat_description: "Uma sala de conversas com várias pessoas. Você pode adicionar pessoas que não permitem conversas privadas se elas aceitarem o convite."
|
||||
createRoom: "Criar Sala"
|
||||
inviteUserToChat: "Convide usuários para começar a conversar"
|
||||
yourRooms: "Salas criadas"
|
||||
joiningRooms: "Salas ingressadas"
|
||||
invitations: "Convidar"
|
||||
noInvitations: "Sem convites"
|
||||
history: "Histórico"
|
||||
noHistory: "Ainda não há histórico"
|
||||
noRooms: "Nenhuma sala encontrada"
|
||||
inviteUser: "Convidar Usuários"
|
||||
sentInvitations: "Convites Enviados"
|
||||
join: "Entrar"
|
||||
ignore: "Ignorar"
|
||||
leave: "Deixar sala"
|
||||
members: "Membros"
|
||||
searchMessages: "Pesquisar mensagens"
|
||||
home: "Início"
|
||||
send: "Enviar"
|
||||
newline: "Nova linha"
|
||||
muteThisRoom: "Silenciar sala"
|
||||
deleteRoom: "Excluir sala"
|
||||
chatNotAvailableForThisAccountOrServer: "Conversas não estão habilitadas nesse servidor ou para essa conta."
|
||||
chatIsReadOnlyForThisAccountOrServer: "Conversas são apenas para leitura nesse servidor ou para essa conta. Não é possível escrever novas mensagens ou criar/ingressar novas conversas."
|
||||
chatNotAvailableInOtherAccount: "A função de conversas está desabilitadas para o outro usuário."
|
||||
cannotChatWithTheUser: "Não é possível conversar com esse usuário."
|
||||
cannotChatWithTheUser_description: "Conversas estão indisponíveis ou o outro usuário não as habilitou."
|
||||
chatWithThisUser: "Conversar com usuário"
|
||||
thisUserAllowsChatOnlyFromFollowers: "Esse usuário aceita conversar apenas com seguidores."
|
||||
thisUserAllowsChatOnlyFromFollowing: "Esse usuário aceita conversar apenas com quem segue."
|
||||
thisUserAllowsChatOnlyFromMutualFollowing: "Esse usuário aceita conversar apenas com seguidores mútuos."
|
||||
thisUserNotAllowedChatAnyone: "Esse usuário não aceita conversar com ninguém."
|
||||
chatAllowedUsers: "Com quem permitir conversas"
|
||||
chatAllowedUsers_note: "Você pode conversar com qualquer um com quem tenha iniciado uma conversa independente dessa configuração."
|
||||
_chatAllowedUsers:
|
||||
everyone: "Todos"
|
||||
followers: "Seus seguidores"
|
||||
following: "Quem você segue"
|
||||
mutual: "Seguidores mútuos"
|
||||
none: "Ninguém"
|
||||
_emojiPalette:
|
||||
palettes: "Paleta"
|
||||
enableSyncBetweenDevicesForPalettes: "Sincronizar paleta entre dispositivos"
|
||||
paletteForMain: "Paleta principal"
|
||||
paletteForReaction: "Paleta de reações"
|
||||
_settings:
|
||||
driveBanner: "Você consegue administrar e configurar o drive, conferir o seu uso e configurar as opções de envio de arquivos."
|
||||
pluginBanner: "Você pode ampliar as funções do cliente com plugins. Você pode instalar plugins, configurar e administrar individualmente."
|
||||
notificationsBanner: "Você pode configurar os tipos e intervalo das notificações do servidor, além de notificações push."
|
||||
api: "API"
|
||||
webhook: "Webhook"
|
||||
serviceConnection: "Integração de serviço"
|
||||
serviceConnectionBanner: "Administre e configure tokens de acesso e webhooks para interagir com aplicações e serviços externos."
|
||||
accountData: "Dados da conta"
|
||||
accountDataBanner: "Exportar e importar dados da conta."
|
||||
muteAndBlockBanner: "Você pode configurar meios para esconder conteúdo e restringir ações de certos usuários."
|
||||
accessibilityBanner: "Você pode personalizar o visual e comportamento do cliente, além de configurar modos de otimizar o uso."
|
||||
privacyBanner: "Você pode configurar a privacidade da conta por meio da visibilidade do conteúdo, capacidade de descoberta e aprovação manual de seguidores."
|
||||
securityBanner: "Você pode configurar a segurança da conta em ajustes como senha, meios de entrada, aplicativos de autenticação e chaves de acesso."
|
||||
preferencesBanner: "Você pode configurar o comportamento geral do cliente segundo as suas preferências."
|
||||
appearanceBanner: "Você pode configurar a aparência do cliente e ajustes de tela segundo as suas preferências."
|
||||
soundsBanner: "Você pode configurar a reprodução de sons no cliente."
|
||||
timelineAndNote: "Notas e linha do tempo"
|
||||
makeEveryTextElementsSelectable: "Tornar todos os elementos de texto selecionáveis"
|
||||
makeEveryTextElementsSelectable_description: "Habilitar isso pode reduzir a usabilidade em algumas situações"
|
||||
useStickyIcons: "Fazer ícones acompanharem a rolagem da tela"
|
||||
showNavbarSubButtons: "Mostrar sub-botões na barra de navegação"
|
||||
ifOn: "Quando ligado"
|
||||
ifOff: "Quando desligado"
|
||||
enableSyncThemesBetweenDevices: "Sincronizar temas instalados entre dispositivos"
|
||||
_chat:
|
||||
showSenderName: "Exibir nome de usuário do remetente"
|
||||
sendOnEnter: "Pressionar Enter para enviar"
|
||||
_preferencesProfile:
|
||||
profileName: "Nome do perfil"
|
||||
profileNameDescription: "Defina o nome que identifica esse dispositivo."
|
||||
profileNameDescription2: "Exemplo: \"Computador Principal\", \"Celular\""
|
||||
_preferencesBackup:
|
||||
autoBackup: "Backup automático"
|
||||
restoreFromBackup: "Restaurar backup"
|
||||
noBackupsFoundTitle: "Nenhum backup encontrado"
|
||||
noBackupsFoundDescription: "Nenhum backup automático foi encontrado. Se você salvou um arquivo de backup manualmente, você pode importá-lo e restaurá-lo."
|
||||
selectBackupToRestore: "Selecionar um backup para restaurar"
|
||||
youNeedToNameYourProfileToEnableAutoBackup: "Um nome de perfil deve ser definido para habilitar o backup automático."
|
||||
autoPreferencesBackupIsNotEnabledForThisDevice: "Backup automático de configurações não está habilitado no dispositivo."
|
||||
backupFound: "Backup de configurações encontrado"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "Exigir cadastro para ver o conteúdo"
|
||||
requireSigninToViewContentsDescription1: "Exigir cadastro para ver todas as notas e outro conteúdo que você criou. Isso previne 'crawlers' de coletar os seus dados."
|
||||
|
@ -1317,6 +1445,7 @@ _accountSettings:
|
|||
makeNotesHiddenBefore: "Tornar notas passadas privadas"
|
||||
makeNotesHiddenBeforeDescription: "Com essa função ativada, apenas você poderá ver as notas anteriores à data e hora marcadas. Se isso for desativado, o status de publicação da nota será reestabelecido."
|
||||
mayNotEffectForFederatedNotes: "Notas federadas a servidores remotos podem não ser afetadas."
|
||||
mayNotEffectSomeSituations: "Essas restrições são simplificadas. Elas podem não ser aplicadas em algumas situações, como ao visualizar num servidor remoto ou durante a moderação."
|
||||
notesHavePassedSpecifiedPeriod: "Notas que duraram um tempo específico."
|
||||
notesOlderThanSpecifiedDateAndTime: "Notas antes do tempo específico."
|
||||
_abuseUserReport:
|
||||
|
@ -1762,6 +1891,8 @@ _role:
|
|||
descriptionOfIsExplorable: "Ao ativar, a lista de membros será pública na seção 'Explorar' e a linha do tempo do cargo ficará disponível."
|
||||
displayOrder: "Ordenação"
|
||||
descriptionOfDisplayOrder: "Quanto maior o número, maior a posição de destaque na interface do usuário."
|
||||
preserveAssignmentOnMoveAccount: "Preservar a associação de cargos durante a migração"
|
||||
preserveAssignmentOnMoveAccount_description: "Quando ligado, esse cargo será encaminhado para a conta final quando houver migração de um usuário."
|
||||
canEditMembersByModerator: "Permitir a edição de membros deste cargo por moderadores"
|
||||
descriptionOfCanEditMembersByModerator: "Quando ativado, os moderadores também poderão atribuir/remover usuários deste papel, além dos administradores. Quando desativado, apenas os administradores poderão fazê-lo."
|
||||
priority: "Prioridade"
|
||||
|
@ -1802,6 +1933,7 @@ _role:
|
|||
canImportFollowing: "Permitir importação de usuários seguidos"
|
||||
canImportMuting: "Permitir importação de silenciamentos"
|
||||
canImportUserLists: "Permitir importação de listas"
|
||||
chatAvailability: "Permitir Conversas"
|
||||
_condition:
|
||||
roleAssignedTo: "Atribuído a cargos manuais"
|
||||
isLocal: "Usuário local"
|
||||
|
@ -1965,6 +2097,7 @@ _theme:
|
|||
installed: "{name} foi instalado"
|
||||
installedThemes: "Temas instalados"
|
||||
builtinThemes: "Temas nativos"
|
||||
instanceTheme: "Tema do servidor"
|
||||
alreadyInstalled: "Esse tema já foi instalado"
|
||||
invalid: "O formato desse tema é invalido"
|
||||
make: "Fazer um tema"
|
||||
|
@ -1997,7 +2130,6 @@ _theme:
|
|||
header: "Cabeçalho"
|
||||
navBg: "Plano de fundo da barra lateral"
|
||||
navFg: "Texto da barra lateral"
|
||||
navHoverFg: "Texto da coluna lateral (Selecionado)"
|
||||
navActive: "Texto da coluna lateral (Ativa)"
|
||||
navIndicator: "Indicador da coluna lateral"
|
||||
link: "Link"
|
||||
|
@ -2020,17 +2152,15 @@ _theme:
|
|||
buttonHoverBg: "Plano de fundo de botão (Selecionado)"
|
||||
inputBorder: "Borda de campo digitável"
|
||||
driveFolderBg: "Plano de fundo da pasta no Drive"
|
||||
wallpaperOverlay: "Sobreposição do papel de parede."
|
||||
badge: "Emblema"
|
||||
messageBg: "Plano de fundo do chat"
|
||||
accentDarken: "Cor de destaque (Escurecida)"
|
||||
accentLighten: "Cor de destaque (Esclarecida)"
|
||||
fgHighlighted: "Texto Destacado"
|
||||
_sfx:
|
||||
note: "Posts"
|
||||
noteMy: "Própria nota"
|
||||
notification: "Notificações"
|
||||
reaction: "Ao selecionar uma reação"
|
||||
chatMessage: "Mensagens em Conversas"
|
||||
_soundSettings:
|
||||
driveFile: "Usar um arquivo de áudio do Drive."
|
||||
driveFileWarn: "Selecione um arquivo de áudio do Drive."
|
||||
|
@ -2178,6 +2308,7 @@ _permissions:
|
|||
"read:federation": "Ver dados de federação"
|
||||
"write:report-abuse": "Reportar violação"
|
||||
"write:chat": "Compor ou editar mensagens de chat"
|
||||
"read:chat": "Navegar Conversas"
|
||||
_auth:
|
||||
shareAccessTitle: "Conceder permissões do aplicativo"
|
||||
shareAccess: "Você gostaria de autorizar \"{name}\" para acessar essa conta?"
|
||||
|
@ -2236,6 +2367,7 @@ _widgets:
|
|||
chooseList: "Selecione uma lista"
|
||||
clicker: "Clicker"
|
||||
birthdayFollowings: "Usuários de aniversário hoje"
|
||||
chat: "Conversas"
|
||||
_cw:
|
||||
hide: "Esconder"
|
||||
show: "Carregar mais"
|
||||
|
@ -2426,6 +2558,7 @@ _notification:
|
|||
newNote: "Nova nota"
|
||||
unreadAntennaNote: "Antena {name}"
|
||||
roleAssigned: "Cargo dado"
|
||||
chatRoomInvitationReceived: "Você foi convidado para uma conversa"
|
||||
emptyPushNotificationMessage: "As notificações de alerta foram atualizadas"
|
||||
achievementEarned: "Conquista desbloqueada"
|
||||
testNotification: "Notificação teste"
|
||||
|
@ -2439,6 +2572,8 @@ _notification:
|
|||
flushNotification: "Limpar notificações"
|
||||
exportOfXCompleted: "Exportação de {x} foi concluída"
|
||||
login: "Alguém entrou na conta"
|
||||
createToken: "Uma token de acesso foi criada"
|
||||
createTokenDescription: "Se você não faz ideia, exclua o token de acesso através de \"{text}\"."
|
||||
_types:
|
||||
all: "Todas"
|
||||
note: "Novas notas"
|
||||
|
@ -2452,9 +2587,11 @@ _notification:
|
|||
receiveFollowRequest: "Recebeu pedidos de seguidor"
|
||||
followRequestAccepted: "Aceitou pedidos de seguidor"
|
||||
roleAssigned: "Cargo dado"
|
||||
chatRoomInvitationReceived: "Convite de conversa recebido"
|
||||
achievementEarned: "Conquista desbloqueada"
|
||||
exportCompleted: "A exportação foi concluída"
|
||||
login: "Iniciar sessão"
|
||||
createToken: "Criar token de acesso"
|
||||
test: "Notificação teste"
|
||||
app: "Notificações de aplicativos conectados"
|
||||
_actions:
|
||||
|
@ -2464,6 +2601,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "Sempre mostrar a coluna principal"
|
||||
columnAlign: "Alinhar colunas"
|
||||
columnGap: "Margem entre colunas"
|
||||
deckMenuPosition: "Posição do menu do deck"
|
||||
navbarPosition: "Posição da barra de navegação"
|
||||
addColumn: "Adicionar coluna"
|
||||
newNoteNotificationSettings: "Opções de notificação para novas notas"
|
||||
configureColumn: "Configurar coluna"
|
||||
|
@ -2482,6 +2622,7 @@ _deck:
|
|||
useSimpleUiForNonRootPages: "Usar UI simples para páginas navegadas"
|
||||
usedAsMinWidthWhenFlexible: "A largura mínima será usada para isso quando o \"Ajuste automático da largura\" estiver ativado"
|
||||
flexible: "Ajuste automático da largura"
|
||||
enableSyncBetweenDevicesForProfiles: "Habilitar sincronização das informações do perfil entre dispositivos"
|
||||
_columns:
|
||||
main: "Principal"
|
||||
widgets: "Widgets"
|
||||
|
@ -2493,6 +2634,7 @@ _deck:
|
|||
mentions: "Menções"
|
||||
direct: "Notas diretas"
|
||||
roleTimeline: "Linha do tempo do cargo"
|
||||
chat: "Conversas"
|
||||
_dialog:
|
||||
charactersExceeded: "Você excedeu o limite de caracteres! Atualmente em {current} de {max}."
|
||||
charactersBelow: "Você está abaixo do limite mínimo de caracteres! Atualmente em {current} of {min}."
|
||||
|
@ -2589,6 +2731,8 @@ _moderationLogTypes:
|
|||
deletePage: "Remover página"
|
||||
deleteFlash: "Remover Play"
|
||||
deleteGalleryPost: "Remover a publicação da galeria"
|
||||
deleteChatRoom: "Sala de Conversas Excluída"
|
||||
updateProxyAccountDescription: "Atualizar descrição da conta de proxy"
|
||||
_fileViewer:
|
||||
title: "Detalhes do arquivo"
|
||||
type: "Tipo de arquivo"
|
||||
|
@ -2723,6 +2867,66 @@ _contextMenu:
|
|||
app: "Aplicativo"
|
||||
appWithShift: "Aplicativo com a tecla shift"
|
||||
native: "Nativo"
|
||||
_gridComponent:
|
||||
_error:
|
||||
requiredValue: "Esse valor é necessário"
|
||||
columnTypeNotSupport: "Validação de expressões regulares (RegEx) só é permitida em colunas type:text."
|
||||
patternNotMatch: "Esse valor não se encaixa no padrão de {pattern}"
|
||||
notUnique: "Valor deve ser único"
|
||||
_roleSelectDialog:
|
||||
notSelected: "Não selecionado"
|
||||
_customEmojisManager:
|
||||
_gridCommon:
|
||||
copySelectionRows: "Copiar linhas selecionadas"
|
||||
copySelectionRanges: "Copiar seleção"
|
||||
deleteSelectionRows: "Excluir linhas selecionadas"
|
||||
deleteSelectionRanges: "Excluir valores selecionados"
|
||||
searchSettings: "Opções de busca"
|
||||
searchSettingCaption: "Definir critérios detalhados de busca."
|
||||
searchLimit: "Limite de busca"
|
||||
sortOrder: "Ordem de classificação"
|
||||
registrationLogs: "Histórico de registros"
|
||||
registrationLogsCaption: "Atualizações e remoções de emoji serão gravadas no histórico. Atualizar, remover, mover a uma nova página ou recarregar limpará o histórico"
|
||||
alertEmojisRegisterFailedDescription: "Não foi possível atualizar ou remover emojis. Por favor, confira o histórico de registro para mais detalhes."
|
||||
_logs:
|
||||
showSuccessLogSwitch: "Exibir sucessos no histórico"
|
||||
failureLogNothing: "Não há registro de falhas."
|
||||
logNothing: "Não há registros."
|
||||
_remote:
|
||||
selectionRowDetail: "Detalhes da linha selecionada"
|
||||
importSelectionRows: "Importar linhas selecionadas"
|
||||
importSelectionRangesRows: "Importar linhas no intervalo"
|
||||
importEmojisButton: "Importar Emojis selecionados"
|
||||
confirmImportEmojisTitle: "Importar Emojis"
|
||||
confirmImportEmojisDescription: "Importar {count} Emoji(s) recebidos de um servidor remoto. Por favor, preste atenção na licença do Emoji. Tem certeza que deseja continuar?"
|
||||
_local:
|
||||
tabTitleList: "Emojis registrados"
|
||||
tabTitleRegister: "Registro de Emoji"
|
||||
_list:
|
||||
emojisNothing: "Não há Emojis registrados."
|
||||
markAsDeleteTargetRows: "Marcar linhas selecionadas para remoção"
|
||||
markAsDeleteTargetRanges: "Marcar linhas no intervalo para remoção"
|
||||
alertUpdateEmojisNothingDescription: "Não há Emojis atualizados."
|
||||
alertDeleteEmojisNothingDescription: "Não há Emojis marcados para remoção."
|
||||
confirmMovePage: "Deseja mudar de página?"
|
||||
confirmChangeView: "Deseja mudar de seção?"
|
||||
confirmUpdateEmojisDescription: "Atualizando {count} Emoji(s). Deseja continuar?"
|
||||
confirmDeleteEmojisDescription: "Removendo {count} Emoji(s) marcado(s). Deseja continuar?"
|
||||
confirmResetDescription: "Todas as mudanças serão redefinidas."
|
||||
confirmMovePageDesciption: "Mudanças foram feitas nos Emojis dessa página. Se você sair sem salvar, todas serão descartadas."
|
||||
dialogSelectRoleTitle: "Buscar por cargo que pode usar esse Emoji"
|
||||
_register:
|
||||
uploadSettingTitle: "Configurações de envio"
|
||||
uploadSettingDescription: "Nessa tela, você pode configurar o comportamento ao enviar Emojis."
|
||||
directoryToCategoryLabel: "Transformar as pastas em categorias"
|
||||
directoryToCategoryCaption: "Quando você arrastar um diretório, converter o caminho das pastas no campo \"categoria\"."
|
||||
emojiInputAreaCaption: "Selecione Emojis que você deseja registrar utilizando um dos métodos."
|
||||
emojiInputAreaList1: "Arraste arquivos de imagem ou diretórios dentro desse quadro"
|
||||
emojiInputAreaList2: "Clique nesse link para abrir a seleção de arquivos"
|
||||
emojiInputAreaList3: "Clique nesse link para selecionar do drive"
|
||||
confirmRegisterEmojisDescription: "Registrando os Emojis da lista como novos Emojis personalizados. Deseja continuar? (Para evitar sobrecarga, apenas {count} Emoji(s) podem ser registrados em uma única operação)"
|
||||
confirmClearEmojisDescription: "Descartando edições e limpando Emojis da lista. Deseja continuar?"
|
||||
confirmUploadEmojisDescription: "Enviando {count} arquivo(s) arrastados ao drive. Deseja continuar?"
|
||||
_embedCodeGen:
|
||||
title: "Personalizar código do embed"
|
||||
header: "Exibir cabeçalho"
|
||||
|
@ -2762,7 +2966,36 @@ _remoteLookupErrors:
|
|||
_noSuchObject:
|
||||
title: "Não encontrado"
|
||||
description: "O recurso solicitado não foi encontrado, confira o endereço."
|
||||
_captcha:
|
||||
verify: "Por favor, verifique o CAPTCHA"
|
||||
testSiteKeyMessage: "Você pode conferir a prévia inserindo valores de teste para o site e chaves secretas.\nVeja a página seguinte para mais detalhes."
|
||||
_error:
|
||||
_requestFailed:
|
||||
title: "O pedido do CAPTCHA falhou"
|
||||
text: "Por favor, tente novamente ou verifique as configurações."
|
||||
_verificationFailed:
|
||||
title: "A validação do CAPTCHA falhou"
|
||||
text: "Por favor, verifique se as configurações estão corretas."
|
||||
_unknown:
|
||||
title: "Erro CAPTCHA"
|
||||
text: "Houve um erro inexperado."
|
||||
_bootErrors:
|
||||
title: "Falha ao carregar"
|
||||
serverError: "Se o problema persistir após esperar um momento e recarregar, contate a administração da instância com o seguinte ID de erro."
|
||||
solution: "O seguinte pode resolver o problema."
|
||||
solution1: "Atualize seu navegador e sistema operacional para a última versão."
|
||||
solution2: "Desative o bloqueador de anúncios"
|
||||
solution3: "Limpe o cache do navegador"
|
||||
solution4: "Defina dom.webaudio.enabled como verdadeiro no Navegador Tor"
|
||||
otherOption: "Outras opções"
|
||||
otherOption1: "Excluir ajustes de cliente e cache"
|
||||
otherOption2: "Iniciar o cliente simples"
|
||||
otherOption3: "Iniciar ferramenta de reparo"
|
||||
_search:
|
||||
searchScopeAll: "Todos"
|
||||
searchScopeLocal: "Local"
|
||||
searchScopeServer: "Servidor específico"
|
||||
searchScopeUser: "Usuário específico"
|
||||
pleaseEnterServerHost: "Insira o endereço do servidor"
|
||||
pleaseSelectUser: "Selecione um usuário"
|
||||
serverHostPlaceholder: "Exemplo: misskey.example.com"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,7 @@ introMisskey: "Добро пожаловать! Misskey — это децент
|
|||
poweredByMisskeyDescription: "{name} – сервис на платформе с открытым исходным кодом <b>Misskey</b>, называемый экземпляром Misskey."
|
||||
monthAndDay: "{day}.{month}"
|
||||
search: "Поиск"
|
||||
reset: "Сброс"
|
||||
notifications: "Уведомления"
|
||||
username: "Имя пользователя"
|
||||
password: "Пароль"
|
||||
|
@ -48,6 +49,7 @@ pin: "Закрепить в профиле"
|
|||
unpin: "Открепить от профиля"
|
||||
copyContent: "Скопировать содержимое"
|
||||
copyLink: "Скопировать ссылку"
|
||||
copyRemoteLink: "Скопировать ссылку на репост"
|
||||
copyLinkRenote: "Скопировать ссылку на репост"
|
||||
delete: "Удалить"
|
||||
deleteAndEdit: "Удалить и отредактировать"
|
||||
|
@ -215,8 +217,10 @@ perDay: "По дням"
|
|||
stopActivityDelivery: "Остановить отправку обновлений активности"
|
||||
blockThisInstance: "Блокировать этот инстанс"
|
||||
silenceThisInstance: "Заглушить этот инстанс"
|
||||
mediaSilenceThisInstance: "Заглушить сервер"
|
||||
operations: "Операции"
|
||||
software: "Программы"
|
||||
softwareName: "Software Name"
|
||||
version: "Версия"
|
||||
metadata: "Метаданные"
|
||||
withNFiles: "Файлы, {n} шт."
|
||||
|
@ -235,7 +239,11 @@ clearCachedFilesConfirm: "Удалить все закэшированные ф
|
|||
blockedInstances: "Заблокированные инстансы"
|
||||
blockedInstancesDescription: "Введите список инстансов, которые хотите заблокировать. Они больше не смогут обмениваться с вашим инстансом."
|
||||
silencedInstances: "Заглушённые инстансы"
|
||||
silencedInstancesDescription: "Перечислите имена серверов, которые вы хотите отключить, разделив их новой строкой. Все учетные записи, принадлежащие к указанным в списке серверам, будут заблокированы и смогут отправлять запросы только на повторное использование и не смогут указывать локальные учетные записи, если они не будут отслеживаться. Это не повлияет на заблокированные серверы."
|
||||
mediaSilencedInstances: "Заглушённые сервера"
|
||||
mediaSilencedInstancesDescription: "Укажите названия серверов, для которых вы хотите отключить доступ к файлам, по одному серверу в строке. Все учетные записи, принадлежащие к перечисленным серверам, будут считаться конфиденциальными и не смогут использовать пользовательские эмодзи. Это никак не повлияет на заблокированные серверы."
|
||||
federationAllowedHosts: "Серверы, поддерживающие федерацию"
|
||||
federationAllowedHostsDescription: "Укажите имена серверов, для которых вы хотите разрешить объединение, разделив их разделителями строк."
|
||||
muteAndBlock: "Скрытие и блокировка"
|
||||
mutedUsers: "Скрытые пользователи"
|
||||
blockedUsers: "Заблокированные пользователи"
|
||||
|
@ -243,7 +251,6 @@ noUsers: "Нет ни одного пользователя"
|
|||
editProfile: "Редактировать профиль"
|
||||
noteDeleteConfirm: "Вы хотите удалить эту заметку?"
|
||||
pinLimitExceeded: "Нельзя закрепить ещё больше заметок"
|
||||
intro: "Установка Misskey завершена! А теперь создайте учетную запись администратора."
|
||||
done: "Готово"
|
||||
processing: "Обработка"
|
||||
preview: "Предпросмотр"
|
||||
|
@ -294,6 +301,7 @@ uploadFromUrlMayTakeTime: "Загрузка может занять некото
|
|||
explore: "Обзор"
|
||||
messageRead: "Прочитали"
|
||||
noMoreHistory: "История закончилась"
|
||||
startChat: "Начать чат"
|
||||
nUsersRead: "Прочитали {n}"
|
||||
agreeTo: "Я соглашаюсь с {0}"
|
||||
agree: "Согласен"
|
||||
|
@ -416,6 +424,7 @@ antennaExcludeBots: "Исключать ботов"
|
|||
antennaKeywordsDescription: "Пишите слова через пробел в одной строке, чтобы ловить их появление вместе; на отдельных строках располагайте слова, или группы слов, чтобы ловить любые из них."
|
||||
notifyAntenna: "Уведомлять о новых заметках"
|
||||
withFileAntenna: "Только заметки с вложениями"
|
||||
excludeNotesInSensitiveChannel: "Исключить заметки из конфиденциальных каналов"
|
||||
enableServiceworker: "Включить ServiceWorker"
|
||||
antennaUsersDescription: "Пишите каждое название аккаута на отдельной строке"
|
||||
caseSensitive: "С учётом регистра"
|
||||
|
@ -446,6 +455,8 @@ totpDescription: "Описание приложения-аутентификат
|
|||
moderator: "Модератор"
|
||||
moderation: "Модерация"
|
||||
moderationNote: "Примечания модератора"
|
||||
moderationNoteDescription: "Вы можете заполнять заметки, которые будут доступны только модераторам."
|
||||
addModerationNote: ""
|
||||
moderationLogs: "Журнал модерации"
|
||||
nUsersMentioned: "Упомянуло пользователей: {n}"
|
||||
securityKeyAndPasskey: "Ключ безопасности и парольная фраза"
|
||||
|
@ -506,6 +517,8 @@ emojiStyle: "Стиль эмодзи"
|
|||
native: "Системные"
|
||||
menuStyle: "Стиль меню"
|
||||
style: "Стиль"
|
||||
drawer: "Панель"
|
||||
popup: "Всплывающие окна"
|
||||
showNoteActionsOnlyHover: "Показывать кнопки у заметок только при наведении"
|
||||
showReactionsCount: "Видеть количество реакций на заметках"
|
||||
noHistory: "История пока пуста"
|
||||
|
@ -560,6 +573,7 @@ serverLogs: "Журнал сервера"
|
|||
deleteAll: "Удалить всё"
|
||||
showFixedPostForm: "Показывать поле для ввода новой заметки наверху ленты"
|
||||
showFixedPostFormInChannel: "Показывать поле для ввода новой заметки наверху ленты (каналы)"
|
||||
withRepliesByDefaultForNewlyFollowed: "По умолчанию включайте ответы новых пользователей, на которых вы подписались, во временную шкалу"
|
||||
newNoteRecived: "Появилась новая заметка"
|
||||
sounds: "Звуки"
|
||||
sound: "Звуки"
|
||||
|
@ -572,6 +586,7 @@ masterVolume: "Основная регулировка громкости"
|
|||
notUseSound: "Выключить звук"
|
||||
useSoundOnlyWhenActive: "Воспроизводить звук только когда Misskey активен."
|
||||
details: "Подробнее"
|
||||
renoteDetails: "Узнать больше"
|
||||
chooseEmoji: "Выберите эмодзи"
|
||||
unableToProcess: "Не удаётся завершить операцию"
|
||||
recentUsed: "Последние использованные"
|
||||
|
@ -587,6 +602,8 @@ ascendingOrder: "по возрастанию"
|
|||
descendingOrder: "По убыванию"
|
||||
scratchpad: "Когтеточка"
|
||||
scratchpadDescription: "«Когтеточка» — это место для опытов с AiScript. Здесь можно писать программы, взаимодействующие с Misskey, запускать и смотреть что из этого получается."
|
||||
uiInspector: "Средство проверки пользовательского интерфейса"
|
||||
uiInspectorDescription: "Вы можете просмотреть список экземпляров компонентов пользовательского интерфейса, существующих в памяти. Элементы пользовательского интерфейса генерируются с помощью серии функций Ui:C:."
|
||||
output: "Выходы"
|
||||
script: "Скрипт"
|
||||
disablePagesScript: "Отключить скрипты на «Страницах»"
|
||||
|
@ -667,14 +684,19 @@ smtpSecure: "Использовать SSL/TLS для SMTP-соединений"
|
|||
smtpSecureInfo: "Выключите при использовании STARTTLS."
|
||||
testEmail: "Проверка доставки электронной почты"
|
||||
wordMute: "Скрытие слов"
|
||||
wordMuteDescription: "Сведите к минимуму записи, содержащие указанное утверждение. Нажмите на свернутую запись, чтобы отобразить ее."
|
||||
hardWordMute: "Строгое скрытие слов"
|
||||
showMutedWord: "Отображать слово без уведомления (звука)"
|
||||
hardWordMuteDescription: "Скрыть заметки, содержащие указанное слово или фразу. В отличие от word mute, заметка будет полностью скрыта от просмотра."
|
||||
regexpError: "Ошибка в регулярном выражении"
|
||||
regexpErrorDescription: "В списке {tab} скрытых слов, в строке {line} обнаружена синтаксическая ошибка:"
|
||||
instanceMute: "Глушение инстансов"
|
||||
userSaysSomething: "{name} что-то сообщает"
|
||||
userSaysSomethingAbout: "{name} что-то говорил о「{word}」"
|
||||
makeActive: "Активировать"
|
||||
display: "Отображение"
|
||||
copy: "Копировать"
|
||||
copiedToClipboard: "Скопированы в буфер обмена"
|
||||
metrics: "Метрики"
|
||||
overview: "Обзор"
|
||||
logs: "Журналы"
|
||||
|
@ -762,7 +784,6 @@ thisIsExperimentalFeature: "Это экспериментальная функц
|
|||
developer: "Разработчик"
|
||||
makeExplorable: "Опубликовать профиль в «Обзоре»."
|
||||
makeExplorableDescription: "Если выключить, ваш профиль не будет показан в разделе «Обзор»."
|
||||
showGapBetweenNotesInTimeline: "Показывать разделитель между заметками в ленте"
|
||||
duplicate: "Дубликат"
|
||||
left: "Слева"
|
||||
center: "По центру"
|
||||
|
@ -840,6 +861,7 @@ administration: "Управление"
|
|||
accounts: "Учётные записи"
|
||||
switch: "Переключение"
|
||||
noMaintainerInformationWarning: "Не заполнены сведения об администраторах"
|
||||
noInquiryUrlWarning: "URL-адрес контактной формы еще не задан."
|
||||
noBotProtectionWarning: "Ботозащита не настроена"
|
||||
configure: "Настроить"
|
||||
postToGallery: "Опубликовать в галерею"
|
||||
|
@ -904,6 +926,7 @@ followersVisibility: "Видимость подписчиков"
|
|||
continueThread: "Показать следующие ответы"
|
||||
deleteAccountConfirm: "Учётная запись будет безвозвратно удалена. Подтверждаете?"
|
||||
incorrectPassword: "Пароль неверен."
|
||||
incorrectTotp: "Введен неверный одноразовый пароль или срок его действия истек."
|
||||
voteConfirm: "Отдать голос за «{choice}»?"
|
||||
hide: "Спрятать"
|
||||
useDrawerReactionPickerForMobile: "Выдвижная палитра на мобильном устройстве"
|
||||
|
@ -928,6 +951,9 @@ oneHour: "1 час"
|
|||
oneDay: "1 день"
|
||||
oneWeek: "1 неделя"
|
||||
oneMonth: "1 месяц"
|
||||
threeMonths: "3 месяца"
|
||||
oneYear: "1 год"
|
||||
threeDays: "3 дня"
|
||||
reflectMayTakeTime: "Изменения могут занять время для отображения"
|
||||
failedToFetchAccountInformation: "Не удалось получить информацию об аккаунте"
|
||||
rateLimitExceeded: "Ограничение скорости превышено"
|
||||
|
@ -952,6 +978,7 @@ document: "Документ"
|
|||
numberOfPageCache: "Количество сохранённых страниц в кэше"
|
||||
numberOfPageCacheDescription: "Описание количества страниц в кэше"
|
||||
logoutConfirm: "Вы хотите выйти из аккаунта?"
|
||||
logoutWillClearClientData: "Когда вы выйдете из системы, информация о конфигурации клиента будет удалена из браузера.Чтобы иметь возможность восстановить информацию о вашей конфигурации при повторном входе в систему, пожалуйста, включите опцию автоматического резервного копирования в настройках."
|
||||
lastActiveDate: "Последняя дата использования"
|
||||
statusbar: "Статусбар"
|
||||
pleaseSelect: "Пожалуйста, выберите"
|
||||
|
@ -1001,6 +1028,7 @@ neverShow: "Больше не показывать"
|
|||
remindMeLater: "Напомнить позже"
|
||||
didYouLikeMisskey: "Вам нравится Misskey?"
|
||||
pleaseDonate: "Сайт {host} работает на Misskey. Это бесплатное программное обеспечение, и ваши пожертвования очень бы помогли продолжать его разработку!"
|
||||
correspondingSourceIsAvailable: "Соответствующий исходный код можно найти по адресу {anchor} "
|
||||
roles: "Роли"
|
||||
role: "Роль"
|
||||
noRole: "Нет роли"
|
||||
|
@ -1056,6 +1084,7 @@ prohibitedWords: "Запрещённые слова"
|
|||
prohibitedWordsDescription: "Включает вывод ошибки при попытке опубликовать пост, содержащий указанное слово/набор слов.\nМножество слов может быть указано, разделяемые новой строкой."
|
||||
prohibitedWordsDescription2: "Разделение пробелом создаёт спецификацию AND, а разделение косой чертой создаёт регулярное выражение."
|
||||
hiddenTags: "Скрытые хештеги"
|
||||
hiddenTagsDescription: "Установленные теги не будут отображаться в тренде, можно установить несколько тегов."
|
||||
notesSearchNotAvailable: "Поиск заметок недоступен"
|
||||
license: "Лицензия"
|
||||
unfavoriteConfirm: "Удалить избранное?"
|
||||
|
@ -1066,6 +1095,7 @@ retryAllQueuesConfirmTitle: "Хотите попробовать ещё раз?"
|
|||
retryAllQueuesConfirmText: "Нагрузка на сервер может увеличиться"
|
||||
enableChartsForRemoteUser: "Создание диаграмм для удалённых пользователей"
|
||||
enableChartsForFederatedInstances: "Создание диаграмм для удалённых серверов"
|
||||
enableStatsForFederatedInstances: "Получить информацию об удаленном сервере"
|
||||
showClipButtonInNoteFooter: "Показать кнопку добавления в подборку в меню действий с заметкой"
|
||||
reactionsDisplaySize: "Размер реакций"
|
||||
limitWidthOfReaction: "Ограничить максимальную ширину реакций и отображать их в уменьшенном размере."
|
||||
|
@ -1101,6 +1131,7 @@ preservedUsernames: "Зарезервированные имена пользо
|
|||
preservedUsernamesDescription: "Перечислите зарезервированные имена пользователей, отделяя их строками. Они станут недоступны при создании учётной записи. Это ограничение не применяется при создании учётной записи администраторами. Также, уже существующие учётные записи останутся без изменений."
|
||||
createNoteFromTheFile: "Создать заметку из этого файла"
|
||||
archive: "Архив"
|
||||
archived: "Архивировано"
|
||||
unarchive: "Разархивировать"
|
||||
channelArchiveConfirmTitle: "Переместить {name} в архив?"
|
||||
channelArchiveConfirmDescription: "Архивированные каналы перестанут отображаться в списке каналов или результатах поиска. В них также нельзя будет добавлять новые записи."
|
||||
|
@ -1121,6 +1152,7 @@ rolesThatCanBeUsedThisEmojiAsReaction: "Роли тех, кому можно и
|
|||
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Если здесь ничего не указать, в качестве реакции эту эмодзи сможет использовать каждый."
|
||||
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Эти роли должны быть общедоступными."
|
||||
cancelReactionConfirm: "Вы действительно хотите удалить свою реакцию?"
|
||||
changeReactionConfirm: "Вы действительно хотите удалить свою реакцию?"
|
||||
later: "Позже"
|
||||
goToMisskey: "К Misskey"
|
||||
additionalEmojiDictionary: "Дополнительные словари эмодзи"
|
||||
|
@ -1130,9 +1162,16 @@ enableServerMachineStats: "Опубликовать характеристики
|
|||
enableIdenticonGeneration: "Включить генерацию иконки пользователя"
|
||||
turnOffToImprovePerformance: "Отключение этого параметра может повысить производительность."
|
||||
createInviteCode: "Создать код приглашения"
|
||||
createWithOptions: "Используйте параметры для создания"
|
||||
createCount: "Количество приглашений"
|
||||
inviteCodeCreated: "Создан пригласительный код"
|
||||
inviteLimitExceeded: "Достигнут предел количества пригласительных кодов, которые могут быть созданы."
|
||||
createLimitRemaining: "Пригласительные коды, которые могут быть созданы: {limit} "
|
||||
inviteLimitResetCycle: "За определенное {time} Вы можете создать неограниченное количество пригласительных кодов {limit} "
|
||||
expirationDate: "Дата истечения"
|
||||
noExpirationDate: "Бессрочно"
|
||||
inviteCodeUsedAt: "Дата и время, когда был использован пригласительный код"
|
||||
registeredUserUsingInviteCode: "Пользователи, которые использовали пригласительный код"
|
||||
unused: "Неиспользованное"
|
||||
used: "Использован"
|
||||
expired: "Срок действия приглашения истёк"
|
||||
|
@ -1159,7 +1198,6 @@ privacyPolicyUrl: "Ссылка на Политику Конфиденциаль
|
|||
attach: "Прикрепить"
|
||||
angle: "Угол"
|
||||
flip: "Переворот"
|
||||
disableStreamingTimeline: "Отключить обновление ленты в режиме реального времени"
|
||||
useGroupedNotifications: "Отображать уведомления сгруппировано"
|
||||
doReaction: "Добавить реакцию"
|
||||
code: "Код"
|
||||
|
@ -1689,7 +1727,6 @@ _theme:
|
|||
header: "Заголовок"
|
||||
navBg: "Фон боковой панели"
|
||||
navFg: "Текст на боковой панели"
|
||||
navHoverFg: "Текст на боковой панели (под указателем)"
|
||||
navActive: "Текст на боковой панели (активирован)"
|
||||
navIndicator: "Индикатор на боковой панели"
|
||||
link: "Ссылка"
|
||||
|
@ -1712,11 +1749,8 @@ _theme:
|
|||
buttonHoverBg: "Текст кнопки"
|
||||
inputBorder: "Рамка поля ввода"
|
||||
driveFolderBg: "Фон папки «Диска»"
|
||||
wallpaperOverlay: "Слой обоев"
|
||||
badge: "Значок"
|
||||
messageBg: "Фон беседы"
|
||||
accentDarken: "Фон (затемнённый)"
|
||||
accentLighten: "Фон (осветлённый)"
|
||||
fgHighlighted: "Подсвеченный текст"
|
||||
_sfx:
|
||||
note: "Заметки"
|
||||
|
|
|
@ -204,7 +204,6 @@ noUsers: "Žiadni používatelia"
|
|||
editProfile: "Upraviť profil"
|
||||
noteDeleteConfirm: "Naozaj chcete odstrániť túto poznámku?"
|
||||
pinLimitExceeded: "Ďalšie poznámky už nemôžete pripnúť."
|
||||
intro: "Inštalácia Misskey je dokončená! Prosím vytvorte administrátora."
|
||||
done: "Hotovo"
|
||||
processing: "Pracujem..."
|
||||
preview: "Náhľad"
|
||||
|
@ -682,7 +681,6 @@ experimentalFeatures: "Experimentálne funkcie"
|
|||
developer: "Vývojár"
|
||||
makeExplorable: "Spraviť účet viditeľný v \"Objavovať\""
|
||||
makeExplorableDescription: "Ak toto vypnete, váš účet sa nezobrazí v sekcii \"Objavovat\"."
|
||||
showGapBetweenNotesInTimeline: "Zobraziť medzeru medzi príspevkami časovej osi."
|
||||
duplicate: "Duplikovať"
|
||||
left: "Naľavo"
|
||||
center: "Stred"
|
||||
|
@ -1089,7 +1087,6 @@ _theme:
|
|||
header: "Hlavička"
|
||||
navBg: "Pozadie bočného panela"
|
||||
navFg: "Text bočného panela"
|
||||
navHoverFg: "Text bočného panela (pod kurzorom)"
|
||||
navActive: "Text bočného panela (aktívny)"
|
||||
navIndicator: "Indikátor bočného panela"
|
||||
link: "Odkaz"
|
||||
|
@ -1112,11 +1109,8 @@ _theme:
|
|||
buttonHoverBg: "Pozadie tlačidla (pod kurzorom)"
|
||||
inputBorder: "Okraj vstupného poľa"
|
||||
driveFolderBg: "Pozadie priečinu disku"
|
||||
wallpaperOverlay: "Vrstvenie pozadia"
|
||||
badge: "Odznak"
|
||||
messageBg: "Pozadie chatu"
|
||||
accentDarken: "Akcent (stmavené)"
|
||||
accentLighten: "Akcent (zosvetlené)"
|
||||
fgHighlighted: "Zvýraznený text"
|
||||
_sfx:
|
||||
note: "Poznámky"
|
||||
|
|
|
@ -211,7 +211,6 @@ noUsers: "Det finns inga användare"
|
|||
editProfile: "Redigera profil"
|
||||
noteDeleteConfirm: "Är du säker på att du vill ta bort denna not?"
|
||||
pinLimitExceeded: "Du kan inte fästa fler noter"
|
||||
intro: "Misskey har installerats! Vänligen skapa en adminanvändare."
|
||||
done: "Klar"
|
||||
processing: "Bearbetar..."
|
||||
preview: "Förhandsvisning"
|
||||
|
|
|
@ -5,6 +5,7 @@ introMisskey: "ยินดีต้อนรับทุกคนจ้า! Mis
|
|||
poweredByMisskeyDescription: "{name} เป็นหนึ่งในเซิร์ฟเวอร์ของแพลตฟอร์มโอเพ่นซอร์ส <b>Misskey</b>"
|
||||
monthAndDay: "{month}/{day}"
|
||||
search: "ค้นหา"
|
||||
reset: "รีเซ็ต"
|
||||
notifications: "เเจ้งเตือน"
|
||||
username: "ชื่อผู้ใช้"
|
||||
password: "รหัสผ่าน"
|
||||
|
@ -48,6 +49,7 @@ pin: "ปักหมุด"
|
|||
unpin: "เลิกปักหมุด"
|
||||
copyContent: "คัดลอกเนื้อหา"
|
||||
copyLink: "คัดลอกลิงก์"
|
||||
copyRemoteLink: "คัดลอกลิงค์ระยะไกล"
|
||||
copyLinkRenote: "คัดลอกลิงก์รีโน้ต"
|
||||
delete: "ลบ"
|
||||
deleteAndEdit: "ลบและแก้ไข"
|
||||
|
@ -248,7 +250,6 @@ noUsers: "ไม่พบผู้ใช้งาน"
|
|||
editProfile: "แก้ไขโปรไฟล์"
|
||||
noteDeleteConfirm: "ต้องการลบโน้ตนี้ใช่ไหม?"
|
||||
pinLimitExceeded: "คุณไม่สามารถปักหมุดโน้ตเพิ่มเติมใดๆได้อีก"
|
||||
intro: "การติดตั้ง Misskey เสร็จสิ้นแล้วนะ! โปรดสร้างผู้ใช้งานที่เป็นผู้ดูแลระบบ"
|
||||
done: "เสร็จสิ้น"
|
||||
processing: "กำลังประมวลผล..."
|
||||
preview: "แสดงตัวอย่าง"
|
||||
|
@ -680,10 +681,12 @@ smtpSecureInfo: "ปิดสิ่งนี้เมื่อใช้ STARTTLS
|
|||
testEmail: "ทดสอบการส่งอีเมล"
|
||||
wordMute: "ปิดเสียงคำ"
|
||||
hardWordMute: "ปิดเสียงคำแบบแข็งโป๊ก"
|
||||
hardWordMuteDescription: "ซ่อนหมายเหตุที่มีวลีที่ระบุ ต่างจากการปิดเสียงคำ โน้ตต่างๆ จะถูกซ่อนไว้อย่างสมบูรณ์"
|
||||
regexpError: "เกิดข้อผิดพลาดใน regular expression"
|
||||
regexpErrorDescription: "เกิดข้อผิดพลาดใน regular expression บรรทัดที่ {line} ของการปิดเสียงคำ {tab} :"
|
||||
instanceMute: "ปิดเสียงเซิร์ฟเวอร์"
|
||||
userSaysSomething: "{name} พูดอะไรบางอย่าง"
|
||||
userSaysSomethingAbout: "{name} พูดอะไรบางอย่างเกี่ยวกับ \"{word}\""
|
||||
makeActive: "เปิดใช้งาน"
|
||||
display: "แสดงผล"
|
||||
copy: "คัดลอก"
|
||||
|
@ -774,7 +777,6 @@ thisIsExperimentalFeature: "นี่เป็นฟีเจอร์ทดล
|
|||
developer: "สำหรับนักพัฒนา"
|
||||
makeExplorable: "ทำให้บัญชีมองเห็นใน “สำรวจ”"
|
||||
makeExplorableDescription: "ถ้าหากคุณปิดการทำงานนี้ บัญชีของคุณนั้นจะไม่แสดงในส่วน “สำรวจ”"
|
||||
showGapBetweenNotesInTimeline: "แสดงช่องว่างระหว่างโพสต์บนไทม์ไลน์"
|
||||
duplicate: "ทำซ้ำ"
|
||||
left: "ซ้าย"
|
||||
center: "กึ่งกลาง"
|
||||
|
@ -1223,7 +1225,6 @@ showAvatarDecorations: "แสดงตกแต่งอวตาร"
|
|||
releaseToRefresh: "ปล่อยเพื่อรีเฟรช"
|
||||
refreshing: "กำลังรีเฟรช..."
|
||||
pullDownToRefresh: "ดึงลงเพื่อรีเฟรช"
|
||||
disableStreamingTimeline: "ปิดใช้งานอัปเดตไทม์ไลน์แบบเรียลไทม์"
|
||||
useGroupedNotifications: "แสดงผลการแจ้งเตือนแบบกลุ่มแล้ว"
|
||||
signupPendingError: "มีปัญหาในการตรวจสอบที่อยู่อีเมลลิงก์อาจหมดอายุแล้ว"
|
||||
cwNotationRequired: "หากเปิดใช้งาน “ซ่อนเนื้อหา” จะต้องระบุคำอธิบาย"
|
||||
|
@ -1288,8 +1289,14 @@ prohibitedWordsForNameOfUser: "คำนี้ไม่สามารถใช
|
|||
prohibitedWordsForNameOfUserDescription: "หากมีสตริงใดๆ ในรายการนี้ปรากฏอยู่ในชื่อของผู้ใช้ ชื่อนั้นจะถูกปฏิเสธ ผู้ใช้ที่มีสิทธิ์แต่ผู้ดูแลระบบนั้นจะไม่ได้รับผลกระทบใดๆจากข้อจำกัดนี้ค่ะ"
|
||||
yourNameContainsProhibitedWords: "ชื่อของคุณนั้นมีคำที่ต้องห้าม"
|
||||
yourNameContainsProhibitedWordsDescription: "ถ้าหากคุณต้องการใช้ชื่อนี้ กรุณาติดต่อผู้ดูแลระบบของเซิร์ฟเวอร์นะค่ะ"
|
||||
federationDisabled: "เซิร์ฟเวอร์นี้ปิดการใช้งานการรวมกลุ่ม คุณไม่สามารถโต้ตอบกับผู้ใช้บนเซิร์ฟเวอร์อื่นได้"
|
||||
reactAreYouSure: "คุณต้องการที่จะตอบสนองต่อ \" {emoji}\" หรือไม่?"
|
||||
markAsSensitiveConfirm: "คุณต้องการทำเครื่องหมายสื่อนี้ว่าละเอียดอ่อนหรือไม่?"
|
||||
unmarkAsSensitiveConfirm: "คุณต้องการลบการกำหนดความไวของสื่อนี้หรือไม่?"
|
||||
postForm: "แบบฟอร์มการโพสต์"
|
||||
information: "เกี่ยวกับ"
|
||||
right: "ขวา"
|
||||
bottom: "ภายใต้"
|
||||
_chat:
|
||||
invitations: "คำเชิญ"
|
||||
noHistory: "ไม่มีประวัติ"
|
||||
|
@ -1298,6 +1305,11 @@ _chat:
|
|||
send: "ส่ง"
|
||||
_settings:
|
||||
webhook: "Webhook"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "ต้องเข้าสู่ระบบเพื่อดูเนื้อหา"
|
||||
requireSigninToViewContentsDescription1: "ต้องเข้าสู่ระบบเพื่อดูบันทึกและเนื้อหาอื่น ๆ ทั้งหมดที่คุณสร้าง คาดว่าจะมีประสิทธิผลในการป้องกันไม่ให้ข้อมูลถูกเก็บรวบรวมโดยโปรแกรมรวบรวมข้อมูล"
|
||||
requireSigninToViewContentsDescription2: "นอกจากนี้ จะไม่สามารถดูจากเซิร์ฟเวอร์ที่ไม่รองรับการดูตัวอย่าง URL (OGP), การฝังในหน้าเว็บ หรือการอ้างอิงหมายเหตุได้"
|
||||
requireSigninToViewContentsDescription3: "เนื้อหาที่ถูกรวมเข้ากับเซิร์ฟเวอร์ระยะไกลอาจไม่อยู่ภายใต้ข้อจำกัดเหล่านี้"
|
||||
_abuseUserReport:
|
||||
forward: "ส่งต่อ"
|
||||
forwardDescription: "ส่งรายงานไปยังเซิร์ฟเวอร์ระยะไกลโดยใช้บัญชีระบบที่ไม่ระบุตัวตน"
|
||||
|
@ -1974,7 +1986,6 @@ _theme:
|
|||
header: "ส่วนหัว"
|
||||
navBg: "พื้นหลังแถบด้านข้าง"
|
||||
navFg: "ข้อความแถบด้านข้าง"
|
||||
navHoverFg: "ข้อความแถบด้านข้าง (โฮเวอร์)"
|
||||
navActive: "ข้อความแถบด้านข้าง (ใช้งานอยู่)"
|
||||
navIndicator: "ตัวระบุแถบด้านข้าง"
|
||||
link: "ลิงก์"
|
||||
|
@ -1997,11 +2008,8 @@ _theme:
|
|||
buttonHoverBg: "ปุ่มพื้นหลัง (โฮเวอร์)"
|
||||
inputBorder: "เส้นขอบของช่องป้อนข้อมูล"
|
||||
driveFolderBg: "พื้นหลังโฟลเดอร์ไดรฟ์"
|
||||
wallpaperOverlay: "วอลล์เปเปอร์ซ้อนทับ"
|
||||
badge: "ตรา"
|
||||
messageBg: "พื้นหลังแชท"
|
||||
accentDarken: "สีหลัก (มืด)"
|
||||
accentLighten: "สีหลัก (สว่าง)"
|
||||
fgHighlighted: "ข้อความที่ไฮไลต์"
|
||||
_sfx:
|
||||
note: "โน้ต"
|
||||
|
|
|
@ -224,7 +224,6 @@ noUsers: "Kullanıcı yok"
|
|||
editProfile: "Profili düzenle"
|
||||
noteDeleteConfirm: "Bu notu silmek istediğinizden emin misiniz?"
|
||||
pinLimitExceeded: "Daha fazla not sabitlenemez"
|
||||
intro: "Misskey yüklemesi tamamlandı! Lütfen yönetici hesabını oluşturun."
|
||||
done: "Tamamlandı"
|
||||
preview: "Önizleme"
|
||||
default: "Varsayılan"
|
||||
|
|
|
@ -208,7 +208,6 @@ noUsers: "Немає користувачів"
|
|||
editProfile: "Редагувати обліковий запис"
|
||||
noteDeleteConfirm: "Ви дійсно хочете видалити цей запис?"
|
||||
pinLimitExceeded: "Більше записів не можна закріпити"
|
||||
intro: "Встановлення Misskey завершено! Будь ласка, створіть обліковий запис адміністратора."
|
||||
done: "Готово"
|
||||
processing: "Обробка"
|
||||
preview: "Попередній перегляд"
|
||||
|
@ -681,7 +680,6 @@ experimentalFeatures: "Експериментальні функції"
|
|||
developer: "Розробник"
|
||||
makeExplorable: "Зробіть обліковий запис видимим у розділі \"Огляд\""
|
||||
makeExplorableDescription: "Вимкніть, щоб обліковий запис не показувався у розділі \"Огляд\"."
|
||||
showGapBetweenNotesInTimeline: "Показувати розрив між записами у стрічці новин"
|
||||
duplicate: "Дублікат"
|
||||
left: "Лівий"
|
||||
center: "Центр"
|
||||
|
@ -1283,7 +1281,6 @@ _theme:
|
|||
header: "Заголовок"
|
||||
navBg: "Фон бокової панелі"
|
||||
navFg: "Текст бокової панелі"
|
||||
navHoverFg: "Текст бокової панелі (під курсором)"
|
||||
navActive: "Текст бокової панелі (активне)"
|
||||
navIndicator: "Індикатор бокової панелі"
|
||||
link: "Посилання"
|
||||
|
@ -1306,11 +1303,8 @@ _theme:
|
|||
buttonHoverBg: "Фон кнопки (при наведенні)"
|
||||
inputBorder: "Край поля вводу"
|
||||
driveFolderBg: "Фон папки на диску"
|
||||
wallpaperOverlay: "Накладання шпалер"
|
||||
badge: "Значок"
|
||||
messageBg: "Фон переписки"
|
||||
accentDarken: "Акцент (Затемлений)"
|
||||
accentLighten: "Акцент (Освітлений)"
|
||||
fgHighlighted: "Виділений текст"
|
||||
_sfx:
|
||||
note: "Нотатки"
|
||||
|
|
|
@ -219,7 +219,6 @@ noUsers: "Foydalanuvchilar yo‘q"
|
|||
editProfile: "Profilni o'zgartirish"
|
||||
noteDeleteConfirm: "Haqiqatan ham bu qaydni oʻchirib tashlamoqchimisiz?"
|
||||
pinLimitExceeded: "Siz boshqa qaydlarni mahkamlay olmaysiz"
|
||||
intro: "Misskeyni o'rnatish tugallandi! Iltimos, administrator foydalanuvchi yarating."
|
||||
done: "Bajarildi"
|
||||
processing: "Amaliyotda"
|
||||
preview: "Ko'rish"
|
||||
|
@ -907,8 +906,6 @@ _theme:
|
|||
mention: "Murojat"
|
||||
renote: "Qayta qayd etish"
|
||||
divider: "Ajratrmoq"
|
||||
accentDarken: "Urg'u (Qoraytirilgan)"
|
||||
accentLighten: "Urg'u (Yoritilgan)"
|
||||
fgHighlighted: "Belgilangan matn"
|
||||
_sfx:
|
||||
note: "Qaydlar"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
_lang_: "Tiếng Nhật"
|
||||
_lang_: "Tiếng Việt "
|
||||
headlineMisskey: "Mạng xã hội liên hợp"
|
||||
introMisskey: "Xin chào! Misskey là một nền tảng tiểu blog phi tập trung mã nguồn mở.\nViết \"tút\" để chia sẻ những suy nghĩ của bạn 📡\nBằng \"biểu cảm\", bạn có thể bày tỏ nhanh chóng cảm xúc của bạn với các tút 👍\nHãy khám phá một thế giới mới! 🚀"
|
||||
poweredByMisskeyDescription: "{name} là một trong những chủ máy của <b>Misskey</b> là nền tảng mã nguồn mở"
|
||||
monthAndDay: "{day} tháng {month}"
|
||||
search: "Tìm kiếm"
|
||||
reset: "cài lại"
|
||||
notifications: "Thông báo"
|
||||
username: "Tên người dùng"
|
||||
password: "Mật khẩu"
|
||||
|
@ -48,9 +49,10 @@ pin: "Ghim"
|
|||
unpin: "Bỏ ghim"
|
||||
copyContent: "Chép nội dung"
|
||||
copyLink: "Chép liên kết"
|
||||
copyRemoteLink: "Sao chép liên kết từ xa"
|
||||
copyLinkRenote: "Sao chép liên kết ghi chú"
|
||||
delete: "Xóa"
|
||||
deleteAndEdit: "Sửa"
|
||||
deleteAndEdit: "Xóa và soạn thảo lại"
|
||||
deleteAndEditConfirm: "Bạn có chắc muốn sửa tút này? Những biểu cảm, lượt trả lời và đăng lại sẽ bị mất."
|
||||
addToList: "Thêm vào danh sách"
|
||||
addToAntenna: "Thêm vào Ăngten"
|
||||
|
@ -63,6 +65,7 @@ copyFileId: "Sao chép ID tập tin"
|
|||
copyFolderId: "Sao chép ID thư mục"
|
||||
copyProfileUrl: "Sao chép URL hồ sơ"
|
||||
searchUser: "Tìm kiếm người dùng"
|
||||
searchThisUsersNotes: "Tìm kiếm ghi chú của người dùng"
|
||||
reply: "Trả lời"
|
||||
loadMore: "Tải thêm"
|
||||
showMore: "Xem thêm"
|
||||
|
@ -111,11 +114,14 @@ enterEmoji: "Chèn emoji"
|
|||
renote: "Đăng lại"
|
||||
unrenote: "Hủy đăng lại"
|
||||
renoted: "Đã đăng lại."
|
||||
renotedToX: "Đã cho thuê lại {name}."
|
||||
cantRenote: "Không thể đăng lại tút này."
|
||||
cantReRenote: "Không thể đăng lại một tút đăng lại."
|
||||
quote: "Trích dẫn"
|
||||
inChannelRenote: "Chia sẻ trong kênh này"
|
||||
inChannelQuote: "Trích dẫn trong kênh này"
|
||||
renoteToChannel: "Đăng lại tới kênh"
|
||||
renoteToOtherChannel: "Đăng lại tới kênh khác"
|
||||
pinnedNote: "Bài viết đã ghim"
|
||||
pinned: "Ghim"
|
||||
you: "Bạn"
|
||||
|
@ -125,6 +131,11 @@ add: "Thêm"
|
|||
reaction: "Biểu cảm"
|
||||
reactions: "Biểu cảm"
|
||||
emojiPicker: "Bộ chọn biểu tượng cảm xúc"
|
||||
pinnedEmojisForReactionSettingDescription: "Ghim các biểu tượng cảm xúc sẽ hiển thị khi phản hồi"
|
||||
pinnedEmojisSettingDescription: "Ghim các biểu tượng cảm xúc sẽ hiển thị trong bảng chọn emoji"
|
||||
emojiPickerDisplay: "Hiển thị bộ chọn"
|
||||
overwriteFromPinnedEmojisForReaction: "Ghi đè thiết lập phản hồi"
|
||||
overwriteFromPinnedEmojis: "Ghi đè thiết lập chung"
|
||||
reactionSettingDescription2: "Kéo để sắp xếp, nhấn để xóa, nhấn \"+\" để thêm."
|
||||
rememberNoteVisibility: "Lưu kiểu tút mặc định"
|
||||
attachCancel: "Gỡ tập tin đính kèm"
|
||||
|
@ -149,6 +160,7 @@ editList: "Chỉnh sửa danh sách"
|
|||
selectChannel: "Lựa chọn kênh"
|
||||
selectAntenna: "Chọn một antenna"
|
||||
editAntenna: "Chỉnh sửa Ăngten"
|
||||
createAntenna: "Tạo Ăngten "
|
||||
selectWidget: "Chọn tiện ích"
|
||||
editWidgets: "Sửa tiện ích"
|
||||
editWidgetsExit: "Xong"
|
||||
|
@ -175,6 +187,10 @@ addAccount: "Thêm tài khoản"
|
|||
reloadAccountsList: "Cập nhật danh sách tài khoản"
|
||||
loginFailed: "Đăng nhập không thành công"
|
||||
showOnRemote: "Truy cập trang của người này"
|
||||
continueOnRemote: "Tiếp tục trên phiên bản từ xa"
|
||||
chooseServerOnMisskeyHub: "Chọn một máy chủ từ Misskey Hub"
|
||||
specifyServerHost: "Thiết lập một máy chủ"
|
||||
inputHostName: "Nhập địa chỉ máy chủ"
|
||||
general: "Tổng quan"
|
||||
wallpaper: "Ảnh bìa"
|
||||
setWallpaper: "Đặt ảnh bìa"
|
||||
|
@ -185,6 +201,7 @@ followConfirm: "Bạn theo dõi {name}?"
|
|||
proxyAccount: "Tài khoản proxy"
|
||||
proxyAccountDescription: "Tài khoản proxy là tài khoản hoạt động như một người theo dõi từ xa cho người dùng trong những điều kiện nhất định. Ví dụ: khi người dùng thêm người dùng từ xa vào danh sách, hoạt động của người dùng từ xa sẽ không được chuyển đến phiên bản nếu không có người dùng cục bộ nào theo dõi người dùng đó, vì vậy tài khoản proxy sẽ theo dõi."
|
||||
host: "Host"
|
||||
selectSelf: "Chọn chính bạn"
|
||||
selectUser: "Chọn người dùng"
|
||||
recipient: "Người nhận"
|
||||
annotation: "Bình luận"
|
||||
|
@ -199,6 +216,8 @@ perHour: "Mỗi Giờ"
|
|||
perDay: "Mỗi Ngày"
|
||||
stopActivityDelivery: "Ngưng gửi hoạt động"
|
||||
blockThisInstance: "Chặn máy chủ này"
|
||||
silenceThisInstance: "Máy chủ im lặng"
|
||||
mediaSilenceThisInstance: "Tắt nội dung đa phương tiện từ máy chủ này"
|
||||
operations: "Vận hành"
|
||||
software: "Phần mềm"
|
||||
version: "Phiên bản"
|
||||
|
@ -218,6 +237,12 @@ clearCachedFiles: "Xóa bộ nhớ đệm"
|
|||
clearCachedFilesConfirm: "Bạn có chắc muốn xóa sạch bộ nhớ đệm?"
|
||||
blockedInstances: "Máy chủ đã chặn"
|
||||
blockedInstancesDescription: "Danh sách những máy chủ bạn muốn chặn. Chúng sẽ không thể giao tiếp với máy chủy này nữa."
|
||||
silencedInstances: "Máy chủ im lặng"
|
||||
silencedInstancesDescription: "Đặt máy chủ mà bạn muốn tắt tiếng, phân tách bằng dấu xuống dòng. Tất cả tài khoản trên máy chủ bị tắt tiếng sẽ được coi là \"bị tắt tiếng\" và mọi hành động theo dõi sẽ được coi là yêu cầu. Không có tác dụng với những trường hợp bị chặn."
|
||||
mediaSilencedInstances: "Các máy chủ đã tắt nội dung đa phương tiện "
|
||||
mediaSilencedInstancesDescription: "Đặt máy chủ mà bạn muốn tắt nội dung đa phương tiện, phân tách bằng dấu xuống dòng. Tất cả tài khoản trên máy chủ bị tắt tiếng sẽ được coi là \"nhạy cảm\" và biểu tượng cảm xúc tùy chỉnh sẽ không thể được sử dụng. Không có tác dụng với những trường hợp bị chặn."
|
||||
federationAllowedHosts: "Các máy chủ được phép liên kết"
|
||||
federationAllowedHostsDescription: "Điền tên các máy chủ mà bạn muốn cho phép liên kết, cách nhau bởi dấu xuống dòng"
|
||||
muteAndBlock: "Ẩn và Chặn"
|
||||
mutedUsers: "Người đã ẩn"
|
||||
blockedUsers: "Người đã chặn"
|
||||
|
@ -225,7 +250,6 @@ noUsers: "Chưa có ai"
|
|||
editProfile: "Sửa hồ sơ"
|
||||
noteDeleteConfirm: "Bạn có chắc muốn xóa tút này?"
|
||||
pinLimitExceeded: "Bạn không thể ghim bài viết nữa"
|
||||
intro: "Đã cài đặt Misskey! Xin hãy tạo tài khoản admin."
|
||||
done: "Xong"
|
||||
processing: "Đang xử lý"
|
||||
preview: "Xem trước"
|
||||
|
@ -254,8 +278,8 @@ more: "Thêm nữa!"
|
|||
featured: "Nổi bật"
|
||||
usernameOrUserId: "Tên người dùng hoặc ID"
|
||||
noSuchUser: "Không tìm thấy người dùng"
|
||||
lookup: "Tìm kiếm"
|
||||
announcements: "Thông báo"
|
||||
lookup: "Tra cứu"
|
||||
announcements: "Thông báo máy chủ"
|
||||
imageUrl: "URL ảnh"
|
||||
remove: "Xóa"
|
||||
removed: "Đã xóa"
|
||||
|
@ -276,6 +300,7 @@ uploadFromUrlMayTakeTime: "Sẽ mất một khoảng thời gian để tải lê
|
|||
explore: "Khám phá"
|
||||
messageRead: "Đã đọc"
|
||||
noMoreHistory: "Không còn gì để đọc"
|
||||
startChat: "Bắt đầu trò chuyện"
|
||||
nUsersRead: "đọc bởi {n}"
|
||||
agreeTo: "Tôi đồng ý {0}"
|
||||
agree: "Đồng ý"
|
||||
|
@ -306,6 +331,7 @@ selectFile: "Chọn tập tin"
|
|||
selectFiles: "Chọn nhiều tập tin"
|
||||
selectFolder: "Chọn thư mục"
|
||||
selectFolders: "Chọn nhiều thư mục"
|
||||
fileNotSelected: "Chưa chọn tệp nào"
|
||||
renameFile: "Đổi tên tập tin"
|
||||
folderName: "Tên thư mục"
|
||||
createFolder: "Tạo thư mục"
|
||||
|
@ -313,6 +339,7 @@ renameFolder: "Đổi tên thư mục"
|
|||
deleteFolder: "Xóa thư mục"
|
||||
folder: "Thư mục"
|
||||
addFile: "Thêm tập tin"
|
||||
showFile: "Hiển thị tập tin"
|
||||
emptyDrive: "Ổ đĩa của bạn trống trơn"
|
||||
emptyFolder: "Thư mục trống"
|
||||
unableToDelete: "Không thể xóa"
|
||||
|
@ -396,6 +423,7 @@ antennaExcludeBots: "Loại trừ các tài khoản bot"
|
|||
antennaKeywordsDescription: "Phân cách bằng dấu cách cho điều kiện AND hoặc bằng xuống dòng cho điều kiện OR."
|
||||
notifyAntenna: "Thông báo có tút mới"
|
||||
withFileAntenna: "Chỉ những tút có media"
|
||||
excludeNotesInSensitiveChannel: "Không hiển thị trong kênh nhạy cảm"
|
||||
enableServiceworker: "Bật ServiceWorker"
|
||||
antennaUsersDescription: "Liệt kê mỗi hàng một tên người dùng"
|
||||
caseSensitive: "Trường hợp nhạy cảm"
|
||||
|
@ -426,6 +454,7 @@ totpDescription: "Nhắn mã OTP bằng ứng dụng xác thực"
|
|||
moderator: "Kiểm duyệt viên"
|
||||
moderation: "Kiểm duyệt"
|
||||
moderationNote: "Ghi chú kiểm duyệt"
|
||||
moderationNoteDescription: "Bạn có thể điền vào những ghi chú chỉ được chia sẻ giữa những người kiểm duyệt."
|
||||
addModerationNote: "Thêm ghi chú kiểm duyệt"
|
||||
moderationLogs: "Nhật kí quản trị"
|
||||
nUsersMentioned: "Dùng bởi {n} người"
|
||||
|
@ -463,6 +492,7 @@ quoteQuestion: "Trích dẫn lại?"
|
|||
attachAsFileQuestion: "Văn bản ở trong bộ nhớ tạm rất dài. Bạn có muốn đăng nó dưới dạng một tệp văn bản không?"
|
||||
onlyOneFileCanBeAttached: "Bạn chỉ có thể đính kèm một tập tin"
|
||||
signinRequired: "Vui lòng đăng nhập"
|
||||
signinOrContinueOnRemote: "Để tiếp tục, bạn cần chuyển máy chủ hoặc đăng nhập/đăng ký ở máy chủ này."
|
||||
invitations: "Mời"
|
||||
invitationCode: "Mã mời"
|
||||
checking: "Đang kiểm tra..."
|
||||
|
@ -484,7 +514,12 @@ uiLanguage: "Ngôn ngữ giao diện"
|
|||
aboutX: "Giới thiệu {x}"
|
||||
emojiStyle: "Kiểu cách Emoji"
|
||||
native: "Bản xứ"
|
||||
menuStyle: "Kiểu Menu"
|
||||
style: "Phong cách"
|
||||
drawer: "Ngăn ứng dụng"
|
||||
popup: "Cửa sổ bật lên"
|
||||
showNoteActionsOnlyHover: "Chỉ hiển thị các hành động ghi chú khi di chuột"
|
||||
showReactionsCount: "Hiển thị số reaction trong bài đăng"
|
||||
noHistory: "Không có dữ liệu"
|
||||
signinHistory: "Lịch sử đăng nhập"
|
||||
enableAdvancedMfm: "Xem bài MFM chất lượng cao."
|
||||
|
@ -497,6 +532,7 @@ createAccount: "Tạo tài khoản"
|
|||
existingAccount: "Tài khoản hiện có"
|
||||
regenerate: "Tạo lại"
|
||||
fontSize: "Cỡ chữ"
|
||||
mediaListWithOneImageAppearance: "Chiều cao của danh sách nội dung đã phương tiện mà chỉ có một hình ảnh"
|
||||
limitTo: "Giới hạn tỷ lệ {x}"
|
||||
noFollowRequests: "Bạn không có yêu cầu theo dõi nào"
|
||||
openImageInNewTab: "Mở ảnh trong tab mới"
|
||||
|
@ -531,10 +567,12 @@ objectStorageUseSSLDesc: "Tắt nếu bạn không dùng HTTPS để kết nối
|
|||
objectStorageUseProxy: "Kết nối thông qua Proxy"
|
||||
objectStorageUseProxyDesc: "Tắt nếu bạn không dùng Proxy để kết nối API"
|
||||
objectStorageSetPublicRead: "Đặt \"public-read\" khi tải lên"
|
||||
s3ForcePathStyleDesc: "Nếu s3ForcePathStyle được bật, tên bucket phải được thêm vào địa chỉ URL thay vì chỉ có tên miền. Bạn có thể phải sử dụng thiết lập này nếu bạn sử dụng các dịch vụ như Minio mà bạn tự cung cấp."
|
||||
serverLogs: "Nhật ký máy chủ"
|
||||
deleteAll: "Xóa tất cả"
|
||||
showFixedPostForm: "Hiện khung soạn tút ở phía trên bảng tin"
|
||||
showFixedPostFormInChannel: "Hiển thị mẫu bài đăng ở phía trên bản tin"
|
||||
withRepliesByDefaultForNewlyFollowed: "Mặc định hiển thị trả lời từ những người dùng mới theo dõi trong dòng thời gian"
|
||||
newNoteRecived: "Đã nhận tút mới"
|
||||
sounds: "Âm thanh"
|
||||
sound: "Âm thanh"
|
||||
|
@ -545,7 +583,9 @@ popout: "Pop-out"
|
|||
volume: "Âm lượng"
|
||||
masterVolume: "Âm thanh chung"
|
||||
notUseSound: "Tắt tiếng"
|
||||
useSoundOnlyWhenActive: "Chỉ phát âm thanh khi Misskey đang được hiển thị"
|
||||
details: "Chi tiết"
|
||||
renoteDetails: "Tìm hiểu thêm về đăng lại "
|
||||
chooseEmoji: "Chọn emoji"
|
||||
unableToProcess: "Không thể hoàn tất hành động"
|
||||
recentUsed: "Sử dụng gần đây"
|
||||
|
@ -561,6 +601,7 @@ ascendingOrder: "Tăng dần"
|
|||
descendingOrder: "Giảm dần"
|
||||
scratchpad: "Scratchpad"
|
||||
scratchpadDescription: "Scratchpad cung cấp môi trường cho các thử nghiệm AiScript. Bạn có thể viết, thực thi và kiểm tra kết quả tương tác với Misskey trong đó."
|
||||
uiInspector: "Trình kiểm tra UI"
|
||||
output: "Nguồn ra"
|
||||
script: "Kịch bản"
|
||||
disablePagesScript: "Tắt AiScript trên Trang"
|
||||
|
@ -619,6 +660,7 @@ medium: "Vừa"
|
|||
small: "Nhỏ"
|
||||
generateAccessToken: "Tạo mã truy cập"
|
||||
permission: "Cho phép "
|
||||
adminPermission: "Quyền quản trị viên"
|
||||
enableAll: "Bật toàn bộ"
|
||||
disableAll: "Tắt toàn bộ"
|
||||
tokenRequested: "Cấp quyền truy cập vào tài khoản"
|
||||
|
@ -640,13 +682,19 @@ smtpSecure: "Dùng SSL/TLS ngầm định cho các kết nối SMTP"
|
|||
smtpSecureInfo: "Tắt cái này nếu dùng STARTTLS"
|
||||
testEmail: "Kiểm tra vận chuyển email"
|
||||
wordMute: "Ẩn chữ"
|
||||
wordMuteDescription: "Thu nhỏ các bài đăng chứa các từ hoặc cụm từ nhất định. Các bài đăng này có thể được hiển thị khi click vào."
|
||||
hardWordMute: "Ẩn cụm từ hoàn toàn"
|
||||
showMutedWord: "Hiển thị từ đã ẩn"
|
||||
hardWordMuteDescription: "Ẩn hoàn toàn các bài đăng chứa từ hoặc cụm từ. Khác với mute, bài đăng sẽ bị ẩn hoàn toàn."
|
||||
regexpError: "Lỗi biểu thức"
|
||||
regexpErrorDescription: "Xảy ra lỗi biểu thức ở dòng {line} của {tab} chữ ẩn:"
|
||||
instanceMute: "Những máy chủ ẩn"
|
||||
userSaysSomething: "{name} nói gì đó"
|
||||
userSaysSomethingAbout: "{name} đã nói gì đó về \"{word}\""
|
||||
makeActive: "Kích hoạt"
|
||||
display: "Hiển thị"
|
||||
copy: "Sao chép"
|
||||
copiedToClipboard: "Đã sao chép vào clipboard"
|
||||
metrics: "Số liệu"
|
||||
overview: "Tổng quan"
|
||||
logs: "Nhật ký"
|
||||
|
@ -661,12 +709,14 @@ useGlobalSettingDesc: "Nếu được bật, cài đặt thông báo của bạn
|
|||
other: "Khác"
|
||||
regenerateLoginToken: "Tạo lại mã đăng nhập"
|
||||
regenerateLoginTokenDescription: "Tạo lại mã nội bộ có thể dùng để đăng nhập. Thông thường hành động này là không cần thiết. Nếu được tạo lại, tất cả các thiết bị sẽ bị đăng xuất."
|
||||
theKeywordWhenSearchingForCustomEmoji: "Đây là từ khoá được sử dụng để tìm kiếm emoji"
|
||||
setMultipleBySeparatingWithSpace: "Tách nhiều mục nhập bằng dấu cách."
|
||||
fileIdOrUrl: "ID tập tin hoặc URL"
|
||||
behavior: "Thao tác"
|
||||
sample: "Ví dụ"
|
||||
abuseReports: "Lượt báo cáo"
|
||||
reportAbuse: "Báo cáo"
|
||||
reportAbuseRenote: "Báo cáo bài đăng lại"
|
||||
reportAbuseOf: "Báo cáo {name}"
|
||||
fillAbuseReportDescription: "Vui lòng điền thông tin chi tiết về báo cáo này. Nếu đó là về một tút cụ thể, hãy kèm theo URL của tút."
|
||||
abuseReported: "Báo cáo đã được gửi. Cảm ơn bạn nhiều."
|
||||
|
@ -716,6 +766,7 @@ lockedAccountInfo: "Ghi chú của bạn sẽ hiển thị với bất kỳ ai,
|
|||
alwaysMarkSensitive: "Luôn đánh dấu NSFW"
|
||||
loadRawImages: "Tải ảnh gốc thay vì ảnh thu nhỏ"
|
||||
disableShowingAnimatedImages: "Không phát ảnh động"
|
||||
highlightSensitiveMedia: "Đánh dấu nội dung nhạy cảm"
|
||||
verificationEmailSent: "Một email xác minh đã được gửi. Vui lòng nhấn vào liên kết đính kèm để hoàn tất xác minh."
|
||||
notSet: "Chưa đặt"
|
||||
emailVerified: "Email đã được xác minh"
|
||||
|
@ -731,7 +782,6 @@ thisIsExperimentalFeature: "Tính năng này đang trong quá trình thử nghi
|
|||
developer: "Nhà phát triển"
|
||||
makeExplorable: "Không hiện tôi trong \"Khám phá\""
|
||||
makeExplorableDescription: "Nếu bạn tắt, tài khoản của bạn sẽ không hiện trong mục \"Khám phá\"."
|
||||
showGapBetweenNotesInTimeline: "Hiện dải phân cách giữa các tút trên bảng tin"
|
||||
duplicate: "Tạo bản sao"
|
||||
left: "Bên trái"
|
||||
center: "Giữa"
|
||||
|
@ -809,6 +859,7 @@ administration: "Quản lý"
|
|||
accounts: "Tài khoản của bạn"
|
||||
switch: "Chuyển đổi"
|
||||
noMaintainerInformationWarning: "Chưa thiết lập thông tin vận hành."
|
||||
noInquiryUrlWarning: "Địa chỉ hỏi đáp chưa được đặt"
|
||||
noBotProtectionWarning: "Bảo vệ Bot chưa thiết lập."
|
||||
configure: "Thiết lập"
|
||||
postToGallery: "Tạo tút có ảnh"
|
||||
|
@ -873,6 +924,7 @@ followersVisibility: "Hiển thị người theo dõi"
|
|||
continueThread: "Tiếp tục xem chuỗi tút"
|
||||
deleteAccountConfirm: "Điều này sẽ khiến tài khoản bị xóa vĩnh viễn. Vẫn tiếp tục?"
|
||||
incorrectPassword: "Sai mật khẩu."
|
||||
incorrectTotp: "Mã OTP không đúng hoặc đã quá hạn"
|
||||
voteConfirm: "Xác nhận bình chọn \"{choice}\"?"
|
||||
hide: "Ẩn"
|
||||
useDrawerReactionPickerForMobile: "Hiện bộ chọn biểu cảm dạng xổ ra trên điện thoại"
|
||||
|
@ -897,6 +949,9 @@ oneHour: "1 giờ"
|
|||
oneDay: "1 ngày"
|
||||
oneWeek: "1 tuần"
|
||||
oneMonth: "1 tháng"
|
||||
threeMonths: "3 tháng"
|
||||
oneYear: "1 năm"
|
||||
threeDays: "3 ngày "
|
||||
reflectMayTakeTime: "Có thể mất một thời gian để điều này được áp dụng."
|
||||
failedToFetchAccountInformation: "Không thể lấy thông tin tài khoản"
|
||||
rateLimitExceeded: "Giới hạn quá mức"
|
||||
|
@ -921,6 +976,7 @@ document: "Tài liệu"
|
|||
numberOfPageCache: "Số lượng trang bộ nhớ đệm"
|
||||
numberOfPageCacheDescription: "Việc tăng con số này sẽ cải thiện sự thuận tiện cho người dùng nhưng gây ra nhiều áp lực hơn cho máy chủ cũng như sử dụng nhiều bộ nhớ hơn."
|
||||
logoutConfirm: "Bạn có chắc muốn đăng xuất?"
|
||||
logoutWillClearClientData: "Đăng xuất sẽ xoá các thiết lập của bạn khỏi trình duyệt. Để có thể khôi phục thiết lập khi đăng nhập lại, bạn phải bật tự động sao lưu cài đặt."
|
||||
lastActiveDate: "Lần cuối vào"
|
||||
statusbar: "Thanh trạng thái"
|
||||
pleaseSelect: "Chọn một lựa chọn"
|
||||
|
@ -970,6 +1026,7 @@ neverShow: "Không hiển thị nữa"
|
|||
remindMeLater: "Để sau"
|
||||
didYouLikeMisskey: "Bạn có ưa thích Mískey không?"
|
||||
pleaseDonate: "Misskey là phần mềm miễn phí mà {host} đang sử dụng. Xin mong bạn quyên góp cho chúng tôi để chúng tôi có thể tiếp tục phát triển dịch vụ này. Xin cảm ơn!!"
|
||||
correspondingSourceIsAvailable: "Mã nguồn có thể được xem tại {anchor}"
|
||||
roles: "Vai trò"
|
||||
role: "Vai trò"
|
||||
noRole: "Bạn chưa được cấp quyền."
|
||||
|
@ -997,23 +1054,41 @@ thisPostMayBeAnnoyingHome: "Đăng trên trang chính"
|
|||
thisPostMayBeAnnoyingCancel: "Từ chối"
|
||||
thisPostMayBeAnnoyingIgnore: "Đăng bài để nguyên"
|
||||
collapseRenotes: "Không hiển thị bài viết đã từng xem"
|
||||
collapseRenotesDescription: "Các bài đăng bị thu gọn mà bạn đã phản hồi hoặc đăng lại trước đây."
|
||||
internalServerError: "Lỗi trong chủ máy"
|
||||
internalServerErrorDescription: "Trong chủ máy lỗi bất ngờ xảy ra"
|
||||
copyErrorInfo: "Sao chép thông tin lỗi"
|
||||
joinThisServer: "Đăng ký trên chủ máy này"
|
||||
exploreOtherServers: "Tìm chủ máy khác"
|
||||
letsLookAtTimeline: "Thử xem Timeline"
|
||||
disableFederationConfirm: "Bạn có muốn làm điều đó mà không cần liên minh không?"
|
||||
disableFederationConfirmWarn: "Ngay cả khi bị trì hoãn, bài đăng vẫn sẽ tiếp tục là công khai trừ khi được thiết lập khác. Bạn thường không cần phải làm điều này."
|
||||
disableFederationOk: "Vô hiệu hoá"
|
||||
invitationRequiredToRegister: "Phiên bản này chỉ dành cho người được mời. Bạn phải nhập mã mời hợp lệ để đăng ký."
|
||||
emailNotSupported: "Máy chủ này không hỗ trợ gửi email"
|
||||
postToTheChannel: "Đăng lên kênh"
|
||||
cannotBeChangedLater: "Không thể thay đổi sau này."
|
||||
reactionAcceptance: "Phản ứng chấp nhận"
|
||||
likeOnly: "Chỉ lượt thích"
|
||||
likeOnlyForRemote: "Tất cả (chỉ bao gồm lượt thích trên các máy chủ khác)"
|
||||
nonSensitiveOnly: "Chỉ nội dung không nhạy cảm"
|
||||
nonSensitiveOnlyForLocalLikeOnlyForRemote: "Chỉ nội dung không nhạy cảm (chỉ bao gồm lượt thích từ máy chủ khác)"
|
||||
rolesAssignedToMe: "Vai trò được giao cho tôi"
|
||||
resetPasswordConfirm: "Bạn thực sự muốn đặt lại mật khẩu?"
|
||||
sensitiveWords: "Các từ nhạy cảm"
|
||||
sensitiveWordsDescription: "Phạm vi của tất cả bài đăng chứa các từ được cấu hình sẽ tự động được đặt về \"Home\". Ban có thể thêm nhiều từ trên mỗi dòng."
|
||||
sensitiveWordsDescription2: "Sử dụng dấu cách sẽ tạo cấu trúc AND và thêm dấu gạch xuôi để sử dụng như một regex."
|
||||
prohibitedWords: "Các từ bị cấm"
|
||||
prohibitedWordsDescription: "Hiển thị lỗi khi đăng một bài đăng chứa các từ sau. Nhiều từ có thể được thêm bằng cách viết một từ trên mỗi dòng."
|
||||
prohibitedWordsDescription2: "Sử dụng dấu cách sẽ tạo cấu trúc AND và thêm dấu gạch xuôi để sử dụng như một regex."
|
||||
hiddenTags: "Hashtag ẩn"
|
||||
hiddenTagsDescription: "Các hashtag này sẽ không được hiển thị trên danh sách Trending. Nhiều tag có thể được thêm bằng cách viết một tag trên mỗi dòng."
|
||||
notesSearchNotAvailable: "Tìm kiếm bài đăng hiện không khả dụng."
|
||||
license: "Giấy phép"
|
||||
unfavoriteConfirm: "Bạn thực sự muốn xoá khỏi mục yêu thích?"
|
||||
myClips: "Các clip của tôi"
|
||||
drivecleaner: "Trình dọn đĩa"
|
||||
retryAllQueuesNow: "Thử lại cho tất cả hàng chờ"
|
||||
retryAllQueuesConfirmTitle: "Bạn có muốn thử lại?"
|
||||
retryAllQueuesConfirmText: "Điều này sẽ tạm thời làm tăng mức độ tải của máy chủ."
|
||||
enableChartsForRemoteUser: "Tạo biểu đồ người dùng từ xa"
|
||||
|
@ -1049,6 +1124,8 @@ options: "Tùy chọn"
|
|||
specifyUser: "Người dùng chỉ định"
|
||||
failedToPreviewUrl: "Không thể xem trước"
|
||||
update: "Cập nhật"
|
||||
cancelReactionConfirm: "Bạn có muốn hủy phản ứng của mình không?"
|
||||
changeReactionConfirm: "Bạn có muốn thay đổi phản ứng của mình không?"
|
||||
later: "Để sau"
|
||||
goToMisskey: "Tới Misskey"
|
||||
installed: "Đã tải xuống"
|
||||
|
@ -1097,6 +1174,7 @@ mutualFollow: "Theo dõi lẫn nhau"
|
|||
followingOrFollower: "Đang theo dõi hoặc người theo dõi"
|
||||
externalServices: "Các dịch vụ bên ngoài"
|
||||
sourceCode: "Mã nguồn"
|
||||
repositoryUrlDescription: "Nếu bạn có kho lưu trữ mã nguồn có thể truy cập công khai, hãy nhập URL. Nếu bạn đang sử dụng Misskey theo mặc định (không thực hiện bất kỳ thay đổi nào đối với mã nguồn), hãy nhập https://github.com/misskey-dev/misskey."
|
||||
feedback: "Phản hồi"
|
||||
feedbackUrl: "URL phản hồi"
|
||||
privacyPolicy: "Chính sách bảo mật"
|
||||
|
@ -1113,8 +1191,18 @@ releaseToRefresh: "Thả để làm mới"
|
|||
refreshing: "Đang làm mới"
|
||||
pullDownToRefresh: "Kéo xuống để làm mới"
|
||||
cwNotationRequired: "Nếu \"Ẩn nội dung\" được bật thì cần phải có chú thích."
|
||||
decorate: "Trang trí"
|
||||
lastNDays: "{n} ngày trước"
|
||||
userSaysSomethingSensitive: "Bài đăng có chứa các tập tin nhạy cảm từ {name}"
|
||||
surrender: "Từ chối"
|
||||
signinWithPasskey: "Đăng nhập bằng mật khẩu của bạn"
|
||||
passkeyVerificationFailed: "Xác minh mật khẩu không thành công."
|
||||
messageToFollower: "Tin nhắn cho người theo dõi"
|
||||
yourNameContainsProhibitedWords: "Tên bạn đang cố gắng đổi có chứa chuỗi ký tự bị cấm."
|
||||
yourNameContainsProhibitedWordsDescription: "Tên có chứa chuỗi ký tự bị cấm. Nếu bạn muốn sử dụng tên này, hãy liên hệ với quản trị viên máy chủ của bạn."
|
||||
federationDisabled: "Liên kết bị vô hiệu hóa trên máy chủ này. Bạn không thể tương tác với người dùng trên các máy chủ khác."
|
||||
reactAreYouSure: "Bạn có muốn phản hồi với \" {emoji} \" không?"
|
||||
paste: "dán"
|
||||
postForm: "Mẫu đăng"
|
||||
information: "Giới thiệu"
|
||||
_chat:
|
||||
|
@ -1123,6 +1211,9 @@ _chat:
|
|||
members: "Thành viên"
|
||||
home: "Trang chính"
|
||||
send: "Gửi"
|
||||
_accountSettings:
|
||||
requireSigninToViewContents: "Yêu cầu đăng nhập để xem nội dung"
|
||||
requireSigninToViewContentsDescription1: "Yêu cầu đăng nhập để xem tất cả ghi chú và nội dung khác mà bạn tạo. Điều này được kỳ vọng sẽ có hiệu quả trong việc ngăn chặn thông tin bị thu thập bởi các trình thu thập thông tin."
|
||||
_delivery:
|
||||
stop: "Đã vô hiệu hóa"
|
||||
_type:
|
||||
|
@ -1146,8 +1237,33 @@ _initialAccountSetting:
|
|||
pushNotificationDescription: "Bật thông báo đẩy sẽ cho phép bạn nhận thông báo từ {name} trực tiếp từ thiết bị của bạn."
|
||||
initialAccountSettingCompleted: "Thiết lập tài khoản thành công!"
|
||||
haveFun: "Hãy tận hưởng {name} nhé!"
|
||||
youCanContinueTutorial: "Bạn có thể tiếp tục xem hướng dẫn về cách sử dụng {name} (Misskey) hoặc bạn có thể thoát khỏi phần thiết lập tại đây và bắt đầu sử dụng ngay lập tức."
|
||||
startTutorial: "Bắt đầu hướng dẫn"
|
||||
skipAreYouSure: "Bạn thực sự muốn bỏ qua mục thiết lập tài khoản?"
|
||||
laterAreYouSure: "Bạn thực sự muốn thiết lập tài khoản vào lúc khác?"
|
||||
_initialTutorial:
|
||||
launchTutorial: "Bắt đầu hướng dẫn"
|
||||
title: "Hướng dẫn"
|
||||
wellDone: "Làm tốt!"
|
||||
skipAreYouSure: "Thoát khỏi hướng dẫn?"
|
||||
_landing:
|
||||
title: "Chào mừng đến với Hướng dẫn"
|
||||
description: "Tại đây, bạn có thể tìm hiểu những điều cơ bản về cách sử dụng Misskey và các tính năng của nó."
|
||||
_note:
|
||||
title: "Bài Viết là gì?"
|
||||
description: "Các bài đăng trên Misskey được gọi là 'Bài Viết'. Ghi chú được sắp xếp theo thứ tự thời gian trên dòng thời gian và được cập nhật theo thời gian thực."
|
||||
_timeline:
|
||||
home: "Bạn có thể xem ghi chú từ những tài khoản bạn theo dõi."
|
||||
local: "Bạn có thể xem ghi chú từ tất cả người dùng trên máy chủ này."
|
||||
social: "Ghi chú từ dòng thời gian Trang chủ và Địa phương sẽ được hiển thị."
|
||||
global: "Bạn có thể xem ghi chú từ tất cả các máy chủ được kết nối."
|
||||
_postNote:
|
||||
_visibility:
|
||||
home: "Chỉ công khai trên dòng thời gian Trang chủ. Những người truy cập trang cá nhân của bạn, thông qua người theo dõi và thông qua ghi chú lại có thể thấy thông tin đó."
|
||||
_timelineDescription:
|
||||
home: "Trong dòng thời gian Trang chính, bạn có thể xem ghi chú từ các tài khoản bạn theo dõi."
|
||||
local: "Trong dòng thời gian cục bộ, bạn có thể xem ghi chú từ tất cả người dùng trên máy chủ này."
|
||||
social: "Dòng thời gian Xã hội hiển thị các ghi chú từ cả dòng thời gian Trang chủ và Địa phương."
|
||||
_serverSettings:
|
||||
iconUrl: "Biểu tượng URL"
|
||||
appIconResolutionMustBe: "Độ phân giải tối thiểu là {resolution}."
|
||||
|
@ -1308,7 +1424,7 @@ _achievements:
|
|||
_postedAt0min0sec:
|
||||
title: "Tín hiệu báo giờ"
|
||||
description: "Đăng bài vào 0 phút 0 giây"
|
||||
flavor: "Piiiiiii ĐÂY LÀ TIẾNG NÓI VIỆT NAM"
|
||||
flavor: "Pin pop pop pop"
|
||||
_selfQuote:
|
||||
title: "Nói đến bản thân"
|
||||
description: "Trích dẫn bài viết của mình"
|
||||
|
@ -1530,7 +1646,6 @@ _theme:
|
|||
header: "Ảnh bìa"
|
||||
navBg: "Nền thanh bên"
|
||||
navFg: "Chữ thanh bên"
|
||||
navHoverFg: "Chữ thanh bên (Khi chạm)"
|
||||
navActive: "Chữ thanh bên (Khi chọn)"
|
||||
navIndicator: "Chỉ báo thanh bên"
|
||||
link: "Đường dẫn"
|
||||
|
@ -1553,11 +1668,8 @@ _theme:
|
|||
buttonHoverBg: "Nền nút (Chạm)"
|
||||
inputBorder: "Đường viền khung soạn thảo"
|
||||
driveFolderBg: "Nền thư mục Ổ đĩa"
|
||||
wallpaperOverlay: "Lớp phủ hình nền"
|
||||
badge: "Huy hiệu"
|
||||
messageBg: "Nền chat"
|
||||
accentDarken: "Màu phụ (Tối)"
|
||||
accentLighten: "Màu phụ (Sáng)"
|
||||
fgHighlighted: "Chữ nổi bật"
|
||||
_sfx:
|
||||
note: "Tút"
|
||||
|
@ -1927,11 +2039,21 @@ _abuseReport:
|
|||
_recipientType:
|
||||
mail: "Email"
|
||||
_moderationLogTypes:
|
||||
createRole: "Tạo một vai trò"
|
||||
deleteRole: "Xóa vai trò"
|
||||
updateRole: "Cập nhật vai trò"
|
||||
assignRole: "Chỉ định cho vai trò"
|
||||
unassignRole: "Bỏ gán vai trò"
|
||||
suspend: "Vô hiệu hóa"
|
||||
unsuspend: "Rã đông"
|
||||
resetPassword: "Đặt lại mật khẩu"
|
||||
createInvitation: "Tạo lời mời"
|
||||
_reversi:
|
||||
total: "Tổng cộng"
|
||||
_customEmojisManager:
|
||||
_local:
|
||||
_list:
|
||||
confirmDeleteEmojisDescription: "Xóa các biểu tượng cảm xúc {count} đã chọn. Bạn có muốn chạy nó không?"
|
||||
_remoteLookupErrors:
|
||||
_noSuchObject:
|
||||
title: "Không tìm thấy"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "静音此服务器"
|
|||
mediaSilenceThisInstance: "隐藏此服务器的媒体文件"
|
||||
operations: "操作"
|
||||
software: "软件"
|
||||
softwareName: "软件名"
|
||||
version: "版本"
|
||||
metadata: "元数据"
|
||||
withNFiles: "{n} 个文件"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "无用户"
|
|||
editProfile: "编辑资料"
|
||||
noteDeleteConfirm: "确定要删除该帖子吗?"
|
||||
pinLimitExceeded: "无法置顶更多了"
|
||||
intro: "Misskey 的部署结束啦!创建管理员账号吧!"
|
||||
done: "完成"
|
||||
processing: "正在处理"
|
||||
preview: "预览"
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "排除机器人账户"
|
|||
antennaKeywordsDescription: "AND 条件用空格分隔,OR 条件用换行符分隔。"
|
||||
notifyAntenna: "开启通知"
|
||||
withFileAntenna: "仅带有附件的帖子"
|
||||
excludeNotesInSensitiveChannel: "排除敏感频道内的帖子"
|
||||
enableServiceworker: "启用 ServiceWorker"
|
||||
antennaUsersDescription: "指定用户名,一行一个"
|
||||
caseSensitive: "区分大小写"
|
||||
|
@ -783,7 +784,6 @@ thisIsExperimentalFeature: "这是一项实验性功能。规范可能会变更
|
|||
developer: "开发者"
|
||||
makeExplorable: "使账号可见。"
|
||||
makeExplorableDescription: "关闭时,账号不会显示在\"发现\"中。"
|
||||
showGapBetweenNotesInTimeline: "时间线上的帖子分开显示。"
|
||||
duplicate: "复制"
|
||||
left: "左"
|
||||
center: "中央"
|
||||
|
@ -978,6 +978,7 @@ document: "文档"
|
|||
numberOfPageCache: "缓存页数"
|
||||
numberOfPageCacheDescription: "设置较高的值会更方便用户,但设备的负载和内存使用量会增加。"
|
||||
logoutConfirm: "是否确认登出?"
|
||||
logoutWillClearClientData: "登出时将会从浏览器中删除客户端的设置信息。如果想要在再次登入时恢复设置信息,请在设置里打开自动备份。"
|
||||
lastActiveDate: "最后活跃时间"
|
||||
statusbar: "状态栏"
|
||||
pleaseSelect: "请选择"
|
||||
|
@ -1235,7 +1236,6 @@ showAvatarDecorations: "显示头像挂件"
|
|||
releaseToRefresh: "松开以刷新"
|
||||
refreshing: "刷新中"
|
||||
pullDownToRefresh: "下拉以刷新"
|
||||
disableStreamingTimeline: "禁止实时更新时间线"
|
||||
useGroupedNotifications: "分组显示通知"
|
||||
signupPendingError: "确认电子邮件时出现错误。链接可能已过期。"
|
||||
cwNotationRequired: "在启用「隐藏内容」时必须输入注释"
|
||||
|
@ -1336,6 +1336,16 @@ chat: "聊天"
|
|||
migrateOldSettings: "迁移旧设置信息"
|
||||
migrateOldSettings_description: "通常设置信息将自动迁移。但如果由于某种原因迁移不成功,则可以手动触发迁移过程。当前的配置信息将被覆盖。"
|
||||
compress: "压缩"
|
||||
right: "右"
|
||||
bottom: "下"
|
||||
top: "上"
|
||||
embed: "嵌入"
|
||||
settingsMigrating: "正在迁移设置,请稍候。(之后也可以在设置 → 其它 → 迁移旧设置来手动迁移)"
|
||||
readonly: "只读"
|
||||
goToDeck: "返回至 Deck"
|
||||
federationJobs: "联合作业"
|
||||
driveAboutTip: "网盘可以显示以前上传的文件。<br>\n也可以在发布帖子时重复使用文件,或在发布帖子前预先上传文件。<br>\n<b>删除文件时,其将从至今为止所有用到该文件的地方(如帖子、页面、头像、横幅)消失。</b><br>\n也可以新建文件夹来整理文件。"
|
||||
scrollToClose: "滑动并关闭"
|
||||
_chat:
|
||||
noMessagesYet: "还没有消息"
|
||||
newMessage: "新消息"
|
||||
|
@ -1365,6 +1375,7 @@ _chat:
|
|||
muteThisRoom: "静音此房间"
|
||||
deleteRoom: "删除房间"
|
||||
chatNotAvailableForThisAccountOrServer: "此服务器或者账户还未开启聊天功能。"
|
||||
chatIsReadOnlyForThisAccountOrServer: "此服务器或者账户内的聊天为只读。无法发布新信息或创建及加入群聊。"
|
||||
chatNotAvailableInOtherAccount: "对方账户目前处于无法使用聊天的状态。"
|
||||
cannotChatWithTheUser: "无法与此用户聊天"
|
||||
cannotChatWithTheUser_description: "可能现在无法使用聊天,或者对方未开启聊天。"
|
||||
|
@ -1410,6 +1421,8 @@ _settings:
|
|||
showNavbarSubButtons: "在导航栏中显示副按钮"
|
||||
ifOn: "启用时"
|
||||
ifOff: "关闭时"
|
||||
enablePullToRefresh: "开启下拉刷新"
|
||||
enablePullToRefresh_description: "使用鼠标时按下滚轮来拖动"
|
||||
_chat:
|
||||
showSenderName: "显示发送者的名字"
|
||||
sendOnEnter: "回车键发送"
|
||||
|
@ -1417,6 +1430,7 @@ _preferencesProfile:
|
|||
profileName: "配置名"
|
||||
profileNameDescription: "请指定用于识别此设备的名称"
|
||||
profileNameDescription2: "如「PC」、「手机」等"
|
||||
manageProfiles: "管理配置文件"
|
||||
_preferencesBackup:
|
||||
autoBackup: "自动备份"
|
||||
restoreFromBackup: "从备份恢复"
|
||||
|
@ -1455,6 +1469,7 @@ _delivery:
|
|||
manuallySuspended: "手动停止中"
|
||||
goneSuspended: "因服务器被删除而停止"
|
||||
autoSuspendedForNotResponding: "因服务器无应答而停止"
|
||||
softwareSuspended: "因有不可用的软件而停止"
|
||||
_bubbleGame:
|
||||
howToPlay: "游戏说明"
|
||||
hold: "抓住"
|
||||
|
@ -1586,6 +1601,7 @@ _serverSettings:
|
|||
openRegistration: "开放注册"
|
||||
openRegistrationWarning: "开放注册有风险。建议仅当能够持续监控服务器并在出现问题时能够立即响应时才打开它。"
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "若在一段时间内没有检测到管理活动,为防止垃圾信息,此设定将自动关闭。"
|
||||
deliverSuspendedSoftware: "不可用的软件"
|
||||
_accountMigration:
|
||||
moveFrom: "从别的账号迁移到此账户"
|
||||
moveFromSub: "为另一个账户建立别名"
|
||||
|
@ -1882,6 +1898,8 @@ _role:
|
|||
descriptionOfIsExplorable: "打开后将公开角色时间线。如果角色不是公开的,就无法公开时间线。"
|
||||
displayOrder: "显示顺序"
|
||||
descriptionOfDisplayOrder: "数字越大,显示位置越靠前。"
|
||||
preserveAssignmentOnMoveAccount: "将分配状态继承到目标账户"
|
||||
preserveAssignmentOnMoveAccount_description: "启用后,当迁移具有该角色的账户时,目标账户也会继承该角色。"
|
||||
canEditMembersByModerator: "允许监察员编辑成员"
|
||||
descriptionOfCanEditMembersByModerator: "如果选中,监察员和管理员都能够为用户分配/取消分配角色。如果未选中,则只有管理员可以执行此操作。"
|
||||
priority: "优先级"
|
||||
|
@ -1901,6 +1919,7 @@ _role:
|
|||
canManageCustomEmojis: "管理自定义表情符号"
|
||||
canManageAvatarDecorations: "管理头像挂件"
|
||||
driveCapacity: "网盘容量"
|
||||
maxFileSize: "可上传的最大文件大小"
|
||||
alwaysMarkNsfw: "总是将文件标记为 NSFW"
|
||||
canUpdateBioMedia: "可以更新头像和横幅"
|
||||
pinMax: "帖子置顶数量限制"
|
||||
|
@ -1922,7 +1941,7 @@ _role:
|
|||
canImportFollowing: "允许导入关注列表"
|
||||
canImportMuting: "允许导入隐藏列表"
|
||||
canImportUserLists: "允许导入用户列表"
|
||||
canChat: "允许聊天"
|
||||
chatAvailability: "允许聊天"
|
||||
_condition:
|
||||
roleAssignedTo: "已分配给手动角色"
|
||||
isLocal: "是本地用户"
|
||||
|
@ -2119,7 +2138,6 @@ _theme:
|
|||
header: "顶栏"
|
||||
navBg: "侧边栏背景"
|
||||
navFg: "侧栏文本"
|
||||
navHoverFg: "侧栏文本(悬停)"
|
||||
navActive: "侧栏文本(活动)"
|
||||
navIndicator: "侧栏标记"
|
||||
link: "链接"
|
||||
|
@ -2142,11 +2160,8 @@ _theme:
|
|||
buttonHoverBg: "按钮背景(悬停)"
|
||||
inputBorder: "输入框边框"
|
||||
driveFolderBg: "网盘的文件夹背景"
|
||||
wallpaperOverlay: "壁纸叠加层"
|
||||
badge: "徽章"
|
||||
messageBg: "聊天背景"
|
||||
accentDarken: "强调色(深)"
|
||||
accentLighten: "强调色(浅)"
|
||||
fgHighlighted: "高亮显示文本"
|
||||
_sfx:
|
||||
note: "帖子"
|
||||
|
@ -2360,6 +2375,7 @@ _widgets:
|
|||
chooseList: "选择列表"
|
||||
clicker: "点击器"
|
||||
birthdayFollowings: "今天是他们的生日"
|
||||
chat: "聊天"
|
||||
_cw:
|
||||
hide: "隐藏"
|
||||
show: "查看更多"
|
||||
|
@ -2593,6 +2609,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "总是显示主列"
|
||||
columnAlign: "列对齐"
|
||||
columnGap: "列间距"
|
||||
deckMenuPosition: "Deck 菜单位置"
|
||||
navbarPosition: "导航栏位置"
|
||||
addColumn: "添加列"
|
||||
newNoteNotificationSettings: "新帖子通知设定"
|
||||
configureColumn: "列设置"
|
||||
|
@ -2606,7 +2625,7 @@ _deck:
|
|||
newProfile: "新建配置文件"
|
||||
deleteProfile: "删除配置文件"
|
||||
introduction: "将各列进行组合以创建您自己的界面!"
|
||||
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
|
||||
introduction2: "可以随时通过屏幕右侧的 + 来添加列"
|
||||
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"
|
||||
useSimpleUiForNonRootPages: "用简易UI表示非根页面"
|
||||
usedAsMinWidthWhenFlexible: "「自适应宽度」被启用的时候,这就是最小的宽度"
|
||||
|
@ -2623,6 +2642,7 @@ _deck:
|
|||
mentions: "提及"
|
||||
direct: "指定用户"
|
||||
roleTimeline: "角色时间线"
|
||||
chat: "聊天"
|
||||
_dialog:
|
||||
charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}"
|
||||
charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "禁言此伺服器"
|
|||
mediaSilenceThisInstance: "將這個伺服器的媒體設為禁言"
|
||||
operations: "操作"
|
||||
software: "軟體"
|
||||
softwareName: "軟體名稱"
|
||||
version: "版本"
|
||||
metadata: "詮釋資料"
|
||||
withNFiles: "{n} 個檔案"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "沒有任何使用者"
|
|||
editProfile: "編輯個人檔案"
|
||||
noteDeleteConfirm: "確定刪除此貼文嗎?"
|
||||
pinLimitExceeded: "不能置頂更多貼文了"
|
||||
intro: "Misskey 部署完成!請建立管理員帳戶。"
|
||||
done: "完成"
|
||||
processing: "處理中"
|
||||
preview: "預覽"
|
||||
|
@ -424,6 +424,7 @@ antennaExcludeBots: "排除機器人帳戶"
|
|||
antennaKeywordsDescription: "空格代表「以及」(AND),換行代表「或者」(OR)"
|
||||
notifyAntenna: "通知有新貼文"
|
||||
withFileAntenna: "僅帶有附件的貼文"
|
||||
excludeNotesInSensitiveChannel: "排除敏感頻道的貼文"
|
||||
enableServiceworker: "啟用瀏覽器的推播通知"
|
||||
antennaUsersDescription: "填寫使用者名稱,以換行分隔"
|
||||
caseSensitive: "區分大小寫"
|
||||
|
@ -783,7 +784,6 @@ thisIsExperimentalFeature: "這是一項實驗性功能,其行為會隨需要
|
|||
developer: "開發者"
|
||||
makeExplorable: "使自己的帳戶更容易被找到"
|
||||
makeExplorableDescription: "如果關閉,帳戶將不會被顯示在「探索」頁面中。"
|
||||
showGapBetweenNotesInTimeline: "分開顯示時間軸上的貼文"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "置中"
|
||||
|
@ -978,6 +978,7 @@ document: "文件"
|
|||
numberOfPageCache: "快取頁面數"
|
||||
numberOfPageCacheDescription: "增加數量會提高便利性,但也會增加負荷與記憶體使用量。"
|
||||
logoutConfirm: "確定要登出嗎?"
|
||||
logoutWillClearClientData: "當您登出時,客戶端的設定資訊將從瀏覽器中清除。為了能夠在重新登入時恢復您的設定資訊,請啟用設定內的自動備份選項。"
|
||||
lastActiveDate: "上次使用日期及時間"
|
||||
statusbar: "狀態列"
|
||||
pleaseSelect: "請選擇"
|
||||
|
@ -1235,7 +1236,6 @@ showAvatarDecorations: "顯示頭像裝飾"
|
|||
releaseToRefresh: "放開以更新內容"
|
||||
refreshing: "載入更新中"
|
||||
pullDownToRefresh: "往下拉來更新內容"
|
||||
disableStreamingTimeline: "停用時間軸的即時更新"
|
||||
useGroupedNotifications: "分組顯示通知訊息"
|
||||
signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。"
|
||||
cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。"
|
||||
|
@ -1307,7 +1307,7 @@ availableRoles: "可用角色"
|
|||
acknowledgeNotesAndEnable: "了解注意事項後再開啟。"
|
||||
federationSpecified: "此伺服器以白名單聯邦的方式運作。除了管理員指定的伺服器外,它無法與其他伺服器互動。"
|
||||
federationDisabled: "此伺服器未開啟站台聯邦。無法與其他伺服器上的使用者互動。"
|
||||
confirmOnReact: "反應時確認"
|
||||
confirmOnReact: "在做出反應前先確認"
|
||||
reactAreYouSure: "用「 {emoji} 」反應嗎?"
|
||||
markAsSensitiveConfirm: "要將這個媒體設定為敏感嗎?"
|
||||
unmarkAsSensitiveConfirm: "要解除這個媒體的敏感設定嗎?"
|
||||
|
@ -1336,6 +1336,16 @@ chat: "聊天"
|
|||
migrateOldSettings: "遷移舊設定資訊"
|
||||
migrateOldSettings_description: "通常情況下,這會自動進行,但若因某些原因未能順利遷移,您可以手動觸發遷移處理。請注意,當前的設定資訊將會被覆寫。"
|
||||
compress: "壓縮"
|
||||
right: "右"
|
||||
bottom: "下"
|
||||
top: "上"
|
||||
embed: "嵌入"
|
||||
settingsMigrating: "正在移轉設定。請稍候……(之後也可以到「設定 → 其他 → 舊設定資訊移轉」中手動進行移轉)"
|
||||
readonly: "唯讀"
|
||||
goToDeck: "回去甲板"
|
||||
federationJobs: "聯邦通訊作業"
|
||||
driveAboutTip: "在「雲端硬碟」中,會顯示過去上傳的檔案列表。<br>\n可以在附加到貼文時重新利用,或者事先上傳之後再用於發布。<br>\n<b>請注意,刪除檔案後,之前使用過該檔案的所有地方(貼文、頁面、大頭貼、橫幅等)也會一併無法顯示。</b><br>\n也可以建立資料夾來整理檔案。"
|
||||
scrollToClose: "用滾輪關閉"
|
||||
_chat:
|
||||
noMessagesYet: "尚無訊息"
|
||||
newMessage: "新訊息"
|
||||
|
@ -1365,6 +1375,7 @@ _chat:
|
|||
muteThisRoom: "此聊天室已靜音"
|
||||
deleteRoom: "刪除聊天室"
|
||||
chatNotAvailableForThisAccountOrServer: "這個伺服器或這個帳號的聊天功能尚未啟用。"
|
||||
chatIsReadOnlyForThisAccountOrServer: "在此伺服器或此帳戶上的聊天是唯讀的。您無法發布新訊息、建立或加入聊天室。"
|
||||
chatNotAvailableInOtherAccount: "對方的帳號無法使用聊天功能。"
|
||||
cannotChatWithTheUser: "無法與此使用者聊天"
|
||||
cannotChatWithTheUser_description: "聊天功能目前無法使用,或對方尚未開放聊天功能。"
|
||||
|
@ -1410,6 +1421,9 @@ _settings:
|
|||
showNavbarSubButtons: "在導覽列顯示輔助按鈕"
|
||||
ifOn: "開啟時"
|
||||
ifOff: "關閉時"
|
||||
enableSyncThemesBetweenDevices: "在裝置之間同步已安裝的主題"
|
||||
enablePullToRefresh: "下拉更新"
|
||||
enablePullToRefresh_description: "使用滑鼠,按下並拖曳滾輪。"
|
||||
_chat:
|
||||
showSenderName: "顯示發送者的名稱"
|
||||
sendOnEnter: "按下 Enter 發送訊息"
|
||||
|
@ -1417,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "設定檔案名稱"
|
||||
profileNameDescription: "設定一個名稱來識別此裝置。"
|
||||
profileNameDescription2: "例如:「主要個人電腦」、「智慧型手機」等"
|
||||
manageProfiles: "管理個人檔案"
|
||||
_preferencesBackup:
|
||||
autoBackup: "自動備份"
|
||||
restoreFromBackup: "從備份還原"
|
||||
|
@ -1429,14 +1444,14 @@ _preferencesBackup:
|
|||
_accountSettings:
|
||||
requireSigninToViewContents: "須登入以顯示內容"
|
||||
requireSigninToViewContentsDescription1: "必須登入才會顯示您建立的貼文等內容。可望有效防止資訊被爬蟲蒐集。"
|
||||
requireSigninToViewContentsDescription2: "來自不支援 URL 預覽 (OGP)、 網頁嵌入和引用貼文的伺服器,也將停止顯示。"
|
||||
requireSigninToViewContentsDescription2: "針對您貼文的 URL 預覽 (OGP) 與網頁嵌入功能將會無法使用。而不支援引用貼文的伺服器,也將停止顯示。"
|
||||
requireSigninToViewContentsDescription3: "這些限制可能不適用於被聯邦發送至遠端伺服器的內容。"
|
||||
makeNotesFollowersOnlyBefore: "讓過去的貼文僅對追隨者顯示"
|
||||
makeNotesFollowersOnlyBeforeDescription: "啟用此功能後,超過設定的日期和時間或超過設定時間的貼文將僅對追隨者顯示。 如果您再次停用它,貼文的公開狀態也會恢復原狀。"
|
||||
makeNotesHiddenBefore: "隱藏過去的貼文"
|
||||
makeNotesHiddenBeforeDescription: "啟用此功能後,超過設定的日期和時間或超過設定時間的貼文將僅對自己顯示(私密化)。 如果您再次停用它,貼文的公開狀態也會恢復原狀。"
|
||||
mayNotEffectForFederatedNotes: "聯邦發送至遠端伺服器的貼文可能會不受影響。"
|
||||
mayNotEffectSomeSituations: "這些限制已經簡化。它們可能不適用於某些情況,例如在遠端伺服器上檢視或管理時。"
|
||||
mayNotEffectSomeSituations: "這些限制僅是簡化版本。在某些情況下,例如在遠端伺服器上瀏覽或進行審核時,可能不會套用這些限制。"
|
||||
notesHavePassedSpecifiedPeriod: "早於指定時間的貼文"
|
||||
notesOlderThanSpecifiedDateAndTime: "指定時間和日期之前的貼文"
|
||||
_abuseUserReport:
|
||||
|
@ -1455,6 +1470,7 @@ _delivery:
|
|||
manuallySuspended: "手動暫停中"
|
||||
goneSuspended: "因為伺服器刪除所以暫停中"
|
||||
autoSuspendedForNotResponding: "因為伺服器沒有回應所以暫停中"
|
||||
softwareSuspended: "此軟體因已停止發佈,目前無法使用"
|
||||
_bubbleGame:
|
||||
howToPlay: "玩法說明"
|
||||
hold: "保留"
|
||||
|
@ -1586,6 +1602,8 @@ _serverSettings:
|
|||
openRegistration: "允許建立帳戶"
|
||||
openRegistrationWarning: "開放註冊伴隨著風險。 建議只有在伺服器受到持續監控,並準備好在出現問題時能立即處理的情況下才開放註冊。"
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "如果在一段期間內沒有偵測到任何審查員活動,此設定將自動關閉,以防止垃圾內容。"
|
||||
deliverSuspendedSoftware: "已停止發佈的軟體"
|
||||
deliverSuspendedSoftwareDescription: "由於脆弱性等原因,可以指定伺服器軟體的名稱與版本範圍來停止其發佈。這些版本資訊是由伺服器所提供,其可靠性無法保證。版本的指定可以使用 semver(語意化版本控制) 的範圍語法,但如果指定為 >= 2024.3.1,則像 2024.3.1-custom.0 這樣的自訂版本將不會被包含在內,因此建議使用 >= 2024.3.1-0 的方式來同時包含預發佈版本。"
|
||||
_accountMigration:
|
||||
moveFrom: "從其他帳戶遷移到這個帳戶"
|
||||
moveFromSub: "為另一個帳戶建立別名"
|
||||
|
@ -1882,6 +1900,8 @@ _role:
|
|||
descriptionOfIsExplorable: "若開啟則公開角色時間軸。若角色不是公開的,則無法公開時間軸。"
|
||||
displayOrder: "顯示順序"
|
||||
descriptionOfDisplayOrder: "數字越大,顯示在UI上的越上面。"
|
||||
preserveAssignmentOnMoveAccount: "將指派狀態承接至轉移後的帳戶"
|
||||
preserveAssignmentOnMoveAccount_description: "開啟此選項後,當具備此角色的帳戶被移轉時,該角色也會承接至轉移後的帳戶。"
|
||||
canEditMembersByModerator: "允許編輯審查員的成員"
|
||||
descriptionOfCanEditMembersByModerator: "如果開啟,管理員與審查員都可以為使用者指派/解除指派該角色。如果關閉,則只有管理員可以執行。"
|
||||
priority: "優先級"
|
||||
|
@ -1901,6 +1921,7 @@ _role:
|
|||
canManageCustomEmojis: "管理自訂表情符號"
|
||||
canManageAvatarDecorations: "管理頭像裝飾"
|
||||
driveCapacity: "雲端硬碟容量"
|
||||
maxFileSize: "可上傳的最大檔案大小"
|
||||
alwaysMarkNsfw: "總是將檔案標記為NSFW"
|
||||
canUpdateBioMedia: "允許更新大頭貼和橫幅"
|
||||
pinMax: "置頂貼文的最大數量"
|
||||
|
@ -1922,7 +1943,7 @@ _role:
|
|||
canImportFollowing: "允許匯入追隨名單"
|
||||
canImportMuting: "允許匯入靜音名單"
|
||||
canImportUserLists: "允許匯入清單"
|
||||
canChat: "允許聊天"
|
||||
chatAvailability: "允許聊天"
|
||||
_condition:
|
||||
roleAssignedTo: "手動指派角色完成"
|
||||
isLocal: "本地使用者"
|
||||
|
@ -2119,7 +2140,6 @@ _theme:
|
|||
header: "標題"
|
||||
navBg: "側邊欄的背景 "
|
||||
navFg: "側邊欄的文字"
|
||||
navHoverFg: "側邊欄文字(懸浮) "
|
||||
navActive: "側邊欄文字(活動)"
|
||||
navIndicator: "側邊欄指示符"
|
||||
link: "連結"
|
||||
|
@ -2142,11 +2162,8 @@ _theme:
|
|||
buttonHoverBg: "按鈕背景 (漂浮)"
|
||||
inputBorder: "輸入框邊框"
|
||||
driveFolderBg: "雲端硬碟文件夾背景"
|
||||
wallpaperOverlay: "壁紙覆蓋層"
|
||||
badge: "徽章"
|
||||
messageBg: "私訊背景"
|
||||
accentDarken: "強調色(黑暗)"
|
||||
accentLighten: "強調色(明亮)"
|
||||
fgHighlighted: "突顯文字"
|
||||
_sfx:
|
||||
note: "貼文"
|
||||
|
@ -2360,6 +2377,7 @@ _widgets:
|
|||
chooseList: "選擇清單"
|
||||
clicker: "點擊器"
|
||||
birthdayFollowings: "今天生日的使用者"
|
||||
chat: "聊天"
|
||||
_cw:
|
||||
hide: "隱藏"
|
||||
show: "顯示內容"
|
||||
|
@ -2593,6 +2611,9 @@ _notification:
|
|||
_deck:
|
||||
alwaysShowMainColumn: "總是顯示主欄"
|
||||
columnAlign: "對齊欄位"
|
||||
columnGap: "欄與欄之間的邊距"
|
||||
deckMenuPosition: "多欄模式的選單位置"
|
||||
navbarPosition: "導覽列位置"
|
||||
addColumn: "新增欄位"
|
||||
newNoteNotificationSettings: "新貼文通知的設定"
|
||||
configureColumn: "欄位的設定"
|
||||
|
@ -2623,6 +2644,7 @@ _deck:
|
|||
mentions: "提及"
|
||||
direct: "指定使用者"
|
||||
roleTimeline: "角色時間軸"
|
||||
chat: "聊天"
|
||||
_dialog:
|
||||
charactersExceeded: "您的貼文太長了!現時字數 {current}/限制字數 {max}"
|
||||
charactersBelow: "您的貼文太短了!現時字數 {current}/限制字數 {min}"
|
||||
|
|
30
package.json
30
package.json
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.3.2-beta.18",
|
||||
"version": "2025.5.1-alpha.0",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/misskey-dev/misskey.git"
|
||||
},
|
||||
"packageManager": "pnpm@10.6.1",
|
||||
"packageManager": "pnpm@10.10.0",
|
||||
"workspaces": [
|
||||
"packages/frontend-shared",
|
||||
"packages/frontend",
|
||||
|
@ -24,7 +24,6 @@
|
|||
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
||||
"build-storybook": "pnpm --filter frontend build-storybook",
|
||||
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
||||
"build-frontend-search-index": "pnpm --filter frontend build-search-index",
|
||||
"start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js",
|
||||
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
||||
"init": "pnpm migrate",
|
||||
|
@ -35,7 +34,7 @@
|
|||
"watch": "pnpm dev",
|
||||
"dev": "node scripts/dev.mjs",
|
||||
"lint": "pnpm -r lint",
|
||||
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
|
||||
"cy:open": "pnpm cypress open --config-file=cypress.config.ts",
|
||||
"cy:run": "pnpm cypress run",
|
||||
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||
"e2e-dev-container": "ncp ./.config/cypress-devcontainer.yml ./.config/test.yml && pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||
|
@ -53,29 +52,29 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"cssnano": "7.0.6",
|
||||
"esbuild": "0.25.3",
|
||||
"execa": "9.5.2",
|
||||
"fast-glob": "3.3.3",
|
||||
"glob": "11.0.2",
|
||||
"ignore-walk": "7.0.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"postcss": "8.5.3",
|
||||
"tar": "7.4.3",
|
||||
"terser": "5.39.0",
|
||||
"typescript": "5.8.2",
|
||||
"esbuild": "0.25.0",
|
||||
"glob": "11.0.1"
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@misskey-dev/eslint-plugin": "2.1.0",
|
||||
"@types/node": "22.13.10",
|
||||
"@typescript-eslint/eslint-plugin": "8.26.0",
|
||||
"@typescript-eslint/parser": "8.26.0",
|
||||
"@types/node": "22.15.2",
|
||||
"@typescript-eslint/eslint-plugin": "8.31.0",
|
||||
"@typescript-eslint/parser": "8.31.0",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "14.1.0",
|
||||
"eslint": "9.22.0",
|
||||
"cypress": "14.3.2",
|
||||
"eslint": "9.25.1",
|
||||
"globals": "16.0.0",
|
||||
"ncp": "2.0.0",
|
||||
"pnpm": "10.6.1",
|
||||
"start-server-and-test": "2.0.10"
|
||||
"pnpm": "10.10.0",
|
||||
"start-server-and-test": "2.0.11"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
|
@ -83,9 +82,6 @@
|
|||
"pnpm": {
|
||||
"overrides": {
|
||||
"@aiscript-dev/aiscript-languageserver": "-"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"re2": "scripts/dependency-patches/re2.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import tsParser from '@typescript-eslint/parser';
|
||||
import globals from 'globals';
|
||||
import sharedConfig from '../shared/eslint.config.js';
|
||||
|
||||
export default [
|
||||
|
@ -6,6 +7,13 @@ export default [
|
|||
{
|
||||
ignores: ['**/node_modules', 'built', '@types/**/*', 'migration'],
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
languageOptions: {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env node
|
||||
import child_process from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import url from 'node:url';
|
||||
|
||||
import semver from 'semver';
|
||||
|
||||
const __filename = url.fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const args = [];
|
||||
args.push(...[
|
||||
...semver.satisfies(process.version, '^20.17.0 || ^22.0.0') ? ['--no-experimental-require-module'] : [],
|
||||
'--experimental-vm-modules',
|
||||
'--experimental-import-meta-resolve',
|
||||
path.join(__dirname, 'node_modules/jest/bin/jest.js'),
|
||||
...process.argv.slice(2),
|
||||
]);
|
||||
|
||||
child_process.spawn(process.execPath, args, { stdio: 'inherit' });
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class AddAntennaHideNotesInSensitiveChannel1736230492103 {
|
||||
name = 'AddAntennaHideNotesInSensitiveChannel1736230492103'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" ADD "hideNotesInSensitiveChannel" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "hideNotesInSensitiveChannel"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class DeliverSuspendedSoftware1743403874305 {
|
||||
name = 'DeliverSuspendedSoftware1743403874305'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "deliverSuspendedSoftware" jsonb NOT NULL DEFAULT '[]'`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deliverSuspendedSoftware"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class RoleCopyOnMoveAccount1743558299182 {
|
||||
name = 'RoleCopyOnMoveAccount1743558299182'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "role" ADD "preserveAssignmentOnMoveAccount" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "preserveAssignmentOnMoveAccount"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class ExcludeNotesInSensitiveChannel1744075766000 {
|
||||
name = 'ExcludeNotesInSensitiveChannel1744075766000'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" RENAME COLUMN "hideNotesInSensitiveChannel" TO "excludeNotesInSensitiveChannel"`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" RENAME COLUMN "excludeNotesInSensitiveChannel" TO "hideNotesInSensitiveChannel"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { isConcurrentIndexMigrationEnabled } from "./js/migration-config.js";
|
||||
|
||||
export class CompositeNoteIndex1745378064470 {
|
||||
name = 'CompositeNoteIndex1745378064470';
|
||||
transaction = isConcurrentIndexMigrationEnabled() ? false : undefined;
|
||||
|
||||
async up(queryRunner) {
|
||||
const concurrently = isConcurrentIndexMigrationEnabled();
|
||||
|
||||
if (concurrently) {
|
||||
const hasValidIndex = await queryRunner.query(`SELECT indisvalid FROM pg_index INNER JOIN pg_class ON pg_index.indexrelid = pg_class.oid WHERE pg_class.relname = 'IDX_724b311e6f883751f261ebe378'`);
|
||||
if (hasValidIndex.length === 0 || hasValidIndex[0].indisvalid !== true) {
|
||||
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_724b311e6f883751f261ebe378"`);
|
||||
await queryRunner.query(`CREATE INDEX CONCURRENTLY "IDX_724b311e6f883751f261ebe378" ON "note" ("userId", "id" DESC)`);
|
||||
}
|
||||
} else {
|
||||
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_724b311e6f883751f261ebe378" ON "note" ("userId", "id" DESC)`);
|
||||
}
|
||||
|
||||
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_5b87d9d19127bd5d92026017a7"`);
|
||||
// Flush all cached Linear Scan Plans and redo statistics for composite index
|
||||
// this is important for Postgres to learn that even in highly complex queries, using this index first can reduce the result set significantly
|
||||
await queryRunner.query(`ANALYZE "user", "note"`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
const mayConcurrently = isConcurrentIndexMigrationEnabled() ? 'CONCURRENTLY' : '';
|
||||
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_724b311e6f883751f261ebe378"`);
|
||||
await queryRunner.query(`CREATE INDEX ${mayConcurrently} "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId")`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class VisibleUserGeneratedContentsForNonLoggedInVisitors1746330901644 {
|
||||
name = 'VisibleUserGeneratedContentsForNonLoggedInVisitors1746330901644'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "ugcVisibilityForVisitor" character varying(128) NOT NULL DEFAULT 'local'`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ugcVisibilityForVisitor"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class SingleUserMode1746422049376 {
|
||||
name = 'SingleUserMode1746422049376'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "singleUserMode" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "singleUserMode"`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export function isConcurrentIndexMigrationEnabled() {
|
||||
return process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { DataSource } from 'typeorm';
|
||||
import { loadConfig } from './built/config.js';
|
||||
import { entities } from './built/postgres.js';
|
||||
import { isConcurrentIndexMigrationEnabled } from "./migration/js/migration-config.js";
|
||||
|
||||
const config = loadConfig();
|
||||
|
||||
|
@ -14,4 +15,5 @@ export default new DataSource({
|
|||
extra: config.db.extra,
|
||||
entities: entities,
|
||||
migrations: ['migration/*.js'],
|
||||
migrationsTransactionMode: isConcurrentIndexMigrationEnabled() ? 'each' : 'all',
|
||||
});
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
|
||||
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
|
||||
"lint": "pnpm typecheck && pnpm eslint",
|
||||
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs",
|
||||
"jest:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.e2e.cjs",
|
||||
"jest:fed": "node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.fed.cjs",
|
||||
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
||||
"jest-and-coverage:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
||||
"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache",
|
||||
"jest": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
|
||||
"jest:e2e": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
|
||||
"jest:fed": "node ./jest.js --forceExit --config jest.config.fed.cjs",
|
||||
"jest-and-coverage": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
||||
"jest-and-coverage:e2e": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
||||
"jest-clear": "cross-env NODE_ENV=test node ./jest.js --clearCache",
|
||||
"test": "pnpm jest",
|
||||
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
|
||||
"test:fed": "pnpm jest:fed",
|
||||
|
@ -37,17 +37,17 @@
|
|||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-android-arm64": "1.3.11",
|
||||
"@swc/core-darwin-arm64": "1.11.11",
|
||||
"@swc/core-darwin-x64": "1.11.11",
|
||||
"@swc/core-darwin-arm64": "1.11.22",
|
||||
"@swc/core-darwin-x64": "1.11.22",
|
||||
"@swc/core-freebsd-x64": "1.3.11",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.11",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.11",
|
||||
"@swc/core-linux-arm64-musl": "1.11.11",
|
||||
"@swc/core-linux-x64-gnu": "1.11.11",
|
||||
"@swc/core-linux-x64-musl": "1.11.11",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.11",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.11",
|
||||
"@swc/core-win32-x64-msvc": "1.11.11",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.22",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.22",
|
||||
"@swc/core-linux-arm64-musl": "1.11.22",
|
||||
"@swc/core-linux-x64-gnu": "1.11.22",
|
||||
"@swc/core-linux-x64-musl": "1.11.22",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.22",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.22",
|
||||
"@swc/core-win32-x64-msvc": "1.11.22",
|
||||
"@tensorflow/tfjs": "4.22.0",
|
||||
"@tensorflow/tfjs-node": "4.22.0",
|
||||
"bufferutil": "4.0.9",
|
||||
|
@ -67,8 +67,8 @@
|
|||
"utf-8-validate": "6.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.772.0",
|
||||
"@aws-sdk/lib-storage": "3.772.0",
|
||||
"@aws-sdk/client-s3": "3.797.0",
|
||||
"@aws-sdk/lib-storage": "3.797.0",
|
||||
"@discordapp/twemoji": "15.1.0",
|
||||
"@fastify/accepts": "5.0.2",
|
||||
"@fastify/cookie": "11.0.2",
|
||||
|
@ -79,20 +79,21 @@
|
|||
"@fastify/static": "8.1.1",
|
||||
"@fastify/view": "10.0.2",
|
||||
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
||||
"@misskey-dev/summaly": "5.2.0",
|
||||
"@napi-rs/canvas": "0.1.68",
|
||||
"@nestjs/common": "11.0.12",
|
||||
"@nestjs/core": "11.0.12",
|
||||
"@nestjs/testing": "11.0.12",
|
||||
"@misskey-dev/summaly": "5.2.1",
|
||||
"@napi-rs/canvas": "0.1.69",
|
||||
"@nestjs/common": "11.1.0",
|
||||
"@nestjs/core": "11.1.0",
|
||||
"@nestjs/testing": "11.1.0",
|
||||
"@peertube/http-signature": "1.7.0",
|
||||
"@sentry/node": "8.55.0",
|
||||
"@sentry/profiling-node": "8.55.0",
|
||||
"@simplewebauthn/server": "12.0.0",
|
||||
"@sinonjs/fake-timers": "11.3.1",
|
||||
"@smithy/node-http-handler": "2.5.0",
|
||||
"@swc/cli": "0.6.0",
|
||||
"@swc/core": "1.11.11",
|
||||
"@swc/cli": "0.7.3",
|
||||
"@swc/core": "1.11.22",
|
||||
"@twemoji/parser": "15.1.1",
|
||||
"@types/redis-info": "3.0.3",
|
||||
"accepts": "1.3.8",
|
||||
"ajv": "8.17.1",
|
||||
"archiver": "7.0.1",
|
||||
|
@ -100,7 +101,7 @@
|
|||
"bcryptjs": "2.4.3",
|
||||
"blurhash": "2.0.5",
|
||||
"body-parser": "1.20.3",
|
||||
"bullmq": "5.44.1",
|
||||
"bullmq": "5.51.1",
|
||||
"cacheable-lookup": "7.0.0",
|
||||
"cbor": "9.0.2",
|
||||
"chalk": "5.4.1",
|
||||
|
@ -111,28 +112,28 @@
|
|||
"content-disposition": "0.5.4",
|
||||
"date-fns": "2.30.0",
|
||||
"deep-email-validator": "0.1.21",
|
||||
"fastify": "5.2.1",
|
||||
"fastify": "5.3.2",
|
||||
"fastify-raw-body": "5.0.0",
|
||||
"feed": "4.2.2",
|
||||
"file-type": "19.6.0",
|
||||
"fluent-ffmpeg": "2.1.3",
|
||||
"form-data": "4.0.2",
|
||||
"got": "14.4.6",
|
||||
"got": "14.4.7",
|
||||
"happy-dom": "16.8.1",
|
||||
"hpagent": "1.2.0",
|
||||
"htmlescape": "1.1.1",
|
||||
"http-link-header": "1.1.3",
|
||||
"ioredis": "5.6.0",
|
||||
"ioredis": "5.6.1",
|
||||
"ip-cidr": "4.0.2",
|
||||
"ipaddr.js": "2.2.0",
|
||||
"is-svg": "5.1.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"jsdom": "26.0.0",
|
||||
"jsdom": "26.1.0",
|
||||
"json5": "2.2.3",
|
||||
"jsonld": "8.3.3",
|
||||
"jsrsasign": "11.1.0",
|
||||
"juice": "11.0.1",
|
||||
"meilisearch": "0.49.0",
|
||||
"meilisearch": "0.50.0",
|
||||
"mfm-js": "0.24.0",
|
||||
"microformats-parser": "2.0.2",
|
||||
"mime-types": "2.1.35",
|
||||
|
@ -142,15 +143,15 @@
|
|||
"nanoid": "5.1.5",
|
||||
"nested-property": "4.0.0",
|
||||
"node-fetch": "3.3.2",
|
||||
"nodemailer": "6.10.0",
|
||||
"nodemailer": "6.10.1",
|
||||
"nsfwjs": "4.2.0",
|
||||
"oauth": "0.10.2",
|
||||
"oauth2orize": "1.12.0",
|
||||
"oauth2orize-pkce": "0.1.2",
|
||||
"os-utils": "0.0.14",
|
||||
"otpauth": "9.3.6",
|
||||
"parse5": "7.2.1",
|
||||
"pg": "8.14.1",
|
||||
"otpauth": "9.4.0",
|
||||
"parse5": "7.3.0",
|
||||
"pg": "8.15.6",
|
||||
"pkce-challenge": "4.1.0",
|
||||
"probe-image-size": "7.2.3",
|
||||
"promise-limit": "2.7.0",
|
||||
|
@ -159,24 +160,26 @@
|
|||
"random-seed": "0.3.0",
|
||||
"ratelimiter": "3.4.1",
|
||||
"re2": "1.21.4",
|
||||
"redis-info": "3.1.0",
|
||||
"redis-lock": "0.1.4",
|
||||
"reflect-metadata": "0.2.2",
|
||||
"rename": "1.0.4",
|
||||
"rss-parser": "3.13.0",
|
||||
"rxjs": "7.8.2",
|
||||
"sanitize-html": "2.15.0",
|
||||
"sanitize-html": "2.16.0",
|
||||
"secure-json-parse": "3.0.2",
|
||||
"sharp": "0.33.5",
|
||||
"semver": "7.7.1",
|
||||
"slacc": "0.0.10",
|
||||
"strict-event-emitter-types": "2.0.0",
|
||||
"stringz": "2.1.0",
|
||||
"systeminformation": "5.25.11",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tmp": "0.2.3",
|
||||
"tsc-alias": "1.8.11",
|
||||
"tsc-alias": "1.8.15",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typeorm": "0.3.21",
|
||||
"typescript": "5.8.2",
|
||||
"typeorm": "0.3.22",
|
||||
"typescript": "5.8.3",
|
||||
"ulid": "2.4.0",
|
||||
"vary": "1.1.2",
|
||||
"web-push": "3.6.7",
|
||||
|
@ -185,9 +188,10 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@jest/globals": "29.7.0",
|
||||
"@nestjs/platform-express": "10.4.15",
|
||||
"@nestjs/platform-express": "10.4.17",
|
||||
"@sentry/vue": "9.14.0",
|
||||
"@simplewebauthn/types": "12.0.0",
|
||||
"@swc/jest": "0.2.37",
|
||||
"@swc/jest": "0.2.38",
|
||||
"@types/accepts": "1.3.7",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/bcryptjs": "2.4.6",
|
||||
|
@ -204,28 +208,29 @@
|
|||
"@types/jsrsasign": "10.5.15",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/ms": "0.7.34",
|
||||
"@types/node": "22.13.10",
|
||||
"@types/node": "22.15.2",
|
||||
"@types/nodemailer": "6.4.17",
|
||||
"@types/oauth": "0.9.6",
|
||||
"@types/oauth2orize": "1.11.5",
|
||||
"@types/oauth2orize-pkce": "0.1.2",
|
||||
"@types/pg": "8.11.11",
|
||||
"@types/pg": "8.11.14",
|
||||
"@types/pug": "2.0.10",
|
||||
"@types/qrcode": "1.5.5",
|
||||
"@types/random-seed": "0.3.5",
|
||||
"@types/ratelimiter": "3.4.6",
|
||||
"@types/rename": "1.0.7",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/semver": "7.5.8",
|
||||
"@types/sanitize-html": "2.15.0",
|
||||
"@types/semver": "7.7.0",
|
||||
"@types/simple-oauth2": "5.0.7",
|
||||
"@types/sinonjs__fake-timers": "8.1.5",
|
||||
"@types/supertest": "6.0.3",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"@types/tmp": "0.2.6",
|
||||
"@types/vary": "1.1.3",
|
||||
"@types/web-push": "3.6.4",
|
||||
"@types/ws": "8.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"@types/ws": "8.18.1",
|
||||
"@typescript-eslint/eslint-plugin": "8.31.0",
|
||||
"@typescript-eslint/parser": "8.31.0",
|
||||
"aws-sdk-client-mock": "4.1.0",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
|
@ -233,8 +238,9 @@
|
|||
"fkill": "9.0.0",
|
||||
"jest": "29.7.0",
|
||||
"jest-mock": "29.7.0",
|
||||
"nodemon": "3.1.9",
|
||||
"nodemon": "3.1.10",
|
||||
"pid-port": "1.0.2",
|
||||
"simple-oauth2": "5.1.0"
|
||||
"simple-oauth2": "5.1.0",
|
||||
"supertest": "7.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,13 @@ const $config: Provider = {
|
|||
const $db: Provider = {
|
||||
provide: DI.db,
|
||||
useFactory: async (config) => {
|
||||
const db = createPostgresDataSource(config);
|
||||
return await db.initialize();
|
||||
try {
|
||||
const db = createPostgresDataSource(config);
|
||||
return await db.initialize();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
inject: [DI.config],
|
||||
};
|
||||
|
|
|
@ -7,7 +7,8 @@ import * as fs from 'node:fs';
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import type * as Sentry from '@sentry/node';
|
||||
import type * as SentryVue from '@sentry/vue';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
|
||||
type RedisOptionsSource = Partial<RedisOptions> & {
|
||||
|
@ -62,7 +63,12 @@ type Source = {
|
|||
scope?: 'local' | 'global' | string[];
|
||||
};
|
||||
sentryForBackend?: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; };
|
||||
sentryForFrontend?: { options: Partial<Sentry.NodeOptions> };
|
||||
sentryForFrontend?: {
|
||||
options: Partial<SentryVue.BrowserOptions> & { dsn: string };
|
||||
vueIntegration?: SentryVue.VueIntegrationOptions | null;
|
||||
browserTracingIntegration?: Parameters<typeof SentryVue.browserTracingIntegration>[0] | null;
|
||||
replayIntegration?: Parameters<typeof SentryVue.replayIntegration>[0] | null;
|
||||
};
|
||||
|
||||
publishTarballInsteadOfProvideRepositoryUrl?: boolean;
|
||||
|
||||
|
@ -198,7 +204,12 @@ export type Config = {
|
|||
redisForTimelines: RedisOptions & RedisOptionsSource;
|
||||
redisForReactions: RedisOptions & RedisOptionsSource;
|
||||
sentryForBackend: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; } | undefined;
|
||||
sentryForFrontend: { options: Partial<Sentry.NodeOptions> } | undefined;
|
||||
sentryForFrontend: {
|
||||
options: Partial<SentryVue.BrowserOptions> & { dsn: string };
|
||||
vueIntegration?: SentryVue.VueIntegrationOptions | null;
|
||||
browserTracingIntegration?: Parameters<typeof SentryVue.browserTracingIntegration>[0] | null;
|
||||
replayIntegration?: Parameters<typeof SentryVue.replayIntegration>[0] | null;
|
||||
} | undefined;
|
||||
perChannelMaxNoteCacheCount: number;
|
||||
perUserNotificationsMaxCount: number;
|
||||
deactivateAntennaThreshold: number;
|
||||
|
|
|
@ -24,6 +24,8 @@ import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
|||
import InstanceChart from '@/core/chart/charts/instance.js';
|
||||
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { AntennaService } from '@/core/AntennaService.js';
|
||||
|
||||
@Injectable()
|
||||
export class AccountMoveService {
|
||||
|
@ -61,6 +63,8 @@ export class AccountMoveService {
|
|||
private relayService: RelayService,
|
||||
private queueService: QueueService,
|
||||
private systemAccountService: SystemAccountService,
|
||||
private roleService: RoleService,
|
||||
private antennaService: AntennaService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -119,7 +123,9 @@ export class AccountMoveService {
|
|||
await Promise.all([
|
||||
this.copyBlocking(src, dst),
|
||||
this.copyMutings(src, dst),
|
||||
this.copyRoles(src, dst),
|
||||
this.updateLists(src, dst),
|
||||
this.antennaService.onMoveAccount(src, dst),
|
||||
]);
|
||||
} catch {
|
||||
/* skip if any error happens */
|
||||
|
@ -201,6 +207,32 @@ export class AccountMoveService {
|
|||
await this.mutingsRepository.insert(arrayToInsert);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async copyRoles(src: ThinUser, dst: ThinUser): Promise<void> {
|
||||
// Insert new roles with the same values except userId
|
||||
// role service may have cache for roles so retrieve roles from service
|
||||
const [oldRoleAssignments, roles] = await Promise.all([
|
||||
this.roleService.getUserAssigns(src.id),
|
||||
this.roleService.getRoles(),
|
||||
]);
|
||||
|
||||
if (oldRoleAssignments.length === 0) return;
|
||||
|
||||
// No promise all since the only async operation is writing to the database
|
||||
for (const oldRoleAssignment of oldRoleAssignments) {
|
||||
const role = roles.find(x => x.id === oldRoleAssignment.roleId);
|
||||
if (role == null) continue; // Very unlikely however removing role may cause this case
|
||||
if (!role.preserveAssignmentOnMoveAccount) continue;
|
||||
|
||||
try {
|
||||
await this.roleService.assign(dst.id, role.id, oldRoleAssignment.expiresAt);
|
||||
} catch (e) {
|
||||
if (e instanceof RoleService.AlreadyAssignedError) continue;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update lists while moving accounts.
|
||||
* - No removal of the old account from the lists
|
||||
|
|
|
@ -9,87 +9,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { NotificationService } from '@/core/NotificationService.js';
|
||||
|
||||
export const ACHIEVEMENT_TYPES = [
|
||||
'notes1',
|
||||
'notes10',
|
||||
'notes100',
|
||||
'notes500',
|
||||
'notes1000',
|
||||
'notes5000',
|
||||
'notes10000',
|
||||
'notes20000',
|
||||
'notes30000',
|
||||
'notes40000',
|
||||
'notes50000',
|
||||
'notes60000',
|
||||
'notes70000',
|
||||
'notes80000',
|
||||
'notes90000',
|
||||
'notes100000',
|
||||
'login3',
|
||||
'login7',
|
||||
'login15',
|
||||
'login30',
|
||||
'login60',
|
||||
'login100',
|
||||
'login200',
|
||||
'login300',
|
||||
'login400',
|
||||
'login500',
|
||||
'login600',
|
||||
'login700',
|
||||
'login800',
|
||||
'login900',
|
||||
'login1000',
|
||||
'passedSinceAccountCreated1',
|
||||
'passedSinceAccountCreated2',
|
||||
'passedSinceAccountCreated3',
|
||||
'loggedInOnBirthday',
|
||||
'loggedInOnNewYearsDay',
|
||||
'noteClipped1',
|
||||
'noteFavorited1',
|
||||
'myNoteFavorited1',
|
||||
'profileFilled',
|
||||
'markedAsCat',
|
||||
'following1',
|
||||
'following10',
|
||||
'following50',
|
||||
'following100',
|
||||
'following300',
|
||||
'followers1',
|
||||
'followers10',
|
||||
'followers50',
|
||||
'followers100',
|
||||
'followers300',
|
||||
'followers500',
|
||||
'followers1000',
|
||||
'collectAchievements30',
|
||||
'viewAchievements3min',
|
||||
'iLoveMisskey',
|
||||
'foundTreasure',
|
||||
'client30min',
|
||||
'client60min',
|
||||
'noteDeletedWithin1min',
|
||||
'postedAtLateNight',
|
||||
'postedAt0min0sec',
|
||||
'selfQuote',
|
||||
'htl20npm',
|
||||
'viewInstanceChart',
|
||||
'outputHelloWorldOnScratchpad',
|
||||
'open3windows',
|
||||
'driveFolderCircularReference',
|
||||
'reactWithoutRead',
|
||||
'clickedClickHere',
|
||||
'justPlainLucky',
|
||||
'setNameToSyuilo',
|
||||
'cookieClicked',
|
||||
'brainDiver',
|
||||
'smashTestNotificationButton',
|
||||
'tutorialCompleted',
|
||||
'bubbleGameExplodingHead',
|
||||
'bubbleGameDoubleExplodingHead',
|
||||
] as const;
|
||||
import { ACHIEVEMENT_TYPES } from '@/models/UserProfile.js';
|
||||
|
||||
@Injectable()
|
||||
export class AchievementService {
|
||||
|
|
|
@ -5,18 +5,20 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as Redis from 'ioredis';
|
||||
import { In } from 'typeorm';
|
||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { AntennasRepository, UserListMembershipsRepository } from '@/models/_.js';
|
||||
import type { MiAntenna } from '@/models/Antenna.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { AntennasRepository, UserListMembershipsRepository } from '@/models/_.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import { CacheService } from './CacheService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
|
@ -37,6 +39,7 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
@Inject(DI.userListMembershipsRepository)
|
||||
private userListMembershipsRepository: UserListMembershipsRepository,
|
||||
|
||||
private cacheService: CacheService,
|
||||
private utilityService: UtilityService,
|
||||
private globalEventService: GlobalEventService,
|
||||
private fanoutTimelineService: FanoutTimelineService,
|
||||
|
@ -111,8 +114,7 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
public async checkHitAntenna(antenna: MiAntenna, note: (MiNote | Packed<'Note'>), noteUser: { id: MiUser['id']; username: string; host: string | null; isBot: boolean; }): Promise<boolean> {
|
||||
if (note.visibility === 'specified') return false;
|
||||
if (note.visibility === 'followers') return false;
|
||||
if (antenna.excludeNotesInSensitiveChannel && note.channel?.isSensitive) return false;
|
||||
|
||||
if (antenna.excludeBots && noteUser.isBot) return false;
|
||||
|
||||
|
@ -120,6 +122,18 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
|
||||
if (!antenna.withReplies && note.replyId != null) return false;
|
||||
|
||||
if (note.visibility === 'specified') {
|
||||
if (note.userId !== antenna.userId) {
|
||||
if (note.visibleUserIds == null) return false;
|
||||
if (!note.visibleUserIds.includes(antenna.userId)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (note.visibility === 'followers') {
|
||||
const isFollowing = Object.hasOwn(await this.cacheService.userFollowingsCache.fetch(antenna.userId), note.userId);
|
||||
if (!isFollowing && antenna.userId !== note.userId) return false;
|
||||
}
|
||||
|
||||
if (antenna.src === 'home') {
|
||||
// TODO
|
||||
} else if (antenna.src === 'list') {
|
||||
|
@ -206,6 +220,41 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
return this.antennas;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async onMoveAccount(src: MiUser, dst: MiUser): Promise<void> {
|
||||
// There is a possibility for users to add the srcUser to their antennas, but it's low, so we don't check it.
|
||||
|
||||
// Get MiAntenna[] from cache and filter to select antennas with the src user is in the users list
|
||||
const srcUserAcct = this.utilityService.getFullApAccount(src.username, src.host).toLowerCase();
|
||||
const antennasToMigrate = (await this.getAntennas()).filter(antenna => {
|
||||
return antenna.users.some(user => {
|
||||
const { username, host } = Acct.parse(user);
|
||||
return this.utilityService.getFullApAccount(username, host).toLowerCase() === srcUserAcct;
|
||||
});
|
||||
});
|
||||
|
||||
if (antennasToMigrate.length === 0) return;
|
||||
|
||||
const antennaIds = antennasToMigrate.map(x => x.id);
|
||||
|
||||
// Update the antennas by appending dst users acct to the users list
|
||||
const dstUserAcct = '@' + Acct.toString({ username: dst.username, host: dst.host });
|
||||
|
||||
await this.antennasRepository.createQueryBuilder('antenna')
|
||||
.update()
|
||||
.set({
|
||||
users: () => 'array_append(antenna.users, :dstUserAcct)',
|
||||
})
|
||||
.where('antenna.id IN (:...antennaIds)', { antennaIds })
|
||||
.setParameters({ dstUserAcct })
|
||||
.execute();
|
||||
|
||||
// announce update to event
|
||||
for (const newAntenna of await this.antennasRepository.findBy({ id: In(antennaIds) })) {
|
||||
this.globalEventService.publishInternalEvent('antennaUpdated', newAntenna);
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public dispose(): void {
|
||||
this.redisForSub.off('message', this.onRedisMessage);
|
||||
|
|
|
@ -94,12 +94,46 @@ export class ChatService {
|
|||
) {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async getChatAvailability(userId: MiUser['id']): Promise<{ read: boolean; write: boolean; }> {
|
||||
const policies = await this.roleService.getUserPolicies(userId);
|
||||
|
||||
switch (policies.chatAvailability) {
|
||||
case 'available':
|
||||
return {
|
||||
read: true,
|
||||
write: true,
|
||||
};
|
||||
case 'readonly':
|
||||
return {
|
||||
read: true,
|
||||
write: false,
|
||||
};
|
||||
case 'unavailable':
|
||||
return {
|
||||
read: false,
|
||||
write: false,
|
||||
};
|
||||
default:
|
||||
throw new Error('invalid chat availability (unreachable)');
|
||||
}
|
||||
}
|
||||
|
||||
/** getChatAvailabilityの糖衣。主にAPI呼び出し時に走らせて、権限的に問題ない場合はそのまま続行する */
|
||||
@bindThis
|
||||
public async checkChatAvailability(userId: MiUser['id'], permission: 'read' | 'write') {
|
||||
const policy = await this.getChatAvailability(userId);
|
||||
if (policy[permission] === false) {
|
||||
throw new Error('ROLE_PERMISSION_DENIED');
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async createMessageToUser(fromUser: { id: MiUser['id']; host: MiUser['host']; }, toUser: MiUser, params: {
|
||||
text?: string | null;
|
||||
file?: MiDriveFile | null;
|
||||
uri?: string | null;
|
||||
}): Promise<Packed<'ChatMessageLite'>> {
|
||||
}): Promise<Packed<'ChatMessageLiteFor1on1'>> {
|
||||
if (fromUser.id === toUser.id) {
|
||||
throw new Error('yourself');
|
||||
}
|
||||
|
@ -140,7 +174,7 @@ export class ChatService {
|
|||
}
|
||||
}
|
||||
|
||||
if (!(await this.roleService.getUserPolicies(toUser.id)).canChat) {
|
||||
if (!(await this.getChatAvailability(toUser.id)).write) {
|
||||
throw new Error('recipient is cannot chat (policy)');
|
||||
}
|
||||
|
||||
|
@ -198,7 +232,7 @@ export class ChatService {
|
|||
|
||||
const packedMessageForTo = await this.chatEntityService.packMessageDetailed(inserted, toUser);
|
||||
this.globalEventService.publishMainStream(toUser.id, 'newChatMessage', packedMessageForTo);
|
||||
//this.pushNotificationService.pushNotification(toUser.id, 'newChatMessage', packedMessageForTo);
|
||||
this.pushNotificationService.pushNotification(toUser.id, 'newChatMessage', packedMessageForTo);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
@ -210,10 +244,16 @@ export class ChatService {
|
|||
text?: string | null;
|
||||
file?: MiDriveFile | null;
|
||||
uri?: string | null;
|
||||
}): Promise<Packed<'ChatMessageLite'>> {
|
||||
const memberships = await this.chatRoomMembershipsRepository.findBy({ roomId: toRoom.id });
|
||||
}): Promise<Packed<'ChatMessageLiteForRoom'>> {
|
||||
const memberships = (await this.chatRoomMembershipsRepository.findBy({ roomId: toRoom.id })).map(m => ({
|
||||
userId: m.userId,
|
||||
isMuted: m.isMuted,
|
||||
})).concat({ // ownerはmembershipレコードを作らないため
|
||||
userId: toRoom.ownerId,
|
||||
isMuted: false,
|
||||
});
|
||||
|
||||
if (toRoom.ownerId !== fromUser.id && !memberships.some(member => member.userId === fromUser.id)) {
|
||||
if (!memberships.some(member => member.userId === fromUser.id)) {
|
||||
throw new Error('you are not a member of the room');
|
||||
}
|
||||
|
||||
|
@ -262,7 +302,7 @@ export class ChatService {
|
|||
if (marker == null) continue;
|
||||
|
||||
this.globalEventService.publishMainStream(membershipsOtherThanMe[i].userId, 'newChatMessage', packedMessageForTo);
|
||||
//this.pushNotificationService.pushNotification(membershipsOtherThanMe[i].userId, 'newChatMessage', packedMessageForTo);
|
||||
this.pushNotificationService.pushNotification(membershipsOtherThanMe[i].userId, 'newChatMessage', packedMessageForTo);
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
|
@ -538,6 +578,20 @@ export class ChatService {
|
|||
|
||||
@bindThis
|
||||
public async deleteRoom(room: MiChatRoom, deleter?: MiUser) {
|
||||
const memberships = (await this.chatRoomMembershipsRepository.findBy({ roomId: room.id })).map(m => ({
|
||||
userId: m.userId,
|
||||
})).concat({ // ownerはmembershipレコードを作らないため
|
||||
userId: room.ownerId,
|
||||
});
|
||||
|
||||
// 未読フラグ削除
|
||||
const redisPipeline = this.redisClient.pipeline();
|
||||
for (const membership of memberships) {
|
||||
redisPipeline.del(`newRoomChatMessageExists:${membership.userId}:${room.id}`);
|
||||
redisPipeline.srem(`newChatMessagesExists:${membership.userId}`, `room:${room.id}`);
|
||||
}
|
||||
await redisPipeline.exec();
|
||||
|
||||
await this.chatRoomsRepository.delete(room.id);
|
||||
|
||||
if (deleter) {
|
||||
|
@ -669,6 +723,12 @@ export class ChatService {
|
|||
public async leaveRoom(userId: MiUser['id'], roomId: MiChatRoom['id']) {
|
||||
const membership = await this.chatRoomMembershipsRepository.findOneByOrFail({ roomId, userId });
|
||||
await this.chatRoomMembershipsRepository.delete(membership.id);
|
||||
|
||||
// 未読フラグを消す (「既読にする」というわけでもないのでreadメソッドは使わないでおく)
|
||||
const redisPipeline = this.redisClient.pipeline();
|
||||
redisPipeline.del(`newRoomChatMessageExists:${userId}:${roomId}`);
|
||||
redisPipeline.srem(`newChatMessagesExists:${userId}`, `room:${roomId}`);
|
||||
await redisPipeline.exec();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
@ -522,9 +522,16 @@ export class DriveService {
|
|||
|
||||
const policies = await this.roleService.getUserPolicies(user.id);
|
||||
const driveCapacity = 1024 * 1024 * policies.driveCapacityMb;
|
||||
const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb;
|
||||
this.registerLogger.debug('drive capacity override applied');
|
||||
this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`);
|
||||
|
||||
if (maxFileSize < info.size) {
|
||||
if (isLocalUser) {
|
||||
throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.');
|
||||
}
|
||||
}
|
||||
|
||||
// If usage limit exceeded
|
||||
if (driveCapacity < usage + info.size) {
|
||||
if (isLocalUser) {
|
||||
|
|
|
@ -8,10 +8,12 @@ import { DI } from '@/di-symbols.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import type { MiMeta } from '@/models/Meta.js';
|
||||
import { Packed } from '@/misc/json-schema.js';
|
||||
import type { NotesRepository } from '@/models/_.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { FanoutTimelineName, FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { isQuote, isRenote } from '@/misc/is-renote.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
|
@ -30,9 +32,11 @@ type TimelineOptions = {
|
|||
alwaysIncludeMyNotes?: boolean;
|
||||
ignoreAuthorFromBlock?: boolean;
|
||||
ignoreAuthorFromMute?: boolean;
|
||||
ignoreAuthorFromInstanceBlock?: boolean;
|
||||
excludeNoFiles?: boolean;
|
||||
excludeReplies?: boolean;
|
||||
excludePureRenotes: boolean;
|
||||
ignoreAuthorFromUserSuspension?: boolean;
|
||||
dbFallback: (untilId: string | null, sinceId: string | null, limit: number) => Promise<MiNote[]>,
|
||||
};
|
||||
|
||||
|
@ -42,9 +46,13 @@ export class FanoutTimelineEndpointService {
|
|||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
private noteEntityService: NoteEntityService,
|
||||
private cacheService: CacheService,
|
||||
private fanoutTimelineService: FanoutTimelineService,
|
||||
private utilityService: UtilityService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -54,7 +62,7 @@ export class FanoutTimelineEndpointService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async getMiNotes(ps: TimelineOptions): Promise<MiNote[]> {
|
||||
async getMiNotes(ps: TimelineOptions): Promise<MiNote[]> {
|
||||
// 呼び出し元と以下の処理をシンプルにするためにdbFallbackを置き換える
|
||||
if (!ps.useDbFallback) ps.dbFallback = () => Promise.resolve([]);
|
||||
|
||||
|
@ -119,6 +127,36 @@ export class FanoutTimelineEndpointService {
|
|||
};
|
||||
}
|
||||
|
||||
{
|
||||
const parentFilter = filter;
|
||||
filter = (note) => {
|
||||
if (!ps.ignoreAuthorFromInstanceBlock) {
|
||||
if (this.utilityService.isBlockedHost(this.meta.blockedHosts, note.userHost)) return false;
|
||||
}
|
||||
if (note.userId !== note.renoteUserId && this.utilityService.isBlockedHost(this.meta.blockedHosts, note.renoteUserHost)) return false;
|
||||
if (note.userId !== note.replyUserId && this.utilityService.isBlockedHost(this.meta.blockedHosts, note.replyUserHost)) return false;
|
||||
|
||||
return parentFilter(note);
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
const parentFilter = filter;
|
||||
filter = (note) => {
|
||||
const noteJoined = note as MiNote & {
|
||||
renoteUser: MiUser | null;
|
||||
replyUser: MiUser | null;
|
||||
};
|
||||
if (!ps.ignoreAuthorFromUserSuspension) {
|
||||
if (note.user!.isSuspended) return false;
|
||||
}
|
||||
if (note.userId !== note.renoteUserId && noteJoined.renoteUser?.isSuspended) return false;
|
||||
if (note.userId !== note.replyUserId && noteJoined.replyUser?.isSuspended) return false;
|
||||
|
||||
return parentFilter(note);
|
||||
};
|
||||
}
|
||||
|
||||
const redisTimeline: MiNote[] = [];
|
||||
let readFromRedis = 0;
|
||||
let lastSuccessfulRate = 1; // rateをキャッシュする?
|
||||
|
|
|
@ -7,13 +7,13 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { ulid } from 'ulid';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { genAid, isSafeAidT, parseAid } from '@/misc/id/aid.js';
|
||||
import { genAidx, isSafeAidxT, parseAidx } from '@/misc/id/aidx.js';
|
||||
import { genMeid, isSafeMeidT, parseMeid } from '@/misc/id/meid.js';
|
||||
import { genMeidg, isSafeMeidgT, parseMeidg } from '@/misc/id/meidg.js';
|
||||
import { genObjectId, isSafeObjectIdT, parseObjectId } from '@/misc/id/object-id.js';
|
||||
import { genAid, isSafeAidT, parseAid, parseAidFull } from '@/misc/id/aid.js';
|
||||
import { genAidx, isSafeAidxT, parseAidx, parseAidxFull } from '@/misc/id/aidx.js';
|
||||
import { genMeid, isSafeMeidT, parseMeid, parseMeidFull } from '@/misc/id/meid.js';
|
||||
import { genMeidg, isSafeMeidgT, parseMeidg, parseMeidgFull } from '@/misc/id/meidg.js';
|
||||
import { genObjectId, isSafeObjectIdT, parseObjectId, parseObjectIdFull } from '@/misc/id/object-id.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { parseUlid } from '@/misc/id/ulid.js';
|
||||
import { parseUlid, parseUlidFull } from '@/misc/id/ulid.js';
|
||||
|
||||
@Injectable()
|
||||
export class IdService {
|
||||
|
@ -70,4 +70,18 @@ export class IdService {
|
|||
default: throw new Error('unrecognized id generation method');
|
||||
}
|
||||
}
|
||||
|
||||
// Note: additional is at most 64 bits
|
||||
@bindThis
|
||||
public parseFull(id: string): { date: number; additional: bigint; } {
|
||||
switch (this.method) {
|
||||
case 'aid': return parseAidFull(id);
|
||||
case 'aidx': return parseAidxFull(id);
|
||||
case 'objectid': return parseObjectIdFull(id);
|
||||
case 'meid': return parseMeidFull(id);
|
||||
case 'meidg': return parseMeidgFull(id);
|
||||
case 'ulid': return parseUlidFull(id);
|
||||
default: throw new Error('unrecognized id generation method');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ export const webpDefault: sharp.WebpOptions = {
|
|||
smartSubsample: true,
|
||||
mixed: true,
|
||||
effort: 2,
|
||||
loop: 0,
|
||||
};
|
||||
|
||||
export const avifDefault: sharp.AvifOptions = {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { URL } from 'node:url';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as parse5 from 'parse5';
|
||||
import { Window, XMLSerializer } from 'happy-dom';
|
||||
import { type Document, type HTMLParagraphElement, Window, XMLSerializer } from 'happy-dom';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { intersperse } from '@/misc/prelude/array.js';
|
||||
|
@ -23,6 +23,8 @@ type ChildNode = DefaultTreeAdapterMap['childNode'];
|
|||
const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
|
||||
const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
|
||||
|
||||
export type Appender = (document: Document, body: HTMLParagraphElement) => void;
|
||||
|
||||
@Injectable()
|
||||
export class MfmService {
|
||||
constructor(
|
||||
|
@ -267,7 +269,7 @@ export class MfmService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = []) {
|
||||
public toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = [], additionalAppenders: Appender[] = []) {
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -492,6 +494,10 @@ export class MfmService {
|
|||
|
||||
appendChildren(nodes, body);
|
||||
|
||||
for (const additionalAppender of additionalAppenders) {
|
||||
additionalAppender(doc, body);
|
||||
}
|
||||
|
||||
// Remove the unnecessary namespace
|
||||
const serialized = new XMLSerializer().serializeToString(body).replace(/^\s*<p xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">/, '<p>');
|
||||
|
||||
|
|
|
@ -532,7 +532,10 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
|
||||
this.pushToTl(note, user);
|
||||
|
||||
this.antennaService.addNoteToAntennas(note, user);
|
||||
this.antennaService.addNoteToAntennas({
|
||||
...note,
|
||||
channel: data.channel ?? null,
|
||||
}, user);
|
||||
|
||||
if (data.reply) {
|
||||
this.saveReply(data.reply, note);
|
||||
|
@ -573,7 +576,14 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
noteId: note.id,
|
||||
}, {
|
||||
delay,
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { setTimeout } from 'node:timers/promises';
|
|||
import * as Redis from 'ioredis';
|
||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||
import { In } from 'typeorm';
|
||||
import { ReplyError } from 'ioredis';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
|
@ -19,7 +20,7 @@ import { IdService } from '@/core/IdService.js';
|
|||
import { CacheService } from '@/core/CacheService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { UserListService } from '@/core/UserListService.js';
|
||||
import type { FilterUnionByProperty } from '@/types.js';
|
||||
import { FilterUnionByProperty, groupedNotificationTypes, obsoleteNotificationTypes } from '@/types.js';
|
||||
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||
|
||||
@Injectable()
|
||||
|
@ -145,21 +146,36 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
}
|
||||
}
|
||||
|
||||
const notification = {
|
||||
id: this.idService.gen(),
|
||||
createdAt: new Date(),
|
||||
type: type,
|
||||
...(notifierId ? {
|
||||
notifierId,
|
||||
} : {}),
|
||||
...data,
|
||||
} as any as FilterUnionByProperty<MiNotification, 'type', T>;
|
||||
const createdAt = new Date();
|
||||
let notification: FilterUnionByProperty<MiNotification, 'type', T>;
|
||||
let redisId: string;
|
||||
|
||||
const redisIdPromise = this.redisClient.xadd(
|
||||
`notificationTimeline:${notifieeId}`,
|
||||
'MAXLEN', '~', this.config.perUserNotificationsMaxCount.toString(),
|
||||
'*',
|
||||
'data', JSON.stringify(notification));
|
||||
do {
|
||||
notification = {
|
||||
id: this.idService.gen(),
|
||||
createdAt,
|
||||
type: type,
|
||||
...(notifierId ? {
|
||||
notifierId,
|
||||
} : {}),
|
||||
...data,
|
||||
} as unknown as FilterUnionByProperty<MiNotification, 'type', T>;
|
||||
|
||||
try {
|
||||
redisId = (await this.redisClient.xadd(
|
||||
`notificationTimeline:${notifieeId}`,
|
||||
'MAXLEN', '~', this.config.perUserNotificationsMaxCount.toString(),
|
||||
this.toXListId(notification.id),
|
||||
'data', JSON.stringify(notification)))!;
|
||||
} catch (e) {
|
||||
// The ID specified in XADD is equal or smaller than the target stream top item で失敗することがあるのでリトライ
|
||||
if (e instanceof ReplyError) continue;
|
||||
throw e;
|
||||
}
|
||||
|
||||
break;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} while (true);
|
||||
|
||||
const packed = await this.notificationEntityService.pack(notification, notifieeId, {});
|
||||
|
||||
|
@ -173,7 +189,7 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
const interval = notification.type === 'test' ? 0 : 2000;
|
||||
setTimeout(interval, 'unread notification', { signal: this.#shutdownController.signal }).then(async () => {
|
||||
const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${notifieeId}`);
|
||||
if (latestReadNotificationId && (latestReadNotificationId >= (await redisIdPromise)!)) return;
|
||||
if (latestReadNotificationId && (latestReadNotificationId >= redisId)) return;
|
||||
|
||||
this.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed);
|
||||
this.pushNotificationService.pushNotification(notifieeId, 'notification', packed);
|
||||
|
@ -228,6 +244,79 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
this.#shutdownController.abort();
|
||||
}
|
||||
|
||||
private toXListId(id: string): string {
|
||||
const { date, additional } = this.idService.parseFull(id);
|
||||
return date.toString() + '-' + additional.toString();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async getNotifications(
|
||||
userId: MiUser['id'],
|
||||
{
|
||||
sinceId,
|
||||
untilId,
|
||||
limit = 20,
|
||||
includeTypes,
|
||||
excludeTypes,
|
||||
}: {
|
||||
sinceId?: string,
|
||||
untilId?: string,
|
||||
limit?: number,
|
||||
// any extra types are allowed, those are no-op
|
||||
includeTypes?: (MiNotification['type'] | string)[],
|
||||
excludeTypes?: (MiNotification['type'] | string)[],
|
||||
},
|
||||
): Promise<MiNotification[]> {
|
||||
let sinceTime = sinceId ? this.toXListId(sinceId) : null;
|
||||
let untilTime = untilId ? this.toXListId(untilId) : null;
|
||||
|
||||
let notifications: MiNotification[];
|
||||
for (;;) {
|
||||
let notificationsRes: [id: string, fields: string[]][];
|
||||
|
||||
// sinceidのみの場合は古い順、そうでない場合は新しい順。 QueryService.makePaginationQueryも参照
|
||||
if (sinceTime && !untilTime) {
|
||||
notificationsRes = await this.redisClient.xrange(
|
||||
`notificationTimeline:${userId}`,
|
||||
'(' + sinceTime,
|
||||
'+',
|
||||
'COUNT', limit);
|
||||
} else {
|
||||
notificationsRes = await this.redisClient.xrevrange(
|
||||
`notificationTimeline:${userId}`,
|
||||
untilTime ? '(' + untilTime : '+',
|
||||
sinceTime ? '(' + sinceTime : '-',
|
||||
'COUNT', limit);
|
||||
}
|
||||
|
||||
if (notificationsRes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
notifications = notificationsRes.map(x => JSON.parse(x[1][1])) as MiNotification[];
|
||||
|
||||
if (includeTypes && includeTypes.length > 0) {
|
||||
notifications = notifications.filter(notification => includeTypes.includes(notification.type));
|
||||
} else if (excludeTypes && excludeTypes.length > 0) {
|
||||
notifications = notifications.filter(notification => !excludeTypes.includes(notification.type));
|
||||
}
|
||||
|
||||
if (notifications.length !== 0) {
|
||||
// 通知が1件以上ある場合は返す
|
||||
break;
|
||||
}
|
||||
|
||||
// フィルタしたことで通知が0件になった場合、次のページを取得する
|
||||
if (sinceId && !untilId) {
|
||||
sinceTime = notificationsRes[notificationsRes.length - 1][0];
|
||||
} else {
|
||||
untilTime = notificationsRes[notificationsRes.length - 1][0];
|
||||
}
|
||||
}
|
||||
|
||||
return notifications;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public onApplicationShutdown(signal?: string | undefined): void {
|
||||
this.dispose();
|
||||
|
|
|
@ -22,6 +22,7 @@ type PushNotificationsTypes = {
|
|||
note: Packed<'Note'>;
|
||||
};
|
||||
'readAllNotifications': undefined;
|
||||
newChatMessage: Packed<'ChatMessage'>;
|
||||
};
|
||||
|
||||
// Reduce length because push message servers have character limits
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Brackets, ObjectLiteral } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository } from '@/models/_.js';
|
||||
import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository, MiMeta } from '@/models/_.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { SelectQueryBuilder } from 'typeorm';
|
||||
|
@ -36,33 +36,43 @@ export class QueryService {
|
|||
@Inject(DI.renoteMutingsRepository)
|
||||
private renoteMutingsRepository: RenoteMutingsRepository,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
public makePaginationQuery<T extends ObjectLiteral>(q: SelectQueryBuilder<T>, sinceId?: string | null, untilId?: string | null, sinceDate?: number | null, untilDate?: number | null): SelectQueryBuilder<T> {
|
||||
public makePaginationQuery<T extends ObjectLiteral>(
|
||||
q: SelectQueryBuilder<T>,
|
||||
sinceId?: string | null,
|
||||
untilId?: string | null,
|
||||
sinceDate?: number | null,
|
||||
untilDate?: number | null,
|
||||
targetColumn = 'id',
|
||||
): SelectQueryBuilder<T> {
|
||||
if (sinceId && untilId) {
|
||||
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId });
|
||||
q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId });
|
||||
q.orderBy(`${q.alias}.id`, 'DESC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} > :sinceId`, { sinceId: sinceId });
|
||||
q.andWhere(`${q.alias}.${targetColumn} < :untilId`, { untilId: untilId });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'DESC');
|
||||
} else if (sinceId) {
|
||||
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId });
|
||||
q.orderBy(`${q.alias}.id`, 'ASC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} > :sinceId`, { sinceId: sinceId });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'ASC');
|
||||
} else if (untilId) {
|
||||
q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId });
|
||||
q.orderBy(`${q.alias}.id`, 'DESC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} < :untilId`, { untilId: untilId });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'DESC');
|
||||
} else if (sinceDate && untilDate) {
|
||||
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
|
||||
q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.gen(untilDate) });
|
||||
q.orderBy(`${q.alias}.id`, 'DESC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
|
||||
q.andWhere(`${q.alias}.${targetColumn} < :untilId`, { untilId: this.idService.gen(untilDate) });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'DESC');
|
||||
} else if (sinceDate) {
|
||||
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
|
||||
q.orderBy(`${q.alias}.id`, 'ASC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'ASC');
|
||||
} else if (untilDate) {
|
||||
q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.gen(untilDate) });
|
||||
q.orderBy(`${q.alias}.id`, 'DESC');
|
||||
q.andWhere(`${q.alias}.${targetColumn} < :untilId`, { untilId: this.idService.gen(untilDate) });
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'DESC');
|
||||
} else {
|
||||
q.orderBy(`${q.alias}.id`, 'DESC');
|
||||
q.orderBy(`${q.alias}.${targetColumn}`, 'DESC');
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
@ -251,4 +261,59 @@ export class QueryService {
|
|||
|
||||
q.setParameters(mutingQuery.getParameters());
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public generateBlockedHostQueryForNote(q: SelectQueryBuilder<any>, excludeAuthor?: boolean): void {
|
||||
let nonBlockedHostQuery: (part: string) => string;
|
||||
if (this.meta.blockedHosts.length === 0) {
|
||||
nonBlockedHostQuery = () => '1=1';
|
||||
} else {
|
||||
nonBlockedHostQuery = (match: string) => `${match} NOT ILIKE ALL(ARRAY[:...blocked])`;
|
||||
q.setParameters({ blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) });
|
||||
}
|
||||
|
||||
if (excludeAuthor) {
|
||||
const instanceSuspension = (user: string) => new Brackets(qb => qb
|
||||
.where(`note.${user}Id IS NULL`) // no corresponding user
|
||||
.orWhere(`note.userId = note.${user}Id`)
|
||||
.orWhere(`note.${user}Host IS NULL`) // local
|
||||
.orWhere(nonBlockedHostQuery(`note.${user}Host`)));
|
||||
|
||||
q
|
||||
.andWhere(instanceSuspension('replyUser'))
|
||||
.andWhere(instanceSuspension('renoteUser'));
|
||||
} else {
|
||||
const instanceSuspension = (user: string) => new Brackets(qb => qb
|
||||
.where(`note.${user}Id IS NULL`) // no corresponding user
|
||||
.orWhere(`note.${user}Host IS NULL`) // local
|
||||
.orWhere(nonBlockedHostQuery(`note.${user}Host`)));
|
||||
|
||||
q
|
||||
.andWhere(instanceSuspension('user'))
|
||||
.andWhere(instanceSuspension('replyUser'))
|
||||
.andWhere(instanceSuspension('renoteUser'));
|
||||
}
|
||||
}
|
||||
|
||||
// Requirements: user replyUser renoteUser must be joined
|
||||
@bindThis
|
||||
public generateSuspendedUserQueryForNote(q: SelectQueryBuilder<any>, excludeAuthor?: boolean): void {
|
||||
if (excludeAuthor) {
|
||||
const brakets = (user: string) => new Brackets(qb => qb
|
||||
.where(`note.${user}Id IS NULL`)
|
||||
.orWhere(`user.id = ${user}.id`)
|
||||
.orWhere(`${user}.isSuspended = FALSE`));
|
||||
q
|
||||
.andWhere(brakets('replyUser'))
|
||||
.andWhere(brakets('renoteUser'));
|
||||
} else {
|
||||
const brakets = (user: string) => new Brackets(qb => qb
|
||||
.where(`note.${user}Id IS NULL`)
|
||||
.orWhere(`${user}.isSuspended = FALSE`));
|
||||
q
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.andWhere(brakets('replyUser'))
|
||||
.andWhere(brakets('renoteUser'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { MetricsTime, type JobType } from 'bullmq';
|
||||
import { parse as parseRedisInfo } from 'redis-info';
|
||||
import type { IActivity } from '@/core/activitypub/type.js';
|
||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import type { MiWebhook, WebhookEventTypes } from '@/models/Webhook.js';
|
||||
|
@ -38,6 +40,18 @@ import type {
|
|||
import type httpSignature from '@peertube/http-signature';
|
||||
import type * as Bull from 'bullmq';
|
||||
|
||||
export const QUEUE_TYPES = [
|
||||
'system',
|
||||
'endedPollNotification',
|
||||
'deliver',
|
||||
'inbox',
|
||||
'db',
|
||||
'relationship',
|
||||
'objectStorage',
|
||||
'userWebhookDeliver',
|
||||
'systemWebhookDeliver',
|
||||
] as const;
|
||||
|
||||
@Injectable()
|
||||
export class QueueService {
|
||||
constructor(
|
||||
|
@ -57,50 +71,58 @@ export class QueueService {
|
|||
this.systemQueue.add('tickCharts', {
|
||||
}, {
|
||||
repeat: { pattern: '55 * * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('resyncCharts', {
|
||||
}, {
|
||||
repeat: { pattern: '0 0 * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('cleanCharts', {
|
||||
}, {
|
||||
repeat: { pattern: '0 0 * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('aggregateRetention', {
|
||||
}, {
|
||||
repeat: { pattern: '0 0 * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('clean', {
|
||||
}, {
|
||||
repeat: { pattern: '0 0 * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('checkExpiredMutings', {
|
||||
}, {
|
||||
repeat: { pattern: '*/5 * * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('bakeBufferedReactions', {
|
||||
}, {
|
||||
repeat: { pattern: '0 0 * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
|
||||
this.systemQueue.add('checkModeratorsActivity', {
|
||||
}, {
|
||||
// 毎時30分に起動
|
||||
repeat: { pattern: '30 * * * *' },
|
||||
removeOnComplete: true,
|
||||
removeOnComplete: 10,
|
||||
removeOnFail: 30,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -122,13 +144,21 @@ export class QueueService {
|
|||
isSharedInbox,
|
||||
};
|
||||
|
||||
return this.deliverQueue.add(to, data, {
|
||||
const label = to.replace('https://', '').replace('/inbox', '');
|
||||
|
||||
return this.deliverQueue.add(label, data, {
|
||||
attempts: this.config.deliverJobMaxAttempts ?? 12,
|
||||
backoff: {
|
||||
type: 'custom',
|
||||
},
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -150,12 +180,18 @@ export class QueueService {
|
|||
backoff: {
|
||||
type: 'custom',
|
||||
},
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
};
|
||||
|
||||
await this.deliverQueue.addBulk(Array.from(inboxes.entries(), d => ({
|
||||
name: d[0],
|
||||
name: d[0].replace('https://', '').replace('/inbox', ''),
|
||||
data: {
|
||||
user,
|
||||
content: contentBody,
|
||||
|
@ -176,13 +212,21 @@ export class QueueService {
|
|||
signature,
|
||||
};
|
||||
|
||||
return this.inboxQueue.add('', data, {
|
||||
const label = (activity.id ?? '').replace('https://', '').replace('/activity', '');
|
||||
|
||||
return this.inboxQueue.add(label, data, {
|
||||
attempts: this.config.inboxJobMaxAttempts ?? 8,
|
||||
backoff: {
|
||||
type: 'custom',
|
||||
},
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -191,8 +235,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('deleteDriveFiles', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -201,8 +251,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportCustomEmojis', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -211,8 +267,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportNotes', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -221,8 +283,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportClips', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -231,8 +299,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportFavorites', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -243,8 +317,14 @@ export class QueueService {
|
|||
excludeMuting,
|
||||
excludeInactive,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -253,8 +333,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportMuting', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -263,8 +349,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportBlocking', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -273,8 +365,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportUserLists', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -283,8 +381,14 @@ export class QueueService {
|
|||
return this.dbQueue.add('exportAntennas', {
|
||||
user: { id: user.id },
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -295,8 +399,14 @@ export class QueueService {
|
|||
fileId: fileId,
|
||||
withReplies,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -312,8 +422,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
fileId: fileId,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -323,8 +439,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
fileId: fileId,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -344,8 +466,14 @@ export class QueueService {
|
|||
name,
|
||||
data,
|
||||
opts: {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -356,8 +484,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
fileId: fileId,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -367,8 +501,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
fileId: fileId,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -378,8 +518,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
antenna,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -389,8 +535,14 @@ export class QueueService {
|
|||
user: { id: user.id },
|
||||
soft: opts.soft,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -440,8 +592,14 @@ export class QueueService {
|
|||
withReplies: data.withReplies,
|
||||
},
|
||||
opts: {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
...opts,
|
||||
},
|
||||
};
|
||||
|
@ -452,16 +610,28 @@ export class QueueService {
|
|||
return this.objectStorageQueue.add('deleteFile', {
|
||||
key: key,
|
||||
}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createCleanRemoteFilesJob() {
|
||||
return this.objectStorageQueue.add('cleanRemoteFiles', {}, {
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -492,8 +662,14 @@ export class QueueService {
|
|||
backoff: {
|
||||
type: 'custom',
|
||||
},
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -523,21 +699,201 @@ export class QueueService {
|
|||
backoff: {
|
||||
type: 'custom',
|
||||
},
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
removeOnComplete: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 30,
|
||||
},
|
||||
removeOnFail: {
|
||||
age: 3600 * 24 * 7, // keep up to 7 days
|
||||
count: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public destroy() {
|
||||
this.deliverQueue.once('cleaned', (jobs, status) => {
|
||||
//deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
||||
});
|
||||
this.deliverQueue.clean(0, 0, 'delayed');
|
||||
private getQueue(type: typeof QUEUE_TYPES[number]): Bull.Queue {
|
||||
switch (type) {
|
||||
case 'system': return this.systemQueue;
|
||||
case 'endedPollNotification': return this.endedPollNotificationQueue;
|
||||
case 'deliver': return this.deliverQueue;
|
||||
case 'inbox': return this.inboxQueue;
|
||||
case 'db': return this.dbQueue;
|
||||
case 'relationship': return this.relationshipQueue;
|
||||
case 'objectStorage': return this.objectStorageQueue;
|
||||
case 'userWebhookDeliver': return this.userWebhookDeliverQueue;
|
||||
case 'systemWebhookDeliver': return this.systemWebhookDeliverQueue;
|
||||
default: throw new Error(`Unrecognized queue type: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.inboxQueue.once('cleaned', (jobs, status) => {
|
||||
//inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
||||
@bindThis
|
||||
public async queueClear(queueType: typeof QUEUE_TYPES[number], state: '*' | 'completed' | 'wait' | 'active' | 'paused' | 'prioritized' | 'delayed' | 'failed') {
|
||||
const queue = this.getQueue(queueType);
|
||||
|
||||
if (state === '*') {
|
||||
await Promise.all([
|
||||
queue.clean(0, 0, 'completed'),
|
||||
queue.clean(0, 0, 'wait'),
|
||||
queue.clean(0, 0, 'active'),
|
||||
queue.clean(0, 0, 'paused'),
|
||||
queue.clean(0, 0, 'prioritized'),
|
||||
queue.clean(0, 0, 'delayed'),
|
||||
queue.clean(0, 0, 'failed'),
|
||||
]);
|
||||
} else {
|
||||
await queue.clean(0, 0, state);
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queuePromoteJobs(queueType: typeof QUEUE_TYPES[number]) {
|
||||
const queue = this.getQueue(queueType);
|
||||
await queue.promoteJobs();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueRetryJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
|
||||
const queue = this.getQueue(queueType);
|
||||
const job: Bull.Job | null = await queue.getJob(jobId);
|
||||
if (job) {
|
||||
if (job.finishedOn != null) {
|
||||
await job.retry();
|
||||
} else {
|
||||
await job.promote();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueRemoveJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
|
||||
const queue = this.getQueue(queueType);
|
||||
const job: Bull.Job | null = await queue.getJob(jobId);
|
||||
if (job) {
|
||||
await job.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private packJobData(job: Bull.Job) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
const stacktrace = job.stacktrace ? job.stacktrace.filter(Boolean) : [];
|
||||
stacktrace.reverse();
|
||||
|
||||
return {
|
||||
id: job.id,
|
||||
name: job.name,
|
||||
data: job.data,
|
||||
opts: job.opts,
|
||||
timestamp: job.timestamp,
|
||||
processedOn: job.processedOn,
|
||||
processedBy: job.processedBy,
|
||||
finishedOn: job.finishedOn,
|
||||
progress: job.progress,
|
||||
attempts: job.attemptsMade,
|
||||
delay: job.delay,
|
||||
failedReason: job.failedReason,
|
||||
stacktrace: stacktrace,
|
||||
returnValue: job.returnvalue,
|
||||
isFailed: !!job.failedReason || (Array.isArray(stacktrace) && stacktrace.length > 0),
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueGetJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
|
||||
const queue = this.getQueue(queueType);
|
||||
const job: Bull.Job | null = await queue.getJob(jobId);
|
||||
if (job) {
|
||||
return this.packJobData(job);
|
||||
} else {
|
||||
throw new Error(`Job not found: ${jobId}`);
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueGetJobs(queueType: typeof QUEUE_TYPES[number], jobTypes: JobType[], search?: string) {
|
||||
const RETURN_LIMIT = 100;
|
||||
const queue = this.getQueue(queueType);
|
||||
let jobs: Bull.Job[];
|
||||
|
||||
if (search) {
|
||||
jobs = await queue.getJobs(jobTypes, 0, 1000);
|
||||
|
||||
jobs = jobs.filter(job => {
|
||||
const jobString = JSON.stringify(job).toLowerCase();
|
||||
return search.toLowerCase().split(' ').every(term => {
|
||||
return jobString.includes(term);
|
||||
});
|
||||
});
|
||||
|
||||
jobs = jobs.slice(0, RETURN_LIMIT);
|
||||
} else {
|
||||
jobs = await queue.getJobs(jobTypes, 0, RETURN_LIMIT);
|
||||
}
|
||||
|
||||
return jobs.map(job => this.packJobData(job));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueGetQueues() {
|
||||
const fetchings = QUEUE_TYPES.map(async type => {
|
||||
const queue = this.getQueue(type);
|
||||
|
||||
const counts = await queue.getJobCounts();
|
||||
const isPaused = await queue.isPaused();
|
||||
const metrics_completed = await queue.getMetrics('completed', 0, MetricsTime.ONE_WEEK);
|
||||
const metrics_failed = await queue.getMetrics('failed', 0, MetricsTime.ONE_WEEK);
|
||||
|
||||
return {
|
||||
name: type,
|
||||
counts: counts,
|
||||
isPaused,
|
||||
metrics: {
|
||||
completed: metrics_completed,
|
||||
failed: metrics_failed,
|
||||
},
|
||||
};
|
||||
});
|
||||
this.inboxQueue.clean(0, 0, 'delayed');
|
||||
|
||||
return await Promise.all(fetchings);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async queueGetQueue(queueType: typeof QUEUE_TYPES[number]) {
|
||||
const queue = this.getQueue(queueType);
|
||||
const counts = await queue.getJobCounts();
|
||||
const isPaused = await queue.isPaused();
|
||||
const metrics_completed = await queue.getMetrics('completed', 0, MetricsTime.ONE_WEEK);
|
||||
const metrics_failed = await queue.getMetrics('failed', 0, MetricsTime.ONE_WEEK);
|
||||
const db = parseRedisInfo(await (await queue.client).info());
|
||||
|
||||
return {
|
||||
name: queueType,
|
||||
qualifiedName: queue.qualifiedName,
|
||||
counts: counts,
|
||||
isPaused,
|
||||
metrics: {
|
||||
completed: metrics_completed,
|
||||
failed: metrics_failed,
|
||||
},
|
||||
db: {
|
||||
version: db.redis_version,
|
||||
mode: db.redis_mode,
|
||||
runId: db.run_id,
|
||||
processId: db.process_id,
|
||||
port: parseInt(db.tcp_port),
|
||||
os: db.os,
|
||||
uptime: parseInt(db.uptime_in_seconds),
|
||||
memory: {
|
||||
total: parseInt(db.total_system_memory) || parseInt(db.maxmemory),
|
||||
used: parseInt(db.used_memory),
|
||||
fragmentationRatio: parseInt(db.mem_fragmentation_ratio),
|
||||
peak: parseInt(db.used_memory_peak),
|
||||
},
|
||||
clients: {
|
||||
connected: parseInt(db.connected_clients),
|
||||
blocked: parseInt(db.blocked_clients),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ export type RolePolicies = {
|
|||
canUseTranslator: boolean;
|
||||
canHideAds: boolean;
|
||||
driveCapacityMb: number;
|
||||
maxFileSizeMb: number;
|
||||
alwaysMarkNsfw: boolean;
|
||||
canUpdateBioMedia: boolean;
|
||||
pinLimit: number;
|
||||
|
@ -63,7 +64,7 @@ export type RolePolicies = {
|
|||
canImportFollowing: boolean;
|
||||
canImportMuting: boolean;
|
||||
canImportUserLists: boolean;
|
||||
canChat: boolean;
|
||||
chatAvailability: 'available' | 'readonly' | 'unavailable';
|
||||
};
|
||||
|
||||
export const DEFAULT_POLICIES: RolePolicies = {
|
||||
|
@ -81,6 +82,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
|||
canUseTranslator: true,
|
||||
canHideAds: false,
|
||||
driveCapacityMb: 100,
|
||||
maxFileSizeMb: 10,
|
||||
alwaysMarkNsfw: false,
|
||||
canUpdateBioMedia: true,
|
||||
pinLimit: 5,
|
||||
|
@ -98,7 +100,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
|||
canImportFollowing: true,
|
||||
canImportMuting: true,
|
||||
canImportUserLists: true,
|
||||
canChat: true,
|
||||
chatAvailability: 'available',
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
|
@ -370,6 +372,12 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
return aggregate(policies.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
|
||||
}
|
||||
|
||||
function aggregateChatAvailability(vs: RolePolicies['chatAvailability'][]) {
|
||||
if (vs.some(v => v === 'available')) return 'available';
|
||||
if (vs.some(v => v === 'readonly')) return 'readonly';
|
||||
return 'unavailable';
|
||||
}
|
||||
|
||||
return {
|
||||
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
|
||||
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
|
||||
|
@ -385,6 +393,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
|
||||
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
|
||||
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
|
||||
maxFileSizeMb: calc('maxFileSizeMb', vs => Math.max(...vs)),
|
||||
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
|
||||
canUpdateBioMedia: calc('canUpdateBioMedia', vs => vs.some(v => v === true)),
|
||||
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
||||
|
@ -402,7 +411,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
canImportFollowing: calc('canImportFollowing', vs => vs.some(v => v === true)),
|
||||
canImportMuting: calc('canImportMuting', vs => vs.some(v => v === true)),
|
||||
canImportUserLists: calc('canImportUserLists', vs => vs.some(v => v === true)),
|
||||
canChat: calc('canChat', vs => vs.some(v => v === true)),
|
||||
chatAvailability: calc('chatAvailability', aggregateChatAvailability),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -630,6 +639,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
isModerator: values.isModerator,
|
||||
isExplorable: values.isExplorable,
|
||||
asBadge: values.asBadge,
|
||||
preserveAssignmentOnMoveAccount: values.preserveAssignmentOnMoveAccount,
|
||||
canEditMembersByModerator: values.canEditMembersByModerator,
|
||||
displayOrder: values.displayOrder,
|
||||
policies: values.policies,
|
||||
|
|
|
@ -234,6 +234,8 @@ export class SearchService {
|
|||
}
|
||||
|
||||
this.queryService.generateVisibilityQuery(query, me);
|
||||
this.queryService.generateBlockedHostQueryForNote(query);
|
||||
this.queryService.generateSuspendedUserQueryForNote(query);
|
||||
if (me) this.queryService.generateMutedUserQueryForNotes(query, me);
|
||||
if (me) this.queryService.generateBlockedUserQueryForNotes(query, me);
|
||||
|
||||
|
@ -295,9 +297,20 @@ export class SearchService {
|
|||
this.cacheService.userBlockedCache.fetch(me.id),
|
||||
])
|
||||
: [new Set<string>(), new Set<string>()];
|
||||
const notes = (await this.notesRepository.findBy({
|
||||
id: In(res.hits.map(x => x.id)),
|
||||
})).filter(note => {
|
||||
|
||||
const query = this.notesRepository.createQueryBuilder('note')
|
||||
.innerJoinAndSelect('note.user', 'user')
|
||||
.leftJoinAndSelect('note.reply', 'reply')
|
||||
.leftJoinAndSelect('note.renote', 'renote')
|
||||
.leftJoinAndSelect('reply.user', 'replyUser')
|
||||
.leftJoinAndSelect('renote.user', 'renoteUser');
|
||||
|
||||
query.where('note.id IN (:...noteIds)', { noteIds: res.hits.map(x => x.id) });
|
||||
|
||||
this.queryService.generateBlockedHostQueryForNote(query);
|
||||
this.queryService.generateSuspendedUserQueryForNote(query);
|
||||
|
||||
const notes = (await query.getMany()).filter(note => {
|
||||
if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false;
|
||||
if (me && isUserRelated(note, userIdsWhoMeMuting)) return false;
|
||||
return true;
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
import { DataSource, IsNull } from 'typeorm';
|
||||
import * as Redis from 'ioredis';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { MiLocalUser, MiUser } from '@/models/User.js';
|
||||
import { MiSystemAccount, MiUsedUsername, MiUserKeypair, MiUserProfile, type UsersRepository, type SystemAccountsRepository } from '@/models/_.js';
|
||||
import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { MemoryKVCache } from '@/misc/cache.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
@ -20,10 +23,13 @@ import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
|
|||
export const SYSTEM_ACCOUNT_TYPES = ['actor', 'relay', 'proxy'] as const;
|
||||
|
||||
@Injectable()
|
||||
export class SystemAccountService {
|
||||
export class SystemAccountService implements OnApplicationShutdown {
|
||||
private cache: MemoryKVCache<MiLocalUser>;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.redisForSub)
|
||||
private redisForSub: Redis.Redis,
|
||||
|
||||
@Inject(DI.db)
|
||||
private db: DataSource,
|
||||
|
||||
|
@ -42,6 +48,31 @@ export class SystemAccountService {
|
|||
private idService: IdService,
|
||||
) {
|
||||
this.cache = new MemoryKVCache<MiLocalUser>(1000 * 60 * 10); // 10m
|
||||
|
||||
this.redisForSub.on('message', this.onMessage);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async onMessage(_: string, data: string): Promise<void> {
|
||||
const obj = JSON.parse(data);
|
||||
|
||||
if (obj.channel === 'internal') {
|
||||
const { type, body } = obj.message as GlobalEvents['internal']['payload'];
|
||||
switch (type) {
|
||||
case 'metaUpdated': {
|
||||
if (body.before != null && body.before.name !== body.after.name) {
|
||||
for (const account of SYSTEM_ACCOUNT_TYPES) {
|
||||
await this.updateCorrespondingUserProfile(account, {
|
||||
name: body.after.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@ -145,7 +176,7 @@ export class SystemAccountService {
|
|||
|
||||
@bindThis
|
||||
public async updateCorrespondingUserProfile(type: typeof SYSTEM_ACCOUNT_TYPES[number], extra: {
|
||||
name?: string;
|
||||
name?: string | null;
|
||||
description?: MiUserProfile['description'];
|
||||
}): Promise<MiLocalUser> {
|
||||
const user = await this.fetch(type);
|
||||
|
@ -169,4 +200,15 @@ export class SystemAccountService {
|
|||
|
||||
return updated;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public dispose(): void {
|
||||
this.redisForSub.off('message', this.onMessage);
|
||||
this.cache.dispose();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public onApplicationShutdown(signal?: string): void {
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
import { URL, domainToASCII } from 'node:url';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import RE2 from 're2';
|
||||
import semver from 'semver';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { MiMeta } from '@/models/Meta.js';
|
||||
import { MiMeta, SoftwareSuspension } from '@/models/Meta.js';
|
||||
import { MiInstance } from '@/models/Instance.js';
|
||||
|
||||
@Injectable()
|
||||
export class UtilityService {
|
||||
|
@ -143,4 +145,20 @@ export class UtilityService {
|
|||
const host = this.extractDbHost(uri);
|
||||
return this.isFederationAllowedHost(host);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isDeliverSuspendedSoftware(software: Pick<MiInstance, 'softwareName' | 'softwareVersion'>): SoftwareSuspension | undefined {
|
||||
if (software.softwareName == null) return undefined;
|
||||
if (software.softwareVersion == null) {
|
||||
// software version is null; suspend iff versionRange is *
|
||||
return this.meta.deliverSuspendedSoftware.find(x =>
|
||||
x.software === software.softwareName
|
||||
&& x.versionRange.trim() === '*');
|
||||
} else {
|
||||
const softwareVersion = software.softwareVersion;
|
||||
return this.meta.deliverSuspendedSoftware.find(x =>
|
||||
x.software === software.softwareName
|
||||
&& semver.satisfies(softwareVersion, x.versionRange, { includePrerelease: true }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -411,8 +411,8 @@ export class WebhookTestService {
|
|||
name: user.name,
|
||||
username: user.username,
|
||||
host: user.host,
|
||||
avatarUrl: user.avatarUrl,
|
||||
avatarBlurhash: user.avatarBlurhash,
|
||||
avatarUrl: user.avatarId == null ? null : user.avatarUrl,
|
||||
avatarBlurhash: user.avatarId == null ? null : user.avatarBlurhash,
|
||||
avatarDecorations: user.avatarDecorations.map(it => ({
|
||||
id: it.id,
|
||||
angle: it.angle,
|
||||
|
@ -441,8 +441,8 @@ export class WebhookTestService {
|
|||
createdAt: new Date().toISOString(),
|
||||
updatedAt: user.updatedAt?.toISOString() ?? null,
|
||||
lastFetchedAt: user.lastFetchedAt?.toISOString() ?? null,
|
||||
bannerUrl: user.bannerUrl,
|
||||
bannerBlurhash: user.bannerBlurhash,
|
||||
bannerUrl: user.bannerId == null ? null : user.bannerUrl,
|
||||
bannerBlurhash: user.bannerId == null ? null : user.bannerBlurhash,
|
||||
isLocked: user.isLocked,
|
||||
isSilenced: false,
|
||||
isSuspended: user.isSuspended,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import * as mfm from 'mfm-js';
|
||||
import { MfmService } from '@/core/MfmService.js';
|
||||
import { MfmService, Appender } from '@/core/MfmService.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { extractApHashtagObjects } from './models/tag.js';
|
||||
|
@ -25,17 +25,17 @@ export class ApMfmService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public getNoteHtml(note: Pick<MiNote, 'text' | 'mentionedRemoteUsers'>, apAppend?: string) {
|
||||
public getNoteHtml(note: Pick<MiNote, 'text' | 'mentionedRemoteUsers'>, additionalAppender: Appender[] = []) {
|
||||
let noMisskeyContent = false;
|
||||
const srcMfm = (note.text ?? '') + (apAppend ?? '');
|
||||
const srcMfm = (note.text ?? '');
|
||||
|
||||
const parsed = mfm.parse(srcMfm);
|
||||
|
||||
if (!apAppend && parsed?.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) {
|
||||
if (!additionalAppender.length && parsed.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) {
|
||||
noMisskeyContent = true;
|
||||
}
|
||||
|
||||
const content = this.mfmService.toHtml(parsed, JSON.parse(note.mentionedRemoteUsers));
|
||||
const content = this.mfmService.toHtml(parsed, JSON.parse(note.mentionedRemoteUsers), additionalAppender);
|
||||
|
||||
return {
|
||||
content,
|
||||
|
|
|
@ -19,7 +19,7 @@ import type { MiEmoji } from '@/models/Emoji.js';
|
|||
import type { MiPoll } from '@/models/Poll.js';
|
||||
import type { MiPollVote } from '@/models/PollVote.js';
|
||||
import { UserKeypairService } from '@/core/UserKeypairService.js';
|
||||
import { MfmService } from '@/core/MfmService.js';
|
||||
import { MfmService, type Appender } from '@/core/MfmService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||
import type { MiUserKeypair } from '@/models/UserKeypair.js';
|
||||
|
@ -430,10 +430,24 @@ export class ApRendererService {
|
|||
poll = await this.pollsRepository.findOneBy({ noteId: note.id });
|
||||
}
|
||||
|
||||
let apAppend = '';
|
||||
const apAppend: Appender[] = [];
|
||||
|
||||
if (quote) {
|
||||
apAppend += `\n\nRE: ${quote}`;
|
||||
// Append quote link as `<br><br><span class="quote-inline">RE: <a href="...">...</a></span>`
|
||||
// the claas name `quote-inline` is used in non-misskey clients for styling quote notes.
|
||||
// For compatibility, the span part should be kept as possible.
|
||||
apAppend.push((doc, body) => {
|
||||
body.appendChild(doc.createElement('br'));
|
||||
body.appendChild(doc.createElement('br'));
|
||||
const span = doc.createElement('span');
|
||||
span.className = 'quote-inline';
|
||||
span.appendChild(doc.createTextNode('RE: '));
|
||||
const link = doc.createElement('a');
|
||||
link.setAttribute('href', quote);
|
||||
link.textContent = quote;
|
||||
span.appendChild(link);
|
||||
body.appendChild(span);
|
||||
});
|
||||
}
|
||||
|
||||
const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;
|
||||
|
@ -509,7 +523,7 @@ export class ApRendererService {
|
|||
const urlPart = match[0];
|
||||
const urlPartParsed = new URL(urlPart);
|
||||
const restPart = maybeUrl.slice(match[0].length);
|
||||
|
||||
|
||||
return `<a href="${urlPartParsed.href}" rel="me nofollow noopener" target="_blank">${urlPart}</a>${restPart}`;
|
||||
} catch (e) {
|
||||
return maybeUrl;
|
||||
|
|
|
@ -41,6 +41,7 @@ export class AntennaEntityService {
|
|||
excludeBots: antenna.excludeBots,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
excludeNotesInSensitiveChannel: antenna.excludeNotesInSensitiveChannel,
|
||||
isActive: antenna.isActive,
|
||||
hasUnreadNote: false, // TODO
|
||||
notify: false, // 後方互換性のため
|
||||
|
|
|
@ -128,7 +128,7 @@ export class ChatEntityService {
|
|||
packedFiles: Map<MiChatMessage['fileId'], Packed<'DriveFile'> | null>;
|
||||
};
|
||||
},
|
||||
): Promise<Packed<'ChatMessageLite'>> {
|
||||
): Promise<Packed<'ChatMessageLiteFor1on1'>> {
|
||||
const packedFiles = options?._hint_?.packedFiles;
|
||||
|
||||
const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src });
|
||||
|
@ -147,7 +147,7 @@ export class ChatEntityService {
|
|||
createdAt: this.idService.parse(message.id).date.toISOString(),
|
||||
text: message.text,
|
||||
fromUserId: message.fromUserId,
|
||||
toUserId: message.toUserId,
|
||||
toUserId: message.toUserId!,
|
||||
fileId: message.fileId,
|
||||
file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null,
|
||||
reactions,
|
||||
|
@ -177,7 +177,7 @@ export class ChatEntityService {
|
|||
packedUsers: Map<MiUser['id'], Packed<'UserLite'>>;
|
||||
};
|
||||
},
|
||||
): Promise<Packed<'ChatMessageLite'>> {
|
||||
): Promise<Packed<'ChatMessageLiteForRoom'>> {
|
||||
const packedFiles = options?._hint_?.packedFiles;
|
||||
const packedUsers = options?._hint_?.packedUsers;
|
||||
|
||||
|
@ -199,7 +199,7 @@ export class ChatEntityService {
|
|||
text: message.text,
|
||||
fromUserId: message.fromUserId,
|
||||
fromUser: packedUsers?.get(message.fromUserId) ?? await this.userEntityService.pack(message.fromUser ?? message.fromUserId),
|
||||
toRoomId: message.toRoomId,
|
||||
toRoomId: message.toRoomId!,
|
||||
fileId: message.fileId,
|
||||
file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null,
|
||||
reactions,
|
||||
|
@ -238,13 +238,15 @@ export class ChatEntityService {
|
|||
options?: {
|
||||
_hint_?: {
|
||||
packedOwners: Map<MiChatRoom['id'], Packed<'UserLite'>>;
|
||||
memberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
|
||||
myMemberships?: Map<MiChatRoom['id'], MiChatRoomMembership | null | undefined>;
|
||||
myInvitations?: Map<MiChatRoom['id'], MiChatRoomInvitation | null | undefined>;
|
||||
};
|
||||
},
|
||||
): Promise<Packed<'ChatRoom'>> {
|
||||
const room = typeof src === 'object' ? src : await this.chatRoomsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
const membership = me && me.id !== room.ownerId ? (options?._hint_?.memberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
||||
const membership = me && me.id !== room.ownerId ? (options?._hint_?.myMemberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
||||
const invitation = me && me.id !== room.ownerId ? (options?._hint_?.myInvitations?.get(room.id) ?? await this.chatRoomInvitationsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null;
|
||||
|
||||
return {
|
||||
id: room.id,
|
||||
|
@ -254,6 +256,7 @@ export class ChatEntityService {
|
|||
ownerId: room.ownerId,
|
||||
owner: options?._hint_?.packedOwners.get(room.ownerId) ?? await this.userEntityService.pack(room.owner ?? room.ownerId, me),
|
||||
isMuted: membership != null ? membership.isMuted : false,
|
||||
invitationExists: invitation != null,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -278,7 +281,7 @@ export class ChatEntityService {
|
|||
|
||||
const owners = _rooms.map(x => x.owner ?? x.ownerId);
|
||||
|
||||
const [packedOwners, memberships] = await Promise.all([
|
||||
const [packedOwners, myMemberships, myInvitations] = await Promise.all([
|
||||
this.userEntityService.packMany(owners, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u]))),
|
||||
this.chatRoomMembershipsRepository.find({
|
||||
|
@ -287,9 +290,15 @@ export class ChatEntityService {
|
|||
userId: me.id,
|
||||
},
|
||||
}).then(memberships => new Map(_rooms.map(r => [r.id, memberships.find(m => m.roomId === r.id)]))),
|
||||
this.chatRoomInvitationsRepository.find({
|
||||
where: {
|
||||
roomId: In(_rooms.map(x => x.id)),
|
||||
userId: me.id,
|
||||
},
|
||||
}).then(invitations => new Map(_rooms.map(r => [r.id, invitations.find(i => i.roomId === r.id)]))),
|
||||
]);
|
||||
|
||||
return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, memberships } })));
|
||||
return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, myMemberships, myInvitations } })));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
@ -31,6 +31,7 @@ export class InstanceEntityService {
|
|||
me?: { id: MiUser['id']; } | null | undefined,
|
||||
): Promise<Packed<'FederationInstance'>> {
|
||||
const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false;
|
||||
const softwareSuspended = this.utilityService.isDeliverSuspendedSoftware(instance);
|
||||
|
||||
return {
|
||||
id: instance.id,
|
||||
|
@ -41,8 +42,8 @@ export class InstanceEntityService {
|
|||
followingCount: instance.followingCount,
|
||||
followersCount: instance.followersCount,
|
||||
isNotResponding: instance.isNotResponding,
|
||||
isSuspended: instance.suspensionState !== 'none',
|
||||
suspensionState: instance.suspensionState,
|
||||
isSuspended: instance.suspensionState !== 'none' || Boolean(softwareSuspended),
|
||||
suspensionState: instance.suspensionState === 'none' && softwareSuspended ? 'softwareSuspended' : instance.suspensionState,
|
||||
isBlocked: this.utilityService.isBlockedHost(this.meta.blockedHosts, instance.host),
|
||||
softwareName: instance.softwareName,
|
||||
softwareVersion: instance.softwareVersion,
|
||||
|
|
|
@ -127,6 +127,7 @@ export class MetaEntityService {
|
|||
|
||||
policies: { ...DEFAULT_POLICIES, ...instance.policies },
|
||||
|
||||
sentryForFrontend: this.config.sentryForFrontend ?? null,
|
||||
mediaProxy: this.config.mediaProxy,
|
||||
enableUrlPreview: instance.urlPreviewEnabled,
|
||||
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
|
||||
|
|
|
@ -429,6 +429,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
userId: channel.userId,
|
||||
} : undefined,
|
||||
mentions: note.mentions.length > 0 ? note.mentions : undefined,
|
||||
hasPoll: note.hasPoll || undefined,
|
||||
uri: note.uri ?? undefined,
|
||||
url: note.url ?? undefined,
|
||||
|
||||
|
@ -593,4 +594,42 @@ export class NoteEntityService implements OnModuleInit {
|
|||
relations: ['user'],
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async fetchDiffs(noteIds: MiNote['id'][]) {
|
||||
if (noteIds.length === 0) return [];
|
||||
|
||||
const notes = await this.notesRepository.find({
|
||||
where: {
|
||||
id: In(noteIds),
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
userHost: true,
|
||||
reactions: true,
|
||||
reactionAndUserPairCache: true,
|
||||
},
|
||||
});
|
||||
|
||||
const bufferedReactionsMap = this.meta.enableReactionsBuffering ? await this.reactionsBufferingService.getMany(noteIds) : null;
|
||||
|
||||
const packings = notes.map(note => {
|
||||
const bufferedReactions = bufferedReactionsMap?.get(note.id);
|
||||
//const reactionAndUserPairCache = note.reactionAndUserPairCache.concat(bufferedReactions.pairs.map(x => x.join('/')));
|
||||
|
||||
const reactions = this.reactionService.convertLegacyReactions(this.reactionsBufferingService.mergeReactions(note.reactions, bufferedReactions?.deltas ?? {}));
|
||||
|
||||
const reactionEmojiNames = Object.keys(reactions)
|
||||
.filter(x => x.startsWith(':') && x.includes('@') && !x.includes('@.')) // リモートカスタム絵文字のみ
|
||||
.map(x => this.reactionService.decodeReaction(x).reaction.replaceAll(':', ''));
|
||||
|
||||
return this.customEmojiService.populateEmojis(reactionEmojiNames, note.userHost).then(reactionEmojis => ({
|
||||
id: note.id,
|
||||
reactions,
|
||||
reactionEmojis,
|
||||
}));
|
||||
});
|
||||
|
||||
return await Promise.all(packings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import type { MiRole } from '@/models/Role.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { Packed } from '@/misc/json-schema.js';
|
||||
|
||||
@Injectable()
|
||||
export class RoleEntityService {
|
||||
|
@ -31,7 +32,7 @@ export class RoleEntityService {
|
|||
public async pack(
|
||||
src: MiRole['id'] | MiRole,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'Role'>> {
|
||||
const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src });
|
||||
|
||||
const assignedCount = await this.roleAssignmentsRepository.createQueryBuilder('assign')
|
||||
|
@ -67,6 +68,7 @@ export class RoleEntityService {
|
|||
isModerator: role.isModerator,
|
||||
isExplorable: role.isExplorable,
|
||||
asBadge: role.asBadge,
|
||||
preserveAssignmentOnMoveAccount: role.preserveAssignmentOnMoveAccount,
|
||||
canEditMembersByModerator: role.canEditMembersByModerator,
|
||||
displayOrder: role.displayOrder,
|
||||
policies: policies,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue