mirror of
https://github.com/sim1222/misskey.git
synced 2025-04-28 18:27:21 +09:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
299527dc10
17
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
Normal file
17
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- ℹ お読みください / README
|
||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
# What
|
||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||
<!-- What did you do with this PR? How will it change things? -->
|
||||
|
||||
# Why
|
||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||
|
||||
# Additional info (optional)
|
||||
<!-- テスト観点など -->
|
||||
<!-- Test perspective, etc -->
|
10
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
Normal file
10
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# Summary
|
||||
This is a release PR.
|
||||
|
||||
For more information on the release instructions, please see:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release
|
||||
|
||||
# Checklist
|
||||
- [ ] package.jsonのバージョンが正しく更新されている
|
||||
- [ ] CHANGELOGが過不足無く更新されている
|
||||
- [ ] CIが全て通っている
|
34
.github/workflows/pr-preview-destroy.yml
vendored
34
.github/workflows/pr-preview-destroy.yml
vendored
@ -9,14 +9,46 @@ name: Destroy preview environment
|
||||
jobs:
|
||||
destroy-preview-environment:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == github.event.pull_request.head.repo.full_name
|
||||
steps:
|
||||
- uses: actions/github-script@v6.3.3
|
||||
id: check-conclusion
|
||||
env:
|
||||
number: ${{ github.event.number }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-encoding: string
|
||||
script: |
|
||||
const { data: pull } = await github.rest.pulls.get({
|
||||
...context.repo,
|
||||
pull_number: process.env.number
|
||||
});
|
||||
const ref = pull.head.sha;
|
||||
|
||||
const { data: checks } = await github.rest.checks.listForRef({
|
||||
...context.repo,
|
||||
ref
|
||||
});
|
||||
|
||||
const check = checks.check_runs.filter(c => c.name === 'deploy-preview-environment');
|
||||
|
||||
if (check.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: result } = await github.rest.checks.get({
|
||||
...context.repo,
|
||||
check_run_id: check[0].id,
|
||||
});
|
||||
|
||||
return result.conclusion;
|
||||
- name: Context
|
||||
if: steps.check-conclusion.outputs.result == 'success'
|
||||
uses: okteto/context@latest
|
||||
with:
|
||||
token: ${{ secrets.OKTETO_TOKEN }}
|
||||
|
||||
- name: Destroy preview environment
|
||||
if: steps.check-conclusion.outputs.result == 'success'
|
||||
uses: okteto/destroy-preview@latest
|
||||
with:
|
||||
name: pr-${{ github.event.number }}-syuilo
|
||||
|
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -2,5 +2,8 @@
|
||||
"search.exclude": {
|
||||
"**/node_modules": true
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"files.associations": {
|
||||
"*.test.ts": "typescript"
|
||||
}
|
||||
}
|
26
CHANGELOG.md
26
CHANGELOG.md
@ -2,17 +2,41 @@
|
||||
## 13.x.x (unreleased)
|
||||
|
||||
### Improvements
|
||||
-
|
||||
|
||||
### Bugfixes
|
||||
-
|
||||
|
||||
You should also include the user name that made the change.
|
||||
-->
|
||||
## 13.7.4 (unreleased)
|
||||
## 13.x.x (unreleased)
|
||||
|
||||
### Improvements
|
||||
- チャンネル内ハイライト
|
||||
- renoteした際の表示を改善
|
||||
- バックグラウンドで一定時間経過したらページネーションのアイテム更新をしない
|
||||
- enhance(client): MkUrlPreviewの閉じるボタンを見やすく
|
||||
- Add dialog to remove follower
|
||||
- enhance(client): improve clip menu ux
|
||||
- 検索画面の統合
|
||||
- enhance(client): ノートメニューからユーザーメニューを開けるように
|
||||
- photoswipe 表示時に戻る操作をしても前の画面に戻らないように
|
||||
|
||||
### Bugfixes
|
||||
- Windows環境でswcを使うと正しくビルドできない問題の修正
|
||||
- fix(client): Android ChromeでPWAとしてインストールできない問題を修正
|
||||
- 未知のユーザーが deleteActor されたら処理をスキップする
|
||||
- fix(server): notes/createで、fileIdsと見つかったファイルの数が異なる場合はエラーにする
|
||||
|
||||
## 13.7.5 (2023/02/24)
|
||||
|
||||
### Note
|
||||
13.7.0以前から直接このバージョンにアップデートする場合は全ての通知が削除**されません。**
|
||||
|
||||
### Improvements
|
||||
- 紛らわしいため公開範囲の「ローカルのみ」オプションの名称を「連合なし」に変更
|
||||
- Frontend: スマホ・タブレットの場合、チャンネルの投稿フォームに自動でフォーカスしないように
|
||||
|
||||
### Bugfixes
|
||||
- 全ての通知が削除されてしまうのを修正
|
||||
|
||||
|
@ -88,6 +88,13 @@ An actual domain will be assigned so you can test the federation.
|
||||
- The target branch must be `master`
|
||||
- The tag name must be the version
|
||||
|
||||
> **Note**
|
||||
> Why this instruction is necessary:
|
||||
> - To perform final QA checks
|
||||
> - To distribute responsibility
|
||||
> - To check direct commits to develop
|
||||
> - To celebrate the release together 🎉
|
||||
|
||||
## Localization (l10n)
|
||||
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
|
||||
You can improve our translations with your Crowdin account.
|
||||
@ -292,6 +299,27 @@ pnpm dlx typeorm migration:generate -d ormconfig.js -o <migration name>
|
||||
- 生成後、ファイルをmigration下に移してください
|
||||
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
||||
|
||||
### JSON SchemaのobjectでanyOfを使うとき
|
||||
JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。
|
||||
バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます)
|
||||
https://github.com/misskey-dev/misskey/pull/10082
|
||||
|
||||
テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合:
|
||||
|
||||
```
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hoge: { type: 'string', minLength: 1 },
|
||||
fuga: { type: 'string', minLength: 1 },
|
||||
},
|
||||
anyOf: [
|
||||
{ required: ['hoge'] },
|
||||
{ required: ['fuga'] },
|
||||
],
|
||||
} as const;
|
||||
```
|
||||
|
||||
### コネクションには`markRaw`せよ
|
||||
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
only_pulls: true
|
||||
project: false
|
||||
patch: false
|
||||
|
@ -379,13 +379,10 @@ about: "عن"
|
||||
aboutMisskey: "عن Misskey"
|
||||
administrator: "المدير"
|
||||
token: "الرمز المميز"
|
||||
twoStepAuthentication: "الإستيثاق بعاملَيْن"
|
||||
moderator: "مشرِف"
|
||||
moderation: "الإشراف"
|
||||
nUsersMentioned: "{n} مستخدمين أُشير إليهم"
|
||||
securityKey: "مفتاح الأمان"
|
||||
securityKeyName: "اسم المفتاح"
|
||||
registerSecurityKey: "سجل مفتاح أمان"
|
||||
lastUsed: "آخر استخدام"
|
||||
unregister: "إلغاء التسجيل"
|
||||
passwordLessLogin: "لِج مِن دون كلمة سرية"
|
||||
@ -403,24 +400,15 @@ markAsReadAllTalkMessages: "علّم جميع الرسائل كمقروءة"
|
||||
help: "المساعدة"
|
||||
inputMessageHere: "اكتب رسالتك هنا"
|
||||
close: "اغلق"
|
||||
group: "الفريق"
|
||||
groups: "الفِرَق"
|
||||
createGroup: "انشئ فريقًا"
|
||||
ownedGroups: "فِرقي"
|
||||
joinedGroups: "الفِرق المُنضم إليها"
|
||||
invites: "دعوة"
|
||||
groupName: "اسم الفريق"
|
||||
members: "الأعضاء"
|
||||
transfer: "نقل"
|
||||
messagingWithUser: "تحدث مع مستخدم"
|
||||
messagingWithGroup: "محادثة جماعية"
|
||||
title: "العنوان"
|
||||
text: "النص"
|
||||
enable: "تشغيل"
|
||||
next: "التالية"
|
||||
retype: "أعد الكتابة"
|
||||
noteOf: "ملاحظات {user}"
|
||||
inviteToGroup: "دعوة إلى فريق"
|
||||
quoteAttached: "اِقتُبسَ"
|
||||
quoteQuestion: "أتريد تضمينها كاقتباس"
|
||||
noMessagesYet: "ليس هناك رسائل بعد"
|
||||
@ -442,14 +430,10 @@ passwordMatched: "التطابق صحيح!"
|
||||
passwordNotMatched: "غير متطابقتان"
|
||||
signinWith: "الولوج عبر {x}"
|
||||
signinFailed: "فشل الولوج، خطأ في اسم المستخدم أو كلمة المرور."
|
||||
tapSecurityKey: "أنقر مفتاح الأمان"
|
||||
or: "أو"
|
||||
language: "اللغة"
|
||||
uiLanguage: "لغة واجهة المستخدم"
|
||||
groupInvited: "دُعيت إلى فريقٍ"
|
||||
aboutX: "عن {x}"
|
||||
youHaveNoGroups: "لا تمتلك أية فِرَق"
|
||||
joinOrCreateGroup: "احصل على دعوة لفريق أو أنشئ واحدًا."
|
||||
noHistory: "السجل فارغ"
|
||||
signinHistory: "تاريخ تسجيل الدخول"
|
||||
doing: "انتظر لحظة"
|
||||
@ -790,8 +774,6 @@ deleteAccountConfirm: "سيحذف حسابك نهائيًا، أتريد الم
|
||||
incorrectPassword: "كلمة السر خاطئة."
|
||||
voteConfirm: "متيقِّن من تصويتك لـ {choice}؟"
|
||||
hide: "إخفاء"
|
||||
leaveGroup: "مغادرة الفريق"
|
||||
leaveGroupConfirm: "متيقن من مغادرة \"{name}\"؟"
|
||||
welcomeBackWithName: "مرحبًا بك مجددًا {name}"
|
||||
clickToFinishEmailVerification: "انقر [{ok}] لاستيثاق بريدك الإلكتروني."
|
||||
overridedDeviceKind: "نوع الجهاز"
|
||||
@ -989,6 +971,7 @@ _ago:
|
||||
weeksAgo: "منذ {n} أسابيع"
|
||||
monthsAgo: "منذ {n} أشهر"
|
||||
yearsAgo: "منذ {n} سنوات"
|
||||
invalid: "لا يوجد شيء هنا"
|
||||
_time:
|
||||
second: "ثا"
|
||||
minute: "د"
|
||||
@ -1019,12 +1002,11 @@ _tutorial:
|
||||
step7_3: "حظًا سعيدًا واستمتع بوقتك مع ميسكي! 🚀"
|
||||
_2fa:
|
||||
alreadyRegistered: "سجلت سلفًا جهازًا للاستيثاق بعاملين."
|
||||
registerDevice: "سجّل جهازًا جديدًا"
|
||||
registerKey: "تسجيل مفتاح أمان جديد"
|
||||
step1: "أولًا ثبّت تطبيق استيثاق على جهازك (مثل {a} و{b})."
|
||||
step2: "امسح رمز الاستجابة السريعة الموجد على الشاشة."
|
||||
step3: "أدخل الرمز الموجود في تطبيقك لإكمال التثبيت."
|
||||
step4: "من هذه اللحظة أثناء ولوجك سيُطلب منك الرمز."
|
||||
renewTOTPCancel: "ليس اﻵن"
|
||||
_permissions:
|
||||
"read:account": "اعرض معلومات حسابك"
|
||||
"write:account": "تعديل معلومات حسابك"
|
||||
@ -1133,8 +1115,6 @@ _visibility:
|
||||
followersDescription: "اجعلها مرئية لمتابِعيك فقط"
|
||||
specified: "مباشرة"
|
||||
specifiedDescription: "اجعلها مرئية لمستخدمين محددين"
|
||||
localOnly: "المحلي فقط"
|
||||
localOnlyDescription: "ليس مرئيًا للمستخدمين البِعاد"
|
||||
_postForm:
|
||||
replyPlaceholder: "رد على هذه الملاحظة…"
|
||||
quotePlaceholder: "اقتبس هذه الملاحظة…"
|
||||
@ -1255,12 +1235,9 @@ _notification:
|
||||
youGotReply: "ردّ عليك {name}"
|
||||
youGotQuote: "اقتبس منك {name}"
|
||||
youRenoted: "إعادت نشر من {name}"
|
||||
youGotMessagingMessageFromUser: "لقد تلقيت رسالة مِن {name}"
|
||||
youGotMessagingMessageFromGroup: "لقد أرسِلَت رسالة إلى الفريق {name}"
|
||||
youWereFollowed: "يتابعك"
|
||||
youReceivedFollowRequest: "تلقيتَ طلب متابعة"
|
||||
yourFollowRequestAccepted: "قُبل طلب المتابعة"
|
||||
youWereInvitedToGroup: "دُعيت إلى فريقٍ"
|
||||
pollEnded: "ظهرت نتائج الاستطلاع"
|
||||
unreadAntennaNote: "هوائي {name}"
|
||||
_types:
|
||||
@ -1273,7 +1250,6 @@ _notification:
|
||||
reaction: "التفاعلات"
|
||||
receiveFollowRequest: "طلبات المتابعة المتلقاة"
|
||||
followRequestAccepted: "طلبات المتابعة المقبولة"
|
||||
groupInvited: "دعوات الفريق"
|
||||
app: "إشعارات التطبيقات المرتبطة"
|
||||
_actions:
|
||||
followBack: "تابعك بالمثل"
|
||||
|
@ -382,12 +382,9 @@ about: "আপনার সম্পর্কে"
|
||||
aboutMisskey: "Misskey সম্পর্কে"
|
||||
administrator: "প্রশাসক"
|
||||
token: "টোকেন"
|
||||
twoStepAuthentication: "২-ধাপ প্রমাণীকরণ"
|
||||
moderator: "মডারেটর"
|
||||
nUsersMentioned: "{n} জনকে উল্লেখ করা হয়েছে"
|
||||
securityKey: "সিকিউরিটি কী"
|
||||
securityKeyName: "কী'র নাম"
|
||||
registerSecurityKey: "সিকিউরিটি কী নিবন্ধন করুন"
|
||||
lastUsed: "শেষ ব্যাবহার করা হয়েছে"
|
||||
unregister: "নিবন্ধনমুক্ত হন"
|
||||
passwordLessLogin: "পাসওয়ার্ড-বিহীন লগইন সেট আপ করুন"
|
||||
@ -405,24 +402,15 @@ markAsReadAllTalkMessages: "সমস্ত মেসেজ পঠিত হি
|
||||
help: "সহায়তা"
|
||||
inputMessageHere: "এখানে মেসেজ লিখুন"
|
||||
close: "বন্ধ"
|
||||
group: "গ্রুপ"
|
||||
groups: "গ্রুপসমূহ"
|
||||
createGroup: "গ্রুপ তৈরী করুন"
|
||||
ownedGroups: "আপনার গ্রুপগুলি"
|
||||
joinedGroups: "যেসব গ্রুপে আপনি আছেন"
|
||||
invites: "আমন্ত্রণ"
|
||||
groupName: "গ্রুপের নাম"
|
||||
members: "সদস্যবৃন্দ"
|
||||
transfer: "হস্তান্তর"
|
||||
messagingWithUser: "প্রাইভেট চ্যাট"
|
||||
messagingWithGroup: "গ্রুপ চ্যাট"
|
||||
title: "শিরোনাম"
|
||||
text: "পাঠ্য"
|
||||
enable: "সক্রিয়"
|
||||
next: "পরবর্তী"
|
||||
retype: "পুনঃ প্রবেশ"
|
||||
noteOf: "{user} এর নোট"
|
||||
inviteToGroup: "গ্রুপে আমন্ত্রণ জানান"
|
||||
quoteAttached: "উদ্ধৃত"
|
||||
quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
|
||||
noMessagesYet: "কোন মেসেজ নেই"
|
||||
@ -444,15 +432,11 @@ passwordMatched: "মিলেছে"
|
||||
passwordNotMatched: "মিলেনি"
|
||||
signinWith: "{x} এর সাহায্যে সাইন ইন করুন"
|
||||
signinFailed: "লগ ইন করা যায়নি। আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেক করুন."
|
||||
tapSecurityKey: "সিকিউরিটি কী স্পর্শ করুন"
|
||||
or: "অথবা"
|
||||
language: "ভাষা"
|
||||
uiLanguage: "UI এর ভাষা"
|
||||
groupInvited: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
|
||||
aboutX: "{x} সম্পর্কে"
|
||||
disableDrawer: "ড্রয়ার মেনু প্রদর্শন করবেন না"
|
||||
youHaveNoGroups: "আপনার কোন গ্রুপ নেই "
|
||||
joinOrCreateGroup: "একটি বিদ্যমান গ্রুপের আমন্ত্রণ পান বা একটি নতুন গ্রুপ তৈরি করুন৷"
|
||||
noHistory: "কোনো ইতিহাস নেই"
|
||||
signinHistory: "প্রবেশ করার ইতিহাস"
|
||||
doing: "প্রক্রিয়া করছে..."
|
||||
@ -820,8 +804,6 @@ deleteAccountConfirm: "আপনার অ্যাকাউন্ট মুছ
|
||||
incorrectPassword: "আপনার দেওয়া পাসওয়ার্ডটি ভুল।"
|
||||
voteConfirm: "\"{choice}\" এ ভোট দিতে চান?"
|
||||
hide: "লুকান"
|
||||
leaveGroup: "গ্রুপ ছেড়ে চলে যান"
|
||||
leaveGroupConfirm: "\"{name}\" গ্রুপ ছেড়ে চলে যেতে চান?"
|
||||
useDrawerReactionPickerForMobile: "মোবাইলে রিঅ্যাকশন পিকারকে ড্রয়ারে প্রদর্শন করুন"
|
||||
welcomeBackWithName: "আবার স্বাগতম, {name}"
|
||||
clickToFinishEmailVerification: " [{ok}] ক্লিক করার মাধ্যমে আপনার ইমেল ঠিকানা নিশ্চিত করুন।"
|
||||
@ -1051,6 +1033,7 @@ _ago:
|
||||
weeksAgo: "{n} সপ্তাহ আগে"
|
||||
monthsAgo: "{n} মাস আগে"
|
||||
yearsAgo: "{n} বছর আগে"
|
||||
invalid: "এখানে কিছুই নাই"
|
||||
_time:
|
||||
second: "সেকেন্ড"
|
||||
minute: "মিনিট"
|
||||
@ -1081,8 +1064,6 @@ _tutorial:
|
||||
step7_3: "এখন Misskey উপভোগ করুন 🚀"
|
||||
_2fa:
|
||||
alreadyRegistered: "আপনি ইতিমধ্যে একটি 2-ফ্যাক্টর অথেনটিকেশন ডিভাইস নিবন্ধন করেছেন৷"
|
||||
registerDevice: "নতুন ডিভাইস নিবন্ধন করুন"
|
||||
registerKey: "সিকিউরিটি কী নিবন্ধন করুন"
|
||||
step1: "প্রথমে, আপনার ডিভাইসে {a} বা {b} এর মতো একটি অথেনটিকেশন অ্যাপ ইনস্টল করুন৷"
|
||||
step2: "এরপরে, অ্যাপের সাহায্যে প্রদর্শিত QR কোডটি স্ক্যান করুন।"
|
||||
step2Url: "ডেস্কটপ অ্যাপে, নিম্নলিখিত URL লিখুন:"
|
||||
@ -1134,7 +1115,6 @@ _antennaSources:
|
||||
homeTimeline: "আপনি অনুসরণ করছেন, এমন ব্যবহারকারীদের নোট"
|
||||
users: "এক বা একাধিক নির্দিষ্ট ব্যবহারকারীর নোট"
|
||||
userList: "নির্দিষ্ট তালিকায় নাম থাকা ব্যবহারকারীদের নোট"
|
||||
userGroup: "নির্দিষ্ট গ্রুপে থাকা ব্যবহারকারীদের নোট"
|
||||
_weekday:
|
||||
sunday: "রবিবার"
|
||||
monday: "সোমবার"
|
||||
@ -1203,8 +1183,6 @@ _visibility:
|
||||
followersDescription: "শুধুমাত্র আপনার অনুসরণকারীদের নিকট পোস্ট করুন"
|
||||
specified: "ডাইরেক্ট নোট"
|
||||
specifiedDescription: "শুধুমাত্র নির্দিষ্ট ব্যাবহারকারীর নিকট পাঠান"
|
||||
localOnly: "শুধুমাত্র লোকাল"
|
||||
localOnlyDescription: "রিমোট ব্যাবহারকারীদের নিকট দৃশ্যমান নয়"
|
||||
_postForm:
|
||||
replyPlaceholder: "নোটটির জবাব দিন..."
|
||||
quotePlaceholder: "নোটটিকে উদ্ধৃত করুন..."
|
||||
@ -1332,12 +1310,9 @@ _notification:
|
||||
youGotReply: "{name} আপনাকে জবাব দিয়েছে"
|
||||
youGotQuote: "{name} আপনাকে উদ্ধৃত করেছে"
|
||||
youRenoted: "{name} এর Renote"
|
||||
youGotMessagingMessageFromUser: "{name} আপনাকে মেসেজ করেছে"
|
||||
youGotMessagingMessageFromGroup: "{name} গ্রুপে একটি নতুন মেসেজ আছে"
|
||||
youWereFollowed: "আপনাকে অনুসরণ করছে"
|
||||
youReceivedFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
||||
yourFollowRequestAccepted: "আপনার অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
||||
youWereInvitedToGroup: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
|
||||
pollEnded: "পোলের ফলাফল দেখা যাবে"
|
||||
emptyPushNotificationMessage: "আপডেট করা পুশ বিজ্ঞপ্তি"
|
||||
_types:
|
||||
@ -1351,7 +1326,6 @@ _notification:
|
||||
pollEnded: "পোল শেষ"
|
||||
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
|
||||
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
|
||||
groupInvited: "গ্রুপের আমন্ত্রনসমূহ"
|
||||
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
|
||||
_actions:
|
||||
followBack: "ফলো ব্যাক করেছে"
|
||||
|
@ -315,13 +315,10 @@ userList: "Llistes"
|
||||
about: "Informació"
|
||||
aboutMisskey: "Quant a Misskey"
|
||||
administrator: "Administrador/a"
|
||||
twoStepAuthentication: "Verificació en dos passos"
|
||||
moderator: "Moderador/a"
|
||||
moderation: "Moderació"
|
||||
nUsersMentioned: "{n} usuaris mencionats"
|
||||
securityKey: "Clau de seguretat"
|
||||
securityKeyName: "Nom de la clau"
|
||||
registerSecurityKey: "Registra la clau de seguretat"
|
||||
unregister: "Cancel·la el registre"
|
||||
passwordLessLogin: "Inici de sessió sense contrasenya"
|
||||
resetPassword: "Restableix la contrasenya"
|
||||
@ -334,7 +331,6 @@ help: "Ajuda"
|
||||
invites: "Convida"
|
||||
next: "Següent"
|
||||
noteOf: "Publicació de: {user}"
|
||||
inviteToGroup: "Convida'l al grup"
|
||||
invitations: "Convida"
|
||||
tags: "Etiquetes"
|
||||
docSource: "Font del document"
|
||||
@ -393,7 +389,6 @@ _antennaSources:
|
||||
homeTimeline: "Publicacions dels usuaris seguits"
|
||||
users: "Publicacions d'usuaris específics"
|
||||
userList: "Publicacions d'una llista d'usuaris"
|
||||
userGroup: "Publicacions d'usuaris d'un grup"
|
||||
_widgets:
|
||||
profile: "Perfil"
|
||||
instanceInfo: "Informació del fitxer d'instal·lació"
|
||||
|
@ -337,12 +337,9 @@ about: "Informace"
|
||||
aboutMisskey: "O Misskey"
|
||||
administrator: "Administrátor"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Dvoufaktorová autentikace"
|
||||
moderator: "Moderátor"
|
||||
nUsersMentioned: "{n} uživatelů zmínilo"
|
||||
securityKey: "Bezpečnostní klíč"
|
||||
securityKeyName: "Název klíče"
|
||||
registerSecurityKey: "Registrovat bezpečnostní klíč"
|
||||
lastUsed: "Naposledy použito"
|
||||
unregister: "Odstranit"
|
||||
resetPassword: "Resetovat heslo"
|
||||
@ -359,13 +356,7 @@ markAsReadAllTalkMessages: "Označit všechny zprávy za přečtené"
|
||||
help: "Nápověda"
|
||||
inputMessageHere: "Sem zadejte zprávu"
|
||||
close: "Zavřít"
|
||||
group: "Skupina"
|
||||
groups: "Skupiny"
|
||||
createGroup: "Vytvořit skupinu"
|
||||
ownedGroups: "Vlastněné skupiny"
|
||||
joinedGroups: "Členství ve skupinách"
|
||||
invites: "Pozvat"
|
||||
groupName: "Název skupiny"
|
||||
members: "Členové"
|
||||
transfer: "Převod"
|
||||
title: "Titulek"
|
||||
@ -374,7 +365,6 @@ enable: "Povolit"
|
||||
next: "Další"
|
||||
retype: "Zadejte znovu"
|
||||
noteOf: "{user} poznámky"
|
||||
inviteToGroup: "Pozvat do skupiny"
|
||||
quoteAttached: "Citace"
|
||||
quoteQuestion: "Přiložit jako citaci?"
|
||||
noMessagesYet: "Zatím tu nejsou žádné zprávy"
|
||||
@ -396,14 +386,10 @@ passwordMatched: "Hesla se schodují"
|
||||
passwordNotMatched: "Hesla se neschodují"
|
||||
signinWith: "Přihlásit se s {x}"
|
||||
signinFailed: "Nelze se přihlásit. Zkontrolujte prosím své uživatelské jméno a heslo."
|
||||
tapSecurityKey: "Ťukněte na bezpečnostní klíč"
|
||||
or: "Nebo"
|
||||
language: "Jazyk"
|
||||
uiLanguage: "Jazyk uživatelského rozhraní"
|
||||
groupInvited: "Pozvat do skupiny"
|
||||
aboutX: "O {x}"
|
||||
youHaveNoGroups: "Nemáte žádné skupiny"
|
||||
joinOrCreateGroup: "Můžete požádat o pozvání do stávající skupiny nebo vytvořit novou."
|
||||
noHistory: "Žádná historie"
|
||||
signinHistory: "Historie přihlášení"
|
||||
category: "Kategorie"
|
||||
@ -673,13 +659,11 @@ _sfx:
|
||||
_ago:
|
||||
future: "Budoucí"
|
||||
justNow: "Teď"
|
||||
invalid: "Nic nebylo nalezeno"
|
||||
_time:
|
||||
second: "Sekund"
|
||||
minute: "Minut"
|
||||
hour: "Hodin"
|
||||
_2fa:
|
||||
registerDevice: "Přidat zařízení"
|
||||
registerKey: "Přidat bezpečnostní klíč"
|
||||
_weekday:
|
||||
sunday: "Neděle"
|
||||
monday: "Pondělí"
|
||||
@ -773,7 +757,6 @@ _pages:
|
||||
button: "Tlačítko"
|
||||
_notification:
|
||||
youWereFollowed: "Máte nového následovníka"
|
||||
youWereInvitedToGroup: "Pozvat do skupiny"
|
||||
_types:
|
||||
all: "Vše"
|
||||
follow: "Sledovaní"
|
||||
|
@ -393,16 +393,19 @@ about: "Über"
|
||||
aboutMisskey: "Über Misskey"
|
||||
administrator: "Administrator"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Zwei-Faktor-Authentifizierung"
|
||||
2fa: "Zwei-Faktor-Authentifizierung"
|
||||
totp: "Authentifizierungs-App"
|
||||
totpDescription: "Logge dich via Authentifizierungs-App mit Einmalpasswort ein"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderation"
|
||||
nUsersMentioned: "Von {n} Benutzern erwähnt"
|
||||
securityKeyAndPasskey: "Security-Tokens und Passkeys"
|
||||
securityKey: "Sicherheitsschlüssel"
|
||||
securityKeyName: "Schlüsselname"
|
||||
registerSecurityKey: "Sicherheitsschlüssel registrieren"
|
||||
lastUsed: "Zuletzt benutzt"
|
||||
lastUsedAt: "Zuletzt verwendet: {t}"
|
||||
unregister: "Deaktivieren"
|
||||
passwordLessLogin: "Passwortloses Anmelden einrichten"
|
||||
passwordLessLoginDescription: "Ermöglicht passwortfreies Einloggen, nur via Security-Token oder Passkey"
|
||||
resetPassword: "Passwort zurücksetzen"
|
||||
newPasswordIs: "Das neue Passwort ist „{password}“"
|
||||
reduceUiAnimation: "Animationen der Benutzeroberfläche reduzieren"
|
||||
@ -417,24 +420,15 @@ markAsReadAllTalkMessages: "Alle Chats als gelesen markieren"
|
||||
help: "Hilfe"
|
||||
inputMessageHere: "Hier Nachricht eingeben"
|
||||
close: "Schließen"
|
||||
group: "Gruppe"
|
||||
groups: "Gruppen"
|
||||
createGroup: "Gruppe erstellen"
|
||||
ownedGroups: "Meine Gruppen"
|
||||
joinedGroups: "Beigetretene Gruppen"
|
||||
invites: "Einladungen"
|
||||
groupName: "Gruppenname"
|
||||
members: "Mitglieder"
|
||||
transfer: "Übertragen"
|
||||
messagingWithUser: "Privatchat"
|
||||
messagingWithGroup: "Gruppenchat"
|
||||
title: "Titel"
|
||||
text: "Text"
|
||||
enable: "Aktivieren"
|
||||
next: "Weiter"
|
||||
retype: "Erneut eingeben"
|
||||
noteOf: "Notiz von {user}"
|
||||
inviteToGroup: "Zu Gruppe einladen"
|
||||
quoteAttached: "Zitat"
|
||||
quoteQuestion: "Als Zitat anhängen?"
|
||||
noMessagesYet: "Noch keine Nachrichten vorhanden"
|
||||
@ -456,17 +450,13 @@ passwordMatched: "Stimmt überein"
|
||||
passwordNotMatched: "Stimmt nicht überein"
|
||||
signinWith: "Mit {x} anmelden"
|
||||
signinFailed: "Anmeldung fehlgeschlagen. Überprüfe Benutzername und Passswort."
|
||||
tapSecurityKey: "Tippe deinen Sicherheitsschlüssel an"
|
||||
or: "Oder"
|
||||
language: "Sprache"
|
||||
uiLanguage: "Sprache der Benutzeroberfläche"
|
||||
groupInvited: "Du wurdest in eine Gruppe eingeladen"
|
||||
aboutX: "Über {x}"
|
||||
emojiStyle: "Emoji-Stil"
|
||||
native: "Nativ"
|
||||
disableDrawer: "Keine ausfahrbaren Menüs verwenden"
|
||||
youHaveNoGroups: "Keine Gruppen vorhanden"
|
||||
joinOrCreateGroup: "Lass dich zu einer Gruppe einladen oder erstelle deine eigene."
|
||||
noHistory: "Kein Verlauf gefunden"
|
||||
signinHistory: "Anmeldungsverlauf"
|
||||
enableAdvancedMfm: "Erweitertes MFM aktivieren"
|
||||
@ -789,6 +779,7 @@ popularPosts: "Beliebte Beiträge"
|
||||
shareWithNote: "Mit Notiz teilen"
|
||||
ads: "Werbung"
|
||||
expiration: "Frist"
|
||||
startingperiod: "Start"
|
||||
memo: "Merkzettel"
|
||||
priority: "Priorität"
|
||||
high: "Hoch"
|
||||
@ -821,6 +812,7 @@ lastCommunication: "Letzte Kommunikation"
|
||||
resolved: "Gelöst"
|
||||
unresolved: "Ungelöst"
|
||||
breakFollow: "Follower entfernen"
|
||||
breakFollowConfirm: "Diesen Follower wirklich entfernen?"
|
||||
itsOn: "Eingeschaltet"
|
||||
itsOff: "Ausgeschaltet"
|
||||
emailRequiredForSignup: "Angabe einer Email-Adresse als benötigt markieren"
|
||||
@ -840,8 +832,6 @@ deleteAccountConfirm: "Dein Benutzerkonto wird unwiderruflich gelöscht. Trotzde
|
||||
incorrectPassword: "Falsches Passwort."
|
||||
voteConfirm: "Wirklich für „{choice}“ abstimmen?"
|
||||
hide: "Inhalt verbergen"
|
||||
leaveGroup: "Gruppe verlassen"
|
||||
leaveGroupConfirm: "Möchtest du „{name}“ wirklich verlassen?"
|
||||
useDrawerReactionPickerForMobile: "Auf mobilen Geräten ausfahrbare Reaktionsauswahl anzeigen"
|
||||
welcomeBackWithName: "Willkommen zurück, {name}"
|
||||
clickToFinishEmailVerification: "Drücke bitte auf [{ok}], um die Email-Bestätigung abzuschließen."
|
||||
@ -957,6 +947,10 @@ collapseRenotes: "Bereits gesehene Renotes verkürzt anzeigen"
|
||||
internalServerError: "Serverinterner Fehler"
|
||||
internalServerErrorDescription: "Im Server ist ein unerwarteter Fehler aufgetreten."
|
||||
copyErrorInfo: "Fehlerdetails kopieren"
|
||||
joinThisServer: "Bei dieser Instanz registrieren"
|
||||
exploreOtherServers: "Eine andere Instanz finden"
|
||||
letsLookAtTimeline: "Die Chronik durchstöbern"
|
||||
disableFederationWarn: "Dies deaktiviert Föderation, aber alle Notizen bleiben, sofern nicht umgestellt, öffentlich. In den meisten Fällen wird diese Option nicht benötigt."
|
||||
_achievements:
|
||||
earnedAt: "Freigeschaltet am"
|
||||
_types:
|
||||
@ -1470,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "vor {n} Woche(n)"
|
||||
monthsAgo: "vor {n} Monat(en)"
|
||||
yearsAgo: "vor {n} Jahr(en)"
|
||||
invalid: "Ungültig"
|
||||
_time:
|
||||
second: "Sekunde(n)"
|
||||
minute: "Minute(n)"
|
||||
@ -1503,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "Diese Einstellung kannst du jederzeit ändern."
|
||||
_2fa:
|
||||
alreadyRegistered: "Du hast bereits ein Gerät für Zwei-Faktor-Authentifizierung registriert."
|
||||
registerDevice: "Neues Gerät registrieren"
|
||||
registerKey: "Neuen Sicherheitsschlüssel registrieren"
|
||||
registerTOTP: "Authentifizierungs-App registrieren"
|
||||
passwordToTOTP: "Bitte Passwort eingeben"
|
||||
step1: "Installiere zuerst eine Authentifizierungsapp (z.B. {a} oder {b}) auf deinem Gerät."
|
||||
step2: "Dann, scanne den angezeigten QR-Code mit deinem Gerät."
|
||||
step2Click: "Durch Klicken dieses QR-Codes kannst du Verifikation mit deinem Security-Token oder einer App registrieren."
|
||||
step2Url: "Nutzt du ein Desktopprogramm kannst du alternativ diese URL eingeben:"
|
||||
step3Title: "Authentifizierungsscode eingeben"
|
||||
step3: "Gib zum Abschluss den Token ein, der von deiner App angezeigt wird."
|
||||
step4: "Alle folgenden Anmeldungsversuche werden ab sofort die Eingabe eines solchen Tokens benötigen."
|
||||
securityKeyNotSupported: "Dein Browser unterstützt keine Security-Tokens."
|
||||
registerTOTPBeforeKey: "Um einen Security-Token oder einen Passkey zu registrieren, musst du zuerst eine Authentifizierungs-App registrieren."
|
||||
securityKeyInfo: "Du kannst neben Fingerabdruck- oder PIN-Authentifizierung auf deinem Gerät auch Anmeldung mit Hilfe eines FIDO2-kompatiblen Hardware-Sicherheitsschlüssels einrichten."
|
||||
chromePasskeyNotSupported: "Chrome-Passkeys werden zur Zeit nicht unterstützt."
|
||||
registerSecurityKey: "Security-Token oder Passkey registrieren"
|
||||
securityKeyName: "Schlüsselname eingeben"
|
||||
tapSecurityKey: "Bitten folge den Anweisungen deines Browsers zur Registrierung"
|
||||
removeKey: "Sicherheitsschlüssel entfernen"
|
||||
removeKeyConfirm: "Den Schlüssel {name} wirklich löschen?"
|
||||
whyTOTPOnlyRenew: "Solange ein Sicherheitsschlüssel registriert ist, kann die Authentifizierungs-App nicht entfernt werden."
|
||||
renewTOTP: "Authentifizierungs-App neu einrichten"
|
||||
renewTOTPConfirm: "Codes der bisherigen App werden hierdurch nutzlos"
|
||||
renewTOTPOk: "Neu einrichten"
|
||||
renewTOTPCancel: "Abbrechen"
|
||||
_permissions:
|
||||
"read:account": "Deine Benutzerkontoinformationen lesen"
|
||||
"write:account": "Deine Benutzerkontoinformationen bearbeiten"
|
||||
@ -1559,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "Notizen von Benutzern, denen gefolgt wird"
|
||||
users: "Notizen von einem oder mehreren angegebenen Benutzern"
|
||||
userList: "Notizen von allen Benutzern einer Liste"
|
||||
userGroup: "Notizen von allen Benutzern einer Gruppe"
|
||||
_weekday:
|
||||
sunday: "Sonntag"
|
||||
monday: "Montag"
|
||||
@ -1634,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "Nur für Follower sichtbar"
|
||||
specified: "Direkt"
|
||||
specifiedDescription: "Nur für bestimmte Benutzer sichtbar"
|
||||
localOnly: "Nur Lokal"
|
||||
localOnlyDescription: "Unsichtbar für Benutzer anderer Instanzen"
|
||||
disableFederation: "Deförderiert"
|
||||
disableFederationDescription: "Nicht an andere Instanzen übertragen"
|
||||
_postForm:
|
||||
replyPlaceholder: "Dieser Notiz antworten …"
|
||||
quotePlaceholder: "Diese Notiz zitieren …"
|
||||
@ -1773,12 +1782,9 @@ _notification:
|
||||
youGotReply: "{name} hat dir geantwortet"
|
||||
youGotQuote: "{name} hat dich zitiert"
|
||||
youRenoted: "Renote deiner Notiz von {name}"
|
||||
youGotMessagingMessageFromUser: "{name} hat dir eine Chatnachricht gesendet"
|
||||
youGotMessagingMessageFromGroup: "In die Gruppe {name} wurde eine Chatnachricht gesendet"
|
||||
youWereFollowed: "ist dir gefolgt"
|
||||
youReceivedFollowRequest: "Du hast eine Follow-Anfrage erhalten"
|
||||
yourFollowRequestAccepted: "Deine Follow-Anfrage wurde akzeptiert"
|
||||
youWereInvitedToGroup: "{userName} hat dich in eine Gruppe eingeladen"
|
||||
pollEnded: "Umfrageergebnisse sind verfügbar"
|
||||
unreadAntennaNote: "Antenne {name}"
|
||||
emptyPushNotificationMessage: "Push-Benachrichtigungen wurden aktualisiert"
|
||||
@ -1794,7 +1800,7 @@ _notification:
|
||||
pollEnded: "Ende von Umfragen"
|
||||
receiveFollowRequest: "Erhaltene Follow-Anfragen"
|
||||
followRequestAccepted: "Akzeptierte Follow-Anfragen"
|
||||
groupInvited: "Erhaltene Gruppeneinladungen"
|
||||
achievementEarned: "Errungenschaft freigeschaltet"
|
||||
app: "Benachrichtigungen von Apps"
|
||||
_actions:
|
||||
followBack: "folgt dir nun auch"
|
||||
@ -1827,3 +1833,6 @@ _deck:
|
||||
channel: "Kanal"
|
||||
mentions: "Erwähnungen"
|
||||
direct: "Direktnachrichten"
|
||||
_dialog:
|
||||
charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}"
|
||||
charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}"
|
||||
|
@ -230,21 +230,13 @@ moderator: "Συντονιστής"
|
||||
moderation: "Συντονισμός"
|
||||
cacheClear: "Εκκαθάριση προσωρινής μνήμης"
|
||||
markAsReadAllNotifications: "Όλες οι ειδοποιήσεις διαβάστηκαν"
|
||||
group: "Ομάδα"
|
||||
groups: "Ομάδες"
|
||||
createGroup: "Δημιουργία ομάδας"
|
||||
ownedGroups: "Οι ομάδες σας"
|
||||
groupName: "Όνομα ομάδας"
|
||||
members: "Μέλη"
|
||||
transfer: "Μεταφορά"
|
||||
messagingWithUser: "Ιδιωτική συνομιλία"
|
||||
messagingWithGroup: "Ομαδική συνομιλία"
|
||||
title: "Τίτλος"
|
||||
text: "Κείμενο"
|
||||
enable: "Ενεργοποίηση"
|
||||
next: "Επόμενο"
|
||||
noteOf: "Σημείωμα από {user}"
|
||||
inviteToGroup: "Πρόσκληση στην ομάδα"
|
||||
quoteAttached: "Παράθεση"
|
||||
signinRequired: "Παρακαλούμε δημιουργήστε λογαριασμό ή συνδεθείτε πριν συνεχίσετε"
|
||||
category: "Κατηγορία"
|
||||
@ -337,7 +329,6 @@ _antennaSources:
|
||||
homeTimeline: "Σημειώματα από μέλη που ακολουθείτε"
|
||||
users: "Σημειώματα από συγκεκριμένα μέλη"
|
||||
userList: "Σημειώματα από καθορισμένη λίστα μελών"
|
||||
userGroup: "Σημειώματα από μέλη καθορισμένης ομάδας"
|
||||
_widgets:
|
||||
profile: "Προφίλ"
|
||||
instanceInfo: "Πληροφορίες του instance"
|
||||
@ -382,7 +373,6 @@ _pages:
|
||||
blocks:
|
||||
image: "Εικόνες"
|
||||
_notification:
|
||||
youGotMessagingMessageFromUser: "{name} σάς έστειλε ένα μήνυμα συνομιλίας"
|
||||
youWereFollowed: "σε ακολούθησε"
|
||||
_types:
|
||||
follow: "Νέοι ακόλουθοι"
|
||||
|
@ -393,16 +393,19 @@ about: "About"
|
||||
aboutMisskey: "About Misskey"
|
||||
administrator: "Administrator"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Two-factor authentication"
|
||||
2fa: "Two-factor authentication"
|
||||
totp: "Authenticator App"
|
||||
totpDescription: "Use an authenticator app to enter one-time passwords"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderation"
|
||||
nUsersMentioned: "Mentioned by {n} users"
|
||||
securityKeyAndPasskey: "Security- and passkeys"
|
||||
securityKey: "Security key"
|
||||
securityKeyName: "Key name"
|
||||
registerSecurityKey: "Register a security key"
|
||||
lastUsed: "Last used"
|
||||
lastUsedAt: "Last used: {t}"
|
||||
unregister: "Unregister"
|
||||
passwordLessLogin: "Password-less login"
|
||||
passwordLessLoginDescription: "Allows password-less login using a security- or passkey only"
|
||||
resetPassword: "Reset password"
|
||||
newPasswordIs: "The new password is \"{password}\""
|
||||
reduceUiAnimation: "Reduce UI animations"
|
||||
@ -417,24 +420,15 @@ markAsReadAllTalkMessages: "Mark all messages as read"
|
||||
help: "Help"
|
||||
inputMessageHere: "Enter message here"
|
||||
close: "Close"
|
||||
group: "Group"
|
||||
groups: "Groups"
|
||||
createGroup: "Create a group"
|
||||
ownedGroups: "Owned Groups"
|
||||
joinedGroups: "Joined groups"
|
||||
invites: "Invites"
|
||||
groupName: "Group name"
|
||||
members: "Members"
|
||||
transfer: "Transfer"
|
||||
messagingWithUser: "Private chat"
|
||||
messagingWithGroup: "Group chat"
|
||||
title: "Title"
|
||||
text: "Text"
|
||||
enable: "Enable"
|
||||
next: "Next"
|
||||
retype: "Enter again"
|
||||
noteOf: "Note by {user}"
|
||||
inviteToGroup: "Invite to group"
|
||||
quoteAttached: "Quote"
|
||||
quoteQuestion: "Append as quote?"
|
||||
noMessagesYet: "No messages yet"
|
||||
@ -456,17 +450,13 @@ passwordMatched: "Matches"
|
||||
passwordNotMatched: "Does not match"
|
||||
signinWith: "Sign in with {x}"
|
||||
signinFailed: "Unable to sign in. The entered username or password is incorrect."
|
||||
tapSecurityKey: "Tap your security key"
|
||||
or: "Or"
|
||||
language: "Language"
|
||||
uiLanguage: "User interface language"
|
||||
groupInvited: "You've been invited to a group"
|
||||
aboutX: "About {x}"
|
||||
emojiStyle: "Emoji style"
|
||||
native: "Native"
|
||||
disableDrawer: "Don't use drawer-style menus"
|
||||
youHaveNoGroups: "You have no groups"
|
||||
joinOrCreateGroup: "Get invited to a group or create your own."
|
||||
noHistory: "No history available"
|
||||
signinHistory: "Login history"
|
||||
enableAdvancedMfm: "Enable advanced MFM"
|
||||
@ -789,6 +779,7 @@ popularPosts: "Popular posts"
|
||||
shareWithNote: "Share with note"
|
||||
ads: "Advertisements"
|
||||
expiration: "Deadline"
|
||||
startingperiod: "Start"
|
||||
memo: "Memo"
|
||||
priority: "Priority"
|
||||
high: "High"
|
||||
@ -821,6 +812,7 @@ lastCommunication: "Last communication"
|
||||
resolved: "Resolved"
|
||||
unresolved: "Unresolved"
|
||||
breakFollow: "Remove follower"
|
||||
breakFollowConfirm: "Really remove this follower?"
|
||||
itsOn: "Enabled"
|
||||
itsOff: "Disabled"
|
||||
emailRequiredForSignup: "Require email address for sign-up"
|
||||
@ -840,8 +832,6 @@ deleteAccountConfirm: "This will irreversibly delete your account. Proceed?"
|
||||
incorrectPassword: "Incorrect password."
|
||||
voteConfirm: "Confirm your vote for \"{choice}\"?"
|
||||
hide: "Hide"
|
||||
leaveGroup: "Leave group"
|
||||
leaveGroupConfirm: "Are you sure you want to leave \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Display reaction picker as drawer on mobile"
|
||||
welcomeBackWithName: "Welcome back, {name}"
|
||||
clickToFinishEmailVerification: "Please click [{ok}] to complete email verification."
|
||||
@ -957,6 +947,10 @@ collapseRenotes: "Collapse renotes you've already seen"
|
||||
internalServerError: "Internal Server Error"
|
||||
internalServerErrorDescription: "The server has run into an unexpected error."
|
||||
copyErrorInfo: "Copy error details"
|
||||
joinThisServer: "Sign up at this instance"
|
||||
exploreOtherServers: "Look for another instance"
|
||||
letsLookAtTimeline: "Have a look at the timeline"
|
||||
disableFederationWarn: "This will disable federation, but posts will continue to be public unless set otherwise. You usually do not need to use this setting."
|
||||
_achievements:
|
||||
earnedAt: "Unlocked at"
|
||||
_types:
|
||||
@ -1165,7 +1159,7 @@ _achievements:
|
||||
description: "You've clicked here"
|
||||
_justPlainLucky:
|
||||
title: "Just Plain Lucky"
|
||||
description: "Has a chance to be obtained with a probability of 0.01% every 10 seconds"
|
||||
description: "Has a chance to be obtained with a probability of 0.005% every 10 seconds"
|
||||
_setNameToSyuilo:
|
||||
title: "God Complex"
|
||||
description: "Set your name to \"syuilo\""
|
||||
@ -1470,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "{n}w ago"
|
||||
monthsAgo: "{n}mo ago"
|
||||
yearsAgo: "{n}y ago"
|
||||
invalid: "None"
|
||||
_time:
|
||||
second: "Second(s)"
|
||||
minute: "Minute(s)"
|
||||
@ -1503,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "You can always change this setting later."
|
||||
_2fa:
|
||||
alreadyRegistered: "You have already registered a 2-factor authentication device."
|
||||
registerDevice: "Register a new device"
|
||||
registerKey: "Register a security key"
|
||||
registerTOTP: "Register authenticator app"
|
||||
passwordToTOTP: "Enter your password"
|
||||
step1: "First, install an authentication app (such as {a} or {b}) on your device."
|
||||
step2: "Then, scan the QR code displayed on this screen."
|
||||
step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app."
|
||||
step2Url: "You can also enter this URL if you're using a desktop program:"
|
||||
step3Title: "Enter an authentication code"
|
||||
step3: "Enter the token provided by your app to finish setup."
|
||||
step4: "From now on, any future login attempts will ask for such a login token."
|
||||
securityKeyNotSupported: "Your browser does not support security keys."
|
||||
registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key."
|
||||
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your account."
|
||||
chromePasskeyNotSupported: "Chrome passkeys are currently not supported."
|
||||
registerSecurityKey: "Register a security or pass key"
|
||||
securityKeyName: "Enter a key name"
|
||||
tapSecurityKey: "Please follow your browser to register the security or pass key"
|
||||
removeKey: "Remove security key"
|
||||
removeKeyConfirm: "Really delete the {name} key?"
|
||||
whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security key is registered."
|
||||
renewTOTP: "Reconfigure authenticator app"
|
||||
renewTOTPConfirm: "This will cause verification codes from your previous app to stop working"
|
||||
renewTOTPOk: "Reconfigure"
|
||||
renewTOTPCancel: "Cancel"
|
||||
_permissions:
|
||||
"read:account": "View your account information"
|
||||
"write:account": "Edit your account information"
|
||||
@ -1559,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "Notes from followed users"
|
||||
users: "Notes from specific users"
|
||||
userList: "Notes from a specified list of users"
|
||||
userGroup: "Notes from users in a specified group"
|
||||
_weekday:
|
||||
sunday: "Sunday"
|
||||
monday: "Monday"
|
||||
@ -1634,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "Make visible to your followers only"
|
||||
specified: "Direct"
|
||||
specifiedDescription: "Make visible for specified users only"
|
||||
localOnly: "Local only"
|
||||
localOnlyDescription: "Not visible to remote users"
|
||||
disableFederation: "Unfederated"
|
||||
disableFederationDescription: "Don't transmit to other instances"
|
||||
_postForm:
|
||||
replyPlaceholder: "Reply to this note..."
|
||||
quotePlaceholder: "Quote this note..."
|
||||
@ -1773,12 +1782,9 @@ _notification:
|
||||
youGotReply: "{name} replied to you"
|
||||
youGotQuote: "{name} quoted you"
|
||||
youRenoted: "Renote from {name}"
|
||||
youGotMessagingMessageFromUser: "{name} sent you a chat message"
|
||||
youGotMessagingMessageFromGroup: "A chat message was sent to the {name} group"
|
||||
youWereFollowed: "followed you"
|
||||
youReceivedFollowRequest: "You've received a follow request"
|
||||
yourFollowRequestAccepted: "Your follow request was accepted"
|
||||
youWereInvitedToGroup: "{userName} invited you to a group"
|
||||
pollEnded: "Poll results have become available"
|
||||
unreadAntennaNote: "Antenna {name}"
|
||||
emptyPushNotificationMessage: "Push notifications have been updated"
|
||||
@ -1794,7 +1800,7 @@ _notification:
|
||||
pollEnded: "Polls ending"
|
||||
receiveFollowRequest: "Received follow requests"
|
||||
followRequestAccepted: "Accepted follow requests"
|
||||
groupInvited: "Group invitations"
|
||||
achievementEarned: "Achievement unlocked"
|
||||
app: "Notifications from linked apps"
|
||||
_actions:
|
||||
followBack: "followed you back"
|
||||
@ -1827,3 +1833,6 @@ _deck:
|
||||
channel: "Channel"
|
||||
mentions: "Mentions"
|
||||
direct: "Direct notes"
|
||||
_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}."
|
||||
|
@ -103,6 +103,8 @@ renoted: "Renotado"
|
||||
cantRenote: "No se puede renotar este post"
|
||||
cantReRenote: "No se puede renotar una renota"
|
||||
quote: "Citar"
|
||||
inChannelRenote: "Renota sólo del canal"
|
||||
inChannelQuote: "Cita sólo del canal"
|
||||
pinnedNote: "Nota fijada"
|
||||
pinned: "Fijar al perfil"
|
||||
you: "Tú"
|
||||
@ -391,16 +393,19 @@ about: "Información"
|
||||
aboutMisskey: "Sobre Misskey"
|
||||
administrator: "Administrador"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Autenticación de dos factores"
|
||||
2fa: "Autenticación de doble factor"
|
||||
totp: "Aplicación autentícadora"
|
||||
totpDescription: "Ingresa una contaseña de un sólo uso usando la aplicación autenticadora"
|
||||
moderator: "Moderador"
|
||||
moderation: "Moderación"
|
||||
nUsersMentioned: "{n} usuarios mencionados"
|
||||
securityKeyAndPasskey: "Clave de seguridad / clave de paso"
|
||||
securityKey: "Clave de seguridad"
|
||||
securityKeyName: "Nombre de la Clave"
|
||||
registerSecurityKey: "Registrar clave de seguridad"
|
||||
lastUsed: "Última vez usado"
|
||||
lastUsedAt: "Último uso: {t}"
|
||||
unregister: "Cancelar registro"
|
||||
passwordLessLogin: "Iniciar sesión sin contraseña"
|
||||
passwordLessLoginDescription: "Iniciar sesión con sólo una clave se seguridad / de paso sin usar una contraseña"
|
||||
resetPassword: "Resetear contraseña"
|
||||
newPasswordIs: "La nueva contraseña es \"{password}\""
|
||||
reduceUiAnimation: "Reducir la animación de la UI"
|
||||
@ -415,24 +420,15 @@ markAsReadAllTalkMessages: "Marcar todos los chats como leídos"
|
||||
help: "Ayuda"
|
||||
inputMessageHere: "Escribe el mensaje aquí"
|
||||
close: "Cerrar"
|
||||
group: "Grupo"
|
||||
groups: "Grupos"
|
||||
createGroup: "Crear grupo"
|
||||
ownedGroups: "Tus"
|
||||
joinedGroups: "Grupos a los que me uní"
|
||||
invites: "Invitar"
|
||||
groupName: "Nombre del grupo"
|
||||
members: "Miembros"
|
||||
transfer: "Transferir"
|
||||
messagingWithUser: "Chatear con usuario"
|
||||
messagingWithGroup: "Chatear en grupo"
|
||||
title: "Título"
|
||||
text: "Texto"
|
||||
enable: "Activar"
|
||||
next: "Siguiente"
|
||||
retype: "Intentar de nuevo"
|
||||
noteOf: "Notas de {user}"
|
||||
inviteToGroup: "Invitar al grupo"
|
||||
quoteAttached: "Cita añadida"
|
||||
quoteQuestion: "¿Quiere añadir una cita?"
|
||||
noMessagesYet: "Aún no hay chat"
|
||||
@ -454,19 +450,17 @@ passwordMatched: "Correcto"
|
||||
passwordNotMatched: "Las contraseñas no son las mismas"
|
||||
signinWith: "Inicie sesión con {x}"
|
||||
signinFailed: "Autenticación fallida. Asegúrate de haber usado el nombre de usuario y contraseña correctos."
|
||||
tapSecurityKey: "Toque la clave de seguridad"
|
||||
or: "O"
|
||||
language: "Idioma"
|
||||
uiLanguage: "Idioma de visualización de la interfaz"
|
||||
groupInvited: "Invitado al grupo"
|
||||
aboutX: "Acerca de {x}"
|
||||
emojiStyle: "Estilo de emoji"
|
||||
native: "Nativo"
|
||||
disableDrawer: "No mostrar los menús en cajones"
|
||||
youHaveNoGroups: "Sin grupos"
|
||||
joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su propio grupo."
|
||||
noHistory: "No hay datos en el historial"
|
||||
signinHistory: "Historial de ingresos"
|
||||
enableAdvancedMfm: "Habilitar MFM avanzado"
|
||||
enableAnimatedMfm: "Habilitar MFM con movimiento"
|
||||
doing: "Voy en camino"
|
||||
category: "Categoría"
|
||||
tags: "Etiqueta"
|
||||
@ -785,6 +779,7 @@ popularPosts: "Más vistos"
|
||||
shareWithNote: "Compartir con una nota"
|
||||
ads: "Anuncios"
|
||||
expiration: "Termina el"
|
||||
startingperiod: "periodo de inicio"
|
||||
memo: "Notas"
|
||||
priority: "Prioridad"
|
||||
high: "Alta"
|
||||
@ -817,6 +812,7 @@ lastCommunication: "Última comunicación"
|
||||
resolved: "Resuelto"
|
||||
unresolved: "Sin resolver"
|
||||
breakFollow: "Dejar de seguir"
|
||||
breakFollowConfirm: "¿Quieres dejar de seguir?"
|
||||
itsOn: "¡Está encendido!"
|
||||
itsOff: "¡Está apagado!"
|
||||
emailRequiredForSignup: "Se requere una dirección de correo electrónico para el registro de la cuenta"
|
||||
@ -836,8 +832,6 @@ deleteAccountConfirm: "La cuenta será borrada. ¿Está seguro?"
|
||||
incorrectPassword: "La contraseña es incorrecta"
|
||||
voteConfirm: "¿Confirma su voto a {choice}?"
|
||||
hide: "Ocultar"
|
||||
leaveGroup: "Dejar el grupo"
|
||||
leaveGroupConfirm: "¿Desea salir de {name}?"
|
||||
useDrawerReactionPickerForMobile: "Mostrar panel de reacciones en móviles"
|
||||
welcomeBackWithName: "Bienvenido otra vez, {name}"
|
||||
clickToFinishEmailVerification: "Cliquée {ok} y verifique su correo"
|
||||
@ -863,6 +857,8 @@ failedToFetchAccountInformation: "No se pudo obtener información de la cuenta"
|
||||
rateLimitExceeded: "Se excedió el límite de peticiones"
|
||||
cropImage: "Recortar imágen"
|
||||
cropImageAsk: "¿Desea recortar la imagen?"
|
||||
cropYes: "Recortar"
|
||||
cropNo: "Usar como está"
|
||||
file: "Archivos"
|
||||
recentNHours: "Últimas {n} horas"
|
||||
recentNDays: "Últimos {n} días"
|
||||
@ -943,6 +939,18 @@ selectFromPresets: "Escoger desde predefinidos"
|
||||
achievements: "Logros"
|
||||
gotInvalidResponseError: "Respuesta del servidor inválida"
|
||||
gotInvalidResponseErrorDescription: "Puede que el servidor esté caído o en mantenimiento. Favor de intentar más tarde"
|
||||
thisPostMayBeAnnoying: "Ésta publicación puede resultar molesta."
|
||||
thisPostMayBeAnnoyingHome: "Publicar en línea de tiempo 'Inicio'"
|
||||
thisPostMayBeAnnoyingCancel: "detener"
|
||||
thisPostMayBeAnnoyingIgnore: "Publicar de todos modos"
|
||||
collapseRenotes: "Colapsar renotas que ya hayas visto"
|
||||
internalServerError: "Error interno del servidor"
|
||||
internalServerErrorDescription: "El servidor tuvo un error inesperado."
|
||||
copyErrorInfo: "Copiar detalles del error"
|
||||
joinThisServer: "Registrarse en esta instancia"
|
||||
exploreOtherServers: "Buscar otra instancia"
|
||||
letsLookAtTimeline: "Mirar la línea de tiempo local"
|
||||
disableFederationWarn: "Esto desactivará la federación, pero las publicaciones segurán siendo públicas al menos que se configure diferente. Usualmente no necesitas usar esta configuración."
|
||||
_achievements:
|
||||
earnedAt: "Desbloqueado el"
|
||||
_types:
|
||||
@ -1456,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "Hace {n} semanas"
|
||||
monthsAgo: "Hace {n} meses"
|
||||
yearsAgo: "Hace {n} años"
|
||||
invalid: "No hay nada que ver aqui"
|
||||
_time:
|
||||
second: "Segundos"
|
||||
minute: "Minutos"
|
||||
@ -1489,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "La configuración de las notificaciones puede modificarse posteriormente."
|
||||
_2fa:
|
||||
alreadyRegistered: "Ya has completado la configuración."
|
||||
registerDevice: "Registrar dispositivo"
|
||||
registerKey: "Registrar clave"
|
||||
registerTOTP: "Registrar aplicación autenticadora"
|
||||
passwordToTOTP: "Ingresa tu contraseña"
|
||||
step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra."
|
||||
step2: "Luego, escanee con la aplicación el código QR mostrado en pantalla."
|
||||
step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app.\nTocar este código QR te permitirá registrar la autenticación 2FA a tu llave de seguridad o aplicación autenticadora."
|
||||
step2Url: "En una aplicación de escritorio se puede ingresar la siguiente URL:"
|
||||
step3Title: "Ingresa un código de autenticación"
|
||||
step3: "Para terminar, ingrese el token mostrado en la aplicación."
|
||||
step4: "Ahora cuando inicie sesión, ingrese el mismo token"
|
||||
securityKeyNotSupported: "Tu navegador no soporta claves de autenticación."
|
||||
registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key.\npor favor. configura una aplicación de autenticación para registrar una llave de seguridad."
|
||||
securityKeyInfo: "Se puede configurar el inicio de sesión usando una clave de seguridad de hardware que soporte FIDO2 o con un certificado de huella digital o con un PIN"
|
||||
chromePasskeyNotSupported: "Las llaves de seguridad de Chrome no son soportadas por el momento."
|
||||
registerSecurityKey: "Registrar una llave de seguridad"
|
||||
securityKeyName: "Ingresa un nombre para la clave"
|
||||
tapSecurityKey: "Por favor, sigue tu navegador para registrar una llave de seguridad"
|
||||
removeKey: "Quitar la llave de seguridad"
|
||||
removeKeyConfirm: "¿Borrar el respaldo \"{name}\"?"
|
||||
whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security key is registered.\nLa aplicación autenticadora no puede ser eliminada mientras la llave de seguridad se encuentre registrada."
|
||||
renewTOTP: "Reconfigurar la aplicación autenticadora"
|
||||
renewTOTPConfirm: "This will cause verification codes from your previous app to stop working\nEsto hará que los códigos de verificación de la aplicación anterior dejen de funcionar"
|
||||
renewTOTPOk: "Reconfigurar"
|
||||
renewTOTPCancel: "No gracias"
|
||||
_permissions:
|
||||
"read:account": "Ver información de la cuenta"
|
||||
"write:account": "Editar información de la cuenta"
|
||||
@ -1545,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "Notas de los usuarios que sigues"
|
||||
users: "Notas de un usuario o varios"
|
||||
userList: "Notas de los usuarios de una lista"
|
||||
userGroup: "Notas de los usuarios de una grupo"
|
||||
_weekday:
|
||||
sunday: "Domingo"
|
||||
monday: "Lunes"
|
||||
@ -1620,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "Visible sólo para tus seguidores"
|
||||
specified: "Mensaje directo"
|
||||
specifiedDescription: "Visible sólo para los usuarios elegidos"
|
||||
localOnly: "Solo local"
|
||||
localOnlyDescription: "Oculto para usuarios remotos"
|
||||
disableFederation: "No federado"
|
||||
disableFederationDescription: "No enviar a otras instancias"
|
||||
_postForm:
|
||||
replyPlaceholder: "Responder a esta nota"
|
||||
quotePlaceholder: "Citar esta nota"
|
||||
@ -1759,12 +1782,9 @@ _notification:
|
||||
youGotReply: "Respuesta de {name}"
|
||||
youGotQuote: "Citado por {name}"
|
||||
youRenoted: "Renotado por {name}"
|
||||
youGotMessagingMessageFromUser: "{name} comenzó un chat contigo"
|
||||
youGotMessagingMessageFromGroup: "Tienes un chat de {name}"
|
||||
youWereFollowed: "te ha seguido"
|
||||
youReceivedFollowRequest: "Has mandado una solicitud de seguimiento"
|
||||
yourFollowRequestAccepted: "Tu solicitud de seguimiento fue aceptada"
|
||||
youWereInvitedToGroup: "Invitado al grupo"
|
||||
pollEnded: "Estan disponibles los resultados de la encuesta"
|
||||
unreadAntennaNote: "Antena {name}"
|
||||
emptyPushNotificationMessage: "Se han actualizado las notificaciones push"
|
||||
@ -1780,7 +1800,7 @@ _notification:
|
||||
pollEnded: "La encuesta terminó"
|
||||
receiveFollowRequest: "Recibió una solicitud de seguimiento"
|
||||
followRequestAccepted: "El seguimiento fue aceptado"
|
||||
groupInvited: "Invitado al grupo"
|
||||
achievementEarned: "Logro desbloqueado"
|
||||
app: "Notificaciones desde aplicaciones"
|
||||
_actions:
|
||||
followBack: "Te sigue de vuelta"
|
||||
@ -1813,3 +1833,6 @@ _deck:
|
||||
channel: "Canal"
|
||||
mentions: "Menciones"
|
||||
direct: "Mensaje directo"
|
||||
_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}."
|
||||
|
@ -388,13 +388,10 @@ about: "Informations"
|
||||
aboutMisskey: "À propos de Misskey"
|
||||
administrator: "Administrateur"
|
||||
token: "Jeton"
|
||||
twoStepAuthentication: "Authentification à deux facteurs"
|
||||
moderator: "Modérateur·rice·s"
|
||||
moderation: "Modérations"
|
||||
nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s"
|
||||
securityKey: "Clé de sécurité"
|
||||
securityKeyName: "Nom de la clé"
|
||||
registerSecurityKey: "Enregistrer une clé de sécurité"
|
||||
lastUsed: "Dernier utilisé"
|
||||
unregister: "Se désinscrire"
|
||||
passwordLessLogin: "Se connecter sans mot de passe"
|
||||
@ -412,24 +409,15 @@ markAsReadAllTalkMessages: "Marquer toutes les discussions comme lues"
|
||||
help: "Aide"
|
||||
inputMessageHere: "Écrivez votre message ici"
|
||||
close: "Fermer"
|
||||
group: "Groupe"
|
||||
groups: "Groupes"
|
||||
createGroup: "Créer un groupe"
|
||||
ownedGroups: "Mes groupes"
|
||||
joinedGroups: "Groupes rejoints"
|
||||
invites: "Invitations"
|
||||
groupName: "Nom du groupe"
|
||||
members: "Membres"
|
||||
transfer: "Transférer"
|
||||
messagingWithUser: "Discuter avec un·e autre utilisateur·rice"
|
||||
messagingWithGroup: "Discuter avec un groupe"
|
||||
title: "Titre"
|
||||
text: "Texte"
|
||||
enable: "Activer"
|
||||
next: "Suivant"
|
||||
retype: "Confirmation"
|
||||
noteOf: "Notes de {user}"
|
||||
inviteToGroup: "Inviter dans un groupe"
|
||||
quoteAttached: "Avec citation"
|
||||
quoteQuestion: "Souhaitez-vous ajouter une citation ?"
|
||||
noMessagesYet: "Pas encore de discussion"
|
||||
@ -451,17 +439,13 @@ passwordMatched: "Les mots de passe correspondent"
|
||||
passwordNotMatched: "Les mots de passe ne correspondent pas"
|
||||
signinWith: "Se connecter avec {x}"
|
||||
signinFailed: "Échec d’authentification. Veuillez vérifier que votre nom d’utilisateur et mot de passe sont corrects."
|
||||
tapSecurityKey: "Appuyez sur votre clé de sécurité"
|
||||
or: "OU"
|
||||
language: "Langue"
|
||||
uiLanguage: "Langue d’affichage de l’interface"
|
||||
groupInvited: "Invité au groupe"
|
||||
aboutX: "À propos de {x}"
|
||||
emojiStyle: "Style des émojis"
|
||||
native: "Natif"
|
||||
disableDrawer: "Les menus ne s'affichent pas dans le tiroir"
|
||||
youHaveNoGroups: "Vous n’avez aucun groupe"
|
||||
joinOrCreateGroup: "Vous pouvez être invité·e à rejoindre des groupes existants ou créer votre propre nouveau groupe."
|
||||
noHistory: "Pas d'historique"
|
||||
signinHistory: "Historique de connexion"
|
||||
doing: "En cours..."
|
||||
@ -831,8 +815,6 @@ deleteAccountConfirm: "Votre compte sera supprimé. Êtes vous certain ?"
|
||||
incorrectPassword: "Le mot de passe est incorrect."
|
||||
voteConfirm: "Confirmez-vous votre vote pour « {choice} » ?"
|
||||
hide: "Masquer"
|
||||
leaveGroup: "Quitter le groupe"
|
||||
leaveGroupConfirm: "Êtes vous sûr de vouloir quitter \"{name}\" ?"
|
||||
useDrawerReactionPickerForMobile: "Afficher le sélecteur de réactions en tant que panneau sur mobile"
|
||||
welcomeBackWithName: "Heureux de vous revoir, {name}"
|
||||
clickToFinishEmailVerification: "Veuillez cliquer sur [{ok}] afin de compléter la vérification par courriel."
|
||||
@ -1139,6 +1121,7 @@ _ago:
|
||||
weeksAgo: "Il y a {n} semaines"
|
||||
monthsAgo: "Il y a {n} mois"
|
||||
yearsAgo: "Il y a {n} ans"
|
||||
invalid: "Il n'y a rien à voir ici"
|
||||
_time:
|
||||
second: "s"
|
||||
minute: "min"
|
||||
@ -1171,14 +1154,14 @@ _tutorial:
|
||||
step8_2: "En les activant, vous recevrez des notifications pour les mentions, les réactions, les suivis, etc., même lorsque Misskey n'est pas ouvert."
|
||||
_2fa:
|
||||
alreadyRegistered: "Configuration déjà achevée."
|
||||
registerDevice: "Ajouter un nouvel appareil"
|
||||
registerKey: "Enregistrer une clef"
|
||||
step1: "Tout d'abord, installez une application d'authentification, telle que {a} ou {b}, sur votre appareil."
|
||||
step2: "Ensuite, scannez le code QR affiché sur l’écran."
|
||||
step2Url: "Vous pouvez également saisir cette URL si vous utilisez un programme de bureau :"
|
||||
step3: "Entrez le jeton affiché sur votre application pour compléter la configuration."
|
||||
step4: "À partir de maintenant, ce même jeton vous sera demandé à chacune de vos connexions."
|
||||
securityKeyInfo: "Vous pouvez configurer l'authentification WebAuthN pour sécuriser davantage le processus de connexion grâce à une clé de sécurité matérielle qui prend en charge FIDO2, ou bien en configurant l'authentification par empreinte digitale ou par code PIN sur votre appareil."
|
||||
removeKeyConfirm: "Voulez-vous supprimer {name} ?"
|
||||
renewTOTPCancel: "Pas maintenant"
|
||||
_permissions:
|
||||
"read:account": "Afficher les informations du compte"
|
||||
"write:account": "Mettre à jour les informations de votre compte"
|
||||
@ -1224,7 +1207,6 @@ _antennaSources:
|
||||
homeTimeline: "Notes venant des utilisateur·rice·s auxquel·les je suis abonné"
|
||||
users: "Notes venant de la part d’utilisateur·rice·s précis"
|
||||
userList: "Notes venant d’une liste spécifique"
|
||||
userGroup: "Notes venant d’utilisateur·rice·s du groupe spécifié"
|
||||
_weekday:
|
||||
sunday: "Dimanche"
|
||||
monday: "Lundi"
|
||||
@ -1296,8 +1278,6 @@ _visibility:
|
||||
followersDescription: "Publier à vos abonné·e·s uniquement"
|
||||
specified: "Direct"
|
||||
specifiedDescription: "Publier uniquement aux utilisateur·rice·s mentionné·e·s"
|
||||
localOnly: "Local seulement"
|
||||
localOnlyDescription: "Caché pour les utilisateurs distant"
|
||||
_postForm:
|
||||
replyPlaceholder: "Répondre à cette note ..."
|
||||
quotePlaceholder: "Citez cette note ..."
|
||||
@ -1425,12 +1405,9 @@ _notification:
|
||||
youGotReply: "Réponse de {name}"
|
||||
youGotQuote: "Cité·e par {name}"
|
||||
youRenoted: "{name} vous a Renoté"
|
||||
youGotMessagingMessageFromUser: "{name} vous envoyé un message"
|
||||
youGotMessagingMessageFromGroup: "Un message a été envoyé au groupe {name}"
|
||||
youWereFollowed: "Vous suit"
|
||||
youReceivedFollowRequest: "Vous avez reçu une demande d’abonnement"
|
||||
yourFollowRequestAccepted: "Votre demande d’abonnement a été accepté"
|
||||
youWereInvitedToGroup: "Invité·e au groupe"
|
||||
pollEnded: "Les résultats du sondage sont disponibles"
|
||||
unreadAntennaNote: "Antenne {name}"
|
||||
emptyPushNotificationMessage: "Les notifications push ont été mises à jour"
|
||||
@ -1445,7 +1422,6 @@ _notification:
|
||||
pollEnded: "Sondages se cloturant"
|
||||
receiveFollowRequest: "Demande d'abonnement reçue"
|
||||
followRequestAccepted: "Demande d'abonnement acceptée"
|
||||
groupInvited: "Invitation à un groupe"
|
||||
app: "Notifications provenant des apps"
|
||||
_actions:
|
||||
followBack: "Suivre"
|
||||
|
@ -84,7 +84,7 @@ error: "Galat"
|
||||
somethingHappened: "Terjadi kesalahan"
|
||||
retry: "Coba lagi"
|
||||
pageLoadError: "Gagal memuat halaman."
|
||||
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
||||
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok peramban. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
||||
serverIsDead: "Tidak ada respon dari peladen. Mohon tunggu dan coba beberapa saat lagi."
|
||||
youShouldUpgradeClient: "Untuk melihat halaman ini, mohon muat ulang untuk memutakhirkan klienmu."
|
||||
enterListName: "Masukkan nama daftar"
|
||||
@ -103,6 +103,8 @@ renoted: "Telah direnote"
|
||||
cantRenote: "Postingan ini tidak dapat direnote"
|
||||
cantReRenote: "Renote tidak dapat direnote"
|
||||
quote: "Kutip"
|
||||
inChannelRenote: "Hanya renote dalam kanal"
|
||||
inChannelQuote: "Hanya kutip dalam kanal"
|
||||
pinnedNote: "Catatan yang disematkan"
|
||||
pinned: "Sematkan ke profil"
|
||||
you: "Kamu"
|
||||
@ -129,6 +131,7 @@ unblockConfirm: "Apakah kamu yakin ingin membuka blokir akun ini?"
|
||||
suspendConfirm: "Apakah kamu yakin ingin membekukan akun ini?"
|
||||
unsuspendConfirm: "Apakah kamu yakin ingin membuka pembekuan akun ini?"
|
||||
selectList: "Pilih daftar"
|
||||
selectChannel: "Pilih kanal"
|
||||
selectAntenna: "Pilih Antena"
|
||||
selectWidget: "Pilih gawit"
|
||||
editWidgets: "Sunting gawit"
|
||||
@ -256,6 +259,8 @@ noMoreHistory: "Tidak ada sejarah lagi"
|
||||
startMessaging: "Mulai mengirim pesan"
|
||||
nUsersRead: "Dibaca oleh {n}"
|
||||
agreeTo: "Saya setuju kepada {0}"
|
||||
agreeBelow: "Saya setuju dengan di bawah ini"
|
||||
basicNotesBeforeCreateAccount: "Catatan penting"
|
||||
tos: "Syarat dan ketentuan"
|
||||
start: "Mulai"
|
||||
home: "Beranda"
|
||||
@ -388,13 +393,10 @@ about: "Informasi"
|
||||
aboutMisskey: "Tentang Misskey"
|
||||
administrator: "Admin"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Otentikasi dua faktor"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderasi"
|
||||
nUsersMentioned: "{n} pengguna disebut"
|
||||
securityKey: "Kunci keamanan"
|
||||
securityKeyName: "Nama kunci"
|
||||
registerSecurityKey: "Daftarkan kunci keamanan"
|
||||
lastUsed: "Terakhir digunakan"
|
||||
unregister: "Batalkan pendaftaran"
|
||||
passwordLessLogin: "Setel login tanpa kata sandi"
|
||||
@ -412,24 +414,15 @@ markAsReadAllTalkMessages: "Tandai semua pesan telah dibaca"
|
||||
help: "Bantuan"
|
||||
inputMessageHere: "Ketik pesan disini"
|
||||
close: "Tutup"
|
||||
group: "Grup"
|
||||
groups: "Grup"
|
||||
createGroup: "Buat grup"
|
||||
ownedGroups: "Grup yang dimiliki"
|
||||
joinedGroups: "Grup yang diikuti"
|
||||
invites: "Undang"
|
||||
groupName: "Nama grup"
|
||||
members: "Anggota"
|
||||
transfer: "Transfer"
|
||||
messagingWithUser: "Obrolan dengan pengguna lain"
|
||||
messagingWithGroup: "Obrolan di dalam grup"
|
||||
title: "Judul"
|
||||
text: "Teks"
|
||||
enable: "Aktifkan"
|
||||
next: "Selanjutnya"
|
||||
retype: "Masukkan ulang"
|
||||
noteOf: "Catatan milik {user}"
|
||||
inviteToGroup: "Undang ke grup"
|
||||
quoteAttached: "Dikutip"
|
||||
quoteQuestion: "Apakah kamu ingin menambahkan kutipan?"
|
||||
noMessagesYet: "Tidak ada pesan"
|
||||
@ -451,19 +444,17 @@ passwordMatched: "Kata sandi sama"
|
||||
passwordNotMatched: "Kata sandi tidak sama"
|
||||
signinWith: "Masuk dengan {x}"
|
||||
signinFailed: "Tidak dapat masuk. Nama pengguna atau kata sandi yang kamu masukkan salah."
|
||||
tapSecurityKey: "Ketuk kunci keamanan kamu"
|
||||
or: "atau"
|
||||
language: "Bahasa"
|
||||
uiLanguage: "Bahasa antarmuka pengguna"
|
||||
groupInvited: "Telah diundang ke grup"
|
||||
aboutX: "Tentang {x}"
|
||||
emojiStyle: "Gaya emoji"
|
||||
native: "Native"
|
||||
disableDrawer: "Jangan gunakan menu bergaya laci"
|
||||
youHaveNoGroups: "Kamu tidak memiliki grup"
|
||||
joinOrCreateGroup: "Bergabunglah dengan grup atau kamu dapat membuat grupmu sendiri."
|
||||
noHistory: "Tidak ada riwayat"
|
||||
signinHistory: "Riwayat masuk"
|
||||
enableAdvancedMfm: "Nyalakan MFM tingkat lanjut"
|
||||
enableAnimatedMfm: "Nyalakan animasi MFM"
|
||||
doing: "Sedang berkerja..."
|
||||
category: "Kategori"
|
||||
tags: "Tandai"
|
||||
@ -833,8 +824,6 @@ deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?"
|
||||
incorrectPassword: "Kata sandi salah."
|
||||
voteConfirm: "Konfirmasi suara kamu untuk ({choice})?"
|
||||
hide: "Sembunyikan"
|
||||
leaveGroup: "Keluar grup"
|
||||
leaveGroupConfirm: "Apakah kamu yakin untuk keluar dari \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Tampilkan bilah reaksi sebagai laci di ponsel"
|
||||
welcomeBackWithName: "Selamat datang kembali, {name}."
|
||||
clickToFinishEmailVerification: "Mohon klik [{ok}] untuk menyelesaikan verifikasi email."
|
||||
@ -860,6 +849,8 @@ failedToFetchAccountInformation: "Gagal untuk mendapatkan informasi akun"
|
||||
rateLimitExceeded: "Batas sudah terlampaui"
|
||||
cropImage: "potong gambar"
|
||||
cropImageAsk: "Ingin memotong gambar?"
|
||||
cropYes: "Potong"
|
||||
cropNo: "Gunakan apa adanya"
|
||||
file: "Berkas"
|
||||
recentNHours: "{n} jam terakhir"
|
||||
recentNDays: "{n} hari terakhir"
|
||||
@ -926,10 +917,87 @@ didYouLikeMisskey: "Apakah kamu mulai menyukai Misskey?"
|
||||
pleaseDonate: "{host} menggunakan perangkat lunak bebas yaitu Misskey. Kami sangat mengapresiasi sekali donasi dari kamu agar pengembangan Misskey tetap dapat berlanjut!"
|
||||
roles: "Peran"
|
||||
role: "Peran"
|
||||
normalUser: "Pengguna umum"
|
||||
undefined: "Tak terdefinisi"
|
||||
assign: "Tetapkan\n"
|
||||
unassign: "Batalkan penetapan"
|
||||
color: "Warna"
|
||||
manageCustomEmojis: "Kelola Emoji Kustom"
|
||||
youCannotCreateAnymore: "Kamu melewati batas pembuatan."
|
||||
cannotPerformTemporary: "Sementara Tidak Tersedia"
|
||||
cannotPerformTemporaryDescription: "Aksi ini tidak dapat dilakukan sementara karena melewati batas eksekusi. Mohon tunggu sejenak dan coba lagi."
|
||||
preset: "Prasetel"
|
||||
selectFromPresets: "Pilih dari prasetel"
|
||||
achievements: "Pencapaian"
|
||||
gotInvalidResponseError: "Respon peladen tidak valid"
|
||||
gotInvalidResponseErrorDescription: "Peladen tidak dapat dijangkau atau sedang dalam perawatan. Mohon coba lagi nanti."
|
||||
thisPostMayBeAnnoying: "Catatan ini mungkin dapat mengganggu orang lain."
|
||||
thisPostMayBeAnnoyingHome: "Catat ke linimasa beranda"
|
||||
thisPostMayBeAnnoyingCancel: "Batalkan"
|
||||
thisPostMayBeAnnoyingIgnore: "Tetap catat"
|
||||
collapseRenotes: "Tutup renote yang sudah kamu lihat"
|
||||
internalServerError: "Kesalahan internal peladen"
|
||||
internalServerErrorDescription: "Peladen sedang mengalami galat tak terduga"
|
||||
copyErrorInfo: "Salin detil galat"
|
||||
_achievements:
|
||||
earnedAt: "Terbuka pada"
|
||||
_types:
|
||||
_notes1:
|
||||
title: "Cus, baru gabung Misskey nih!"
|
||||
description: "Catat catatan pertama kamu"
|
||||
flavor: "Selamat bersenang-senang dengan Misskey!"
|
||||
_notes10:
|
||||
title: "Beberapa catatan"
|
||||
description: "Catat 10 catatan"
|
||||
_notes100:
|
||||
title: "Banyak catatan"
|
||||
description: "Catat 100 catatan"
|
||||
_notes500:
|
||||
title: "Tertumpuk catatan"
|
||||
description: "Catat 500 catatan"
|
||||
_notes1000:
|
||||
title: "Gunung catatan"
|
||||
description: "Catat 1000 catatan"
|
||||
_notes5000:
|
||||
title: "Luapan catatan"
|
||||
description: "Catat 5000 catatan"
|
||||
_notes10000:
|
||||
title: "Catatan super"
|
||||
description: "Catat 10 ribu catatan"
|
||||
_notes20000:
|
||||
title: "Butuh... banyak... catatan..."
|
||||
description: "Catat 20 ribu catatan"
|
||||
_notes30000:
|
||||
title: "Catat, catat, catat !"
|
||||
description: "Catat 30 ribu catatan"
|
||||
_notes40000:
|
||||
title: "Pabrik catatan"
|
||||
description: "Catat 40 ribu catatan"
|
||||
_notes50000:
|
||||
title: "Planet catatan"
|
||||
description: "Catat 50 ribu catatan"
|
||||
_notes60000:
|
||||
title: "Kuasar catatan"
|
||||
description: "Catat 60 ribu catatan"
|
||||
_notes70000:
|
||||
title: "Lubang hitam catatan"
|
||||
description: "Catat 70 ribu catatan"
|
||||
_notes80000:
|
||||
title: "Galaksi catatan"
|
||||
description: "Catat 80 ribu catatan"
|
||||
_notes90000:
|
||||
title: "Semesta catatan"
|
||||
description: "Catat 90 ribu catatan"
|
||||
_notes100000:
|
||||
title: "ALL YOUR NOTE ARE BELONG TO US"
|
||||
description: "Catat 100 ribu catatan"
|
||||
flavor: "Banyak bacot ya kamu."
|
||||
_login3:
|
||||
title: "Pemula I"
|
||||
description: "Login selama 3 hari"
|
||||
flavor: "Mulai hari ini, panggil gue Misskist"
|
||||
_login7:
|
||||
title: "Pemula II"
|
||||
description: "Login selama 7 hari"
|
||||
flavor: "Sudah mulai terbiasa?"
|
||||
_login15:
|
||||
@ -1002,7 +1070,80 @@ _achievements:
|
||||
_following100:
|
||||
title: "100 Teman"
|
||||
description: "Ikuti 100 pengguna lain"
|
||||
_following300:
|
||||
title: "Kelebihan teman"
|
||||
description: "Mengikuti 300 pengguna lain"
|
||||
_followers1:
|
||||
title: "Pengikut pertama"
|
||||
description: "Dapatkan 1 pengikut"
|
||||
_followers10:
|
||||
title: "Ikuti aku!"
|
||||
description: "Dapatkan 10 pengikut"
|
||||
_followers50:
|
||||
title: "Rame-rame"
|
||||
description: "Dapatkan 50 pengikut"
|
||||
_followers100:
|
||||
title: "Terkenal"
|
||||
description: "Dapatkan 100 pengikut"
|
||||
_followers300:
|
||||
title: "Mohon antri satu baris"
|
||||
description: "Dapatkan 300 pengikut"
|
||||
_followers500:
|
||||
title: "Stasiun Informasi"
|
||||
description: "Dapatkan 500 pengikut"
|
||||
_followers1000:
|
||||
title: "Influencer"
|
||||
description: "Dapatkan 1000 pengikut"
|
||||
_collectAchievements30:
|
||||
title: "Kolektor pencapaian"
|
||||
description: "Dapatkan 30 pencapaian"
|
||||
_viewAchievements3min:
|
||||
title: "Suka Pencapaian"
|
||||
description: "Lugat daftar pencapaianmu setidaknya 3 menit"
|
||||
_iLoveMisskey:
|
||||
title: "I Love Misskey"
|
||||
description: "Catat \"I ❤ #Misskey\""
|
||||
flavor: "Tim pengembang misskey sangat mengapresiasi dukungan kamu!"
|
||||
_foundTreasure:
|
||||
title: "Berburu Harta Karun"
|
||||
description: "Kamu telah menemukan harta karun tersembunyi"
|
||||
_client30min:
|
||||
title: "Istirahat pendek"
|
||||
description: "Habiskan waktu 30 menit di Misskey"
|
||||
_noteDeletedWithin1min:
|
||||
title: "Eh, salah coy!"
|
||||
description: "Hapus catatan kurang dari semenit kamu catat"
|
||||
_postedAtLateNight:
|
||||
title: "Nokturnal"
|
||||
description: "Catat catatan di tengah malam hari"
|
||||
flavor: "Udah waktunya boboq."
|
||||
_postedAt0min0sec:
|
||||
title: "Jam ngomong"
|
||||
description: "Catat catatan di jam 00.00"
|
||||
flavor: "Tik Tok Tik Toeeeng"
|
||||
_selfQuote:
|
||||
title: "Rujukan mandiri"
|
||||
description: "Kutip catatanmu sendiri"
|
||||
_htl20npm:
|
||||
title: "Linimasa mengalir"
|
||||
description: "Memiliki linimasa beranda dengan kecepatan melebihi 20 cpm (catatan per menit)"
|
||||
_viewInstanceChart:
|
||||
title: "Analis"
|
||||
description: "Lihat bagan instansimu"
|
||||
_outputHelloWorldOnScratchpad:
|
||||
title: "Halo, dunia!"
|
||||
description: "Munculkan \"hello world\" di Scratchpad"
|
||||
_open3windows:
|
||||
title: "Jendela ganda"
|
||||
description: "Memiliki setidaknya 3 jendela yang terbuka secara bersamaan"
|
||||
_driveFolderCircularReference:
|
||||
title: "Referensi Siklus"
|
||||
description: "Mencoba membuat folder bersarang rekursif di Drive"
|
||||
_reactWithoutRead:
|
||||
title: "Beneran udah dibaca?"
|
||||
description: "Mereaksi catatan dengan 100 karakter panjangnya dalam 3 detik setelah dicatat"
|
||||
_clickedClickHere:
|
||||
title: "Klik di sini"
|
||||
description: "Kamu telah mengeklik disini"
|
||||
_justPlainLucky:
|
||||
title: "Lagi Beruntung"
|
||||
@ -1025,6 +1166,7 @@ _achievements:
|
||||
_loggedInOnNewYearsDay:
|
||||
title: "Selamat Tahun Baru!"
|
||||
description: "Login di hari pertama tahun baru"
|
||||
flavor: "Untuk tahun baru yang berkah bagi instansi ini"
|
||||
_cookieClicked:
|
||||
title: "Permainan dimana kamu mengeklik kue"
|
||||
description: "Mengeklik kue"
|
||||
@ -1053,6 +1195,9 @@ _role:
|
||||
baseRole: "Templat peran"
|
||||
useBaseValue: "Gunakan nilai templat peran"
|
||||
chooseRoleToAssign: "Pilih peran yang ditugaskan"
|
||||
iconUrl: "URL ikon"
|
||||
asBadge: "Tampilkan sebagai lencana"
|
||||
descriptionOfAsBadge: "Ikon peran ini akan ditampilkan bersebelahan dengan username pengguna yang memiliki peran ini jika dinyalakan."
|
||||
canEditMembersByModerator: "Perbolehkan moderator untuk menyunting daftar anggota untuk peran ini"
|
||||
descriptionOfCanEditMembersByModerator: "Ketika dinyalakan, moderator beserta administrator dapat menugaskan ataupun mencabut pengguna ke peran ini. Ketika dimatikan, hanya administrator saja yang dapat menugaskan pengguna ke peran ini."
|
||||
priority: "Prioritas"
|
||||
@ -1068,6 +1213,36 @@ _role:
|
||||
canManageCustomEmojis: "Dapat mengelola Emoji kustom"
|
||||
driveCapacity: "Kapasitas Drive"
|
||||
pinMax: "Jumlah maksimal catatan yang disematkan"
|
||||
antennaMax: "Jumlah maksimum antena"
|
||||
wordMuteMax: "Jumlah maksimum karakter yang diperbolehkan dalam membisukan kata"
|
||||
webhookMax: "Jumlah maksimum Webhook"
|
||||
clipMax: "Jumlah maksimum Klip"
|
||||
noteEachClipsMax: "Jumlah maksimum catatan di dalam Klip"
|
||||
userListMax: "Jumlah maksimum daftar pengguna"
|
||||
userEachUserListsMax: "Jumlah maksimum pengguna dalam dsftar pengguna"
|
||||
rateLimitFactor: "Batas kecepatan"
|
||||
descriptionOfRateLimitFactor: "Batas kecepatan yang rendah tidak begitu membatasi, batas kecepatan tinggi lebih membatasi. "
|
||||
canHideAds: "Dapat menyembunyikan iklan"
|
||||
_condition:
|
||||
isLocal: "Pengguna lokal"
|
||||
isRemote: "Pengguna remote"
|
||||
createdLessThan: "Telah berlalu kurang dari X sejak pembuatan akun"
|
||||
createdMoreThan: "Telah berlalu lebih dari X sejak pembuatan akun"
|
||||
followersLessThanOrEq: "Memiliki pengikut X atau kurang dari tersebut"
|
||||
followersMoreThanOrEq: "Memiliki pengikut X atau lebih dari tersebut"
|
||||
followingLessThanOrEq: "Mengikuti X pengguna atau kurang dari itu"
|
||||
followingMoreThanOrEq: "Mengikuti X pengguna atau lebih dari itu"
|
||||
and: "Kondisi-AND"
|
||||
or: "Kondisi-OR"
|
||||
not: "Kondisi-NOT"
|
||||
_sensitiveMediaDetection:
|
||||
description: "Mengurangi usaha moderasi server dengan mengenali media NSFW srcara otomatis menggunakan Machine Learning. Fungsi ini akan sedikit menaikkan beban peladen."
|
||||
sensitivity: "Sensitivitas deteksi"
|
||||
sensitivityDescription: "Mengurangi sensitivitas akan mengurangi misdeteksi (false positive) sedangkan meningkatkannya akan menambah misdeteksi (false positive)."
|
||||
setSensitiveFlagAutomatically: "Tandai sebagai NSFW"
|
||||
setSensitiveFlagAutomaticallyDescription: "Hasil dari deteksi internal akan dipertahankan meskipun fungsi ini dimatikan."
|
||||
analyzeVideos: "Nyalakan analisis terhadap video"
|
||||
analyzeVideosDescription: "Analisa video sebagai tambahan dari gambar. Ini akan sedikit meningkatkan beban ke peladen."
|
||||
_emailUnavailable:
|
||||
used: "Alamat surel ini telah digunakan"
|
||||
format: "Format tidak valid."
|
||||
@ -1111,6 +1286,24 @@ _plugin:
|
||||
install: "Memasang plugin"
|
||||
installWarn: "Mohon jangan memasang plugin yang tidak dapat dipercayai."
|
||||
manage: "Manajemen plugin"
|
||||
_preferencesBackups:
|
||||
list: "Cadangan yang dibuat"
|
||||
saveNew: "Simpan cadangan baru"
|
||||
loadFile: "Muat dari berkas"
|
||||
apply: "Terapkan pada perangkat ini"
|
||||
save: "Simpan perubahan"
|
||||
inputName: "Mohon masukkan nama untuk cadangan ini"
|
||||
cannotSave: "Gagal menyimpan"
|
||||
nameAlreadyExists: "Cadangan bernama \"{name}\" sudah ada. Mohon gunakan nama lain."
|
||||
applyConfirm: "Apakah kamu yakin untuk menerapkan cadangan \"{name}\" ke perangkat ini? Pengaturan yang sudah ada di perangkat ini nantinya akan ditimpa."
|
||||
saveConfirm: "Simpan cadangan sebagai {name}?"
|
||||
deleteConfirm: "Hapus cadangan {name}?"
|
||||
renameConfirm: "Ganti cadangan ini dari \"{old}\" ke \"{new}\"?"
|
||||
noBackups: "Tidak ada cadangan. Kamu dapat mencadangkan pengaturanmu di peladen ini dengan menggunakan \"Buat cadangan baru\"."
|
||||
createdAt: "Dibuat pada: {date} {time}"
|
||||
updatedAt: "Diperbarui pada: {date} {time}"
|
||||
cannotLoad: "Gagal memuat"
|
||||
invalidFile: "Format berkas tidak valid"
|
||||
_registry:
|
||||
scope: "Lingkup"
|
||||
key: "Kunci"
|
||||
@ -1259,6 +1452,7 @@ _ago:
|
||||
weeksAgo: "{n} minggu lalu"
|
||||
monthsAgo: "{n} bulan lalu"
|
||||
yearsAgo: "{n} tahun lalu"
|
||||
invalid: "Tidak ada sama sekali disini"
|
||||
_time:
|
||||
second: "detik"
|
||||
minute: "menit"
|
||||
@ -1287,17 +1481,19 @@ _tutorial:
|
||||
step7_1: "Yay, Selamat! Kamu sudah menyelesaikan tutorial dasar Misskey."
|
||||
step7_2: "Jika kamu ingin mempelajari lebih lanjut tentang Misskey, cobalah berkunjung ke bagian {help}."
|
||||
step7_3: "Semoga berhasil dan bersenang-senanglah! 🚀"
|
||||
step8_1: "Yang terakhir, apakah kamu ingin menyalakam pemberitahuan push?"
|
||||
step8_2: "Menyalakan ini akan memungkinkan kamu menerima pemberitahuan untuk sebutan, reaksi, ikuti, dll. Bahkan ketika Misskey sedang tidak dibuka."
|
||||
step8_3: "Kamu dapat mengganti pengaturan ini nanti."
|
||||
_2fa:
|
||||
alreadyRegistered: "Kamu telah mendaftarkan perangkat otentikasi dua faktor."
|
||||
registerDevice: "Daftarkan perangkat baru"
|
||||
registerKey: "Daftarkan kunci keamanan baru"
|
||||
step1: "Pertama, pasang aplikasi otentikasi (seperti {a} atau {b}) di perangkat kamu."
|
||||
step2: "Lalu, pindai kode QR yang ada di layar."
|
||||
step2Url: "Di aplikasi desktop, masukkan URL berikut:"
|
||||
step3: "Masukkan token yang telah disediakan oleh aplikasimu untuk menyelesaikan pemasangan."
|
||||
step4: "Mulai sekarang, upaya login apapun akan meminta token login dari aplikasi otentikasi kamu."
|
||||
securityKeyInfo: "Kamu dapat memasang otentikasi WebAuthN untuk mengamankan proses login lebih lanjut dengan tidak hanya perangkat keras kunci keamanan yang mendukung FIDO2, namun juga sidik jari atau otentikasi PIN pada perangkatmu."
|
||||
removeKeyConfirm: "Hapus cadangan {name}?"
|
||||
renewTOTPCancel: "Tidak sekarang."
|
||||
_permissions:
|
||||
"read:account": "Lihat informasi akun"
|
||||
"write:account": "Sunting informasi akun"
|
||||
@ -1332,18 +1528,20 @@ _permissions:
|
||||
"read:gallery-likes": "Lihat daftar postingan galeri yang disukai"
|
||||
"write:gallery-likes": "Sunting daftar postingan galeri yang disukai"
|
||||
_auth:
|
||||
shareAccessTitle: "Mendapatkan ijin akses aplikasi"
|
||||
shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?"
|
||||
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun kamu?"
|
||||
permission: "{name} meminta ijin berikut"
|
||||
permissionAsk: "Aplikasi ini membutuhkan beberapa ijin, yaitu:"
|
||||
pleaseGoBack: "Mohon kembali ke aplikasi kamu"
|
||||
callback: "Mengembalikan kamu ke aplikasi"
|
||||
denied: "Akses ditolak"
|
||||
pleaseLogin: "Mohon masuk untuk otorisasi aplikasi."
|
||||
_antennaSources:
|
||||
all: "Semua catatan"
|
||||
homeTimeline: "Catatan dari pengguna yang diikuti"
|
||||
users: "Catatan dari pengguna tertentu"
|
||||
userList: "Catatan dari daftar tertentu"
|
||||
userGroup: "Catatan dari pengguna dalam grup yang ditentukan"
|
||||
_weekday:
|
||||
sunday: "Minggu"
|
||||
monday: "Senin"
|
||||
@ -1418,8 +1616,6 @@ _visibility:
|
||||
followersDescription: "Catat ke pengikut saja"
|
||||
specified: "Langsung"
|
||||
specifiedDescription: "Catat ke pengguna yang ditentukan saja"
|
||||
localOnly: "Hanya lokal"
|
||||
localOnlyDescription: "Hanya dapat dilihat di instansi lokal"
|
||||
_postForm:
|
||||
replyPlaceholder: "Balas ke catatan ini..."
|
||||
quotePlaceholder: "Kutip catatan ini..."
|
||||
@ -1557,12 +1753,9 @@ _notification:
|
||||
youGotReply: "{name} membalas kamu"
|
||||
youGotQuote: "{name} mengutip kamu"
|
||||
youRenoted: "{name} me-renote kamu"
|
||||
youGotMessagingMessageFromUser: "{name} mengirimi kamu pesan"
|
||||
youGotMessagingMessageFromGroup: "Sebuah pesan telah dikirim ke grup {name}"
|
||||
youWereFollowed: "Mengikuti kamu"
|
||||
youReceivedFollowRequest: "Kamu menerima permintaan mengikuti"
|
||||
yourFollowRequestAccepted: "Permintaan mengikuti kamu telah diterima"
|
||||
youWereInvitedToGroup: "Telah diundang ke grup"
|
||||
pollEnded: "Hasil Kuesioner telah keluar"
|
||||
unreadAntennaNote: "Antena {name}"
|
||||
emptyPushNotificationMessage: "Pembaruan notifikasi dorong"
|
||||
@ -1578,7 +1771,6 @@ _notification:
|
||||
pollEnded: "Jajak pendapat berakhir"
|
||||
receiveFollowRequest: "Permintaan mengikuti diterima"
|
||||
followRequestAccepted: "Permintaan mengikuti disetujui"
|
||||
groupInvited: "Diundang ke grup"
|
||||
app: "Pemberitahuan dari aplikasi"
|
||||
_actions:
|
||||
followBack: "Ikuti Kembali"
|
||||
|
@ -11,7 +11,7 @@ password: "Password"
|
||||
forgotPassword: "Hai dimenticato la password?"
|
||||
fetchingAsApObject: "Recuperando dal Fediverso..."
|
||||
ok: "OK"
|
||||
gotIt: "Ho capito"
|
||||
gotIt: "ok!"
|
||||
cancel: "Annulla"
|
||||
noThankYou: "No grazie"
|
||||
enterUsername: "Inserisci un nome utente"
|
||||
@ -46,7 +46,7 @@ copyContent: "Copia il contenuto"
|
||||
copyLink: "Copia il link"
|
||||
delete: "Elimina"
|
||||
deleteAndEdit: "Elimina e modifica"
|
||||
deleteAndEditConfirm: "Vuoi davvero cancellare questa nota e scriverla di nuovo? Verrano eliminate anche tutte le reazioni, Rinote e risposte collegate."
|
||||
deleteAndEditConfirm: "Vuoi davvero cancellare questa nota e scriverla di nuovo? Verranno eliminate anche tutte le reazioni, rinote e risposte collegate."
|
||||
addToList: "Aggiungi alla lista"
|
||||
sendMessage: "Invia messaggio"
|
||||
copyRSS: "Copia RSS"
|
||||
@ -75,7 +75,7 @@ lists: "Liste"
|
||||
noLists: "Nessuna lista"
|
||||
note: "Nota"
|
||||
notes: "Note"
|
||||
following: "Follows"
|
||||
following: "Lǝ segui"
|
||||
followers: "Followers"
|
||||
followsYou: "Ti segue"
|
||||
createList: "Aggiungi una nuova lista"
|
||||
@ -121,7 +121,7 @@ markAsSensitive: "Segna come sensibile"
|
||||
unmarkAsSensitive: "Segna come non sensibile"
|
||||
enterFileName: "Nome del file"
|
||||
mute: "Silenzia"
|
||||
unmute: "Riattiva"
|
||||
unmute: "Riattiva l'audio"
|
||||
block: "Blocca"
|
||||
unblock: "Sblocca"
|
||||
suspend: "Sospendi"
|
||||
@ -143,7 +143,7 @@ emojiName: "Nome dell'emoji"
|
||||
emojiUrl: "URL dell'emoji"
|
||||
addEmoji: "Aggiungi un emoji"
|
||||
settingGuide: "Configurazione suggerita"
|
||||
cacheRemoteFiles: "Memorizzazione nella cache dei file remoti"
|
||||
cacheRemoteFiles: "Memorizza i file remoti nella cache"
|
||||
cacheRemoteFilesDescription: "Disabilitando questa opzione, i file remoti verranno linkati direttamente senza essere memorizzati nella cache. Sarà possibile risparmiare spazio di archiviazione sul server, ma il traffico aumenterà in quanto non verranno generate anteprime."
|
||||
flagAsBot: "Io sono un robot"
|
||||
flagAsBotDescription: "Attiva questo campo se il profilo esegue principalmente operazioni automatiche. L'attivazione segnala agli altri sviluppatori come comportarsi per evitare catene d’interazione infinite con altri bot. I sistemi interni di Misskey si adegueranno al fine di trattare questo profilo come bot."
|
||||
@ -154,7 +154,7 @@ flagShowTimelineRepliesDescription: "Se è attiva, la timeline mostra le rispost
|
||||
autoAcceptFollowed: "Accetta automaticamente le richieste di follow da utenti che già segui"
|
||||
addAccount: "Aggiungi profilo"
|
||||
loginFailed: "Accesso non riuscito"
|
||||
showOnRemote: "Sfoglia sull'istanza remota"
|
||||
showOnRemote: "Visualizza sull'istanza remota"
|
||||
general: "Generali"
|
||||
wallpaper: "Sfondo"
|
||||
setWallpaper: "Imposta sfondo"
|
||||
@ -209,14 +209,14 @@ intro: "L'installazione di Misskey è terminata! Si prega di creare il profilo a
|
||||
done: "Fine"
|
||||
processing: "In elaborazione"
|
||||
preview: "Anteprima"
|
||||
default: "Predefinito"
|
||||
default: "Medio"
|
||||
defaultValueIs: "Predefinito: {value}"
|
||||
noCustomEmojis: "Nessun emoji"
|
||||
noJobs: "Nessun lavoro"
|
||||
federating: "Federazione"
|
||||
blocked: "Bloccato"
|
||||
suspended: "Sospensione"
|
||||
all: "Tutti"
|
||||
all: "Tutte"
|
||||
subscribing: "Iscrizione"
|
||||
publishing: "Pubblicazione"
|
||||
notResponding: "Nessuna risposta"
|
||||
@ -234,7 +234,7 @@ more: "Di più!"
|
||||
featured: "Tendenze"
|
||||
usernameOrUserId: "Nome utente o ID utente"
|
||||
noSuchUser: "Nessun utente trovato"
|
||||
lookup: "Cercare"
|
||||
lookup: "Cerca"
|
||||
announcements: "Annunci"
|
||||
imageUrl: "URL dell'immagine"
|
||||
remove: "Elimina"
|
||||
@ -288,7 +288,7 @@ selectFolders: "Seleziona cartella"
|
||||
renameFile: "Rinomina file"
|
||||
folderName: "Nome della cartella"
|
||||
createFolder: "Nuova cartella"
|
||||
renameFolder: "Rinominare cartella"
|
||||
renameFolder: "Rinomina cartella"
|
||||
deleteFolder: "Elimina cartella"
|
||||
addFile: "Allega"
|
||||
emptyDrive: "Il Drive è vuoto"
|
||||
@ -305,7 +305,7 @@ avatar: "Foto del profilo"
|
||||
banner: "Intestazione"
|
||||
nsfw: "Contenuti sensibili"
|
||||
whenServerDisconnected: "Quando la connessione col server è persa"
|
||||
disconnectedFromServer: "Disconness@ dal server"
|
||||
disconnectedFromServer: "Il server si è disconnesso"
|
||||
reload: "Ricarica"
|
||||
doNothing: "Nessun'azione"
|
||||
reloadConfirm: "Vuoi ricaricare?"
|
||||
@ -316,9 +316,9 @@ reject: "Rifiuta"
|
||||
normal: "Normale"
|
||||
instanceName: "Nome dell'istanza"
|
||||
instanceDescription: "Descrizione dell'istanza"
|
||||
maintainerName: "Nome dell'Amministratore"
|
||||
maintainerEmail: "Indirizzo e-mail dell'Amministratore"
|
||||
tosUrl: "Termini di servizio URL"
|
||||
maintainerName: "Nome dell'amministratore"
|
||||
maintainerEmail: "Indirizzo e-mail dell'amministratore"
|
||||
tosUrl: "URL dei termini del servizio e della privacy"
|
||||
thisYear: "Anno"
|
||||
thisMonth: "Mese"
|
||||
today: "Oggi"
|
||||
@ -327,13 +327,13 @@ monthX: "{month}"
|
||||
yearX: "{year}"
|
||||
pages: "Pagine"
|
||||
integration: "App collegate"
|
||||
connectService: "Connessione"
|
||||
disconnectService: "Disconnessione "
|
||||
enableLocalTimeline: "Abilita Timeline locale"
|
||||
enableGlobalTimeline: "Abilita Timeline federata"
|
||||
connectService: "Connetti"
|
||||
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"
|
||||
enableRegistration: "Permettere nuove registrazioni"
|
||||
enableRegistration: "Consenti a chiunque di registrarsi"
|
||||
invite: "Invita"
|
||||
driveCapacityPerLocalAccount: "Capienza del Drive per profilo locale"
|
||||
driveCapacityPerRemoteAccount: "Capienza del Drive per profilo remoto"
|
||||
@ -393,13 +393,10 @@ about: "Informazioni"
|
||||
aboutMisskey: "Informazioni di Misskey"
|
||||
administrator: "Amministratore"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Autenticazione a due fattori"
|
||||
moderator: "Moderatore"
|
||||
moderation: "moderazione"
|
||||
nUsersMentioned: "{n} profili menzionati"
|
||||
securityKey: "Chiave di sicurezza"
|
||||
securityKeyName: "Nome della chiave"
|
||||
registerSecurityKey: "Registra una chiave di sicurezza"
|
||||
lastUsed: "Ultima attività"
|
||||
unregister: "Annulla l'iscrizione"
|
||||
passwordLessLogin: "Accedi senza password"
|
||||
@ -417,24 +414,15 @@ markAsReadAllTalkMessages: "Segna tutte le chat come lette"
|
||||
help: "Guida"
|
||||
inputMessageHere: "Scrivi messaggio qui"
|
||||
close: "Chiudi"
|
||||
group: "Gruppo"
|
||||
groups: "Gruppi"
|
||||
createGroup: "Nuovo gruppo"
|
||||
ownedGroups: "I miei gruppi"
|
||||
joinedGroups: "Gruppi a cui mi sono unit@"
|
||||
invites: "Inviti"
|
||||
groupName: "Nome del gruppo"
|
||||
members: "Membri"
|
||||
transfer: "Trasferisci"
|
||||
messagingWithUser: "Iniziare una chat con un altr@ utente"
|
||||
messagingWithGroup: "Chattare in gruppo"
|
||||
title: "Titolo"
|
||||
text: "Testo"
|
||||
enable: "Abilita"
|
||||
next: "Avanti"
|
||||
retype: "Conferma"
|
||||
noteOf: "Note di {user}"
|
||||
inviteToGroup: "Invitare al gruppo"
|
||||
quoteAttached: "Citazione allegata"
|
||||
quoteQuestion: "Vuoi aggiungere una citazione?"
|
||||
noMessagesYet: "Ancora nessuna chat"
|
||||
@ -456,17 +444,13 @@ passwordMatched: "Corretta"
|
||||
passwordNotMatched: "Le password non corrispondono."
|
||||
signinWith: "Accedi con {x}"
|
||||
signinFailed: "Autenticazione non riuscita. Controlla la tua password e nome utente."
|
||||
tapSecurityKey: "Premi la chiave di sicurezza"
|
||||
or: "oppure"
|
||||
language: "Lingua"
|
||||
uiLanguage: "Lingua di visualizzazione dell'interfaccia"
|
||||
groupInvited: "Invitat@ al gruppo"
|
||||
aboutX: "Informazioni su {x}"
|
||||
emojiStyle: "Stile emoji"
|
||||
native: "Nativo"
|
||||
disableDrawer: "Non mostrare il menù sul drawer"
|
||||
youHaveNoGroups: "Nessun gruppo"
|
||||
joinOrCreateGroup: "Puoi creare il tuo gruppo o essere invitat@ a gruppi che già esistono."
|
||||
noHistory: "Nessuna cronologia"
|
||||
signinHistory: "Storico degli accessi al profilo"
|
||||
enableAdvancedMfm: "Attiva MFM avanzati"
|
||||
@ -480,7 +464,7 @@ existingAccount: "Profilo esistente"
|
||||
regenerate: "Generare di nuovo"
|
||||
fontSize: "Dimensione carattere"
|
||||
noFollowRequests: "Non hai alcuna richiesta di follow"
|
||||
openImageInNewTab: "Aprire immagini in una nuova scheda"
|
||||
openImageInNewTab: "Apri le immagini in un nuovo tab"
|
||||
dashboard: "Pannello di controllo"
|
||||
local: "Locale"
|
||||
remote: "Remoto"
|
||||
@ -609,7 +593,7 @@ smtpPass: "Password"
|
||||
emptyToDisableSmtpAuth: "Lasciare il nome utente e la password vuoti per disabilitare la verifica SMTP"
|
||||
smtpSecure: "Usare la porta SSL/TLS implicito per le connessioni SMTP"
|
||||
smtpSecureInfo: "Disabilitare quando è attivo STARTTLS."
|
||||
testEmail: "Testare la consegna di posta elettronica"
|
||||
testEmail: "Testa la consegna di posta elettronica"
|
||||
wordMute: "Filtri parole"
|
||||
regexpError: "errore regex"
|
||||
regexpErrorDescription: "Si è verificato un errore nell'espressione regolare alla riga {line} della parola muta {tab}:"
|
||||
@ -622,7 +606,7 @@ metrics: "Statistiche"
|
||||
overview: "Anteprima"
|
||||
logs: "Log"
|
||||
delayed: "Ritardo"
|
||||
database: "Base di dati"
|
||||
database: "Base dati"
|
||||
channel: "Canale"
|
||||
create: "Crea"
|
||||
notificationSetting: "Impostazioni notifiche"
|
||||
@ -711,7 +695,7 @@ narrow: "Stretto"
|
||||
reloadToApplySetting: "Le tue preferenze verranno impostate dopo il ricaricamento della pagina. Vuoi ricaricare adesso?"
|
||||
needReloadToApply: "È necessario riavviare per rendere effettive le modifiche."
|
||||
showTitlebar: "Visualizza la barra del titolo"
|
||||
clearCache: "Svuota cache"
|
||||
clearCache: "Svuota la cache"
|
||||
onlineUsersCount: "{n} utenti online"
|
||||
nUsers: "{n} utenti"
|
||||
nNotes: "{n}Note"
|
||||
@ -736,9 +720,9 @@ currentVersion: "Versione attuale"
|
||||
latestVersion: "Ultima versione"
|
||||
youAreRunningUpToDateClient: "Stai usando la versione più recente del client."
|
||||
newVersionOfClientAvailable: "Una nuova versione del tuo client è disponibile."
|
||||
usageAmount: "In utilizzo"
|
||||
usageAmount: "In uso"
|
||||
capacity: "Capacità"
|
||||
inUse: "In utilizzo"
|
||||
inUse: "In uso"
|
||||
editCode: "Modifica codice"
|
||||
apply: "Applica"
|
||||
receiveAnnouncementFromInstance: "Ricevi i messaggi informativi dall'istanza"
|
||||
@ -824,7 +808,7 @@ breakFollow: "Smetti di seguire"
|
||||
itsOn: "Abilitato"
|
||||
itsOff: "Disabilitato"
|
||||
emailRequiredForSignup: "L'ndirizzo e-mail è obbligatorio per registrarsi"
|
||||
unread: "Non letto"
|
||||
unread: "Non lette"
|
||||
filter: "Filtri"
|
||||
controlPanel: "Pannello di controllo"
|
||||
manageAccounts: "Gestisci i profili"
|
||||
@ -840,8 +824,6 @@ deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?"
|
||||
incorrectPassword: "La password è errata."
|
||||
voteConfirm: "Votare per「{choice}」?"
|
||||
hide: "Nascondere"
|
||||
leaveGroup: "Esci dal gruppo"
|
||||
leaveGroupConfirm: "Uscire da「{name}」?"
|
||||
useDrawerReactionPickerForMobile: "Mostra sul drawer da dispositivo mobile"
|
||||
welcomeBackWithName: "Ciao, {name}! Eccoti di nuovo!"
|
||||
clickToFinishEmailVerification: "Fai click su [{ok}] per completare la verifica dell'indirizzo email."
|
||||
@ -864,9 +846,9 @@ oneDay: "1 giorno"
|
||||
oneWeek: "1 settimana"
|
||||
reflectMayTakeTime: "Potrebbe essere necessario un po' di tempo perché ciò abbia effetto."
|
||||
failedToFetchAccountInformation: "Impossibile recuperare le informazioni sul profilo"
|
||||
rateLimitExceeded: "Superato il limite di velocità."
|
||||
cropImage: "Ritaglio dell'immagine"
|
||||
cropImageAsk: "Si desidera ritagliare l'immagine?"
|
||||
rateLimitExceeded: "Superato il limite di richieste."
|
||||
cropImage: "Ritaglia l'immagine"
|
||||
cropImageAsk: "Vuoi ritagliare l'immagine?"
|
||||
cropYes: "Ritaglia"
|
||||
cropNo: "Non ritagliare"
|
||||
file: "Allegati"
|
||||
@ -1012,53 +994,53 @@ _achievements:
|
||||
flavor: "Hai molto da scrivere?"
|
||||
_login3:
|
||||
title: "Principiante I"
|
||||
description: "Accedi per un totale di 3 giorni"
|
||||
description: "Hai totalizzato 3 accessi!"
|
||||
flavor: "Da oggi, chiamatemi Misskist"
|
||||
_login7:
|
||||
title: "Principiante II"
|
||||
description: "Accedi per un totale di 7 giorni"
|
||||
description: "Hai totalizzato 7 accessi!"
|
||||
flavor: "Ti sembra di avere la situazione sotto controllo?"
|
||||
_login15:
|
||||
title: "Principiante III"
|
||||
description: "Accedi per un totale di 15 giorni"
|
||||
description: "Hai totalizzato 15 accessi!"
|
||||
_login30:
|
||||
title: "Misskist I"
|
||||
description: "Accedi per un totale di 30 giorni"
|
||||
description: "Hai totalizzato 30 accessi!"
|
||||
_login60:
|
||||
title: "Misskeist II"
|
||||
description: "Accedi per un totale di 60 giorni"
|
||||
description: "Hai totalizzato 60 accessi!"
|
||||
_login100:
|
||||
title: "Misskeist III"
|
||||
description: "Accedi per un totale di 100 giorni"
|
||||
description: "Hai totalizzato 100 accessi!"
|
||||
flavor: "Violent Misskeist"
|
||||
_login200:
|
||||
title: "Regolare I"
|
||||
description: "Accedi per un totale di 200 giorni"
|
||||
title: "Regolare I livello"
|
||||
description: "Hai totalizzato 200 accessi!"
|
||||
_login300:
|
||||
title: "Regolare II"
|
||||
description: "Accedi per un totale di 300 giorni"
|
||||
title: "Regolare II livello"
|
||||
description: "Hai totalizzato 300 accessi!"
|
||||
_login400:
|
||||
title: "Regolare III"
|
||||
description: "Accedi per un totale di 400 giorni"
|
||||
title: "Regolare III livello"
|
||||
description: "Hai totalizzato 400 accessi!"
|
||||
_login500:
|
||||
title: "Professionista I"
|
||||
description: "Accedi per un totale di 500 giorni"
|
||||
title: "Professionista I livello"
|
||||
description: "Hai totalizzato 500 accessi!"
|
||||
flavor: "Amici cari, mi piacciono le Note"
|
||||
_login600:
|
||||
title: "Professionista II"
|
||||
description: "Accedi per un totale di 600 giorni"
|
||||
title: "Professionista II livello"
|
||||
description: "Hai totalizzato 600 accessi!"
|
||||
_login700:
|
||||
title: "Professionista III"
|
||||
description: "Accedi per un totale di 700 giorni"
|
||||
title: "Professionista III livello"
|
||||
description: "Hai totalizzato 700 accessi!"
|
||||
_login800:
|
||||
title: "Maestro di Note I"
|
||||
description: "Accedi per un totale di 800 giorni"
|
||||
title: "Maestro di Note I livello"
|
||||
description: "Hai totalizzato 800 accessi!"
|
||||
_login900:
|
||||
title: "Maestro di Note II"
|
||||
description: "Accedi per un totale di 900 giorni"
|
||||
title: "Maestro di Note II livello"
|
||||
description: "Hai totalizzato 900 accessi!"
|
||||
_login1000:
|
||||
title: "Maestro di Note III"
|
||||
description: "Accedi per un totale di 1.000 giorni"
|
||||
title: "Maestro di Note III livello"
|
||||
description: "Hai totalizzato 1000 accessi!"
|
||||
flavor: "Grazie per aver usato Misskey!"
|
||||
_noteClipped1:
|
||||
title: "Devo clippare!"
|
||||
@ -1070,7 +1052,7 @@ _achievements:
|
||||
title: "Fornitura stelline"
|
||||
description: "Qualcuno ha preferito una delle tue Note"
|
||||
_profileFilled:
|
||||
title: "Perfettamente"
|
||||
title: "Preparazione perfetta!"
|
||||
description: "Imposta il tuo profilo"
|
||||
_markedAsCat:
|
||||
title: "Io sono un gatto"
|
||||
@ -1470,6 +1452,7 @@ _ago:
|
||||
weeksAgo: "{n} sett. fa"
|
||||
monthsAgo: "{n} mesi fa"
|
||||
yearsAgo: "{n} anni fa"
|
||||
invalid: "Niente da visualizzare"
|
||||
_time:
|
||||
second: "s"
|
||||
minute: "min"
|
||||
@ -1478,10 +1461,10 @@ _time:
|
||||
_tutorial:
|
||||
title: "Come usare Misskey"
|
||||
step1_1: "Eccoci!"
|
||||
step1_2: "Questa pagina si chiama una \" Timeline \". Mostra in ordine cronologico le \" note \" delle persone che segui."
|
||||
step1_3: "Attualmente la tua Timeline è vuota perché non segui alcun profilo e non hai pubblicato alcuna nota ancora."
|
||||
step1_2: "Questa pagina si chiama \"Timeline \" e mostra in ordine cronologico le \"note\" delle persone che segui."
|
||||
step1_3: "Attualmente la tua Timeline è vuota perché non segui alcun profilo e non hai ancora pubblicato alcuna nota."
|
||||
step2_1: "Prima di scrivere una «Nota» o di seguire altri profili, prepara il tuo profilo!"
|
||||
step2_2: "Aggiungere qualche informazione su di te aumenterà le tue possibilità di essere seguit@ da altre persone. "
|
||||
step2_2: "Se aggiungi informazioni personali aumenterai le tue possibilità di essere seguit@ da altre persone. "
|
||||
step3_1: "Hai finito di impostare il tuo profilo?"
|
||||
step3_2: "Ora puoi pubblicare una «Nota». Proviamo subito! Premi il bottone con l'icona «penna» per iniziare a scrivere in una finestra di dialogo. "
|
||||
step3_3: "Scritto il testo della nota, puoi pubblicarla premendo il pulsante nella parte superiore destra della finestra di dialogo."
|
||||
@ -1500,24 +1483,24 @@ _tutorial:
|
||||
step7_3: "Da ultimo, buon divertimento su Misskey! 🚀"
|
||||
step8_1: "Per concludere, vuoi attivare le notifiche push?"
|
||||
step8_2: "Attivandole, otterrai notifiche di follow, reazioni e menzioni anche quando Misskey è chiuso."
|
||||
step8_3: "Puoi anche modificare questa impostazione successivamente."
|
||||
step8_3: "Potrai modificare questa impostazione."
|
||||
_2fa:
|
||||
alreadyRegistered: "La configurazione è stata già completata."
|
||||
registerDevice: "Aggiungi dispositivo"
|
||||
registerKey: "Chiave di registro."
|
||||
step1: "Innanzitutto, installare sul dispositivo un'applicazione di autenticazione come {a} o {b}."
|
||||
step2: "Quindi, scansionare il codice QR visualizzato con l'app."
|
||||
step2Url: "Nell'applicazione desktop inserire il seguente URL: "
|
||||
step3: "Inserite il token visualizzato nell'app e il gioco è fatto."
|
||||
step4: "D'ora in poi, quando si accede, si inserisce il token nello stesso modo."
|
||||
securityKeyInfo: "È possibile impostare il dispositivo per accedere utilizzando una chiave di sicurezza hardware che supporta FIDO2 o un'impronta digitale o un PIN sul dispositivo."
|
||||
removeKeyConfirm: "Vuoi davvero eliminare \"{name}\"?"
|
||||
renewTOTPCancel: "No grazie"
|
||||
_permissions:
|
||||
"read:account": "Visualizzare le informazioni sul profilo"
|
||||
"write:account": "Modificare le informazioni sul profilo"
|
||||
"read:account": "Visualizza le informazioni sul profilo"
|
||||
"write:account": "Modifica le informazioni sul profilo"
|
||||
"read:blocks": "Visualizza i profili bloccati"
|
||||
"write:blocks": "Gestisci i profili bloccati"
|
||||
"read:drive": "Aprire il Drive"
|
||||
"write:drive": "Gestire il Drive"
|
||||
"read:drive": "Apri il Drive"
|
||||
"write:drive": "Gestisci il Drive"
|
||||
"read:favorites": "Visualizza i tuoi preferiti"
|
||||
"write:favorites": "Gestisci i tuoi preferiti"
|
||||
"read:following": "Vedi le informazioni di follow"
|
||||
@ -1559,7 +1542,6 @@ _antennaSources:
|
||||
homeTimeline: "Note dagli utenti che segui"
|
||||
users: "Note dagli utenti selezionati"
|
||||
userList: "Note dagli utenti della lista selezionata"
|
||||
userGroup: "Note dagli utenti del gruppo selezionato"
|
||||
_weekday:
|
||||
sunday: "Domenica"
|
||||
monday: "Lunedì"
|
||||
@ -1632,21 +1614,19 @@ _visibility:
|
||||
homeDescription: "Visibile solo sulla timeline \"Home\""
|
||||
followers: "Followers"
|
||||
followersDescription: "Visibile solo per i tuoi followers"
|
||||
specified: "Diretta"
|
||||
specified: "Nota diretta"
|
||||
specifiedDescription: "Visibile solo ai profili menzionati"
|
||||
localOnly: "Soltanto locale"
|
||||
localOnlyDescription: "Non visibile ai profili remoti"
|
||||
_postForm:
|
||||
replyPlaceholder: "Nota la tua risposta.."
|
||||
quotePlaceholder: "Cita Nota..."
|
||||
channelPlaceholder: "Pubblica in canale"
|
||||
replyPlaceholder: "Rispondi a questa nota..."
|
||||
quotePlaceholder: "Cita questa nota..."
|
||||
channelPlaceholder: "Pubblica sul canale..."
|
||||
_placeholders:
|
||||
a: "Che succede?"
|
||||
b: "È successo qualcosa?"
|
||||
c: "Che cos'hai in mente?"
|
||||
a: "Come va?"
|
||||
b: "Hai qualcosa da raccontare? Inizia pure..."
|
||||
c: "Stai pensando a qualcosa?"
|
||||
d: "Vuoi dire qualcosa?"
|
||||
e: "Scrivi qualcosa qui"
|
||||
f: "Aspettando che scriva..."
|
||||
e: "Puoi scrivere qui..."
|
||||
f: "Inizia pure a scrivere..."
|
||||
_profile:
|
||||
name: "Nome"
|
||||
username: "Nome utente"
|
||||
@ -1677,9 +1657,9 @@ _charts:
|
||||
notesIncDec: "Variazione del numero di note"
|
||||
localNotesIncDec: "Variazione del numero di note locali"
|
||||
remoteNotesIncDec: "Variazione del numero di note distanti"
|
||||
notesTotal: "Conteggio totale di note"
|
||||
notesTotal: "Numero di note in totale"
|
||||
filesIncDec: "Variazione del numero dei file"
|
||||
filesTotal: "Numero totale di file"
|
||||
filesTotal: "Numero di file in totale"
|
||||
storageUsageIncDec: "Variazione dell'utilizzo dell'immagazzinamento"
|
||||
storageUsageTotal: "Utilizzo totale dell'immagazzinamento"
|
||||
_instanceCharts:
|
||||
@ -1771,14 +1751,11 @@ _notification:
|
||||
fileUploaded: "File caricato correttamente"
|
||||
youGotMention: "{name} ti ha menzionato"
|
||||
youGotReply: "{name} ti ha risposto"
|
||||
youGotQuote: "{name} ha citato il tuo Nota e ha detto"
|
||||
youGotQuote: "{name} ha citato la tua Nota e ha detto"
|
||||
youRenoted: "{name} ha rinotato"
|
||||
youGotMessagingMessageFromUser: "{name} ti ha mandato un messaggio"
|
||||
youGotMessagingMessageFromGroup: "{name} ti ha mandato un messaggio nella chat"
|
||||
youWereFollowed: "Ha iniziato a seguirti"
|
||||
youReceivedFollowRequest: "Hai ricevuto una richiesta di follow"
|
||||
yourFollowRequestAccepted: "La tua richiesta di follow è stata accettata"
|
||||
youWereInvitedToGroup: "Invitat@ al gruppo"
|
||||
pollEnded: "Risultati del sondaggio."
|
||||
unreadAntennaNote: "Antenna {name}"
|
||||
emptyPushNotificationMessage: "Le notifiche push sono state aggiornate."
|
||||
@ -1794,7 +1771,6 @@ _notification:
|
||||
pollEnded: "Sondaggio chiuso."
|
||||
receiveFollowRequest: "Richiesta di follow ricevuta"
|
||||
followRequestAccepted: "Richiesta di follow accettata"
|
||||
groupInvited: "Invito a un gruppo"
|
||||
app: "Notifiche da applicazioni"
|
||||
_actions:
|
||||
followBack: "Segui"
|
||||
|
@ -814,6 +814,7 @@ lastCommunication: "直近の通信"
|
||||
resolved: "解決済み"
|
||||
unresolved: "未解決"
|
||||
breakFollow: "フォロワーを解除"
|
||||
breakFollowConfirm: "フォロワー解除しますか?"
|
||||
itsOn: "オンになっています"
|
||||
itsOff: "オフになっています"
|
||||
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
|
||||
@ -951,6 +952,7 @@ copyErrorInfo: "エラー情報をコピー"
|
||||
joinThisServer: "このサーバーに登録する"
|
||||
exploreOtherServers: "他のサーバーを探す"
|
||||
letsLookAtTimeline: "タイムラインを見てみる"
|
||||
disableFederationWarn: "連合が無効になっています。無効にしても投稿が非公開にはなりません。ほとんどの場合、このオプションを有効にする必要はありません。"
|
||||
|
||||
_achievements:
|
||||
earnedAt: "獲得日時"
|
||||
@ -1494,6 +1496,7 @@ _ago:
|
||||
weeksAgo: "{n}週間前"
|
||||
monthsAgo: "{n}ヶ月前"
|
||||
yearsAgo: "{n}年前"
|
||||
invalid: "ありません"
|
||||
|
||||
_time:
|
||||
second: "秒"
|
||||
@ -1687,8 +1690,8 @@ _visibility:
|
||||
followersDescription: "自分のフォロワーのみに公開"
|
||||
specified: "ダイレクト"
|
||||
specifiedDescription: "指定したユーザーのみに公開"
|
||||
localOnly: "ローカルのみ"
|
||||
localOnlyDescription: "リモートユーザーには非公開"
|
||||
disableFederation: "連合なし"
|
||||
disableFederationDescription: "他インスタンスへの配信を行いません"
|
||||
|
||||
_postForm:
|
||||
replyPlaceholder: "このノートに返信..."
|
||||
|
@ -67,7 +67,7 @@ import: "インポート"
|
||||
export: "エクスポート"
|
||||
files: "ファイル"
|
||||
download: "ダウンロード"
|
||||
driveFileDeleteConfirm: "ファイル「{name}」を消してしもうてええか?このファイルを添付したノートも消えてまうで。"
|
||||
driveFileDeleteConfirm: "ファイル「{name}」をほかしてええか?このファイルを添付したノートも消えてまうで。"
|
||||
unfollowConfirm: "{name}のフォローを解除してもええんか?"
|
||||
exportRequested: "エクスポートしてな、ってリクエストしたけど、これ多分めっちゃ時間かかるで。エクスポート終わったら「ドライブ」に突っ込んどくで。"
|
||||
importRequested: "インポートしてな、ってリクエストしたけど、これ多分めっちゃ時間かかるで。"
|
||||
@ -83,7 +83,7 @@ manageLists: "リストの管理"
|
||||
error: "エラー"
|
||||
somethingHappened: "なんかアカンことが起こったで"
|
||||
retry: "もっぺんやる?"
|
||||
pageLoadError: "ページの読み込みに失敗してしもうたで…"
|
||||
pageLoadError: "ページの読み込みに失敗してもうたわ…"
|
||||
pageLoadErrorDescription: "これは普通、ネットワークかブラウザキャッシュが原因やからね。キャッシュをクリアするか、もうちっとだけ待ってくれへんか?"
|
||||
serverIsDead: "サーバーからの応答がないで。もうちょい待ってから試してみてな。"
|
||||
youShouldUpgradeClient: "このページを表示するには、リロードして新しいバージョンのクライアントを使ってなー。"
|
||||
@ -153,7 +153,7 @@ flagShowTimelineReplies: "タイムラインにノートへの返信を表示す
|
||||
flagShowTimelineRepliesDescription: "オンにしたら、タイムラインにユーザーのノートの他にもそのユーザーの他のノートへの返信を表示するで。"
|
||||
autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストを勝手に許可しとく"
|
||||
addAccount: "アカウントを追加"
|
||||
loginFailed: "ログインに失敗してしもうた…"
|
||||
loginFailed: "ログインに失敗してもうた…"
|
||||
showOnRemote: "リモートで見る"
|
||||
general: "全般"
|
||||
wallpaper: "壁紙"
|
||||
@ -245,7 +245,7 @@ resetAreYouSure: "リセットしてええん?"
|
||||
saved: "保存したで!"
|
||||
messaging: "チャット"
|
||||
upload: "アップロード"
|
||||
keepOriginalUploading: "オリジナル画像を保持するで"
|
||||
keepOriginalUploading: "オリジナル画像を保持するわ"
|
||||
keepOriginalUploadingDescription: "画像を上げるときにオリジナル版を保持するで。オフにしたら上げたときにブラウザでWeb公開用の画像を生成するで。 "
|
||||
fromDrive: "ドライブから"
|
||||
fromUrl: "URLから"
|
||||
@ -393,16 +393,19 @@ about: "情報"
|
||||
aboutMisskey: "Misskeyってなんや?"
|
||||
administrator: "管理者"
|
||||
token: "トークン"
|
||||
twoStepAuthentication: "二段階認証"
|
||||
2fa: "二要素認証"
|
||||
totp: "認証アプリ"
|
||||
totpDescription: "認証アプリ使てワンタイムパスワードを入れる"
|
||||
moderator: "モデレーター"
|
||||
moderation: "モデレーション"
|
||||
nUsersMentioned: "{n}人が投稿"
|
||||
securityKeyAndPasskey: "セキュリティキー・パスキー"
|
||||
securityKey: "セキュリティキー"
|
||||
securityKeyName: "キーの名前"
|
||||
registerSecurityKey: "セキュリティキーを登録するで"
|
||||
lastUsed: "最後につこうた日"
|
||||
lastUsedAt: "最後に使たん: {t}"
|
||||
unregister: "登録やめる"
|
||||
passwordLessLogin: "パスワード無くてもログインできるようにする"
|
||||
passwordLessLoginDescription: "パスワードやなくて、セキュリティキーとかパスキーだけでログインするわ"
|
||||
resetPassword: "パスワードをリセット"
|
||||
newPasswordIs: "今度のパスワードは「{password}」や"
|
||||
reduceUiAnimation: "UIの動きやアニメーションを減らす"
|
||||
@ -417,24 +420,15 @@ markAsReadAllTalkMessages: "チャットはもうぜんぶ読んだわっ"
|
||||
help: "ヘルプ"
|
||||
inputMessageHere: "ここにメッセージ書いてや"
|
||||
close: "閉じる"
|
||||
group: "グループ"
|
||||
groups: "グループ"
|
||||
createGroup: "グループを作るで"
|
||||
ownedGroups: "所有しとるグループ"
|
||||
joinedGroups: "参加しとるグループ"
|
||||
invites: "来てや"
|
||||
groupName: "グループ名"
|
||||
members: "メンバー"
|
||||
transfer: "譲渡"
|
||||
messagingWithUser: "ユーザーとチャット"
|
||||
messagingWithGroup: "グループでチャット"
|
||||
title: "タイトル"
|
||||
text: "テキスト"
|
||||
enable: "有効にするで"
|
||||
next: "次"
|
||||
retype: "もっかい入力"
|
||||
noteOf: "{user}のノート"
|
||||
inviteToGroup: "グループに招く"
|
||||
quoteAttached: "引用付いとるで"
|
||||
quoteQuestion: "引用として添付してもええか?"
|
||||
noMessagesYet: "まだチャットはあらへんで"
|
||||
@ -456,17 +450,13 @@ passwordMatched: "よし!一致や!"
|
||||
passwordNotMatched: "一致しとらんで?"
|
||||
signinWith: "{x}でログイン"
|
||||
signinFailed: "ログインできんかったで。もっかいユーザー名とパスワードを確認してみてな。"
|
||||
tapSecurityKey: "セキュリティキーにタッチしてな"
|
||||
or: "それか"
|
||||
language: "言語"
|
||||
uiLanguage: "UIの表示言語"
|
||||
groupInvited: "グループに招待されとるで"
|
||||
aboutX: "{x}について"
|
||||
emojiStyle: "絵文字のスタイル"
|
||||
native: "ネイティブ"
|
||||
disableDrawer: "メニューをドロワーで表示せぇへん"
|
||||
youHaveNoGroups: "グループがあらへんねぇ。"
|
||||
joinOrCreateGroup: "既存のグループに招待してもらうか、新しくグループ作ってからやってな"
|
||||
noHistory: "履歴はあらへんねぇ。"
|
||||
signinHistory: "ログイン履歴"
|
||||
enableAdvancedMfm: "ややこしいMFMもありにする"
|
||||
@ -591,7 +581,7 @@ generateAccessToken: "アクセストークンの発行"
|
||||
permission: "権限"
|
||||
enableAll: "全部使えるようにする"
|
||||
disableAll: "全部使えへんようにする"
|
||||
tokenRequested: "アカウントへのアクセス許可"
|
||||
tokenRequested: "アカウントへのアクセス許してやったらどうや"
|
||||
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を使えるようになるで。"
|
||||
notificationType: "通知の種類"
|
||||
edit: "編集"
|
||||
@ -789,6 +779,7 @@ popularPosts: "人気の投稿"
|
||||
shareWithNote: "ノートで共有"
|
||||
ads: "広告"
|
||||
expiration: "期限"
|
||||
startingperiod: "始めた期間"
|
||||
memo: "メモ"
|
||||
priority: "優先度"
|
||||
high: "高い"
|
||||
@ -821,6 +812,7 @@ lastCommunication: "直近の通信"
|
||||
resolved: "解決したで"
|
||||
unresolved: "まだ解決してないで"
|
||||
breakFollow: "フォロワーを解除するで"
|
||||
breakFollowConfirm: "フォロワー解除してもええか?"
|
||||
itsOn: "オンになっとるよ"
|
||||
itsOff: "オフになってるで"
|
||||
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にするで"
|
||||
@ -840,10 +832,8 @@ deleteAccountConfirm: "アカウントを消すで?ええんか?"
|
||||
incorrectPassword: "パスワードがちゃうで。"
|
||||
voteConfirm: "「{choice}」に投票するんか?"
|
||||
hide: "隠す"
|
||||
leaveGroup: "グループから抜けるで"
|
||||
leaveGroupConfirm: "「{name}」から抜けるん?"
|
||||
useDrawerReactionPickerForMobile: "ケータイとかのときドロワーで表示するで"
|
||||
welcomeBackWithName: "まいど、{name}さん"
|
||||
welcomeBackWithName: "まいど、{name}はん"
|
||||
clickToFinishEmailVerification: "[{ok}]を押してメアドの確認を終わらせてなー"
|
||||
overridedDeviceKind: "デバイスタイプ"
|
||||
smartphone: "スマホ"
|
||||
@ -900,7 +890,7 @@ fast: "速い"
|
||||
sensitiveMediaDetection: "センシティブなメディアの検出"
|
||||
localOnly: "ローカルのみ"
|
||||
remoteOnly: "リモートのみ"
|
||||
failedToUpload: "アップロードに失敗したで"
|
||||
failedToUpload: "アップロードに失敗してもうたわ…"
|
||||
cannotUploadBecauseInappropriate: "不適切な内容を含むかもしれへんって判定されたでアップロードできまへん。"
|
||||
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いでアップロードできまへん。"
|
||||
beta: "ベータ"
|
||||
@ -957,6 +947,10 @@ collapseRenotes: "見たことあるRenoteは省略やで"
|
||||
internalServerError: "サーバー内部エラー"
|
||||
internalServerErrorDescription: "サーバー内部でよう分からんエラーやわ"
|
||||
copyErrorInfo: "エラー情報をコピー"
|
||||
joinThisServer: "このサーバーに登録するわ"
|
||||
exploreOtherServers: "他のサーバー見てみる"
|
||||
letsLookAtTimeline: "タイムライン見てみーや"
|
||||
disableFederationWarn: "連合が無効になっとるで。無効にしても投稿は非公開ってわけちゃうねん。大体の場合はこのオプションを有効にする必要は別にないで。"
|
||||
_achievements:
|
||||
earnedAt: "貰った日ぃ"
|
||||
_types:
|
||||
@ -1012,33 +1006,106 @@ _achievements:
|
||||
flavor: "そんなに書くことあるんか?"
|
||||
_login3:
|
||||
title: "ビギナーⅠ"
|
||||
description: "通算ログイン日数が3日"
|
||||
description: "通算3日ログインした"
|
||||
flavor: "今日からワシはミスキストやで"
|
||||
_login7:
|
||||
title: "ビギナーⅡ"
|
||||
description: "通算ログイン日数が7日"
|
||||
description: "通算7日ログインした"
|
||||
flavor: "慣れてきたんちゃう?"
|
||||
_login15:
|
||||
title: "ビギナーⅢ"
|
||||
description: "通算ログイン日数が15日"
|
||||
description: "通算15日ログインした"
|
||||
_login30:
|
||||
title: "ミスキストⅠ"
|
||||
description: "通算ログイン日数が30日"
|
||||
description: "通算30日ログインした"
|
||||
_login60:
|
||||
title: "ミスキストⅡ"
|
||||
description: "通算ログイン日数が60日"
|
||||
description: "通算60日ログインした"
|
||||
_login100:
|
||||
title: "ミスキストⅢ"
|
||||
description: "通算ログイン日数が100日"
|
||||
description: "通算100日ログインした"
|
||||
flavor: "そのユーザー、ミスキストにつき"
|
||||
_login200:
|
||||
title: "常連Ⅰ"
|
||||
title: "常連さんⅠ"
|
||||
description: "通算200日ログインした"
|
||||
_login300:
|
||||
title: "常連さんⅡ"
|
||||
description: "通算300日ログインした"
|
||||
_login400:
|
||||
title: "常連さんⅢ"
|
||||
description: "通算400日ログインした"
|
||||
_login500:
|
||||
title: "ベテランさんⅠ"
|
||||
description: "通算500日ログインした"
|
||||
flavor: "あんたら、うちはノートが好きや"
|
||||
_login600:
|
||||
title: "ベテランさんⅡ"
|
||||
description: "通算600日ログインした"
|
||||
_login700:
|
||||
title: "ベテランさんⅢ"
|
||||
description: "通算700日ログインした"
|
||||
_login800:
|
||||
title: "ノートマイスターⅠ"
|
||||
description: "通算800日ログインした"
|
||||
_login900:
|
||||
title: "ノートマイスターⅡ"
|
||||
description: "通算900日ログインした"
|
||||
_login1000:
|
||||
title: "ノートマイスターⅢ"
|
||||
description: "通算1,000日ログインした"
|
||||
flavor: "Misskeyようさん使てもろておおきにな!"
|
||||
_noteClipped1:
|
||||
title: "アカンどれもクリップしたいわ"
|
||||
description: "初めてノートをクリップした"
|
||||
_noteFavorited1:
|
||||
title: "星ぃみるひと"
|
||||
description: "初めてノートをお気に入りに登録した"
|
||||
_myNoteFavorited1:
|
||||
title: "星ぃ欲しい"
|
||||
description: "ワレのノートが他のひとにお気に入り登録されたで"
|
||||
_profileFilled:
|
||||
title: "準備万端や"
|
||||
description: "プロフィールを設定した"
|
||||
_markedAsCat:
|
||||
title: "吾輩は猫やねん"
|
||||
description: "アカウントがCatになってもうた"
|
||||
flavor: "名前はまだないねん。"
|
||||
_following1:
|
||||
title: "はじめてのフォロー"
|
||||
description: "初めてフォローした"
|
||||
_following10:
|
||||
title: "ついてく、ついてく"
|
||||
description: "フォローが10人超えた"
|
||||
_following50:
|
||||
title: "友達ぎょうさん"
|
||||
description: "フォローが50人超えた"
|
||||
_following100:
|
||||
title: "友達100人"
|
||||
description: "フォローが100人超えた"
|
||||
_following300:
|
||||
title: "いや友達多すぎやろ"
|
||||
description: "フォローが300人超えた"
|
||||
_followers1:
|
||||
title: "はじめてのフォロワー"
|
||||
description: "初めてフォローされた"
|
||||
_followers10:
|
||||
title: "フォローみぃ!"
|
||||
description: "フォロワーが10人超えた"
|
||||
_followers50:
|
||||
title: "ぞろぞろ"
|
||||
description: "フォロワーが50人超えた"
|
||||
_followers100:
|
||||
title: "人気もん"
|
||||
description: "フォロワーが100人超えた"
|
||||
_followers300:
|
||||
title: "ほらそこ一列に並んで!"
|
||||
description: "フォロワーが300人超えた"
|
||||
_followers500:
|
||||
title: "基地局"
|
||||
description: "フォロワーが500人を超した"
|
||||
description: "フォロワーが500人超えた"
|
||||
_followers1000:
|
||||
title: "インフルエンサー"
|
||||
description: "フォロワーが1,000人を超した"
|
||||
description: "フォロワーが1,000人超えた"
|
||||
_collectAchievements30:
|
||||
title: "実績コレクター"
|
||||
description: "実績を30個以上獲得した"
|
||||
@ -1112,6 +1179,14 @@ _achievements:
|
||||
title: "あけましておめでとうございます!"
|
||||
description: "元旦にログインした"
|
||||
flavor: "今年も弊インスタンスをよろしくお願いします"
|
||||
_cookieClicked:
|
||||
title: "クッキー叩くやつ"
|
||||
description: "クッキー叩いてもうた"
|
||||
flavor: "兄ちゃんソフト間違っとんで"
|
||||
_brainDiver:
|
||||
title: "Brain Diver"
|
||||
description: "Brain Diverへのリンクを投稿したった"
|
||||
flavor: "Misskey-Misskey La-Tu-Ma"
|
||||
_role:
|
||||
new: "ロールの作成"
|
||||
edit: "ロールの編集"
|
||||
@ -1132,6 +1207,9 @@ _role:
|
||||
baseRole: "ベースロール"
|
||||
useBaseValue: "ベースロールの値を使用"
|
||||
chooseRoleToAssign: "アサインするロールを選択"
|
||||
iconUrl: "アイコン画像のURL"
|
||||
asBadge: "バッジとして見せる"
|
||||
descriptionOfAsBadge: "オンにすると、ユーザー名の横んとこにロールのアイコンが表示されるで。"
|
||||
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
|
||||
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになるで。オフにすると管理者のみが行えるで。"
|
||||
priority: "優先度"
|
||||
@ -1386,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "{n}週間前"
|
||||
monthsAgo: "{n}ヶ月前"
|
||||
yearsAgo: "{n}年前"
|
||||
invalid: "あらへん"
|
||||
_time:
|
||||
second: "秒"
|
||||
minute: "分"
|
||||
@ -1419,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "通知の設定はあとから変更できるで"
|
||||
_2fa:
|
||||
alreadyRegistered: "もう設定終わっとるわ。"
|
||||
registerDevice: "デバイスを登録するで"
|
||||
registerKey: "キーを登録するで"
|
||||
registerTOTP: "認証アプリの設定はじめる"
|
||||
passwordToTOTP: "パスワードを入れてーや"
|
||||
step1: "ほんなら、{a}や{b}とかの認証アプリを使っとるデバイスにインストールしてな。"
|
||||
step2: "次に、ここにあるQRコードをアプリでスキャンしてな~。"
|
||||
step2Click: "QRコードをクリックすると、今使とる端末に入っとる認証アプリとかキーリングに登録できるで。"
|
||||
step2Url: "デスクトップアプリやったら次のURLを入力してや:"
|
||||
step3Title: "確認コードを入れてーや"
|
||||
step3: "アプリに表示されているトークンを入力して終わりや。"
|
||||
step4: "これからログインするときも、同じようにトークンを入力するんやで"
|
||||
securityKeyNotSupported: "今使とるブラウザはセキュリティキーに対応してへんのやってさ。"
|
||||
registerTOTPBeforeKey: "セキュリティキー・パスキーを登録するんやったら、まず認証アプリを設定してーな。"
|
||||
securityKeyInfo: "FIDO2をサポートするハードウェアセキュリティキーか端末の指紋認証やPINを使ってログインするように設定できるで。"
|
||||
chromePasskeyNotSupported: "Chromeのパスキーは今んとこ対応してないねん。"
|
||||
registerSecurityKey: "セキュリティキー・パスキーを登録するわ"
|
||||
securityKeyName: "キーの名前を入れてーや"
|
||||
tapSecurityKey: "ブラウザが言うこと聞いて、セキュリティキーとかパスキー登録しといでや"
|
||||
removeKey: "セキュリティキーをほかす"
|
||||
removeKeyConfirm: "{name}を消すん?"
|
||||
whyTOTPOnlyRenew: "セキュリティキーが登録されとったら、認証アプリの設定は解除できへんで。"
|
||||
renewTOTP: "認証アプリをもっかい設定"
|
||||
renewTOTPConfirm: "今までの人称アプリの確認コードは使えんくなるけどええか?"
|
||||
renewTOTPOk: "もっかい設定する"
|
||||
renewTOTPCancel: "やめとく"
|
||||
_permissions:
|
||||
"read:account": "アカウントの情報を見るで"
|
||||
"write:account": "アカウントの情報を変更するで"
|
||||
@ -1461,6 +1555,7 @@ _permissions:
|
||||
"read:gallery-likes": "ギャラリーのいいねを見るで"
|
||||
"write:gallery-likes": "ギャラリーのいいねを操作するで"
|
||||
_auth:
|
||||
shareAccessTitle: "アプリへのアクセス許してやったらどうや"
|
||||
shareAccess: "「{name}」がアカウントにアクセスすることを許可してええか?"
|
||||
shareAccessAsk: "アカウントのアクセスを許可してもええか?"
|
||||
permission: "{name}に次の権限つけたってやって"
|
||||
@ -1474,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "フォローしとるユーザーのノート"
|
||||
users: "選らんだ一人か複数のユーザーのノート"
|
||||
userList: "選んだリストのユーザーのノート"
|
||||
userGroup: "選んだグループのユーザーのノート"
|
||||
_weekday:
|
||||
sunday: "日曜日"
|
||||
monday: "月曜日"
|
||||
@ -1549,16 +1643,16 @@ _visibility:
|
||||
followersDescription: "自分のフォロワーのみに公開するで"
|
||||
specified: "ダイレクト"
|
||||
specifiedDescription: "選んだユーザーのみに公開するで"
|
||||
localOnly: "ローカルのみ"
|
||||
localOnlyDescription: "リモートユーザーには非公開にするで"
|
||||
disableFederation: "連合なし"
|
||||
disableFederationDescription: "他インスタンスへは送らんとくわ"
|
||||
_postForm:
|
||||
replyPlaceholder: "このノートに返信..."
|
||||
quotePlaceholder: "このノートを引用..."
|
||||
channelPlaceholder: "チャンネルに投稿..."
|
||||
_placeholders:
|
||||
a: "いまどうしとるん?"
|
||||
a: "いまどないしとるん?"
|
||||
b: "何かあったん?"
|
||||
c: "何を考えとるん?"
|
||||
c: "何か考えとるん?"
|
||||
d: "何か言いたいことあるん?"
|
||||
e: "ここに書いてーなー"
|
||||
f: "あんたが書くの待っとるで"
|
||||
@ -1645,7 +1739,7 @@ _pages:
|
||||
viewPage: "ページを見る"
|
||||
like: "ええやん"
|
||||
unlike: "良くないわ"
|
||||
my: "人気のページ"
|
||||
my: "自分のページ"
|
||||
liked: "ええと思ったページ"
|
||||
featured: "人気"
|
||||
inspector: "インスペクター"
|
||||
@ -1688,12 +1782,9 @@ _notification:
|
||||
youGotReply: "{name}からのリプライ"
|
||||
youGotQuote: "{name}による引用"
|
||||
youRenoted: "{name}がRenoteしたみたいやで"
|
||||
youGotMessagingMessageFromUser: "{name}からのチャットがあるで"
|
||||
youGotMessagingMessageFromGroup: "{name}のチャットがあるで"
|
||||
youWereFollowed: "フォローされたで"
|
||||
youReceivedFollowRequest: "フォロー許可してほしいみたいやな"
|
||||
yourFollowRequestAccepted: "フォローさせてもろたで"
|
||||
youWereInvitedToGroup: "グループに招待されとるで"
|
||||
pollEnded: "アンケートの結果が出たみたいや"
|
||||
unreadAntennaNote: "アンテナ {name}"
|
||||
emptyPushNotificationMessage: "プッシュ通知の更新をしといたで"
|
||||
@ -1709,7 +1800,7 @@ _notification:
|
||||
pollEnded: "アンケートが終了したで"
|
||||
receiveFollowRequest: "フォロー許可してほしいみたいやで"
|
||||
followRequestAccepted: "フォローが受理されたで"
|
||||
groupInvited: "グループに招待されたで"
|
||||
achievementEarned: "実績の獲得"
|
||||
app: "連携アプリからの通知や"
|
||||
_actions:
|
||||
followBack: "フォローバック"
|
||||
@ -1742,3 +1833,6 @@ _deck:
|
||||
channel: "チャンネル"
|
||||
mentions: "あんた宛て"
|
||||
direct: "ダイレクト"
|
||||
_dialog:
|
||||
charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}"
|
||||
charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}"
|
||||
|
@ -39,10 +39,8 @@ remove: "Kkes"
|
||||
connectService: "Qqen"
|
||||
userList: "Tibdarin"
|
||||
securityKey: "Tasarutt n tɣellist"
|
||||
securityKeyName: "Isem n tsarutt"
|
||||
signinRequired: "Ttxil jerred"
|
||||
signinWith: "Tuqqna s {x}"
|
||||
tapSecurityKey: "Sekcem tasarutt-ik·im n tɣellist"
|
||||
uiLanguage: "Tutlayt n wegrudem"
|
||||
accountSettings: "Iɣewwaṛen n umiḍan"
|
||||
plugins: "Izegrar"
|
||||
|
@ -15,7 +15,7 @@ gotIt: "알겠어요"
|
||||
cancel: "취소"
|
||||
noThankYou: "나중에"
|
||||
enterUsername: "유저명 입력"
|
||||
renotedBy: "{user}님이 리노트"
|
||||
renotedBy: "{user}님의 리노트"
|
||||
noNotes: "노트가 없습니다"
|
||||
noNotifications: "표시할 알림이 없습니다"
|
||||
instance: "인스턴스"
|
||||
@ -103,6 +103,8 @@ renoted: "리노트했습니다"
|
||||
cantRenote: "이 게시물은 리노트 할 수 없습니다."
|
||||
cantReRenote: "리노트를 리노트 할 수 없습니다."
|
||||
quote: "인용"
|
||||
inChannelRenote: "채널 내 리노트"
|
||||
inChannelQuote: "채널 내 인용"
|
||||
pinnedNote: "고정해놓은 노트"
|
||||
pinned: "프로필에 고정"
|
||||
you: "당신"
|
||||
@ -391,13 +393,10 @@ about: "정보"
|
||||
aboutMisskey: "Misskey에 대하여"
|
||||
administrator: "관리자"
|
||||
token: "토큰"
|
||||
twoStepAuthentication: "2단계 인증"
|
||||
moderator: "모더레이터"
|
||||
moderation: "모더레이션"
|
||||
nUsersMentioned: "{n}명이 언급함"
|
||||
securityKey: "보안 키"
|
||||
securityKeyName: "키 이름"
|
||||
registerSecurityKey: "보안 키를 등록"
|
||||
lastUsed: "마지막 사용"
|
||||
unregister: "등록 해제"
|
||||
passwordLessLogin: "비밀번호 없이 로그인"
|
||||
@ -415,24 +414,15 @@ markAsReadAllTalkMessages: "모든 대화를 읽은 상태로 표시"
|
||||
help: "도움말"
|
||||
inputMessageHere: "여기에 메시지를 입력하세요"
|
||||
close: "닫기"
|
||||
group: "그룹"
|
||||
groups: "그룹"
|
||||
createGroup: "그룹 만들기"
|
||||
ownedGroups: "소유 그룹"
|
||||
joinedGroups: "참여중인 그룹"
|
||||
invites: "초대"
|
||||
groupName: "그룹명"
|
||||
members: "멤버"
|
||||
transfer: "양도"
|
||||
messagingWithUser: "유저와 대화하기"
|
||||
messagingWithGroup: "그룹끼리 대화하기"
|
||||
title: "제목"
|
||||
text: "텍스트"
|
||||
enable: "사용"
|
||||
next: "다음"
|
||||
retype: "다시 입력"
|
||||
noteOf: "{user}의 노트"
|
||||
inviteToGroup: "그룹에 초대하기"
|
||||
quoteAttached: "인용함"
|
||||
quoteQuestion: "인용해서 작성하시겠습니까?"
|
||||
noMessagesYet: "아직 대화가 없습니다"
|
||||
@ -454,17 +444,13 @@ passwordMatched: "일치합니다"
|
||||
passwordNotMatched: "일치하지 않습니다"
|
||||
signinWith: "{x}로 로그인"
|
||||
signinFailed: "로그인할 수 없습니다. 사용자명과 비밀번호를 확인하여 주십시오."
|
||||
tapSecurityKey: "보안 키를 터치"
|
||||
or: "혹은"
|
||||
language: "언어"
|
||||
uiLanguage: "UI 표시 언어"
|
||||
groupInvited: "그룹에 초대되었습니다"
|
||||
aboutX: "{x}에 대하여"
|
||||
emojiStyle: "이모지 스타일"
|
||||
native: "네이티브"
|
||||
disableDrawer: "드로어 메뉴를 사용하지 않기"
|
||||
youHaveNoGroups: "그룹이 없습니다"
|
||||
joinOrCreateGroup: "다른 그룹의 초대를 받거나, 직접 새 그룹을 만들어 보세요."
|
||||
noHistory: "기록이 없습니다"
|
||||
signinHistory: "로그인 기록"
|
||||
enableAdvancedMfm: "고급 MFM을 활성화"
|
||||
@ -838,8 +824,6 @@ deleteAccountConfirm: "계정이 삭제되고 되돌릴 수 없게 됩니다.
|
||||
incorrectPassword: "비밀번호가 올바르지 않습니다."
|
||||
voteConfirm: "\"{choice}\"에 투표하시겠습니까?"
|
||||
hide: "숨기기"
|
||||
leaveGroup: "그룹 나가기"
|
||||
leaveGroupConfirm: "\"{name}\"에서 나갈까요?"
|
||||
useDrawerReactionPickerForMobile: "모바일에서 드로어 메뉴로 표시"
|
||||
welcomeBackWithName: "환영합니다, {name}님"
|
||||
clickToFinishEmailVerification: "[{ok}]를 눌러 이메일 인증을 완료하세요."
|
||||
@ -951,6 +935,10 @@ thisPostMayBeAnnoying: "이 게시물은 다른 유저에게 피해를 줄 가
|
||||
thisPostMayBeAnnoyingHome: "홈에 게시"
|
||||
thisPostMayBeAnnoyingCancel: "그만두기"
|
||||
thisPostMayBeAnnoyingIgnore: "이대로 게시"
|
||||
collapseRenotes: "이미 본 리노트를 간략화하기"
|
||||
internalServerError: "내부 서버 오류"
|
||||
internalServerErrorDescription: "내부 서버에서 예기치 않은 오류가 발생했습니다."
|
||||
copyErrorInfo: "오류 정보 복사"
|
||||
_achievements:
|
||||
earnedAt: "달성 일시"
|
||||
_types:
|
||||
@ -1232,7 +1220,7 @@ _role:
|
||||
noteEachClipsMax: "각 클립에 추가할 수 있는 노트 수"
|
||||
userListMax: "생성할 수 있는 유저 리스트 수"
|
||||
userEachUserListsMax: "유저 리스트당 최대 사용자 수"
|
||||
rateLimitFactor: "속도 제한"
|
||||
rateLimitFactor: "요청 빈도 제한"
|
||||
descriptionOfRateLimitFactor: "작을수록 제한이 완화되고, 클수록 제한이 강화됩니다."
|
||||
canHideAds: "광고 숨기기"
|
||||
_condition:
|
||||
@ -1464,6 +1452,7 @@ _ago:
|
||||
weeksAgo: "{n}주 전"
|
||||
monthsAgo: "{n}개월 전"
|
||||
yearsAgo: "{n}년 전"
|
||||
invalid: "아무것도 없습니다"
|
||||
_time:
|
||||
second: "초"
|
||||
minute: "분"
|
||||
@ -1497,14 +1486,14 @@ _tutorial:
|
||||
step8_3: "알림 설정은 나중에도 변경할 수 있습니다."
|
||||
_2fa:
|
||||
alreadyRegistered: "이미 설정이 완료되었습니다."
|
||||
registerDevice: "디바이스 등록"
|
||||
registerKey: "키를 등록"
|
||||
step1: "먼저, {a}나 {b}등의 인증 앱을 사용 중인 디바이스에 설치합니다."
|
||||
step2: "그 후, 표시되어 있는 QR코드를 앱으로 스캔합니다."
|
||||
step2Url: "데스크톱 앱에서는 다음 URL을 입력하세요:"
|
||||
step3: "앱에 표시된 토큰을 입력하시면 완료됩니다."
|
||||
step4: "다음 로그인부터는 토큰을 입력해야 합니다."
|
||||
securityKeyInfo: "FIDO2를 지원하는 하드웨어 보안 키 혹은 디바이스의 지문인식이나 화면잠금 PIN을 이용해서 로그인하도록 설정할 수 있습니다."
|
||||
removeKeyConfirm: "{name} 을(를) 삭제하시겠습니까?"
|
||||
renewTOTPCancel: "나중에"
|
||||
_permissions:
|
||||
"read:account": "계정의 정보를 봅니다"
|
||||
"write:account": "계정의 정보를 변경합니다"
|
||||
@ -1553,7 +1542,6 @@ _antennaSources:
|
||||
homeTimeline: "팔로우중인 유저의 노트"
|
||||
users: "지정한 한 명 혹은 여러 명의 유저의 노트"
|
||||
userList: "지정한 리스트에 속한 유저의 노트"
|
||||
userGroup: "지정한 그룹에 속한 유저의 노트"
|
||||
_weekday:
|
||||
sunday: "일요일"
|
||||
monday: "월요일"
|
||||
@ -1628,8 +1616,6 @@ _visibility:
|
||||
followersDescription: "팔로워에게만 공개"
|
||||
specified: "다이렉트"
|
||||
specifiedDescription: "지정한 유저에게만 공개"
|
||||
localOnly: "로컬에만"
|
||||
localOnlyDescription: "리모트 유저에게 보이지 않기"
|
||||
_postForm:
|
||||
replyPlaceholder: "이 노트에 답글..."
|
||||
quotePlaceholder: "이 노트를 인용..."
|
||||
@ -1767,12 +1753,9 @@ _notification:
|
||||
youGotReply: "{name}님이 답글함"
|
||||
youGotQuote: "{name}님이 인용함"
|
||||
youRenoted: "{name}님이 Renote"
|
||||
youGotMessagingMessageFromUser: "{name} 님이 보낸 채팅이 있어요"
|
||||
youGotMessagingMessageFromGroup: "{name}에서 보낸 채팅이 있어요"
|
||||
youWereFollowed: "새로운 팔로워가 있습니다"
|
||||
youReceivedFollowRequest: "새로운 팔로우 요청이 있습니다"
|
||||
yourFollowRequestAccepted: "팔로우 요청이 수락되었습니다"
|
||||
youWereInvitedToGroup: "그룹에 초대되었습니다"
|
||||
pollEnded: "투표 결과가 발표되었습니다"
|
||||
unreadAntennaNote: "안테나 {name}"
|
||||
emptyPushNotificationMessage: "푸시 알림이 갱신되었습니다"
|
||||
@ -1788,7 +1771,6 @@ _notification:
|
||||
pollEnded: "투표가 종료됨"
|
||||
receiveFollowRequest: "팔로우 요청을 받았을 때"
|
||||
followRequestAccepted: "팔로우 요청이 승인되었을 때"
|
||||
groupInvited: "그룹에 초대되었을 때"
|
||||
app: "연동된 앱을 통한 알림"
|
||||
_actions:
|
||||
followBack: "팔로우"
|
||||
|
@ -136,7 +136,29 @@ loginFailed: "ການເຂົ້າສູ່ລະບົບບໍ່ສຳເ
|
||||
general: "ທົ່ວໄປ"
|
||||
wallpaper: "ພາບພື້ນຫລັງ"
|
||||
setWallpaper: "ຕັ້ງເປັນພາບພື້ນຫຼັງ"
|
||||
searchWith: "ຊອກຫາ: {q}"
|
||||
proxyAccount: "ບັນຊີພຣັອກຊີ"
|
||||
host: "ໂຮດສ"
|
||||
selectUser: "ເລືອກຜູ້ໃຊ້"
|
||||
recipient: "ເຖິງ"
|
||||
annotation: "ຄຳເຫັນ"
|
||||
federation: "ສະຫະພັນ"
|
||||
instances: "ອີນສະແຕນ"
|
||||
registeredAt: "ລົງທະບຽນຢູ່"
|
||||
storageUsage: "ບ່ອນຈັດເກັບຂໍ້ມູນທີ່ໃຊ້"
|
||||
charts: "ອັນດັບເພງ"
|
||||
perHour: "ຕໍ່ຊົ່ວໂມງ"
|
||||
perDay: "ຕໍ່ມື້"
|
||||
stopActivityDelivery: "ຢຸດເຊົາການສົ່ງກິດຈະກໍາ"
|
||||
blockThisInstance: "ຂັດຂວາງຕົວຢ່າງນີ້"
|
||||
operations: "ການດຳເນີນງານ"
|
||||
software: "ຊອບແວ"
|
||||
version: "ສະບັບ"
|
||||
metadata: "Metadata"
|
||||
monitor: "ຈໍພາບ"
|
||||
cpuAndMemory: "CPU ແລະ ຫນ່ວຍຄວາມຈໍາ"
|
||||
network: "ເຄືອຂ່າຍ"
|
||||
disk: "ດິສກ໌"
|
||||
instanceInfo: "ອີນສະແຕນ"
|
||||
statistics: "ສະຖິຕິ"
|
||||
clearQueue: "ລ້າງຄິວ"
|
||||
@ -178,6 +200,7 @@ nsfw: "NSFW"
|
||||
accept: "ອະນຸຍາດ"
|
||||
pinnedNotes: "ບັນທຶກທີ່ປັກໝຸດໄວ້"
|
||||
userList: "ລາຍການ"
|
||||
smtpHost: "ໂຮດສ"
|
||||
smtpUser: "ຊື່ຜູ້ໃຊ້"
|
||||
smtpPass: "ລະຫັດຜ່ານ"
|
||||
clearCache: "ລຶບລ້າງແຄສ"
|
||||
@ -195,11 +218,14 @@ _sfx:
|
||||
note: "ບັນທຶກ"
|
||||
notification: "ການແຈ້ງເຕືອນ"
|
||||
chat: "ແຊ໋ດ"
|
||||
_2fa:
|
||||
renewTOTPCancel: "ບໍ່ແມ່ນຕອນນີ້"
|
||||
_widgets:
|
||||
profile: "ໂພຼຟາຍ"
|
||||
instanceInfo: "ອີນສະແຕນ"
|
||||
notifications: "ການແຈ້ງເຕືອນ"
|
||||
timeline: "ເສັ້ນກຳນົດເວລາ"
|
||||
federation: "ສະຫະພັນ"
|
||||
_userList:
|
||||
chooseList: "ເລືອກບັນຊີລາຍການ"
|
||||
_cw:
|
||||
@ -214,6 +240,8 @@ _exportOrImport:
|
||||
muteList: "ປີດສຽງ"
|
||||
blockingList: "ບ໋ອກ"
|
||||
userLists: "ລາຍການ"
|
||||
_charts:
|
||||
federation: "ສະຫະພັນ"
|
||||
_timelines:
|
||||
home: "ໜ້າຫຼັກ"
|
||||
_pages:
|
||||
|
@ -376,13 +376,10 @@ about: "Over"
|
||||
aboutMisskey: "Over Misskey"
|
||||
administrator: "Beheerder"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Tweestapsverificatie"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderatie"
|
||||
nUsersMentioned: "Vermeld door {n} gebruikers"
|
||||
securityKey: "Beveiligingssleutel"
|
||||
securityKeyName: "Sleutelnaam"
|
||||
registerSecurityKey: "Zekerheids-Sleutel registreren"
|
||||
lastUsed: "Laatst gebruikt"
|
||||
unregister: "Uitschrijven"
|
||||
passwordLessLogin: "Inloggen zonder wachtwoord"
|
||||
@ -399,8 +396,6 @@ markAsReadAllTalkMessages: "Markeer alle berichten als gelezen"
|
||||
help: "Help"
|
||||
inputMessageHere: "Voer hier je bericht in"
|
||||
close: "Sluiten"
|
||||
group: "Groep"
|
||||
groups: "Groepen"
|
||||
invites: "Uitnodigen"
|
||||
invitations: "Uitnodigen"
|
||||
sound: "Geluid"
|
||||
@ -435,6 +430,8 @@ _sfx:
|
||||
note: "Notities"
|
||||
notification: "Meldingen"
|
||||
chat: "Chat"
|
||||
_2fa:
|
||||
renewTOTPCancel: "Nee, bedankt"
|
||||
_widgets:
|
||||
profile: "Profiel"
|
||||
instanceInfo: "Serverinformatie"
|
||||
|
@ -385,13 +385,10 @@ about: "Informacje"
|
||||
aboutMisskey: "O Misskey"
|
||||
administrator: "Admin"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Uwierzytelnianie dwuskładnikowe"
|
||||
moderator: "Moderator"
|
||||
moderation: "Moderacja"
|
||||
nUsersMentioned: "{n} wspomnianych użytkowników"
|
||||
securityKey: "Klucz bezpieczeństwa"
|
||||
securityKeyName: "Nazwa klucza"
|
||||
registerSecurityKey: "Zarejestruj klucz bezpieczeństwa"
|
||||
lastUsed: "Ostatnio używane"
|
||||
unregister: "Cofnij rejestrację"
|
||||
passwordLessLogin: "Skonfiguruj logowanie bez użycia hasła"
|
||||
@ -409,24 +406,15 @@ markAsReadAllTalkMessages: "Oznacz wszystkie wiadomości jako przeczytane"
|
||||
help: "Pomoc"
|
||||
inputMessageHere: "Wprowadź wiadomość tutaj"
|
||||
close: "Zamknij"
|
||||
group: "Grupy"
|
||||
groups: "Grupy"
|
||||
createGroup: "Utwórz grupę"
|
||||
ownedGroups: "Posiadane grupy"
|
||||
joinedGroups: "Członkostwa w grupach"
|
||||
invites: "Zaproś"
|
||||
groupName: "Nazwa grupy"
|
||||
members: "Członkowie"
|
||||
transfer: "Transfer"
|
||||
messagingWithUser: "Rozmowy z innym użytkownikiem"
|
||||
messagingWithGroup: "Rozmowy wewnątrz grupy"
|
||||
title: "Tytuł"
|
||||
text: "Tekst"
|
||||
enable: "Włącz"
|
||||
next: "Dalej"
|
||||
retype: "Wprowadź ponownie"
|
||||
noteOf: "Wpisy {user}"
|
||||
inviteToGroup: "Zaproś do grupy"
|
||||
quoteAttached: "Zacytowano"
|
||||
quoteQuestion: "Czy na pewno chcesz umieścić cytat?"
|
||||
noMessagesYet: "Nie napisano jeszcze wiadomości"
|
||||
@ -448,17 +436,13 @@ passwordMatched: "Pasuje"
|
||||
passwordNotMatched: "Hasła nie pasują do siebie"
|
||||
signinWith: "Zaloguj się z {x}"
|
||||
signinFailed: "Nie udało się zalogować. Wprowadzona nazwa użytkownika lub hasło są nieprawidłowe."
|
||||
tapSecurityKey: "Wybierz swój klucz bezpieczeństwa"
|
||||
or: "Lub"
|
||||
language: "Język"
|
||||
uiLanguage: "Język wyświetlania UI"
|
||||
groupInvited: "Zaproszony(-a) do grupy"
|
||||
aboutX: "O {x}"
|
||||
emojiStyle: "Styl emoji"
|
||||
native: "Natywny"
|
||||
disableDrawer: "Nie używaj menu w stylu szuflady"
|
||||
youHaveNoGroups: "Nie masz żadnych grup"
|
||||
joinOrCreateGroup: "Uzyskaj zaproszenie do dołączenia do grupy lub utwórz własną grupę."
|
||||
noHistory: "Brak historii"
|
||||
signinHistory: "Historia logowania"
|
||||
doing: "Przetwarzanie..."
|
||||
@ -816,8 +800,6 @@ deleteAccountConfirm: "Spowoduje to nieodwracalne usunięcie Twojego konta. Kont
|
||||
incorrectPassword: "Nieprawidłowe hasło."
|
||||
voteConfirm: "Potwierdzić swój głos na \"{choice}\"?"
|
||||
hide: "Ukryj"
|
||||
leaveGroup: "Opuść grupę"
|
||||
leaveGroupConfirm: "Czy na pewno chcesz opuścić \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Wyświetlaj wybornik reakcji jako szufladę na urządzeniach mobilnych"
|
||||
welcomeBackWithName: "Witaj z powrotem, {name}"
|
||||
clickToFinishEmailVerification: "Kliknij [{ok}], aby zakończyć weryfikację e-mail."
|
||||
@ -1079,6 +1061,7 @@ _ago:
|
||||
weeksAgo: "{n} tyg. temu"
|
||||
monthsAgo: "{n} mies. temu"
|
||||
yearsAgo: "{n} lat temu"
|
||||
invalid: "Nie ma tu niczego"
|
||||
_time:
|
||||
second: "sekunda"
|
||||
minute: "minuta"
|
||||
@ -1112,12 +1095,12 @@ _tutorial:
|
||||
step8_3: "Ustawienia powiadomień można zmienić później."
|
||||
_2fa:
|
||||
alreadyRegistered: "Zarejestrowałeś już urządzenie do uwierzytelniania dwuskładnikowego."
|
||||
registerDevice: "Zarejestruj nowe urządzenie"
|
||||
registerKey: "Zarejestruj klucz bezpieczeństwa"
|
||||
step1: "Najpierw, zainstaluj aplikację uwierzytelniającą (taką jak {a} lub {b}) na swoim urządzeniu."
|
||||
step2: "Następnie, zeskanuje kod QR z ekranu."
|
||||
step3: "Wprowadź token podany w aplikacji, aby ukończyć konfigurację."
|
||||
step4: "Od teraz, przy każdej próbie logowania otrzymasz prośbę o token logowania."
|
||||
removeKeyConfirm: "Usunąć kopię zapasową {name}?"
|
||||
renewTOTPCancel: "Nie teraz"
|
||||
_permissions:
|
||||
"read:account": "Wyświetl informacje o swoim koncie"
|
||||
"write:account": "Edytuj swoje informacje o koncie"
|
||||
@ -1328,12 +1311,9 @@ _notification:
|
||||
youGotReply: "{name} odpowiedział(a) Tobie"
|
||||
youGotQuote: "{name} zacytował(a) Ciebie"
|
||||
youRenoted: "{name} udostępnił(a) Twój wpis"
|
||||
youGotMessagingMessageFromUser: "{name} wysłał(a) Ci wiadomość"
|
||||
youGotMessagingMessageFromGroup: "Została wysłana wiadomość do grupy {name}"
|
||||
youWereFollowed: "Zaobserwował(a) Cię"
|
||||
youReceivedFollowRequest: "Otrzymałeś(-aś) prośbę o możliwość obserwacji"
|
||||
yourFollowRequestAccepted: "Twoja prośba o możliwość obserwacji została przyjęta"
|
||||
youWereInvitedToGroup: "Zaproszony(-a) do grupy"
|
||||
pollEnded: "Wyniki ankiety stały się dostępne"
|
||||
unreadAntennaNote: "Antena {name}"
|
||||
emptyPushNotificationMessage: "Powiadomienia push zostały zaktualizowane"
|
||||
@ -1347,7 +1327,6 @@ _notification:
|
||||
reaction: "Reakcja"
|
||||
receiveFollowRequest: "Otrzymano prośbę o możliwość obserwacji"
|
||||
followRequestAccepted: "Przyjęto prośbę o możliwość obserwacji"
|
||||
groupInvited: "Zaproszono do grup"
|
||||
app: "Powiadomienia z aplikacji"
|
||||
_actions:
|
||||
followBack: "zaobserwował cię z powrotem"
|
||||
|
@ -382,12 +382,9 @@ about: "Informações"
|
||||
aboutMisskey: "Sobre Misskey"
|
||||
administrator: "Administrador"
|
||||
token: "Símbolo"
|
||||
twoStepAuthentication: "Verificação em duas etapas"
|
||||
moderator: "Moderador"
|
||||
nUsersMentioned: "Postado por {n} pessoas"
|
||||
securityKey: "Chave de segurança"
|
||||
securityKeyName: "Nome chave"
|
||||
registerSecurityKey: "Registre a chave de segurança"
|
||||
lastUsed: "Último uso"
|
||||
unregister: "Cancelar registro"
|
||||
passwordLessLogin: "Entrar sem senha"
|
||||
@ -405,10 +402,6 @@ markAsReadAllTalkMessages: "Marcar todas as conversas como lidas"
|
||||
help: "Ajuda"
|
||||
inputMessageHere: "Escrever mensagem aqui"
|
||||
close: "Fechar"
|
||||
group: "Grupos"
|
||||
groups: "Grupos"
|
||||
createGroup: "Criar grupo"
|
||||
ownedGroups: "Grupo próprio"
|
||||
invites: "Convidar"
|
||||
invitations: "Convidar"
|
||||
tags: "Etiquetas"
|
||||
@ -522,12 +515,9 @@ _notification:
|
||||
youGotMention: "{name} te mencionou"
|
||||
youGotReply: "{name} te respondeu"
|
||||
youGotQuote: "{name} te citou"
|
||||
youGotMessagingMessageFromUser: "{name} te mandou uma mensagem de bate-papo"
|
||||
youGotMessagingMessageFromGroup: "Uma mensagem foi mandada para o grupo {name}"
|
||||
youWereFollowed: "Você tem um novo seguidor"
|
||||
youReceivedFollowRequest: "Você recebeu um pedido de seguimento"
|
||||
yourFollowRequestAccepted: "Seu pedido de seguimento foi aceito"
|
||||
youWereInvitedToGroup: "{userName} te convidou para um grupo"
|
||||
pollEnded: "Os resultados da enquete agora estão disponíveis"
|
||||
emptyPushNotificationMessage: "As notificações de alerta foram atualizadas"
|
||||
_types:
|
||||
@ -541,7 +531,6 @@ _notification:
|
||||
pollEnded: "Enquetes terminando"
|
||||
receiveFollowRequest: "Recebeu pedidos de seguimento"
|
||||
followRequestAccepted: "Aceitou pedidos de seguimento"
|
||||
groupInvited: "Convites de grupo"
|
||||
app: "Notificações de aplicativos conectados"
|
||||
_actions:
|
||||
followBack: "te seguiu de volta"
|
||||
|
@ -382,12 +382,9 @@ about: "Despre"
|
||||
aboutMisskey: "Despre Misskey"
|
||||
administrator: "Administrator"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Autentificare în doi pași"
|
||||
moderator: "Moderator"
|
||||
nUsersMentioned: "Menționat de {n} utilizatori"
|
||||
securityKey: "Cheie de securitate"
|
||||
securityKeyName: "Numele cheii"
|
||||
registerSecurityKey: "Înregistrează o cheie de securitate"
|
||||
lastUsed: "Ultima utilizată"
|
||||
unregister: "Dezînregistrează"
|
||||
passwordLessLogin: "Autentificare fără parolă"
|
||||
@ -405,24 +402,15 @@ markAsReadAllTalkMessages: "Marchează toate mesajele drept citit"
|
||||
help: "Ajutor"
|
||||
inputMessageHere: "Introdu un mesaj aici"
|
||||
close: "Închide"
|
||||
group: "Grup"
|
||||
groups: "Grupuri"
|
||||
createGroup: "Crează un grup"
|
||||
ownedGroups: "Grupuri deținute"
|
||||
joinedGroups: "Grupuri alăturate"
|
||||
invites: "Invită"
|
||||
groupName: "Numele grupului"
|
||||
members: "Membri"
|
||||
transfer: "Transferă"
|
||||
messagingWithUser: "Chat privat"
|
||||
messagingWithGroup: "Chat de grup"
|
||||
title: "Titlu"
|
||||
text: "Text"
|
||||
enable: "Activează"
|
||||
next: "Următorul"
|
||||
retype: "Introdu din nou"
|
||||
noteOf: "Notă de {user}"
|
||||
inviteToGroup: "Invită în grup"
|
||||
quoteAttached: "Citat"
|
||||
quoteQuestion: "Vrei să adaugi ca citat?"
|
||||
noMessagesYet: "Niciun mesaj încă"
|
||||
@ -444,15 +432,11 @@ passwordMatched: "Se potrivește!"
|
||||
passwordNotMatched: "Nu se potrivește"
|
||||
signinWith: "Autentifică-te cu {x}"
|
||||
signinFailed: "Nu se poate autentifica. Numele de utilizator sau parola introduse sunt incorecte."
|
||||
tapSecurityKey: "Apasă pe cheia ta de securitate."
|
||||
or: "Sau"
|
||||
language: "Limbă"
|
||||
uiLanguage: "Limba interfeței"
|
||||
groupInvited: "Ai fost invitat într-un grup"
|
||||
aboutX: "Despre {x}"
|
||||
disableDrawer: "Nu folosi meniuri în stil sertar"
|
||||
youHaveNoGroups: "Nu ai niciun grup"
|
||||
joinOrCreateGroup: "Primește o invitație într-un grup sau creează unul nou."
|
||||
noHistory: "Nu există istoric"
|
||||
signinHistory: "Istoric autentificări"
|
||||
doing: "Se procesează..."
|
||||
@ -664,6 +648,8 @@ _sfx:
|
||||
note: "Note"
|
||||
notification: "Notificări"
|
||||
chat: "Chat"
|
||||
_ago:
|
||||
invalid: "Nu e nimic de văzut aici"
|
||||
_widgets:
|
||||
profile: "Profil"
|
||||
instanceInfo: "Informații despre instanță"
|
||||
@ -699,7 +685,6 @@ _pages:
|
||||
image: "Imagini"
|
||||
_notification:
|
||||
youWereFollowed: "te-a urmărit"
|
||||
youWereInvitedToGroup: "Ai fost invitat într-un grup"
|
||||
_types:
|
||||
follow: "Urmărești"
|
||||
mention: "Mențiune"
|
||||
|
@ -8,7 +8,7 @@ search: "Поиск"
|
||||
notifications: "Уведомления"
|
||||
username: "Имя пользователя"
|
||||
password: "Пароль"
|
||||
forgotPassword: "Пароль забыт"
|
||||
forgotPassword: "Забыли пароль?"
|
||||
fetchingAsApObject: "Приём с других сайтов"
|
||||
ok: "Окей"
|
||||
gotIt: "Ясно!"
|
||||
@ -103,6 +103,8 @@ renoted: "Репост совершён."
|
||||
cantRenote: "Это нельзя репостить."
|
||||
cantReRenote: "Невозможно репостить репост."
|
||||
quote: "Цитата"
|
||||
inChannelRenote: "В канале"
|
||||
inChannelQuote: "Заметки в канале"
|
||||
pinnedNote: "Закреплённая заметка"
|
||||
pinned: "Закрепить в профиле"
|
||||
you: "Вы"
|
||||
@ -129,6 +131,7 @@ unblockConfirm: "Разблокировать этот аккаунт?"
|
||||
suspendConfirm: "Заморозить этот аккаунт?"
|
||||
unsuspendConfirm: "Разморозить этот аккаунт?"
|
||||
selectList: "Выберите список"
|
||||
selectChannel: "Выберите канал"
|
||||
selectAntenna: "Выберите антенну"
|
||||
selectWidget: "Выберите виджет"
|
||||
editWidgets: "Редактировать виджеты"
|
||||
@ -256,6 +259,8 @@ noMoreHistory: "История закончилась"
|
||||
startMessaging: "Начать общение"
|
||||
nUsersRead: "Прочитали {n}"
|
||||
agreeTo: "Я соглашаюсь с {0}"
|
||||
agreeBelow: "Согласен со следующими"
|
||||
basicNotesBeforeCreateAccount: "Записи, перед созданием аккаунта"
|
||||
tos: "Пользовательское соглашение"
|
||||
start: "Начать"
|
||||
home: "Главная"
|
||||
@ -351,6 +356,8 @@ recaptcha: "reCAPTCHA"
|
||||
enableRecaptcha: "Включить reCAPTCHA"
|
||||
recaptchaSiteKey: "Ключ сайта"
|
||||
recaptchaSecretKey: "Секретный ключ"
|
||||
turnstile: "Сервис Turnstile"
|
||||
enableTurnstile: "Включить Turnstile"
|
||||
turnstileSiteKey: "Ключ сайта"
|
||||
turnstileSecretKey: "Секретный ключ"
|
||||
avoidMultiCaptchaConfirm: "Несколько способов проверки могут мешать друг другу. Подтвердите, если хотите отключить другие способы. Или нажмите «Отмена», чтобы оставить их включёнными."
|
||||
@ -386,13 +393,10 @@ about: "Описание"
|
||||
aboutMisskey: "О Misskey"
|
||||
administrator: "Администратор"
|
||||
token: "Токен"
|
||||
twoStepAuthentication: "Двухфакторная аутентификация"
|
||||
moderator: "Модератор"
|
||||
moderation: "Модерация"
|
||||
nUsersMentioned: "Упомянуло пользователей: {n}"
|
||||
securityKey: "Ключ безопасности"
|
||||
securityKeyName: "Имя ключа"
|
||||
registerSecurityKey: "Зарегистрировать защитный ключ"
|
||||
lastUsed: "Последнее использование"
|
||||
unregister: "Отписаться"
|
||||
passwordLessLogin: "Настроить вход без пароля"
|
||||
@ -410,24 +414,15 @@ markAsReadAllTalkMessages: "Отметить все реплики как про
|
||||
help: "Помощь"
|
||||
inputMessageHere: "Введите сообщение здесь"
|
||||
close: "Закрыть"
|
||||
group: "Группа"
|
||||
groups: "Группы"
|
||||
createGroup: "Создать группу"
|
||||
ownedGroups: "Собственные группы"
|
||||
joinedGroups: "Участие в группах"
|
||||
invites: "Приглашения"
|
||||
groupName: "Название группы"
|
||||
members: "Участники"
|
||||
transfer: "Отдать"
|
||||
messagingWithUser: "Общение с другим пользователем"
|
||||
messagingWithGroup: "Общение в группе"
|
||||
title: "Заголовок"
|
||||
text: "Текст"
|
||||
enable: "Включить"
|
||||
next: "Дальше"
|
||||
retype: "Введите ещё раз"
|
||||
noteOf: "Что пишет {user}"
|
||||
inviteToGroup: "Пригласить в группу"
|
||||
quoteAttached: "Цитата"
|
||||
quoteQuestion: "Хотите добавить цитату?"
|
||||
noMessagesYet: "Пока ни одного сообщения"
|
||||
@ -449,19 +444,17 @@ passwordMatched: "Совпали"
|
||||
passwordNotMatched: "Не совпадают"
|
||||
signinWith: "Использовать {x} для входа"
|
||||
signinFailed: "Невозможно войти в систему. Введенное вами имя пользователя или пароль неверны."
|
||||
tapSecurityKey: "Нажмите на свой электронный ключ"
|
||||
or: "или"
|
||||
language: "Язык"
|
||||
uiLanguage: "Язык интерфейса"
|
||||
groupInvited: "Приглашение в группу"
|
||||
aboutX: "Описание {x}"
|
||||
emojiStyle: "Стиль эмодзи"
|
||||
native: "Системные"
|
||||
disableDrawer: "Не использовать выдвижные меню"
|
||||
youHaveNoGroups: "У вас нет ни одной группы"
|
||||
joinOrCreateGroup: "Получайте приглашения в группы или создавайте свои собственные"
|
||||
noHistory: "История пока пуста"
|
||||
signinHistory: "Журнал посещений"
|
||||
enableAdvancedMfm: "Включить расширенный MFM"
|
||||
enableAnimatedMfm: "Включить анимированную разметку MFM"
|
||||
doing: "В процессе"
|
||||
category: "Категория"
|
||||
tags: "Метки"
|
||||
@ -831,8 +824,6 @@ deleteAccountConfirm: "Учётная запись будет безвозвра
|
||||
incorrectPassword: "Пароль неверен."
|
||||
voteConfirm: "Отдать голос за «{choice}»?"
|
||||
hide: "Спрятать"
|
||||
leaveGroup: "Покинуть группу"
|
||||
leaveGroupConfirm: "Покинуть группу «{name}»?"
|
||||
useDrawerReactionPickerForMobile: "Выдвижная палитра на мобильном устройстве"
|
||||
welcomeBackWithName: "С возвращением, {name}!"
|
||||
clickToFinishEmailVerification: "Пожалуйста, нажмите [{ok}], чтобы завершить подтверждение адреса электронной почты."
|
||||
@ -855,8 +846,11 @@ oneDay: "1 день"
|
||||
oneWeek: "1 неделя"
|
||||
reflectMayTakeTime: "Изменения могут занять время для отображения"
|
||||
failedToFetchAccountInformation: "Не удалось получить информацию об аккаунте"
|
||||
rateLimitExceeded: "Ограничение скорости превышено"
|
||||
cropImage: "Кадрирование"
|
||||
cropImageAsk: "Нужно ли кадрировать изображение?"
|
||||
cropYes: "Обрезать"
|
||||
cropNo: "Не обрезать"
|
||||
file: "Файлы"
|
||||
recentNHours: "Последние {n} ч"
|
||||
recentNDays: "Последние {n} сут"
|
||||
@ -883,6 +877,8 @@ refreshInterval: "Интервал перезагрузки"
|
||||
label: "Метка"
|
||||
type: "Тип"
|
||||
speed: "Скорость"
|
||||
slow: "Медленная"
|
||||
fast: "Быстрая"
|
||||
sensitiveMediaDetection: "Определение содержимого деликатного характера"
|
||||
localOnly: "Локально"
|
||||
remoteOnly: "Только удалённо"
|
||||
@ -933,6 +929,16 @@ cannotPerformTemporaryDescription: "Это действие временно н
|
||||
preset: "Шаблоны"
|
||||
selectFromPresets: "Выбрать из шаблонов"
|
||||
achievements: "Достижения"
|
||||
gotInvalidResponseError: "Сервер ответил ошибкой"
|
||||
gotInvalidResponseErrorDescription: "Сервер временно не доступен. Возможно проводятся технические работы, или сервер отключен."
|
||||
thisPostMayBeAnnoying: "Это сообщение может быть неприятным."
|
||||
thisPostMayBeAnnoyingHome: "Этот пост может быть отправлен на главную"
|
||||
thisPostMayBeAnnoyingCancel: "Этот пост не может быть отменен."
|
||||
thisPostMayBeAnnoyingIgnore: "Этот пост может быть проигнорирован "
|
||||
collapseRenotes: "Свернуть репосты"
|
||||
internalServerError: "Внутренняя ошибка сервера"
|
||||
internalServerErrorDescription: "Внутри сервера произошла непредвиденная ошибка."
|
||||
copyErrorInfo: "Скопировать код ошибки"
|
||||
_achievements:
|
||||
earnedAt: "Разблокировано в"
|
||||
_types:
|
||||
@ -1189,6 +1195,9 @@ _role:
|
||||
baseRole: "Шаблон роли"
|
||||
useBaseValue: "Использовать значение из шаблона"
|
||||
chooseRoleToAssign: "Выберите роль, которую хотите выдать"
|
||||
iconUrl: "Адрес на иконку роли"
|
||||
asBadge: "Показывать как значок"
|
||||
descriptionOfAsBadge: "Описание значка"
|
||||
canEditMembersByModerator: "Могут назначать модераторы"
|
||||
descriptionOfCanEditMembersByModerator: "Если включено, на эту роль могут назначать пользователей как администраторы, так и модераторы. Если выключено, назначать могут только администраторы."
|
||||
priority: "Приоритет"
|
||||
@ -1206,6 +1215,7 @@ _role:
|
||||
pinMax: "Доступное количество закреплённых заметок"
|
||||
antennaMax: "Доступное количество антенн"
|
||||
wordMuteMax: "Доступное количество знаков в списке скрытия слов"
|
||||
webhookMax: "Максимум web-хуков"
|
||||
clipMax: "Максимальное количество подборок"
|
||||
noteEachClipsMax: "Максимальное количество заметок в подборке"
|
||||
userListMax: "Максимальное количество списков аккаунтов"
|
||||
@ -1227,7 +1237,12 @@ _role:
|
||||
not: "Кроме тех, у кого…"
|
||||
_sensitiveMediaDetection:
|
||||
description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно."
|
||||
sensitivity: "Чувствительность обнаружения"
|
||||
sensitivityDescription: "Более низкая чувствительность уменьшает количество ложных срабатываний (false positives). Повышение чувствительности уменьшает утечку при обнаружении (ложноотрицательные результаты)."
|
||||
setSensitiveFlagAutomatically: "Установить флаг NSFW"
|
||||
setSensitiveFlagAutomaticallyDescription: "Даже если этот параметр отключен, результат оценки сохраняется внутри системы."
|
||||
analyzeVideos: "Анализировать видео?"
|
||||
analyzeVideosDescription: "Анализируйте видео в дополнение к неподвижным изображениям. Нагрузка на сервер немного увеличивается."
|
||||
_emailUnavailable:
|
||||
used: "Уже используется"
|
||||
format: "Неверный формат"
|
||||
@ -1437,6 +1452,7 @@ _ago:
|
||||
weeksAgo: "{n} нед. назад"
|
||||
monthsAgo: "{n} мес. назад"
|
||||
yearsAgo: "{n} г. назад"
|
||||
invalid: "Ничего нет"
|
||||
_time:
|
||||
second: "с"
|
||||
minute: "мин"
|
||||
@ -1470,14 +1486,14 @@ _tutorial:
|
||||
step8_3: "Эту настройку вы всегда сможете поменять"
|
||||
_2fa:
|
||||
alreadyRegistered: "Двухфакторная аутентификация уже настроена."
|
||||
registerDevice: "Зарегистрируйте ваше устройство"
|
||||
registerKey: "Зарегистрировать ключ"
|
||||
step1: "Прежде всего, установите на устройство приложение для аутентификации, например, {a} или {b}."
|
||||
step2: "Далее отсканируйте отображаемый QR-код при помощи приложения."
|
||||
step2Url: "Если пользуетесь приложением на компьютере, можете ввести в него эту строку (URL):"
|
||||
step3: "И наконец, введите код, который покажет приложение."
|
||||
step4: "Теперь при каждом входе на сайт вам нужно будет вводить код из приложения аналогичным образом."
|
||||
securityKeyInfo: "Вы можете настроить вход с помощью аппаратного ключа безопасности, поддерживающего FIDO2, или отпечатка пальца или PIN-кода на устройстве."
|
||||
removeKeyConfirm: "Удалить резервную копию «{name}»?"
|
||||
renewTOTPCancel: "Нет, спасибо"
|
||||
_permissions:
|
||||
"read:account": "Просматривать данные учётной записи"
|
||||
"write:account": "Изменять данные учётной записи"
|
||||
@ -1512,18 +1528,20 @@ _permissions:
|
||||
"read:gallery-likes": "Просмотр списка понравившегося в галерее"
|
||||
"write:gallery-likes": "Изменение списка понравившегося в галерее"
|
||||
_auth:
|
||||
shareAccessTitle: "Разрешения для приложений"
|
||||
shareAccess: "Дать доступ для «{name}» к вашей учётной записи?"
|
||||
shareAccessAsk: "Уверены, что хотите дать приложению доступ к своей учётной записи?"
|
||||
permission: "{name} Запрашивает следующие разрешения:"
|
||||
permissionAsk: "Приложение запрашивает следующие разрешения:"
|
||||
pleaseGoBack: "Вернитесь, пожалуйста, в приложение"
|
||||
callback: "Возврат в приложение"
|
||||
denied: "Доступ закрыт"
|
||||
pleaseLogin: "Вы должны войти в систему, чтобы дать разрешение приложению."
|
||||
_antennaSources:
|
||||
all: "Все заметки"
|
||||
homeTimeline: "Заметки тех на которых вы подписаны"
|
||||
users: "Заметки выбранных пользователей"
|
||||
userList: "Заметки пользователей из выбранных списков"
|
||||
userGroup: "Заметки от пользователей из заданной группы"
|
||||
_weekday:
|
||||
sunday: "Воскресенье"
|
||||
monday: "Понедельник"
|
||||
@ -1598,8 +1616,6 @@ _visibility:
|
||||
followersDescription: "Только вашим подписчикам"
|
||||
specified: "Личное"
|
||||
specifiedDescription: "Тем, кого укажете"
|
||||
localOnly: "Локально"
|
||||
localOnlyDescription: "Только для этого сайта"
|
||||
_postForm:
|
||||
replyPlaceholder: "Ответ на заметку..."
|
||||
quotePlaceholder: "Пояснение к цитате..."
|
||||
@ -1664,7 +1680,16 @@ _timelines:
|
||||
social: "Социальная"
|
||||
global: "Всеобщая"
|
||||
_play:
|
||||
new: "Создать приложение "
|
||||
edit: "Редактировать приложение"
|
||||
created: "Приложение создано"
|
||||
updated: "Приложение обновлено"
|
||||
deleted: "Приложение удалено"
|
||||
pageSetting: "Настройки приложения"
|
||||
editThisPage: "Отредактировать страницу"
|
||||
viewSource: "Просмотр исходника"
|
||||
my: "Мои приложения "
|
||||
liked: "Понравилось"
|
||||
featured: "Популярные"
|
||||
title: "Заголовок"
|
||||
script: "Скрипт"
|
||||
@ -1728,13 +1753,11 @@ _notification:
|
||||
youGotReply: "{name} отвечает вам."
|
||||
youGotQuote: "{name} цитирует вас."
|
||||
youRenoted: "{name} передаёт вашу заметку."
|
||||
youGotMessagingMessageFromUser: "{name} пишет вам."
|
||||
youGotMessagingMessageFromGroup: "Новое сообщение в группе «{name}»."
|
||||
youWereFollowed: "У вас новый подписчик."
|
||||
youReceivedFollowRequest: "У вас новый запрос на подписку."
|
||||
yourFollowRequestAccepted: "Ваш запрос на подписку одобрен."
|
||||
youWereInvitedToGroup: "Вы приглашены в группу."
|
||||
pollEnded: "Подведены окончательные итоги опроса"
|
||||
unreadAntennaNote: "Антенна {name}"
|
||||
emptyPushNotificationMessage: "Обновлены push-уведомления"
|
||||
achievementEarned: "Получено достижение"
|
||||
_types:
|
||||
@ -1748,7 +1771,6 @@ _notification:
|
||||
pollEnded: "Окончания опросов"
|
||||
receiveFollowRequest: "Получен запрос на подписку"
|
||||
followRequestAccepted: "Запрос на подписку одобрен"
|
||||
groupInvited: "Приглашение в группы"
|
||||
app: "Уведомления из приложений"
|
||||
_actions:
|
||||
followBack: "отвечает взаимной подпиской"
|
||||
|
@ -388,13 +388,10 @@ about: "Informácie"
|
||||
aboutMisskey: "O Misskey"
|
||||
administrator: "Administrátor"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Dvojfaktorová autentifikácia"
|
||||
moderator: "Moderátor"
|
||||
moderation: "Moderovanie"
|
||||
nUsersMentioned: "{n} používateľov spomenulo"
|
||||
securityKey: "Bezpečnostný kľúč"
|
||||
securityKeyName: "Názov kľúča"
|
||||
registerSecurityKey: "Registrovať bezpečnostný kľúč"
|
||||
lastUsed: "Naposledy použité"
|
||||
unregister: "Odregistrovať"
|
||||
passwordLessLogin: "Nastaviť bezheslové prihlásenie"
|
||||
@ -412,24 +409,15 @@ markAsReadAllTalkMessages: "Označiť všetky správy ako prečítané"
|
||||
help: "Pomoc"
|
||||
inputMessageHere: "Sem napíšte správu"
|
||||
close: "Zavrieť"
|
||||
group: "Skupina"
|
||||
groups: "Skupiny"
|
||||
createGroup: "Vytvoriť skupinu"
|
||||
ownedGroups: "Vlastnené skupiny"
|
||||
joinedGroups: "Členstvo v skupinách"
|
||||
invites: "Pozvať"
|
||||
groupName: "Názov skupiny"
|
||||
members: "Členovia"
|
||||
transfer: "Presun"
|
||||
messagingWithUser: "Súkromný chat"
|
||||
messagingWithGroup: "Skupinový chat"
|
||||
title: "Nadpis"
|
||||
text: "Text"
|
||||
enable: "Povoliť"
|
||||
next: "Ďalší"
|
||||
retype: "Zadajte znovu"
|
||||
noteOf: "Poznámky používateľa {user}"
|
||||
inviteToGroup: "Pozvať do skupiny"
|
||||
quoteAttached: "Citované"
|
||||
quoteQuestion: "Pripojiť ako citát?"
|
||||
noMessagesYet: "Zatiaľ žiadne správy"
|
||||
@ -451,17 +439,13 @@ passwordMatched: "Heslá sú rovnaké"
|
||||
passwordNotMatched: "Heslá nie sú rovnaké"
|
||||
signinWith: "Prihlásiť sa použitím {x}"
|
||||
signinFailed: "Nedá sa prihlásiť. Skontrolujte prosím meno používateľa a heslo."
|
||||
tapSecurityKey: "Ťuknite na bezpečnostný kľúč"
|
||||
or: "Alebo"
|
||||
language: "Jazyk"
|
||||
uiLanguage: "Jazyk používateľského prostredia"
|
||||
groupInvited: "Pozvať do skupiny"
|
||||
aboutX: "O {x}"
|
||||
emojiStyle: "Štýl emoji"
|
||||
native: "Natívne"
|
||||
disableDrawer: "Nepoužívať šuflíkové menu"
|
||||
youHaveNoGroups: "Nemáte žiadne skupiny"
|
||||
joinOrCreateGroup: "Požiadajte o pozvanie do existujúcej skupiny alebo vytvorte novú."
|
||||
noHistory: "Žiadna história"
|
||||
signinHistory: "História prihlásení"
|
||||
doing: "Pracujem..."
|
||||
@ -832,8 +816,6 @@ deleteAccountConfirm: "Toto nezvrátiteľne vymaže váš účet. Pokračovať?"
|
||||
incorrectPassword: "Nesprávne heslo."
|
||||
voteConfirm: "Potvrdzujete svoj hlas za \"{choice}\"?"
|
||||
hide: "Skryť"
|
||||
leaveGroup: "Opustiť skupiny"
|
||||
leaveGroupConfirm: "Naozaj chcete opustiť \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Zobraziť výber reakcií ako šuflík na mobile"
|
||||
welcomeBackWithName: "Vitajte späť, {name}"
|
||||
clickToFinishEmailVerification: "Kliknutím na [{ok}] dokončíte overeniu emailu."
|
||||
@ -1141,6 +1123,7 @@ _ago:
|
||||
weeksAgo: "pred {n} týždňami"
|
||||
monthsAgo: "pred {n} mesiacmi"
|
||||
yearsAgo: "pred {n} rokmi"
|
||||
invalid: "Nič tu nie je"
|
||||
_time:
|
||||
second: "s"
|
||||
minute: "min"
|
||||
@ -1174,14 +1157,14 @@ _tutorial:
|
||||
step8_3: "Nastavenia notifikácií môžete neskôr zmeniť."
|
||||
_2fa:
|
||||
alreadyRegistered: "Už ste zaregistrovali 2-faktorové autentifikačné zariadenie."
|
||||
registerDevice: "Registrovať nové zariadenie"
|
||||
registerKey: "Registrovať bezpečnostný kľúč"
|
||||
step1: "Najprv si nainštalujte autentifikačnú aplikáciu (napríklad {a} alebo {b}) na svoje zariadenie."
|
||||
step2: "Potom, naskenujte QR kód zobrazený na obrazovke."
|
||||
step2Url: "Do aplikácie zadajte nasledujúcu URL adresu:"
|
||||
step3: "Nastavenie dokončíte zadaním tokenu z vašej aplikácie."
|
||||
step4: "Od teraz, všetky ďalšie prihlásenia budú vyžadovať prihlasovací token."
|
||||
securityKeyInfo: "Okrem odtlačku prsta alebo PIN autentifikácie si môžete nastaviť autentifikáciu cez hardvérový bezpečnostný kľúč podporujúci FIDO2 a tak ešte viac zabezpečiť svoj účet."
|
||||
removeKeyConfirm: "Naozaj chcete odstrániť \"{name}\"?"
|
||||
renewTOTPCancel: "Nie, ďakujem"
|
||||
_permissions:
|
||||
"read:account": "Vidieť informácie o vašom účte"
|
||||
"write:account": "Upraviť informácie o vašom účte"
|
||||
@ -1227,7 +1210,6 @@ _antennaSources:
|
||||
homeTimeline: "Poznámky od sledovaného používateľa"
|
||||
users: "Poznámky od konkrétneho používateľa"
|
||||
userList: "Poznámky od používateľov v zozname"
|
||||
userGroup: "Poznámky od používateľov z konkrétnej skupiny."
|
||||
_weekday:
|
||||
sunday: "Nedeľa"
|
||||
monday: "Pondelok"
|
||||
@ -1299,8 +1281,6 @@ _visibility:
|
||||
followersDescription: "Viditeľné iba tým, ktorí vás sledujú"
|
||||
specified: "Priame"
|
||||
specifiedDescription: "Viditeľné iba pre konkrétnych používateľov"
|
||||
localOnly: "Iba lokálne"
|
||||
localOnlyDescription: "Vzdialený používatelia nebudú vidieť"
|
||||
_postForm:
|
||||
replyPlaceholder: "Odpoveď na túto poznámku..."
|
||||
quotePlaceholder: "Citovanie tejto poznámky..."
|
||||
@ -1428,12 +1408,9 @@ _notification:
|
||||
youGotReply: "{name} vám odpovedal/a"
|
||||
youGotQuote: "{name} vás citoval/a"
|
||||
youRenoted: "{name} preposlal/a vašu poznámku"
|
||||
youGotMessagingMessageFromUser: "{name} vám poslal/a správu"
|
||||
youGotMessagingMessageFromGroup: "Prišla správa do skupiny {name}"
|
||||
youWereFollowed: "Máte nového sledujúceho"
|
||||
youReceivedFollowRequest: "Dostali ste žiadosť o sledovanie"
|
||||
yourFollowRequestAccepted: "Vaša žiadosť o sledovanie bola prijatá"
|
||||
youWereInvitedToGroup: "Pozvať do skupiny"
|
||||
pollEnded: "Výsledky hlasovania sú k dispozícii."
|
||||
unreadAntennaNote: "Anténa {name}"
|
||||
emptyPushNotificationMessage: "Push notifikácie aktualizované"
|
||||
@ -1448,7 +1425,6 @@ _notification:
|
||||
pollEnded: "Hlasovanie skončilo"
|
||||
receiveFollowRequest: "Doručené žiadosti o sledovanie"
|
||||
followRequestAccepted: "Schválené žiadosti o sledovanie"
|
||||
groupInvited: "Pozvánky do skupín"
|
||||
app: "Oznámenia z prepojených aplikácií"
|
||||
_actions:
|
||||
followBack: "Sledovať späť\n"
|
||||
|
@ -383,12 +383,13 @@ _sfx:
|
||||
notification: "Notifikationer"
|
||||
chat: "Chatt"
|
||||
antenna: "Antenner"
|
||||
_2fa:
|
||||
renewTOTPCancel: "Nej tack"
|
||||
_antennaSources:
|
||||
all: "Alla noter"
|
||||
homeTimeline: "Noter från följda användare"
|
||||
users: "Noter från specifika användare"
|
||||
userList: "Noter från en specificerad lista av användare"
|
||||
userGroup: "Noter från användare i en specificerad grupp"
|
||||
_widgets:
|
||||
profile: "Profil"
|
||||
instanceInfo: "Instansinformation"
|
||||
|
@ -103,6 +103,8 @@ renoted: "รีโน้ตเอาไว้"
|
||||
cantRenote: "โพสต์นี้ไม่สามารถรีโน้ตไว้ใหม่ได้นะ"
|
||||
cantReRenote: "ไม่สามารถรีโน้ตเอาไว้ใหม่ได้นะ"
|
||||
quote: "อ้างคำพูด"
|
||||
inChannelRenote: "รีโน้ตช่องแชลแนลเท่านั้น"
|
||||
inChannelQuote: "อ้างช่องเท่านั้น"
|
||||
pinnedNote: "โน้ตที่ปักหมุดเอาไว้"
|
||||
pinned: "ปักหมุดไปยังโปรไฟล์"
|
||||
you: "ตัวเอง"
|
||||
@ -257,6 +259,8 @@ noMoreHistory: "ในนั้นไม่มีประวัติอีก
|
||||
startMessaging: "เริ่มการสนทนา"
|
||||
nUsersRead: "อ่านโดย {n}"
|
||||
agreeTo: "ฉันยอมรับที่จะ {0}"
|
||||
agreeBelow: "ฉันยอมรับถึงด้านล่าง"
|
||||
basicNotesBeforeCreateAccount: "หมายเหตุสำคัญ"
|
||||
tos: "ข้อกำหนดและเงื่อนไข"
|
||||
start: "เริ่มต้นใช้งาน"
|
||||
home: "หน้าแรก"
|
||||
@ -389,16 +393,19 @@ about: "เกี่ยวกับ"
|
||||
aboutMisskey: "เกี่ยวกับ Misskey"
|
||||
administrator: "ผู้ดูแลระบบ"
|
||||
token: "โทเค็น"
|
||||
twoStepAuthentication: "ยืนยันตัวตน 2 ชั้น"
|
||||
2fa: "การยืนยันตัวตนแบบสองชั้น"
|
||||
totp: "แอป Authenticator"
|
||||
totpDescription: "ใช้แอปยืนยันตัวตนเพื่อป้อนรหัสผ่านแบบใช้ครั้งเดียว"
|
||||
moderator: "ผู้ควบคุม"
|
||||
moderation: "การกลั่นกรอง"
|
||||
nUsersMentioned: "กล่าวถึงโดยผู้ใช้ {n} รายนี้"
|
||||
securityKeyAndPasskey: "ความปลอดภัยและรหัสผ่าน"
|
||||
securityKey: "กุญแจความปลอดภัย"
|
||||
securityKeyName: "ชื่อคีย์"
|
||||
registerSecurityKey: "ลงทะเบียนรหัสความปลอดภัยคีย์"
|
||||
lastUsed: "ใช้ล่าสุด"
|
||||
lastUsedAt: "ใช้งานครั้งล่าสุด: {t}"
|
||||
unregister: "เลิกติดตาม"
|
||||
passwordLessLogin: "เข้าสู่ระบบแบบไม่ใช้รหัสผ่าน"
|
||||
passwordLessLoginDescription: "อนุญาตให้เข้าสู่ระบบโดยไม่ต้องใช้รหัสผ่านโดยใช้รหัสรักษาความปลอดภัยหรือรหัสผ่านเท่านั้น"
|
||||
resetPassword: "รีเซ็ตรหัสผ่าน"
|
||||
newPasswordIs: "รหัสผ่านใหม่คือ \"{password}\""
|
||||
reduceUiAnimation: "ลดภาพเคลื่อนไหว UI"
|
||||
@ -413,24 +420,15 @@ markAsReadAllTalkMessages: "ทำเครื่องหมายข้อค
|
||||
help: "ช่วยเหลือ"
|
||||
inputMessageHere: "พิมพ์ข้อความที่นี่"
|
||||
close: "ปิด"
|
||||
group: "กลุ่ม"
|
||||
groups: "กลุ่ม"
|
||||
createGroup: "สร้างกลุ่ม"
|
||||
ownedGroups: "กลุ่มที่เป็นเจ้าของ"
|
||||
joinedGroups: "เข้าร่วมกลุ่ม"
|
||||
invites: "เชิญชวน"
|
||||
groupName: "ชื่อกลุ่ม"
|
||||
members: "สมาชิก"
|
||||
transfer: "ถ่ายโอน"
|
||||
messagingWithUser: "แชทส่วนตัว"
|
||||
messagingWithGroup: "แชทกลุ่ม"
|
||||
title: "หัวข้อ"
|
||||
text: "ข้อความ"
|
||||
enable: "เปิดใช้งาน"
|
||||
next: "ถัดไป"
|
||||
retype: "พิมพ์รหัสอีกครั้ง"
|
||||
noteOf: "โน้ต โดย {ผู้ใช้งาน}"
|
||||
inviteToGroup: "ชวนเข้ากลุ่ม"
|
||||
quoteAttached: "อ้างอิง"
|
||||
quoteQuestion: "นายต้องการที่จะอ้างอิงหรอ?"
|
||||
noMessagesYet: "ยังไม่มีข้อความนะ"
|
||||
@ -452,19 +450,17 @@ passwordMatched: "ถูกต้อง!"
|
||||
passwordNotMatched: "ไม่ถูกต้อง"
|
||||
signinWith: "ลงชื่อเข้าใช้ด้วย {x}"
|
||||
signinFailed: "ไม่สามารถลงชื่อผู้เข้าใช้ได้ เนื่องจาก ชื่อผู้ใช้หรือรหัสผ่านที่คุณป้อนนั้นไม่ถูกต้องนะ"
|
||||
tapSecurityKey: "แตะคีย์ความปลอดภัย"
|
||||
or: "หรือ"
|
||||
language: "ภาษา"
|
||||
uiLanguage: "ภาษาอินเทอร์เฟซผู้ใช้งาน"
|
||||
groupInvited: "คุณได้รับเชิญให้เข้าร่วมกลุ่ม"
|
||||
aboutX: "เกี่ยวกับ {x}"
|
||||
emojiStyle: "สไตล์อิโมจิ"
|
||||
native: "ภาษาแม่"
|
||||
disableDrawer: "อย่าใช้ลิ้นชักสไตล์เมนู"
|
||||
youHaveNoGroups: "คุณยังไม่มีกลุ่ม"
|
||||
joinOrCreateGroup: "รับเชิญเข้าร่วมกลุ่มหรือสร้างกลุ่มของคุณเองเลยนะ"
|
||||
noHistory: "ไม่มีรายการ"
|
||||
signinHistory: "ประวัติการเข้าสู่ระบบ"
|
||||
enableAdvancedMfm: "เปิดใช้งาน MFM ขั้นสูง"
|
||||
enableAnimatedMfm: "เปิดการใช้งาน MFM ด้วยแอนิเมชั่น"
|
||||
doing: "กำลังประมวลผล......"
|
||||
category: "หมวดหมู่"
|
||||
tags: "แท็ก"
|
||||
@ -783,6 +779,7 @@ popularPosts: "โพสต์ติดอันดับ"
|
||||
shareWithNote: "แบ่งปันด้วยโน้ต"
|
||||
ads: "โฆษณา"
|
||||
expiration: "กำหนดเวลา"
|
||||
startingperiod: "เริ่ม"
|
||||
memo: "ข้อควรจำ"
|
||||
priority: "ลำดับความสำคัญ"
|
||||
high: "สูง"
|
||||
@ -815,6 +812,7 @@ lastCommunication: "การสื่อสารครั้งสุดท้
|
||||
resolved: "คลี่คลายแล้ว"
|
||||
unresolved: "รอการเฉลย"
|
||||
breakFollow: "ลบผู้ติดตาม"
|
||||
breakFollowConfirm: "ลบผู้ติดตามนี้ออกจริงหรอ?"
|
||||
itsOn: "เปิดใช้งาน"
|
||||
itsOff: "ปิดใช้งาน"
|
||||
emailRequiredForSignup: "จำเป็นต้องการใช้ที่อยู่อีเมลสำหรับการสมัคร"
|
||||
@ -834,8 +832,6 @@ deleteAccountConfirm: "การดำเนินการนี้จะลบ
|
||||
incorrectPassword: "รหัสผ่านไม่ถูกต้อง"
|
||||
voteConfirm: "ยืนยันการโหวต \"{choice}\" มั้ย?"
|
||||
hide: "ซ่อน"
|
||||
leaveGroup: "ออกจากกลุ่ม"
|
||||
leaveGroupConfirm: "คุณแน่ใจหรอว่าต้องการออกจาก \"{name}\""
|
||||
useDrawerReactionPickerForMobile: "แสดงผล ตัวเลือกปฏิกิริยาเป็นลิ้นชักบนมือถือ"
|
||||
welcomeBackWithName: "ยินดีต้อนรับการกลับมานะค่ะ, {name}"
|
||||
clickToFinishEmailVerification: "กรุณาคลิก [{ok}] เพื่อดำเนินการยืนยันอีเมลให้เสร็จสมบูรณ์นะ"
|
||||
@ -861,6 +857,8 @@ failedToFetchAccountInformation: "ไม่สามารถเรียกด
|
||||
rateLimitExceeded: "เกินขีดจำกัดอัตรา"
|
||||
cropImage: "ครอบตัดรูปภาพ"
|
||||
cropImageAsk: "คุณต้องการครอบตัดรูปภาพนี้อย่างงั้นหรือ?"
|
||||
cropYes: "ครอบตัด"
|
||||
cropNo: "ใช้ตามที่เป็นอยู่"
|
||||
file: "ไฟล์"
|
||||
recentNHours: "ล่าสุด {n} ชั่วโมงที่แล้ว"
|
||||
recentNDays: "ล่าสุด {n} วันที่แล้ว"
|
||||
@ -941,6 +939,18 @@ selectFromPresets: "เลือกจากการพรีเซ็ต"
|
||||
achievements: "ความสำเร็จ"
|
||||
gotInvalidResponseError: "การตอบสนองเซิร์ฟเวอร์ไม่ถูกต้อง"
|
||||
gotInvalidResponseErrorDescription: "เซิร์ฟเวอร์อาจไม่สามารถเข้าถึงได้หรืออาจจะกำลังอยู่ในระหว่างปรับปรุง กรุณาลองใหม่อีกครั้งในภายหลังนะคะ"
|
||||
thisPostMayBeAnnoying: "โน้ตนี้อาจจะเป็นการรบกวนผู้อื่นนะคะ"
|
||||
thisPostMayBeAnnoyingHome: "โพสต์ไปยังบ้านไทม์ไลน์"
|
||||
thisPostMayBeAnnoyingCancel: "เลิก"
|
||||
thisPostMayBeAnnoyingIgnore: "โพสต์ยังไงก็แล้วแต่"
|
||||
collapseRenotes: "ยุบ renotes ที่คุณได้เห็นแล้ว"
|
||||
internalServerError: "เซิร์ฟเวอร์ภายในเกิดข้อผิดพลาด"
|
||||
internalServerErrorDescription: "เซิร์ฟเวอร์รันค้นพบข้อผิดพลาดที่ไม่คาดคิด"
|
||||
copyErrorInfo: "คัดลอกรายละเอียดข้อผิดพลาด"
|
||||
joinThisServer: "ลงชื่อสมัครใช้ในอินสแตนซ์นี้"
|
||||
exploreOtherServers: "มองหาอินสแตนซ์อื่น"
|
||||
letsLookAtTimeline: "ลองดูที่ไทม์ไลน์"
|
||||
disableFederationWarn: "การดำเนินการนี้ถ้าหากจะปิดใช้งานการรวมศูนย์ แต่โพสต์ดังกล่าวนั้นจะยังคงเป็นสาธารณะต่อไป ยกเว้นแต่ว่าจะตั้งค่าเป็นอย่างอื่น โดยปกติคุณไม่จำเป็นต้องใช้การตั้งค่านี้นะ"
|
||||
_achievements:
|
||||
earnedAt: "ได้รับเมื่อ"
|
||||
_types:
|
||||
@ -1454,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "{n} สัปดาห์ที่แล้ว"
|
||||
monthsAgo: "{n} เดือนที่แล้ว"
|
||||
yearsAgo: "{n} ปีที่ผ่านมา"
|
||||
invalid: "ไม่พบผลลัพธ์"
|
||||
_time:
|
||||
second: "วินาที"
|
||||
minute: "นาที"
|
||||
@ -1487,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "คุณสามารถเปลี่ยนการตั้งค่านี้ในภายหลังได้ตลอดเวลานะ"
|
||||
_2fa:
|
||||
alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว"
|
||||
registerDevice: "ลงทะเบียนอุปกรณ์ใหม่"
|
||||
registerKey: "ลงทะเบียนรหัสความปลอดภัย"
|
||||
registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์"
|
||||
passwordToTOTP: "กรอกรหัสผ่าน"
|
||||
step1: "ขั้นตอนแรก ติดตั้งแอปยืนยันตัวตน (เช่น {a} หรือ {b}) บนอุปกรณ์ของคุณ"
|
||||
step2: "จากนั้นสแกนรหัส QR ที่แสดงบนหน้าจอนี้"
|
||||
step2Click: "การคลิกที่รหัส QR นี้จะช่วยให้คุณนั้นสามารถลงทะเบียน 2FA กับคีย์ความปลอดภัยหรือแอปตรวจสอบความถูกต้องของโทรศัพท์ได้"
|
||||
step2Url: "คุณยังสามารถป้อนบน URL นี้หากคุณใช้โปรแกรมเดสก์ท็อป:"
|
||||
step3Title: "ป้อนรหัสยืนยัน"
|
||||
step3: "ป้อนโทเค็นที่แอปของคุณให้มาเพื่อเสร็จสิ้นการตั้งค่า"
|
||||
step4: "นับจากนี้เป็นต้นไปการพยายามเข้าสู่ระบบในอนาคตนั้น อาจจะต้องขอโทเค็นในการเข้าสู่ระบบดังกล่าว"
|
||||
securityKeyNotSupported: "เบราว์เซอร์ของคุณไม่รองรับคีย์ความปลอดภัยนะ"
|
||||
registerTOTPBeforeKey: "กรุณาตั้งค่าแอปยืนยันตัวตนเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน"
|
||||
securityKeyInfo: "นอกจากนี้การตรวจสอบความถูกต้องด้วยลายนิ้วมือหรือ PIN แล้ว คุณยังสามารถตั้งค่าการตรวจสอบสิทธิ์ผ่านคีย์ความปลอดภัยของฮาร์ดแวร์ที่รองรับ FIDO2 เพื่อเพิ่มความปลอดภัยให้กับบัญชีของคุณ"
|
||||
chromePasskeyNotSupported: "ขณะนี้ยังไม่รองรับรหัสผ่านของ Chrome"
|
||||
registerSecurityKey: "ลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน"
|
||||
securityKeyName: "ป้อนชื่อคีย์"
|
||||
tapSecurityKey: "กรุณาทำตามเบราว์เซอร์ของคุณเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน"
|
||||
removeKey: "ลบคีย์ความปลอดภัยออก"
|
||||
removeKeyConfirm: "ลบข้อมูลสำรอง {name} มั้ย?"
|
||||
whyTOTPOnlyRenew: "ไม่สามารถลบแอปตัวรับรองความถูกต้องได้ตราบใดที่มีการลงทะเบียนคีย์ความปลอดภัยไว้แล้ว"
|
||||
renewTOTP: "กำหนดค่าแอพตัวตรวจสอบสิทธิ์ใหม่"
|
||||
renewTOTPConfirm: "วิธีการแบบนี้จะทําให้รหัสยืนยันจากแอพก่อนหน้าของคุณหยุดทํางานเลยนะ"
|
||||
renewTOTPOk: "ตั้งค่าคอนฟิกใหม่"
|
||||
renewTOTPCancel: "ไม่เป็นไร"
|
||||
_permissions:
|
||||
"read:account": "ดูข้อมูลบัญชีของคุณ"
|
||||
"write:account": "แก้ไขข้อมูลบัญชีของคุณ"
|
||||
@ -1543,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "โน้ตจากผู้ใช้ที่ติดตาม"
|
||||
users: "โน้ตจากผู้ใช้ที่เฉพาะเจาะจง"
|
||||
userList: "โน้ตจากรายชื่อผู้ใช้ที่ระบุ"
|
||||
userGroup: "โน้ตจากผู้ใช้ในกลุ่มที่ระบุ"
|
||||
_weekday:
|
||||
sunday: "วันอาทิตย์"
|
||||
monday: "วันจันทร์"
|
||||
@ -1618,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "ทำให้ผู้ติดตามนั้นมองเห็นแค่คุณเท่านั้น"
|
||||
specified: "ไดเร็ค"
|
||||
specifiedDescription: "ทำให้มองเห็นได้เฉพาะผู้ใช้ที่ระบุเท่านั้น"
|
||||
localOnly: "เฉพาะท้องถิ่น"
|
||||
localOnlyDescription: "ผู้ใช้ระยะไกลนั้นไม่สามารถมองเห็นได้"
|
||||
disableFederation: "ไม่มีสหภาพ"
|
||||
disableFederationDescription: "อย่าส่งไปยังอินสแตนซ์อื่น"
|
||||
_postForm:
|
||||
replyPlaceholder: "ตอบกลับโน้ตนี้..."
|
||||
quotePlaceholder: "อ้างโน้ตนี้..."
|
||||
@ -1757,12 +1782,9 @@ _notification:
|
||||
youGotReply: "{name} ตอบกลับถึงคุณ"
|
||||
youGotQuote: "{name} อ้างถึงคุณ"
|
||||
youRenoted: "รีโน้ตจาก {name}"
|
||||
youGotMessagingMessageFromUser: "{name} ได้ส่งข้อความแชทถึงคุณ"
|
||||
youGotMessagingMessageFromGroup: "ข้อความแชทถูกส่งไปยัง {name} กลุ่ม"
|
||||
youWereFollowed: "ได้ติดตามคุณ"
|
||||
youReceivedFollowRequest: "คุณมีคำขอติดตามใหม่น่ะ"
|
||||
yourFollowRequestAccepted: "คำขอติดตามของคุณได้รับการยอมรับแล้วน่ะ"
|
||||
youWereInvitedToGroup: "{userName} ได้เชิญคุณเข้ากลุ่ม"
|
||||
pollEnded: "โพลสำรวจความคิดเห็นผลลัพธ์มีพร้อมใช้งาน"
|
||||
unreadAntennaNote: "เสาอากาศ {name}"
|
||||
emptyPushNotificationMessage: "การแจ้งเตือนแบบพุชได้รับการอัพเดทแล้ว"
|
||||
@ -1778,7 +1800,7 @@ _notification:
|
||||
pollEnded: "โพลนี้สิ้นสุดลงแล้ว"
|
||||
receiveFollowRequest: "ได้รับคำขอติดตาม\n"
|
||||
followRequestAccepted: "ยอมรับคำขอติดตาม"
|
||||
groupInvited: "ได้รับคำเชิญเข้ากลุ่ม"
|
||||
achievementEarned: "ปลดล็อกความสำเร็จแล้ว"
|
||||
app: "การแจ้งเตือนจากแอปที่มีลิงก์"
|
||||
_actions:
|
||||
followBack: "ติดตามกลับด้วย"
|
||||
@ -1811,3 +1833,6 @@ _deck:
|
||||
channel: "แชนแนล"
|
||||
mentions: "พูดถึง"
|
||||
direct: "ไดเร็ค"
|
||||
_dialog:
|
||||
charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}"
|
||||
charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}"
|
||||
|
@ -49,6 +49,7 @@ deleteAndEdit: "Видалити й редагувати"
|
||||
deleteAndEditConfirm: "Ви впевнені, що хочете видалити цю нотатку та відредагувати її? Ви втратите всі реакції, поширення та відповіді на неї."
|
||||
addToList: "Додати до списку"
|
||||
sendMessage: "Надіслати повідомлення"
|
||||
copyRSS: "Скопіювати RSS"
|
||||
copyUsername: "Скопіювати ім’я користувача"
|
||||
searchUser: "Пошук користувачів"
|
||||
reply: "Відповісти"
|
||||
@ -128,6 +129,7 @@ unblockConfirm: "Ви впевнені, що хочете розблокуват
|
||||
suspendConfirm: "Ви впевнені, що хочете призупинити цей акаунт?"
|
||||
unsuspendConfirm: "Ви впевнені, що хочете відновити цей акаунт?"
|
||||
selectList: "Виберіть список"
|
||||
selectChannel: "Виберіть канал"
|
||||
selectAntenna: "Виберіть антену"
|
||||
selectWidget: "Виберіть віджет"
|
||||
editWidgets: "Редагувати віджети"
|
||||
@ -255,6 +257,7 @@ noMoreHistory: "Подальшої історії немає"
|
||||
startMessaging: "Розпочати діалог"
|
||||
nUsersRead: "Прочитали {n}"
|
||||
agreeTo: "Я погоджуюсь з {0}"
|
||||
agreeBelow: "Я погоджуюся з наведеним нижче"
|
||||
tos: "Умови використання"
|
||||
start: "Розпочати"
|
||||
home: "Домівка"
|
||||
@ -387,13 +390,12 @@ about: "Інформація"
|
||||
aboutMisskey: "Про Misskey"
|
||||
administrator: "Адмін"
|
||||
token: "Токен"
|
||||
twoStepAuthentication: "Двохфакторна аутентифікація"
|
||||
2fa: "Двофакторна аутентифікація"
|
||||
totp: "Програма аутентифікації"
|
||||
moderator: "Модератор"
|
||||
moderation: "Модерація"
|
||||
nUsersMentioned: "Згадали: {n}"
|
||||
securityKey: "Ключ захисту"
|
||||
securityKeyName: "Назва ключа"
|
||||
registerSecurityKey: "Зареєструвати ключ захисту"
|
||||
lastUsed: "Востаннє використано"
|
||||
unregister: "Скасувати реєстрацію"
|
||||
passwordLessLogin: "Налаштувати вхід без пароля"
|
||||
@ -411,24 +413,15 @@ markAsReadAllTalkMessages: "Позначити всі повідомлення
|
||||
help: "Допомога"
|
||||
inputMessageHere: "Введіть повідомлення тут"
|
||||
close: "Закрити"
|
||||
group: "Група"
|
||||
groups: "Групи"
|
||||
createGroup: "Створити групу"
|
||||
ownedGroups: "Власні групи"
|
||||
joinedGroups: "Членство в групах"
|
||||
invites: "Запросити"
|
||||
groupName: "Назва групи"
|
||||
members: "Учасники"
|
||||
transfer: "Передача"
|
||||
messagingWithUser: "Чат з користувачами"
|
||||
messagingWithGroup: "Чат з групою"
|
||||
title: "Тема"
|
||||
text: "Текст"
|
||||
enable: "Увімкнути"
|
||||
next: "Далі"
|
||||
retype: "Введіть ще раз"
|
||||
noteOf: "Нотатка {user}"
|
||||
inviteToGroup: "Запрошення до групи"
|
||||
quoteAttached: "Цитата"
|
||||
quoteQuestion: "Ви хочете додати цитату?"
|
||||
noMessagesYet: "Ще немає повідомлень"
|
||||
@ -450,17 +443,15 @@ passwordMatched: "Все вірно"
|
||||
passwordNotMatched: "Паролі не співпадають"
|
||||
signinWith: "Увійти за допомогою {x}"
|
||||
signinFailed: "Не вдалося увійти. Введені ім’я користувача або пароль неправильнi."
|
||||
tapSecurityKey: "Торкніться ключа безпеки"
|
||||
or: "або"
|
||||
language: "Мова"
|
||||
uiLanguage: "Мова інтерфейсу"
|
||||
groupInvited: "Запрошення до групи"
|
||||
aboutX: "Про {x}"
|
||||
disableDrawer: "Не використовувати висувні меню"
|
||||
youHaveNoGroups: "Немає груп"
|
||||
joinOrCreateGroup: "Отримуйте запрошення до груп або створюйте свої власні групи."
|
||||
noHistory: "Історія порожня"
|
||||
signinHistory: "Історія входів"
|
||||
enableAdvancedMfm: "Увімкнути розширений MFM"
|
||||
enableAnimatedMfm: "Увімкнути анімований MFM"
|
||||
doing: "Виконується"
|
||||
category: "Категорія"
|
||||
tags: "Теги"
|
||||
@ -713,6 +704,7 @@ accentColor: "Акцент"
|
||||
textColor: "Текст"
|
||||
saveAs: "Зберегти як…"
|
||||
advanced: "Розширені"
|
||||
advancedSettings: "Розширені налаштування"
|
||||
value: "Значення"
|
||||
createdAt: "Створено"
|
||||
updatedAt: "Останнє оновлення"
|
||||
@ -777,6 +769,7 @@ popularPosts: "Популярні дописи"
|
||||
shareWithNote: "Поділитися нотаткою"
|
||||
ads: "Реклама"
|
||||
expiration: "Опитування закінчується"
|
||||
startingperiod: "Початковий період"
|
||||
memo: "Примітка"
|
||||
priority: "Пріоритет"
|
||||
high: "Високий"
|
||||
@ -825,8 +818,6 @@ deleteAccountConfirm: "Це незворотно видалить ваш ака
|
||||
incorrectPassword: "Неправильний пароль."
|
||||
voteConfirm: "Підтверджуєте свій голос за \"{choice}\"?"
|
||||
hide: "Сховати"
|
||||
leaveGroup: "Залишити групу"
|
||||
leaveGroupConfirm: "Залишити \"{name}\"?"
|
||||
welcomeBackWithName: "З поверненням, {name}!"
|
||||
clickToFinishEmailVerification: "Натисніть [{ok}], щоб завершити перевірку email."
|
||||
overridedDeviceKind: "Тип пристрою"
|
||||
@ -897,8 +888,17 @@ like: "Вподобати"
|
||||
unlike: "Не вподобати"
|
||||
numberOfLikes: "Вподобання"
|
||||
show: "Відображення"
|
||||
roles: "Ролі"
|
||||
role: "Роль"
|
||||
normalUser: "Звичайний користувач"
|
||||
undefined: "Не визначено"
|
||||
assign: "Призначити"
|
||||
unassign: "Скасувати призначення"
|
||||
color: "Колір"
|
||||
achievements: "Досягнення"
|
||||
joinThisServer: "Зареєструватися на цьому сервері"
|
||||
exploreOtherServers: "Знайти інший сервер"
|
||||
letsLookAtTimeline: "Перегляд історії"
|
||||
_achievements:
|
||||
earnedAt: "Відкрито"
|
||||
_types:
|
||||
@ -1120,6 +1120,13 @@ _achievements:
|
||||
description: "Відправити посилання на \"Brain Diver\""
|
||||
flavor: "Misskey-Misskey La-Tu-Ma"
|
||||
_role:
|
||||
new: "Нова роль"
|
||||
edit: "Змінити роль"
|
||||
name: "Назва ролі"
|
||||
description: "Опис ролі"
|
||||
permission: "Права ролі"
|
||||
assignTarget: "Призначити"
|
||||
manual: "Вручну"
|
||||
priority: "Пріоритет"
|
||||
_priority:
|
||||
low: "Низький"
|
||||
@ -1317,6 +1324,7 @@ _ago:
|
||||
weeksAgo: "{n} тиж. тому"
|
||||
monthsAgo: "{n} міс. тому"
|
||||
yearsAgo: "{n} р. тому"
|
||||
invalid: "Тут нічого немає"
|
||||
_time:
|
||||
second: "с"
|
||||
minute: "х"
|
||||
@ -1349,13 +1357,12 @@ _tutorial:
|
||||
step8_3: "Ви завжди можете змінити цей параметр пізніше."
|
||||
_2fa:
|
||||
alreadyRegistered: "Двофакторна автентифікація вже налаштована."
|
||||
registerDevice: "Зареєструвати новий пристрій"
|
||||
registerKey: "Зареєструвати новий ключ безпеки"
|
||||
step1: "Спершу встановіть на свій пристрій програму автентифікації (наприклад {a} або {b})."
|
||||
step2: "Потім відскануйте QR-код, який відображається на цьому екрані."
|
||||
step2Url: "Ви також можете ввести цю URL-адресу, якщо використовуєте програму для ПК:"
|
||||
step3: "Щоб завершити налаштування, введіть токен, наданий вашою програмою."
|
||||
step4: "Відтепер будь-які майбутні спроби входу вимагатимуть такого токена."
|
||||
renewTOTPCancel: "Не зараз"
|
||||
_permissions:
|
||||
"read:account": "Переглядати дані профілю"
|
||||
"write:account": "Змінити дані акаунту"
|
||||
@ -1464,8 +1471,6 @@ _visibility:
|
||||
followersDescription: "Тільки для підписників"
|
||||
specified: "Особисто"
|
||||
specifiedDescription: "Лише для певних користувачів"
|
||||
localOnly: "Локально"
|
||||
localOnlyDescription: "Приховано для віддалених користувачів"
|
||||
_postForm:
|
||||
replyPlaceholder: "Відповідь на цю нотатку..."
|
||||
quotePlaceholder: "Прокоментуйте цю нотатку..."
|
||||
@ -1590,12 +1595,9 @@ _notification:
|
||||
youGotReply: "{name} відповідає"
|
||||
youGotQuote: "{name} цитує вас"
|
||||
youRenoted: "{name} поширює"
|
||||
youGotMessagingMessageFromUser: "Повідомлення від {name}"
|
||||
youGotMessagingMessageFromGroup: "Нове повідомлення в групі {name}"
|
||||
youWereFollowed: "Новий підписник"
|
||||
youReceivedFollowRequest: "Ви отримали запит на підписку"
|
||||
yourFollowRequestAccepted: "Запит на підписку прийнято"
|
||||
youWereInvitedToGroup: "Запрошення до групи"
|
||||
achievementEarned: "Досягнення відкрито"
|
||||
_types:
|
||||
all: "Все"
|
||||
@ -1607,7 +1609,6 @@ _notification:
|
||||
reaction: "Реакції"
|
||||
receiveFollowRequest: "Запити на підписку"
|
||||
followRequestAccepted: "Прийняті підписки"
|
||||
groupInvited: "Запрошення до груп"
|
||||
app: "Сповіщення від додатків"
|
||||
_actions:
|
||||
reply: "Відповісти"
|
||||
|
@ -383,13 +383,10 @@ about: "Giới thiệu"
|
||||
aboutMisskey: "Về Misskey"
|
||||
administrator: "Quản trị viên"
|
||||
token: "Token"
|
||||
twoStepAuthentication: "Xác minh 2 bước"
|
||||
moderator: "Kiểm duyệt viên"
|
||||
moderation: "Kiểm duyệt"
|
||||
nUsersMentioned: "Dùng bởi {n} người"
|
||||
securityKey: "Khóa bảo mật"
|
||||
securityKeyName: "Tên khoá"
|
||||
registerSecurityKey: "Đăng ký khóa bảo mật"
|
||||
lastUsed: "Dùng lần cuối"
|
||||
unregister: "Hủy đăng ký"
|
||||
passwordLessLogin: "Đăng nhập không mật khẩu"
|
||||
@ -407,24 +404,15 @@ markAsReadAllTalkMessages: "Đánh dấu tất cả các tin nhắn là đã đ
|
||||
help: "Trợ giúp"
|
||||
inputMessageHere: "Nhập nội dung tin nhắn"
|
||||
close: "Đóng"
|
||||
group: "Nhóm"
|
||||
groups: "Các nhóm"
|
||||
createGroup: "Tạo nhóm"
|
||||
ownedGroups: "Nhóm tôi quản lý"
|
||||
joinedGroups: "Nhóm tôi tham gia"
|
||||
invites: "Mời"
|
||||
groupName: "Tên nhóm"
|
||||
members: "Thành viên"
|
||||
transfer: "Chuyển giao"
|
||||
messagingWithUser: "Nhắn riêng"
|
||||
messagingWithGroup: "Chat nhóm"
|
||||
title: "Tựa đề"
|
||||
text: "Nội dung"
|
||||
enable: "Bật"
|
||||
next: "Kế tiếp"
|
||||
retype: "Nhập lại"
|
||||
noteOf: "Tút của {user}"
|
||||
inviteToGroup: "Mời vào nhóm"
|
||||
quoteAttached: "Trích dẫn"
|
||||
quoteQuestion: "Trích dẫn lại?"
|
||||
noMessagesYet: "Chưa có tin nhắn"
|
||||
@ -446,15 +434,11 @@ passwordMatched: "Trùng khớp"
|
||||
passwordNotMatched: "Không trùng khớp"
|
||||
signinWith: "Đăng nhập bằng {x}"
|
||||
signinFailed: "Không thể đăng nhập. Vui lòng kiểm tra tên người dùng và mật khẩu của bạn."
|
||||
tapSecurityKey: "Nhấn mã bảo mật của bạn"
|
||||
or: "Hoặc"
|
||||
language: "Ngôn ngữ"
|
||||
uiLanguage: "Ngôn ngữ giao diện"
|
||||
groupInvited: "Bạn đã được mời tham gia nhóm"
|
||||
aboutX: "Giới thiệu {x}"
|
||||
disableDrawer: "Không dùng menu thanh bên"
|
||||
youHaveNoGroups: "Không có nhóm nào"
|
||||
joinOrCreateGroup: "Tham gia hoặc tạo một nhóm mới."
|
||||
noHistory: "Không có dữ liệu"
|
||||
signinHistory: "Lịch sử đăng nhập"
|
||||
doing: "Đang xử lý..."
|
||||
@ -825,8 +809,6 @@ deleteAccountConfirm: "Điều này sẽ khiến tài khoản bị xóa vĩnh vi
|
||||
incorrectPassword: "Sai mật khẩu."
|
||||
voteConfirm: "Xác nhận bình chọn \"{choice}\"?"
|
||||
hide: "Ẩn"
|
||||
leaveGroup: "Rời khỏi nhóm"
|
||||
leaveGroupConfirm: "Bạn có chắc muốn rời khỏi nhóm \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Hiện bộ chọn biểu cảm dạng xổ ra trên điện thoại"
|
||||
welcomeBackWithName: "Chào mừng trở lại, {name}"
|
||||
clickToFinishEmailVerification: "Vui lòng nhấn [{ok}] để hoàn tất việc đăng ký."
|
||||
@ -1120,6 +1102,7 @@ _ago:
|
||||
weeksAgo: "{n} tuần trước"
|
||||
monthsAgo: "{n} tháng trước"
|
||||
yearsAgo: "{n} năm trước"
|
||||
invalid: "Không có gì ở đây"
|
||||
_time:
|
||||
second: "s"
|
||||
minute: "phút"
|
||||
@ -1150,14 +1133,13 @@ _tutorial:
|
||||
step7_3: "Bây giờ, chúc may mắn và vui vẻ với Misskey! 🚀"
|
||||
_2fa:
|
||||
alreadyRegistered: "Bạn đã đăng ký thiết bị xác minh 2 bước."
|
||||
registerDevice: "Đăng ký một thiết bị"
|
||||
registerKey: "Đăng ký một mã bảo vệ"
|
||||
step1: "Trước tiên, hãy cài đặt một ứng dụng xác minh (chẳng hạn như {a} hoặc {b}) trên thiết bị của bạn."
|
||||
step2: "Sau đó, quét mã QR hiển thị trên màn hình này."
|
||||
step2Url: "Bạn cũng có thể nhập URL này nếu sử dụng một chương trình máy tính:"
|
||||
step3: "Nhập mã token do ứng dụng của bạn cung cấp để hoàn tất thiết lập."
|
||||
step4: "Kể từ bây giờ, những lần đăng nhập trong tương lai sẽ yêu cầu mã token đăng nhập đó."
|
||||
securityKeyInfo: "Bên cạnh xác minh bằng vân tay hoặc mã PIN, bạn cũng có thể thiết lập xác minh thông qua khóa bảo mật phần cứng hỗ trợ FIDO2 để bảo mật hơn nữa cho tài khoản của mình."
|
||||
removeKeyConfirm: "Xóa bản sao lưu {name}?"
|
||||
_permissions:
|
||||
"read:account": "Xem thông tin tài khoản của bạn"
|
||||
"write:account": "Sửa thông tin tài khoản của bạn"
|
||||
@ -1203,7 +1185,6 @@ _antennaSources:
|
||||
homeTimeline: "Tút từ những người đã theo dõi"
|
||||
users: "Tút từ những người cụ thể"
|
||||
userList: "Tút từ danh sách người dùng cụ thể"
|
||||
userGroup: "Tút từ người dùng trong một nhóm cụ thể"
|
||||
_weekday:
|
||||
sunday: "Chủ Nhật"
|
||||
monday: "Thứ Hai"
|
||||
@ -1275,8 +1256,6 @@ _visibility:
|
||||
followersDescription: "Dành riêng cho người theo dõi"
|
||||
specified: "Nhắn riêng"
|
||||
specifiedDescription: "Chỉ người được nhắc đến mới thấy"
|
||||
localOnly: "Chỉ trên máy chủ"
|
||||
localOnlyDescription: "Không hiển thị với người ở máy chủ khác"
|
||||
_postForm:
|
||||
replyPlaceholder: "Trả lời tút này"
|
||||
quotePlaceholder: "Trích dẫn tút này"
|
||||
@ -1404,12 +1383,9 @@ _notification:
|
||||
youGotReply: "{name} trả lời bạn"
|
||||
youGotQuote: "{name} trích dẫn tút của bạn"
|
||||
youRenoted: "{name} đăng lại tút của bạn"
|
||||
youGotMessagingMessageFromUser: "{name} nhắn tin cho bạn"
|
||||
youGotMessagingMessageFromGroup: "Một tin nhắn trong nhóm {name}"
|
||||
youWereFollowed: "đã theo dõi bạn"
|
||||
youReceivedFollowRequest: "Bạn vừa có một yêu cầu theo dõi"
|
||||
yourFollowRequestAccepted: "Yêu cầu theo dõi của bạn đã được chấp nhận"
|
||||
youWereInvitedToGroup: "Bạn đã được mời tham gia nhóm"
|
||||
pollEnded: "Cuộc bình chọn đã kết thúc"
|
||||
emptyPushNotificationMessage: "Đã cập nhật thông báo đẩy"
|
||||
_types:
|
||||
@ -1423,7 +1399,6 @@ _notification:
|
||||
pollEnded: "Bình chọn kết thúc"
|
||||
receiveFollowRequest: "Yêu cầu theo dõi"
|
||||
followRequestAccepted: "Yêu cầu theo dõi được chấp nhận"
|
||||
groupInvited: "Mời vào nhóm"
|
||||
app: "Từ app liên kết"
|
||||
_actions:
|
||||
followBack: "đã theo dõi lại bạn"
|
||||
|
@ -393,16 +393,19 @@ about: "关于"
|
||||
aboutMisskey: "关于 Misskey"
|
||||
administrator: "管理员"
|
||||
token: "Token (令牌)"
|
||||
twoStepAuthentication: "两步验证"
|
||||
2fa: "双因素认证"
|
||||
totp: "身份验证应用"
|
||||
totpDescription: "使用认证应用输入一次性密码。"
|
||||
moderator: "监察员"
|
||||
moderation: "管理"
|
||||
nUsersMentioned: "{n} 被提到"
|
||||
securityKeyAndPasskey: "安全密钥/密码"
|
||||
securityKey: "安全密钥"
|
||||
securityKeyName: "密钥名称"
|
||||
registerSecurityKey: "注册硬件安全密钥"
|
||||
lastUsed: "最后使用:"
|
||||
lastUsedAt: "最后使用: {t}"
|
||||
unregister: "删除账户"
|
||||
passwordLessLogin: "无密码登录"
|
||||
passwordLessLoginDescription: "不使用密码,仅使用安全密钥或Passkey登录"
|
||||
resetPassword: "重置密码"
|
||||
newPasswordIs: "新的密码是「{password}」"
|
||||
reduceUiAnimation: "减少UI动画"
|
||||
@ -417,24 +420,15 @@ markAsReadAllTalkMessages: "将所有聊天标记为已读"
|
||||
help: "帮助"
|
||||
inputMessageHere: "在此键入信息"
|
||||
close: "关闭"
|
||||
group: "群组"
|
||||
groups: "群组"
|
||||
createGroup: "创建群组"
|
||||
ownedGroups: "拥有的群组"
|
||||
joinedGroups: "已加入的群组"
|
||||
invites: "邀请"
|
||||
groupName: "群组名"
|
||||
members: "成员"
|
||||
transfer: "转让"
|
||||
messagingWithUser: "与用户聊天"
|
||||
messagingWithGroup: "与群组聊天"
|
||||
title: "标题"
|
||||
text: "文本"
|
||||
enable: "启用"
|
||||
next: "下一个"
|
||||
retype: "重新输入"
|
||||
noteOf: "{user}的帖子"
|
||||
inviteToGroup: "群组邀请"
|
||||
quoteAttached: "已引用"
|
||||
quoteQuestion: "是否引用此链接内容?"
|
||||
noMessagesYet: "现在没有新的聊天"
|
||||
@ -456,17 +450,13 @@ passwordMatched: "密码一致"
|
||||
passwordNotMatched: "密码不一致"
|
||||
signinWith: "以{x}登录"
|
||||
signinFailed: "无法登录,请检查您的用户名和密码是否正确。"
|
||||
tapSecurityKey: "轻触硬件安全密钥"
|
||||
or: "或者"
|
||||
language: "语言"
|
||||
uiLanguage: "显示语言"
|
||||
groupInvited: "您有新的群组邀请"
|
||||
aboutX: "关于 {x}"
|
||||
emojiStyle: "emoji 的样式"
|
||||
native: "原生"
|
||||
disableDrawer: "不显示抽屉菜单"
|
||||
youHaveNoGroups: "没有群组"
|
||||
joinOrCreateGroup: "请加入一个现有的群组,或者创建新群组。"
|
||||
noHistory: "没有历史记录"
|
||||
signinHistory: "登录历史"
|
||||
enableAdvancedMfm: "启用扩展MFM"
|
||||
@ -685,7 +675,7 @@ driveFilesCount: "网盘的文件数"
|
||||
driveUsage: "网盘的空间用量"
|
||||
noCrawle: "要求搜索引擎不索引该用户"
|
||||
noCrawleDescription: "要求搜索引擎不要收录(索引)您的用户页面,帖子,页面等。"
|
||||
lockedAccountInfo: "即使通过了关注请求,只要您不将帖子可见范围设置成“关注者”,任何人都可以看到您的帖子。"
|
||||
lockedAccountInfo: "即使启用该功能,只要您不将帖子可见范围设置为“仅关注者”,任何人都还是可以看到您的帖子。"
|
||||
alwaysMarkSensitive: "默认将媒体文件标记为敏感内容"
|
||||
loadRawImages: "添加附件图像的缩略图时使用原始图像质量"
|
||||
disableShowingAnimatedImages: "不播放动画"
|
||||
@ -789,6 +779,7 @@ popularPosts: "热门投稿"
|
||||
shareWithNote: "在帖子中分享"
|
||||
ads: "广告"
|
||||
expiration: "截止时间"
|
||||
startingperiod: "开始时间"
|
||||
memo: "便笺"
|
||||
priority: "优先级"
|
||||
high: "高"
|
||||
@ -821,6 +812,7 @@ lastCommunication: "最近通信"
|
||||
resolved: "已解决"
|
||||
unresolved: "未解决"
|
||||
breakFollow: "移除关注者"
|
||||
breakFollowConfirm: "你想取消关注吗?"
|
||||
itsOn: "已开启"
|
||||
itsOff: "已关闭"
|
||||
emailRequiredForSignup: "注册账户需要电子邮件地址"
|
||||
@ -840,8 +832,6 @@ deleteAccountConfirm: "将要删除账户。是否确认?"
|
||||
incorrectPassword: "密码错误"
|
||||
voteConfirm: "确定投给“{choice}” ?"
|
||||
hide: "隐藏"
|
||||
leaveGroup: "离开群组"
|
||||
leaveGroupConfirm: "确定离开「{name}」?"
|
||||
useDrawerReactionPickerForMobile: "在移动设备上使用抽屉显示"
|
||||
welcomeBackWithName: "欢迎回来,{name}"
|
||||
clickToFinishEmailVerification: "点击 [{ok}] 完成电子邮件地址认证。"
|
||||
@ -867,7 +857,7 @@ failedToFetchAccountInformation: "获取账户信息失败"
|
||||
rateLimitExceeded: "已超過速率限制"
|
||||
cropImage: "剪裁图像"
|
||||
cropImageAsk: "是否要裁剪图像?"
|
||||
cropYes: "已裁剪"
|
||||
cropYes: "去裁剪"
|
||||
cropNo: "就这样吧!"
|
||||
file: "文件"
|
||||
recentNHours: "最近{n}小时"
|
||||
@ -957,6 +947,10 @@ collapseRenotes: "省略显示已经看过的转发内容"
|
||||
internalServerError: "内部服务器错误"
|
||||
internalServerErrorDescription: "内部服务器发生了预期外的错误"
|
||||
copyErrorInfo: "复制错误信息"
|
||||
joinThisServer: "在本实例上注册"
|
||||
exploreOtherServers: "探索其他实例"
|
||||
letsLookAtTimeline: "时间线"
|
||||
disableFederationWarn: "联合被禁用。 禁用它并不能使帖子变成私人的。 在大多数情况下,这个选项不需要被启用。"
|
||||
_achievements:
|
||||
earnedAt: "达成时间"
|
||||
_types:
|
||||
@ -1470,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "{n}周前"
|
||||
monthsAgo: "{n}月前"
|
||||
yearsAgo: "{n}年前"
|
||||
invalid: "没有"
|
||||
_time:
|
||||
second: "秒"
|
||||
minute: "分"
|
||||
@ -1503,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "您也可以稍后再更改通知设置。"
|
||||
_2fa:
|
||||
alreadyRegistered: "此设备已被注册"
|
||||
registerDevice: "注册设备"
|
||||
registerKey: "注册密钥"
|
||||
registerTOTP: "开始设置认证应用"
|
||||
passwordToTOTP: "请输入您的密码"
|
||||
step1: "首先,在您的设备上安装验证应用,例如{a}或{b}。"
|
||||
step2: "然后,扫描屏幕上显示的二维码。"
|
||||
step2Click: "通过点击QR码,您可以使用设备上安装的身份验证器应用程序或密钥环进行注册"
|
||||
step2Url: "在桌面应用程序中输入以下URL:"
|
||||
step3Title: "输入验证码"
|
||||
step3: "输入您的应用提供的动态口令以完成设置。"
|
||||
step4: "从现在开始,任何登录操作都将要求您提供动态口令。"
|
||||
securityKeyNotSupported: "您的浏览器不支持安全密钥。"
|
||||
registerTOTPBeforeKey: "要注册安全密钥或Passkey,请先设置验证器应用程序。"
|
||||
securityKeyInfo: "您可以设置使用支持FIDO2的硬件安全密钥、设备上的指纹或PIN来保护您的登录过程。"
|
||||
chromePasskeyNotSupported: "目前不支持 Chrome 的Passkey。"
|
||||
registerSecurityKey: "注册安全密钥或Passkey"
|
||||
securityKeyName: "输入密钥名称"
|
||||
tapSecurityKey: "请按照浏览器说明操作来注册安全密钥或Passkey。"
|
||||
removeKey: "删除安全密钥"
|
||||
removeKeyConfirm: "您确定要删除 {name} 吗?"
|
||||
whyTOTPOnlyRenew: "如果注册了安全密钥,则无法取消验证器应用程序上的设置。"
|
||||
renewTOTP: "重置验证器应用程序"
|
||||
renewTOTPConfirm: "当前验证器应用程序的验证码将不再有效"
|
||||
renewTOTPOk: "重新配置"
|
||||
renewTOTPCancel: "不用,谢谢"
|
||||
_permissions:
|
||||
"read:account": "查看账户信息"
|
||||
"write:account": "更改帐户信息"
|
||||
@ -1559,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "已关注用户的帖子"
|
||||
users: "来自指定用户的帖子"
|
||||
userList: "来自指定列表中的帖子"
|
||||
userGroup: "来自指定群组中用户的帖子"
|
||||
_weekday:
|
||||
sunday: "星期日"
|
||||
monday: "星期一"
|
||||
@ -1634,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "仅发送至关注者"
|
||||
specified: "指定用户"
|
||||
specifiedDescription: "仅发送至指定用户"
|
||||
localOnly: "仅限本地"
|
||||
localOnlyDescription: "对远程用户不可见"
|
||||
disableFederation: "不参与联合"
|
||||
disableFederationDescription: "不发送到其他实例"
|
||||
_postForm:
|
||||
replyPlaceholder: "回复这个帖子..."
|
||||
quotePlaceholder: "引用这个帖子..."
|
||||
@ -1773,12 +1782,9 @@ _notification:
|
||||
youGotReply: "来自{name}的回复"
|
||||
youGotQuote: "来自{name}的引用"
|
||||
youRenoted: "来自{name}的转发"
|
||||
youGotMessagingMessageFromUser: "来自{name}的聊天"
|
||||
youGotMessagingMessageFromGroup: "来自{name}的群聊"
|
||||
youWereFollowed: "关注了你。"
|
||||
youReceivedFollowRequest: "您有新的关注请求"
|
||||
yourFollowRequestAccepted: "您的关注请求已通过"
|
||||
youWereInvitedToGroup: "您有新的群组邀请"
|
||||
pollEnded: "问卷调查结果已生成。"
|
||||
unreadAntennaNote: "天线 {name}"
|
||||
emptyPushNotificationMessage: "推送通知已更新"
|
||||
@ -1794,7 +1800,7 @@ _notification:
|
||||
pollEnded: "问卷调查结束"
|
||||
receiveFollowRequest: "收到关注请求"
|
||||
followRequestAccepted: "关注请求已通过"
|
||||
groupInvited: "加入群组邀请"
|
||||
achievementEarned: "取得的成就"
|
||||
app: "关联应用的通知"
|
||||
_actions:
|
||||
followBack: "回关"
|
||||
@ -1827,3 +1833,6 @@ _deck:
|
||||
channel: "频道"
|
||||
mentions: "提及"
|
||||
direct: "指定用户"
|
||||
_dialog:
|
||||
charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}"
|
||||
charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}"
|
||||
|
@ -46,7 +46,7 @@ copyContent: "複製內容"
|
||||
copyLink: "複製連結"
|
||||
delete: "刪除"
|
||||
deleteAndEdit: "刪除並編輯"
|
||||
deleteAndEditConfirm: "要刪除並再次編輯嗎?此貼文的所有情感、轉發和回覆也將會消失。"
|
||||
deleteAndEditConfirm: "要刪除並再次編輯嗎?此貼文的所有反應、轉發和回覆也將會消失。"
|
||||
addToList: "加入至清單"
|
||||
sendMessage: "發送訊息"
|
||||
copyRSS: "複製RSS"
|
||||
@ -111,8 +111,8 @@ you: "您"
|
||||
clickToShow: "按一下以顯示"
|
||||
sensitive: "敏感內容"
|
||||
add: "新增"
|
||||
reaction: "情感"
|
||||
reactions: "情感"
|
||||
reaction: "反應"
|
||||
reactions: "反應"
|
||||
reactionSetting: "在選擇器中顯示反應"
|
||||
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
|
||||
rememberNoteVisibility: "記住貼文可見性"
|
||||
@ -213,7 +213,7 @@ default: "預設"
|
||||
defaultValueIs: "預設值:{value}"
|
||||
noCustomEmojis: "沒有自訂的表情符號"
|
||||
noJobs: "沒有任務"
|
||||
federating: "整合搜索中"
|
||||
federating: "聯邦運作中"
|
||||
blocked: "已封鎖"
|
||||
suspended: "已凍結"
|
||||
all: "全部"
|
||||
@ -393,16 +393,19 @@ about: "關於"
|
||||
aboutMisskey: "關於 Misskey"
|
||||
administrator: "管理員"
|
||||
token: "權杖"
|
||||
twoStepAuthentication: "兩階段驗證"
|
||||
2fa: "雙因素驗證"
|
||||
totp: "驗證應用程式"
|
||||
totpDescription: "以驗證應用程式輸入一次性密碼"
|
||||
moderator: "審查員"
|
||||
moderation: "審查"
|
||||
nUsersMentioned: "提到了{n}"
|
||||
securityKeyAndPasskey: "安全金鑰・Passkey"
|
||||
securityKey: "安全金鑰"
|
||||
securityKeyName: "金鑰名稱"
|
||||
registerSecurityKey: "註冊安全金鑰"
|
||||
lastUsed: "上次使用"
|
||||
lastUsedAt: "最後使用:{t}"
|
||||
unregister: "註銷帳號"
|
||||
passwordLessLogin: "設置無密碼登入"
|
||||
passwordLessLoginDescription: "不使用密碼,以安全金鑰或 Passkey 登入"
|
||||
resetPassword: "重置密碼"
|
||||
newPasswordIs: "新密碼為「{password}」"
|
||||
reduceUiAnimation: "減少介面的動態視覺"
|
||||
@ -417,24 +420,15 @@ markAsReadAllTalkMessages: "標記所有訊息為已讀"
|
||||
help: "幫助"
|
||||
inputMessageHere: "在此輸入訊息"
|
||||
close: "關閉"
|
||||
group: "群組"
|
||||
groups: "群組"
|
||||
createGroup: "創建群組"
|
||||
ownedGroups: "擁有的群組"
|
||||
joinedGroups: "群組成員"
|
||||
invites: "邀請"
|
||||
groupName: "群組名稱"
|
||||
members: "成員"
|
||||
transfer: "轉讓"
|
||||
messagingWithUser: "與其他使用者聊天"
|
||||
messagingWithGroup: "發送訊息至群組"
|
||||
title: "標題"
|
||||
text: "文字"
|
||||
enable: "啟用"
|
||||
next: "下一步"
|
||||
retype: "重新輸入"
|
||||
retype: "再次輸入"
|
||||
noteOf: "{user}的貼文"
|
||||
inviteToGroup: "邀請至群組"
|
||||
quoteAttached: "引用"
|
||||
quoteQuestion: "是否要引用?"
|
||||
noMessagesYet: "沒有訊息"
|
||||
@ -456,17 +450,13 @@ passwordMatched: "密碼一致"
|
||||
passwordNotMatched: "密碼不一致"
|
||||
signinWith: "以{x}登錄"
|
||||
signinFailed: "登入失敗。 請檢查使用者名稱和密碼。"
|
||||
tapSecurityKey: "點擊安全密鑰"
|
||||
or: "或者"
|
||||
language: "語言"
|
||||
uiLanguage: "介面語言"
|
||||
groupInvited: "您有新的群組邀請"
|
||||
aboutX: "關於{x}"
|
||||
emojiStyle: "表情符號的風格"
|
||||
native: "原生"
|
||||
disableDrawer: "不顯示下拉式選單"
|
||||
youHaveNoGroups: "找不到群組"
|
||||
joinOrCreateGroup: "請加入現有群組,或創建新群組。"
|
||||
noHistory: "沒有歷史紀錄"
|
||||
signinHistory: "登入歷史"
|
||||
enableAdvancedMfm: "啟用高級MFM"
|
||||
@ -675,8 +665,8 @@ repliedCount: "回覆數量"
|
||||
renotedCount: "轉發次數"
|
||||
followingCount: "正在跟隨的用戶數量"
|
||||
followersCount: "跟隨者數量"
|
||||
sentReactionsCount: "情感發送次數"
|
||||
receivedReactionsCount: "情感收到次數"
|
||||
sentReactionsCount: "反應發送次數"
|
||||
receivedReactionsCount: "收到反應次數"
|
||||
pollVotesCount: "已統計的投票數"
|
||||
pollVotedCount: "已投票數"
|
||||
yes: "確定"
|
||||
@ -789,6 +779,7 @@ popularPosts: "熱門的貼文"
|
||||
shareWithNote: "在貼文中分享"
|
||||
ads: "廣告"
|
||||
expiration: "期限"
|
||||
startingperiod: "開始期間"
|
||||
memo: "備忘錄"
|
||||
priority: "優先級"
|
||||
high: "高"
|
||||
@ -821,6 +812,7 @@ lastCommunication: "最近的通信"
|
||||
resolved: "已解決"
|
||||
unresolved: "未解決"
|
||||
breakFollow: "移除追蹤者"
|
||||
breakFollowConfirm: "確定要取消被追隨嗎?"
|
||||
itsOn: "已開啟"
|
||||
itsOff: "已關閉"
|
||||
emailRequiredForSignup: "註冊帳戶需要電子郵件地址"
|
||||
@ -840,8 +832,6 @@ deleteAccountConfirm: "將要刪除帳戶。是否確定?"
|
||||
incorrectPassword: "密碼錯誤。"
|
||||
voteConfirm: "確定投給「{choice}」?"
|
||||
hide: "隱藏"
|
||||
leaveGroup: "離開群組"
|
||||
leaveGroupConfirm: "確定離開「{name}」?"
|
||||
useDrawerReactionPickerForMobile: "在移動設備上使用抽屜顯示"
|
||||
welcomeBackWithName: "歡迎回來,{name}"
|
||||
clickToFinishEmailVerification: "點擊 [{ok}] 完成電子郵件地址認證。"
|
||||
@ -957,6 +947,10 @@ collapseRenotes: "省略顯示已看過的轉發貼文"
|
||||
internalServerError: "內部伺服器錯誤"
|
||||
internalServerErrorDescription: "內部伺服器發生了非預期的錯誤。"
|
||||
copyErrorInfo: "複製錯誤資訊"
|
||||
joinThisServer: "在此伺服器上註冊"
|
||||
exploreOtherServers: "探索其他伺服器"
|
||||
letsLookAtTimeline: "看看時間軸"
|
||||
disableFederationWarn: "聯邦被停用了。即使停用也不會讓您的貼文不公開,在大多數情況下,不需要啟用這個選項。"
|
||||
_achievements:
|
||||
earnedAt: "獲得日期"
|
||||
_types:
|
||||
@ -1101,7 +1095,7 @@ _achievements:
|
||||
title: "成群結隊"
|
||||
description: "跟隨者超過50人了"
|
||||
_followers100:
|
||||
title: "紅人"
|
||||
title: "熱門人物"
|
||||
description: "跟隨者超過100人了"
|
||||
_followers300:
|
||||
title: "請排成一排"
|
||||
@ -1159,7 +1153,7 @@ _achievements:
|
||||
description: "試圖遞迴套入雲端硬碟資料夾"
|
||||
_reactWithoutRead:
|
||||
title: "有好好讀過嗎?"
|
||||
description: "對包含100字以上內容的貼文做出情感反應"
|
||||
description: "對包含100字以上內容的貼文在3秒以內做出反應"
|
||||
_clickedClickHere:
|
||||
title: "點擊這裡"
|
||||
description: "已點擊這裡了"
|
||||
@ -1470,6 +1464,7 @@ _ago:
|
||||
weeksAgo: "{n}周前"
|
||||
monthsAgo: "{n}個月前"
|
||||
yearsAgo: "{n}年前"
|
||||
invalid: "未發現"
|
||||
_time:
|
||||
second: "秒"
|
||||
minute: "分鐘"
|
||||
@ -1493,7 +1488,7 @@ _tutorial:
|
||||
step5_3: "想要追隨其他人,只要點擊他們的大頭貼並按「追隨」即可。"
|
||||
step5_4: "如果使用者的名字旁有鎖頭的圖示,代表他們需要手動核准你的追隨請求。"
|
||||
step6_1: "現在你可以在時間軸上看到其他用戶的貼文。"
|
||||
step6_2: "你也可以對別人的貼文作出「情感」,作出簡單的回覆。"
|
||||
step6_2: "你也可以對別人的貼文作出「反應」,作出簡單的回覆。"
|
||||
step6_3: "在他人的貼文按下\"+\"圖標,即可選擇喜好的表情符號進行回應。"
|
||||
step7_1: "以上為Misskey的基本操作說明,教學在此告一段落。辛苦了。"
|
||||
step7_2: "歡迎到{help}來瞭解更多Misskey相關介紹。"
|
||||
@ -1503,14 +1498,29 @@ _tutorial:
|
||||
step8_3: "通知的設定可以在之後變更。"
|
||||
_2fa:
|
||||
alreadyRegistered: "此設備已經被註冊過了"
|
||||
registerDevice: "註冊裝置"
|
||||
registerKey: "註冊鍵"
|
||||
registerTOTP: "開始設定驗證應用程式"
|
||||
passwordToTOTP: "請輸入密碼"
|
||||
step1: "首先,在您的設備上安裝二步驗證程式,例如{a}或{b}。"
|
||||
step2: "然後,掃描螢幕上的QR code。"
|
||||
step2Click: "點擊QR code,可以使用設備上安裝的驗證應用程式或金鑰環進行註冊。"
|
||||
step2Url: "在桌面版應用中,請輸入以下的URL:"
|
||||
step3Title: "輸入驗證碼"
|
||||
step3: "輸入您的App提供的權杖以完成設定。"
|
||||
step4: "從現在開始,任何登入操作都將要求您提供權杖。"
|
||||
securityKeyNotSupported: "您的瀏覽器不支援安全金鑰。"
|
||||
registerTOTPBeforeKey: "要註冊安全金鑰・Passkey,請先設定驗證應用程式。"
|
||||
securityKeyInfo: "您可以設定使用支援FIDO2的硬體安全鎖、終端設備的指纹認證或者PIN碼來登入。"
|
||||
chromePasskeyNotSupported: "目前不支援Chrome的Passkey。"
|
||||
registerSecurityKey: "註冊安全金鑰・Passkey"
|
||||
securityKeyName: "輸入金鑰名稱"
|
||||
tapSecurityKey: "按照瀏覽器的說明操作,註冊安全金鑰和Passkey。"
|
||||
removeKey: "刪除安全金鑰"
|
||||
removeKeyConfirm: "要刪除{name}嗎?"
|
||||
whyTOTPOnlyRenew: "如果註冊了安全金鑰,則無法解除驗證應用程式的設定。"
|
||||
renewTOTP: "重設驗證應用程式"
|
||||
renewTOTPConfirm: "目前驗證應用程式的驗證碼將無法使用。"
|
||||
renewTOTPOk: "重設"
|
||||
renewTOTPCancel: "現在不要"
|
||||
_permissions:
|
||||
"read:account": "查看我的帳戶資訊"
|
||||
"write:account": "更改我的帳戶資訊"
|
||||
@ -1529,8 +1539,8 @@ _permissions:
|
||||
"write:notes": "撰寫或刪除貼文"
|
||||
"read:notifications": "查看通知"
|
||||
"write:notifications": "編輯通知"
|
||||
"read:reactions": "查看情感"
|
||||
"write:reactions": "編輯情感"
|
||||
"read:reactions": "查看反應"
|
||||
"write:reactions": "編輯反應"
|
||||
"write:votes": "投票"
|
||||
"read:pages": "顯示頁面"
|
||||
"write:pages": "編輯頁面"
|
||||
@ -1559,7 +1569,6 @@ _antennaSources:
|
||||
homeTimeline: "來自已追隨使用者的貼文"
|
||||
users: "來自特定使用者的貼文"
|
||||
userList: "來自特定清單中的貼文"
|
||||
userGroup: "來自特定群組的貼文"
|
||||
_weekday:
|
||||
sunday: "週日"
|
||||
monday: "週一"
|
||||
@ -1583,7 +1592,7 @@ _widgets:
|
||||
photos: "照片"
|
||||
digitalClock: "電子時鐘"
|
||||
unixClock: "UNIX時間"
|
||||
federation: "聯邦宇宙"
|
||||
federation: "站台聯邦"
|
||||
instanceCloud: "實例雲"
|
||||
postForm: "發佈窗口"
|
||||
slideshow: "幻燈片"
|
||||
@ -1634,8 +1643,8 @@ _visibility:
|
||||
followersDescription: "僅發送至關注者"
|
||||
specified: "指定使用者"
|
||||
specifiedDescription: "僅發送至指定使用者"
|
||||
localOnly: "僅限本地"
|
||||
localOnlyDescription: "對遠端使用者隱藏"
|
||||
disableFederation: "停用聯邦"
|
||||
disableFederationDescription: "不要傳遞給其他實例"
|
||||
_postForm:
|
||||
replyPlaceholder: "回覆此貼文..."
|
||||
quotePlaceholder: "引用此貼文..."
|
||||
@ -1773,12 +1782,9 @@ _notification:
|
||||
youGotReply: "{name}回覆了您"
|
||||
youGotQuote: "{name}引用了您"
|
||||
youRenoted: "{name} 轉發了你的貼文"
|
||||
youGotMessagingMessageFromUser: "{name}發送給您的訊息"
|
||||
youGotMessagingMessageFromGroup: "{name}發送給您的訊息"
|
||||
youWereFollowed: "您有新的追隨者"
|
||||
youReceivedFollowRequest: "您有新的追隨請求"
|
||||
yourFollowRequestAccepted: "您的追隨請求已通過"
|
||||
youWereInvitedToGroup: "您有新的群組邀請"
|
||||
pollEnded: "問卷調查已產生結果"
|
||||
unreadAntennaNote: "天線 {name}"
|
||||
emptyPushNotificationMessage: "推送通知已更新"
|
||||
@ -1794,7 +1800,7 @@ _notification:
|
||||
pollEnded: "問卷調查結束"
|
||||
receiveFollowRequest: "已收到追隨請求"
|
||||
followRequestAccepted: "追隨請求已接受"
|
||||
groupInvited: "加入社群邀請"
|
||||
achievementEarned: "獲得成就"
|
||||
app: "應用程式通知"
|
||||
_actions:
|
||||
followBack: "回關"
|
||||
@ -1827,3 +1833,6 @@ _deck:
|
||||
channel: "頻道"
|
||||
mentions: "提及"
|
||||
direct: "指定使用者"
|
||||
_dialog:
|
||||
charactersExceeded: "已超過最大字數!現在 {current} / 限制 {max}"
|
||||
charactersBelow: "低於最少字數!現在 {current} / 限制 {max}"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "13.7.3-simkey",
|
||||
"version": "13.7.5-simkey",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -16,10 +16,11 @@
|
||||
"scripts": {
|
||||
"build-pre": "node ./scripts/build-pre.js",
|
||||
"build": "pnpm build-pre && pnpm -r build && pnpm gulp",
|
||||
"start": "cd packages/backend && node ./built/boot/index.js",
|
||||
"start": "pnpm check:connect && cd packages/backend && node ./built/boot/index.js",
|
||||
"start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/index.js",
|
||||
"init": "pnpm migrate",
|
||||
"migrate": "cd packages/backend && pnpm migrate",
|
||||
"check:connect": "cd packages/backend && pnpm check:connect",
|
||||
"migrateandstart": "pnpm migrate && pnpm start",
|
||||
"gulp": "pnpm exec gulp build",
|
||||
"watch": "pnpm dev",
|
||||
|
@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: ['./tsconfig.json'],
|
||||
project: ['./tsconfig.json', './test/tsconfig.json'],
|
||||
},
|
||||
extends: [
|
||||
'../shared/.eslintrc.js',
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 48 KiB |
10
packages/backend/check_connect.js
Normal file
10
packages/backend/check_connect.js
Normal file
@ -0,0 +1,10 @@
|
||||
import {loadConfig} from './built/config.js';
|
||||
import {createRedisConnection} from "./built/redis.js";
|
||||
|
||||
const config = loadConfig();
|
||||
const redis = createRedisConnection(config);
|
||||
|
||||
redis.on('connect', () => redis.disconnect());
|
||||
redis.on('error', (e) => {
|
||||
throw e;
|
||||
});
|
@ -20,7 +20,7 @@ module.exports = {
|
||||
// collectCoverage: false,
|
||||
|
||||
// An array of glob patterns indicating a set of files for which coverage information should be collected
|
||||
collectCoverageFrom: ['src/**/*.ts'],
|
||||
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.test.ts'],
|
||||
|
||||
// The directory where Jest should output its coverage files
|
||||
coverageDirectory: "coverage",
|
||||
@ -159,6 +159,7 @@ module.exports = {
|
||||
// The glob patterns Jest uses to detect test files
|
||||
testMatch: [
|
||||
"<rootDir>/test/unit/**/*.ts",
|
||||
"<rootDir>/src/**/*.test.ts",
|
||||
//"<rootDir>/test/e2e/**/*.ts"
|
||||
],
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
"start": "node ./built/index.js",
|
||||
"start:test": "NODE_ENV=test node ./built/index.js",
|
||||
"migrate": "pnpm typeorm migration:run -d ormconfig.js",
|
||||
"check:connect": "node ./check_connect.js",
|
||||
"build": "swc src -d built -D",
|
||||
"watch:swc": "swc src -d built -D -w",
|
||||
"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
||||
@ -14,8 +15,8 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"eslint": "eslint --quiet \"src/**/*.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 --runInBand",
|
||||
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --runInBand",
|
||||
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --runInBand --detectOpenHandles",
|
||||
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --runInBand --detectOpenHandles",
|
||||
"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache",
|
||||
"test": "pnpm jest",
|
||||
"test-and-coverage": "pnpm jest-and-coverage"
|
||||
@ -53,7 +54,7 @@
|
||||
"@peertube/http-signature": "1.7.0",
|
||||
"@sinonjs/fake-timers": "10.0.2",
|
||||
"@swc/cli": "0.1.62",
|
||||
"@swc/core": "1.3.35",
|
||||
"@swc/core": "1.3.36",
|
||||
"accepts": "1.3.8",
|
||||
"ajv": "8.12.0",
|
||||
"archiver": "5.3.1",
|
||||
|
@ -450,8 +450,10 @@ export class ApInboxService {
|
||||
return `skip: delete actor ${actor.uri} !== ${uri}`;
|
||||
}
|
||||
|
||||
const user = await this.usersRepository.findOneByOrFail({ id: actor.id });
|
||||
if (user.isDeleted) {
|
||||
const user = await this.usersRepository.findOneBy({ id: actor.id });
|
||||
if (user == null) {
|
||||
return 'skip: actor not found';
|
||||
} else if (user.isDeleted) {
|
||||
return 'skip: already deleted';
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,101 @@ type PrivateKey = {
|
||||
keyId: string;
|
||||
};
|
||||
|
||||
export class ApRequestCreator {
|
||||
static createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed {
|
||||
const u = new URL(args.url);
|
||||
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'POST',
|
||||
headers: this.#objectAssignWithLcKey({
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': u.host,
|
||||
'Content-Type': 'application/activity+json',
|
||||
'Digest': digestHeader,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = this.#signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
|
||||
const u = new URL(args.url);
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'GET',
|
||||
headers: this.#objectAssignWithLcKey({
|
||||
'Accept': 'application/activity+json, application/ld+json',
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': new URL(args.url).host,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = this.#signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
static #signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]): Signed {
|
||||
const signingString = this.#genSigningString(request, includeHeaders);
|
||||
const signature = crypto.sign('sha256', Buffer.from(signingString), key.privateKeyPem).toString('base64');
|
||||
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
|
||||
|
||||
request.headers = this.#objectAssignWithLcKey(request.headers, {
|
||||
Signature: signatureHeader,
|
||||
});
|
||||
// node-fetch will generate this for us. if we keep 'Host', it won't change with redirects!
|
||||
delete request.headers['host'];
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString,
|
||||
signature,
|
||||
signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
static #genSigningString(request: Request, includeHeaders: string[]): string {
|
||||
request.headers = this.#lcObjectKey(request.headers);
|
||||
|
||||
const results: string[] = [];
|
||||
|
||||
for (const key of includeHeaders.map(x => x.toLowerCase())) {
|
||||
if (key === '(request-target)') {
|
||||
results.push(`(request-target): ${request.method.toLowerCase()} ${new URL(request.url).pathname}`);
|
||||
} else {
|
||||
results.push(`${key}: ${request.headers[key]}`);
|
||||
}
|
||||
}
|
||||
|
||||
return results.join('\n');
|
||||
}
|
||||
|
||||
static #lcObjectKey(src: Record<string, string>): Record<string, string> {
|
||||
const dst: Record<string, string> = {};
|
||||
for (const key of Object.keys(src).filter(x => x !== '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
|
||||
return dst;
|
||||
}
|
||||
|
||||
static #objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>): Record<string, string> {
|
||||
return Object.assign(this.#lcObjectKey(a), this.#lcObjectKey(b));
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ApRequestService {
|
||||
private logger: Logger;
|
||||
@ -44,112 +139,13 @@ export class ApRequestService {
|
||||
this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed {
|
||||
const u = new URL(args.url);
|
||||
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'POST',
|
||||
headers: this.objectAssignWithLcKey({
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': u.host,
|
||||
'Content-Type': 'application/activity+json',
|
||||
'Digest': digestHeader,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = this.signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
|
||||
const u = new URL(args.url);
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'GET',
|
||||
headers: this.objectAssignWithLcKey({
|
||||
'Accept': 'application/activity+json, application/ld+json',
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': new URL(args.url).host,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = this.signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]): Signed {
|
||||
const signingString = this.genSigningString(request, includeHeaders);
|
||||
const signature = crypto.sign('sha256', Buffer.from(signingString), key.privateKeyPem).toString('base64');
|
||||
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
|
||||
|
||||
request.headers = this.objectAssignWithLcKey(request.headers, {
|
||||
Signature: signatureHeader,
|
||||
});
|
||||
// node-fetch will generate this for us. if we keep 'Host', it won't change with redirects!
|
||||
delete request.headers['host'];
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString,
|
||||
signature,
|
||||
signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private genSigningString(request: Request, includeHeaders: string[]): string {
|
||||
request.headers = this.lcObjectKey(request.headers);
|
||||
|
||||
const results: string[] = [];
|
||||
|
||||
for (const key of includeHeaders.map(x => x.toLowerCase())) {
|
||||
if (key === '(request-target)') {
|
||||
results.push(`(request-target): ${request.method.toLowerCase()} ${new URL(request.url).pathname}`);
|
||||
} else {
|
||||
results.push(`${key}: ${request.headers[key]}`);
|
||||
}
|
||||
}
|
||||
|
||||
return results.join('\n');
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private lcObjectKey(src: Record<string, string>): Record<string, string> {
|
||||
const dst: Record<string, string> = {};
|
||||
for (const key of Object.keys(src).filter(x => x !== '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
|
||||
return dst;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>): Record<string, string> {
|
||||
return Object.assign(this.lcObjectKey(a), this.lcObjectKey(b));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async signedPost(user: { id: User['id'] }, url: string, object: any) {
|
||||
const body = JSON.stringify(object);
|
||||
|
||||
const keypair = await this.userKeypairStoreService.getUserKeypair(user.id);
|
||||
|
||||
const req = this.createSignedPost({
|
||||
const req = ApRequestCreator.createSignedPost({
|
||||
key: {
|
||||
privateKeyPem: keypair.privateKey,
|
||||
keyId: `${this.config.url}/users/${user.id}#main-key`,
|
||||
@ -176,7 +172,7 @@ export class ApRequestService {
|
||||
public async signedGet(url: string, user: { id: User['id'] }) {
|
||||
const keypair = await this.userKeypairStoreService.getUserKeypair(user.id);
|
||||
|
||||
const req = this.createSignedGet({
|
||||
const req = ApRequestCreator.createSignedGet({
|
||||
key: {
|
||||
privateKeyPem: keypair.privateKey,
|
||||
keyId: `${this.config.url}/users/${user.id}#main-key`,
|
||||
|
@ -116,10 +116,10 @@ export type Obj = Record<string, Schema>;
|
||||
// https://github.com/misskey-dev/misskey/issues/8535
|
||||
// To avoid excessive stack depth error,
|
||||
// deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it).
|
||||
export type ObjType<s extends Obj, RequiredProps extends keyof s> =
|
||||
export type ObjType<s extends Obj, RequiredProps extends ReadonlyArray<keyof s>> =
|
||||
UnionToIntersection<
|
||||
{ -readonly [R in RequiredPropertyNames<s>]-?: SchemaType<s[R]> } &
|
||||
{ -readonly [R in RequiredProps]-?: SchemaType<s[R]> } &
|
||||
{ -readonly [R in RequiredProps[number]]-?: SchemaType<s[R]> } &
|
||||
{ -readonly [P in keyof s]?: SchemaType<s[P]> }
|
||||
>;
|
||||
|
||||
@ -136,18 +136,19 @@ type PartialIntersection<T> = Partial<UnionToIntersection<T>>;
|
||||
// https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552
|
||||
// To get union, we use `Foo extends any ? Hoge<Foo> : never`
|
||||
type UnionSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? SchemaType<X> : never;
|
||||
type UnionObjectSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? ObjectSchemaType<X> : never;
|
||||
//type UnionObjectSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? ObjectSchemaType<X> : never;
|
||||
type UnionObjType<s extends Obj, a extends readonly any[], X extends ReadonlyArray<keyof s> = a[number]> = X extends any ? ObjType<s, X> : never;
|
||||
type ArrayUnion<T> = T extends any ? Array<T> : never;
|
||||
|
||||
type ObjectSchemaTypeDef<p extends Schema> =
|
||||
p['ref'] extends keyof typeof refs ? Packed<p['ref']> :
|
||||
p['properties'] extends NonNullable<Obj> ?
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ?
|
||||
ObjType<p['properties'], NonNullable<p['required']>[number]> & UnionObjectSchemaType<p['anyOf']> & PartialIntersection<UnionObjectSchemaType<p['anyOf']>>
|
||||
:
|
||||
ObjType<p['properties'], NonNullable<p['required']>[number]>
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? p['anyOf'][number]['required'] extends ReadonlyArray<keyof p['properties']> ?
|
||||
UnionObjType<p['properties'], NonNullable<p['anyOf'][number]['required']>> & ObjType<p['properties'], NonNullable<p['required']>>
|
||||
: never
|
||||
: ObjType<p['properties'], NonNullable<p['required']>>
|
||||
:
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? UnionObjectSchemaType<p['anyOf']> & PartialIntersection<UnionObjectSchemaType<p['anyOf']>> :
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? never : // see CONTRIBUTING.md
|
||||
p['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> :
|
||||
any
|
||||
|
||||
|
@ -138,19 +138,13 @@ export const meta = {
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
url: { type: 'string' },
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['fileId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
url: { type: 'string' },
|
||||
},
|
||||
required: ['url'],
|
||||
},
|
||||
{ required: ['fileId'] },
|
||||
{ required: ['url'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -16,7 +16,7 @@ export const meta = {
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'MO_SUCH_FILE',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
|
||||
},
|
||||
},
|
||||
|
@ -39,19 +39,13 @@ export const meta = {
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
url: { type: 'string' },
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['fileId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
url: { type: 'string' },
|
||||
},
|
||||
required: ['url'],
|
||||
},
|
||||
{ required: ['fileId'] },
|
||||
{ required: ['url'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
248
packages/backend/src/server/api/endpoints/notes/create.test.ts
Normal file
248
packages/backend/src/server/api/endpoints/notes/create.test.ts
Normal file
@ -0,0 +1,248 @@
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname } from 'node:path';
|
||||
import { describe, test, expect } from '@jest/globals';
|
||||
import { getValidator } from '../../../../../test/prelude/get-api-validator.js';
|
||||
import { paramDef } from './create.js';
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
const _dirname = dirname(_filename);
|
||||
|
||||
const VALID = true;
|
||||
const INVALID = false;
|
||||
|
||||
describe('api:notes/create', () => {
|
||||
describe('validation', () => {
|
||||
const v = getValidator(paramDef);
|
||||
const tooLong = readFile(_dirname + '/../../../../../test/resources/misskey.svg', 'utf-8');
|
||||
|
||||
test('reject empty', () => {
|
||||
const valid = v({ });
|
||||
expect(valid).toBe(INVALID);
|
||||
});
|
||||
|
||||
describe('text', () => {
|
||||
test('simple post', () => {
|
||||
expect(v({ text: 'Hello, world!' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('null post', () => {
|
||||
expect(v({ text: null }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('0 characters post', () => {
|
||||
expect(v({ text: '' }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('over 3000 characters post', async () => {
|
||||
expect(v({ text: await tooLong }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cw', () => {
|
||||
test('simple cw', () => {
|
||||
expect(v({ text: 'Hello, world!', cw: 'Hello, world!' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('null cw', () => {
|
||||
expect(v({ text: 'Body', cw: null }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('0 characters cw', () => {
|
||||
expect(v({ text: 'Body', cw: '' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('reject only cw', () => {
|
||||
expect(v({ cw: 'Hello, world!' }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('over 100 characters cw', async () => {
|
||||
expect(v({ text: 'Body', cw: await tooLong }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
});
|
||||
|
||||
describe('visibility', () => {
|
||||
test('public', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'public' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('home', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'home' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('followers', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'followers' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('reject only visibility', () => {
|
||||
expect(v({ visibility: 'public' }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject invalid visibility', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'invalid' }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject null visibility', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: null }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
describe('visibility:specified', () => {
|
||||
test('specified without visibleUserIds', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'specified' }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('specified with empty visibleUserIds', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: [] }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('reject specified with non unique visibleUserIds', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: ['1', '1', '2'] }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject specified with null visibleUserIds', () => {
|
||||
expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: null }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fileIds', () => {
|
||||
test('only fileIds', () => {
|
||||
expect(v({ fileIds: ['1', '2', '3'] }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('text and fileIds', () => {
|
||||
expect(v({ text: 'Hello, world!', fileIds: ['1', '2', '3'] }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('reject null fileIds', () => {
|
||||
expect(v({ fileIds: null }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject text and null fileIds (複合的なanyOfのバリデーションが正しく動作する)', () => {
|
||||
expect(v({ text: 'Hello, world!', fileIds: null }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject 0 files', () => {
|
||||
expect(v({ fileIds: [] }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject non unique', () => {
|
||||
expect(v({ fileIds: ['1', '1', '2'] }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject invalid id', () => {
|
||||
expect(v({ fileIds: ['あ'] }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject over 17 files', () => {
|
||||
const valid = v({ text: 'Hello, world!', fileIds: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'] });
|
||||
expect(valid).toBe(INVALID);
|
||||
});
|
||||
});
|
||||
|
||||
describe('poll', () => {
|
||||
test('note with poll', () => {
|
||||
expect(v({ text: 'Hello, world!', poll: { choices: ['a', 'b', 'c'] } }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('null poll', () => {
|
||||
expect(v({ text: 'Hello, world!', poll: null }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('allow only poll', () => {
|
||||
expect(v({ poll: { choices: ['a', 'b', 'c'] } }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('poll with expiresAt', async () => {
|
||||
expect(v({ poll: { choices: ['a', 'b', 'c'], expiresAt: 1 } }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('poll with expiredAfter', async () => {
|
||||
expect(v({ poll: { choices: ['a', 'b', 'c'], expiredAfter: 1 } }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('reject poll without choices', () => {
|
||||
expect(v({ poll: { } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with empty choices', () => {
|
||||
expect(v({ poll: { choices: [] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with null choices', () => {
|
||||
expect(v({ poll: { choices: null } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with 1 choice', () => {
|
||||
expect(v({ poll: { choices: ['a'] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with too long choice', async () => {
|
||||
expect(v({ poll: { choices: [await tooLong, '2'] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with too many choices', () => {
|
||||
expect(v({ poll: { choices: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with non unique choices', () => {
|
||||
expect(v({ poll: { choices: ['a', 'a', 'b', 'c'] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
|
||||
test('reject poll with expiredAfter 0', async () => {
|
||||
expect(v({ poll: { choices: ['a', 'b', 'c'], expiredAfter: 0 } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
});
|
||||
|
||||
test('text, fileIds and poll', () => {
|
||||
expect(v({ text: 'Hello, world!', fileIds: ['1', '2', '3'], poll: { choices: ['a', 'b', 'c'] } }))
|
||||
.toBe(VALID);
|
||||
});
|
||||
|
||||
test('text, invalid fileIds and invalid poll', () => {
|
||||
expect(v({ text: 'Hello, world!', fileIds: ['あ'], poll: { choices: ['a'] } }))
|
||||
.toBe(INVALID);
|
||||
});
|
||||
});
|
||||
});
|
@ -79,6 +79,12 @@ export const meta = {
|
||||
code: 'YOU_HAVE_BEEN_BLOCKED',
|
||||
id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3',
|
||||
},
|
||||
|
||||
noSuchFile: {
|
||||
message: 'Some files are not found.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'b6992544-63e7-67f0-fa7f-32444b1b5306',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
@ -95,74 +101,55 @@ export const paramDef = {
|
||||
noExtractHashtags: { type: 'boolean', default: false },
|
||||
noExtractEmojis: { type: 'boolean', default: false },
|
||||
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
|
||||
// anyOf内にバリデーションを書いても最初の一つしかチェックされない
|
||||
// See https://github.com/misskey-dev/misskey/pull/10082
|
||||
text: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: MAX_NOTE_TEXT_LENGTH,
|
||||
nullable: false
|
||||
},
|
||||
fileIds: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
maxItems: 16,
|
||||
items: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
mediaIds: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
maxItems: 16,
|
||||
items: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
poll: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
properties: {
|
||||
choices: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 2,
|
||||
maxItems: 10,
|
||||
items: { type: 'string', minLength: 1, maxLength: 50 },
|
||||
},
|
||||
multiple: { type: 'boolean' },
|
||||
expiresAt: { type: 'integer', nullable: true },
|
||||
expiredAfter: { type: 'integer', nullable: true, minimum: 1 },
|
||||
},
|
||||
required: ['choices'],
|
||||
},
|
||||
},
|
||||
// (re)note with text, files and poll are optional
|
||||
anyOf: [
|
||||
{
|
||||
// (re)note with text, files and poll are optional
|
||||
properties: {
|
||||
text: { type: 'string', minLength: 1, maxLength: MAX_NOTE_TEXT_LENGTH, nullable: false },
|
||||
},
|
||||
required: ['text'],
|
||||
},
|
||||
{
|
||||
// (re)note with files, text and poll are optional
|
||||
properties: {
|
||||
fileIds: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
maxItems: 16,
|
||||
items: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
},
|
||||
required: ['fileIds'],
|
||||
},
|
||||
{
|
||||
// (re)note with files, text and poll are optional
|
||||
properties: {
|
||||
mediaIds: {
|
||||
deprecated: true,
|
||||
description: 'Use `fileIds` instead. If both are specified, this property is discarded.',
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
maxItems: 16,
|
||||
items: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
},
|
||||
required: ['mediaIds'],
|
||||
},
|
||||
{
|
||||
// (re)note with poll, text and files are optional
|
||||
properties: {
|
||||
poll: {
|
||||
type: 'object',
|
||||
nullable: true,
|
||||
properties: {
|
||||
choices: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 2,
|
||||
maxItems: 10,
|
||||
items: { type: 'string', minLength: 1, maxLength: 50 },
|
||||
},
|
||||
multiple: { type: 'boolean' },
|
||||
expiresAt: { type: 'integer', nullable: true },
|
||||
expiredAfter: { type: 'integer', nullable: true, minimum: 1 },
|
||||
},
|
||||
required: ['choices'],
|
||||
},
|
||||
},
|
||||
required: ['poll'],
|
||||
},
|
||||
{
|
||||
// pure renote
|
||||
properties: {
|
||||
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
},
|
||||
required: ['renoteId'],
|
||||
},
|
||||
{ required: ['text'] },
|
||||
{ required: ['fileIds'] },
|
||||
{ required: ['mediaIds'] },
|
||||
{ required: ['poll'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
@ -207,6 +194,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
.orderBy('array_position(ARRAY[:...fileIds], "id"::text)')
|
||||
.setParameters({ fileIds })
|
||||
.getMany();
|
||||
|
||||
if (files.length !== fileIds.length) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
}
|
||||
|
||||
let renote: Note | null = null;
|
||||
|
@ -28,6 +28,7 @@ export const paramDef = {
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
offset: { type: 'integer', default: 0 },
|
||||
channelId: { type: 'string', nullable: true, format: 'misskey:id' },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
@ -63,6 +64,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
|
||||
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
|
||||
|
||||
if (ps.channelId) query.andWhere('note.channelId = :channelId', { channelId: ps.channelId });
|
||||
|
||||
if (me) this.queryService.generateMutedUserQuery(query, me);
|
||||
if (me) this.queryService.generateBlockedUserQuery(query, me);
|
||||
|
||||
|
@ -36,32 +36,25 @@ export const paramDef = {
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
|
||||
tag: { type: 'string', minLength: 1 },
|
||||
query: {
|
||||
type: 'array',
|
||||
description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.',
|
||||
items: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
},
|
||||
minItems: 1,
|
||||
},
|
||||
minItems: 1,
|
||||
},
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
tag: { type: 'string', minLength: 1 },
|
||||
},
|
||||
required: ['tag'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
query: {
|
||||
type: 'array',
|
||||
description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.',
|
||||
items: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
},
|
||||
minItems: 1,
|
||||
},
|
||||
minItems: 1,
|
||||
},
|
||||
},
|
||||
required: ['query'],
|
||||
},
|
||||
{ required: ['tag'] },
|
||||
{ required: ['query'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -29,20 +29,14 @@ export const meta = {
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
pageId: { type: 'string', format: 'misskey:id' },
|
||||
name: { type: 'string' },
|
||||
username: { type: 'string' },
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
pageId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['pageId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
username: { type: 'string' },
|
||||
},
|
||||
required: ['name', 'username'],
|
||||
},
|
||||
{ required: ['pageId'] },
|
||||
{ required: ['name', 'username'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -46,25 +46,18 @@ export const paramDef = {
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
required: ['username', 'host'],
|
||||
},
|
||||
{ required: ['userId'] },
|
||||
{ required: ['username', 'host'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -46,25 +46,18 @@ export const paramDef = {
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
required: ['username', 'host'],
|
||||
},
|
||||
{ required: ['userId'] },
|
||||
{ required: ['username', 'host'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -31,20 +31,13 @@ export const paramDef = {
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
detail: { type: 'boolean', default: true },
|
||||
|
||||
username: { type: 'string', nullable: true },
|
||||
host: { type: 'string', nullable: true },
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
username: { type: 'string', nullable: true },
|
||||
},
|
||||
required: ['username'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
host: { type: 'string', nullable: true },
|
||||
},
|
||||
required: ['host'],
|
||||
},
|
||||
{ required: ['username'] },
|
||||
{ required: ['host'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -54,32 +54,22 @@ export const meta = {
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
userIds: { type: 'array', uniqueItems: true, items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
userIds: { type: 'array', uniqueItems: true, items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
},
|
||||
required: ['userIds'],
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
required: ['username'],
|
||||
},
|
||||
{ required: ['userId'] },
|
||||
{ required: ['userIds'] },
|
||||
{ required: ['username'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
@ -17,10 +17,18 @@
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/static-assets/splash.png",
|
||||
"sizes": "300x300",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
}
|
||||
],
|
||||
"share_target": {
|
||||
"action": "/share/",
|
||||
"method": "GET",
|
||||
"enctype": "application/x-www-form-urlencoded",
|
||||
"params": {
|
||||
"title": "title",
|
||||
"text": "text",
|
||||
|
11
packages/backend/test/prelude/get-api-validator.ts
Normal file
11
packages/backend/test/prelude/get-api-validator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Schema } from '@/misc/schema';
|
||||
import Ajv from 'ajv';
|
||||
|
||||
export const getValidator = (paramDef: Schema) => {
|
||||
const ajv = new Ajv({
|
||||
useDefaults: true,
|
||||
});
|
||||
ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/);
|
||||
|
||||
return ajv.compile(paramDef);
|
||||
}
|
7
packages/backend/test/resources/misskey.svg
Normal file
7
packages/backend/test/resources/misskey.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.2 KiB |
@ -33,10 +33,12 @@
|
||||
"lib": [
|
||||
"esnext"
|
||||
],
|
||||
"types": ["jest"]
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"compileOnSave": false,
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
"./**/*.ts",
|
||||
"../src/**/*.test.ts",
|
||||
"../src/@types/**/*.ts",
|
||||
]
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import * as assert from 'assert';
|
||||
import httpSignature from '@peertube/http-signature';
|
||||
import { genRsaKeyPair } from '../../src/misc/gen-key-pair.js';
|
||||
import { createSignedPost, createSignedGet } from '../../src/activitypub/ap-request.js';
|
||||
|
||||
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
|
||||
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||
|
||||
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
|
||||
return {
|
||||
@ -9,7 +10,7 @@ export const buildParsedSignature = (signingString: string, signature: string, a
|
||||
params: {
|
||||
keyId: 'KeyID', // dummy, not used for verify
|
||||
algorithm: algorithm,
|
||||
headers: [ '(request-target)', 'date', 'host', 'digest' ], // dummy, not used for verify
|
||||
headers: ['(request-target)', 'date', 'host', 'digest'], // dummy, not used for verify
|
||||
signature: signature,
|
||||
},
|
||||
signingString: signingString,
|
||||
@ -29,7 +30,7 @@ describe('ap-request', () => {
|
||||
'User-Agent': 'UA',
|
||||
};
|
||||
|
||||
const req = createSignedPost({ key, url, body, additionalHeaders: headers });
|
||||
const req = ApRequestCreator.createSignedPost({ key, url, body, additionalHeaders: headers });
|
||||
|
||||
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
|
||||
|
||||
@ -45,7 +46,7 @@ describe('ap-request', () => {
|
||||
'User-Agent': 'UA',
|
||||
};
|
||||
|
||||
const req = createSignedGet({ key, url, additionalHeaders: headers });
|
||||
const req = ApRequestCreator.createSignedGet({ key, url, additionalHeaders: headers });
|
||||
|
||||
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
|
||||
|
@ -26,9 +26,7 @@
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"outDir": "./built",
|
||||
"types": [
|
||||
@ -46,4 +44,7 @@
|
||||
"include": [
|
||||
"./src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"./src/**/*.test.ts"
|
||||
]
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 26 KiB |
@ -32,6 +32,8 @@ let rootEl = $shallowRef<HTMLDivElement>();
|
||||
|
||||
let zIndex = $ref<number>(os.claimZIndex('high'));
|
||||
|
||||
const SCROLLBAR_THICKNESS = 16;
|
||||
|
||||
onMounted(() => {
|
||||
let left = props.ev.pageX + 1; // 間違って右ダブルクリックした場合に意図せずアイテムがクリックされるのを防ぐため + 1
|
||||
let top = props.ev.pageY + 1; // 間違って右ダブルクリックした場合に意図せずアイテムがクリックされるのを防ぐため + 1
|
||||
@ -39,12 +41,12 @@ onMounted(() => {
|
||||
const width = rootEl.offsetWidth;
|
||||
const height = rootEl.offsetHeight;
|
||||
|
||||
if (left + width - window.pageXOffset > window.innerWidth) {
|
||||
left = window.innerWidth - width + window.pageXOffset;
|
||||
if (left + width - window.pageXOffset >= (window.innerWidth - SCROLLBAR_THICKNESS)) {
|
||||
left = (window.innerWidth - SCROLLBAR_THICKNESS) - width + window.pageXOffset;
|
||||
}
|
||||
|
||||
if (top + height - window.pageYOffset > window.innerHeight) {
|
||||
top = window.innerHeight - height + window.pageYOffset;
|
||||
if (top + height - window.pageYOffset >= (window.innerHeight - SCROLLBAR_THICKNESS)) {
|
||||
top = (window.innerHeight - SCROLLBAR_THICKNESS) - height + window.pageYOffset;
|
||||
}
|
||||
|
||||
if (top < 0) {
|
||||
|
@ -113,6 +113,23 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
lightbox.init();
|
||||
|
||||
window.addEventListener('popstate', () => {
|
||||
if (lightbox.pswp && lightbox.pswp.isOpen === true) {
|
||||
lightbox.pswp.close();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
lightbox.on('beforeOpen', () => {
|
||||
history.pushState(null, '', '#pswp');
|
||||
});
|
||||
|
||||
lightbox.on('close', () => {
|
||||
if (window.location.hash === '#pswp') {
|
||||
history.back();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const previewable = (file: misskey.entities.DriveFile): boolean => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div ref="el" class="sfhdhdhr">
|
||||
<MkMenu ref="menu" :items="items" :align="align" :width="width" :as-drawer="false" @close="onChildClosed"/>
|
||||
<div ref="el" :class="$style.root">
|
||||
<MkMenu :items="items" :align="align" :width="width" :as-drawer="false" @close="onChildClosed"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, shallowRef, watch } from 'vue';
|
||||
import { nextTick, onMounted, onUnmounted, shallowRef, watch } from 'vue';
|
||||
import MkMenu from './MkMenu.vue';
|
||||
import { MenuItem } from '@/types/menu';
|
||||
|
||||
@ -25,11 +25,21 @@ const emit = defineEmits<{
|
||||
const el = shallowRef<HTMLElement>();
|
||||
const align = 'left';
|
||||
|
||||
const SCROLLBAR_THICKNESS = 16;
|
||||
|
||||
function setPosition() {
|
||||
const rootRect = props.rootElement.getBoundingClientRect();
|
||||
const rect = props.targetElement.getBoundingClientRect();
|
||||
const left = props.targetElement.offsetWidth;
|
||||
const top = (rect.top - rootRect.top) - 8;
|
||||
const parentRect = props.targetElement.getBoundingClientRect();
|
||||
const myRect = el.value.getBoundingClientRect();
|
||||
|
||||
let left = props.targetElement.offsetWidth;
|
||||
let top = (parentRect.top - rootRect.top) - 8;
|
||||
if (rootRect.left + left + myRect.width >= (window.innerWidth - SCROLLBAR_THICKNESS)) {
|
||||
left = -myRect.width;
|
||||
}
|
||||
if (rootRect.top + top + myRect.height >= (window.innerHeight - SCROLLBAR_THICKNESS)) {
|
||||
top = top - ((rootRect.top + top + myRect.height) - (window.innerHeight - SCROLLBAR_THICKNESS));
|
||||
}
|
||||
el.value.style.left = left + 'px';
|
||||
el.value.style.top = top + 'px';
|
||||
}
|
||||
@ -46,13 +56,22 @@ watch(() => props.targetElement, () => {
|
||||
setPosition();
|
||||
});
|
||||
|
||||
const ro = new ResizeObserver((entries, observer) => {
|
||||
setPosition();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
ro.observe(el.value);
|
||||
setPosition();
|
||||
nextTick(() => {
|
||||
setPosition();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
ro.disconnect();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
checkHit: (ev: MouseEvent) => {
|
||||
return (ev.target === el.value || el.value.contains(ev.target));
|
||||
@ -60,8 +79,8 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sfhdhdhr {
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -56,7 +56,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, watch } from 'vue';
|
||||
import { defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import { MenuItem, InnerMenuItem, MenuPending, MenuAction } from '@/types/menu';
|
||||
@ -111,11 +111,11 @@ watch(() => props.items, () => {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
let childMenu = $ref<MenuItem[] | null>();
|
||||
let childMenu = ref<MenuItem[] | null>();
|
||||
let childTarget = $shallowRef<HTMLElement | null>();
|
||||
|
||||
function closeChild() {
|
||||
childMenu = null;
|
||||
childMenu.value = null;
|
||||
childShowingItem = null;
|
||||
}
|
||||
|
||||
@ -140,13 +140,31 @@ function onItemMouseLeave(item) {
|
||||
if (childCloseTimer) window.clearTimeout(childCloseTimer);
|
||||
}
|
||||
|
||||
let childrenCache = new WeakMap();
|
||||
async function showChildren(item: MenuItem, ev: MouseEvent) {
|
||||
const children = ref([]);
|
||||
if (childrenCache.has(item)) {
|
||||
children.value = childrenCache.get(item);
|
||||
} else {
|
||||
if (typeof item.children === 'function') {
|
||||
children.value = [{
|
||||
type: 'pending',
|
||||
}];
|
||||
item.children().then(x => {
|
||||
children.value = x;
|
||||
childrenCache.set(item, x);
|
||||
});
|
||||
} else {
|
||||
children.value = item.children;
|
||||
}
|
||||
}
|
||||
|
||||
if (props.asDrawer) {
|
||||
os.popupMenu(item.children, ev.currentTarget ?? ev.target);
|
||||
os.popupMenu(children, ev.currentTarget ?? ev.target);
|
||||
close();
|
||||
} else {
|
||||
childTarget = ev.currentTarget ?? ev.target;
|
||||
childMenu = item.children;
|
||||
childMenu = children;
|
||||
childShowingItem = item;
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ function onBgClick() {
|
||||
}
|
||||
|
||||
if (type === 'drawer') {
|
||||
maxHeight = window.innerHeight / 1.5;
|
||||
maxHeight = (window.innerHeight - SCROLLBAR_THICKNESS) / 1.5;
|
||||
}
|
||||
|
||||
const keymap = {
|
||||
@ -133,6 +133,7 @@ const keymap = {
|
||||
};
|
||||
|
||||
const MARGIN = 16;
|
||||
const SCROLLBAR_THICKNESS = 16;
|
||||
|
||||
const align = () => {
|
||||
if (props.src == null) return;
|
||||
@ -170,15 +171,15 @@ const align = () => {
|
||||
|
||||
if (fixed) {
|
||||
// 画面から横にはみ出る場合
|
||||
if (left + width > window.innerWidth) {
|
||||
left = window.innerWidth - width;
|
||||
if (left + width > (window.innerWidth - SCROLLBAR_THICKNESS)) {
|
||||
left = (window.innerWidth - SCROLLBAR_THICKNESS) - width;
|
||||
}
|
||||
|
||||
const underSpace = (window.innerHeight - MARGIN) - top;
|
||||
const underSpace = ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN) - top;
|
||||
const upperSpace = (srcRect.top - MARGIN);
|
||||
|
||||
// 画面から縦にはみ出る場合
|
||||
if (top + height > (window.innerHeight - MARGIN)) {
|
||||
if (top + height > ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN)) {
|
||||
if (props.noOverlap && props.anchor.x === 'center') {
|
||||
if (underSpace >= (upperSpace / 3)) {
|
||||
maxHeight = underSpace;
|
||||
@ -187,22 +188,22 @@ const align = () => {
|
||||
top = (upperSpace + MARGIN) - height;
|
||||
}
|
||||
} else {
|
||||
top = (window.innerHeight - MARGIN) - height;
|
||||
top = ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN) - height;
|
||||
}
|
||||
} else {
|
||||
maxHeight = underSpace;
|
||||
}
|
||||
} else {
|
||||
// 画面から横にはみ出る場合
|
||||
if (left + width - window.pageXOffset > window.innerWidth) {
|
||||
left = window.innerWidth - width + window.pageXOffset - 1;
|
||||
if (left + width - window.pageXOffset > (window.innerWidth - SCROLLBAR_THICKNESS)) {
|
||||
left = (window.innerWidth - SCROLLBAR_THICKNESS) - width + window.pageXOffset - 1;
|
||||
}
|
||||
|
||||
const underSpace = (window.innerHeight - MARGIN) - (top - window.pageYOffset);
|
||||
const underSpace = ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN) - (top - window.pageYOffset);
|
||||
const upperSpace = (srcRect.top - MARGIN);
|
||||
|
||||
// 画面から縦にはみ出る場合
|
||||
if (top + height - window.pageYOffset > (window.innerHeight - MARGIN)) {
|
||||
if (top + height - window.pageYOffset > ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN)) {
|
||||
if (props.noOverlap && props.anchor.x === 'center') {
|
||||
if (underSpace >= (upperSpace / 3)) {
|
||||
maxHeight = underSpace;
|
||||
@ -211,7 +212,7 @@ const align = () => {
|
||||
top = window.pageYOffset + ((upperSpace + MARGIN) - height);
|
||||
}
|
||||
} else {
|
||||
top = (window.innerHeight - MARGIN) - height + window.pageYOffset - 1;
|
||||
top = ((window.innerHeight - SCROLLBAR_THICKNESS) - MARGIN) - height + window.pageYOffset - 1;
|
||||
}
|
||||
} else {
|
||||
maxHeight = underSpace;
|
||||
|
@ -31,7 +31,7 @@
|
||||
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['localOnly']"><i class="ti ti-world-off"></i></span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-world-off"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
||||
@ -287,7 +287,7 @@ function renote(viaKeyboard = false) {
|
||||
text: i18n.ts.inChannelRenote,
|
||||
icon: 'ti ti-repeat',
|
||||
action: () => {
|
||||
os.api('notes/create', {
|
||||
os.apiWithDialog('notes/create', {
|
||||
renoteId: appearNote.id,
|
||||
channelId: appearNote.channelId,
|
||||
});
|
||||
@ -308,7 +308,7 @@ function renote(viaKeyboard = false) {
|
||||
text: i18n.ts.renote,
|
||||
icon: 'ti ti-repeat',
|
||||
action: () => {
|
||||
os.api('notes/create', {
|
||||
os.apiWithDialog('notes/create', {
|
||||
renoteId: appearNote.id,
|
||||
});
|
||||
},
|
||||
@ -743,9 +743,17 @@ function showReactions(): void {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@container (max-width: 500px) {
|
||||
@container (max-width: 580px) {
|
||||
.root {
|
||||
font-size: 0.9em;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.renote {
|
||||
padding: 12px 26px 0 26px;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 24px 26px 14px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
@ -754,7 +762,21 @@ function showReactions(): void {
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 450px) {
|
||||
@container (max-width: 500px) {
|
||||
.root {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.renote {
|
||||
padding: 10px 22px 0 22px;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 20px 22px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 480px) {
|
||||
.renote {
|
||||
padding: 8px 16px 0 16px;
|
||||
}
|
||||
@ -771,7 +793,9 @@ function showReactions(): void {
|
||||
.article {
|
||||
padding: 14px 16px 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 450px) {
|
||||
.avatar {
|
||||
margin: 0 10px 8px 0;
|
||||
width: 46px;
|
||||
@ -780,7 +804,7 @@ function showReactions(): void {
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 350px) {
|
||||
@container (max-width: 400px) {
|
||||
.footerButton {
|
||||
&:not(:last-child) {
|
||||
margin-right: 18px;
|
||||
@ -788,6 +812,14 @@ function showReactions(): void {
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 350px) {
|
||||
.footerButton {
|
||||
&:not(:last-child) {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@container (max-width: 300px) {
|
||||
.avatar {
|
||||
width: 44px;
|
||||
@ -796,7 +828,7 @@ function showReactions(): void {
|
||||
|
||||
.footerButton {
|
||||
&:not(:last-child) {
|
||||
margin-right: 12px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['localOnly']"><i class="ti ti-world-off"></i></span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-world-off"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<article class="article" @contextmenu.stop="onContextmenu">
|
||||
@ -48,7 +48,7 @@
|
||||
<i v-else-if="appearNote.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="appearNote.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['localOnly']"><i class="ti ti-world-off"></i></span>
|
||||
<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-world-off"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="username"><MkAcct :user="appearNote.user"/></div>
|
||||
@ -250,7 +250,7 @@ function renote(viaKeyboard = false) {
|
||||
text: i18n.ts.inChannelRenote,
|
||||
icon: 'ti ti-repeat',
|
||||
action: () => {
|
||||
os.api('notes/create', {
|
||||
os.apiWithDialog('notes/create', {
|
||||
renoteId: appearNote.id,
|
||||
channelId: appearNote.channelId,
|
||||
});
|
||||
@ -271,7 +271,7 @@ function renote(viaKeyboard = false) {
|
||||
text: i18n.ts.renote,
|
||||
icon: 'ti ti-repeat',
|
||||
action: () => {
|
||||
os.api('notes/create', {
|
||||
os.apiWithDialog('notes/create', {
|
||||
renoteId: appearNote.id,
|
||||
});
|
||||
},
|
||||
|
@ -17,7 +17,7 @@
|
||||
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
||||
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
||||
</span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['localOnly']"><i class="ti ti-world-off"></i></span>
|
||||
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-world-off"></i></span>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
@ -42,6 +42,7 @@ import { computed, ComputedRef, isRef, nextTick, onActivated, onBeforeUnmount, o
|
||||
import * as misskey from 'misskey-js';
|
||||
import * as os from '@/os';
|
||||
import { onScrollTop, isTopVisible, getBodyScrollHeight, getScrollContainer, onScrollBottom, scrollToBottom, scroll, isBottomVisible } from '@/scripts/scroll';
|
||||
import { useDocumentVisibility } from '@/scripts/use-document-visibility';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { defaultStore } from '@/store';
|
||||
import { MisskeyEntity } from '@/types/date-separated-list';
|
||||
@ -107,6 +108,12 @@ const {
|
||||
const contentEl = $computed(() => props.pagination.pageEl ?? rootEl);
|
||||
const scrollableElement = $computed(() => getScrollContainer(contentEl));
|
||||
|
||||
const visibility = useDocumentVisibility();
|
||||
|
||||
let isPausingUpdate = false;
|
||||
let timerForSetPause: number | null = null;
|
||||
const BACKGROUND_PAUSE_WAIT_SEC = 10;
|
||||
|
||||
// 先頭が表示されているかどうかを検出
|
||||
// https://qiita.com/mkataigi/items/0154aefd2223ce23398e
|
||||
let scrollObserver = $ref<IntersectionObserver>();
|
||||
@ -279,6 +286,28 @@ const fetchMoreAhead = async (): Promise<void> => {
|
||||
});
|
||||
};
|
||||
|
||||
const isTop = (): boolean => isBackTop.value || (props.pagination.reversed ? isBottomVisible : isTopVisible)(contentEl, TOLERANCE);
|
||||
|
||||
watch(visibility, () => {
|
||||
if (visibility.value === 'hidden') {
|
||||
timerForSetPause = window.setTimeout(() => {
|
||||
isPausingUpdate = true;
|
||||
timerForSetPause = null;
|
||||
},
|
||||
BACKGROUND_PAUSE_WAIT_SEC * 1000);
|
||||
} else { // 'visible'
|
||||
if (timerForSetPause) {
|
||||
clearTimeout(timerForSetPause);
|
||||
timerForSetPause = null;
|
||||
} else {
|
||||
isPausingUpdate = false;
|
||||
if (isTop()) {
|
||||
executeQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const prepend = (item: MisskeyEntity): void => {
|
||||
// 初回表示時はunshiftだけでOK
|
||||
if (!rootEl) {
|
||||
@ -286,9 +315,7 @@ const prepend = (item: MisskeyEntity): void => {
|
||||
return;
|
||||
}
|
||||
|
||||
const isTop = isBackTop.value || (props.pagination.reversed ? isBottomVisible : isTopVisible)(contentEl, TOLERANCE);
|
||||
|
||||
if (isTop) unshiftItems([item]);
|
||||
if (isTop() && !isPausingUpdate) unshiftItems([item]);
|
||||
else prependQueue(item);
|
||||
};
|
||||
|
||||
@ -357,6 +384,10 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (timerForSetPause) {
|
||||
clearTimeout(timerForSetPause);
|
||||
timerForSetPause = null;
|
||||
}
|
||||
scrollObserver.disconnect();
|
||||
});
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
<button class="_buttonPrimary" style="padding: 4px; border-radius: 8px;" @click="addVisibleUser"><i class="ti ti-plus ti-fw"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<MkInfo v-if="localOnly && channel == null" warn :class="$style.disableFederationWarn">{{ i18n.ts.disableFederationWarn }}</MkInfo>
|
||||
<MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
|
||||
<input v-show="useCw" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown">
|
||||
<textarea ref="textareaEl" v-model="text" :class="[$style.text, { [$style.withCw]: useCw }]" :disabled="posting || posted" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
|
||||
@ -950,6 +951,10 @@ defineExpose({
|
||||
background: var(--X4);
|
||||
}
|
||||
|
||||
.disableFederationWarn {
|
||||
margin: 0 20px 16px 20px;
|
||||
}
|
||||
|
||||
.hasNotSpecifiedMentions {
|
||||
margin: 0 20px 16px 20px;
|
||||
}
|
||||
|
@ -1,12 +1,25 @@
|
||||
<template>
|
||||
<div v-if="playerEnabled" :class="$style.player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
||||
<button :class="$style.disablePlayer" :title="i18n.ts.disablePlayer" @click="playerEnabled = false"><i class="ti ti-x"></i></button>
|
||||
<iframe v-if="player.url.startsWith('http://') || player.url.startsWith('https://')" :class="$style.playerIframe" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
|
||||
<span v-else>invalid url</span>
|
||||
</div>
|
||||
<div v-else-if="tweetId && tweetExpanded" ref="twitter" :class="$style.twitter">
|
||||
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
||||
</div>
|
||||
<template v-if="playerEnabled">
|
||||
<div :class="$style.player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
||||
<iframe v-if="player.url.startsWith('http://') || player.url.startsWith('https://')" :class="$style.playerIframe" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
|
||||
<span v-else>invalid url</span>
|
||||
</div>
|
||||
<div :class="$style.action">
|
||||
<MkButton :small="true" inline @click="playerEnabled = false">
|
||||
<i class="ti ti-x"></i> {{ i18n.ts.disablePlayer }}
|
||||
</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="tweetId && tweetExpanded">
|
||||
<div ref="twitter" :class="$style.twitter">
|
||||
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
||||
</div>
|
||||
<div :class="$style.action">
|
||||
<MkButton :small="true" inline @click="tweetExpanded = false">
|
||||
<i class="ti ti-x"></i> {{ i18n.ts.close }}
|
||||
</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else :class="$style.urlPreview">
|
||||
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
|
||||
<div v-if="thumbnail" :class="$style.thumbnail" :style="`background-image: url('${thumbnail}')`">
|
||||
|
@ -33,8 +33,8 @@
|
||||
<button key="localOnly" class="_button" :class="[$style.item, $style.localOnly, { [$style.active]: localOnly }]" data-index="5" @click="localOnly = !localOnly">
|
||||
<div :class="$style.icon"><i class="ti ti-world-off"></i></div>
|
||||
<div :class="$style.body">
|
||||
<span :class="$style.itemTitle">{{ i18n.ts._visibility.localOnly }}</span>
|
||||
<span :class="$style.itemDescription">{{ i18n.ts._visibility.localOnlyDescription }}</span>
|
||||
<span :class="$style.itemTitle">{{ i18n.ts._visibility.disableFederation }}</span>
|
||||
<span :class="$style.itemDescription">{{ i18n.ts._visibility.disableFederationDescription }}</span>
|
||||
</div>
|
||||
<div :class="$style.toggle"><i :class="localOnly ? 'ti ti-toggle-right' : 'ti ti-toggle-left'"></i></div>
|
||||
</button>
|
||||
|
@ -103,7 +103,7 @@ function onTabWheel(ev: WheelEvent) {
|
||||
ev.stopPropagation();
|
||||
(ev.currentTarget as HTMLElement).scrollBy({
|
||||
left: ev.deltaY,
|
||||
behavior: 'smooth',
|
||||
behavior: 'instant',
|
||||
});
|
||||
}
|
||||
return false;
|
||||
|
@ -151,10 +151,7 @@ onUnmounted(() => {
|
||||
|
||||
.tabs:first-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
.tabs:not(:first-child) {
|
||||
padding-left: 16px;
|
||||
mask-image: linear-gradient(90deg, rgba(0,0,0,0), rgb(0,0,0) 16px, rgb(0,0,0) 100%);
|
||||
padding: 0 12px;
|
||||
}
|
||||
.tabs {
|
||||
margin-right: auto;
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<time :title="absolute">
|
||||
<template v-if="mode === 'relative'">{{ relative }}</template>
|
||||
<template v-if="invalid">{{ i18n.ts._ago.invalid }}</template>
|
||||
<template v-else-if="mode === 'relative'">{{ relative }}</template>
|
||||
<template v-else-if="mode === 'absolute'">{{ absolute }}</template>
|
||||
<template v-else-if="mode === 'detail'">{{ absolute }} ({{ allRelative }})</template>
|
||||
</time>
|
||||
@ -12,18 +13,24 @@ import { i18n } from '@/i18n';
|
||||
import { dateTimeFormat } from '@/scripts/intl-const';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
time: Date | string;
|
||||
time: Date | string | number | null;
|
||||
mode?: 'relative' | 'absolute' | 'detail';
|
||||
}>(), {
|
||||
mode: 'relative',
|
||||
});
|
||||
|
||||
const _time = typeof props.time === 'string' ? new Date(props.time) : props.time;
|
||||
const absolute = dateTimeFormat.format(_time);
|
||||
const _time = props.time == null ? NaN :
|
||||
typeof props.time === 'number' ? props.time :
|
||||
(props.time instanceof Date ? props.time : new Date(props.time)).getTime();
|
||||
const invalid = Number.isNaN(_time);
|
||||
const absolute = !invalid ? dateTimeFormat.format(_time) : i18n.ts._ago.invalid;
|
||||
|
||||
let now = $shallowRef(new Date());
|
||||
const relative = $computed(() => {
|
||||
const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/;
|
||||
let now = $ref((new Date()).getTime());
|
||||
const relative = $computed<string>(() => {
|
||||
if (props.mode === 'absolute') return ''; // absoluteではrelativeを使わないので計算しない
|
||||
if (invalid) return i18n.ts._ago.invalid;
|
||||
|
||||
const ago = (now - _time) / 1000/*ms*/;
|
||||
return (
|
||||
ago >= 86400 ? _time.toLocaleDateString() :
|
||||
ago >= 3600 ? i18n.t('_ago.hoursAgo', { n: Math.round(ago / 3600).toString() }) :
|
||||
@ -50,8 +57,8 @@ const allRelative = $computed(() => {
|
||||
let tickId: number;
|
||||
|
||||
function tick() {
|
||||
now = new Date();
|
||||
const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/;
|
||||
now = (new Date()).getTime();
|
||||
const ago = (now - _time) / 1000/*ms*/;
|
||||
const next = ago < 60 ? 10000 : ago < 3600 ? 60000 : 180000;
|
||||
|
||||
tickId = window.setTimeout(tick, next);
|
||||
|
@ -36,7 +36,6 @@ import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
|
||||
import { defaultStore, ColdDeviceStorage } from '@/store';
|
||||
import { fetchInstance, instance } from '@/instance';
|
||||
import { makeHotkey } from '@/scripts/hotkey';
|
||||
import { search } from '@/scripts/search';
|
||||
import { deviceKind } from '@/scripts/device-kind';
|
||||
import { initializeSw } from '@/scripts/initialize-sw';
|
||||
import { reloadChannel } from '@/scripts/unison-reload';
|
||||
@ -47,6 +46,7 @@ import { deckStore } from './ui/deck/deck-store';
|
||||
import { miLocalStorage } from './local-storage';
|
||||
import { claimAchievement, claimedAchievements } from './scripts/achievements';
|
||||
import { fetchCustomEmojis } from './custom-emojis';
|
||||
import { mainRouter } from './router';
|
||||
|
||||
console.info(`Misskey v${version}`);
|
||||
|
||||
@ -353,7 +353,9 @@ const hotkeys = {
|
||||
'd': (): void => {
|
||||
defaultStore.set('darkMode', !defaultStore.state.darkMode);
|
||||
},
|
||||
's': search,
|
||||
's': (): void => {
|
||||
mainRouter.push('/search');
|
||||
}
|
||||
};
|
||||
|
||||
if (!$i) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { computed, reactive } from 'vue';
|
||||
import { $i } from './account';
|
||||
import { miLocalStorage } from './local-storage';
|
||||
import { search } from '@/scripts/search';
|
||||
import { openInstanceMenu } from './ui/_common_/common';
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { ui } from '@/config';
|
||||
@ -42,7 +42,7 @@ export const navbarItemDef = reactive({
|
||||
search: {
|
||||
title: i18n.ts.search,
|
||||
icon: 'ti ti-search',
|
||||
action: () => search(),
|
||||
to: '/search',
|
||||
},
|
||||
lists: {
|
||||
title: i18n.ts.lists,
|
||||
@ -129,6 +129,13 @@ export const navbarItemDef = reactive({
|
||||
}], ev.currentTarget ?? ev.target);
|
||||
},
|
||||
},
|
||||
about: {
|
||||
title: i18n.ts.about,
|
||||
icon: 'ti ti-info-circle',
|
||||
action: (ev) => {
|
||||
openInstanceMenu(ev);
|
||||
},
|
||||
},
|
||||
reload: {
|
||||
title: i18n.ts.reload,
|
||||
icon: 'ti ti-refresh',
|
||||
|
@ -203,6 +203,7 @@ const patrons = [
|
||||
'ThatOneCalculator',
|
||||
'pixeldesu',
|
||||
'あめ玉',
|
||||
'氷月氷華里',
|
||||
];
|
||||
|
||||
let thereIsTreasure = $ref($i && !claimedAchievements.includes('foundTreasure'));
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :content-max="700">
|
||||
<div v-if="channel">
|
||||
<div class="wpgynlbz _panel _margin blur" :class="{ hide: !showBanner }">
|
||||
<div v-if="channel && tab === 'timeline'" class="_gaps">
|
||||
<div class="wpgynlbz _panel" :class="{ hide: !showBanner }">
|
||||
<XChannelFollowButton :channel="channel" :full="true" class="subscribe"/>
|
||||
<button class="_button toggle" @click="() => showBanner = !showBanner">
|
||||
<template v-if="showBanner"><i class="ti ti-chevron-up"></i></template>
|
||||
@ -23,9 +23,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MkPostForm v-if="$i" :channel="channel" class="post-form _panel _margin blur" fixed/>
|
||||
<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
|
||||
<MkPostForm v-if="$i" :channel="channel" class="post-form _panel blur" fixed :autofocus="deviceKind === 'desktop'"/>
|
||||
|
||||
<MkTimeline :key="channelId" class="_margin" src="channel" :channel="channelId" @before="before" @after="after"/>
|
||||
<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'featured'">
|
||||
<MkNotes :pagination="featuredPagination"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
@ -41,6 +45,8 @@ import { useRouter } from '@/router';
|
||||
import { $i } from '@/account';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { deviceKind } from '@/scripts/device-kind';
|
||||
import MkNotes from '@/components/MkNotes.vue';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@ -48,15 +54,17 @@ const props = defineProps<{
|
||||
channelId: string;
|
||||
}>();
|
||||
|
||||
let tab = $ref('timeline');
|
||||
let channel = $ref(null);
|
||||
let showBanner = $ref(true);
|
||||
const pagination = {
|
||||
endpoint: 'channels/timeline' as const,
|
||||
const featuredPagination = $computed(() => ({
|
||||
endpoint: 'notes/featured' as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
offsetMode: true,
|
||||
params: {
|
||||
channelId: props.channelId,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}));
|
||||
|
||||
watch(() => props.channelId, async () => {
|
||||
channel = await os.api('channels/show', {
|
||||
@ -74,7 +82,15 @@ const headerActions = $computed(() => channel && channel.userId ? [{
|
||||
handler: edit,
|
||||
}] : null);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
const headerTabs = $computed(() => [{
|
||||
key: 'timeline',
|
||||
title: i18n.ts.timeline,
|
||||
icon: 'ti ti-home',
|
||||
}, {
|
||||
key: 'featured',
|
||||
title: i18n.ts.featured,
|
||||
icon: 'ti ti-bolt',
|
||||
}]);
|
||||
|
||||
definePageMetadata(computed(() => channel ? {
|
||||
title: channel.name,
|
||||
|
@ -11,23 +11,6 @@
|
||||
<div v-else-if="tab === 'roles'">
|
||||
<XRoles/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'search'">
|
||||
<MkSpacer :content-max="1200">
|
||||
<div>
|
||||
<MkInput v-model="searchQuery" :debounce="true" type="search">
|
||||
<template #prefix><i class="ti ti-search"></i></template>
|
||||
<template #label>{{ i18n.ts.searchUser }}</template>
|
||||
</MkInput>
|
||||
<MkRadios v-model="searchOrigin">
|
||||
<option value="combined">{{ i18n.ts.all }}</option>
|
||||
<option value="local">{{ i18n.ts.local }}</option>
|
||||
<option value="remote">{{ i18n.ts.remote }}</option>
|
||||
</MkRadios>
|
||||
</div>
|
||||
|
||||
<MkUserList v-if="searchQuery" ref="searchEl" class="_margin" :pagination="searchPagination"/>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</div>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
@ -38,11 +21,8 @@ import XFeatured from './explore.featured.vue';
|
||||
import XUsers from './explore.users.vue';
|
||||
import XRoles from './explore.roles.vue';
|
||||
import MkFoldableSection from '@/components/MkFoldableSection.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import MkRadios from '@/components/MkRadios.vue';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { i18n } from '@/i18n';
|
||||
import MkUserList from '@/components/MkUserList.vue';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
tag?: string;
|
||||
@ -53,22 +33,11 @@ const props = withDefaults(defineProps<{
|
||||
|
||||
let tab = $ref(props.initialTab);
|
||||
let tagsEl = $shallowRef<InstanceType<typeof MkFoldableSection>>();
|
||||
let searchQuery = $ref(null);
|
||||
let searchOrigin = $ref('combined');
|
||||
|
||||
watch(() => props.tag, () => {
|
||||
if (tagsEl) tagsEl.toggleContent(props.tag == null);
|
||||
});
|
||||
|
||||
const searchPagination = {
|
||||
endpoint: 'users/search' as const,
|
||||
limit: 10,
|
||||
params: computed(() => (searchQuery && searchQuery !== '') ? {
|
||||
query: searchQuery,
|
||||
origin: searchOrigin,
|
||||
} : null),
|
||||
};
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => [{
|
||||
@ -83,10 +52,6 @@ const headerTabs = $computed(() => [{
|
||||
key: 'roles',
|
||||
icon: 'ti ti-badges',
|
||||
title: i18n.ts.roles,
|
||||
}, {
|
||||
key: 'search',
|
||||
icon: 'ti ti-search',
|
||||
title: i18n.ts.search,
|
||||
}]);
|
||||
|
||||
definePageMetadata(computed(() => ({
|
||||
|
@ -2,33 +2,104 @@
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkNotes ref="notes" :pagination="pagination"/>
|
||||
<MkInput v-model="searchQuery" :large="true" :autofocus="true" :debounce="true" type="search" style="margin-bottom: var(--margin);" @update:model-value="search()">
|
||||
<template #prefix><i class="ti ti-search"></i></template>
|
||||
</MkInput>
|
||||
<MkTab v-model="searchType" style="margin-bottom: var(--margin);" @update:model-value="search()">
|
||||
<option value="note">{{ i18n.ts.note }}</option>
|
||||
<option value="user">{{ i18n.ts.user }}</option>
|
||||
</MkTab>
|
||||
|
||||
<div v-if="searchType === 'note'">
|
||||
<MkNotes v-if="searchQuery" ref="notes" :pagination="notePagination"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<MkRadios v-model="searchOrigin" style="margin-bottom: var(--margin);" @update:model-value="search()">
|
||||
<option value="combined">{{ i18n.ts.all }}</option>
|
||||
<option value="local">{{ i18n.ts.local }}</option>
|
||||
<option value="remote">{{ i18n.ts.remote }}</option>
|
||||
</MkRadios>
|
||||
|
||||
<MkUserList v-if="searchQuery" ref="users" :pagination="userPagination"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import MkNotes from '@/components/MkNotes.vue';
|
||||
import MkUserList from '@/components/MkUserList.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import MkTab from '@/components/MkTab.vue';
|
||||
import MkRadios from '@/components/MkRadios.vue';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import * as os from '@/os';
|
||||
import { useRouter } from '@/router';
|
||||
import { $i } from '@/account';
|
||||
import { useRouter, mainRouter } from '@/router';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const props = defineProps<{
|
||||
query: string;
|
||||
channel?: string;
|
||||
type?: string;
|
||||
origin?: string;
|
||||
}>();
|
||||
|
||||
const query = props.query;
|
||||
let searchQuery = $ref('');
|
||||
let searchType = $ref('note');
|
||||
let searchOrigin = $ref('combined');
|
||||
|
||||
if ($i != null) {
|
||||
if (query.startsWith('https://') || (query.startsWith('@') && !query.includes(' '))) {
|
||||
onMounted(() => {
|
||||
searchQuery = props.query ?? '';
|
||||
searchType = props.type ?? 'note';
|
||||
searchOrigin = props.origin ?? 'combined';
|
||||
|
||||
if (searchQuery) {
|
||||
search();
|
||||
}
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
const query = searchQuery.toString().trim();
|
||||
|
||||
if (query == null || query === '') return;
|
||||
|
||||
if (query.startsWith('@') && !query.includes(' ')) {
|
||||
mainRouter.push(`/${query}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.startsWith('#')) {
|
||||
mainRouter.push(`/tags/${encodeURIComponent(query.substr(1))}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// like 2018/03/12
|
||||
if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(query.replace(/-/g, '/'))) {
|
||||
const date = new Date(query.replace(/-/g, '/'));
|
||||
|
||||
// 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは
|
||||
// 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので
|
||||
// 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の
|
||||
// 結果になってしまい、2018/03/12 のコンテンツは含まれない)
|
||||
if (query.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) {
|
||||
date.setHours(23, 59, 59, 999);
|
||||
}
|
||||
|
||||
// TODO
|
||||
//v.$root.$emit('warp', date);
|
||||
os.alert({
|
||||
icon: 'ti ti-history',
|
||||
iconOnly: true, autoClose: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.startsWith('https://')) {
|
||||
const promise = os.api('ap/show', {
|
||||
uri: props.query,
|
||||
uri: query,
|
||||
});
|
||||
|
||||
os.promiseDialog(promise, null, null, i18n.ts.fetchingAsApObject);
|
||||
@ -36,28 +107,40 @@ if ($i != null) {
|
||||
const res = await promise;
|
||||
|
||||
if (res.type === 'User') {
|
||||
router.replace(`/@${res.object.username}@${res.object.host}`);
|
||||
mainRouter.push(`/@${res.object.username}@${res.object.host}`);
|
||||
} else if (res.type === 'Note') {
|
||||
router.replace(`/notes/${res.object.id}`);
|
||||
mainRouter.push(`/notes/${res.object.id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pagination = {
|
||||
return;
|
||||
}
|
||||
|
||||
window.history.replaceState('', '', `/search?q=${encodeURIComponent(query)}&type=${searchType}${searchType === 'user' ? `&origin=${searchOrigin}` : ''}`);
|
||||
};
|
||||
|
||||
const notePagination = {
|
||||
endpoint: 'notes/search' as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
query: props.query,
|
||||
query: searchQuery,
|
||||
channelId: props.channel,
|
||||
})),
|
||||
};
|
||||
const userPagination = {
|
||||
endpoint: 'users/search' as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
query: searchQuery,
|
||||
origin: searchOrigin,
|
||||
})),
|
||||
};
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
|
||||
definePageMetadata(computed(() => ({
|
||||
title: i18n.t('searchWith', { q: props.query }),
|
||||
title: searchQuery ? i18n.t('searchWith', { q: searchQuery }) : i18n.ts.search,
|
||||
icon: 'ti ti-search',
|
||||
})));
|
||||
</script>
|
||||
|
@ -4,27 +4,29 @@
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ i18n.ts.manage }}</template>
|
||||
<div v-for="plugin in plugins" :key="plugin.id" class="_panel _gaps_s blur" style="padding: 20px;">
|
||||
<span style="display: flex;"><b>{{ plugin.name }}</b><span style="margin-left: auto;">v{{ plugin.version }}</span></span>
|
||||
<div class="_gaps_s">
|
||||
<div v-for="plugin in plugins" :key="plugin.id" class="_panel _gaps_s blur" style="padding: 20px;">
|
||||
<span style="display: flex;"><b>{{ plugin.name }}</b><span style="margin-left: auto;">v{{ plugin.version }}</span></span>
|
||||
|
||||
<MkSwitch :model-value="plugin.active" @update:model-value="changeActive(plugin, $event)">{{ i18n.ts.makeActive }}</MkSwitch>
|
||||
<MkSwitch :model-value="plugin.active" @update:model-value="changeActive(plugin, $event)">{{ i18n.ts.makeActive }}</MkSwitch>
|
||||
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.author }}</template>
|
||||
<template #value>{{ plugin.author }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.description }}</template>
|
||||
<template #value>{{ plugin.description }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.permission }}</template>
|
||||
<template #value>{{ plugin.permission }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.author }}</template>
|
||||
<template #value>{{ plugin.author }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.description }}</template>
|
||||
<template #value>{{ plugin.description }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.permission }}</template>
|
||||
<template #value>{{ plugin.permission }}</template>
|
||||
</MkKeyValue>
|
||||
|
||||
<div class="_buttons">
|
||||
<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="ti ti-settings"></i> {{ i18n.ts.settings }}</MkButton>
|
||||
<MkButton inline danger @click="uninstall(plugin)"><i class="ti ti-trash"></i> {{ i18n.ts.uninstall }}</MkButton>
|
||||
<div class="_buttons">
|
||||
<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="ti ti-settings"></i> {{ i18n.ts.settings }}</MkButton>
|
||||
<MkButton inline danger @click="uninstall(plugin)"><i class="ti ti-trash"></i> {{ i18n.ts.uninstall }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
@ -46,7 +46,7 @@
|
||||
<option value="followers">{{ i18n.ts._visibility.followers }}</option>
|
||||
<option value="specified">{{ i18n.ts._visibility.specified }}</option>
|
||||
</MkSelect>
|
||||
<MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.localOnly }}</MkSwitch>
|
||||
<MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</div>
|
||||
|
@ -217,6 +217,8 @@ export const routes = [{
|
||||
query: {
|
||||
q: 'query',
|
||||
channel: 'channel',
|
||||
type: 'type',
|
||||
origin: 'origin',
|
||||
},
|
||||
}, {
|
||||
path: '/authorize-follow',
|
||||
|
@ -9,6 +9,7 @@ import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import { url } from '@/config';
|
||||
import { noteActions } from '@/store';
|
||||
import { miLocalStorage } from '@/local-storage';
|
||||
import { getUserMenu } from '@/scripts/get-user-menu';
|
||||
|
||||
export function getNoteMenu(props: {
|
||||
note: misskey.entities.Note;
|
||||
@ -122,66 +123,6 @@ export function getNoteMenu(props: {
|
||||
});
|
||||
}
|
||||
|
||||
async function clip(): Promise<void> {
|
||||
const clips = await os.api('clips/list');
|
||||
os.popupMenu([{
|
||||
icon: 'ti ti-plus',
|
||||
text: i18n.ts.createNew,
|
||||
action: async () => {
|
||||
const { canceled, result } = await os.form(i18n.ts.createNewClip, {
|
||||
name: {
|
||||
type: 'string',
|
||||
label: i18n.ts.name,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
multiline: true,
|
||||
label: i18n.ts.description,
|
||||
},
|
||||
isPublic: {
|
||||
type: 'boolean',
|
||||
label: i18n.ts.public,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
const clip = await os.apiWithDialog('clips/create', result);
|
||||
|
||||
claimAchievement('noteClipped1');
|
||||
os.apiWithDialog('clips/add-note', { clipId: clip.id, noteId: appearNote.id });
|
||||
},
|
||||
}, null, ...clips.map(clip => ({
|
||||
text: clip.name,
|
||||
action: () => {
|
||||
claimAchievement('noteClipped1');
|
||||
os.promiseDialog(
|
||||
os.api('clips/add-note', { clipId: clip.id, noteId: appearNote.id }),
|
||||
null,
|
||||
async (err) => {
|
||||
if (err.id === '734806c4-542c-463a-9311-15c512803965') {
|
||||
const confirm = await os.confirm({
|
||||
type: 'warning',
|
||||
text: i18n.t('confirmToUnclipAlreadyClippedNote', { name: clip.name }),
|
||||
});
|
||||
if (!confirm.canceled) {
|
||||
os.apiWithDialog('clips/remove-note', { clipId: clip.id, noteId: appearNote.id });
|
||||
if (props.currentClipPage?.value.id === clip.id) props.isDeleted.value = true;
|
||||
}
|
||||
} else {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: err.message + '\n' + err.id,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
}))], props.menuButton.value, {
|
||||
}).then(focus);
|
||||
}
|
||||
|
||||
async function unclip(): Promise<void> {
|
||||
os.apiWithDialog('clips/remove-note', { clipId: props.currentClipPage.value.id, noteId: appearNote.id });
|
||||
props.isDeleted.value = true;
|
||||
@ -297,9 +238,67 @@ export function getNoteMenu(props: {
|
||||
action: () => toggleFavorite(true),
|
||||
}),
|
||||
{
|
||||
type: 'parent',
|
||||
icon: 'ti ti-paperclip',
|
||||
text: i18n.ts.clip,
|
||||
action: () => clip(),
|
||||
children: async () => {
|
||||
const clips = await os.api('clips/list');
|
||||
return [{
|
||||
icon: 'ti ti-plus',
|
||||
text: i18n.ts.createNew,
|
||||
action: async () => {
|
||||
const { canceled, result } = await os.form(i18n.ts.createNewClip, {
|
||||
name: {
|
||||
type: 'string',
|
||||
label: i18n.ts.name,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
multiline: true,
|
||||
label: i18n.ts.description,
|
||||
},
|
||||
isPublic: {
|
||||
type: 'boolean',
|
||||
label: i18n.ts.public,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
const clip = await os.apiWithDialog('clips/create', result);
|
||||
|
||||
claimAchievement('noteClipped1');
|
||||
os.apiWithDialog('clips/add-note', { clipId: clip.id, noteId: appearNote.id });
|
||||
},
|
||||
}, null, ...clips.map(clip => ({
|
||||
text: clip.name,
|
||||
action: () => {
|
||||
claimAchievement('noteClipped1');
|
||||
os.promiseDialog(
|
||||
os.api('clips/add-note', { clipId: clip.id, noteId: appearNote.id }),
|
||||
null,
|
||||
async (err) => {
|
||||
if (err.id === '734806c4-542c-463a-9311-15c512803965') {
|
||||
const confirm = await os.confirm({
|
||||
type: 'warning',
|
||||
text: i18n.t('confirmToUnclipAlreadyClippedNote', { name: clip.name }),
|
||||
});
|
||||
if (!confirm.canceled) {
|
||||
os.apiWithDialog('clips/remove-note', { clipId: clip.id, noteId: appearNote.id });
|
||||
if (props.currentClipPage?.value.id === clip.id) props.isDeleted.value = true;
|
||||
}
|
||||
} else {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: err.message + '\n' + err.id,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
}))];
|
||||
},
|
||||
},
|
||||
statePromise.then(state => state.isMutedThread ? {
|
||||
icon: 'ti ti-message-off',
|
||||
@ -319,6 +318,15 @@ export function getNoteMenu(props: {
|
||||
text: i18n.ts.pin,
|
||||
action: () => togglePin(true),
|
||||
} : undefined,
|
||||
appearNote.userId !== $i.id ? {
|
||||
type: 'parent',
|
||||
icon: 'ti ti-user',
|
||||
text: i18n.ts.user,
|
||||
children: async () => {
|
||||
const user = await os.api('users/show', { userId: appearNote.userId });
|
||||
return getUserMenu(user);
|
||||
},
|
||||
} : undefined,
|
||||
/*
|
||||
...($i.isModerator || $i.isAdmin ? [
|
||||
null,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import { i18n } from '@/i18n';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import { host } from '@/config';
|
||||
@ -8,32 +9,9 @@ import { $i, iAmModerator } from '@/account';
|
||||
import { mainRouter } from '@/router';
|
||||
import { Router } from '@/nirax';
|
||||
|
||||
export function getUserMenu(user, router: Router = mainRouter) {
|
||||
export function getUserMenu(user: misskey.entities.UserDetailed, router: Router = mainRouter) {
|
||||
const meId = $i ? $i.id : null;
|
||||
|
||||
async function pushList() {
|
||||
const t = i18n.ts.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく
|
||||
const lists = await os.api('users/lists/list');
|
||||
if (lists.length === 0) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts.youHaveNoLists,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { canceled, result: listId } = await os.select({
|
||||
title: t,
|
||||
items: lists.map(list => ({
|
||||
value: list.id, text: list.name,
|
||||
})),
|
||||
});
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('users/lists/push', {
|
||||
listId: listId,
|
||||
userId: user.id,
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleMute() {
|
||||
if (user.isMuted) {
|
||||
os.apiWithDialog('mute/delete', {
|
||||
@ -102,6 +80,8 @@ export function getUserMenu(user, router: Router = mainRouter) {
|
||||
}
|
||||
|
||||
async function invalidateFollow() {
|
||||
if (!await getConfirmed(i18n.ts.breakFollowConfirm)) return;
|
||||
|
||||
os.apiWithDialog('following/invalidate', {
|
||||
userId: user.id,
|
||||
}).then(() => {
|
||||
@ -113,7 +93,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
|
||||
icon: 'ti ti-at',
|
||||
text: i18n.ts.copyUsername,
|
||||
action: () => {
|
||||
copyToClipboard(`@${user.username}@${user.host || host}`);
|
||||
copyToClipboard(`@${user.username}@${user.host ?? host}`);
|
||||
},
|
||||
}, {
|
||||
icon: 'ti ti-info-circle',
|
||||
@ -134,12 +114,43 @@ export function getUserMenu(user, router: Router = mainRouter) {
|
||||
os.post({ specified: user });
|
||||
},
|
||||
}, null, {
|
||||
type: 'parent',
|
||||
icon: 'ti ti-list',
|
||||
text: i18n.ts.addToList,
|
||||
action: pushList,
|
||||
children: async () => {
|
||||
const lists = await os.api('users/lists/list');
|
||||
|
||||
return lists.map(list => ({
|
||||
text: list.name,
|
||||
action: () => {
|
||||
os.apiWithDialog('users/lists/push', {
|
||||
listId: list.id,
|
||||
userId: user.id,
|
||||
});
|
||||
},
|
||||
}));
|
||||
},
|
||||
}] as any;
|
||||
|
||||
if ($i && meId !== user.id) {
|
||||
if (iAmModerator) {
|
||||
menu = menu.concat([{
|
||||
type: 'parent',
|
||||
icon: 'ti ti-badges',
|
||||
text: i18n.ts.roles,
|
||||
children: async () => {
|
||||
const roles = await os.api('admin/roles/list');
|
||||
|
||||
return roles.filter(r => r.target === 'manual').map(r => ({
|
||||
text: r.name,
|
||||
action: () => {
|
||||
os.apiWithDialog('admin/roles/assign', { roleId: r.id, userId: user.id });
|
||||
},
|
||||
}));
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
menu = menu.concat([null, {
|
||||
icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
|
||||
text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
|
||||
@ -163,30 +174,6 @@ export function getUserMenu(user, router: Router = mainRouter) {
|
||||
text: i18n.ts.reportAbuse,
|
||||
action: reportAbuse,
|
||||
}]);
|
||||
|
||||
if (iAmModerator) {
|
||||
menu = menu.concat([null, {
|
||||
icon: 'ti ti-user-exclamation',
|
||||
text: i18n.ts.moderation,
|
||||
action: () => {
|
||||
router.push('/user-info/' + user.id + '#moderation');
|
||||
},
|
||||
}, {
|
||||
icon: 'ti ti-badges',
|
||||
text: i18n.ts.roles,
|
||||
action: async () => {
|
||||
const roles = await os.api('admin/roles/list');
|
||||
|
||||
const { canceled, result: roleId } = await os.select({
|
||||
title: i18n.ts._role.chooseRoleToAssign,
|
||||
items: roles.map(r => ({ text: r.name, value: r.id })),
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
await os.apiWithDialog('admin/roles/assign', { roleId, userId: user.id });
|
||||
},
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($i && meId === user.id) {
|
||||
|
@ -1,63 +0,0 @@
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { mainRouter } from '@/router';
|
||||
|
||||
export async function search() {
|
||||
const { canceled, result: query } = await os.inputText({
|
||||
title: i18n.ts.search,
|
||||
});
|
||||
if (canceled || query == null || query === '') return;
|
||||
|
||||
const q = query.trim();
|
||||
|
||||
if (q.startsWith('@') && !q.includes(' ')) {
|
||||
mainRouter.push(`/${q}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.startsWith('#')) {
|
||||
mainRouter.push(`/tags/${encodeURIComponent(q.substr(1))}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// like 2018/03/12
|
||||
if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(q.replace(/-/g, '/'))) {
|
||||
const date = new Date(q.replace(/-/g, '/'));
|
||||
|
||||
// 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは
|
||||
// 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので
|
||||
// 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の
|
||||
// 結果になってしまい、2018/03/12 のコンテンツは含まれない)
|
||||
if (q.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) {
|
||||
date.setHours(23, 59, 59, 999);
|
||||
}
|
||||
|
||||
// TODO
|
||||
//v.$root.$emit('warp', date);
|
||||
os.alert({
|
||||
icon: 'ti ti-history',
|
||||
iconOnly: true, autoClose: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.startsWith('https://')) {
|
||||
const promise = os.api('ap/show', {
|
||||
uri: q,
|
||||
});
|
||||
|
||||
os.promiseDialog(promise, null, null, i18n.ts.fetchingAsApObject);
|
||||
|
||||
const res = await promise;
|
||||
|
||||
if (res.type === 'User') {
|
||||
mainRouter.push(`/@${res.object.username}@${res.object.host}`);
|
||||
} else if (res.type === 'Note') {
|
||||
mainRouter.push(`/notes/${res.object.id}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mainRouter.push(`/search?q=${encodeURIComponent(q)}`);
|
||||
}
|
19
packages/frontend/src/scripts/use-document-visibility.ts
Normal file
19
packages/frontend/src/scripts/use-document-visibility.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { onMounted, onUnmounted, ref, Ref } from 'vue';
|
||||
|
||||
export function useDocumentVisibility(): Ref<DocumentVisibilityState> {
|
||||
const visibility = ref(document.visibilityState);
|
||||
|
||||
const onChange = (): void => {
|
||||
visibility.value = document.visibilityState;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('visibilitychange', onChange);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('visibilitychange', onChange);
|
||||
});
|
||||
|
||||
return visibility;
|
||||
}
|
@ -45,11 +45,11 @@
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import { openInstanceMenu } from './_common_/common';
|
||||
import { host } from '@/config';
|
||||
import { search } from '@/scripts/search';
|
||||
import * as os from '@/os';
|
||||
import { navbarItemDef } from '@/navbar';
|
||||
import { openAccountMenu } from '@/account';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { mainRouter } from '@/router';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -103,7 +103,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
search() {
|
||||
search();
|
||||
mainRouter.push('/search');
|
||||
},
|
||||
|
||||
more(ev) {
|
||||
|
@ -44,12 +44,12 @@
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import { openInstanceMenu } from './_common_/common';
|
||||
import { host } from '@/config';
|
||||
import { search } from '@/scripts/search';
|
||||
import * as os from '@/os';
|
||||
import { navbarItemDef } from '@/navbar';
|
||||
import { openAccountMenu } from '@/account';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { StickySidebar } from '@/scripts/sticky-sidebar';
|
||||
import { mainRouter } from '@/router';
|
||||
//import MisskeyLogo from '@assets/client/misskey.svg';
|
||||
|
||||
export default defineComponent({
|
||||
@ -120,7 +120,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
search() {
|
||||
search();
|
||||
mainRouter.push('/search');
|
||||
},
|
||||
|
||||
more(ev) {
|
||||
|
@ -40,7 +40,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import XHeader from './header.vue';
|
||||
import { host, instanceName } from '@/config';
|
||||
import { search } from '@/scripts/search';
|
||||
import * as os from '@/os';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
@ -77,7 +76,9 @@ export default defineComponent({
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) return;
|
||||
this.$store.set('darkMode', !this.$store.state.darkMode);
|
||||
},
|
||||
's': search,
|
||||
's': () => {
|
||||
mainRouter.push('/search');
|
||||
},
|
||||
'h|/': this.help,
|
||||
};
|
||||
},
|
||||
|
@ -58,7 +58,6 @@ import { ComputedRef, onMounted, provide } from 'vue';
|
||||
import XHeader from './header.vue';
|
||||
import XKanban from './kanban.vue';
|
||||
import { host, instanceName } from '@/config';
|
||||
import { search } from '@/scripts/search';
|
||||
import * as os from '@/os';
|
||||
import { instance } from '@/instance';
|
||||
import XSigninDialog from '@/components/MkSigninDialog.vue';
|
||||
@ -97,7 +96,9 @@ const keymap = $computed(() => {
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) return;
|
||||
defaultStore.set('darkMode', !defaultStore.state.darkMode);
|
||||
},
|
||||
's': search,
|
||||
's': () => {
|
||||
mainRouter.push('/search');
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -27,7 +27,7 @@ import XSigninDialog from '@/components/MkSigninDialog.vue';
|
||||
import XSignupDialog from '@/components/MkSignupDialog.vue';
|
||||
import * as os from '@/os';
|
||||
import { instance } from '@/instance';
|
||||
import { search } from '@/scripts/search';
|
||||
import { mainRouter } from '@/router';
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
@ -55,7 +55,9 @@ export default defineComponent({
|
||||
}, {}, 'closed');
|
||||
},
|
||||
|
||||
search,
|
||||
search() {
|
||||
mainRouter.push('/search');
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
140
pnpm-lock.yaml
generated
140
pnpm-lock.yaml
generated
@ -67,7 +67,7 @@ importers:
|
||||
'@redocly/openapi-core': 1.0.0-beta.123
|
||||
'@sinonjs/fake-timers': 10.0.2
|
||||
'@swc/cli': 0.1.62
|
||||
'@swc/core': 1.3.35
|
||||
'@swc/core': 1.3.36
|
||||
'@swc/core-android-arm64': ^1.3.11
|
||||
'@swc/core-darwin-arm64': ^1.3.36
|
||||
'@swc/core-darwin-x64': ^1.3.36
|
||||
@ -235,8 +235,8 @@ importers:
|
||||
'@nestjs/testing': 9.3.9_77foi4w27ghy47yutmnzv7krjy
|
||||
'@peertube/http-signature': 1.7.0
|
||||
'@sinonjs/fake-timers': 10.0.2
|
||||
'@swc/cli': 0.1.62_r2avoeggowhtjk5lmq5oy455q4
|
||||
'@swc/core': 1.3.35
|
||||
'@swc/cli': 0.1.62_wyduggqpvtv2oy5nc7cgtozgpy
|
||||
'@swc/core': 1.3.36
|
||||
accepts: 1.3.8
|
||||
ajv: 8.12.0
|
||||
archiver: 5.3.1
|
||||
@ -342,7 +342,7 @@ importers:
|
||||
devDependencies:
|
||||
'@jest/globals': 29.4.3
|
||||
'@redocly/openapi-core': 1.0.0-beta.123
|
||||
'@swc/jest': 0.2.24_@swc+core@1.3.35
|
||||
'@swc/jest': 0.2.24_@swc+core@1.3.36
|
||||
'@types/accepts': 1.3.5
|
||||
'@types/archiver': 5.3.1
|
||||
'@types/bcryptjs': 2.4.2
|
||||
@ -2169,7 +2169,7 @@ packages:
|
||||
resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==}
|
||||
dev: false
|
||||
|
||||
/@swc/cli/0.1.62_r2avoeggowhtjk5lmq5oy455q4:
|
||||
/@swc/cli/0.1.62_wyduggqpvtv2oy5nc7cgtozgpy:
|
||||
resolution: {integrity: sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw==}
|
||||
engines: {node: '>= 12.13'}
|
||||
hasBin: true
|
||||
@ -2181,7 +2181,7 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@mole-inc/bin-wrapper': 8.0.1
|
||||
'@swc/core': 1.3.35
|
||||
'@swc/core': 1.3.36
|
||||
chokidar: 3.5.3
|
||||
commander: 7.2.0
|
||||
fast-glob: 3.2.12
|
||||
@ -2201,29 +2201,12 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-arm64/1.3.35:
|
||||
resolution: {integrity: sha512-zQUFkHx4gZpu0uo2IspvPnKsz8bsdXd5bC33xwjtoAI1cpLerDyqo4v2zIahEp+FdKZjyVsLHtfJiQiA1Qka3A==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-arm64/1.3.36:
|
||||
resolution: {integrity: sha512-lsP+C8p9cC/Vd9uAbtxpEnM8GoJI/MMnVuXak7OlxOtDH9/oTwmAcAQTfNGNaH19d2FAIRwf+5RbXCPnxa2Zjw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-x64/1.3.35:
|
||||
resolution: {integrity: sha512-oOSkSGWtALovaw22lNevKD434OQTPf8X+dVPvPMrJXJpJ34dWDlFWpLntoc+arvKLNZ7LQmTuk8rR1hkrAY7cw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-x64/1.3.36:
|
||||
@ -2232,15 +2215,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm-gnueabihf/1.3.35:
|
||||
resolution: {integrity: sha512-Yie8k00O6O8BCATS/xeKStquV4OYSskUGRDXBQVDw1FrE23PHaSeHCgg4q6iNZjJzXCOJbaTCKnYoIDn9DMf7A==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm-gnueabihf/1.3.36:
|
||||
@ -2249,15 +2223,6 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-gnu/1.3.35:
|
||||
resolution: {integrity: sha512-Zlv3WHa/4x2p51HSvjUWXHfSe1Gl2prqImUZJc8NZOlj75BFzVuR0auhQ+LbwvIQ3gaA1LODX9lyS9wXL3yjxA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-gnu/1.3.36:
|
||||
@ -2266,15 +2231,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-musl/1.3.35:
|
||||
resolution: {integrity: sha512-u6tCYsrSyZ8U+4jLMA/O82veBfLy2aUpn51WxQaeH7wqZGy9TGSJXoO8vWxARQ6b72vjsnKDJHP4MD8hFwcctg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-musl/1.3.36:
|
||||
@ -2283,15 +2239,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-gnu/1.3.35:
|
||||
resolution: {integrity: sha512-Dtxf2IbeH7XlNhP1Qt2/MvUPkpEbn7hhGfpSRs4ot8D3Vf5QEX4S/QtC1OsFWuciiYgHAT1Ybjt4xZic9DSkmA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-gnu/1.3.36:
|
||||
@ -2300,15 +2247,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-musl/1.3.35:
|
||||
resolution: {integrity: sha512-4XavNJ60GprjpTiESCu5daJUnmErixPAqDitJSMu4TV32LNIE8G00S9pDLXinDTW1rgcGtQdq1NLkNRmwwovtg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-musl/1.3.36:
|
||||
@ -2317,15 +2255,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-arm64-msvc/1.3.35:
|
||||
resolution: {integrity: sha512-dNGfKCUSX2M4qVyaS80Lyos0FkXyHRCvrdQ2Y4Hrg3FVokiuw3yY6fLohpUfQ5ws3n2A39dh7jGDeh34+l0sGA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-arm64-msvc/1.3.36:
|
||||
@ -2334,15 +2263,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-ia32-msvc/1.3.35:
|
||||
resolution: {integrity: sha512-ChuPSrDR+JBf7S7dEKPicnG8A3bM0uWPsW2vG+V2wH4iNfNxKVemESHosmYVeEZXqMpomNMvLyeHep1rjRsc0Q==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-ia32-msvc/1.3.36:
|
||||
@ -2351,15 +2271,6 @@ packages:
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-x64-msvc/1.3.35:
|
||||
resolution: {integrity: sha512-/RvphT4WfuGfIK84Ha0dovdPrKB1bW/mc+dtdmhv2E3EGkNc5FoueNwYmXWRimxnU7X0X7IkcRhyKB4G5DeAmg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-x64-msvc/1.3.36:
|
||||
@ -2368,33 +2279,32 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@swc/core/1.3.35:
|
||||
resolution: {integrity: sha512-KmiBin0XSVzJhzX19zTiCqmLslZ40Cl7zqskJcTDeIrRhfgKdiAsxzYUanJgMJIRjYtl9Kcg1V/Ip2o2wL8v3w==}
|
||||
/@swc/core/1.3.36:
|
||||
resolution: {integrity: sha512-Ogrd9uRNIj7nHjXxG66UlKBIcXESUenJ7OD6K2a8p82qlg6ne7Ne5Goiipm/heHYhSfVmjcnRWL9ZJ4gv+YCPA==}
|
||||
engines: {node: '>=10'}
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@swc/core-darwin-arm64': 1.3.35
|
||||
'@swc/core-darwin-x64': 1.3.35
|
||||
'@swc/core-linux-arm-gnueabihf': 1.3.35
|
||||
'@swc/core-linux-arm64-gnu': 1.3.35
|
||||
'@swc/core-linux-arm64-musl': 1.3.35
|
||||
'@swc/core-linux-x64-gnu': 1.3.35
|
||||
'@swc/core-linux-x64-musl': 1.3.35
|
||||
'@swc/core-win32-arm64-msvc': 1.3.35
|
||||
'@swc/core-win32-ia32-msvc': 1.3.35
|
||||
'@swc/core-win32-x64-msvc': 1.3.35
|
||||
'@swc/core-darwin-arm64': 1.3.36
|
||||
'@swc/core-darwin-x64': 1.3.36
|
||||
'@swc/core-linux-arm-gnueabihf': 1.3.36
|
||||
'@swc/core-linux-arm64-gnu': 1.3.36
|
||||
'@swc/core-linux-arm64-musl': 1.3.36
|
||||
'@swc/core-linux-x64-gnu': 1.3.36
|
||||
'@swc/core-linux-x64-musl': 1.3.36
|
||||
'@swc/core-win32-arm64-msvc': 1.3.36
|
||||
'@swc/core-win32-ia32-msvc': 1.3.36
|
||||
'@swc/core-win32-x64-msvc': 1.3.36
|
||||
|
||||
/@swc/jest/0.2.24_@swc+core@1.3.35:
|
||||
/@swc/jest/0.2.24_@swc+core@1.3.36:
|
||||
resolution: {integrity: sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==}
|
||||
engines: {npm: '>= 7.0.0'}
|
||||
peerDependencies:
|
||||
'@swc/core': '*'
|
||||
dependencies:
|
||||
'@jest/create-cache-key-function': 27.5.1
|
||||
'@swc/core': 1.3.35
|
||||
'@swc/core': 1.3.36
|
||||
jsonc-parser: 3.2.0
|
||||
dev: true
|
||||
|
||||
@ -3828,7 +3738,7 @@ packages:
|
||||
/axios/0.24.0:
|
||||
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
@ -3836,7 +3746,7 @@ packages:
|
||||
/axios/0.27.2_debug@4.3.4:
|
||||
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2_debug@4.3.4
|
||||
follow-redirects: 1.15.2
|
||||
form-data: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
@ -6612,7 +6522,7 @@ packages:
|
||||
readable-stream: 2.3.7
|
||||
dev: false
|
||||
|
||||
/follow-redirects/1.15.2_debug@4.3.4:
|
||||
/follow-redirects/1.15.2:
|
||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
@ -6620,8 +6530,6 @@ packages:
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
|
||||
/for-each/0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
@ -13013,6 +12921,7 @@ packages:
|
||||
/vite/4.1.2_hlkwzk2izwsolfmdrejei4vrty:
|
||||
resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@types/node': '>= 14'
|
||||
less: '*'
|
||||
@ -13092,6 +13001,7 @@ packages:
|
||||
|
||||
/vue-tsc/1.1.4_typescript@4.9.5:
|
||||
resolution: {integrity: sha512-CMG8KZsBBPyulYie05XxJCfq/yAPiB/uMMeHmog09aLm2Kml82C6tUSRgQz8ujM4JoCrpDqVCd9G0NuM9aLt1g==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
dependencies:
|
||||
|
Loading…
x
Reference in New Issue
Block a user