Compare commits
190 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3b1669fb6b | ||
![]() |
395e18e584 | ||
![]() |
1c3715a43a | ||
![]() |
e3aa39e050 | ||
![]() |
c4830dcf3a | ||
![]() |
cb35ace047 | ||
![]() |
d8767fa87b | ||
![]() |
5ec10f9ff7 | ||
![]() |
f22c32af05 | ||
![]() |
b31f09692a | ||
![]() |
3a9da78901 | ||
![]() |
dea5e6207e | ||
![]() |
2cd70b80a2 | ||
![]() |
bdaa35d11f | ||
![]() |
b934c738a6 | ||
![]() |
f3164c9cf2 | ||
![]() |
78f061b9db | ||
![]() |
14c2f9e47e | ||
![]() |
b5bf4e75a6 | ||
![]() |
6dcee5aa5c | ||
![]() |
519c8b419b | ||
![]() |
b7f4cb6433 | ||
![]() |
595bf6fc69 | ||
![]() |
36f083c189 | ||
![]() |
f835421d70 | ||
![]() |
756eeb51f3 | ||
![]() |
9f5c8f42e0 | ||
![]() |
212b2c738b | ||
![]() |
92f9392bcf | ||
![]() |
bd8db402e6 | ||
![]() |
d93ad43c49 | ||
![]() |
ab9fcc863f | ||
![]() |
c64b3c9c43 | ||
![]() |
3acfeb1680 | ||
![]() |
e371120c8b | ||
![]() |
43ee600fb3 | ||
![]() |
b6556c7ff1 | ||
![]() |
9d5901a779 | ||
![]() |
59b7b0f832 | ||
![]() |
035ec0a874 | ||
![]() |
9ed6a9701a | ||
![]() |
53d24c2ba1 | ||
![]() |
62226b985a | ||
![]() |
d72ac908f4 | ||
![]() |
00be79ce13 | ||
![]() |
8261321dac | ||
![]() |
4761ff7444 | ||
![]() |
d1f1430b84 | ||
![]() |
39ee039fcb | ||
![]() |
9606ba0454 | ||
![]() |
50e3ca19bc | ||
![]() |
9a1f5afde9 | ||
![]() |
716cb23acb | ||
![]() |
e83dd90e07 | ||
![]() |
66f1aaf5f7 | ||
![]() |
17afbc3c46 | ||
![]() |
09591fa4ae | ||
![]() |
b495f6cfff | ||
![]() |
c3c74c098d | ||
![]() |
4769cd420b | ||
![]() |
5b8d960b9f | ||
![]() |
7dd381bb5c | ||
![]() |
a3c2dbbfb5 | ||
![]() |
e35f599b6d | ||
![]() |
6fc42629c8 | ||
![]() |
a8867a8eea | ||
![]() |
264a6cda8e | ||
![]() |
a675131b80 | ||
![]() |
369660ac79 | ||
![]() |
b3b0a960af | ||
![]() |
1c21cb4d82 | ||
![]() |
85ce00adc0 | ||
![]() |
036017a6af | ||
![]() |
f095863b61 | ||
![]() |
49499f3d7d | ||
![]() |
cbd07cdbe9 | ||
![]() |
b123cbca58 | ||
![]() |
61d8b56eee | ||
![]() |
e9a97b4717 | ||
![]() |
01d7403dc4 | ||
![]() |
8f3ca867d2 | ||
![]() |
d7222dd56a | ||
![]() |
f25518af91 | ||
![]() |
3b69a563f8 | ||
![]() |
0331f3c61b | ||
![]() |
2dae56fc8f | ||
![]() |
bec2d9e3fa | ||
![]() |
da92988fb8 | ||
![]() |
77d4d6e377 | ||
![]() |
b796aacf7f | ||
![]() |
a974ab00d7 | ||
![]() |
4352331b70 | ||
![]() |
e4453e9ca8 | ||
![]() |
3811b90150 | ||
![]() |
003f592ef6 | ||
![]() |
a3f3ef4226 | ||
![]() |
fbb0cc686e | ||
![]() |
c1c8c9c37c | ||
![]() |
ff24811676 | ||
![]() |
ab3bc4a982 | ||
![]() |
b6e4ec7056 | ||
![]() |
5619a3390d | ||
![]() |
e9fd064624 | ||
![]() |
274bfc965f | ||
![]() |
672ceb8687 | ||
![]() |
a3a9b7fbd3 | ||
![]() |
57e533a5ef | ||
![]() |
4f9b03a997 | ||
![]() |
01d07edfe3 | ||
![]() |
4c8a1867f0 | ||
![]() |
7d63118941 | ||
![]() |
aa5eab746a | ||
![]() |
3d0870f414 | ||
![]() |
92e8a5dbd6 | ||
![]() |
113df68843 | ||
![]() |
92792719bd | ||
![]() |
47186c0fff | ||
![]() |
eb73a8137d | ||
![]() |
7cb5b5c8c2 | ||
![]() |
6f45208ab6 | ||
![]() |
165c4b2c00 | ||
![]() |
a4b5a0072d | ||
![]() |
ddc899938a | ||
![]() |
77c2a7cd71 | ||
![]() |
de24131993 | ||
![]() |
7b7fe019c0 | ||
![]() |
c30ffec1af | ||
![]() |
44f560b453 | ||
![]() |
5fa8c62305 | ||
![]() |
17500fc9c9 | ||
![]() |
e3bad795e0 | ||
![]() |
1ba559a98b | ||
![]() |
3053767c71 | ||
![]() |
f2e91f4d62 | ||
![]() |
10f4815d34 | ||
![]() |
d43eb123b1 | ||
![]() |
800bbc4328 | ||
![]() |
7a43cac6b3 | ||
![]() |
fa5140310f | ||
![]() |
1dec3461cd | ||
![]() |
0ddabdbf68 | ||
![]() |
d78faf1134 | ||
![]() |
cb00786f1e | ||
![]() |
61e26696aa | ||
![]() |
f3b0c6f1e7 | ||
![]() |
242538ddce | ||
![]() |
64be9baed0 | ||
![]() |
bce48dfee9 | ||
![]() |
e365139961 | ||
![]() |
719c438b41 | ||
![]() |
5948a9da0f | ||
![]() |
db21be3282 | ||
![]() |
096b306bc5 | ||
![]() |
e30a03b5c4 | ||
![]() |
21d22200a3 | ||
![]() |
53227d76d6 | ||
![]() |
9cc08aebbe | ||
![]() |
ee9bb8286e | ||
![]() |
ae92378689 | ||
![]() |
714c80bf3f | ||
![]() |
947f079735 | ||
![]() |
c771135fd8 | ||
![]() |
ad970dffda | ||
![]() |
dd4f7be3da | ||
![]() |
0bcfa2d04f | ||
![]() |
170b1b89ba | ||
![]() |
b08ead1dce | ||
![]() |
05a342009f | ||
![]() |
d7247e2db2 | ||
![]() |
4550a4459b | ||
![]() |
660781afd9 | ||
![]() |
1557d0afb8 | ||
![]() |
d8264b11e2 | ||
![]() |
a5648fb07f | ||
![]() |
43316ec355 | ||
![]() |
18206e3cf6 | ||
![]() |
9107de63b4 | ||
![]() |
bbe4824955 | ||
![]() |
e7f4ec72b4 | ||
![]() |
5cdb9fb748 | ||
![]() |
83ebe79a3f | ||
![]() |
7f808eaf42 | ||
![]() |
fbd6b90bf8 | ||
![]() |
d92200a6d6 | ||
![]() |
c20311b8a7 | ||
![]() |
111d4d0149 | ||
![]() |
49012f8352 | ||
![]() |
53e54c22fa | ||
![]() |
75d516011b | ||
![]() |
522ddba3d7 |
81
CHANGELOG.md
81
CHANGELOG.md
@@ -2,6 +2,7 @@
|
|||||||
## 12.x.x (unreleased)
|
## 12.x.x (unreleased)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
- Client: Preferences Registry
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
-
|
-
|
||||||
@@ -9,6 +10,86 @@
|
|||||||
You should also include the user name that made the change.
|
You should also include the user name that made the change.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 12.118.0 (2022/08/07)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Client: 設定のバックアップ/リストア機能
|
||||||
|
- Client: Add vi-VN language support
|
||||||
|
- Client: Add unix time widget @syuilo
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Server: リモートユーザーを正しくブロックできるように修正する @xianonn
|
||||||
|
- Client: 一度作ったwebhookの設定画面を開こうとするとページがフリーズする @syuilo
|
||||||
|
- Client: MiAuth認証ページが機能していない @syuilo
|
||||||
|
- Client: 一部のアプリからファイルを投稿フォームへドロップできない場合がある問題を修正 @m-hayabusa
|
||||||
|
|
||||||
|
## 12.117.1 (2022/07/19)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Client: UIのブラッシュアップ @syuilo
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Server: ファイルのアップロードに失敗することがある問題を修正 @acid-chicken
|
||||||
|
- Client: リアクションピッカーがアプリ内ウィンドウの後ろに表示されてしまう問題を修正 @syuilo
|
||||||
|
- Client: ユーザー情報の取得の再試行を修正 @xianonn
|
||||||
|
- Client: MFMチートシートの挙動を修正 @syuilo
|
||||||
|
- Client: 「インスタンスからのお知らせを受け取る」の設定を変更できない問題を修正 @syuilo
|
||||||
|
|
||||||
|
## 12.117.0 (2022/07/18)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Client: ウィンドウを最大化できるように @syuilo
|
||||||
|
- Client: Shiftキーを押した状態でリンクをクリックするとアプリ内ウィンドウで開くように @syuilo
|
||||||
|
- Client: デッキを使用している際、Ctrlキーを押した状態でリンクをクリックするとページ遷移を強制できるように @syuilo
|
||||||
|
- Client: UIのブラッシュアップ @syuilo
|
||||||
|
|
||||||
|
## 12.116.1 (2022/07/17)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Client: デッキUI時に ページで表示 ボタンが機能しない問題を修正 @syuilo
|
||||||
|
- Error During Migration Run to 12.111.x
|
||||||
|
|
||||||
|
## 12.116.0 (2022/07/16)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Client: registry editor @syuilo
|
||||||
|
- Client: UIのブラッシュアップ @syuilo
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Error During Migration Run to 12.111.x
|
||||||
|
- Server: TypeError: Cannot convert undefined or null to object @syuilo
|
||||||
|
|
||||||
|
## 12.115.0 (2022/07/16)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Client: Deckのプロファイル切り替えを簡単に @syuilo
|
||||||
|
- Client: UIのブラッシュアップ @syuilo
|
||||||
|
|
||||||
|
## 12.114.0 (2022/07/15)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- RSSティッカーで表示順序をシャッフルできるように @syuilo
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- クライアントが起動しなくなることがある問題を修正 @syuilo
|
||||||
|
|
||||||
|
## 12.113.0 (2022/07/13)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Support <plain> syntax for MFM
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Server: Fix crash at startup if TensorFlow is not supported @mei23
|
||||||
|
- Client: URLエンコードされたルーティングを修正
|
||||||
|
|
||||||
|
## 12.112.3 (2022/07/09)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Make active email validation configurable
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Server: Fix Attempts to update all notifications @mei23
|
||||||
|
|
||||||
## 12.112.2 (2022/07/08)
|
## 12.112.2 (2022/07/08)
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
@@ -140,6 +140,34 @@ Misskey uses Vue(v3) as its front-end framework.
|
|||||||
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
||||||
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
||||||
|
|
||||||
|
## nirax
|
||||||
|
niraxは、Misskeyで使用しているオリジナルのフロントエンドルーティングシステムです。
|
||||||
|
**vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。**
|
||||||
|
|
||||||
|
### ルート定義
|
||||||
|
ルート定義は、以下の形式のオブジェクトの配列です。
|
||||||
|
|
||||||
|
``` ts
|
||||||
|
{
|
||||||
|
name?: string;
|
||||||
|
path: string;
|
||||||
|
component: Component;
|
||||||
|
query?: Record<string, string>;
|
||||||
|
loginRequired?: boolean;
|
||||||
|
hash?: string;
|
||||||
|
globalCacheKey?: string;
|
||||||
|
children?: RouteDef[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Warning**
|
||||||
|
> 現状、ルートは定義された順に評価されます。
|
||||||
|
> たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。
|
||||||
|
|
||||||
|
### 複数のルーター
|
||||||
|
vue-routerとの最大の違いは、niraxは複数のルーターが存在することを許可している点です。
|
||||||
|
これにより、アプリ内ウィンドウでブラウザとは個別にルーティングすることなどが可能になります。
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
### How to resolve conflictions occurred at yarn.lock?
|
### How to resolve conflictions occurred at yarn.lock?
|
||||||
|
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "ابحث عن مستخدمين"
|
|||||||
reply: "رد"
|
reply: "رد"
|
||||||
loadMore: "عرض المزيد"
|
loadMore: "عرض المزيد"
|
||||||
showMore: "عرض المزيد"
|
showMore: "عرض المزيد"
|
||||||
|
showLess: "اغلق"
|
||||||
youGotNewFollower: "يتابعك"
|
youGotNewFollower: "يتابعك"
|
||||||
receiveFollowRequest: "تلقيت طلب متابعة"
|
receiveFollowRequest: "تلقيت طلب متابعة"
|
||||||
followRequestAccepted: "قُبل طلب المتابعة"
|
followRequestAccepted: "قُبل طلب المتابعة"
|
||||||
@@ -804,6 +805,11 @@ oneDay: "يوم"
|
|||||||
oneWeek: "أسبوع"
|
oneWeek: "أسبوع"
|
||||||
failedToFetchAccountInformation: "تعذر جلب معلومات الحساب"
|
failedToFetchAccountInformation: "تعذر جلب معلومات الحساب"
|
||||||
file: "الملفات"
|
file: "الملفات"
|
||||||
|
reverse: "اقلب"
|
||||||
|
colored: "ملوّن"
|
||||||
|
label: "التسمية"
|
||||||
|
localOnly: "المحلي فقط"
|
||||||
|
account: "الحسابات"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "هذا البريد الإلكتروني مستخدم"
|
used: "هذا البريد الإلكتروني مستخدم"
|
||||||
format: "صيغة البريد الإلكتروني غير صالحة"
|
format: "صيغة البريد الإلكتروني غير صالحة"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "ব্যবহারকারী খুঁজুন..."
|
|||||||
reply: "জবাব"
|
reply: "জবাব"
|
||||||
loadMore: "আরও দেখুন"
|
loadMore: "আরও দেখুন"
|
||||||
showMore: "আরও দেখুন"
|
showMore: "আরও দেখুন"
|
||||||
|
showLess: "বন্ধ"
|
||||||
youGotNewFollower: "আপনাকে অনুসরণ করছে"
|
youGotNewFollower: "আপনাকে অনুসরণ করছে"
|
||||||
receiveFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
receiveFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
||||||
followRequestAccepted: "অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
followRequestAccepted: "অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
||||||
@@ -844,6 +845,11 @@ reflectMayTakeTime: "এটির কাজ দেখা যেতে কিছ
|
|||||||
failedToFetchAccountInformation: "অ্যাকাউন্টের তথ্য উদ্ধার করা যায়নি"
|
failedToFetchAccountInformation: "অ্যাকাউন্টের তথ্য উদ্ধার করা যায়নি"
|
||||||
rateLimitExceeded: "রেট লিমিট ছাড়িয়ে গেছে "
|
rateLimitExceeded: "রেট লিমিট ছাড়িয়ে গেছে "
|
||||||
file: "ফাইলগুলি"
|
file: "ফাইলগুলি"
|
||||||
|
reverse: "উল্টান"
|
||||||
|
colored: "রঙ্গিন"
|
||||||
|
label: "লেবেল"
|
||||||
|
localOnly: "শুধুমাত্র লোকাল"
|
||||||
|
account: "অ্যাকাউন্টগুলি"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
|
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
|
||||||
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
|
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
|
||||||
@@ -1640,6 +1646,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "সর্বদা মেইন কলাম দেখান"
|
alwaysShowMainColumn: "সর্বদা মেইন কলাম দেখান"
|
||||||
columnAlign: "কলাম সাজান"
|
columnAlign: "কলাম সাজান"
|
||||||
addColumn: "কলাম যুক্ত করুন"
|
addColumn: "কলাম যুক্ত করুন"
|
||||||
|
configureColumn: "কলাম সেটিংস"
|
||||||
swapLeft: "বামে সরান"
|
swapLeft: "বামে সরান"
|
||||||
swapRight: "ডানে সরান"
|
swapRight: "ডানে সরান"
|
||||||
swapUp: "উপরে উঠান"
|
swapUp: "উপরে উঠান"
|
||||||
|
@@ -111,6 +111,14 @@ reactionSettingDescription2: "Arrossega per reordenar, fes clic per suprimir, pr
|
|||||||
rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes"
|
rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes"
|
||||||
attachCancel: "Eliminar el fitxer adjunt"
|
attachCancel: "Eliminar el fitxer adjunt"
|
||||||
markAsSensitive: "Marcar com a NSFW"
|
markAsSensitive: "Marcar com a NSFW"
|
||||||
|
unmarkAsSensitive: "Deixar de marcar com a sensible"
|
||||||
|
enterFileName: "Defineix nom del fitxer"
|
||||||
|
mute: "Silencia"
|
||||||
|
unmute: "Deixa de silenciar"
|
||||||
|
block: "Bloqueja"
|
||||||
|
unblock: "Desbloqueja"
|
||||||
|
suspend: "Suspèn"
|
||||||
|
unsuspend: "Deixa de suspendre"
|
||||||
instances: "Instàncies"
|
instances: "Instàncies"
|
||||||
remove: "Eliminar"
|
remove: "Eliminar"
|
||||||
nsfw: "NSFW"
|
nsfw: "NSFW"
|
||||||
@@ -148,6 +156,8 @@ _profile:
|
|||||||
username: "Nom d'usuari"
|
username: "Nom d'usuari"
|
||||||
_exportOrImport:
|
_exportOrImport:
|
||||||
followingList: "Seguint"
|
followingList: "Seguint"
|
||||||
|
muteList: "Silencia"
|
||||||
|
blockingList: "Bloqueja"
|
||||||
userLists: "Llistes"
|
userLists: "Llistes"
|
||||||
_pages:
|
_pages:
|
||||||
script:
|
script:
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Vyhledat uživatele"
|
|||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
loadMore: "Zobrazit více"
|
loadMore: "Zobrazit více"
|
||||||
showMore: "Zobrazit více"
|
showMore: "Zobrazit více"
|
||||||
|
showLess: "Zavřít"
|
||||||
youGotNewFollower: "Máte nového následovníka"
|
youGotNewFollower: "Máte nového následovníka"
|
||||||
receiveFollowRequest: "Žádost o sledování přijata"
|
receiveFollowRequest: "Žádost o sledování přijata"
|
||||||
followRequestAccepted: "Žádost o sledování přijata"
|
followRequestAccepted: "Žádost o sledování přijata"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Nach einem Benutzer suchen"
|
|||||||
reply: "Antworten"
|
reply: "Antworten"
|
||||||
loadMore: "Mehr laden"
|
loadMore: "Mehr laden"
|
||||||
showMore: "Mehr anzeigen"
|
showMore: "Mehr anzeigen"
|
||||||
|
showLess: "Schließen"
|
||||||
youGotNewFollower: "ist dir gefolgt"
|
youGotNewFollower: "ist dir gefolgt"
|
||||||
receiveFollowRequest: "Follow-Anfrage erhalten"
|
receiveFollowRequest: "Follow-Anfrage erhalten"
|
||||||
followRequestAccepted: "Follow-Anfrage akzeptiert"
|
followRequestAccepted: "Follow-Anfrage akzeptiert"
|
||||||
@@ -561,6 +562,7 @@ author: "Autor"
|
|||||||
leaveConfirm: "Es gibt unspeicherte Änderungen. Möchtest du diese verwerfen?"
|
leaveConfirm: "Es gibt unspeicherte Änderungen. Möchtest du diese verwerfen?"
|
||||||
manage: "Verwaltung"
|
manage: "Verwaltung"
|
||||||
plugins: "Plugins"
|
plugins: "Plugins"
|
||||||
|
preferencesBackups: "Einstellungsbackups"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Deck verlassen"
|
undeck: "Deck verlassen"
|
||||||
useBlurEffectForModal: "Weichzeichnungseffekt für Modals verwenden"
|
useBlurEffectForModal: "Weichzeichnungseffekt für Modals verwenden"
|
||||||
@@ -862,13 +864,43 @@ requireAdminForView: "Melde dich mit einem Administratorkonto an, um dies einzus
|
|||||||
isSystemAccount: "Ein Benutzerkonto, dass durch das System erstellt und automatisch kontrolliert wird."
|
isSystemAccount: "Ein Benutzerkonto, dass durch das System erstellt und automatisch kontrolliert wird."
|
||||||
typeToConfirm: "Bitte gib zur Bestätigung {x} ein"
|
typeToConfirm: "Bitte gib zur Bestätigung {x} ein"
|
||||||
deleteAccount: "Benutzerkonto löschen"
|
deleteAccount: "Benutzerkonto löschen"
|
||||||
document: "Dokument"
|
document: "Dokumentation"
|
||||||
numberOfPageCache: "Seitencachegröße"
|
numberOfPageCache: "Seitencachegröße"
|
||||||
numberOfPageCacheDescription: "Das Erhöhen dieses Caches führt zu einer angenehmerern Benutzererfahrung, erhöht aber Serverlast und Arbeitsspeicherauslastung."
|
numberOfPageCacheDescription: "Das Erhöhen dieses Caches führt zu einer angenehmerern Benutzererfahrung, erhöht aber Serverlast und Arbeitsspeicherauslastung."
|
||||||
logoutConfirm: "Wirklich abmelden?"
|
logoutConfirm: "Wirklich abmelden?"
|
||||||
lastActiveDate: "Zuletzt verwendet am"
|
lastActiveDate: "Zuletzt verwendet am"
|
||||||
statusbar: "Statusleiste"
|
statusbar: "Statusleiste"
|
||||||
pleaseSelect: "Wähle eine Option"
|
pleaseSelect: "Wähle eine Option"
|
||||||
|
reverse: "Umkehren"
|
||||||
|
colored: "Farbig"
|
||||||
|
refreshInterval: "Aktualisierungsrate"
|
||||||
|
label: "Beschriftung"
|
||||||
|
type: "Art"
|
||||||
|
speed: "Geschwindigkeit"
|
||||||
|
slow: "Langsam"
|
||||||
|
fast: "Schnell"
|
||||||
|
sensitiveMediaDetection: "Erkennung von NSFW-Medien"
|
||||||
|
localOnly: "Nur Lokal"
|
||||||
|
remoteOnly: "Nur für fremde Instanzen"
|
||||||
|
failedToUpload: "Hochladen fehlgeschlagen"
|
||||||
|
cannotUploadBecauseInappropriate: "Diese Datei kann nicht hochgeladen werden, da Anteile der Datei als möglicherweise NSFW festgestellt wurden."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "Die Datei konnte nicht hochgeladen werden, da dein Drive-Speicherplatz aufgebraucht ist."
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "NSFW-Automarkierung"
|
||||||
|
enableAutoSensitiveDescription: "Setzt soweit möglich durch Verwendung von Machine Learning automatisch NSFW-Markierungen für Medien, die NSFW-Anteile beinhalten. Auch wenn du diese Option deaktiviert hast, ist sie möglicherweise auf Instanzebene aktiviert."
|
||||||
|
activeEmailValidationDescription: "Aktivert strengere Überprüfung von E-Mail-Adressen, d.h. Testen auf Wegwerfadressen und darauf, ob mit der Adresse tatsächlich kommuniziert werden kann. Ist dies deaktiviert, so wird nur das Format der E-Mail überprüft."
|
||||||
|
navbar: "Navigationsleiste"
|
||||||
|
shuffle: "Mischen"
|
||||||
|
account: "Benutzerkonto"
|
||||||
|
move: "Verschieben"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Ermöglicht eine Erleichterung der Servermoderation durch die automatische Erkennungen von NSFW-Medien unter Verwendung von Machine Learning. Hierdurch wird die Serverlast etwas erhöht."
|
||||||
|
sensitivity: "Erkennungssensitivität"
|
||||||
|
sensitivityDescription: "Durch das Senken der Sensitivität kann die Anzahl an Fehlerkennungen (sog. false positives) reduziert werden. Durch ein Erhöhen dieser kann die Anzahl an verpassten Erkennungen (sog. false negatives) reduziert werden."
|
||||||
|
setSensitiveFlagAutomatically: "Als NSFW markieren"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "Die Resultate der internen Erkennung werden beibehalten, auch wenn diese Option deaktiviert ist."
|
||||||
|
analyzeVideos: "Videoanalyse aktivieren"
|
||||||
|
analyzeVideosDescription: "Analysiert zusätzlich zu Bildern auch Videos. Die Last des Servers wird hierdurch etwas erhöht."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Diese Email-Adresse wird bereits verwendet"
|
used: "Diese Email-Adresse wird bereits verwendet"
|
||||||
format: "Das Format dieser Email-Adresse ist ungültig"
|
format: "Das Format dieser Email-Adresse ist ungültig"
|
||||||
@@ -911,6 +943,24 @@ _plugin:
|
|||||||
install: "Plugins installieren"
|
install: "Plugins installieren"
|
||||||
installWarn: "Installiere bitte nur vertrauenswürdige Plugins."
|
installWarn: "Installiere bitte nur vertrauenswürdige Plugins."
|
||||||
manage: "Plugins verwalten"
|
manage: "Plugins verwalten"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "Erstellte Backups"
|
||||||
|
saveNew: "Neu erstellen"
|
||||||
|
loadFile: "Von Datei laden"
|
||||||
|
apply: "Auf dieses Gerät anwenden"
|
||||||
|
save: "Speichern"
|
||||||
|
inputName: "Gib einen Namen für dieses Backup ein"
|
||||||
|
cannotSave: "Speichern fehlgeschlagen"
|
||||||
|
nameAlreadyExists: "Es existiert bereits ein Backup unter dem Namen \"{name}\". Bitte gib einen anderen Namen ein."
|
||||||
|
applyConfirm: "Wirklich das Backup \"{name}\" auf dieses Gerät anwenden? Bestehende Einstellungen darauf werden überschrieben."
|
||||||
|
saveConfirm: "Als {name} speichern?"
|
||||||
|
deleteConfirm: "Das Backup {name} löschen?"
|
||||||
|
renameConfirm: "Soll dieses Backup von \"{old}\" zu \"{new}\" umbenannt werden?"
|
||||||
|
noBackups: "Keine Backups existieren. Backups können über \"Neu erstellen\" erstelllt werden."
|
||||||
|
createdAt: "Erstellt am: {date} {time}"
|
||||||
|
updatedAt: "Aktualisiert am: {date} {time}"
|
||||||
|
cannotLoad: "Laden fehlgeschlagen"
|
||||||
|
invalidFile: "Ungültiges Dateiformat."
|
||||||
_registry:
|
_registry:
|
||||||
scope: "Scope"
|
scope: "Scope"
|
||||||
key: "Schlüssel"
|
key: "Schlüssel"
|
||||||
@@ -994,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "Verleiht Inhalt einen glitzernden Partikeleffekt."
|
sparkleDescription: "Verleiht Inhalt einen glitzernden Partikeleffekt."
|
||||||
rotate: "Drehen"
|
rotate: "Drehen"
|
||||||
rotateDescription: "Dreht den Inhalt um einen angegebenen Winkel."
|
rotateDescription: "Dreht den Inhalt um einen angegebenen Winkel."
|
||||||
|
plain: "Schlicht"
|
||||||
|
plainDescription: "Deaktiviert jegliche MFM-Syntax, die sich innerhalb dieses MFM-Effekts befindet."
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "Nie anzeigen"
|
none: "Nie anzeigen"
|
||||||
remote: "Für Benutzer fremder Instanzen anzeigen"
|
remote: "Für Benutzer fremder Instanzen anzeigen"
|
||||||
@@ -1227,6 +1279,7 @@ _widgets:
|
|||||||
activity: "Aktivität"
|
activity: "Aktivität"
|
||||||
photos: "Fotos"
|
photos: "Fotos"
|
||||||
digitalClock: "Digitaluhr"
|
digitalClock: "Digitaluhr"
|
||||||
|
unixClock: "UNIX-Uhr"
|
||||||
federation: "Föderation"
|
federation: "Föderation"
|
||||||
instanceCloud: "Instanzwolke"
|
instanceCloud: "Instanzwolke"
|
||||||
postForm: "Notizfenster"
|
postForm: "Notizfenster"
|
||||||
@@ -1667,6 +1720,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Hauptspalte immer zeigen"
|
alwaysShowMainColumn: "Hauptspalte immer zeigen"
|
||||||
columnAlign: "Spaltenausrichtung"
|
columnAlign: "Spaltenausrichtung"
|
||||||
addColumn: "Spalte hinzufügen"
|
addColumn: "Spalte hinzufügen"
|
||||||
|
configureColumn: "Spalteneinstellungen"
|
||||||
swapLeft: "Mit linker Spalte tauschen"
|
swapLeft: "Mit linker Spalte tauschen"
|
||||||
swapRight: "Mit rechter Spalte tauschen"
|
swapRight: "Mit rechter Spalte tauschen"
|
||||||
swapUp: "Mit oberer Spalte tauschen"
|
swapUp: "Mit oberer Spalte tauschen"
|
||||||
@@ -1674,6 +1728,8 @@ _deck:
|
|||||||
stackLeft: "Auf linke Spalte stapeln"
|
stackLeft: "Auf linke Spalte stapeln"
|
||||||
popRight: "Nach rechts vom Stapel nehmen"
|
popRight: "Nach rechts vom Stapel nehmen"
|
||||||
profile: "Profil"
|
profile: "Profil"
|
||||||
|
newProfile: "Neues Profil"
|
||||||
|
deleteProfile: "Profil löschen"
|
||||||
introduction: "Erstelle eine auf dich zugeschneiderte Benutzeroberfläche durch das Aneinanderreihen von Spalten!"
|
introduction: "Erstelle eine auf dich zugeschneiderte Benutzeroberfläche durch das Aneinanderreihen von Spalten!"
|
||||||
introduction2: "Klicke auf das + rechts um wann immer du möchtest neue Spalten hinzuzufügen."
|
introduction2: "Klicke auf das + rechts um wann immer du möchtest neue Spalten hinzuzufügen."
|
||||||
widgetsIntroduction: "Drücke bitte \"Widgets bearbeiten\" im Spaltenmenü und füge ein Widget hinzu."
|
widgetsIntroduction: "Drücke bitte \"Widgets bearbeiten\" im Spaltenmenü und füge ein Widget hinzu."
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Search for a user"
|
|||||||
reply: "Reply"
|
reply: "Reply"
|
||||||
loadMore: "Load more"
|
loadMore: "Load more"
|
||||||
showMore: "Show more"
|
showMore: "Show more"
|
||||||
|
showLess: "Close"
|
||||||
youGotNewFollower: "followed you"
|
youGotNewFollower: "followed you"
|
||||||
receiveFollowRequest: "Follow request received"
|
receiveFollowRequest: "Follow request received"
|
||||||
followRequestAccepted: "Follow request accepted"
|
followRequestAccepted: "Follow request accepted"
|
||||||
@@ -561,6 +562,7 @@ author: "Author"
|
|||||||
leaveConfirm: "There are unsaved changes. Do you want to discard them?"
|
leaveConfirm: "There are unsaved changes. Do you want to discard them?"
|
||||||
manage: "Management"
|
manage: "Management"
|
||||||
plugins: "Plugins"
|
plugins: "Plugins"
|
||||||
|
preferencesBackups: "Preference backups"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Leave Deck"
|
undeck: "Leave Deck"
|
||||||
useBlurEffectForModal: "Use blur effect for modals"
|
useBlurEffectForModal: "Use blur effect for modals"
|
||||||
@@ -862,13 +864,43 @@ requireAdminForView: "You must log in with an administrator account to view this
|
|||||||
isSystemAccount: "An account created and automatically operated by the system."
|
isSystemAccount: "An account created and automatically operated by the system."
|
||||||
typeToConfirm: "Please enter {x} to confirm"
|
typeToConfirm: "Please enter {x} to confirm"
|
||||||
deleteAccount: "Delete account"
|
deleteAccount: "Delete account"
|
||||||
document: "Document"
|
document: "Documentation"
|
||||||
numberOfPageCache: "Number of cached pages"
|
numberOfPageCache: "Number of cached pages"
|
||||||
numberOfPageCacheDescription: "Increasing this number will improve convenience for users but cause more server load as well as more memory to be used."
|
numberOfPageCacheDescription: "Increasing this number will improve convenience for users but cause more server load as well as more memory to be used."
|
||||||
logoutConfirm: "Really log out?"
|
logoutConfirm: "Really log out?"
|
||||||
lastActiveDate: "Last used at"
|
lastActiveDate: "Last used at"
|
||||||
statusbar: "Status bar"
|
statusbar: "Status bar"
|
||||||
pleaseSelect: "Select an option"
|
pleaseSelect: "Select an option"
|
||||||
|
reverse: "Reverse"
|
||||||
|
colored: "Colored"
|
||||||
|
refreshInterval: "Update interval "
|
||||||
|
label: "Label"
|
||||||
|
type: "Type"
|
||||||
|
speed: "Speed"
|
||||||
|
slow: "Slow"
|
||||||
|
fast: "Fast"
|
||||||
|
sensitiveMediaDetection: "Detection of NSFW media"
|
||||||
|
localOnly: "Local only"
|
||||||
|
remoteOnly: "Remote only"
|
||||||
|
failedToUpload: "Upload failed"
|
||||||
|
cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of it have been detected as potentially NSFW."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity."
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "Automatic NSFW-Marking"
|
||||||
|
enableAutoSensitiveDescription: "Allows automatic detection and marking of NSFW media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide."
|
||||||
|
activeEmailValidationDescription: "Enables stricter validation of email addresses, which includes checking for disposable addresses and by whether it can actually be communicated with. When unchecked, only the format of the email is validated."
|
||||||
|
navbar: "Navigation bar"
|
||||||
|
shuffle: "Shuffle"
|
||||||
|
account: "Account"
|
||||||
|
move: "Move"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Reduces the effort of server moderation through automatically recognizing NSFW media via Machine Learning. This will slightly increase the load on the server."
|
||||||
|
sensitivity: "Detection sensitivity"
|
||||||
|
sensitivityDescription: "Reducing the sensitivity will lead to fewer misdetections (false positives) whereas increasing it will lead to fewer missed detections (false negatives)."
|
||||||
|
setSensitiveFlagAutomatically: "Mark as NSFW"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "The results of the internal detection will be retained even if this option is turned off."
|
||||||
|
analyzeVideos: "Enable analysis of videos"
|
||||||
|
analyzeVideosDescription: "Analyzes videos in addition to images. This will slightly increase the load on the server."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "This email address is already being used"
|
used: "This email address is already being used"
|
||||||
format: "The format of this email address is invalid"
|
format: "The format of this email address is invalid"
|
||||||
@@ -911,6 +943,24 @@ _plugin:
|
|||||||
install: "Install plugins"
|
install: "Install plugins"
|
||||||
installWarn: "Please do not install untrustworthy plugins."
|
installWarn: "Please do not install untrustworthy plugins."
|
||||||
manage: "Manage plugins"
|
manage: "Manage plugins"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "Created backups"
|
||||||
|
saveNew: "Save new backup"
|
||||||
|
loadFile: "Load from file"
|
||||||
|
apply: "Apply to this device"
|
||||||
|
save: "Save changes"
|
||||||
|
inputName: "Please enter a name for this backup"
|
||||||
|
cannotSave: "Saving failed"
|
||||||
|
nameAlreadyExists: "A backup called \"{name}\" already exists. Please enter a different name."
|
||||||
|
applyConfirm: "Do you really want to apply the \"{name}\" backup to this device? Existing settings of this device will be overwritten."
|
||||||
|
saveConfirm: "Save backup as {name}?"
|
||||||
|
deleteConfirm: "Delete the {name} backup?"
|
||||||
|
renameConfirm: "Rename this backup from \"{old}\" to \"{new}\"?"
|
||||||
|
noBackups: "No backups exist. You may backup your client settings on this server by using \"Create new backup\"."
|
||||||
|
createdAt: "Created at: {date} {time}"
|
||||||
|
updatedAt: "Updated at: {date} {time}"
|
||||||
|
cannotLoad: "Loading failed"
|
||||||
|
invalidFile: "Invalid file format"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "Scope"
|
scope: "Scope"
|
||||||
key: "Key"
|
key: "Key"
|
||||||
@@ -994,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "Gives content a sparkling particle effect."
|
sparkleDescription: "Gives content a sparkling particle effect."
|
||||||
rotate: "Rotate"
|
rotate: "Rotate"
|
||||||
rotateDescription: "Turns content by a specified angle."
|
rotateDescription: "Turns content by a specified angle."
|
||||||
|
plain: "Plain"
|
||||||
|
plainDescription: "Deactivates the effects of all MFM contained within this MFM effect."
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "Never show"
|
none: "Never show"
|
||||||
remote: "Show for remote users"
|
remote: "Show for remote users"
|
||||||
@@ -1227,6 +1279,7 @@ _widgets:
|
|||||||
activity: "Activity"
|
activity: "Activity"
|
||||||
photos: "Photos"
|
photos: "Photos"
|
||||||
digitalClock: "Digital clock"
|
digitalClock: "Digital clock"
|
||||||
|
unixClock: "UNIX clock"
|
||||||
federation: "Federation"
|
federation: "Federation"
|
||||||
instanceCloud: "Instance cloud"
|
instanceCloud: "Instance cloud"
|
||||||
postForm: "Posting form"
|
postForm: "Posting form"
|
||||||
@@ -1667,6 +1720,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Always show main column"
|
alwaysShowMainColumn: "Always show main column"
|
||||||
columnAlign: "Align columns"
|
columnAlign: "Align columns"
|
||||||
addColumn: "Add column"
|
addColumn: "Add column"
|
||||||
|
configureColumn: "Column settings"
|
||||||
swapLeft: "Swap with the left column"
|
swapLeft: "Swap with the left column"
|
||||||
swapRight: "Swap with the right column"
|
swapRight: "Swap with the right column"
|
||||||
swapUp: "Swap with the above column"
|
swapUp: "Swap with the above column"
|
||||||
@@ -1674,6 +1728,8 @@ _deck:
|
|||||||
stackLeft: "Stack with the left column"
|
stackLeft: "Stack with the left column"
|
||||||
popRight: "Pop column to the right"
|
popRight: "Pop column to the right"
|
||||||
profile: "Profile"
|
profile: "Profile"
|
||||||
|
newProfile: "New profile"
|
||||||
|
deleteProfile: "Delete profile"
|
||||||
introduction: "Create the perfect interface for you by arranging columns freely!"
|
introduction: "Create the perfect interface for you by arranging columns freely!"
|
||||||
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
|
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
|
||||||
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
|
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
---
|
---
|
||||||
_lang_: "Español"
|
_lang_: "Español"
|
||||||
headlineMisskey: "Red conectada por notas"
|
headlineMisskey: "Red conectada por notas"
|
||||||
introMisskey: "¡Bienvenido/a! Misskey es un servicio de microblogging descentralizado de código abierto.\nEscribe \"notas\" para compartir lo que te ocurre ahora o para contar sobre ti a todos 📡\nCon la función de \"reacciones\", puedes también añadir una reacción rápida a las notas de todos 👍\nExplora un nuevo mundo 🚀"
|
introMisskey: "¡Bienvenido/a! Misskey es un servicio de microblogging descentralizado de código abierto.\nEscribe \"notas\" para compartir lo que te ocurre ahora o para contar sobre ti a todos 📡\nCon la función de \"reacciones\", puedes también añadir una reacción rápida a las notas de todos 👍\n¡Exploremos juntos un nuevo mundo! 🚀"
|
||||||
monthAndDay: "{day}/{month}"
|
monthAndDay: "{day}/{month}"
|
||||||
search: "Buscar"
|
search: "Buscar"
|
||||||
notifications: "Notificaciones"
|
notifications: "Notificaciones"
|
||||||
username: "Nombre de usuario"
|
username: "Nombre de usuario"
|
||||||
password: "Contraseña"
|
password: "Contraseña"
|
||||||
forgotPassword: "Olvidé mi Contraseña"
|
forgotPassword: "Olvidé mi Contraseña"
|
||||||
fetchingAsApObject: "Buscando en el fediverso"
|
fetchingAsApObject: "Recuperando desde el Fediverso..."
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
gotIt: "Entendido"
|
gotIt: "¡Lo tengo!"
|
||||||
cancel: "Cancelar"
|
cancel: "Cancelar"
|
||||||
enterUsername: "Introduce el nombre de usuario"
|
enterUsername: "Introduce el nombre de usuario"
|
||||||
renotedBy: "Renotado por {user}"
|
renotedBy: "Renotado por {user}"
|
||||||
@@ -22,36 +22,37 @@ basicSettings: "Configuración Básica"
|
|||||||
otherSettings: "Configuración avanzada"
|
otherSettings: "Configuración avanzada"
|
||||||
openInWindow: "Abrir en una ventana"
|
openInWindow: "Abrir en una ventana"
|
||||||
profile: "Perfil"
|
profile: "Perfil"
|
||||||
timeline: "Linea de tiempo"
|
timeline: "Línea de tiempo"
|
||||||
noAccountDescription: "Este usuario no tiene una descripción"
|
noAccountDescription: "Este usuario no ha escrito su biografía aún"
|
||||||
login: "Iniciar sesión"
|
login: "Iniciar sesión"
|
||||||
loggingIn: "Iniciando sesión"
|
loggingIn: "Iniciando sesión"
|
||||||
logout: "Cerrar sesión"
|
logout: "Cerrar sesión"
|
||||||
signup: "Registrarse"
|
signup: "Registrarse"
|
||||||
uploading: "Cargando"
|
uploading: "Cargando..."
|
||||||
save: "Guardar"
|
save: "Guardar"
|
||||||
users: "Usuarios"
|
users: "Usuarios"
|
||||||
addUser: "Agregar usuario"
|
addUser: "Agregar usuario"
|
||||||
favorite: "Favorito"
|
favorite: "Añadir a favoritos"
|
||||||
favorites: "Favoritos"
|
favorites: "Favoritos"
|
||||||
unfavorite: "Quitar de favoritos"
|
unfavorite: "Quitar de favoritos"
|
||||||
favorited: "Añadido a favoritos"
|
favorited: "Añadido a favoritos."
|
||||||
alreadyFavorited: "Ya había sido añadido a favoritos"
|
alreadyFavorited: "Ya había sido añadido a favoritos"
|
||||||
cantFavorite: "No fue añadido a favoritos"
|
cantFavorite: "No se puede añadir a favoritos."
|
||||||
pin: "Fijar"
|
pin: "Fijar al perfil"
|
||||||
unpin: "Desfijar"
|
unpin: "Desfijar"
|
||||||
copyContent: "Copiar contenido"
|
copyContent: "Copiar contenido"
|
||||||
copyLink: "Copiar enlace"
|
copyLink: "Copiar enlace"
|
||||||
delete: "Borrar"
|
delete: "Borrar"
|
||||||
deleteAndEdit: "Borrar y editar"
|
deleteAndEdit: "Borrar y editar"
|
||||||
deleteAndEditConfirm: "¿Quieres borrar y editar este nota? Las reacciones, renotes, respuestas y todo desaparecerán."
|
deleteAndEditConfirm: "¿Estás seguro de que quieres borrar esta nota y editarla? Perderás todas las reacciones, renotas y respuestas."
|
||||||
addToList: "Agregar a lista"
|
addToList: "Agregar a lista"
|
||||||
sendMessage: "Énviar mensaje"
|
sendMessage: "Enviar un mensaje"
|
||||||
copyUsername: "Copiar nombre de usuario"
|
copyUsername: "Copiar nombre de usuario"
|
||||||
searchUser: "Búsqueda de usuarios"
|
searchUser: "Buscar un usuario"
|
||||||
reply: "Responder"
|
reply: "Responder"
|
||||||
loadMore: "Ver más"
|
loadMore: "Ver más"
|
||||||
showMore: "Ver más"
|
showMore: "Ver más"
|
||||||
|
showLess: "Cerrar"
|
||||||
youGotNewFollower: "te ha seguido"
|
youGotNewFollower: "te ha seguido"
|
||||||
receiveFollowRequest: "Recibiste una solicitud de seguimiento"
|
receiveFollowRequest: "Recibiste una solicitud de seguimiento"
|
||||||
followRequestAccepted: "La solicitud de seguimiento fue aceptada"
|
followRequestAccepted: "La solicitud de seguimiento fue aceptada"
|
||||||
@@ -87,11 +88,11 @@ enterListName: "Ingrese nombre de lista"
|
|||||||
privacy: "Privacidad"
|
privacy: "Privacidad"
|
||||||
makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento"
|
makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento"
|
||||||
defaultNoteVisibility: "Visibilidad por defecto"
|
defaultNoteVisibility: "Visibilidad por defecto"
|
||||||
follow: "Sigue"
|
follow: "Seguir"
|
||||||
followRequest: "Solicitud de seguimiento"
|
followRequest: "Enviar solicitud de seguimiento"
|
||||||
followRequests: "Solicitudes de seguimiento"
|
followRequests: "Solicitudes de seguimiento"
|
||||||
unfollow: "Dejar de seguir"
|
unfollow: "Dejar de seguir"
|
||||||
followRequestPending: "Solicitudes de seguimiento pendientes"
|
followRequestPending: "Solicitudes de seguimiento pendiente"
|
||||||
enterEmoji: "Ingresar emojis"
|
enterEmoji: "Ingresar emojis"
|
||||||
renote: "Renotar"
|
renote: "Renotar"
|
||||||
unrenote: "Quitar renota"
|
unrenote: "Quitar renota"
|
||||||
@@ -100,7 +101,7 @@ cantRenote: "No se puede renotar este post"
|
|||||||
cantReRenote: "No se puede renotar una renota"
|
cantReRenote: "No se puede renotar una renota"
|
||||||
quote: "Citar"
|
quote: "Citar"
|
||||||
pinnedNote: "Nota fijada"
|
pinnedNote: "Nota fijada"
|
||||||
pinned: "Fijar"
|
pinned: "Fijar al perfil"
|
||||||
you: "Tú"
|
you: "Tú"
|
||||||
clickToShow: "Click para ver"
|
clickToShow: "Click para ver"
|
||||||
sensitive: "Marcado como sensible"
|
sensitive: "Marcado como sensible"
|
||||||
@@ -203,6 +204,7 @@ done: "Terminado"
|
|||||||
processing: "Procesando"
|
processing: "Procesando"
|
||||||
preview: "Vista previa"
|
preview: "Vista previa"
|
||||||
default: "Predeterminado"
|
default: "Predeterminado"
|
||||||
|
defaultValueIs: "Predeterminado"
|
||||||
noCustomEmojis: "No hay emojis personalizados"
|
noCustomEmojis: "No hay emojis personalizados"
|
||||||
noJobs: "No hay trabajos"
|
noJobs: "No hay trabajos"
|
||||||
federating: "Federando"
|
federating: "Federando"
|
||||||
@@ -381,6 +383,7 @@ administrator: "Administrador"
|
|||||||
token: "Token"
|
token: "Token"
|
||||||
twoStepAuthentication: "Autenticación de dos factores"
|
twoStepAuthentication: "Autenticación de dos factores"
|
||||||
moderator: "Moderador"
|
moderator: "Moderador"
|
||||||
|
moderation: "Moderación"
|
||||||
nUsersMentioned: "{n} usuarios mencionados"
|
nUsersMentioned: "{n} usuarios mencionados"
|
||||||
securityKey: "Clave de seguridad"
|
securityKey: "Clave de seguridad"
|
||||||
securityKeyName: "Nombre de la Clave"
|
securityKeyName: "Nombre de la Clave"
|
||||||
@@ -559,6 +562,7 @@ author: "Autor"
|
|||||||
leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?"
|
leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?"
|
||||||
manage: "Administrar"
|
manage: "Administrar"
|
||||||
plugins: "Plugins"
|
plugins: "Plugins"
|
||||||
|
preferencesBackups: "Respaldo de preferencias"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Quitar deck"
|
undeck: "Quitar deck"
|
||||||
useBlurEffectForModal: "Usar efecto borroso en modales"
|
useBlurEffectForModal: "Usar efecto borroso en modales"
|
||||||
@@ -854,6 +858,9 @@ noEmailServerWarning: "No se ha configurado un servidor de correo electrónico."
|
|||||||
thereIsUnresolvedAbuseReportWarning: "Hay reportes sin resolver"
|
thereIsUnresolvedAbuseReportWarning: "Hay reportes sin resolver"
|
||||||
recommended: "Recomendado"
|
recommended: "Recomendado"
|
||||||
check: "Verificar"
|
check: "Verificar"
|
||||||
|
driveCapOverrideLabel: "Cambiar la capacidad de la unidad para este usuario"
|
||||||
|
driveCapOverrideCaption: "Restablecer la capacidad a su predeterminado ingresando un valor de 0 o menos"
|
||||||
|
requireAdminForView: "Necesitas iniciar sesión como administrador para ver esto."
|
||||||
isSystemAccount: "Cuenta creada y operada automáticamente por el sistema"
|
isSystemAccount: "Cuenta creada y operada automáticamente por el sistema"
|
||||||
typeToConfirm: "Ingrese {x} para confirmar"
|
typeToConfirm: "Ingrese {x} para confirmar"
|
||||||
deleteAccount: "Borrar cuenta"
|
deleteAccount: "Borrar cuenta"
|
||||||
@@ -861,6 +868,39 @@ document: "Documento"
|
|||||||
numberOfPageCache: "Cantidad de páginas cacheadas"
|
numberOfPageCache: "Cantidad de páginas cacheadas"
|
||||||
numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien puede aumentar la carga y la memoria a usarse"
|
numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien puede aumentar la carga y la memoria a usarse"
|
||||||
logoutConfirm: "¿Cerrar sesión?"
|
logoutConfirm: "¿Cerrar sesión?"
|
||||||
|
lastActiveDate: "Utilizado por última vez el"
|
||||||
|
statusbar: "Barra de estado"
|
||||||
|
pleaseSelect: "Selecciona una opción"
|
||||||
|
reverse: "Echar de un capirotazo"
|
||||||
|
colored: "Color"
|
||||||
|
refreshInterval: "Intervalo de actualización"
|
||||||
|
label: "Etiqueta"
|
||||||
|
type: "Tipo"
|
||||||
|
speed: "Velocidad"
|
||||||
|
slow: "Lento"
|
||||||
|
fast: "Rápido"
|
||||||
|
sensitiveMediaDetection: "Detección de contenido NSFW"
|
||||||
|
localOnly: "Solo local"
|
||||||
|
remoteOnly: "Sólo remoto"
|
||||||
|
failedToUpload: "La subida falló"
|
||||||
|
cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas partes han sido detectadas comoNSFW."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en la unidad del usuario."
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "Marcar automáticamente contenido NSFW"
|
||||||
|
enableAutoSensitiveDescription: "Permite la detección y marcado automático de contenido NSFW usando 'Machine Learning' cuando sea posible. Incluso si esta opción está desactivada, puede ser activado para toda la instancia."
|
||||||
|
activeEmailValidationDescription: "Habilita la validación estricta de direcciones de correo electrónico, lo cual incluye la revisión de direcciones desechables y si se puede comunicar con éstas. Cuando está deshabilitado, sólo el formato de la dirección es validado."
|
||||||
|
navbar: "Barra de navegación"
|
||||||
|
shuffle: "Aleatorio"
|
||||||
|
account: "Cuentas"
|
||||||
|
move: "Mover"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Reduce el esfuerzo de la moderación el el servidor a través del reconocimiento automático de contenido NSFW usando 'Machine Learning'. Esto puede incrementar ligeramente la carga en el servidor."
|
||||||
|
sensitivity: "Sensibilidad de detección"
|
||||||
|
sensitivityDescription: "Reducir la sensibilidad puede acarrear a varios falsos positivos, mientras que incrementarla puede reducir las detecciones (falsos negativos)."
|
||||||
|
setSensitiveFlagAutomatically: "Marcar como NSFW"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "Los resultados de la detección interna pueden ser retenidos incluso si la opción está desactivada."
|
||||||
|
analyzeVideos: "Habilitar el análisis de videos"
|
||||||
|
analyzeVideosDescription: "Analizar videos en adición a las imágenes. Esto puede incrementar ligeramente la carga del servidor."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Ya fue usado"
|
used: "Ya fue usado"
|
||||||
format: "Formato no válido."
|
format: "Formato no válido."
|
||||||
@@ -903,6 +943,24 @@ _plugin:
|
|||||||
install: "Instalar plugins"
|
install: "Instalar plugins"
|
||||||
installWarn: "Por favor no instale plugins que no son de confianza"
|
installWarn: "Por favor no instale plugins que no son de confianza"
|
||||||
manage: "Gestionar plugins"
|
manage: "Gestionar plugins"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "Respaldos creados"
|
||||||
|
saveNew: "Guardar nuevo respaldo"
|
||||||
|
loadFile: "Cargar desde archivo"
|
||||||
|
apply: "Aplicar a este dispositivo"
|
||||||
|
save: "Guardar cambios"
|
||||||
|
inputName: "Por favor, ingresa un nombre para este respaldo"
|
||||||
|
cannotSave: "Fallo al guardar"
|
||||||
|
nameAlreadyExists: "Un respaldo llamado \"{name}\" ya existe. Por favor ingresa un nombre diferente"
|
||||||
|
applyConfirm: "¿Realmente quieres aplicar los cambios desde el archivo \"{name}\" a este dispositivo? Las configuraciones existentes serán sobreescritas. "
|
||||||
|
saveConfirm: "¿Guardar respaldo como \"{name}\"?"
|
||||||
|
deleteConfirm: "¿Borrar el respaldo \"{name}\"?"
|
||||||
|
renameConfirm: "¿Renombrar este respaldo de \"{old}\" a \"{new}\"?"
|
||||||
|
noBackups: "No existen respaldos. Deberás respaldar las configuraciones del cliente en este servidor usando \"Crear nuevo respaldo\""
|
||||||
|
createdAt: "Creado: {date} {time}"
|
||||||
|
updatedAt: "Actualizado: {date} {time}"
|
||||||
|
cannotLoad: "La carga falló"
|
||||||
|
invalidFile: "Formato de archivo inválido"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "Alcance"
|
scope: "Alcance"
|
||||||
key: "Clave"
|
key: "Clave"
|
||||||
@@ -986,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "Aplica un efecto de partículas parpadeantes"
|
sparkleDescription: "Aplica un efecto de partículas parpadeantes"
|
||||||
rotate: "Rotar"
|
rotate: "Rotar"
|
||||||
rotateDescription: "Rota el contenido a un ángulo especificado."
|
rotateDescription: "Rota el contenido a un ángulo especificado."
|
||||||
|
plain: "Plano"
|
||||||
|
plainDescription: "Desactiva los efectos de todo el contenido MFM con este efecto MFM."
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "No mostrar"
|
none: "No mostrar"
|
||||||
remote: "Mostrar a usuarios remotos"
|
remote: "Mostrar a usuarios remotos"
|
||||||
@@ -1215,9 +1275,11 @@ _widgets:
|
|||||||
trends: "Tendencias"
|
trends: "Tendencias"
|
||||||
clock: "Reloj"
|
clock: "Reloj"
|
||||||
rss: "Lector RSS"
|
rss: "Lector RSS"
|
||||||
|
rssTicker: "Ticker-RSS"
|
||||||
activity: "Actividad"
|
activity: "Actividad"
|
||||||
photos: "Fotos"
|
photos: "Fotos"
|
||||||
digitalClock: "Reloj digital"
|
digitalClock: "Reloj digital"
|
||||||
|
unixClock: "Reloj UNIX"
|
||||||
federation: "Federación"
|
federation: "Federación"
|
||||||
instanceCloud: "Nube de palabras de la instancia"
|
instanceCloud: "Nube de palabras de la instancia"
|
||||||
postForm: "Formulario"
|
postForm: "Formulario"
|
||||||
@@ -1658,6 +1720,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Siempre mostrar la columna principal"
|
alwaysShowMainColumn: "Siempre mostrar la columna principal"
|
||||||
columnAlign: "Alinear columnas"
|
columnAlign: "Alinear columnas"
|
||||||
addColumn: "Agregar columna"
|
addColumn: "Agregar columna"
|
||||||
|
configureColumn: "Ajustes de columna"
|
||||||
swapLeft: "Mover a la izquierda"
|
swapLeft: "Mover a la izquierda"
|
||||||
swapRight: "Mover a la derecha"
|
swapRight: "Mover a la derecha"
|
||||||
swapUp: "Mover arriba"
|
swapUp: "Mover arriba"
|
||||||
@@ -1665,6 +1728,11 @@ _deck:
|
|||||||
stackLeft: "Apilar a la izquierda"
|
stackLeft: "Apilar a la izquierda"
|
||||||
popRight: "Sacar a la derecha"
|
popRight: "Sacar a la derecha"
|
||||||
profile: "Perfil"
|
profile: "Perfil"
|
||||||
|
newProfile: "Nuevo perfil"
|
||||||
|
deleteProfile: "Eliminar perfil"
|
||||||
|
introduction: "¡Crea la interfaz perfecta para tí organizando las columnas libremente!"
|
||||||
|
introduction2: "Presiona en la + de la derecha de la pantalla para añadir nuevas columnas donde quieras."
|
||||||
|
widgetsIntroduction: "Por favor selecciona \"Editar Widgets\" en el menú columna y agrega un widget."
|
||||||
_columns:
|
_columns:
|
||||||
main: "Principal"
|
main: "Principal"
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Chercher un·e utilisateur·rice"
|
|||||||
reply: "Répondre"
|
reply: "Répondre"
|
||||||
loadMore: "Afficher plus …"
|
loadMore: "Afficher plus …"
|
||||||
showMore: "Afficher plus …"
|
showMore: "Afficher plus …"
|
||||||
|
showLess: "Fermer"
|
||||||
youGotNewFollower: "Vous suit"
|
youGotNewFollower: "Vous suit"
|
||||||
receiveFollowRequest: "Demande d’abonnement reçue"
|
receiveFollowRequest: "Demande d’abonnement reçue"
|
||||||
followRequestAccepted: "La demande d’abonnement a été acceptée"
|
followRequestAccepted: "La demande d’abonnement a été acceptée"
|
||||||
@@ -839,6 +840,11 @@ rateLimitExceeded: "Limite de taux dépassée"
|
|||||||
cropImage: "Recadrer l'image"
|
cropImage: "Recadrer l'image"
|
||||||
cropImageAsk: "Voulez-vous recadrer cette image ?"
|
cropImageAsk: "Voulez-vous recadrer cette image ?"
|
||||||
file: "Fichiers"
|
file: "Fichiers"
|
||||||
|
reverse: "Inverser"
|
||||||
|
colored: "Coloré"
|
||||||
|
label: "Étiquette"
|
||||||
|
localOnly: "Local seulement"
|
||||||
|
account: "Comptes"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Non disponible"
|
used: "Non disponible"
|
||||||
format: "Le format de cette adresse de courriel est invalide"
|
format: "Le format de cette adresse de courriel est invalide"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Cari pengguna"
|
|||||||
reply: "Balas"
|
reply: "Balas"
|
||||||
loadMore: "Selebihnya"
|
loadMore: "Selebihnya"
|
||||||
showMore: "Selebihnya"
|
showMore: "Selebihnya"
|
||||||
|
showLess: "Tutup"
|
||||||
youGotNewFollower: "Mengikuti kamu"
|
youGotNewFollower: "Mengikuti kamu"
|
||||||
receiveFollowRequest: "Ingin mengikuti kamu"
|
receiveFollowRequest: "Ingin mengikuti kamu"
|
||||||
followRequestAccepted: "Permintaan mengikuti telah disetujui"
|
followRequestAccepted: "Permintaan mengikuti telah disetujui"
|
||||||
@@ -848,6 +849,11 @@ rateLimitExceeded: "Batas sudah terlampaui"
|
|||||||
cropImage: "potong gambar"
|
cropImage: "potong gambar"
|
||||||
cropImageAsk: "Ingin memotong gambar?"
|
cropImageAsk: "Ingin memotong gambar?"
|
||||||
file: "Berkas"
|
file: "Berkas"
|
||||||
|
reverse: "Balik"
|
||||||
|
colored: "Diwarnai"
|
||||||
|
label: "Label"
|
||||||
|
localOnly: "Hanya lokal"
|
||||||
|
account: "Akun"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Alamat surel ini telah digunakan"
|
used: "Alamat surel ini telah digunakan"
|
||||||
format: "Format tidak valid."
|
format: "Format tidak valid."
|
||||||
|
@@ -36,6 +36,7 @@ const languages = [
|
|||||||
'sk-SK',
|
'sk-SK',
|
||||||
'ug-CN',
|
'ug-CN',
|
||||||
'uk-UA',
|
'uk-UA',
|
||||||
|
'vi-VN',
|
||||||
'zh-CN',
|
'zh-CN',
|
||||||
'zh-TW',
|
'zh-TW',
|
||||||
];
|
];
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Cerca utente"
|
|||||||
reply: "Rispondi"
|
reply: "Rispondi"
|
||||||
loadMore: "Mostra di più"
|
loadMore: "Mostra di più"
|
||||||
showMore: "Mostra di più"
|
showMore: "Mostra di più"
|
||||||
|
showLess: "Chiudi"
|
||||||
youGotNewFollower: "Ha iniziato a seguirti"
|
youGotNewFollower: "Ha iniziato a seguirti"
|
||||||
receiveFollowRequest: "Hai ricevuto una richiesta di follow."
|
receiveFollowRequest: "Hai ricevuto una richiesta di follow."
|
||||||
followRequestAccepted: "Richiesta di follow accettata"
|
followRequestAccepted: "Richiesta di follow accettata"
|
||||||
@@ -810,6 +811,11 @@ oneHour: "1 ora"
|
|||||||
oneDay: "1 giorno"
|
oneDay: "1 giorno"
|
||||||
oneWeek: "1 settimana"
|
oneWeek: "1 settimana"
|
||||||
file: "Allegati"
|
file: "Allegati"
|
||||||
|
reverse: "Inverti"
|
||||||
|
colored: "Colorato"
|
||||||
|
label: "Etichetta"
|
||||||
|
localOnly: "Soltanto locale"
|
||||||
|
account: "Account"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Email già in uso"
|
used: "Email già in uso"
|
||||||
format: "Formato email non valido"
|
format: "Formato email non valido"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "ユーザーを検索"
|
|||||||
reply: "返信"
|
reply: "返信"
|
||||||
loadMore: "もっと見る"
|
loadMore: "もっと見る"
|
||||||
showMore: "もっと見る"
|
showMore: "もっと見る"
|
||||||
|
showLess: "閉じる"
|
||||||
youGotNewFollower: "フォローされました"
|
youGotNewFollower: "フォローされました"
|
||||||
receiveFollowRequest: "フォローリクエストされました"
|
receiveFollowRequest: "フォローリクエストされました"
|
||||||
followRequestAccepted: "フォローが承認されました"
|
followRequestAccepted: "フォローが承認されました"
|
||||||
@@ -561,6 +562,7 @@ author: "作者"
|
|||||||
leaveConfirm: "未保存の変更があります。破棄しますか?"
|
leaveConfirm: "未保存の変更があります。破棄しますか?"
|
||||||
manage: "管理"
|
manage: "管理"
|
||||||
plugins: "プラグイン"
|
plugins: "プラグイン"
|
||||||
|
preferencesBackups: "設定のバックアップ"
|
||||||
deck: "デッキ"
|
deck: "デッキ"
|
||||||
undeck: "デッキ解除"
|
undeck: "デッキ解除"
|
||||||
useBlurEffectForModal: "モーダルにぼかし効果を使用"
|
useBlurEffectForModal: "モーダルにぼかし効果を使用"
|
||||||
@@ -886,6 +888,11 @@ cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためア
|
|||||||
beta: "ベータ"
|
beta: "ベータ"
|
||||||
enableAutoSensitive: "自動NSFW判定"
|
enableAutoSensitive: "自動NSFW判定"
|
||||||
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
|
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
|
||||||
|
activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。"
|
||||||
|
navbar: "ナビゲーションバー"
|
||||||
|
shuffle: "シャッフル"
|
||||||
|
account: "アカウント"
|
||||||
|
move: "移動"
|
||||||
|
|
||||||
_sensitiveMediaDetection:
|
_sensitiveMediaDetection:
|
||||||
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"
|
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"
|
||||||
@@ -947,6 +954,25 @@ _plugin:
|
|||||||
installWarn: "信頼できないプラグインはインストールしないでください。"
|
installWarn: "信頼できないプラグインはインストールしないでください。"
|
||||||
manage: "プラグインの管理"
|
manage: "プラグインの管理"
|
||||||
|
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "作成したバックアップ"
|
||||||
|
saveNew: "新規保存"
|
||||||
|
loadFile: "ファイルを読み込み"
|
||||||
|
apply: "このデバイスに適用"
|
||||||
|
save: "上書き保存"
|
||||||
|
inputName: "バックアップ名を入力"
|
||||||
|
cannotSave: "保存できません"
|
||||||
|
nameAlreadyExists: "バックアップ名「{name}」は既に存在します。違う名前を指定してください。"
|
||||||
|
applyConfirm: "バックアップ「{name}」を現在のデバイスに適用しますか?現在のデバイス設定は失われます。"
|
||||||
|
saveConfirm: "{name}に上書き保存しますか?"
|
||||||
|
deleteConfirm: "{name}を削除しますか?"
|
||||||
|
renameConfirm: "「{old}」を「{new}」に変更しますか?"
|
||||||
|
noBackups: "バックアップはありません。「新規保存」で現在のクライアント設定をサーバーに保存できます。"
|
||||||
|
createdAt: "作成日時: {date} {time}"
|
||||||
|
updatedAt: "更新日時: {date} {time}"
|
||||||
|
cannotLoad: "読み込みできません"
|
||||||
|
invalidFile: "ファイル形式が違います。"
|
||||||
|
|
||||||
_registry:
|
_registry:
|
||||||
scope: "スコープ"
|
scope: "スコープ"
|
||||||
key: "キー"
|
key: "キー"
|
||||||
@@ -1033,6 +1059,8 @@ _mfm:
|
|||||||
sparkleDescription: "キラキラしたパーティクルのエフェクトを追加します。"
|
sparkleDescription: "キラキラしたパーティクルのエフェクトを追加します。"
|
||||||
rotate: "回転"
|
rotate: "回転"
|
||||||
rotateDescription: "指定した角度で回転させます。"
|
rotateDescription: "指定した角度で回転させます。"
|
||||||
|
plain: "プレーン"
|
||||||
|
plainDescription: "内側の構文を全て無効にします。"
|
||||||
|
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "表示しない"
|
none: "表示しない"
|
||||||
@@ -1284,6 +1312,7 @@ _widgets:
|
|||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
photos: "フォト"
|
photos: "フォト"
|
||||||
digitalClock: "デジタル時計"
|
digitalClock: "デジタル時計"
|
||||||
|
unixClock: "UNIX時計"
|
||||||
federation: "連合"
|
federation: "連合"
|
||||||
instanceCloud: "インスタンスクラウド"
|
instanceCloud: "インスタンスクラウド"
|
||||||
postForm: "投稿フォーム"
|
postForm: "投稿フォーム"
|
||||||
@@ -1751,6 +1780,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "常にメインカラムを表示"
|
alwaysShowMainColumn: "常にメインカラムを表示"
|
||||||
columnAlign: "カラムの寄せ"
|
columnAlign: "カラムの寄せ"
|
||||||
addColumn: "カラムを追加"
|
addColumn: "カラムを追加"
|
||||||
|
configureColumn: "カラムの設定"
|
||||||
swapLeft: "左に移動"
|
swapLeft: "左に移動"
|
||||||
swapRight: "右に移動"
|
swapRight: "右に移動"
|
||||||
swapUp: "上に移動"
|
swapUp: "上に移動"
|
||||||
@@ -1758,6 +1788,8 @@ _deck:
|
|||||||
stackLeft: "左に重ねる"
|
stackLeft: "左に重ねる"
|
||||||
popRight: "右に出す"
|
popRight: "右に出す"
|
||||||
profile: "プロファイル"
|
profile: "プロファイル"
|
||||||
|
newProfile: "新規プロファイル"
|
||||||
|
deleteProfile: "プロファイルを削除"
|
||||||
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
|
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
|
||||||
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
|
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
|
||||||
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
|
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "ユーザーを検索"
|
|||||||
reply: "返事"
|
reply: "返事"
|
||||||
loadMore: "まだまだあるで!"
|
loadMore: "まだまだあるで!"
|
||||||
showMore: "まだまだあるで!"
|
showMore: "まだまだあるで!"
|
||||||
|
showLess: "閉じる"
|
||||||
youGotNewFollower: "フォローされたで"
|
youGotNewFollower: "フォローされたで"
|
||||||
receiveFollowRequest: "フォローリクエストされたで"
|
receiveFollowRequest: "フォローリクエストされたで"
|
||||||
followRequestAccepted: "フォローが承認されたで"
|
followRequestAccepted: "フォローが承認されたで"
|
||||||
@@ -203,6 +204,7 @@ done: "でけた"
|
|||||||
processing: "処理しとる"
|
processing: "処理しとる"
|
||||||
preview: "プレビュー"
|
preview: "プレビュー"
|
||||||
default: "デフォルト"
|
default: "デフォルト"
|
||||||
|
defaultValueIs: "デフォルト"
|
||||||
noCustomEmojis: "絵文字はあらへん"
|
noCustomEmojis: "絵文字はあらへん"
|
||||||
noJobs: "ジョブはあらへん"
|
noJobs: "ジョブはあらへん"
|
||||||
federating: "連合しとる"
|
federating: "連合しとる"
|
||||||
@@ -317,6 +319,8 @@ monthX: "{month}月"
|
|||||||
yearX: "{year}年"
|
yearX: "{year}年"
|
||||||
pages: "ページ"
|
pages: "ページ"
|
||||||
integration: "連携"
|
integration: "連携"
|
||||||
|
connectService: "つなげるで"
|
||||||
|
disconnectService: "切るで"
|
||||||
enableLocalTimeline: "ローカルタイムラインを使えるようにする"
|
enableLocalTimeline: "ローカルタイムラインを使えるようにする"
|
||||||
enableGlobalTimeline: "グローバルタイムラインを使えるようにする"
|
enableGlobalTimeline: "グローバルタイムラインを使えるようにする"
|
||||||
disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。"
|
disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。"
|
||||||
@@ -328,10 +332,13 @@ driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのド
|
|||||||
inMb: "メガバイト単位"
|
inMb: "メガバイト単位"
|
||||||
iconUrl: "アイコン画像のURL"
|
iconUrl: "アイコン画像のURL"
|
||||||
bannerUrl: "バナー画像のURL"
|
bannerUrl: "バナー画像のURL"
|
||||||
|
backgroundImageUrl: "背景画像のURL"
|
||||||
basicInfo: "基本情報"
|
basicInfo: "基本情報"
|
||||||
pinnedUsers: "ピン留めしたユーザー"
|
pinnedUsers: "ピン留めしたユーザー"
|
||||||
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。他ん人との名前は改行で区切ればええんやで。"
|
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。他ん人との名前は改行で区切ればええんやで。"
|
||||||
pinnedPages: "ピン留めページ"
|
pinnedPages: "ピン留めページ"
|
||||||
|
pinnedPagesDescription: "インスタンスのいっちゃん上にピン留めしたいページのパスを改行で区切って記述してな"
|
||||||
|
pinnedClipId: "ピン留めするクリップのID"
|
||||||
pinnedNotes: "ピン留めされとるノート"
|
pinnedNotes: "ピン留めされとるノート"
|
||||||
hcaptcha: "hCaptcha(キャプチャ)"
|
hcaptcha: "hCaptcha(キャプチャ)"
|
||||||
enableHcaptcha: "hCaptcha(キャプチャ)をつけとく"
|
enableHcaptcha: "hCaptcha(キャプチャ)をつけとく"
|
||||||
@@ -376,6 +383,7 @@ administrator: "管理者"
|
|||||||
token: "トークン"
|
token: "トークン"
|
||||||
twoStepAuthentication: "二段階認証"
|
twoStepAuthentication: "二段階認証"
|
||||||
moderator: "モデレーター"
|
moderator: "モデレーター"
|
||||||
|
moderation: "モデレーション"
|
||||||
nUsersMentioned: "{n}人が投稿"
|
nUsersMentioned: "{n}人が投稿"
|
||||||
securityKey: "セキュリティキー"
|
securityKey: "セキュリティキー"
|
||||||
securityKeyName: "キーの名前"
|
securityKeyName: "キーの名前"
|
||||||
@@ -435,13 +443,17 @@ strongPassword: "ええ感じのパスワード"
|
|||||||
passwordMatched: "よし!一致や!"
|
passwordMatched: "よし!一致や!"
|
||||||
passwordNotMatched: "一致しとらんで?"
|
passwordNotMatched: "一致しとらんで?"
|
||||||
signinWith: "{x}でログイン"
|
signinWith: "{x}でログイン"
|
||||||
|
signinFailed: "ログインできんかったで。もっかいユーザー名とパスワードを確認してみてな。"
|
||||||
|
tapSecurityKey: "セキュリティキーにタッチしてな"
|
||||||
or: "それか"
|
or: "それか"
|
||||||
language: "言語"
|
language: "言語"
|
||||||
uiLanguage: "UIの表示言語"
|
uiLanguage: "UIの表示言語"
|
||||||
groupInvited: "グループに招待されとるで"
|
groupInvited: "グループに招待されとるで"
|
||||||
aboutX: "{x}について"
|
aboutX: "{x}について"
|
||||||
useOsNativeEmojis: "OSネイティブの絵文字を使う"
|
useOsNativeEmojis: "OSネイティブの絵文字を使う"
|
||||||
|
disableDrawer: "メニューをドロワーで表示せぇへん"
|
||||||
youHaveNoGroups: "グループがあらへんねぇ。"
|
youHaveNoGroups: "グループがあらへんねぇ。"
|
||||||
|
joinOrCreateGroup: "既存のグループに招待してもらうか、新しくグループ作ってからやってな"
|
||||||
noHistory: "履歴はあらへんねぇ。"
|
noHistory: "履歴はあらへんねぇ。"
|
||||||
signinHistory: "ログイン履歴"
|
signinHistory: "ログイン履歴"
|
||||||
disableAnimatedMfm: "動きがやかましいMFMを止める"
|
disableAnimatedMfm: "動きがやかましいMFMを止める"
|
||||||
@@ -450,6 +462,7 @@ category: "カテゴリ"
|
|||||||
tags: "タグ"
|
tags: "タグ"
|
||||||
docSource: "このドキュメントのソース"
|
docSource: "このドキュメントのソース"
|
||||||
createAccount: "アカウントを作成"
|
createAccount: "アカウントを作成"
|
||||||
|
existingAccount: "既存のアカウント"
|
||||||
regenerate: "再生成"
|
regenerate: "再生成"
|
||||||
fontSize: "フォントサイズ"
|
fontSize: "フォントサイズ"
|
||||||
noFollowRequests: "フォロー申請はあらへんで"
|
noFollowRequests: "フォロー申請はあらへんで"
|
||||||
@@ -473,10 +486,15 @@ useObjectStorage: "オブジェクトストレージを使う"
|
|||||||
objectStorageBaseUrl: "Base URL"
|
objectStorageBaseUrl: "Base URL"
|
||||||
objectStorageBaseUrlDesc: "参照に使うにURLやで。CDNやProxyを使用してるんならそのURL、S3: 'https://<bucket>.s3.amazonaws.com'、GCSとかなら: 'https://storage.googleapis.com/<bucket>'。"
|
objectStorageBaseUrlDesc: "参照に使うにURLやで。CDNやProxyを使用してるんならそのURL、S3: 'https://<bucket>.s3.amazonaws.com'、GCSとかなら: 'https://storage.googleapis.com/<bucket>'。"
|
||||||
objectStorageBucket: "Bucket"
|
objectStorageBucket: "Bucket"
|
||||||
|
objectStorageBucketDesc: "使ってるサービスのbucket名を選んでな"
|
||||||
objectStoragePrefix: "Prefix"
|
objectStoragePrefix: "Prefix"
|
||||||
|
objectStoragePrefixDesc: "このprefixのディレクトリ下に格納されるで"
|
||||||
objectStorageEndpoint: "Endpoint"
|
objectStorageEndpoint: "Endpoint"
|
||||||
|
objectStorageEndpointDesc: "S3のときは空、それ以外は各サービスのendpointを指定してなー。'<host>'ってやるか'<host>:<port>'みたいに指定するんやで。"
|
||||||
objectStorageRegion: "Region"
|
objectStorageRegion: "Region"
|
||||||
|
objectStorageRegionDesc: "'xx-east-1'みたいなregionを指定したってやー。使ってるサービスにregionの概念がないときは、空か'us-east-1'にするんやで。"
|
||||||
objectStorageUseSSL: "SSLを使う"
|
objectStorageUseSSL: "SSLを使う"
|
||||||
|
objectStorageUseSSLDesc: "API接続にhttpsを使わん場合はオフにするんやで"
|
||||||
objectStorageUseProxy: "Proxyを使う"
|
objectStorageUseProxy: "Proxyを使う"
|
||||||
objectStorageUseProxyDesc: "API接続にproxy使わんのやったら切ってくれへん?"
|
objectStorageUseProxyDesc: "API接続にproxy使わんのやったら切ってくれへん?"
|
||||||
objectStorageSetPublicRead: "アップロードした時に'public-read'を設定してや"
|
objectStorageSetPublicRead: "アップロードした時に'public-read'を設定してや"
|
||||||
@@ -517,29 +535,52 @@ removeAllFollowing: "フォローを全解除"
|
|||||||
removeAllFollowingDescription: "{host}からのフォローをすべて解除するで。そのインスタンスが消えて無くなった時とかには便利な機能やで。"
|
removeAllFollowingDescription: "{host}からのフォローをすべて解除するで。そのインスタンスが消えて無くなった時とかには便利な機能やで。"
|
||||||
userSuspended: "このユーザーは...凍結されとる。"
|
userSuspended: "このユーザーは...凍結されとる。"
|
||||||
userSilenced: "このユーザーは...サイレンスされとる。"
|
userSilenced: "このユーザーは...サイレンスされとる。"
|
||||||
|
yourAccountSuspendedTitle: "あんたのアカウント凍結されとるで"
|
||||||
|
yourAccountSuspendedDescription: "あんたのアカウントは、サーバーの利用規約に違反したとかの理由で、凍結されとるで。細かいことは管理者までお問い合わせたってなー。絶対に新しいアカウント作ったらあかんで。絶対やで。"
|
||||||
|
menu: "メニュー"
|
||||||
divider: "分割線"
|
divider: "分割線"
|
||||||
|
addItem: "項目を追加"
|
||||||
relays: "リレー"
|
relays: "リレー"
|
||||||
addRelay: "リレーの追加"
|
addRelay: "リレーの追加"
|
||||||
inboxUrl: "inboxのURL"
|
inboxUrl: "inboxのURL"
|
||||||
addedRelays: "追加済みのリレー"
|
addedRelays: "追加済みのリレー"
|
||||||
|
serviceworkerInfo: "プッシュ通知をするんなら有効にせなあかんで。"
|
||||||
|
deletedNote: "消された投稿"
|
||||||
|
invisibleNote: "非公開の投稿"
|
||||||
|
enableInfiniteScroll: "自動でもっと見る"
|
||||||
|
visibility: "公開範囲"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
|
useCw: "内容を隠す"
|
||||||
enablePlayer: "プレイヤーを開く"
|
enablePlayer: "プレイヤーを開く"
|
||||||
disablePlayer: "プレイヤーを閉じる"
|
disablePlayer: "プレイヤーを閉じる"
|
||||||
expandTweet: "ツイートを展開する"
|
expandTweet: "ツイートを展開する"
|
||||||
themeEditor: "テーマエディター"
|
themeEditor: "テーマエディター"
|
||||||
description: "説明"
|
description: "説明"
|
||||||
|
describeFile: "キャプションを付ける"
|
||||||
|
enterFileDescription: "キャプションを入力"
|
||||||
author: "作者"
|
author: "作者"
|
||||||
leaveConfirm: "未保存の変更があるで!ほかしてええか?"
|
leaveConfirm: "未保存の変更があるで!ほかしてええか?"
|
||||||
manage: "管理"
|
manage: "管理"
|
||||||
plugins: "プラグイン"
|
plugins: "プラグイン"
|
||||||
deck: "デッキ"
|
deck: "デッキ"
|
||||||
undeck: "デッキ解除"
|
undeck: "デッキ解除"
|
||||||
|
useBlurEffectForModal: "モーダルにぼかし効果を使用"
|
||||||
|
useFullReactionPicker: "フル機能にリアクションピッカーを使用"
|
||||||
width: "幅"
|
width: "幅"
|
||||||
height: "高さ"
|
height: "高さ"
|
||||||
large: "大"
|
large: "大"
|
||||||
medium: "中"
|
medium: "中"
|
||||||
small: "小"
|
small: "小"
|
||||||
|
generateAccessToken: "アクセストークンの発行"
|
||||||
|
permission: "権限"
|
||||||
|
enableAll: "全部使えるようにする"
|
||||||
|
disableAll: "全部使えへんようにする"
|
||||||
|
tokenRequested: "アカウントへのアクセス許可"
|
||||||
|
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を使えるようになるで。"
|
||||||
|
notificationType: "通知の種類"
|
||||||
edit: "編集"
|
edit: "編集"
|
||||||
|
useStarForReactionFallback: "リアクションがようわからん場合、★を使う"
|
||||||
|
emailServer: "メールサーバー"
|
||||||
enableEmail: "メール配信を受け取る"
|
enableEmail: "メール配信を受け取る"
|
||||||
emailConfigInfo: "メールアドレスの確認とかパスワードリセットの時に使うで"
|
emailConfigInfo: "メールアドレスの確認とかパスワードリセットの時に使うで"
|
||||||
email: "メール"
|
email: "メール"
|
||||||
@@ -551,8 +592,12 @@ smtpUser: "ユーザー名"
|
|||||||
smtpPass: "パスワード"
|
smtpPass: "パスワード"
|
||||||
emptyToDisableSmtpAuth: "ユーザー名とパスワードになんも入れんかったら、SMTP認証を無効化するで"
|
emptyToDisableSmtpAuth: "ユーザー名とパスワードになんも入れんかったら、SMTP認証を無効化するで"
|
||||||
smtpSecure: "SMTP 接続に暗黙的なSSL/TLSを使用する"
|
smtpSecure: "SMTP 接続に暗黙的なSSL/TLSを使用する"
|
||||||
|
smtpSecureInfo: "STARTTLS使っとる時はオフにするで。"
|
||||||
testEmail: "配信テスト"
|
testEmail: "配信テスト"
|
||||||
wordMute: "ワードミュート"
|
wordMute: "ワードミュート"
|
||||||
|
regexpError: "正規表現エラー"
|
||||||
|
regexpErrorDescription: "{tab}ワードミュートの{line}行目の正規表現にエラーが出てきたで:"
|
||||||
|
instanceMute: "インスタンスミュート"
|
||||||
userSaysSomething: "{name}が何か言ったようやで"
|
userSaysSomething: "{name}が何か言ったようやで"
|
||||||
makeActive: "使うで"
|
makeActive: "使うで"
|
||||||
display: "表示"
|
display: "表示"
|
||||||
@@ -567,13 +612,24 @@ create: "作成"
|
|||||||
notificationSetting: "通知設定"
|
notificationSetting: "通知設定"
|
||||||
notificationSettingDesc: "表示する通知の種類えらんでや。"
|
notificationSettingDesc: "表示する通知の種類えらんでや。"
|
||||||
useGlobalSetting: "グローバル設定を使ってや"
|
useGlobalSetting: "グローバル設定を使ってや"
|
||||||
|
useGlobalSettingDesc: "オンにすると、アカウントの通知設定が使われるで。オフにすると、別々に設定できるようになるで。"
|
||||||
other: "その他"
|
other: "その他"
|
||||||
regenerateLoginToken: "ログイントークンを再生成"
|
regenerateLoginToken: "ログイントークンを再生成"
|
||||||
|
regenerateLoginTokenDescription: "ログインに使われる内部トークンをもっかい作るで。いつもならこれをやる必要はないで。もっかい作ると、全部のデバイスでログアウトされるで気ぃつけてなー。"
|
||||||
|
setMultipleBySeparatingWithSpace: "スペースで区切って複数設定できるで。"
|
||||||
|
fileIdOrUrl: "ファイルIDかURL"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
sample: "サンプル"
|
sample: "サンプル"
|
||||||
abuseReports: "通報"
|
abuseReports: "通報"
|
||||||
reportAbuse: "通報"
|
reportAbuse: "通報"
|
||||||
reportAbuseOf: "{name}を通報する"
|
reportAbuseOf: "{name}を通報する"
|
||||||
|
fillAbuseReportDescription: "細かい通報理由を書いてなー。対象ノートがある時はそのURLも書いといてなー。"
|
||||||
|
abuseReported: "無事内容が送信されたみたいやで。おおきに〜。"
|
||||||
|
reporter: "通報者"
|
||||||
|
reporteeOrigin: "通報先"
|
||||||
|
reporterOrigin: "通報元"
|
||||||
|
forwardReport: "リモートインスタンスに通報を転送するで"
|
||||||
|
forwardReportIsAnonymous: "リモートインスタンスからはあんたの情報は見れへんくって、匿名のシステムアカウントとして表示されるで。"
|
||||||
send: "送信"
|
send: "送信"
|
||||||
abuseMarkAsResolved: "対応したで"
|
abuseMarkAsResolved: "対応したで"
|
||||||
openInNewTab: "新しいタブで開く"
|
openInNewTab: "新しいタブで開く"
|
||||||
@@ -587,22 +643,57 @@ system: "システム"
|
|||||||
switchUi: "UI切り替え"
|
switchUi: "UI切り替え"
|
||||||
desktop: "デスクトップ"
|
desktop: "デスクトップ"
|
||||||
clip: "クリップ"
|
clip: "クリップ"
|
||||||
|
createNew: "新しく作るで"
|
||||||
|
optional: "任意"
|
||||||
|
createNewClip: "新しいクリップを作るで"
|
||||||
|
unclip: "クリップ解除するで"
|
||||||
|
confirmToUnclipAlreadyClippedNote: "このノートはすでにクリップ「{name}」に含まれとるで。ノートをこのクリップから除外したる?"
|
||||||
|
public: "パブリック"
|
||||||
|
i18nInfo: "Misskeyは有志によっていろんな言語に翻訳されとるで。{link}で翻訳に協力したってやー。"
|
||||||
|
manageAccessTokens: "アクセストークンの管理"
|
||||||
|
accountInfo: "アカウント情報"
|
||||||
|
notesCount: "ノートの数やで"
|
||||||
|
repliesCount: "返信した数やで"
|
||||||
|
renotesCount: "Renoteした数やで"
|
||||||
|
repliedCount: "返信された数やで"
|
||||||
|
renotedCount: "Renoteされた数やで"
|
||||||
|
followingCount: "フォロー数やで"
|
||||||
|
followersCount: "フォロワー数やで"
|
||||||
|
sentReactionsCount: "リアクションした数やで"
|
||||||
receivedReactionsCount: "リアクションされた数"
|
receivedReactionsCount: "リアクションされた数"
|
||||||
pollVotesCount: "アンケートに投票した数"
|
pollVotesCount: "アンケートに投票した数"
|
||||||
pollVotedCount: "アンケートに投票された数"
|
pollVotedCount: "アンケートに投票された数"
|
||||||
yes: "はい"
|
yes: "はい"
|
||||||
no: "いいえ"
|
no: "いいえ"
|
||||||
driveFilesCount: "ドライブのファイル数"
|
driveFilesCount: "ドライブのファイル数"
|
||||||
|
driveUsage: "ドライブ使用量やで"
|
||||||
|
noCrawle: "クローラーによるインデックスを拒否するで"
|
||||||
|
noCrawleDescription: "検索エンジンにあんたのユーザーページ、ノート、Pagesとかのコンテンツを登録(インデックス)せぇへんように頼むで。"
|
||||||
|
lockedAccountInfo: "フォローを承認制にしとっても、ノートの公開範囲を「フォロワー」にせぇへん限り、誰でもあんたのノートを見れるで。"
|
||||||
|
alwaysMarkSensitive: "デフォルトでメディアを閲覧注意にするで"
|
||||||
|
loadRawImages: "添付画像のサムネイルをオリジナル画質にするで"
|
||||||
|
disableShowingAnimatedImages: "アニメーション画像を再生しやへんで"
|
||||||
|
verificationEmailSent: "無事確認のメールを送れたで。メールに書いてあるリンクにアクセスして、設定を完了してなー。"
|
||||||
|
notSet: "未設定"
|
||||||
emailVerified: "メールアドレスは確認されたで"
|
emailVerified: "メールアドレスは確認されたで"
|
||||||
|
noteFavoritesCount: "お気に入りノートの数やで"
|
||||||
pageLikesCount: "Pageにええやんと思った数"
|
pageLikesCount: "Pageにええやんと思った数"
|
||||||
pageLikedCount: "Pageにええやんと思ってくれた数"
|
pageLikedCount: "Pageにええやんと思ってくれた数"
|
||||||
|
contact: "連絡先"
|
||||||
|
useSystemFont: "システムのデフォルトのフォントを使うで"
|
||||||
clips: "クリップ"
|
clips: "クリップ"
|
||||||
|
experimentalFeatures: "実験的機能やで"
|
||||||
|
developer: "開発者やで"
|
||||||
|
makeExplorable: "アカウントを見つけやすくするで"
|
||||||
|
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らんくなるで。"
|
||||||
|
showGapBetweenNotesInTimeline: "タイムラインのノートを放して表示するで"
|
||||||
duplicate: "複製"
|
duplicate: "複製"
|
||||||
left: "左"
|
left: "左"
|
||||||
center: "中央"
|
center: "中央"
|
||||||
wide: "広い"
|
wide: "広い"
|
||||||
narrow: "狭い"
|
narrow: "狭い"
|
||||||
reloadToApplySetting: "設定はページリロード後に反映されるで。今リロードしとくか?"
|
reloadToApplySetting: "設定はページリロード後に反映されるで。今リロードしとくか?"
|
||||||
|
needReloadToApply: "反映には再起動せなあかんで"
|
||||||
showTitlebar: "タイトルバーを見せる"
|
showTitlebar: "タイトルバーを見せる"
|
||||||
clearCache: "キャッシュをほかす"
|
clearCache: "キャッシュをほかす"
|
||||||
onlineUsersCount: "{n}人が起きとるで"
|
onlineUsersCount: "{n}人が起きとるで"
|
||||||
@@ -621,6 +712,7 @@ createdAt: "作成した日"
|
|||||||
updatedAt: "更新日時"
|
updatedAt: "更新日時"
|
||||||
saveConfirm: "保存するで?"
|
saveConfirm: "保存するで?"
|
||||||
deleteConfirm: "ホンマに削除するで?"
|
deleteConfirm: "ホンマに削除するで?"
|
||||||
|
invalidValue: "有効な値じゃないみたいやで。"
|
||||||
registry: "レジストリ"
|
registry: "レジストリ"
|
||||||
closeAccount: "アカウントを閉鎖する"
|
closeAccount: "アカウントを閉鎖する"
|
||||||
currentVersion: "現在のバージョン"
|
currentVersion: "現在のバージョン"
|
||||||
@@ -634,6 +726,7 @@ editCode: "コードを編集"
|
|||||||
apply: "適用"
|
apply: "適用"
|
||||||
receiveAnnouncementFromInstance: "インスタンスからのお知らせを受け取る"
|
receiveAnnouncementFromInstance: "インスタンスからのお知らせを受け取る"
|
||||||
emailNotification: "メール通知"
|
emailNotification: "メール通知"
|
||||||
|
publish: "公開"
|
||||||
inChannelSearch: "チャンネル内検索"
|
inChannelSearch: "チャンネル内検索"
|
||||||
useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開くようにする"
|
useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開くようにする"
|
||||||
typingUsers: "{users}が今書きよるで"
|
typingUsers: "{users}が今書きよるで"
|
||||||
@@ -642,22 +735,121 @@ showingPastTimeline: "過去のタイムラインを表示してるで"
|
|||||||
clear: "クリア"
|
clear: "クリア"
|
||||||
markAllAsRead: "もうみな読んでもうたわ"
|
markAllAsRead: "もうみな読んでもうたわ"
|
||||||
goBack: "戻る"
|
goBack: "戻る"
|
||||||
|
unlikeConfirm: "いいね解除するんか?"
|
||||||
|
fullView: "フルビュー"
|
||||||
|
quitFullView: "フルビュー解除"
|
||||||
|
addDescription: "説明を追加するで"
|
||||||
|
userPagePinTip: "個々のノートのメニューから「ピン留め」を選んどくと、ここにノートを表示しておけるで。"
|
||||||
|
notSpecifiedMentionWarning: "宛先に含まれてへんメンションがあるで"
|
||||||
info: "情報"
|
info: "情報"
|
||||||
|
userInfo: "ユーザー情報やで"
|
||||||
|
unknown: "不明"
|
||||||
|
onlineStatus: "オンライン状態"
|
||||||
|
hideOnlineStatus: "オンライン状態を隠すで"
|
||||||
|
hideOnlineStatusDescription: "オンライン状態を隠すと、検索とかの一部の機能で使いにくくなるかもしれんよ。"
|
||||||
|
online: "オンライン"
|
||||||
|
active: "アクティブ"
|
||||||
|
offline: "オフライン"
|
||||||
|
notRecommended: "あんま推奨しやんで"
|
||||||
|
botProtection: "Botプロテクション"
|
||||||
|
instanceBlocking: "インスタンスブロック"
|
||||||
|
selectAccount: "アカウントを選んでなー"
|
||||||
|
switchAccount: "アカウントを変えるで"
|
||||||
|
enabled: "有効"
|
||||||
|
disabled: "無効"
|
||||||
|
quickAction: "クイックアクション"
|
||||||
user: "ユーザー"
|
user: "ユーザー"
|
||||||
administration: "管理"
|
administration: "管理"
|
||||||
|
accounts: "アカウント"
|
||||||
|
switch: "切り替え"
|
||||||
|
noMaintainerInformationWarning: "管理者情報が設定されてへんで"
|
||||||
|
noBotProtectionWarning: "Botプロテクションが設定されてへんで。"
|
||||||
|
configure: "設定する"
|
||||||
|
postToGallery: "ギャラリーへ投稿"
|
||||||
|
gallery: "ギャラリー"
|
||||||
|
recentPosts: "最近の投稿"
|
||||||
|
popularPosts: "人気の投稿"
|
||||||
|
shareWithNote: "ノートで共有"
|
||||||
ads: "広告"
|
ads: "広告"
|
||||||
expiration: "期限"
|
expiration: "期限"
|
||||||
memo: "メモ"
|
memo: "メモ"
|
||||||
|
priority: "優先度"
|
||||||
high: "高い"
|
high: "高い"
|
||||||
middle: "中"
|
middle: "中"
|
||||||
low: "低い"
|
low: "低い"
|
||||||
|
emailNotConfiguredWarning: "メアドの設定がされてへんで。"
|
||||||
|
ratio: "比率"
|
||||||
|
previewNoteText: "本文を下見するで"
|
||||||
|
customCss: "カスタムCSS"
|
||||||
|
customCssWarn: "この設定は必ず知識のある人がやらなあかんで。あんま良くない設定をしたるとクライアントがちゃんと使えへんくなってくで。"
|
||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
|
squareAvatars: "アイコンを四角形で表示するで"
|
||||||
sent: "送信"
|
sent: "送信"
|
||||||
|
received: "受信"
|
||||||
|
searchResult: "検索結果やで"
|
||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
|
troubleshooting: "トラブルシューティング"
|
||||||
|
useBlurEffect: "UIにぼかし効果を使うで"
|
||||||
|
learnMore: "詳しく"
|
||||||
|
misskeyUpdated: "Misskeyが更新されたで!\nモデレーターの人らに感謝せなあかんで"
|
||||||
|
whatIsNew: "更新情報を見るで"
|
||||||
|
translate: "翻訳"
|
||||||
|
translatedFrom: "{x}から翻訳するで"
|
||||||
|
accountDeletionInProgress: "アカウント削除しとるで待っとってなー"
|
||||||
|
usernameInfo: "サーバー上であんたのアカウントをあんたやと分かるようにするための名前やで。アルファベット(a~z, A~Z)、数字(0~9)、それとアンダーバー(_)が使って考えてな。この名前は後から変更することはできへんからちゃんと考えるんやで。"
|
||||||
|
aiChanMode: "藍モードやで"
|
||||||
|
keepCw: "CWを維持するで"
|
||||||
|
pubSub: "Pub/Subのアカウント"
|
||||||
|
lastCommunication: "直近の通信"
|
||||||
|
resolved: "解決したで"
|
||||||
|
unresolved: "まだ解決してないで"
|
||||||
|
breakFollow: "フォロワーを解除するで"
|
||||||
|
itsOn: "オンになっとるよ"
|
||||||
hide: "隠す"
|
hide: "隠す"
|
||||||
searchByGoogle: "探す"
|
searchByGoogle: "探す"
|
||||||
indefinitely: "無期限"
|
indefinitely: "無期限"
|
||||||
file: "ファイル"
|
file: "ファイル"
|
||||||
|
requireAdminForView: "これを見るには管理者アカウントでログインしとらなあかんで。"
|
||||||
|
isSystemAccount: "システムが自動で作成・管理しとるアカウントやで。"
|
||||||
|
typeToConfirm: "この操作をやるんなら {x} と入力してなー"
|
||||||
|
deleteAccount: "アカウント削除するで"
|
||||||
|
document: "ドキュメント"
|
||||||
|
numberOfPageCache: "ページキャッシュ数やで"
|
||||||
|
numberOfPageCacheDescription: "増やすと使いやすくなる、負荷とメモリ使用量が増えてくで。一長一短やな。"
|
||||||
|
logoutConfirm: "ログアウトしまっか?"
|
||||||
|
lastActiveDate: "最後に使った日時"
|
||||||
|
statusbar: "ステータスバー"
|
||||||
|
pleaseSelect: "選択したってやー"
|
||||||
|
reverse: "反転"
|
||||||
|
colored: "色付き"
|
||||||
|
refreshInterval: "更新間隔"
|
||||||
|
label: "ラベル"
|
||||||
|
type: "タイプ"
|
||||||
|
speed: "速度"
|
||||||
|
slow: "遅い"
|
||||||
|
fast: "速い"
|
||||||
|
sensitiveMediaDetection: "センシティブなメディアの検出"
|
||||||
|
localOnly: "ローカルのみ"
|
||||||
|
remoteOnly: "リモートのみ"
|
||||||
|
failedToUpload: "アップロードに失敗したで"
|
||||||
|
cannotUploadBecauseInappropriate: "不適切な内容を含むかもしれへんって判定されたでアップロードできまへん。"
|
||||||
|
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いでアップロードできまへん。"
|
||||||
|
beta: "ベータ"
|
||||||
|
enableAutoSensitive: "自動NSFW判定"
|
||||||
|
enableAutoSensitiveDescription: "使える時は、機械学習を使って自動でメディアにNSFWフラグを設定するで。この機能をオフにしても、インスタンスによっては自動で設定されることがあるで。"
|
||||||
|
activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかとかを判定して積極的に行うで。オフにすると単に文字列として正しいかどうかだけチェックするで。"
|
||||||
|
navbar: "ナビゲーションバー"
|
||||||
|
shuffle: "シャッフルするで"
|
||||||
|
account: "アカウント"
|
||||||
|
move: "移動するで"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "機械学習を使って自動でセンシティブなメディアを検出して、モデレーションに役立てることができるで。サーバーの負荷が少し増えてまうなあ。"
|
||||||
|
sensitivity: "検出感度やで"
|
||||||
|
sensitivityDescription: "感度を低くすると、誤検知(偽陽性)が減るで。感度を高くすると、検知漏れ(偽陰性)が減るで。"
|
||||||
|
setSensitiveFlagAutomatically: "NSFWフラグを設定するで"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "この設定をオフにしても内部的に判定結果は保持されるで。"
|
||||||
|
_ffVisibility:
|
||||||
|
public: "公開"
|
||||||
_ad:
|
_ad:
|
||||||
back: "戻る"
|
back: "戻る"
|
||||||
_gallery:
|
_gallery:
|
||||||
|
@@ -57,6 +57,7 @@ selectAccount: "Fren amiḍan"
|
|||||||
accounts: "Imiḍan"
|
accounts: "Imiḍan"
|
||||||
searchByGoogle: "Nadi"
|
searchByGoogle: "Nadi"
|
||||||
file: "Ifuyla"
|
file: "Ifuyla"
|
||||||
|
account: "Imiḍan"
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "Yeṭṭafaṛ-ik·em-id"
|
title: "Yeṭṭafaṛ-ik·em-id"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "사용자 검색"
|
|||||||
reply: "답글"
|
reply: "답글"
|
||||||
loadMore: "더 보기"
|
loadMore: "더 보기"
|
||||||
showMore: "더 보기"
|
showMore: "더 보기"
|
||||||
|
showLess: "닫기"
|
||||||
youGotNewFollower: "새로운 팔로워가 있습니다"
|
youGotNewFollower: "새로운 팔로워가 있습니다"
|
||||||
receiveFollowRequest: "새로운 팔로우 요청이 있습니다"
|
receiveFollowRequest: "새로운 팔로우 요청이 있습니다"
|
||||||
followRequestAccepted: "팔로우가 수락되었습니다"
|
followRequestAccepted: "팔로우가 수락되었습니다"
|
||||||
@@ -203,6 +204,7 @@ done: "완료"
|
|||||||
processing: "처리중"
|
processing: "처리중"
|
||||||
preview: "미리보기"
|
preview: "미리보기"
|
||||||
default: "기본값"
|
default: "기본값"
|
||||||
|
defaultValueIs: "기본값: {value}"
|
||||||
noCustomEmojis: "이모지가 없습니다"
|
noCustomEmojis: "이모지가 없습니다"
|
||||||
noJobs: "작업이 없습니다"
|
noJobs: "작업이 없습니다"
|
||||||
federating: "연합 중"
|
federating: "연합 중"
|
||||||
@@ -381,6 +383,7 @@ administrator: "관리자"
|
|||||||
token: "토큰"
|
token: "토큰"
|
||||||
twoStepAuthentication: "2단계 인증"
|
twoStepAuthentication: "2단계 인증"
|
||||||
moderator: "모더레이터"
|
moderator: "모더레이터"
|
||||||
|
moderation: "모더레이션"
|
||||||
nUsersMentioned: "{n}명이 언급함"
|
nUsersMentioned: "{n}명이 언급함"
|
||||||
securityKey: "보안 키"
|
securityKey: "보안 키"
|
||||||
securityKeyName: "키 이름"
|
securityKeyName: "키 이름"
|
||||||
@@ -854,9 +857,48 @@ noEmailServerWarning: "메일 서버가 설정되어 있지 않습니다."
|
|||||||
thereIsUnresolvedAbuseReportWarning: "해결되지 않은 신고가 있습니다."
|
thereIsUnresolvedAbuseReportWarning: "해결되지 않은 신고가 있습니다."
|
||||||
recommended: "추천"
|
recommended: "추천"
|
||||||
check: "체크"
|
check: "체크"
|
||||||
|
driveCapOverrideLabel: "이 유저의 드라이브 용량을 변경"
|
||||||
|
driveCapOverrideCaption: "0 이하를 지정하면 해제됩니다."
|
||||||
|
requireAdminForView: "열람하려면 관리자 계정으로 로그인해야 합니다."
|
||||||
isSystemAccount: "시스템에 의해 자동으로 생성되어 관리되는 계정입니다."
|
isSystemAccount: "시스템에 의해 자동으로 생성되어 관리되는 계정입니다."
|
||||||
typeToConfirm: "계속하시려면 {x} 을 입력하세요"
|
typeToConfirm: "계속하시려면 {x} 을 입력하세요"
|
||||||
deleteAccount: "계정 삭제"
|
deleteAccount: "계정 삭제"
|
||||||
|
document: "문서"
|
||||||
|
numberOfPageCache: "페이지 캐시 수"
|
||||||
|
numberOfPageCacheDescription: "숫자가 클 수록 편리성이 높아지지만, 시스템 자원과 메모리를 더 많이 사용합니다."
|
||||||
|
logoutConfirm: "로그아웃 하시겠습니까?"
|
||||||
|
lastActiveDate: "마지막 이용"
|
||||||
|
pleaseSelect: "선택해 주세요"
|
||||||
|
reverse: "플립"
|
||||||
|
colored: "색 입히기"
|
||||||
|
refreshInterval: "업데이트 주기"
|
||||||
|
label: "라벨"
|
||||||
|
type: "종류"
|
||||||
|
speed: "속도"
|
||||||
|
slow: "느리게"
|
||||||
|
fast: "빠르게"
|
||||||
|
sensitiveMediaDetection: "민감한 미디어 탐지"
|
||||||
|
localOnly: "로컬에만"
|
||||||
|
remoteOnly: "리모트만"
|
||||||
|
failedToUpload: "업로드 실패"
|
||||||
|
cannotUploadBecauseInappropriate: "이 파일은 부적절한 내용을 포함한다고 판단되어 업로드할 수 없습니다."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "드라이브 용량이 부족하여 업로드할 수 없습니다."
|
||||||
|
beta: "베타"
|
||||||
|
enableAutoSensitive: "자동 NSFW 탐지"
|
||||||
|
enableAutoSensitiveDescription: "이용 가능할 경우 기계학습을 통해 자동으로 미디어 NSFW를 설정합니다. 이 기능을 해제하더라도, 인스턴스 정책에 따라 자동으로 설정될 수 있습니다."
|
||||||
|
activeEmailValidationDescription: "유저가 입력한 메일 주소가 일회용 메일인지, 실제로 통신할 수 있는 지 엄격하게 검사합니다. 해제할 경우 이메일 형식에 대해서만 검사합니다."
|
||||||
|
navbar: "네비게이션 바"
|
||||||
|
shuffle: "셔플"
|
||||||
|
account: "계정"
|
||||||
|
move: "이동"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "기계학습을 통해 자동으로 민감한 미디어를 탐지하여, 모더레이션에 참고할 수 있도록 합니다. 서버의 부하를 약간 증가시킵니다."
|
||||||
|
sensitivity: "탐지 민감도"
|
||||||
|
sensitivityDescription: "민감도가 낮을수록 안전한 미디어가 잘못 탐지될 확률이 줄어들며, 높을수록 민감한 미디어가 탐지되지 않을 확률이 줄어듭니다."
|
||||||
|
setSensitiveFlagAutomatically: "자동으로 NSFW로 설정하기"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "이 설정을 해제해도 탐지 결과는 유지됩니다."
|
||||||
|
analyzeVideos: "동영상도 같이 확인하기"
|
||||||
|
analyzeVideosDescription: "사진 뿐만 아니라 동영상의 NSFW 여부도 탐지합니다. 서버의 부하를 약간 증가시킵니다."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "이 메일 주소는 사용중입니다"
|
used: "이 메일 주소는 사용중입니다"
|
||||||
format: "형식이 올바르지 않습니다"
|
format: "형식이 올바르지 않습니다"
|
||||||
@@ -982,6 +1024,8 @@ _mfm:
|
|||||||
sparkleDescription: "반짝이는 파티클 효과를 추가합니다."
|
sparkleDescription: "반짝이는 파티클 효과를 추가합니다."
|
||||||
rotate: "회전"
|
rotate: "회전"
|
||||||
rotateDescription: "지정한 각도로 회전시킵니다."
|
rotateDescription: "지정한 각도로 회전시킵니다."
|
||||||
|
plain: "평문"
|
||||||
|
plainDescription: "안에 있는 MFM 구문을 모두 무시하고 평문으로 표시합니다."
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "보이지 않음"
|
none: "보이지 않음"
|
||||||
remote: "리모트 유저에게만 보이기"
|
remote: "리모트 유저에게만 보이기"
|
||||||
@@ -1215,6 +1259,7 @@ _widgets:
|
|||||||
photos: "사진"
|
photos: "사진"
|
||||||
digitalClock: "디지털 시계"
|
digitalClock: "디지털 시계"
|
||||||
federation: "연합"
|
federation: "연합"
|
||||||
|
instanceCloud: "인스턴스 구름"
|
||||||
postForm: "글 입력란"
|
postForm: "글 입력란"
|
||||||
slideshow: "슬라이드 쇼"
|
slideshow: "슬라이드 쇼"
|
||||||
button: "버튼"
|
button: "버튼"
|
||||||
@@ -1653,6 +1698,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "메인 칼럼 항상 표시"
|
alwaysShowMainColumn: "메인 칼럼 항상 표시"
|
||||||
columnAlign: "칼럼 정렬"
|
columnAlign: "칼럼 정렬"
|
||||||
addColumn: "칼럼 추가"
|
addColumn: "칼럼 추가"
|
||||||
|
configureColumn: "칼럼 설정"
|
||||||
swapLeft: "왼쪽으로 이동"
|
swapLeft: "왼쪽으로 이동"
|
||||||
swapRight: "오른쪽으로 이동"
|
swapRight: "오른쪽으로 이동"
|
||||||
swapUp: "위로 이동"
|
swapUp: "위로 이동"
|
||||||
@@ -1660,6 +1706,11 @@ _deck:
|
|||||||
stackLeft: "왼쪽에 쌓기"
|
stackLeft: "왼쪽에 쌓기"
|
||||||
popRight: "오른쪽으로 빼기"
|
popRight: "오른쪽으로 빼기"
|
||||||
profile: "프로파일"
|
profile: "프로파일"
|
||||||
|
newProfile: "새 프로파일"
|
||||||
|
deleteProfile: "프로파일 삭제"
|
||||||
|
introduction: "칼럼을 조합해서 나만의 인터페이스를 구성해 보아요!"
|
||||||
|
introduction2: "나중에라도 화면 우측의 + 버튼을 눌러 새 칼럼을 추가할 수 있습니다."
|
||||||
|
widgetsIntroduction: "칼럼 메뉴의 \"위젯 편집\"에서 위젯을 추가해 주세요"
|
||||||
_columns:
|
_columns:
|
||||||
main: "메인"
|
main: "메인"
|
||||||
widgets: "위젯"
|
widgets: "위젯"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Wyszukiwanie użytkowników"
|
|||||||
reply: "Odpowiedz"
|
reply: "Odpowiedz"
|
||||||
loadMore: "Załaduj więcej"
|
loadMore: "Załaduj więcej"
|
||||||
showMore: "Załaduj więcej"
|
showMore: "Załaduj więcej"
|
||||||
|
showLess: "Zamknij"
|
||||||
youGotNewFollower: "Zaobserwował(a) Cię"
|
youGotNewFollower: "Zaobserwował(a) Cię"
|
||||||
receiveFollowRequest: "Otrzymano prośbę o możliwość obserwacji"
|
receiveFollowRequest: "Otrzymano prośbę o możliwość obserwacji"
|
||||||
followRequestAccepted: "Zaakceptowano prośbę o możliwość obserwacji"
|
followRequestAccepted: "Zaakceptowano prośbę o możliwość obserwacji"
|
||||||
@@ -761,6 +762,10 @@ hide: "Ukryj"
|
|||||||
searchByGoogle: "Szukaj"
|
searchByGoogle: "Szukaj"
|
||||||
indefinitely: "Nigdy"
|
indefinitely: "Nigdy"
|
||||||
file: "Pliki"
|
file: "Pliki"
|
||||||
|
reverse: "Odwróć"
|
||||||
|
colored: "Kolorowe"
|
||||||
|
label: "Etykieta"
|
||||||
|
account: "Konta"
|
||||||
_ffVisibility:
|
_ffVisibility:
|
||||||
public: "Publikuj"
|
public: "Publikuj"
|
||||||
_ad:
|
_ad:
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Pesquisar utilizador"
|
|||||||
reply: "Responder"
|
reply: "Responder"
|
||||||
loadMore: "Carregar mais"
|
loadMore: "Carregar mais"
|
||||||
showMore: "Ver mais"
|
showMore: "Ver mais"
|
||||||
|
showLess: "Fechar"
|
||||||
youGotNewFollower: "Você tem um novo seguidor"
|
youGotNewFollower: "Você tem um novo seguidor"
|
||||||
receiveFollowRequest: "Pedido de seguimento recebido"
|
receiveFollowRequest: "Pedido de seguimento recebido"
|
||||||
followRequestAccepted: "Pedido de seguir aceito"
|
followRequestAccepted: "Pedido de seguir aceito"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Caută un utilizator"
|
|||||||
reply: "Răspunde"
|
reply: "Răspunde"
|
||||||
loadMore: "Incarcă mai mult"
|
loadMore: "Incarcă mai mult"
|
||||||
showMore: "Arată mai mult"
|
showMore: "Arată mai mult"
|
||||||
|
showLess: "Închide"
|
||||||
youGotNewFollower: "te-a urmărit"
|
youGotNewFollower: "te-a urmărit"
|
||||||
receiveFollowRequest: "Cerere de urmărire primită"
|
receiveFollowRequest: "Cerere de urmărire primită"
|
||||||
followRequestAccepted: "Cerere de urmărire acceptată"
|
followRequestAccepted: "Cerere de urmărire acceptată"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Поиск людей"
|
|||||||
reply: "Ответить"
|
reply: "Ответить"
|
||||||
loadMore: "Показать еще"
|
loadMore: "Показать еще"
|
||||||
showMore: "Показать еще"
|
showMore: "Показать еще"
|
||||||
|
showLess: "Закрыть"
|
||||||
youGotNewFollower: "Новый подписчик"
|
youGotNewFollower: "Новый подписчик"
|
||||||
receiveFollowRequest: "Получен запрос на подписку"
|
receiveFollowRequest: "Получен запрос на подписку"
|
||||||
followRequestAccepted: "Запрос на подписку принят"
|
followRequestAccepted: "Запрос на подписку принят"
|
||||||
@@ -203,6 +204,7 @@ done: "Готово"
|
|||||||
processing: "Обработка"
|
processing: "Обработка"
|
||||||
preview: "Предпросмотр"
|
preview: "Предпросмотр"
|
||||||
default: "По умолчанию"
|
default: "По умолчанию"
|
||||||
|
defaultValueIs: "По умолчанию: {value}"
|
||||||
noCustomEmojis: "Собственные эмодзи отсутствуют"
|
noCustomEmojis: "Собственные эмодзи отсутствуют"
|
||||||
noJobs: "Нет заданий"
|
noJobs: "Нет заданий"
|
||||||
federating: "Федерируется"
|
federating: "Федерируется"
|
||||||
@@ -834,6 +836,20 @@ instanceDefaultLightTheme: "Светлая тема по умолчанию"
|
|||||||
instanceDefaultDarkTheme: "Темная тема по умолчанию"
|
instanceDefaultDarkTheme: "Темная тема по умолчанию"
|
||||||
indefinitely: "вечно"
|
indefinitely: "вечно"
|
||||||
file: "Файлы"
|
file: "Файлы"
|
||||||
|
recommended: "Рекомендуем"
|
||||||
|
check: "Проверить"
|
||||||
|
driveCapOverrideLabel: "Изменение лимита дискового пространства для этого пользователя"
|
||||||
|
reverse: "Переворот"
|
||||||
|
colored: "Выделена цветом"
|
||||||
|
label: "Метка"
|
||||||
|
localOnly: "Локально"
|
||||||
|
beta: "Бета"
|
||||||
|
enableAutoSensitive: "Автоматическое определение NSFW"
|
||||||
|
enableAutoSensitiveDescription: "Если доступно, используйте машинное обучение для автоматической установки флага NSFW на носителе. Даже если эта функция отключена, она может быть установлена автоматически в зависимости от инстанта."
|
||||||
|
account: "Учётные записи"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно."
|
||||||
|
setSensitiveFlagAutomatically: "Установить флаг NSFW"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Уже используется"
|
used: "Уже используется"
|
||||||
format: "Неверный формат"
|
format: "Неверный формат"
|
||||||
@@ -1622,6 +1638,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Всегда показывать главную колонку"
|
alwaysShowMainColumn: "Всегда показывать главную колонку"
|
||||||
columnAlign: "Выравнивание колонок"
|
columnAlign: "Выравнивание колонок"
|
||||||
addColumn: "Добавить колонку"
|
addColumn: "Добавить колонку"
|
||||||
|
configureColumn: "Настройки колонок"
|
||||||
swapLeft: "Переставить левее"
|
swapLeft: "Переставить левее"
|
||||||
swapRight: "Переставить правее"
|
swapRight: "Переставить правее"
|
||||||
swapUp: "Переставить выше"
|
swapUp: "Переставить выше"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Hľadať používateľov"
|
|||||||
reply: "Odpovedať"
|
reply: "Odpovedať"
|
||||||
loadMore: "Zobraziť viac"
|
loadMore: "Zobraziť viac"
|
||||||
showMore: "Zobraziť viac"
|
showMore: "Zobraziť viac"
|
||||||
|
showLess: "Zavrieť"
|
||||||
youGotNewFollower: "Máte nového sledujúceho"
|
youGotNewFollower: "Máte nového sledujúceho"
|
||||||
receiveFollowRequest: "Žiadosť o sledovanie prijatá"
|
receiveFollowRequest: "Žiadosť o sledovanie prijatá"
|
||||||
followRequestAccepted: "Žiadosť o sledovanie akceptovaná"
|
followRequestAccepted: "Žiadosť o sledovanie akceptovaná"
|
||||||
@@ -561,6 +562,7 @@ author: "Autor"
|
|||||||
leaveConfirm: "Máte neuložené zmeny. Chcete ich zahodiť?"
|
leaveConfirm: "Máte neuložené zmeny. Chcete ich zahodiť?"
|
||||||
manage: "Administrácia"
|
manage: "Administrácia"
|
||||||
plugins: "Pluginy"
|
plugins: "Pluginy"
|
||||||
|
preferencesBackups: "Zálohy nastavení"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
useBlurEffectForModal: "Použiť efekt rozmazania na okná"
|
useBlurEffectForModal: "Použiť efekt rozmazania na okná"
|
||||||
useFullReactionPicker: "Použiť plnú veľkosť výberu reakcií"
|
useFullReactionPicker: "Použiť plnú veľkosť výberu reakcií"
|
||||||
@@ -865,6 +867,35 @@ numberOfPageCacheDescription: "Zvýši rýchlosť ale tiež nároky na pamäť."
|
|||||||
logoutConfirm: "Naozaj sa chcete odhlásiť?"
|
logoutConfirm: "Naozaj sa chcete odhlásiť?"
|
||||||
statusbar: "Stavový riadok"
|
statusbar: "Stavový riadok"
|
||||||
pleaseSelect: "Prosím vyberte"
|
pleaseSelect: "Prosím vyberte"
|
||||||
|
reverse: "Preklopiť"
|
||||||
|
colored: "Farebné"
|
||||||
|
refreshInterval: "Interval obnovenia"
|
||||||
|
label: "Popisok"
|
||||||
|
type: "Typ"
|
||||||
|
speed: "Rýchlosť"
|
||||||
|
slow: "Pomaly"
|
||||||
|
fast: "Rýchlo"
|
||||||
|
sensitiveMediaDetection: "Detekcia citlivých médií."
|
||||||
|
localOnly: "Iba lokálne"
|
||||||
|
remoteOnly: "Len vzdialené"
|
||||||
|
failedToUpload: "Nahrávanie zlyhalo"
|
||||||
|
cannotUploadBecauseInappropriate: "Nemožno nahrať, pretože pravdepodobne obsahuje nevhodný obsah."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "Nemožno nahrať kvôli nedostatku voľného úložiska."
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "Automatická detekcia NSFW"
|
||||||
|
enableAutoSensitiveDescription: "Ak je zapnuté, príznak NSFW sa na médiách automaticky nastaví pomocou strojového učenia. Aj keď je táto funkcia vypnutá, v niektorých prípadoch sa môže nastaviť automaticky."
|
||||||
|
activeEmailValidationDescription: "Dôkladnejšie overí e-mailovú adresu používateľa tým, že zistí, či ide o vyradenú e-mailovú adresu a či sa s ňou dá skutočne komunikovať. Ak nie je začiarknuté, e-mailová adresa sa kontroluje len ako text."
|
||||||
|
navbar: "Navigačný panel"
|
||||||
|
account: "Účty"
|
||||||
|
move: "Pohyb"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Strojové učenie sa použije na automatickú detekciu citlivých médií na účely ich moderovania. Mierne sa zvýši zaťaženie servera."
|
||||||
|
sensitivity: "Citlivosť detekcie"
|
||||||
|
sensitivityDescription: "Nižšia citlivosť znižuje počet falošne pozitívnych výsledkov (false positives). Vyššia citlivosť znižuje počet falošne negatívnych výsledkov (false negatives)."
|
||||||
|
setSensitiveFlagAutomatically: "Nastaviť príznak NSFW"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "Aj keď je toto nastavenie vypnuté, výsledok rozhodnutia je interne uložený."
|
||||||
|
analyzeVideos: "Zapnúť analýzu videa"
|
||||||
|
analyzeVideosDescription: "Okrem obrázkov zapne detekciu aj pre videá. Zaťaženie servera sa mierne zvýši."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Táto emailová adresa sa už používa"
|
used: "Táto emailová adresa sa už používa"
|
||||||
format: "Formát emailovej adresy je nesprávny"
|
format: "Formát emailovej adresy je nesprávny"
|
||||||
@@ -907,6 +938,24 @@ _plugin:
|
|||||||
install: "Inštalova pluginy"
|
install: "Inštalova pluginy"
|
||||||
installWarn: "Prosím neinštalujte nedôveryhodné pluginy."
|
installWarn: "Prosím neinštalujte nedôveryhodné pluginy."
|
||||||
manage: "Spravovanie pluginov"
|
manage: "Spravovanie pluginov"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "Vytvorené zálohy"
|
||||||
|
saveNew: "Uložiť novú"
|
||||||
|
loadFile: "Nahrať súbor"
|
||||||
|
apply: "Použiť na toto zariadenie"
|
||||||
|
save: "Uložiť"
|
||||||
|
inputName: "Názov zálohy"
|
||||||
|
cannotSave: "Nedá sa uložiť"
|
||||||
|
nameAlreadyExists: "Záloha s názvom \"{name}\" už existuje. Zadajte iný názov."
|
||||||
|
applyConfirm: "Chcete použiť zálohu '{name}' na aktuálne zariadenie? Aktuálne nastavenia zariadenia sa stratia."
|
||||||
|
saveConfirm: "Chcete prepísať {name}?"
|
||||||
|
deleteConfirm: "Naozaj chcete odstrániť \"{name}\"?"
|
||||||
|
renameConfirm: "Chcete zmeniť \"{old}\" na \"{new}\"?"
|
||||||
|
noBackups: "Nie je k dispozícii žiadna záloha. \"Uložiť novú\" umožňuje uložiť aktuálnu konfiguráciu zariadenia na server."
|
||||||
|
createdAt: "Dátum vytvorenia: {date} {time}"
|
||||||
|
updatedAt: "Dátum úpravy: {date} {time}"
|
||||||
|
cannotLoad: "Nedá sa nahrať"
|
||||||
|
invalidFile: "Neplatný formát súboru"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "Oblasť"
|
scope: "Oblasť"
|
||||||
key: "Kľúč"
|
key: "Kľúč"
|
||||||
@@ -990,6 +1039,8 @@ _mfm:
|
|||||||
sparkleDescription: "Obsahu dodá trblietajúci efekt."
|
sparkleDescription: "Obsahu dodá trblietajúci efekt."
|
||||||
rotate: "Otáčať"
|
rotate: "Otáčať"
|
||||||
rotateDescription: "Otočí obsah o určitý uhol."
|
rotateDescription: "Otočí obsah o určitý uhol."
|
||||||
|
plain: "Obyčajné"
|
||||||
|
plainDescription: "Bez akejkoľvej syntaxe"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "Nikdy nezobrazovať"
|
none: "Nikdy nezobrazovať"
|
||||||
remote: "Zobraziť pre vzdialených používateľov"
|
remote: "Zobraziť pre vzdialených používateľov"
|
||||||
@@ -1223,6 +1274,7 @@ _widgets:
|
|||||||
activity: "Aktivita"
|
activity: "Aktivita"
|
||||||
photos: "Fotky"
|
photos: "Fotky"
|
||||||
digitalClock: "Digitálne hodiny"
|
digitalClock: "Digitálne hodiny"
|
||||||
|
unixClock: "UNIX čas"
|
||||||
federation: "Federácia"
|
federation: "Federácia"
|
||||||
instanceCloud: "Cloud serverov"
|
instanceCloud: "Cloud serverov"
|
||||||
postForm: "Napísať poznámku"
|
postForm: "Napísať poznámku"
|
||||||
@@ -1663,6 +1715,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Vždy zobraziť v hlavnom stĺpci"
|
alwaysShowMainColumn: "Vždy zobraziť v hlavnom stĺpci"
|
||||||
columnAlign: "Zarovnať stĺpce"
|
columnAlign: "Zarovnať stĺpce"
|
||||||
addColumn: "Pridať stĺpec"
|
addColumn: "Pridať stĺpec"
|
||||||
|
configureColumn: "Nastavenie stĺpcov"
|
||||||
swapLeft: "Vymeniť vľavo"
|
swapLeft: "Vymeniť vľavo"
|
||||||
swapRight: "Vymeniť vpravo"
|
swapRight: "Vymeniť vpravo"
|
||||||
swapUp: "Vymeniť hore"
|
swapUp: "Vymeniť hore"
|
||||||
@@ -1670,6 +1723,8 @@ _deck:
|
|||||||
stackLeft: "Priložiť do ľavého stĺpca"
|
stackLeft: "Priložiť do ľavého stĺpca"
|
||||||
popRight: "Vybrať napravo"
|
popRight: "Vybrať napravo"
|
||||||
profile: "Profil"
|
profile: "Profil"
|
||||||
|
newProfile: "Nový profil"
|
||||||
|
deleteProfile: "Odstrániť profil"
|
||||||
introduction: "Kombinujte stĺpce a vytvorte si svoje vlastné rozhranie!"
|
introduction: "Kombinujte stĺpce a vytvorte si svoje vlastné rozhranie!"
|
||||||
introduction2: "Stlačením tlačidla + v pravej časti obrazovky môžete kedykoľvek pridať stĺpce."
|
introduction2: "Stlačením tlačidla + v pravej časti obrazovky môžete kedykoľvek pridať stĺpce."
|
||||||
widgetsIntroduction: "V ponuke stĺpca vyberte možnosť \"Upraviť widget\" a pridajte widget"
|
widgetsIntroduction: "V ponuke stĺpca vyberte možnosť \"Upraviť widget\" a pridajte widget"
|
||||||
|
@@ -203,6 +203,7 @@ done: "Klar"
|
|||||||
processing: "Bearbetar..."
|
processing: "Bearbetar..."
|
||||||
preview: "Förhandsvisning"
|
preview: "Förhandsvisning"
|
||||||
default: "Standard"
|
default: "Standard"
|
||||||
|
defaultValueIs: "Standard: {value}"
|
||||||
noCustomEmojis: "Det finns ingen emoji"
|
noCustomEmojis: "Det finns ingen emoji"
|
||||||
noJobs: "Det finns inga jobb"
|
noJobs: "Det finns inga jobb"
|
||||||
federating: "Federerar"
|
federating: "Federerar"
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "ค้นหาผู้ใช้งาน"
|
|||||||
reply: "ตอบกลับ"
|
reply: "ตอบกลับ"
|
||||||
loadMore: "โหลดเพิ่มเติม"
|
loadMore: "โหลดเพิ่มเติม"
|
||||||
showMore: "แสดงเพิ่มเติม"
|
showMore: "แสดงเพิ่มเติม"
|
||||||
|
showLess: "ปิด"
|
||||||
youGotNewFollower: "ได้ติดตามคุณ"
|
youGotNewFollower: "ได้ติดตามคุณ"
|
||||||
receiveFollowRequest: "คำขอผู้ติดตามที่ได้รับ"
|
receiveFollowRequest: "คำขอผู้ติดตามที่ได้รับ"
|
||||||
followRequestAccepted: "ผู้ติดตามได้ตอบรับคำขอร้องของคุณแล้ว"
|
followRequestAccepted: "ผู้ติดตามได้ตอบรับคำขอร้องของคุณแล้ว"
|
||||||
@@ -795,10 +796,123 @@ whatIsNew: "แสดงการเปลี่ยนแปลง"
|
|||||||
translate: "แปลภาษา"
|
translate: "แปลภาษา"
|
||||||
translatedFrom: "แปลมาจาก {x}"
|
translatedFrom: "แปลมาจาก {x}"
|
||||||
accountDeletionInProgress: "กำลังดำเนินการลบบัญชีอยู่"
|
accountDeletionInProgress: "กำลังดำเนินการลบบัญชีอยู่"
|
||||||
|
usernameInfo: "ชื่อที่ระบุบัญชีของคุณจากผู้อื่นในเซิร์ฟเวอร์นี้ คุณสามารถใช้ตัวอักษร (a~z, A~Z), ตัวเลข (0~9) หรือขีดล่าง (_) ชื่อผู้ใช้ไม่สามารถเปลี่ยนแปลงได้ในภายหลัง"
|
||||||
|
aiChanMode: "โหมด Ai "
|
||||||
|
keepCw: "เก็บคำเตือนเนื้อหา"
|
||||||
|
pubSub: "บัญชีผับ/ย่อย"
|
||||||
|
lastCommunication: "การสื่อสารครั้งสุดท้ายล่าสุด"
|
||||||
|
resolved: "คลี่คลายแล้ว"
|
||||||
|
unresolved: "รอการเฉลย"
|
||||||
|
breakFollow: "ลบผู้ติดตาม"
|
||||||
|
itsOn: "เปิดใช้งาน"
|
||||||
|
itsOff: "ปิดใช้งาน"
|
||||||
|
emailRequiredForSignup: "จำเป็นต้องการใช้ที่อยู่อีเมลสำหรับการสมัคร"
|
||||||
|
unread: "ไม่ได้อ่าน"
|
||||||
|
filter: "กรอง"
|
||||||
|
controlPanel: "แผงควบคุม"
|
||||||
|
manageAccounts: "จัดการบัญชี"
|
||||||
|
makeReactionsPublic: "ตั้งค่าประวัติปฏิกิริยาต่อสาธารณะ"
|
||||||
|
makeReactionsPublicDescription: "การทำเช่นนี้จะทำให้รายการปฏิกิริยาที่ผ่านมาของคุณจะปรากฏต่อสาธารณะนะ"
|
||||||
|
classic: "คลาสสิค"
|
||||||
|
muteThread: "ปิดเสียงเธรด"
|
||||||
|
unmuteThread: "เปิดเสียงเธรด"
|
||||||
|
ffVisibility: "การมองเห็นผู้ติดตาม/ผู้ติดตาม"
|
||||||
|
ffVisibilityDescription: "ช่วยให้คุณสามารถกำหนดค่าได้ว่าใครสามารถดูได้ว่าคุณติดตามใครและใครติดตามคุณบ้าง"
|
||||||
|
continueThread: "ดูความต่อเนื่องเธรด"
|
||||||
|
deleteAccountConfirm: "การดำเนินการนี้จะลบบัญชีของคุณอย่างถาวรเลยนะ แน่ใจหรอดำเนินการ?"
|
||||||
|
incorrectPassword: "รหัสผ่านไม่ถูกต้อง"
|
||||||
|
voteConfirm: "ยืนยันการโหวต \"{choice}\" มั้ย?"
|
||||||
|
hide: "ซ่อน"
|
||||||
|
leaveGroup: "ออกจากกลุ่ม"
|
||||||
|
leaveGroupConfirm: "คุณแน่ใจหรอว่าต้องการออกจาก \"{name}\""
|
||||||
|
useDrawerReactionPickerForMobile: "แสดงผล ตัวเลือกปฏิกิริยาเป็นลิ้นชักบนมือถือ"
|
||||||
|
welcomeBackWithName: "ยินดีต้อนรับการกลับมานะค่ะ, {name}"
|
||||||
|
clickToFinishEmailVerification: "กรุณาคลิก [{ok}] เพื่อดำเนินการยืนยันอีเมลให้เสร็จสมบูรณ์นะ"
|
||||||
|
overridedDeviceKind: "ประเภทอุปกรณ์"
|
||||||
|
smartphone: "สมาร์ทโฟน"
|
||||||
|
tablet: "แท็บเล็ต"
|
||||||
|
auto: "อัตโนมัติ"
|
||||||
|
themeColor: "อินสแตนซ์ Ticker Color"
|
||||||
|
size: "ขนาด"
|
||||||
|
numberOfColumn: "จำนวนคอลัมน์"
|
||||||
searchByGoogle: "ค้นหา"
|
searchByGoogle: "ค้นหา"
|
||||||
|
instanceDefaultLightTheme: "ธีมสว่างค่าเริ่มต้นสำหรับอินสแตนซ์"
|
||||||
|
instanceDefaultDarkTheme: "ธีมมืดค่าเริ่มต้นอินสแตนซ์"
|
||||||
|
instanceDefaultThemeDescription: "ป้อนรหัสธีมในรูปแบบออบเจ็กต์"
|
||||||
|
mutePeriod: "ระยะเวลาปิดเสียง"
|
||||||
|
indefinitely: "ตลอดไป"
|
||||||
|
tenMinutes: "10 นาที"
|
||||||
|
oneHour: "1 ชั่วโมง"
|
||||||
|
oneDay: "1 วัน"
|
||||||
|
oneWeek: "1 สัปดาห์"
|
||||||
|
reflectMayTakeTime: "อาจจำเป็นต้องใช้เวลาสักระยะหนึ่งจึงจะเห็นแสดงผลได้นะ"
|
||||||
|
failedToFetchAccountInformation: "ไม่สามารถเรียกดึงข้อมูลบัญชีได้"
|
||||||
|
rateLimitExceeded: "เกินขีดจำกัดอัตรา"
|
||||||
|
cropImage: "ครอบตัดรูปภาพ"
|
||||||
|
cropImageAsk: "คุณต้องการครอบตัดรูปภาพนี้อย่างงั้นหรือ?"
|
||||||
file: "ไฟล์"
|
file: "ไฟล์"
|
||||||
|
recentNHours: "ล่าสุด {n} ชั่วโมงที่แล้ว"
|
||||||
|
recentNDays: "ล่าสุด {n} วันที่แล้ว"
|
||||||
|
noEmailServerWarning: "ไม่ได้กำหนดค่าเซิร์ฟเวอร์อีเมลนี้"
|
||||||
|
thereIsUnresolvedAbuseReportWarning: "มีรายงานที่ยังไม่ได้แก้ไข"
|
||||||
|
recommended: "แนะนำ"
|
||||||
|
check: "ตรวจสอบ"
|
||||||
|
driveCapOverrideLabel: "เปลี่ยนความจุของไดรฟ์สำหรับผู้ใช้รายนี้"
|
||||||
|
driveCapOverrideCaption: "รีเซ็ตความจุเป็นค่าเริ่มต้นโดยการป้อนค่าเป็น 0 หรือ ต่ำกว่า"
|
||||||
|
requireAdminForView: "คุณจำเป็นต้องเข้าสู่ระบบด้วยบัญชีผู้ดูแลระบบเพื่อเข้าดูสิ่งนี้"
|
||||||
|
isSystemAccount: "บัญชีที่ถูกสร้างมานั้น และถูกดำเนินการโดยอัตโนมัติด้วยระบบ"
|
||||||
|
typeToConfirm: "โปรดป้อน {x} เพื่อยืนยัน"
|
||||||
|
deleteAccount: "ลบบัญชี"
|
||||||
|
document: "เอกสาร"
|
||||||
|
numberOfPageCache: "จำนวนหน้าเพจที่แคช"
|
||||||
|
numberOfPageCacheDescription: "การเพิ่มจำนวนนี้จะช่วยเพิ่มความสะดวกให้กับผู้ใช้งาน แต่จะทำให้เซิร์ฟเวอร์โหลดมากขึ้นและต้องใช้หน่วยความจำมากขึ้นอีกด้วย"
|
||||||
|
logoutConfirm: "คุณแน่ใจว่าต้องการออกจากระบบ?"
|
||||||
|
lastActiveDate: "ใช้งานล่าสุดที่"
|
||||||
|
statusbar: "ไอคอนบนแถบสถานะ"
|
||||||
|
pleaseSelect: "ตัวเลือก"
|
||||||
|
reverse: "ย้อนกลับ"
|
||||||
|
colored: "สี"
|
||||||
|
refreshInterval: "รอบการอัพเดต"
|
||||||
|
label: "ป้ายชื่อ"
|
||||||
|
type: "รูปแบบ"
|
||||||
|
speed: "ความเร็ว"
|
||||||
|
slow: "ช้า"
|
||||||
|
fast: "เร็ว"
|
||||||
|
sensitiveMediaDetection: "การตรวจจับของสื่อ NSFW"
|
||||||
|
localOnly: "เฉพาะท้องถิ่น"
|
||||||
|
remoteOnly: "รีโมทเท่านั้น"
|
||||||
|
failedToUpload: "การอัปโหลดล้มเหลว"
|
||||||
|
cannotUploadBecauseInappropriate: "ไม่สามารถอัปโหลดไฟล์นี้ได้เนื่องจากระบบตรวจพบบางส่วนของไฟล์ว่านี้อาจจะเป็น NSFW"
|
||||||
|
cannotUploadBecauseNoFreeSpace: "การอัปโหลดนั้นล้มเหลวเนื่องจากไม่มีความจุของไดรฟ์"
|
||||||
|
beta: "เบต้า"
|
||||||
|
enableAutoSensitive: "ทำเครื่องหมาย NSFW อัตโนมัติ"
|
||||||
|
enableAutoSensitiveDescription: "อนุญาตให้ตรวจหาและทำเครื่องหมายสื่อ NSFW โดยอัตโนมัติผ่านการเรียนรู้ของเครื่องหากเป็นไปได้ แม้ว่าตัวเลือกนี้จะถูกปิดใช้งาน แต่ก็สามารถเปิดใช้งานได้ทั้งอินสแตนซ์นี้"
|
||||||
|
activeEmailValidationDescription: "เปิดใช้งานการตรวจสอบที่อยู่อีเมลให้มีความเข้มงวดยิ่งขึ้น ซึ่งอาจจะรวมไปถึงการตรวจสอบที่อยู่อีเมล์ที่ใช้แล้วทิ้งและโดยให้พิจารณาว่าสามารถสื่อสารด้วยได้หรือไม่ เมื่อไม่เลือกระบบจะตรวจสอบเฉพาะรูปแบบของอีเมลเท่านั้น"
|
||||||
|
navbar: "แถบนำทาง"
|
||||||
|
shuffle: "สลับ"
|
||||||
|
account: "บัญชีผู้ใช้"
|
||||||
|
move: "ย้าย"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "ลดความพยายามในการดูแลเซิร์ฟเวอร์ผ่านการจดจำสื่อ NSFW โดยอัตโนมัติผ่านการเรียนรู้ของเครื่อง การทำสิ่งนี้อาจจะเพิ่มภาระบนเซิร์ฟเวอร์เล็กน้อย"
|
||||||
|
sensitivity: "การตรวจจับความไว"
|
||||||
|
sensitivityDescription: "การลดความไวนั้นจะนำไปสู่การตรวจจับที่ผิดพลาดน้อยลง (ผลบวกที่ผิดพลาด) แต่ในขณะที่การเพิ่มนั้นจะนำไปสู่การตรวจหาที่พลาดน้อยลง (ผลลบเท็จ)"
|
||||||
|
setSensitiveFlagAutomatically: "ทำเครื่องหมายว่าเป็น NSFW"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "ผลลัพธ์ของการตรวจจับภายในนั้นจะยังคงอยู่ ถึงแม้ว่าจะปิดตัวเลือกนี้"
|
||||||
|
analyzeVideos: "เปิดใช้งานวิเคราะห์ของวิดีโอ"
|
||||||
|
analyzeVideosDescription: "การวิเคราะห์วิดีโอนอกเหนือจากรูปภาพนั้น การทำสิ่งนี้จะทำให้เพิ่มภาระบนเซิร์ฟเวอร์เล็กน้อย"
|
||||||
|
_emailUnavailable:
|
||||||
|
used: "ที่อยู่อีเมลนี้ได้ถูกใช้ไปแล้ว"
|
||||||
|
format: "รูปแบบของที่อยู่อีเมลนี้ไม่ถูกต้อง"
|
||||||
|
disposable: "ที่อยู่อีเมลที่ใช้แล้วทิ้งนั้นไม่สามารถใช้ได้"
|
||||||
|
mx: "เซิร์ฟเวอร์อีเมลนี้ไม่ถูกต้อง"
|
||||||
|
smtp: "เซิร์ฟเวอร์อีเมลนี้ไม่มีการตอบสนอง"
|
||||||
_ffVisibility:
|
_ffVisibility:
|
||||||
public: "เผยแพร่"
|
public: "เผยแพร่"
|
||||||
|
followers: "ปรากฏให้แก่ผู้ติดตามเท่านั้น"
|
||||||
|
private: "ส่วนตัว"
|
||||||
|
_signup:
|
||||||
|
almostThere: "เกือบจะมี"
|
||||||
|
emailAddressInfo: "โปรดกรอกอีเมลของคุณ มันจะไม่เปิดเผยต่อสาธารณะ"
|
||||||
_ad:
|
_ad:
|
||||||
back: "ย้อนกลับ"
|
back: "ย้อนกลับ"
|
||||||
_email:
|
_email:
|
||||||
@@ -806,9 +920,22 @@ _email:
|
|||||||
title: "ได้ติดตามคุณ"
|
title: "ได้ติดตามคุณ"
|
||||||
_mfm:
|
_mfm:
|
||||||
mention: "กล่าวถึง"
|
mention: "กล่าวถึง"
|
||||||
|
centerDescription: "แสดงผลเนื้อหาเป็นศูนย์กลาง"
|
||||||
|
inlineCode: "โค้ด (อินไลน์)"
|
||||||
|
inlineCodeDescription: "แสดงผลการเน้นไวยากรณ์แบบอินไลน์สำหรับโค้ด (โปรแกรม)"
|
||||||
|
blockCode: "โค้ด (บล็อก)"
|
||||||
|
blockCodeDescription: "แสดงผลการเน้นไวยากรณ์สำหรับโค้ดหลายบรรทัด (โปรแกรม) ในบล็อก"
|
||||||
|
inlineMath: "คณิต (อินไลน์)"
|
||||||
|
inlineMathDescription: "แสดงผลสูตรคณิต (KaTeX) ในบรรทัด"
|
||||||
|
blockMath: "คณิต (บล็อก)"
|
||||||
|
blockMathDescription: "แสดงผลสูตรคณิตหลายบรรทัด (KaTeX) ในบล็อก"
|
||||||
quote: "อ้างคำพูด"
|
quote: "อ้างคำพูด"
|
||||||
|
quoteDescription: "แสดงผลเนื้อหาเป็นใบเสนอราคา"
|
||||||
emoji: "กำหนดอีโมจิเอง"
|
emoji: "กำหนดอีโมจิเอง"
|
||||||
|
emojiDescription: "โดยล้อมรอบชื่ออีโมจิที่กำหนดเองด้วยเครื่องหมายทวิภาค จะสามารถแสดงผลอีโมจิที่กำหนดเองได้"
|
||||||
search: "ค้นหา"
|
search: "ค้นหา"
|
||||||
|
searchDescription: "แสดงผลกล่องค้นหาพร้อมกับข้อความที่ป้อนไว้ล่วงหน้า"
|
||||||
|
flip: "พลิก"
|
||||||
_theme:
|
_theme:
|
||||||
description: "รายละเอียด"
|
description: "รายละเอียด"
|
||||||
keys:
|
keys:
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Пошук користувачів"
|
|||||||
reply: "Відповісти"
|
reply: "Відповісти"
|
||||||
loadMore: "Показати більше"
|
loadMore: "Показати більше"
|
||||||
showMore: "Показати більше"
|
showMore: "Показати більше"
|
||||||
|
showLess: "Закрити"
|
||||||
youGotNewFollower: "Новий підписник"
|
youGotNewFollower: "Новий підписник"
|
||||||
receiveFollowRequest: "Отримано запит на підписку"
|
receiveFollowRequest: "Отримано запит на підписку"
|
||||||
followRequestAccepted: "Підписка прийнята"
|
followRequestAccepted: "Підписка прийнята"
|
||||||
@@ -738,6 +739,10 @@ hide: "Сховати"
|
|||||||
searchByGoogle: "Пошук"
|
searchByGoogle: "Пошук"
|
||||||
indefinitely: "Ніколи"
|
indefinitely: "Ніколи"
|
||||||
file: "Файли"
|
file: "Файли"
|
||||||
|
reverse: "Перевернути"
|
||||||
|
colored: "Кольоровий"
|
||||||
|
label: "Назва"
|
||||||
|
localOnly: "Локально"
|
||||||
_ffVisibility:
|
_ffVisibility:
|
||||||
public: "Опублікувати"
|
public: "Опублікувати"
|
||||||
_ad:
|
_ad:
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "Tìm kiếm người dùng"
|
|||||||
reply: "Trả lời"
|
reply: "Trả lời"
|
||||||
loadMore: "Tải thêm"
|
loadMore: "Tải thêm"
|
||||||
showMore: "Xem thêm"
|
showMore: "Xem thêm"
|
||||||
|
showLess: "Đóng"
|
||||||
youGotNewFollower: "đã theo dõi bạn"
|
youGotNewFollower: "đã theo dõi bạn"
|
||||||
receiveFollowRequest: "Đã yêu cầu theo dõi"
|
receiveFollowRequest: "Đã yêu cầu theo dõi"
|
||||||
followRequestAccepted: "Đã chấp nhận yêu cầu theo dõi"
|
followRequestAccepted: "Đã chấp nhận yêu cầu theo dõi"
|
||||||
@@ -561,6 +562,7 @@ author: "Tác giả"
|
|||||||
leaveConfirm: "Có những thay đổi chưa được lưu. Bạn có muốn bỏ chúng không?"
|
leaveConfirm: "Có những thay đổi chưa được lưu. Bạn có muốn bỏ chúng không?"
|
||||||
manage: "Quản lý"
|
manage: "Quản lý"
|
||||||
plugins: "Plugin"
|
plugins: "Plugin"
|
||||||
|
preferencesBackups: "Sao lưu thiết lập"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Bỏ Deck"
|
undeck: "Bỏ Deck"
|
||||||
useBlurEffectForModal: "Sử dụng hiệu ứng mờ cho các hộp thoại"
|
useBlurEffectForModal: "Sử dụng hiệu ứng mờ cho các hộp thoại"
|
||||||
@@ -869,6 +871,36 @@ logoutConfirm: "Bạn có chắc muốn đăng xuất?"
|
|||||||
lastActiveDate: "Lần cuối vào"
|
lastActiveDate: "Lần cuối vào"
|
||||||
statusbar: "Thanh trạng thái"
|
statusbar: "Thanh trạng thái"
|
||||||
pleaseSelect: "Chọn một lựa chọn"
|
pleaseSelect: "Chọn một lựa chọn"
|
||||||
|
reverse: "Lật"
|
||||||
|
colored: "Với màu"
|
||||||
|
refreshInterval: "Cập nhật nội bộ"
|
||||||
|
label: "Nhãn"
|
||||||
|
type: "Loại"
|
||||||
|
speed: "Tốc độ"
|
||||||
|
slow: "Chậm"
|
||||||
|
fast: "Nhanh"
|
||||||
|
sensitiveMediaDetection: "Tự động phát hiện NSFW"
|
||||||
|
localOnly: "Chỉ trên máy chủ"
|
||||||
|
remoteOnly: "Chỉ máy chủ từ xa"
|
||||||
|
failedToUpload: "Tải lên thất bại"
|
||||||
|
cannotUploadBecauseInappropriate: "Không thể tải lên tập tin này vì các phần của tập tin đã được phát hiện có khả năng là NSFW."
|
||||||
|
cannotUploadBecauseNoFreeSpace: "Tải lên không thành công do thiếu dung lượng Drive."
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "Tự động đánh dấu NSFW"
|
||||||
|
enableAutoSensitiveDescription: "Cho phép tự động phát hiện và đánh dấu media NSFW thông qua học máy, nếu có thể. Ngay cả khi tùy chọn này bị tắt, nó vẫn có thể được bật trên toàn máy chủ."
|
||||||
|
activeEmailValidationDescription: "Cho phép xác minh địa chỉ email chặt chẽ hơn, bao gồm việc kiểm tra các địa chỉ dùng một lần và xem nó có thực sự được giao tiếp hay không. Khi bỏ chọn, chỉ định dạng của email được xác minh."
|
||||||
|
navbar: "Thanh điều hướng"
|
||||||
|
shuffle: "Xáo trộn"
|
||||||
|
account: "Tài khoản của bạn"
|
||||||
|
move: "Di chuyển"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "Giảm nỗ lực kiểm duyệt máy chủ thông qua việc tự động nhận dạng media NSFW thông qua học máy. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
|
||||||
|
sensitivity: "Phát hiện nhạy cảm"
|
||||||
|
sensitivityDescription: "Giảm độ nhạy sẽ dẫn đến ít phát hiện sai hơn (dương tính giả), tăng nó sẽ dẫn đến ít phát hiện sai hơn (âm tính giả)."
|
||||||
|
setSensitiveFlagAutomatically: "Đánh dấu là NSFW"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "Kết quả của phát hiện nội bộ sẽ được giữ lại ngay cả khi tùy chọn này bị tắt."
|
||||||
|
analyzeVideos: "Bật chuẩn đoán video"
|
||||||
|
analyzeVideosDescription: "Phân tích video bên cạnh hình ảnh. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Địa chỉ email đã được sử dụng"
|
used: "Địa chỉ email đã được sử dụng"
|
||||||
format: "Địa chỉ email không hợp lệ"
|
format: "Địa chỉ email không hợp lệ"
|
||||||
@@ -911,6 +943,24 @@ _plugin:
|
|||||||
install: "Cài đặt tiện ích"
|
install: "Cài đặt tiện ích"
|
||||||
installWarn: "Vui lòng không cài đặt những tiện ích đáng ngờ."
|
installWarn: "Vui lòng không cài đặt những tiện ích đáng ngờ."
|
||||||
manage: "Quản lý plugin"
|
manage: "Quản lý plugin"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "Tạo sao lưu"
|
||||||
|
saveNew: "Lưu bản sao lưu"
|
||||||
|
loadFile: "Nhập tập tin"
|
||||||
|
apply: "Áp dụng lên thiết bị này"
|
||||||
|
save: "Lưu thay đổi"
|
||||||
|
inputName: "Nhập tên bản sao lưu"
|
||||||
|
cannotSave: "Không thể lưu"
|
||||||
|
nameAlreadyExists: "Bản sao lưu \"{name}\" đã tồn tại. Xin nhập tên khác."
|
||||||
|
applyConfirm: "Bạn có chắc muốn áp dụng bản sao lưu \"{name}\" cho thiết bị này? Thiết lập hiện tại sẽ bị ghi đè."
|
||||||
|
saveConfirm: "Lưu bản sao lưu {name}?"
|
||||||
|
deleteConfirm: "Xóa bản sao lưu {name}?"
|
||||||
|
renameConfirm: "Đổi tên bản sao lưu \"{old}\" thành \"{new}\"?"
|
||||||
|
noBackups: "Chưa có bản sao lưu. Bạn có thể sao lưu thiết lập trên máy chủ này bằng cách sử dụng \"Tạo sao lưu\"."
|
||||||
|
createdAt: "Tạo vào: {time} {date}"
|
||||||
|
updatedAt: "Cập nhật: {time} {date}"
|
||||||
|
cannotLoad: "Tải thất bại"
|
||||||
|
invalidFile: "Sai định dạng tập tin"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "Phạm vi"
|
scope: "Phạm vi"
|
||||||
key: "Mã"
|
key: "Mã"
|
||||||
@@ -994,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "Làm cho nội dung hiệu ứng hạt lấp lánh."
|
sparkleDescription: "Làm cho nội dung hiệu ứng hạt lấp lánh."
|
||||||
rotate: "Xoay"
|
rotate: "Xoay"
|
||||||
rotateDescription: "Xoay nội dung theo một góc cụ thể."
|
rotateDescription: "Xoay nội dung theo một góc cụ thể."
|
||||||
|
plain: "Đơn giản"
|
||||||
|
plainDescription: "Vô hiệu hóa mọi hiệu ứng MFM chứa trong hiệu ứng MFM này."
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "Không hiển thị"
|
none: "Không hiển thị"
|
||||||
remote: "Hiện cho người dùng từ máy chủ khác"
|
remote: "Hiện cho người dùng từ máy chủ khác"
|
||||||
@@ -1227,6 +1279,7 @@ _widgets:
|
|||||||
activity: "Hoạt động"
|
activity: "Hoạt động"
|
||||||
photos: "Kho ảnh"
|
photos: "Kho ảnh"
|
||||||
digitalClock: "Đồng hồ số"
|
digitalClock: "Đồng hồ số"
|
||||||
|
unixClock: "Đồng hồ UNIX"
|
||||||
federation: "Liên hợp"
|
federation: "Liên hợp"
|
||||||
instanceCloud: "Instance cloud"
|
instanceCloud: "Instance cloud"
|
||||||
postForm: "Mẫu đăng"
|
postForm: "Mẫu đăng"
|
||||||
@@ -1667,6 +1720,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "Luôn hiện cột chính"
|
alwaysShowMainColumn: "Luôn hiện cột chính"
|
||||||
columnAlign: "Căn cột"
|
columnAlign: "Căn cột"
|
||||||
addColumn: "Thêm cột"
|
addColumn: "Thêm cột"
|
||||||
|
configureColumn: "Cài đặt cột"
|
||||||
swapLeft: "Hoán đổi với cột bên trái"
|
swapLeft: "Hoán đổi với cột bên trái"
|
||||||
swapRight: "Hoán đổi với cột bên phải"
|
swapRight: "Hoán đổi với cột bên phải"
|
||||||
swapUp: "Hoán đổi với cột trên"
|
swapUp: "Hoán đổi với cột trên"
|
||||||
@@ -1674,6 +1728,8 @@ _deck:
|
|||||||
stackLeft: "Xếp chồng với cột bên trái"
|
stackLeft: "Xếp chồng với cột bên trái"
|
||||||
popRight: "Xếp chồng với cột bên trái"
|
popRight: "Xếp chồng với cột bên trái"
|
||||||
profile: "Hồ sơ"
|
profile: "Hồ sơ"
|
||||||
|
newProfile: "Hồ sơ mới"
|
||||||
|
deleteProfile: "Xóa hồ sơ"
|
||||||
introduction: "Kết hợp các cột để tạo giao diện của riêng bạn!"
|
introduction: "Kết hợp các cột để tạo giao diện của riêng bạn!"
|
||||||
introduction2: "Bạn có thể thêm cột bất kỳ lúc nào bằng cách nhấn + ở bên phải màn hình."
|
introduction2: "Bạn có thể thêm cột bất kỳ lúc nào bằng cách nhấn + ở bên phải màn hình."
|
||||||
widgetsIntroduction: "Chọn \"Sửa widget\" trong menu cột và thêm một widget."
|
widgetsIntroduction: "Chọn \"Sửa widget\" trong menu cột và thêm một widget."
|
||||||
|
@@ -52,6 +52,7 @@ searchUser: "搜索用户"
|
|||||||
reply: "回复"
|
reply: "回复"
|
||||||
loadMore: "查看更多"
|
loadMore: "查看更多"
|
||||||
showMore: "查看更多"
|
showMore: "查看更多"
|
||||||
|
showLess: "关闭"
|
||||||
youGotNewFollower: "你有新的关注者"
|
youGotNewFollower: "你有新的关注者"
|
||||||
receiveFollowRequest: "您收到了关注请求"
|
receiveFollowRequest: "您收到了关注请求"
|
||||||
followRequestAccepted: "您的关注请求被通过了"
|
followRequestAccepted: "您的关注请求被通过了"
|
||||||
@@ -203,6 +204,7 @@ done: "完成"
|
|||||||
processing: "正在处理"
|
processing: "正在处理"
|
||||||
preview: "预览"
|
preview: "预览"
|
||||||
default: "默认"
|
default: "默认"
|
||||||
|
defaultValueIs: "默认值: {value}"
|
||||||
noCustomEmojis: "没有自定义表情符号"
|
noCustomEmojis: "没有自定义表情符号"
|
||||||
noJobs: "没有任务"
|
noJobs: "没有任务"
|
||||||
federating: "联合中"
|
federating: "联合中"
|
||||||
@@ -336,7 +338,7 @@ pinnedUsers: "置顶用户"
|
|||||||
pinnedUsersDescription: "在「发现」页面中使用换行标记想要置顶的用户。"
|
pinnedUsersDescription: "在「发现」页面中使用换行标记想要置顶的用户。"
|
||||||
pinnedPages: "固定页面"
|
pinnedPages: "固定页面"
|
||||||
pinnedPagesDescription: "输入您要固定到实例首页的页面路径,以换行符分隔。"
|
pinnedPagesDescription: "输入您要固定到实例首页的页面路径,以换行符分隔。"
|
||||||
pinnedClipId: "置顶的书签ID"
|
pinnedClipId: "置顶的便签ID"
|
||||||
pinnedNotes: "已置顶的帖子"
|
pinnedNotes: "已置顶的帖子"
|
||||||
hcaptcha: "hCaptcha"
|
hcaptcha: "hCaptcha"
|
||||||
enableHcaptcha: "启用 hCaptcha"
|
enableHcaptcha: "启用 hCaptcha"
|
||||||
@@ -381,6 +383,7 @@ administrator: "管理员"
|
|||||||
token: "Token (令牌)"
|
token: "Token (令牌)"
|
||||||
twoStepAuthentication: "两步验证"
|
twoStepAuthentication: "两步验证"
|
||||||
moderator: "监察员"
|
moderator: "监察员"
|
||||||
|
moderation: "管理"
|
||||||
nUsersMentioned: "{n} 被提到"
|
nUsersMentioned: "{n} 被提到"
|
||||||
securityKey: "安全密钥"
|
securityKey: "安全密钥"
|
||||||
securityKeyName: "密钥名称"
|
securityKeyName: "密钥名称"
|
||||||
@@ -481,13 +484,13 @@ showFeaturedNotesInTimeline: "在时间线上显示热门推荐"
|
|||||||
objectStorage: "对象存储"
|
objectStorage: "对象存储"
|
||||||
useObjectStorage: "使用对象存储"
|
useObjectStorage: "使用对象存储"
|
||||||
objectStorageBaseUrl: "Base URL"
|
objectStorageBaseUrl: "Base URL"
|
||||||
objectStorageBaseUrlDesc: "URL前缀,用于构造URL到对象(媒体)的引用,如果您使用的是CDN或反向代理,请指定其URL,否则请根据您使用的服务指定可公开访问的地址。例如“https://<bucket>.s3.amazonaws.com”用于AWS S3,“https://storage.googleapis.com/<bucket>”用于GCS"
|
objectStorageBaseUrlDesc: "用于引用的URL。如果您正在使用CDN或反向代理,请指定其URL,例如S3:“https://<bucket>.s3.amazonaws.com”,GCS:“https://storage.googleapis.com/<bucket>”"
|
||||||
objectStorageBucket: "存储桶"
|
objectStorageBucket: "存储桶"
|
||||||
objectStorageBucketDesc: "请指定使用的对象存储服务的存储桶名称。"
|
objectStorageBucketDesc: "请指定使用的对象存储服务的存储桶名称。"
|
||||||
objectStoragePrefix: "前缀"
|
objectStoragePrefix: "前缀"
|
||||||
objectStoragePrefixDesc: "文件将存储在此前缀的目录下。"
|
objectStoragePrefixDesc: "文件将存储在此前缀的目录下。"
|
||||||
objectStorageEndpoint: "端点"
|
objectStorageEndpoint: "端点"
|
||||||
objectStorageEndpointDesc: "如果你希望使用AWS S3请留空。否则请根据你使用的服务来进行设置,指定端点形式为“<host>”或“<host>:<port>”。"
|
objectStorageEndpointDesc: "如果你使用AWS S3请留空。否则请根据你使用的服务商的说明来进行设置,指定端点形式为“<host>”或“<host>:<port>”。"
|
||||||
objectStorageRegion: "可用区"
|
objectStorageRegion: "可用区"
|
||||||
objectStorageRegionDesc: "指定一个可用区,例如“xx-east-1”。 如果您的对象存储服务没有可用区概念,请将其留空或填写“us-east-1”。"
|
objectStorageRegionDesc: "指定一个可用区,例如“xx-east-1”。 如果您的对象存储服务没有可用区概念,请将其留空或填写“us-east-1”。"
|
||||||
objectStorageUseSSL: "使用SSL"
|
objectStorageUseSSL: "使用SSL"
|
||||||
@@ -559,6 +562,7 @@ author: "作者"
|
|||||||
leaveConfirm: "存在未保存的更改。要放弃更改吗?"
|
leaveConfirm: "存在未保存的更改。要放弃更改吗?"
|
||||||
manage: "管理"
|
manage: "管理"
|
||||||
plugins: "插件"
|
plugins: "插件"
|
||||||
|
preferencesBackups: "备份设置"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "取消Deck"
|
undeck: "取消Deck"
|
||||||
useBlurEffectForModal: "对话框使用模糊效果"
|
useBlurEffectForModal: "对话框使用模糊效果"
|
||||||
@@ -639,10 +643,12 @@ random: "随机"
|
|||||||
system: "系统"
|
system: "系统"
|
||||||
switchUi: "切换界面"
|
switchUi: "切换界面"
|
||||||
desktop: "桌面"
|
desktop: "桌面"
|
||||||
clip: "书签"
|
clip: "便签"
|
||||||
createNew: "新建"
|
createNew: "新建"
|
||||||
optional: "可选"
|
optional: "可选"
|
||||||
createNewClip: "新建书签"
|
createNewClip: "新建便签"
|
||||||
|
unclip: "移除便签"
|
||||||
|
confirmToUnclipAlreadyClippedNote: "本帖已包含在便签\"{name}\"里。您想要将本帖从该便签中移除吗?"
|
||||||
public: "公开"
|
public: "公开"
|
||||||
i18nInfo: "Misskey已经被志愿者们翻译成了各种语言。如果你也有兴趣,可以通过{link}帮助翻译。"
|
i18nInfo: "Misskey已经被志愿者们翻译成了各种语言。如果你也有兴趣,可以通过{link}帮助翻译。"
|
||||||
manageAccessTokens: "管理 Access Tokens"
|
manageAccessTokens: "管理 Access Tokens"
|
||||||
@@ -676,7 +682,7 @@ pageLikesCount: "页面点赞次数"
|
|||||||
pageLikedCount: "页面被点赞次数"
|
pageLikedCount: "页面被点赞次数"
|
||||||
contact: "联系人"
|
contact: "联系人"
|
||||||
useSystemFont: "使用系统默认字体"
|
useSystemFont: "使用系统默认字体"
|
||||||
clips: "书签"
|
clips: "便签"
|
||||||
experimentalFeatures: "实验性功能"
|
experimentalFeatures: "实验性功能"
|
||||||
developer: "开发者"
|
developer: "开发者"
|
||||||
makeExplorable: "使账号可见。"
|
makeExplorable: "使账号可见。"
|
||||||
@@ -842,6 +848,7 @@ oneDay: "1天"
|
|||||||
oneWeek: "1周"
|
oneWeek: "1周"
|
||||||
reflectMayTakeTime: "可能需要一些时间才能体现出效果。"
|
reflectMayTakeTime: "可能需要一些时间才能体现出效果。"
|
||||||
failedToFetchAccountInformation: "获取账户信息失败"
|
failedToFetchAccountInformation: "获取账户信息失败"
|
||||||
|
rateLimitExceeded: "已超過速率限制"
|
||||||
cropImage: "剪裁图像"
|
cropImage: "剪裁图像"
|
||||||
cropImageAsk: "是否要裁剪图像?"
|
cropImageAsk: "是否要裁剪图像?"
|
||||||
file: "文件"
|
file: "文件"
|
||||||
@@ -851,7 +858,49 @@ noEmailServerWarning: "电子邮件服务器未设置。"
|
|||||||
thereIsUnresolvedAbuseReportWarning: "有未解决的报告"
|
thereIsUnresolvedAbuseReportWarning: "有未解决的报告"
|
||||||
recommended: "推荐"
|
recommended: "推荐"
|
||||||
check: "检查"
|
check: "检查"
|
||||||
|
driveCapOverrideLabel: "變更此用戶的雲端硬碟容量上限"
|
||||||
|
driveCapOverrideCaption: "设定为 0 以下则会解除此限制。"
|
||||||
|
requireAdminForView: "需要使用管理员账户登录才能查看。"
|
||||||
isSystemAccount: "该账号由系统自动创建和管理。"
|
isSystemAccount: "该账号由系统自动创建和管理。"
|
||||||
|
typeToConfirm: "输入 {x} 以确认操作。"
|
||||||
|
deleteAccount: "删除账户"
|
||||||
|
document: "文档"
|
||||||
|
numberOfPageCache: "缓存页数"
|
||||||
|
numberOfPageCacheDescription: "设置较高的值会更方便用户,但设备的负载和内存使用量会增加。"
|
||||||
|
logoutConfirm: "是否确认登出?"
|
||||||
|
lastActiveDate: "最后活跃时间"
|
||||||
|
statusbar: "状态栏"
|
||||||
|
pleaseSelect: "请选择"
|
||||||
|
reverse: "翻转"
|
||||||
|
colored: "彩色"
|
||||||
|
refreshInterval: "刷新间隔"
|
||||||
|
label: "标签"
|
||||||
|
type: "类型"
|
||||||
|
speed: "速度"
|
||||||
|
slow: "慢"
|
||||||
|
fast: "快"
|
||||||
|
sensitiveMediaDetection: "检测到敏感媒体"
|
||||||
|
localOnly: "仅限本地"
|
||||||
|
remoteOnly: "仅远程"
|
||||||
|
failedToUpload: "上传失败"
|
||||||
|
cannotUploadBecauseInappropriate: "因为可能含有不适宜的内容,无法上传。"
|
||||||
|
cannotUploadBecauseNoFreeSpace: "因为已无可用空间,无法上传。"
|
||||||
|
beta: "测试"
|
||||||
|
enableAutoSensitive: "自动 NSFW 识别"
|
||||||
|
enableAutoSensitiveDescription: "如果可用,请使用机器学习在媒体上自动设置 NSFW 标志。即使关闭此功能,也可能会根据实例自动设置。"
|
||||||
|
activeEmailValidationDescription: "积极地验证用户的电子邮件地址,判断它是一次性的电子邮件地址,还是可以实际通信的地址。关闭时,则只检查字符串是否正确。"
|
||||||
|
navbar: "导航栏"
|
||||||
|
shuffle: "随机"
|
||||||
|
account: "账户"
|
||||||
|
move: "移动"
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "可以使用机器学习技术自动检测敏感媒体,以便进行审核。服务器负载将略微增加。"
|
||||||
|
sensitivity: "检测敏感度"
|
||||||
|
sensitivityDescription: "敏感度较低,则误检(假阳性)会减少;敏感度较高,则漏检(假阴性)会减少。"
|
||||||
|
setSensitiveFlagAutomatically: "自动设置 NSFW 标签"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "即使关闭此配置,识别结果也会在内部保存。"
|
||||||
|
analyzeVideos: "启用对视频的检测"
|
||||||
|
analyzeVideosDescription: "除了静止图像之外,还对视频进行分析。服务器负载会略微增加。"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "已经被使用过"
|
used: "已经被使用过"
|
||||||
format: "无效的格式"
|
format: "无效的格式"
|
||||||
@@ -894,6 +943,24 @@ _plugin:
|
|||||||
install: "安装插件"
|
install: "安装插件"
|
||||||
installWarn: "请不要安装不可信的插件。"
|
installWarn: "请不要安装不可信的插件。"
|
||||||
manage: "管理插件..."
|
manage: "管理插件..."
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "已创建的备份"
|
||||||
|
saveNew: "另存为"
|
||||||
|
loadFile: "导入文件"
|
||||||
|
apply: "应用于本设备"
|
||||||
|
save: "覆盖存档"
|
||||||
|
inputName: "请输入备份的名称"
|
||||||
|
cannotSave: "无法保存"
|
||||||
|
nameAlreadyExists: "备份名称\"{name}\"已经存在,请指定其他名称。"
|
||||||
|
applyConfirm: "您是否要将备份\"{name}\"应用到当前设备上?当前设备现有配置将被丢弃。"
|
||||||
|
saveConfirm: "您确定要覆盖保存 {name} 吗?"
|
||||||
|
deleteConfirm: "您确定要删除 {name} 吗?"
|
||||||
|
renameConfirm: "您确定要把“{old}”改为“{new}”吗?"
|
||||||
|
noBackups: "当前没有备份,“另存为”允许您在服务器上保存当前客户端的配置。"
|
||||||
|
createdAt: "创建日期:{date} {time}"
|
||||||
|
updatedAt: "更新日期:{date} {time}"
|
||||||
|
cannotLoad: "无法加载"
|
||||||
|
invalidFile: "无效的的文件格式。"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "范围"
|
scope: "范围"
|
||||||
key: "主要"
|
key: "主要"
|
||||||
@@ -977,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "添加发光粒子效果。"
|
sparkleDescription: "添加发光粒子效果。"
|
||||||
rotate: "旋转"
|
rotate: "旋转"
|
||||||
rotateDescription: "旋转指定的角度。"
|
rotateDescription: "旋转指定的角度。"
|
||||||
|
plain: "简洁"
|
||||||
|
plainDescription: "禁用所有内部语法。"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "不显示"
|
none: "不显示"
|
||||||
remote: "仅远程用户"
|
remote: "仅远程用户"
|
||||||
@@ -1206,10 +1275,13 @@ _widgets:
|
|||||||
trends: "趋势"
|
trends: "趋势"
|
||||||
clock: "时钟"
|
clock: "时钟"
|
||||||
rss: "RSS阅读器"
|
rss: "RSS阅读器"
|
||||||
|
rssTicker: "RSS Ticker"
|
||||||
activity: "活动"
|
activity: "活动"
|
||||||
photos: "照片"
|
photos: "照片"
|
||||||
digitalClock: "数字时钟"
|
digitalClock: "数字时钟"
|
||||||
|
unixClock: "UNIX时钟"
|
||||||
federation: "联邦宇宙"
|
federation: "联邦宇宙"
|
||||||
|
instanceCloud: "实例云"
|
||||||
postForm: "投稿窗口"
|
postForm: "投稿窗口"
|
||||||
slideshow: "幻灯片展示"
|
slideshow: "幻灯片展示"
|
||||||
button: "按钮"
|
button: "按钮"
|
||||||
@@ -1648,13 +1720,19 @@ _deck:
|
|||||||
alwaysShowMainColumn: "总是显示主列"
|
alwaysShowMainColumn: "总是显示主列"
|
||||||
columnAlign: "列对齐"
|
columnAlign: "列对齐"
|
||||||
addColumn: "添加列"
|
addColumn: "添加列"
|
||||||
|
configureColumn: "列设置"
|
||||||
swapLeft: "向左移动"
|
swapLeft: "向左移动"
|
||||||
swapRight: "向右移动"
|
swapRight: "向右移动"
|
||||||
swapUp: "向上移动"
|
swapUp: "向上移动"
|
||||||
swapDown: "向下移动"
|
swapDown: "向下移动"
|
||||||
stackLeft: "向左折叠"
|
stackLeft: "向左折叠"
|
||||||
popRight: "向右弹出"
|
popRight: "向右弹出"
|
||||||
profile: "个人资料"
|
profile: "配置文件"
|
||||||
|
newProfile: "新建配置文件"
|
||||||
|
deleteProfile: "删除配置文件"
|
||||||
|
introduction: "将各列进行组合以创建您自己的界面!"
|
||||||
|
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
|
||||||
|
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"
|
||||||
_columns:
|
_columns:
|
||||||
main: "主列"
|
main: "主列"
|
||||||
widgets: "小工具"
|
widgets: "小工具"
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
_lang_: "繁體中文"
|
_lang_: "繁體中文"
|
||||||
headlineMisskey: "貼文連繫網路"
|
headlineMisskey: "貼文連繫網路"
|
||||||
introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀"
|
introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「反應」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀"
|
||||||
monthAndDay: "{month}月 {day}日"
|
monthAndDay: "{month}月 {day}日"
|
||||||
search: "搜尋"
|
search: "搜尋"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
@@ -52,6 +52,7 @@ searchUser: "搜尋使用者"
|
|||||||
reply: "回覆"
|
reply: "回覆"
|
||||||
loadMore: "載入更多"
|
loadMore: "載入更多"
|
||||||
showMore: "載入更多"
|
showMore: "載入更多"
|
||||||
|
showLess: "關閉"
|
||||||
youGotNewFollower: "您有新的追隨者"
|
youGotNewFollower: "您有新的追隨者"
|
||||||
receiveFollowRequest: "您有新的追隨請求"
|
receiveFollowRequest: "您有新的追隨請求"
|
||||||
followRequestAccepted: "追隨請求已接受"
|
followRequestAccepted: "追隨請求已接受"
|
||||||
@@ -155,7 +156,7 @@ searchWith: "搜尋: {q}"
|
|||||||
youHaveNoLists: "你沒有任何清單"
|
youHaveNoLists: "你沒有任何清單"
|
||||||
followConfirm: "你真的要追隨{name}嗎?"
|
followConfirm: "你真的要追隨{name}嗎?"
|
||||||
proxyAccount: "代理帳戶"
|
proxyAccount: "代理帳戶"
|
||||||
proxyAccountDescription: "代理帳戶是在某些情況下充當其他伺服器用戶的帳戶。例如,當使用者將一個來自其他伺服器的帳戶放在列表中時,由於沒有其他使用者關注該帳戶,該指令不會傳送到該伺服器上,因此會由代理帳戶關注。"
|
proxyAccountDescription: "代理帳戶是在某些情況下充當其他伺服器用戶的帳戶。例如,當使用者將一個來自其他伺服器的帳戶放在列表中時,由於沒有其他使用者追蹤該帳戶,該指令不會傳送到該伺服器上,因此會由代理帳戶追蹤。"
|
||||||
host: "主機"
|
host: "主機"
|
||||||
selectUser: "選取使用者"
|
selectUser: "選取使用者"
|
||||||
recipient: "收件人"
|
recipient: "收件人"
|
||||||
@@ -561,6 +562,7 @@ author: "作者"
|
|||||||
leaveConfirm: "有未保存的更改。要放棄嗎?"
|
leaveConfirm: "有未保存的更改。要放棄嗎?"
|
||||||
manage: "管理"
|
manage: "管理"
|
||||||
plugins: "外掛"
|
plugins: "外掛"
|
||||||
|
preferencesBackups: "備份設定檔"
|
||||||
deck: "多欄模式"
|
deck: "多欄模式"
|
||||||
undeck: "取消多欄模式"
|
undeck: "取消多欄模式"
|
||||||
useBlurEffectForModal: "在模態框使用模糊效果"
|
useBlurEffectForModal: "在模態框使用模糊效果"
|
||||||
@@ -727,7 +729,7 @@ receiveAnnouncementFromInstance: "接收由本實例發出的電郵通知"
|
|||||||
emailNotification: "郵件通知"
|
emailNotification: "郵件通知"
|
||||||
publish: "發佈"
|
publish: "發佈"
|
||||||
inChannelSearch: "頻道内搜尋"
|
inChannelSearch: "頻道内搜尋"
|
||||||
useReactionPickerForContextMenu: "點擊右鍵開啟回應工具欄"
|
useReactionPickerForContextMenu: "點擊右鍵開啟反應工具欄"
|
||||||
typingUsers: "{users}輸入中..."
|
typingUsers: "{users}輸入中..."
|
||||||
jumpToSpecifiedDate: "跳轉到特定日期"
|
jumpToSpecifiedDate: "跳轉到特定日期"
|
||||||
showingPastTimeline: "顯示過往的時間線"
|
showingPastTimeline: "顯示過往的時間線"
|
||||||
@@ -810,8 +812,8 @@ unread: "未讀"
|
|||||||
filter: "篩選"
|
filter: "篩選"
|
||||||
controlPanel: "控制台"
|
controlPanel: "控制台"
|
||||||
manageAccounts: "管理帳戶"
|
manageAccounts: "管理帳戶"
|
||||||
makeReactionsPublic: "將回應設為公開"
|
makeReactionsPublic: "將反應設為公開"
|
||||||
makeReactionsPublicDescription: "將您做過的回應設為公開可見。"
|
makeReactionsPublicDescription: "將您做過的反應設為公開可見。"
|
||||||
classic: "經典"
|
classic: "經典"
|
||||||
muteThread: "將貼文串設為靜音"
|
muteThread: "將貼文串設為靜音"
|
||||||
unmuteThread: "將貼文串的靜音解除"
|
unmuteThread: "將貼文串的靜音解除"
|
||||||
@@ -869,6 +871,36 @@ logoutConfirm: "確定要登出嗎?"
|
|||||||
lastActiveDate: "上次使用日期及時間"
|
lastActiveDate: "上次使用日期及時間"
|
||||||
statusbar: "狀態列"
|
statusbar: "狀態列"
|
||||||
pleaseSelect: "請選擇"
|
pleaseSelect: "請選擇"
|
||||||
|
reverse: "翻轉"
|
||||||
|
colored: "彩色"
|
||||||
|
refreshInterval: "更新間隔"
|
||||||
|
label: "標籤"
|
||||||
|
type: "類型"
|
||||||
|
speed: "速度"
|
||||||
|
slow: "慢"
|
||||||
|
fast: "快"
|
||||||
|
sensitiveMediaDetection: "敏感性媒體的檢測"
|
||||||
|
localOnly: "僅限本地"
|
||||||
|
remoteOnly: "僅限遠端"
|
||||||
|
failedToUpload: "上傳失敗"
|
||||||
|
cannotUploadBecauseInappropriate: "由於判定可能包含不適當的內容,因此無法上船。"
|
||||||
|
cannotUploadBecauseNoFreeSpace: "由於雲端硬碟沒有可用空間,因此無法上船>"
|
||||||
|
beta: "Beta"
|
||||||
|
enableAutoSensitive: "自動NSFW判定"
|
||||||
|
enableAutoSensitiveDescription: "如果可用,請利用機器學習在媒體上自動設置 NSFW 旗標。 即使關閉此功能,依實例而定也可能會自動設置。"
|
||||||
|
activeEmailValidationDescription: "積極地驗證用戶的電子郵件地址,判斷它是否為免洗地址,或者它是否可以通信。 若關閉,則只會檢查字元是否正確。"
|
||||||
|
navbar: "導覽列"
|
||||||
|
shuffle: "隨機"
|
||||||
|
account: "帳戶"
|
||||||
|
move: "移動 "
|
||||||
|
_sensitiveMediaDetection:
|
||||||
|
description: "您可以使用機器學習自動檢測敏感媒體並將其用於審核。 伺服器的負荷會稍微增加。"
|
||||||
|
sensitivity: "檢測敏感度"
|
||||||
|
sensitivityDescription: "敏感度低時,誤檢測(偽陽性)會減少。敏感度高時,漏檢(偽陰性)會減少。"
|
||||||
|
setSensitiveFlagAutomatically: "設定 NSFW 旗標"
|
||||||
|
setSensitiveFlagAutomaticallyDescription: "即使將此設定關閉,判定結果也會保留在內部。"
|
||||||
|
analyzeVideos: "啟用影片分析"
|
||||||
|
analyzeVideosDescription: "除了靜止影像以外,也分析影片。伺服器的負荷會稍微增加。"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "已經在使用中"
|
used: "已經在使用中"
|
||||||
format: "格式無效"
|
format: "格式無效"
|
||||||
@@ -911,6 +943,24 @@ _plugin:
|
|||||||
install: "安裝外掛組件"
|
install: "安裝外掛組件"
|
||||||
installWarn: "請不要安裝來源不明的外掛組件。"
|
installWarn: "請不要安裝來源不明的外掛組件。"
|
||||||
manage: "管理外掛"
|
manage: "管理外掛"
|
||||||
|
_preferencesBackups:
|
||||||
|
list: "已備份的設定檔"
|
||||||
|
saveNew: "另存新檔"
|
||||||
|
loadFile: "讀取檔案"
|
||||||
|
apply: "套用在此裝置"
|
||||||
|
save: "覆蓋存檔"
|
||||||
|
inputName: "輸入備份檔名稱"
|
||||||
|
cannotSave: "無法儲存"
|
||||||
|
nameAlreadyExists: "備份檔名稱「{name}」已經存在。請指定不同的名稱。"
|
||||||
|
applyConfirm: "將備份檔「{name}」套用在現在的裝置嗎?現在的裝置設定將會消失。"
|
||||||
|
saveConfirm: "要覆蓋存檔{name}嗎?"
|
||||||
|
deleteConfirm: "要刪除{name}嗎?"
|
||||||
|
renameConfirm: "要將「{old}」變更為「{new}」嗎?"
|
||||||
|
noBackups: "沒有備份檔。您可以用「另存新檔」將現在的客戶端設定儲存在伺服器上。"
|
||||||
|
createdAt: "建立日期:{date} {time}"
|
||||||
|
updatedAt: "更新日期:{date} {time}"
|
||||||
|
cannotLoad: "無法讀取"
|
||||||
|
invalidFile: "檔案形式錯誤。"
|
||||||
_registry:
|
_registry:
|
||||||
scope: "範圍"
|
scope: "範圍"
|
||||||
key: "機碼"
|
key: "機碼"
|
||||||
@@ -994,6 +1044,8 @@ _mfm:
|
|||||||
sparkleDescription: "添加閃閃發光的粒子效果。"
|
sparkleDescription: "添加閃閃發光的粒子效果。"
|
||||||
rotate: "旋轉"
|
rotate: "旋轉"
|
||||||
rotateDescription: "以指定的角度旋轉。"
|
rotateDescription: "以指定的角度旋轉。"
|
||||||
|
plain: "簡潔"
|
||||||
|
plainDescription: "停用全部的內部語法。"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "隱藏"
|
none: "隱藏"
|
||||||
remote: "向遠端使用者顯示"
|
remote: "向遠端使用者顯示"
|
||||||
@@ -1227,6 +1279,7 @@ _widgets:
|
|||||||
activity: "動態"
|
activity: "動態"
|
||||||
photos: "照片"
|
photos: "照片"
|
||||||
digitalClock: "電子時鐘"
|
digitalClock: "電子時鐘"
|
||||||
|
unixClock: "UNIX時間"
|
||||||
federation: "聯邦宇宙"
|
federation: "聯邦宇宙"
|
||||||
instanceCloud: "實例雲"
|
instanceCloud: "實例雲"
|
||||||
postForm: "發佈窗口"
|
postForm: "發佈窗口"
|
||||||
@@ -1667,6 +1720,7 @@ _deck:
|
|||||||
alwaysShowMainColumn: "總是顯示主欄"
|
alwaysShowMainColumn: "總是顯示主欄"
|
||||||
columnAlign: "對齊欄位"
|
columnAlign: "對齊欄位"
|
||||||
addColumn: "新增欄位"
|
addColumn: "新增欄位"
|
||||||
|
configureColumn: "欄位的設定"
|
||||||
swapLeft: "向左移動"
|
swapLeft: "向左移動"
|
||||||
swapRight: "向右移動"
|
swapRight: "向右移動"
|
||||||
swapUp: "往上移動"
|
swapUp: "往上移動"
|
||||||
@@ -1674,6 +1728,8 @@ _deck:
|
|||||||
stackLeft: "向左折疊"
|
stackLeft: "向左折疊"
|
||||||
popRight: "向右彈出"
|
popRight: "向右彈出"
|
||||||
profile: "個人檔案"
|
profile: "個人檔案"
|
||||||
|
newProfile: "新建個人檔案"
|
||||||
|
deleteProfile: "刪除個人檔案"
|
||||||
introduction: "組合欄位來製作屬於自己的介面吧!"
|
introduction: "組合欄位來製作屬於自己的介面吧!"
|
||||||
introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。"
|
introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。"
|
||||||
widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具"
|
widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.112.2",
|
"version": "12.118.0",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -41,9 +41,9 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/gulp": "4.0.9",
|
"@types/gulp": "4.0.9",
|
||||||
"@types/gulp-rename": "2.0.1",
|
"@types/gulp-rename": "2.0.1",
|
||||||
"@typescript-eslint/parser": "5.30.0",
|
"@typescript-eslint/parser": "5.31.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "10.3.0",
|
"cypress": "10.3.1",
|
||||||
"start-server-and-test": "1.14.0",
|
"start-server-and-test": "1.14.0",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
}
|
}
|
||||||
|
@@ -28,11 +28,11 @@ export class foreignKeyReports1651224615271 {
|
|||||||
|
|
||||||
queryRunner.query(`CREATE INDEX "IDX_315c779174fe8247ab324f036e" ON "drive_file" ("isLink")`),
|
queryRunner.query(`CREATE INDEX "IDX_315c779174fe8247ab324f036e" ON "drive_file" ("isLink")`),
|
||||||
queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId")`),
|
queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId")`),
|
||||||
queryRunner.query(`CREATE INDEX "IDX_a9021cc2e1feb5f72d3db6e9f5" ON "abuse_user_report" ("targetUserId")`),
|
//queryRunner.query(`CREATE INDEX "IDX_a9021cc2e1feb5f72d3db6e9f5" ON "abuse_user_report" ("targetUserId")`),
|
||||||
|
|
||||||
queryRunner.query(`DELETE FROM "abuse_user_report" WHERE "targetUserId" NOT IN (SELECT "id" FROM "user")`).then(() => {
|
//queryRunner.query(`DELETE FROM "abuse_user_report" WHERE "targetUserId" NOT IN (SELECT "id" FROM "user")`).then(() => {
|
||||||
queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_a9021cc2e1feb5f72d3db6e9f5f" FOREIGN KEY ("targetUserId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
// queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_a9021cc2e1feb5f72d3db6e9f5f" FOREIGN KEY ("targetUserId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
}),
|
//}),
|
||||||
|
|
||||||
queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b" UNIQUE ("noteId")`),
|
queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b" UNIQUE ("noteId")`),
|
||||||
queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6" UNIQUE ("userId")`),
|
queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6" UNIQUE ("userId")`),
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
export class activeEmailValidation1657346559800 {
|
||||||
|
name = 'activeEmailValidation1657346559800'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "enableActiveEmailValidation" boolean NOT NULL DEFAULT true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableActiveEmailValidation"`);
|
||||||
|
}
|
||||||
|
}
|
@@ -13,8 +13,11 @@
|
|||||||
"chokidar": "^3.3.1",
|
"chokidar": "^3.3.1",
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
},
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@tensorflow/tfjs-node": "3.19.0"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bull-board/koa": "4.0.0",
|
"@bull-board/koa": "4.1.1",
|
||||||
"@discordapp/twemoji": "14.0.2",
|
"@discordapp/twemoji": "14.0.2",
|
||||||
"@elastic/elasticsearch": "7.11.0",
|
"@elastic/elasticsearch": "7.11.0",
|
||||||
"@koa/cors": "3.1.0",
|
"@koa/cors": "3.1.0",
|
||||||
@@ -23,31 +26,29 @@
|
|||||||
"@peertube/http-signature": "1.6.0",
|
"@peertube/http-signature": "1.6.0",
|
||||||
"@sinonjs/fake-timers": "9.1.2",
|
"@sinonjs/fake-timers": "9.1.2",
|
||||||
"@syuilo/aiscript": "0.11.1",
|
"@syuilo/aiscript": "0.11.1",
|
||||||
"@tensorflow/tfjs-node": "3.18.0",
|
|
||||||
"abort-controller": "3.0.0",
|
|
||||||
"ajv": "8.11.0",
|
"ajv": "8.11.0",
|
||||||
"archiver": "5.3.1",
|
"archiver": "5.3.1",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"aws-sdk": "2.1165.0",
|
"aws-sdk": "2.1185.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "1.1.5",
|
"blurhash": "1.1.5",
|
||||||
"bull": "4.8.4",
|
"bull": "4.8.5",
|
||||||
"cacheable-lookup": "6.0.4",
|
"cacheable-lookup": "6.0.4",
|
||||||
"cbor": "8.1.0",
|
"cbor": "8.1.0",
|
||||||
"chalk": "5.0.1",
|
"chalk": "5.0.1",
|
||||||
"chalk-template": "0.4.0",
|
"chalk-template": "0.4.0",
|
||||||
"chokidar": "3.3.1",
|
"chokidar": "3.5.3",
|
||||||
"cli-highlight": "2.1.11",
|
"cli-highlight": "2.1.11",
|
||||||
"color-convert": "2.0.1",
|
"color-convert": "2.0.1",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"date-fns": "2.28.0",
|
"date-fns": "2.29.1",
|
||||||
"deep-email-validator": "0.1.21",
|
"deep-email-validator": "0.1.21",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"feed": "4.2.2",
|
"feed": "4.2.2",
|
||||||
"file-type": "17.1.2",
|
"file-type": "17.1.4",
|
||||||
"fluent-ffmpeg": "2.1.2",
|
"fluent-ffmpeg": "2.1.2",
|
||||||
"got": "12.1.0",
|
"got": "12.3.0",
|
||||||
"hpagent": "0.1.2",
|
"hpagent": "0.1.2",
|
||||||
"ioredis": "4.28.5",
|
"ioredis": "4.28.5",
|
||||||
"ip-cidr": "3.0.10",
|
"ip-cidr": "3.0.10",
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
"json5": "2.2.1",
|
"json5": "2.2.1",
|
||||||
"json5-loader": "4.0.1",
|
"json5-loader": "4.0.1",
|
||||||
"jsonld": "6.0.0",
|
"jsonld": "6.0.0",
|
||||||
"jsrsasign": "10.5.25",
|
"jsrsasign": "10.5.26",
|
||||||
"koa": "2.13.4",
|
"koa": "2.13.4",
|
||||||
"koa-bodyparser": "4.3.0",
|
"koa-bodyparser": "4.3.0",
|
||||||
"koa-favicon": "2.1.0",
|
"koa-favicon": "2.1.0",
|
||||||
@@ -67,15 +68,15 @@
|
|||||||
"koa-send": "5.0.1",
|
"koa-send": "5.0.1",
|
||||||
"koa-slow": "2.1.0",
|
"koa-slow": "2.1.0",
|
||||||
"koa-views": "7.0.2",
|
"koa-views": "7.0.2",
|
||||||
"mfm-js": "0.22.1",
|
"mfm-js": "0.23.0",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"misskey-js": "0.0.14",
|
"misskey-js": "0.0.14",
|
||||||
"mocha": "10.0.0",
|
"mocha": "10.0.0",
|
||||||
"ms": "3.0.0-canary.1",
|
"ms": "3.0.0-canary.1",
|
||||||
"multer": "1.4.4",
|
"multer": "1.4.4",
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"node-fetch": "3.2.6",
|
"node-fetch": "3.2.10",
|
||||||
"nodemailer": "6.7.6",
|
"nodemailer": "6.7.7",
|
||||||
"nsfwjs": "2.4.1",
|
"nsfwjs": "2.4.1",
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"parse5": "7.0.0",
|
"parse5": "7.0.0",
|
||||||
@@ -86,32 +87,30 @@
|
|||||||
"pug": "3.0.2",
|
"pug": "3.0.2",
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
"pureimage": "0.3.14",
|
"pureimage": "0.3.14",
|
||||||
"qrcode": "1.5.0",
|
"qrcode": "1.5.1",
|
||||||
"random-seed": "0.3.0",
|
"random-seed": "0.3.0",
|
||||||
"ratelimiter": "3.4.1",
|
"ratelimiter": "3.4.1",
|
||||||
"re2": "1.17.7",
|
"re2": "1.17.7",
|
||||||
"redis-lock": "0.1.4",
|
"redis-lock": "0.1.4",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"rename": "1.0.4",
|
"rename": "1.0.4",
|
||||||
"require-all": "3.0.0",
|
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
"rss-parser": "3.12.0",
|
"rss-parser": "3.12.0",
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
"sanitize-html": "2.7.0",
|
"sanitize-html": "2.7.1",
|
||||||
"semver": "7.3.7",
|
"semver": "7.3.7",
|
||||||
"sharp": "0.29.3",
|
"sharp": "0.29.3",
|
||||||
"speakeasy": "2.0.0",
|
"speakeasy": "2.0.0",
|
||||||
"strict-event-emitter-types": "2.0.0",
|
"strict-event-emitter-types": "2.0.0",
|
||||||
"stringz": "2.1.0",
|
"stringz": "2.1.0",
|
||||||
"style-loader": "3.3.1",
|
"summaly": "2.7.0",
|
||||||
"summaly": "2.6.0",
|
|
||||||
"syslog-pro": "1.0.0",
|
"syslog-pro": "1.0.0",
|
||||||
"systeminformation": "5.11.22",
|
"systeminformation": "5.12.1",
|
||||||
"tinycolor2": "1.4.2",
|
"tinycolor2": "1.4.2",
|
||||||
"tmp": "0.2.1",
|
"tmp": "0.2.1",
|
||||||
"ts-loader": "9.3.1",
|
"ts-loader": "9.3.1",
|
||||||
"ts-node": "10.8.1",
|
"ts-node": "10.9.1",
|
||||||
"tsc-alias": "1.6.11",
|
"tsc-alias": "1.7.0",
|
||||||
"tsconfig-paths": "4.0.0",
|
"tsconfig-paths": "4.0.0",
|
||||||
"twemoji-parser": "14.0.0",
|
"twemoji-parser": "14.0.0",
|
||||||
"typeorm": "0.3.7",
|
"typeorm": "0.3.7",
|
||||||
@@ -120,22 +119,21 @@
|
|||||||
"uuid": "8.3.2",
|
"uuid": "8.3.2",
|
||||||
"web-push": "3.5.0",
|
"web-push": "3.5.0",
|
||||||
"websocket": "1.0.34",
|
"websocket": "1.0.34",
|
||||||
"ws": "8.8.0",
|
"ws": "8.8.1",
|
||||||
"xev": "3.0.2"
|
"xev": "3.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redocly/openapi-core": "1.0.0-beta.97",
|
"@redocly/openapi-core": "1.0.0-beta.105",
|
||||||
"@types/bcryptjs": "2.4.2",
|
"@types/bcryptjs": "2.4.2",
|
||||||
"@types/bull": "3.15.8",
|
"@types/bull": "3.15.9",
|
||||||
"@types/cbor": "6.0.0",
|
"@types/cbor": "6.0.0",
|
||||||
"@types/escape-regexp": "0.0.1",
|
"@types/escape-regexp": "0.0.1",
|
||||||
"@types/fluent-ffmpeg": "2.1.20",
|
"@types/fluent-ffmpeg": "2.1.20",
|
||||||
"@types/is-url": "1.2.30",
|
|
||||||
"@types/js-yaml": "4.0.5",
|
"@types/js-yaml": "4.0.5",
|
||||||
"@types/jsdom": "16.2.14",
|
"@types/jsdom": "16.2.14",
|
||||||
"@types/jsonld": "1.5.6",
|
"@types/jsonld": "1.5.6",
|
||||||
"@types/jsrsasign": "10.5.1",
|
"@types/jsrsasign": "10.5.2",
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.5",
|
||||||
"@types/koa-bodyparser": "4.3.7",
|
"@types/koa-bodyparser": "4.3.7",
|
||||||
"@types/koa-cors": "0.0.2",
|
"@types/koa-cors": "0.0.2",
|
||||||
"@types/koa-favicon": "2.0.21",
|
"@types/koa-favicon": "2.0.21",
|
||||||
@@ -147,7 +145,7 @@
|
|||||||
"@types/koa__multer": "2.0.4",
|
"@types/koa__multer": "2.0.4",
|
||||||
"@types/koa__router": "8.0.11",
|
"@types/koa__router": "8.0.11",
|
||||||
"@types/mocha": "9.1.1",
|
"@types/mocha": "9.1.1",
|
||||||
"@types/node": "18.0.0",
|
"@types/node": "18.6.3",
|
||||||
"@types/node-fetch": "3.0.3",
|
"@types/node-fetch": "3.0.3",
|
||||||
"@types/nodemailer": "6.4.4",
|
"@types/nodemailer": "6.4.4",
|
||||||
"@types/oauth": "0.9.1",
|
"@types/oauth": "0.9.1",
|
||||||
@@ -169,10 +167,10 @@
|
|||||||
"@types/web-push": "3.3.2",
|
"@types/web-push": "3.3.2",
|
||||||
"@types/websocket": "1.0.5",
|
"@types/websocket": "1.0.5",
|
||||||
"@types/ws": "8.5.3",
|
"@types/ws": "8.5.3",
|
||||||
"@typescript-eslint/eslint-plugin": "5.30.0",
|
"@typescript-eslint/eslint-plugin": "5.31.0",
|
||||||
"@typescript-eslint/parser": "5.30.0",
|
"@typescript-eslint/parser": "5.31.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"eslint": "8.18.0",
|
"eslint": "8.20.0",
|
||||||
"eslint-plugin-import": "2.26.0",
|
"eslint-plugin-import": "2.26.0",
|
||||||
"execa": "6.1.0",
|
"execa": "6.1.0",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
|
@@ -145,6 +145,12 @@ export function toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMenti
|
|||||||
a.textContent = node.props.content;
|
a.textContent = node.props.content;
|
||||||
return a;
|
return a;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
plain(node) {
|
||||||
|
const el = doc.createElement('span');
|
||||||
|
appendChildren(node.children, el);
|
||||||
|
return el;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
appendChildren(nodes, doc.body);
|
appendChildren(nodes, doc.body);
|
||||||
|
@@ -7,28 +7,31 @@ import { WriteStream } from 'node:fs';
|
|||||||
import * as p from 'pureimage';
|
import * as p from 'pureimage';
|
||||||
import gen from 'random-seed';
|
import gen from 'random-seed';
|
||||||
|
|
||||||
const size = 256; // px
|
const size = 128; // px
|
||||||
const n = 5; // resolution
|
const n = 5; // resolution
|
||||||
const margin = (size / n);
|
const margin = (size / 4);
|
||||||
const colors = [
|
const colors = [
|
||||||
'#e57373',
|
['#FF512F', '#DD2476'],
|
||||||
'#F06292',
|
['#FF61D2', '#FE9090'],
|
||||||
'#BA68C8',
|
['#72FFB6', '#10D164'],
|
||||||
'#9575CD',
|
['#FD8451', '#FFBD6F'],
|
||||||
'#7986CB',
|
['#305170', '#6DFC6B'],
|
||||||
'#64B5F6',
|
['#00C0FF', '#4218B8'],
|
||||||
'#4FC3F7',
|
['#009245', '#FCEE21'],
|
||||||
'#4DD0E1',
|
['#0100EC', '#FB36F4'],
|
||||||
'#4DB6AC',
|
['#FDABDD', '#374A5A'],
|
||||||
'#81C784',
|
['#38A2D7', '#561139'],
|
||||||
'#8BC34A',
|
['#121C84', '#8278DA'],
|
||||||
'#AFB42B',
|
['#5761B2', '#1FC5A8'],
|
||||||
'#F57F17',
|
['#FFDB01', '#0E197D'],
|
||||||
'#FF5722',
|
['#FF3E9D', '#0E1F40'],
|
||||||
'#795548',
|
['#766eff', '#00d4ff'],
|
||||||
'#455A64',
|
['#9bff6e', '#00d4ff'],
|
||||||
|
['#ff6e94', '#00d4ff'],
|
||||||
|
['#ffa96e', '#00d4ff'],
|
||||||
|
['#ffa96e', '#ff009d'],
|
||||||
|
['#ffdd6e', '#ff009d'],
|
||||||
];
|
];
|
||||||
const bg = '#e9e9e9';
|
|
||||||
|
|
||||||
const actualSize = size - (margin * 2);
|
const actualSize = size - (margin * 2);
|
||||||
const cellSize = actualSize / n;
|
const cellSize = actualSize / n;
|
||||||
@@ -42,11 +45,17 @@ export function genIdenticon(seed: string, stream: WriteStream): Promise<void> {
|
|||||||
const canvas = p.make(size, size, undefined);
|
const canvas = p.make(size, size, undefined);
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
const bgColors = colors[rand(colors.length)];
|
||||||
|
|
||||||
|
const bg = ctx.createLinearGradient(0, 0, size, size);
|
||||||
|
bg.addColorStop(0, bgColors[0]);
|
||||||
|
bg.addColorStop(1, bgColors[1]);
|
||||||
|
|
||||||
ctx.fillStyle = bg;
|
ctx.fillStyle = bg;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.fillRect(0, 0, size, size);
|
ctx.fillRect(0, 0, size, size);
|
||||||
|
|
||||||
ctx.fillStyle = colors[rand(colors.length)];
|
ctx.fillStyle = '#ffffff';
|
||||||
|
|
||||||
// side bitmap (filled by false)
|
// side bitmap (filled by false)
|
||||||
const side: boolean[][] = new Array(sideN);
|
const side: boolean[][] = new Array(sideN);
|
||||||
|
@@ -101,13 +101,17 @@ export async function getFileInfo(path: string, opts: {
|
|||||||
let porn = false;
|
let porn = false;
|
||||||
|
|
||||||
if (!opts.skipSensitiveDetection) {
|
if (!opts.skipSensitiveDetection) {
|
||||||
[sensitive, porn] = await detectSensitivity(
|
await detectSensitivity(
|
||||||
path,
|
path,
|
||||||
type.mime,
|
type.mime,
|
||||||
opts.sensitiveThreshold ?? 0.5,
|
opts.sensitiveThreshold ?? 0.5,
|
||||||
opts.sensitiveThresholdForPorn ?? 0.75,
|
opts.sensitiveThresholdForPorn ?? 0.75,
|
||||||
opts.enableSensitiveMediaDetectionForVideos ?? false,
|
opts.enableSensitiveMediaDetectionForVideos ?? false,
|
||||||
);
|
).then(value => {
|
||||||
|
[sensitive, porn] = value;
|
||||||
|
}, error => {
|
||||||
|
warnings.push(`detectSensitivity failed: ${error}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@@ -454,4 +454,9 @@ export class Meta {
|
|||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
public enableIpLogging: boolean;
|
public enableIpLogging: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
public enableActiveEmailValidation: boolean;
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import { queueLogger } from '../../logger.js';
|
|||||||
import { addFile } from '@/services/drive/add-file.js';
|
import { addFile } from '@/services/drive/add-file.js';
|
||||||
import { format as dateFormat } from 'date-fns';
|
import { format as dateFormat } from 'date-fns';
|
||||||
import { Users, Emojis } from '@/models/index.js';
|
import { Users, Emojis } from '@/models/index.js';
|
||||||
import { } from '@/queue/types.js';
|
import { } from '@/queue/types.js';
|
||||||
import { createTemp, createTempDir } from '@/misc/create-temp.js';
|
import { createTemp, createTempDir } from '@/misc/create-temp.js';
|
||||||
import { downloadUrl } from '@/misc/download-url.js';
|
import { downloadUrl } from '@/misc/download-url.js';
|
||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
import Resolver from '../resolver.js';
|
import Resolver from '../resolver.js';
|
||||||
import { IObject, IQuestion, isQuestion } from '../type.js';
|
import { IObject, IQuestion, isQuestion } from '../type.js';
|
||||||
import { apLogger } from '../logger.js';
|
import { apLogger } from '../logger.js';
|
||||||
import { Notes, Polls } from '@/models/index.js';
|
import { Notes, Polls } from '@/models/index.js';
|
||||||
import { IPoll } from '@/models/entities/poll.js';
|
import { IPoll } from '@/models/entities/poll.js';
|
||||||
|
@@ -7,7 +7,7 @@ import { Blocking } from '@/models/entities/blocking.js';
|
|||||||
* @param block The block to be rendered. The blockee relation must be loaded.
|
* @param block The block to be rendered. The blockee relation must be loaded.
|
||||||
*/
|
*/
|
||||||
export function renderBlock(block: Blocking) {
|
export function renderBlock(block: Blocking) {
|
||||||
if (block.blockee?.url == null) {
|
if (block.blockee?.uri == null) {
|
||||||
throw new Error('renderBlock: missing blockee uri');
|
throw new Error('renderBlock: missing blockee uri');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ import renderEmoji from './emoji.js';
|
|||||||
export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
|
export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
|
||||||
const reaction = noteReaction.reaction;
|
const reaction = noteReaction.reaction;
|
||||||
|
|
||||||
const object = {
|
const object = {
|
||||||
type: 'Like',
|
type: 'Like',
|
||||||
id: `${config.url}/likes/${noteReaction.id}`,
|
id: `${config.url}/likes/${noteReaction.id}`,
|
||||||
actor: `${config.url}/users/${noteReaction.userId}`,
|
actor: `${config.url}/users/${noteReaction.userId}`,
|
||||||
|
@@ -68,11 +68,11 @@ export default (endpoint: IEndpoint, ctx: Koa.Context) => new Promise<void>((res
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UserIps.insert({
|
UserIps.createQueryBuilder().insert().values({
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
ip: ip,
|
ip: ip,
|
||||||
});
|
}).orIgnore(true).execute();
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,13 +12,15 @@ export async function readNotification(
|
|||||||
if (notificationIds.length === 0) return;
|
if (notificationIds.length === 0) return;
|
||||||
|
|
||||||
// Update documents
|
// Update documents
|
||||||
await Notifications.update({
|
const result = await Notifications.update({
|
||||||
id: In(notificationIds),
|
id: In(notificationIds),
|
||||||
isRead: false,
|
isRead: false,
|
||||||
}, {
|
}, {
|
||||||
isRead: true,
|
isRead: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result.affected === 0) return;
|
||||||
|
|
||||||
if (!await Users.getHasUnreadNotification(userId)) return postReadAllNotifications(userId);
|
if (!await Users.getHasUnreadNotification(userId)) return postReadAllNotifications(userId);
|
||||||
else return postReadNotifications(userId, notificationIds);
|
else return postReadNotifications(userId, notificationIds);
|
||||||
}
|
}
|
||||||
@@ -27,7 +29,7 @@ export async function readNotificationByQuery(
|
|||||||
userId: User['id'],
|
userId: User['id'],
|
||||||
query: Record<string, any>
|
query: Record<string, any>
|
||||||
) {
|
) {
|
||||||
const notificationIds = await Notifications.find({
|
const notificationIds = await Notifications.findBy({
|
||||||
...query,
|
...query,
|
||||||
notifieeId: userId,
|
notifieeId: userId,
|
||||||
isRead: false,
|
isRead: false,
|
||||||
|
@@ -324,6 +324,10 @@ export const meta = {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: true, nullable: false,
|
||||||
},
|
},
|
||||||
|
enableActiveEmailValidation: {
|
||||||
|
type: 'boolean',
|
||||||
|
optional: true, nullable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
@@ -421,5 +425,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
deeplAuthKey: instance.deeplAuthKey,
|
deeplAuthKey: instance.deeplAuthKey,
|
||||||
deeplIsPro: instance.deeplIsPro,
|
deeplIsPro: instance.deeplIsPro,
|
||||||
enableIpLogging: instance.enableIpLogging,
|
enableIpLogging: instance.enableIpLogging,
|
||||||
|
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@@ -101,6 +101,7 @@ export const paramDef = {
|
|||||||
objectStorageSetPublicRead: { type: 'boolean' },
|
objectStorageSetPublicRead: { type: 'boolean' },
|
||||||
objectStorageS3ForcePathStyle: { type: 'boolean' },
|
objectStorageS3ForcePathStyle: { type: 'boolean' },
|
||||||
enableIpLogging: { type: 'boolean' },
|
enableIpLogging: { type: 'boolean' },
|
||||||
|
enableActiveEmailValidation: { type: 'boolean' },
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
@@ -421,6 +422,10 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||||||
set.enableIpLogging = ps.enableIpLogging;
|
set.enableIpLogging = ps.enableIpLogging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.enableActiveEmailValidation !== undefined) {
|
||||||
|
set.enableActiveEmailValidation = ps.enableActiveEmailValidation;
|
||||||
|
}
|
||||||
|
|
||||||
await db.transaction(async transactionalEntityManager => {
|
await db.transaction(async transactionalEntityManager => {
|
||||||
const metas = await transactionalEntityManager.find(Meta, {
|
const metas = await transactionalEntityManager.find(Meta, {
|
||||||
order: {
|
order: {
|
||||||
|
@@ -13,7 +13,7 @@ export const meta = {
|
|||||||
|
|
||||||
limit: {
|
limit: {
|
||||||
duration: 60000,
|
duration: 60000,
|
||||||
max: 10,
|
max: 15,
|
||||||
},
|
},
|
||||||
|
|
||||||
kind: 'read:notifications',
|
kind: 'read:notifications',
|
||||||
|
@@ -214,7 +214,7 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
|||||||
const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description;
|
const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description;
|
||||||
|
|
||||||
if (newName != null) {
|
if (newName != null) {
|
||||||
const tokens = mfm.parsePlain(newName);
|
const tokens = mfm.parseSimple(newName);
|
||||||
emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
|
emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ export default class extends Channel {
|
|||||||
constructor(id: string, connection: Channel['connection']) {
|
constructor(id: string, connection: Channel['connection']) {
|
||||||
super(id, connection);
|
super(id, connection);
|
||||||
this.onNote = this.onNote.bind(this);
|
this.onNote = this.onNote.bind(this);
|
||||||
|
this.emitTypers = this.emitTypers.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async init(params: any) {
|
public async init(params: any) {
|
||||||
|
@@ -78,6 +78,7 @@ const nodeinfo2 = async () => {
|
|||||||
enableEmail: meta.enableEmail,
|
enableEmail: meta.enableEmail,
|
||||||
enableServiceWorker: meta.enableServiceWorker,
|
enableServiceWorker: meta.enableServiceWorker,
|
||||||
proxyAccountName: proxyAccount ? proxyAccount.username : null,
|
proxyAccountName: proxyAccount ? proxyAccount.username : null,
|
||||||
|
themeColor: meta.themeColor || '#86b300',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -14,9 +14,11 @@
|
|||||||
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
||||||
(async () => {
|
(async () => {
|
||||||
window.onerror = (e) => {
|
window.onerror = (e) => {
|
||||||
|
console.error(e);
|
||||||
renderError('SOMETHING_HAPPENED', e);
|
renderError('SOMETHING_HAPPENED', e);
|
||||||
};
|
};
|
||||||
window.onunhandledrejection = (e) => {
|
window.onunhandledrejection = (e) => {
|
||||||
|
console.error(e);
|
||||||
renderError('SOMETHING_HAPPENED_IN_PROMISE', e);
|
renderError('SOMETHING_HAPPENED_IN_PROMISE', e);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,18 +49,30 @@
|
|||||||
localStorage.setItem('localeVersion', v);
|
localStorage.setItem('localeVersion', v);
|
||||||
} else {
|
} else {
|
||||||
await checkUpdate();
|
await checkUpdate();
|
||||||
renderError('LOCALE_FETCH_FAILED');
|
renderError('LOCALE_FETCH');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Script
|
//#region Script
|
||||||
import(`/assets/${CLIENT_ENTRY}`)
|
function importAppScript() {
|
||||||
.catch(async e => {
|
import(`/assets/${CLIENT_ENTRY}`)
|
||||||
await checkUpdate();
|
.catch(async e => {
|
||||||
renderError('APP_FETCH_FAILED', e);
|
await checkUpdate();
|
||||||
})
|
console.error(e);
|
||||||
|
renderError('APP_IMPORT', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある
|
||||||
|
if (document.readyState !== 'loading') {
|
||||||
|
importAppScript();
|
||||||
|
} else {
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
importAppScript();
|
||||||
|
});
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Theme
|
//#region Theme
|
||||||
@@ -112,35 +126,37 @@
|
|||||||
let errorsElement = document.getElementById('errors');
|
let errorsElement = document.getElementById('errors');
|
||||||
|
|
||||||
if (!errorsElement) {
|
if (!errorsElement) {
|
||||||
document.documentElement.innerHTML = `
|
document.body.innerHTML = `
|
||||||
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
<path d="M12 9v2m0 4v.01"></path>
|
<path d="M12 9v2m0 4v.01"></path>
|
||||||
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
||||||
</svg>
|
</svg>
|
||||||
<h1>An error has occurred!</h1>
|
<h1>An error has occurred!</h1>
|
||||||
<button class="button-big" onclick="location.reload(true);">
|
<button class="button-big" onclick="location.reload(true);">
|
||||||
<span class="button-label-big">Refresh</span>
|
<span class="button-label-big">Refresh</span>
|
||||||
</button>
|
</button>
|
||||||
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
||||||
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
|
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
|
||||||
<a href="/flush">
|
<p>Update your os and browser.</p>
|
||||||
<button class="button-small">
|
<p>Disable an adblocker.</p>
|
||||||
<span class="button-label-small">Clear preferences and cache</span>
|
<a href="/flush">
|
||||||
</button>
|
<button class="button-small">
|
||||||
</a>
|
<span class="button-label-small">Clear preferences and cache</span>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<a href="/cli">
|
<a href="/cli">
|
||||||
<button class="button-small">
|
<button class="button-small">
|
||||||
<span class="button-label-small">Start the simple client</span>
|
<span class="button-label-small">Start the simple client</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<a href="/bios">
|
<a href="/bios">
|
||||||
<button class="button-small">
|
<button class="button-small">
|
||||||
<span class="button-label-small">Start the repair tool</span>
|
<span class="button-label-small">Start the repair tool</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<div id="errors"></div>
|
<div id="errors"></div>
|
||||||
`;
|
`;
|
||||||
@@ -269,17 +285,22 @@
|
|||||||
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
// eslint-disable-next-line no-inner-declarations
|
||||||
async function checkUpdate() {
|
async function checkUpdate() {
|
||||||
// TODO: サーバーが落ちている場合などのエラーハンドリング
|
try {
|
||||||
const res = await fetch('/api/meta', {
|
const res = await fetch('/api/meta', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
cache: 'no-cache'
|
cache: 'no-cache'
|
||||||
});
|
});
|
||||||
|
|
||||||
const meta = await res.json();
|
const meta = await res.json();
|
||||||
|
|
||||||
if (meta.version != v) {
|
if (meta.version != v) {
|
||||||
localStorage.setItem('v', meta.version);
|
localStorage.setItem('v', meta.version);
|
||||||
refresh();
|
refresh();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
renderError('UPDATE_CHECK', e);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ html
|
|||||||
.then(registrations => {
|
.then(registrations => {
|
||||||
return Promise.all(registrations.map(registration => registration.unregister()));
|
return Promise.all(registrations.map(registration => registration.unregister()));
|
||||||
})
|
})
|
||||||
.catch(e => { throw Error(e) });
|
.catch(e => { throw new Error(e) });
|
||||||
}
|
}
|
||||||
|
|
||||||
message(successText);
|
message(successText);
|
||||||
|
@@ -2,19 +2,34 @@ import * as fs from 'node:fs';
|
|||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { dirname } from 'node:path';
|
import { dirname } from 'node:path';
|
||||||
import * as nsfw from 'nsfwjs';
|
import * as nsfw from 'nsfwjs';
|
||||||
import * as tf from '@tensorflow/tfjs-node';
|
import si from 'systeminformation';
|
||||||
|
|
||||||
const _filename = fileURLToPath(import.meta.url);
|
const _filename = fileURLToPath(import.meta.url);
|
||||||
const _dirname = dirname(_filename);
|
const _dirname = dirname(_filename);
|
||||||
|
|
||||||
|
const REQUIRED_CPU_FLAGS = ['avx2', 'fma'];
|
||||||
|
let isSupportedCpu: undefined | boolean = undefined;
|
||||||
|
|
||||||
let model: nsfw.NSFWJS;
|
let model: nsfw.NSFWJS;
|
||||||
|
|
||||||
export async function detectSensitive(path: string): Promise<nsfw.predictionType[] | null> {
|
export async function detectSensitive(path: string): Promise<nsfw.predictionType[] | null> {
|
||||||
try {
|
try {
|
||||||
|
if (isSupportedCpu === undefined) {
|
||||||
|
const cpuFlags = await getCpuFlags();
|
||||||
|
isSupportedCpu = REQUIRED_CPU_FLAGS.every(required => cpuFlags.includes(required));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSupportedCpu) {
|
||||||
|
console.error('This CPU cannot use TensorFlow.');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tf = await import('@tensorflow/tfjs-node');
|
||||||
|
|
||||||
if (model == null) model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, { size: 299 });
|
if (model == null) model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, { size: 299 });
|
||||||
|
|
||||||
const buffer = await fs.promises.readFile(path);
|
const buffer = await fs.promises.readFile(path);
|
||||||
const image = await tf.node.decodeImage(buffer, 3) as tf.Tensor3D;
|
const image = await tf.node.decodeImage(buffer, 3) as any;
|
||||||
try {
|
try {
|
||||||
const predictions = await model.classify(image);
|
const predictions = await model.classify(image);
|
||||||
return predictions;
|
return predictions;
|
||||||
@@ -26,3 +41,8 @@ export async function detectSensitive(path: string): Promise<nsfw.predictionType
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getCpuFlags(): Promise<string[]> {
|
||||||
|
const str = await si.cpuFlags();
|
||||||
|
return str.split(/\s+/);
|
||||||
|
}
|
||||||
|
@@ -34,7 +34,7 @@ export async function fetchInstanceMetadata(instance: Instance, force = false):
|
|||||||
const [favicon, icon, themeColor, name, description] = await Promise.all([
|
const [favicon, icon, themeColor, name, description] = await Promise.all([
|
||||||
fetchFaviconUrl(instance, dom).catch(() => null),
|
fetchFaviconUrl(instance, dom).catch(() => null),
|
||||||
fetchIconUrl(instance, dom, manifest).catch(() => null),
|
fetchIconUrl(instance, dom, manifest).catch(() => null),
|
||||||
getThemeColor(dom, manifest).catch(() => null),
|
getThemeColor(info, dom, manifest).catch(() => null),
|
||||||
getSiteName(info, dom, manifest).catch(() => null),
|
getSiteName(info, dom, manifest).catch(() => null),
|
||||||
getDescription(info, dom, manifest).catch(() => null),
|
getDescription(info, dom, manifest).catch(() => null),
|
||||||
]);
|
]);
|
||||||
@@ -208,8 +208,8 @@ async function fetchIconUrl(instance: Instance, doc: DOMWindow['document'] | nul
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getThemeColor(doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
async function getThemeColor(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
||||||
const themeColor = doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') || manifest?.theme_color;
|
const themeColor = info?.metadata?.themeColor || doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') || manifest?.theme_color;
|
||||||
|
|
||||||
if (themeColor) {
|
if (themeColor) {
|
||||||
const color = new tinycolor(themeColor);
|
const color = new tinycolor(themeColor);
|
||||||
|
@@ -64,6 +64,7 @@ export async function pushNotification<T extends keyof pushNotificationsTypes>(u
|
|||||||
type,
|
type,
|
||||||
body: type === 'notification' ? truncateNotification(body as Packed<'Notification'>) : body,
|
body: type === 'notification' ? truncateNotification(body as Packed<'Notification'>) : body,
|
||||||
userId,
|
userId,
|
||||||
|
dateTime: (new Date()).getTime(),
|
||||||
}), {
|
}), {
|
||||||
proxy: config.proxy,
|
proxy: config.proxy,
|
||||||
}).catch((err: any) => {
|
}).catch((err: any) => {
|
||||||
|
@@ -1,34 +1,37 @@
|
|||||||
import { validate as validateEmail } from 'deep-email-validator';
|
import { validate as validateEmail } from 'deep-email-validator';
|
||||||
import { UserProfiles } from '@/models/index.js';
|
import { UserProfiles } from '@/models/index.js';
|
||||||
|
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||||
|
|
||||||
export async function validateEmailForAccount(emailAddress: string): Promise<{
|
export async function validateEmailForAccount(emailAddress: string): Promise<{
|
||||||
available: boolean;
|
available: boolean;
|
||||||
reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp';
|
reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp';
|
||||||
}> {
|
}> {
|
||||||
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
const exist = await UserProfiles.countBy({
|
const exist = await UserProfiles.countBy({
|
||||||
emailVerified: true,
|
emailVerified: true,
|
||||||
email: emailAddress,
|
email: emailAddress,
|
||||||
});
|
});
|
||||||
|
|
||||||
const validated = await validateEmail({
|
const validated = meta.enableActiveEmailValidation ? await validateEmail({
|
||||||
email: emailAddress,
|
email: emailAddress,
|
||||||
validateRegex: true,
|
validateRegex: true,
|
||||||
validateMx: true,
|
validateMx: true,
|
||||||
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
|
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
|
||||||
validateDisposable: true, // 捨てアドかどうかチェック
|
validateDisposable: true, // 捨てアドかどうかチェック
|
||||||
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
|
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
|
||||||
});
|
}) : { valid: true };
|
||||||
|
|
||||||
const available = exist === 0 && validated.valid;
|
const available = exist === 0 && validated.valid;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
available,
|
available,
|
||||||
reason: available ? null :
|
reason: available ? null :
|
||||||
exist !== 0 ? 'used' :
|
exist !== 0 ? 'used' :
|
||||||
validated.reason === 'regex' ? 'format' :
|
validated.reason === 'regex' ? 'format' :
|
||||||
validated.reason === 'disposable' ? 'disposable' :
|
validated.reason === 'disposable' ? 'disposable' :
|
||||||
validated.reason === 'mx' ? 'mx' :
|
validated.reason === 'mx' ? 'mx' :
|
||||||
validated.reason === 'smtp' ? 'smtp' :
|
validated.reason === 'smtp' ? 'smtp' :
|
||||||
null,
|
null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"target": "es2017",
|
"target": "es2021",
|
||||||
"module": "es2020",
|
"module": "es2020",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"target": "es2017",
|
"target": "es2021",
|
||||||
"module": "es2020",
|
"module": "es2020",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -11,102 +11,79 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordapp/twemoji": "14.0.2",
|
"@discordapp/twemoji": "14.0.2",
|
||||||
"@fortawesome/fontawesome-free": "6.1.1",
|
"@fortawesome/fontawesome-free": "6.1.2",
|
||||||
"@rollup/plugin-alias": "3.1.9",
|
"@rollup/plugin-alias": "3.1.9",
|
||||||
"@rollup/plugin-json": "4.1.0",
|
"@rollup/plugin-json": "4.1.0",
|
||||||
"@syuilo/aiscript": "0.11.1",
|
"@syuilo/aiscript": "0.11.1",
|
||||||
"@vitejs/plugin-vue": "3.0.0-beta.1",
|
"@vitejs/plugin-vue": "3.0.1",
|
||||||
"@vue/compiler-sfc": "3.2.37",
|
"@vue/compiler-sfc": "3.2.37",
|
||||||
"abort-controller": "3.0.0",
|
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "5.0.1",
|
"autosize": "5.0.1",
|
||||||
"autwh": "0.1.0",
|
|
||||||
"blurhash": "1.1.5",
|
"blurhash": "1.1.5",
|
||||||
"broadcast-channel": "4.13.0",
|
"broadcast-channel": "4.14.0",
|
||||||
"browser-image-resizer": "git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.2",
|
"browser-image-resizer": "git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.2",
|
||||||
"chart.js": "3.8.0",
|
"chart.js": "3.8.2",
|
||||||
"chartjs-adapter-date-fns": "2.0.0",
|
"chartjs-adapter-date-fns": "2.0.0",
|
||||||
"chartjs-plugin-gradient": "0.5.0",
|
"chartjs-plugin-gradient": "0.5.0",
|
||||||
"chartjs-plugin-zoom": "1.2.1",
|
"chartjs-plugin-zoom": "1.2.1",
|
||||||
"compare-versions": "4.1.3",
|
"compare-versions": "4.1.3",
|
||||||
"content-disposition": "0.5.4",
|
|
||||||
"cropperjs": "2.0.0-beta",
|
"cropperjs": "2.0.0-beta",
|
||||||
"date-fns": "2.28.0",
|
"date-fns": "2.29.1",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eventemitter3": "4.0.7",
|
"eventemitter3": "4.0.7",
|
||||||
"feed": "4.2.2",
|
|
||||||
"idb-keyval": "6.2.0",
|
"idb-keyval": "6.2.0",
|
||||||
"insert-text-at-cursor": "0.3.0",
|
"insert-text-at-cursor": "0.3.0",
|
||||||
"json5": "2.2.1",
|
"json5": "2.2.1",
|
||||||
"katex": "0.15.6",
|
"katex": "0.15.6",
|
||||||
"matter-js": "0.18.0",
|
"matter-js": "0.18.0",
|
||||||
"mfm-js": "0.22.1",
|
"mfm-js": "0.23.0",
|
||||||
"misskey-js": "0.0.14",
|
"misskey-js": "0.0.14",
|
||||||
"mocha": "10.0.0",
|
"photoswipe": "5.3.0",
|
||||||
"ms": "2.1.3",
|
|
||||||
"nested-property": "4.0.0",
|
|
||||||
"photoswipe": "5.2.8",
|
|
||||||
"prismjs": "1.28.0",
|
"prismjs": "1.28.0",
|
||||||
"private-ip": "2.3.3",
|
|
||||||
"promise-limit": "2.7.0",
|
|
||||||
"pug": "3.0.2",
|
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
"qrcode": "1.5.0",
|
|
||||||
"querystring": "0.2.1",
|
"querystring": "0.2.1",
|
||||||
"random-seed": "0.3.0",
|
|
||||||
"reflect-metadata": "0.1.13",
|
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
"rollup": "2.75.7",
|
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
"sass": "1.53.0",
|
"sass": "1.54.0",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"strict-event-emitter-types": "2.0.0",
|
"strict-event-emitter-types": "2.0.0",
|
||||||
"stringz": "2.1.0",
|
"stringz": "2.1.0",
|
||||||
"syuilo-password-strength": "0.0.1",
|
"syuilo-password-strength": "0.0.1",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"three": "0.142.0",
|
"three": "0.143.0",
|
||||||
"throttle-debounce": "5.0.0",
|
"throttle-debounce": "5.0.0",
|
||||||
"tinycolor2": "1.4.2",
|
"tinycolor2": "1.4.2",
|
||||||
"tsc-alias": "1.6.11",
|
"tsc-alias": "1.7.0",
|
||||||
"tsconfig-paths": "4.0.0",
|
"tsconfig-paths": "4.0.0",
|
||||||
"twemoji-parser": "14.0.0",
|
"twemoji-parser": "14.0.0",
|
||||||
"typescript": "4.7.4",
|
"typescript": "4.7.4",
|
||||||
"uuid": "8.3.2",
|
"uuid": "8.3.2",
|
||||||
"v-debounce": "0.1.2",
|
|
||||||
"vanilla-tilt": "1.7.2",
|
"vanilla-tilt": "1.7.2",
|
||||||
"vite": "3.0.0-beta.7",
|
"vite": "3.0.4",
|
||||||
"vue": "3.2.37",
|
"vue": "3.2.37",
|
||||||
"vue-prism-editor": "2.0.0-alpha.2",
|
"vue-prism-editor": "2.0.0-alpha.2",
|
||||||
"vuedraggable": "4.0.1",
|
"vuedraggable": "4.0.1"
|
||||||
"websocket": "1.0.34",
|
|
||||||
"ws": "8.8.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/escape-regexp": "0.0.1",
|
"@types/escape-regexp": "0.0.1",
|
||||||
"@types/glob": "7.2.0",
|
"@types/glob": "7.2.0",
|
||||||
"@types/gulp": "4.0.9",
|
"@types/gulp": "4.0.9",
|
||||||
"@types/gulp-rename": "2.0.1",
|
"@types/gulp-rename": "2.0.1",
|
||||||
"@types/is-url": "1.2.30",
|
|
||||||
"@types/katex": "0.14.0",
|
"@types/katex": "0.14.0",
|
||||||
"@types/matter-js": "0.17.7",
|
"@types/matter-js": "0.17.7",
|
||||||
"@types/mocha": "9.1.1",
|
|
||||||
"@types/oauth": "0.9.1",
|
|
||||||
"@types/punycode": "2.1.0",
|
"@types/punycode": "2.1.0",
|
||||||
"@types/qrcode": "1.4.2",
|
|
||||||
"@types/random-seed": "0.3.3",
|
|
||||||
"@types/seedrandom": "3.0.2",
|
"@types/seedrandom": "3.0.2",
|
||||||
"@types/throttle-debounce": "5.0.0",
|
"@types/throttle-debounce": "5.0.0",
|
||||||
"@types/tinycolor2": "1.4.3",
|
"@types/tinycolor2": "1.4.3",
|
||||||
"@types/uuid": "8.3.4",
|
"@types/uuid": "8.3.4",
|
||||||
"@types/websocket": "1.0.5",
|
"@typescript-eslint/eslint-plugin": "5.31.0",
|
||||||
"@types/ws": "8.5.3",
|
"@typescript-eslint/parser": "5.31.0",
|
||||||
"@typescript-eslint/eslint-plugin": "5.30.0",
|
|
||||||
"@typescript-eslint/parser": "5.30.0",
|
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "10.3.0",
|
"cypress": "10.3.1",
|
||||||
"eslint": "8.18.0",
|
"eslint": "8.20.0",
|
||||||
"eslint-plugin-import": "2.26.0",
|
"eslint-plugin-import": "2.26.0",
|
||||||
"eslint-plugin-vue": "9.1.1",
|
"eslint-plugin-vue": "9.3.0",
|
||||||
|
"rollup": "2.77.2",
|
||||||
"start-server-and-test": "1.14.0"
|
"start-server-and-test": "1.14.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -206,17 +206,16 @@ export async function openAccountMenu(opts: {
|
|||||||
to: `/@${ $i.username }`,
|
to: `/@${ $i.username }`,
|
||||||
avatar: $i,
|
avatar: $i,
|
||||||
}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
|
}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
|
||||||
|
type: 'parent',
|
||||||
icon: 'fas fa-plus',
|
icon: 'fas fa-plus',
|
||||||
text: i18n.ts.addAccount,
|
text: i18n.ts.addAccount,
|
||||||
action: () => {
|
children: [{
|
||||||
popupMenu([{
|
text: i18n.ts.existingAccount,
|
||||||
text: i18n.ts.existingAccount,
|
action: () => { showSigninDialog(); },
|
||||||
action: () => { showSigninDialog(); },
|
}, {
|
||||||
}, {
|
text: i18n.ts.createAccount,
|
||||||
text: i18n.ts.createAccount,
|
action: () => { createAccount(); },
|
||||||
action: () => { createAccount(); },
|
}],
|
||||||
}], ev.currentTarget ?? ev.target);
|
|
||||||
},
|
|
||||||
}, {
|
}, {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
icon: 'fas fa-users',
|
icon: 'fas fa-users',
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<XNoteHeader class="header" :note="note" :mini="true"/>
|
<XNoteHeader class="header" :note="note" :mini="true"/>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<p v-if="note.cw != null" class="cw">
|
<p v-if="note.cw != null" class="cw">
|
||||||
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
|
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
|
||||||
<XCwButton v-model="showContent" :note="note"/>
|
<XCwButton v-model="showContent" :note="note"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="note.cw == null || showContent" class="content">
|
<div v-show="note.cw == null || showContent" class="content">
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<MkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" class="reply" :detail="true" :depth="depth + 1"/>
|
<MkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" class="reply" :detail="true" :depth="depth + 1"/>
|
||||||
</template>
|
</template>
|
||||||
<div v-else class="more">
|
<div v-else class="more">
|
||||||
<MkA class="text _link" :to="notePage(note)">{{ $ts.continueThread }} <i class="fas fa-angle-double-right"></i></MkA>
|
<MkA class="text _link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="fas fa-angle-double-right"></i></MkA>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -27,11 +27,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import { notePage } from '@/filters/note';
|
|
||||||
import XNoteHeader from './note-header.vue';
|
import XNoteHeader from './note-header.vue';
|
||||||
import MkNoteSubNoteContent from './sub-note-content.vue';
|
import MkNoteSubNoteContent from './sub-note-content.vue';
|
||||||
import XCwButton from './cw-button.vue';
|
import XCwButton from './cw-button.vue';
|
||||||
|
import { notePage } from '@/filters/note';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
note: misskey.entities.Note;
|
note: misskey.entities.Note;
|
||||||
@@ -49,7 +50,7 @@ let replies: misskey.entities.Note[] = $ref([]);
|
|||||||
if (props.detail) {
|
if (props.detail) {
|
||||||
os.api('notes/children', {
|
os.api('notes/children', {
|
||||||
noteId: props.note.id,
|
noteId: props.note.id,
|
||||||
limit: 5
|
limit: 5,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
replies = res;
|
replies = res;
|
||||||
});
|
});
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</MkA>
|
</MkA>
|
||||||
<MkKeyValue class="_formBlock">
|
<MkKeyValue class="_formBlock">
|
||||||
<template #key>{{ $ts.registeredDate }}</template>
|
<template #key>{{ i18n.ts.registeredDate }}</template>
|
||||||
<template #value>{{ new Date(report.targetUser.createdAt).toLocaleString() }} (<MkTime :time="report.targetUser.createdAt"/>)</template>
|
<template #value>{{ new Date(report.targetUser.createdAt).toLocaleString() }} (<MkTime :time="report.targetUser.createdAt"/>)</template>
|
||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,18 +18,18 @@
|
|||||||
<Mfm :text="report.comment"/>
|
<Mfm :text="report.comment"/>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div>{{ $ts.reporter }}: <MkAcct :user="report.reporter"/></div>
|
<div>{{ i18n.ts.reporter }}: <MkAcct :user="report.reporter"/></div>
|
||||||
<div v-if="report.assignee">
|
<div v-if="report.assignee">
|
||||||
{{ $ts.moderator }}:
|
{{ i18n.ts.moderator }}:
|
||||||
<MkAcct :user="report.assignee"/>
|
<MkAcct :user="report.assignee"/>
|
||||||
</div>
|
</div>
|
||||||
<div><MkTime :time="report.createdAt"/></div>
|
<div><MkTime :time="report.createdAt"/></div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<MkSwitch v-model="forward" :disabled="report.targetUser.host == null || report.resolved">
|
<MkSwitch v-model="forward" :disabled="report.targetUser.host == null || report.resolved">
|
||||||
{{ $ts.forwardReport }}
|
{{ i18n.ts.forwardReport }}
|
||||||
<template #caption>{{ $ts.forwardReportIsAnonymous }}</template>
|
<template #caption>{{ i18n.ts.forwardReportIsAnonymous }}</template>
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
<MkButton v-if="!report.resolved" primary @click="resolve">{{ $ts.abuseMarkAsResolved }}</MkButton>
|
<MkButton v-if="!report.resolved" primary @click="resolve">{{ i18n.ts.abuseMarkAsResolved }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,6 +41,7 @@ import MkSwitch from '@/components/form/switch.vue';
|
|||||||
import MkKeyValue from '@/components/key-value.vue';
|
import MkKeyValue from '@/components/key-value.vue';
|
||||||
import { acct, userPage } from '@/filters/user';
|
import { acct, userPage } from '@/filters/user';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
report: any;
|
report: any;
|
||||||
|
@@ -1,12 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="mbcofsoe" viewBox="0 0 10 10" preserveAspectRatio="none">
|
<svg class="mbcofsoe" viewBox="0 0 10 10" preserveAspectRatio="none">
|
||||||
<circle v-for="(angle, i) in graduations"
|
<template v-if="props.graduations === 'dots'">
|
||||||
:key="i"
|
<circle
|
||||||
:cx="5 + (Math.sin(angle) * (5 - graduationsPadding))"
|
v-for="(angle, i) in graduationsMajor"
|
||||||
:cy="5 - (Math.cos(angle) * (5 - graduationsPadding))"
|
:cx="5 + (Math.sin(angle) * (5 - graduationsPadding))"
|
||||||
:r="i % 5 == 0 ? 0.125 : 0.05"
|
:cy="5 - (Math.cos(angle) * (5 - graduationsPadding))"
|
||||||
:fill="i % 5 == 0 ? majorGraduationColor : minorGraduationColor"
|
:r="0.125"
|
||||||
/>
|
:fill="(props.twentyfour ? h : h % 12) === i ? nowColor : majorGraduationColor"
|
||||||
|
:opacity="!props.fadeGraduations || (props.twentyfour ? h : h % 12) === i ? 1 : Math.max(0, 1 - (angleDiff(hAngle, angle) / Math.PI) - numbersOpacityFactor)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="props.graduations === 'numbers'">
|
||||||
|
<text
|
||||||
|
v-for="(angle, i) in texts"
|
||||||
|
:x="5 + (Math.sin(angle) * (5 - textsPadding))"
|
||||||
|
:y="5 - (Math.cos(angle) * (5 - textsPadding))"
|
||||||
|
text-anchor="middle"
|
||||||
|
dominant-baseline="middle"
|
||||||
|
:font-size="(props.twentyfour ? h : h % 12) === i ? 1 : 0.7"
|
||||||
|
:font-weight="(props.twentyfour ? h : h % 12) === i ? 'bold' : 'normal'"
|
||||||
|
:fill="(props.twentyfour ? h : h % 12) === i ? nowColor : 'currentColor'"
|
||||||
|
:opacity="!props.fadeGraduations || (props.twentyfour ? h : h % 12) === i ? 1 : Math.max(0, 1 - (angleDiff(hAngle, angle) / Math.PI) - numbersOpacityFactor)"
|
||||||
|
>
|
||||||
|
{{ i === 0 ? (props.twentyfour ? '24' : '12') : i }}
|
||||||
|
</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
<line
|
<line
|
||||||
:x1="5 - (Math.sin(sAngle) * (sHandLengthRatio * handsTailLength))"
|
:x1="5 - (Math.sin(sAngle) * (sHandLengthRatio * handsTailLength))"
|
||||||
@@ -41,63 +59,116 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
|
import { ref, computed, onMounted, onBeforeUnmount, shallowRef } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
|
import { globalEvents } from '@/events.js';
|
||||||
|
|
||||||
withDefaults(defineProps<{
|
// https://stackoverflow.com/questions/1878907/how-can-i-find-the-difference-between-two-angles
|
||||||
thickness: number;
|
const angleDiff = (a: number, b: number) => {
|
||||||
|
const x = Math.abs(a - b);
|
||||||
|
return Math.abs((x + Math.PI) % (Math.PI * 2) - Math.PI);
|
||||||
|
};
|
||||||
|
|
||||||
|
const graduationsPadding = 0.5;
|
||||||
|
const textsPadding = 0.6;
|
||||||
|
const handsPadding = 1;
|
||||||
|
const handsTailLength = 0.7;
|
||||||
|
const hHandLengthRatio = 0.75;
|
||||||
|
const mHandLengthRatio = 1;
|
||||||
|
const sHandLengthRatio = 1;
|
||||||
|
const numbersOpacityFactor = 0.35;
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
thickness?: number;
|
||||||
|
offset?: number;
|
||||||
|
twentyfour?: boolean;
|
||||||
|
graduations?: 'none' | 'dots' | 'numbers';
|
||||||
|
fadeGraduations?: boolean;
|
||||||
}>(), {
|
}>(), {
|
||||||
|
numbers: false,
|
||||||
thickness: 0.1,
|
thickness: 0.1,
|
||||||
|
offset: 0 - new Date().getTimezoneOffset(),
|
||||||
|
twentyfour: false,
|
||||||
|
graduations: 'dots',
|
||||||
|
fadeGraduations: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const now = ref(new Date());
|
const graduationsMajor = computed(() => {
|
||||||
const enabled = ref(true);
|
|
||||||
const graduationsPadding = ref(0.5);
|
|
||||||
const handsPadding = ref(1);
|
|
||||||
const handsTailLength = ref(0.7);
|
|
||||||
const hHandLengthRatio = ref(0.75);
|
|
||||||
const mHandLengthRatio = ref(1);
|
|
||||||
const sHandLengthRatio = ref(1);
|
|
||||||
const computedStyle = getComputedStyle(document.documentElement);
|
|
||||||
|
|
||||||
const dark = computed(() => tinycolor(computedStyle.getPropertyValue('--bg')).isDark());
|
|
||||||
const majorGraduationColor = computed(() => dark.value ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)');
|
|
||||||
const minorGraduationColor = computed(() => dark.value ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)');
|
|
||||||
const sHandColor = computed(() => dark.value ? 'rgba(255, 255, 255, 0.5)' : 'rgba(0, 0, 0, 0.3)');
|
|
||||||
const mHandColor = computed(() => tinycolor(computedStyle.getPropertyValue('--fg')).toHexString());
|
|
||||||
const hHandColor = computed(() => tinycolor(computedStyle.getPropertyValue('--accent')).toHexString());
|
|
||||||
const s = computed(() => now.value.getSeconds());
|
|
||||||
const m = computed(() => now.value.getMinutes());
|
|
||||||
const h = computed(() => now.value.getHours());
|
|
||||||
const hAngle = computed(() => Math.PI * (h.value % 12 + (m.value + s.value / 60) / 60) / 6);
|
|
||||||
const mAngle = computed(() => Math.PI * (m.value + s.value / 60) / 30);
|
|
||||||
const sAngle = computed(() => Math.PI * s.value / 30);
|
|
||||||
const graduations = computed(() => {
|
|
||||||
const angles: number[] = [];
|
const angles: number[] = [];
|
||||||
for (let i = 0; i < 60; i++) {
|
const times = props.twentyfour ? 24 : 12;
|
||||||
const angle = Math.PI * i / 30;
|
for (let i = 0; i < times; i++) {
|
||||||
|
const angle = Math.PI * i / (times / 2);
|
||||||
|
angles.push(angle);
|
||||||
|
}
|
||||||
|
return angles;
|
||||||
|
});
|
||||||
|
const texts = computed(() => {
|
||||||
|
const angles: number[] = [];
|
||||||
|
const times = props.twentyfour ? 24 : 12;
|
||||||
|
for (let i = 0; i < times; i++) {
|
||||||
|
const angle = Math.PI * i / (times / 2);
|
||||||
angles.push(angle);
|
angles.push(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return angles;
|
return angles;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let enabled = true;
|
||||||
|
let majorGraduationColor = $ref<string>();
|
||||||
|
//let minorGraduationColor = $ref<string>();
|
||||||
|
let sHandColor = $ref<string>();
|
||||||
|
let mHandColor = $ref<string>();
|
||||||
|
let hHandColor = $ref<string>();
|
||||||
|
let nowColor = $ref<string>();
|
||||||
|
let h = $ref<number>(0);
|
||||||
|
let m = $ref<number>(0);
|
||||||
|
let s = $ref<number>(0);
|
||||||
|
let hAngle = $ref<number>(0);
|
||||||
|
let mAngle = $ref<number>(0);
|
||||||
|
let sAngle = $ref<number>(0);
|
||||||
|
|
||||||
function tick() {
|
function tick() {
|
||||||
now.value = new Date();
|
const now = new Date();
|
||||||
|
now.setMinutes(now.getMinutes() + (new Date().getTimezoneOffset() + props.offset));
|
||||||
|
s = now.getSeconds();
|
||||||
|
m = now.getMinutes();
|
||||||
|
h = now.getHours();
|
||||||
|
hAngle = Math.PI * (h % (props.twentyfour ? 24 : 12) + (m + s / 60) / 60) / (props.twentyfour ? 12 : 6);
|
||||||
|
mAngle = Math.PI * (m + s / 60) / 30;
|
||||||
|
sAngle = Math.PI * s / 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
function calcColors() {
|
||||||
|
const computedStyle = getComputedStyle(document.documentElement);
|
||||||
|
const dark = tinycolor(computedStyle.getPropertyValue('--bg')).isDark();
|
||||||
|
const accent = tinycolor(computedStyle.getPropertyValue('--accent')).toHexString();
|
||||||
|
majorGraduationColor = dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
|
||||||
|
//minorGraduationColor = dark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
||||||
|
sHandColor = dark ? 'rgba(255, 255, 255, 0.5)' : 'rgba(0, 0, 0, 0.3)';
|
||||||
|
mHandColor = tinycolor(computedStyle.getPropertyValue('--fg')).toHexString();
|
||||||
|
hHandColor = accent;
|
||||||
|
nowColor = accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
calcColors();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const update = () => {
|
const update = () => {
|
||||||
if (enabled.value) {
|
if (enabled) {
|
||||||
tick();
|
tick();
|
||||||
window.setTimeout(update, 1000);
|
window.setTimeout(update, 1000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
globalEvents.on('themeChanged', calcColors);
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
enabled.value = false;
|
enabled = false;
|
||||||
|
|
||||||
|
globalEvents.off('themeChanged', calcColors);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -316,7 +316,7 @@ const render = () => {
|
|||||||
plugins: [{
|
plugins: [{
|
||||||
id: 'vLine',
|
id: 'vLine',
|
||||||
beforeDraw(chart, args, options) {
|
beforeDraw(chart, args, options) {
|
||||||
if (chart.tooltip._active && chart.tooltip._active.length) {
|
if (chart.tooltip?._active?.length) {
|
||||||
const activePoint = chart.tooltip._active[0];
|
const activePoint = chart.tooltip._active[0];
|
||||||
const ctx = chart.ctx;
|
const ctx = chart.ctx;
|
||||||
const x = activePoint.element.x;
|
const x = activePoint.element.x;
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
@ok="ok()"
|
@ok="ok()"
|
||||||
@closed="$emit('closed')"
|
@closed="$emit('closed')"
|
||||||
>
|
>
|
||||||
<template #header>{{ $ts.cropImage }}</template>
|
<template #header>{{ i18n.ts.cropImage }}</template>
|
||||||
<template #default="{ width, height }">
|
<template #default="{ width, height }">
|
||||||
<div class="mk-cropper-dialog" :style="`--vw: ${width}px; --vh: ${height}px;`">
|
<div class="mk-cropper-dialog" :style="`--vw: ${width}px; --vh: ${height}px;`">
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
@@ -36,6 +36,7 @@ import { $i } from '@/account';
|
|||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { apiUrl, url } from '@/config';
|
import { apiUrl, url } from '@/config';
|
||||||
import { query } from '@/scripts/url';
|
import { query } from '@/scripts/url';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: 'ok', cropped: misskey.entities.DriveFile): void;
|
(ev: 'ok', cropped: misskey.entities.DriveFile): void;
|
||||||
|
77
packages/client/src/components/digital-clock.vue
Normal file
77
packages/client/src/components/digital-clock.vue
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<span class="zjobosdg">
|
||||||
|
<span v-text="hh"></span>
|
||||||
|
<span class="colon" :class="{ showColon }">:</span>
|
||||||
|
<span v-text="mm"></span>
|
||||||
|
<span v-if="showS" class="colon" :class="{ showColon }">:</span>
|
||||||
|
<span v-if="showS" v-text="ss"></span>
|
||||||
|
<span v-if="showMs" class="colon" :class="{ showColon }">:</span>
|
||||||
|
<span v-if="showMs" v-text="ms"></span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onUnmounted, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
showS?: boolean;
|
||||||
|
showMs?: boolean;
|
||||||
|
offset?: number;
|
||||||
|
}>(), {
|
||||||
|
showS: true,
|
||||||
|
showMs: false,
|
||||||
|
offset: 0 - new Date().getTimezoneOffset(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let intervalId;
|
||||||
|
const hh = ref('');
|
||||||
|
const mm = ref('');
|
||||||
|
const ss = ref('');
|
||||||
|
const ms = ref('');
|
||||||
|
const showColon = ref(false);
|
||||||
|
let prevSec: number | null = null;
|
||||||
|
|
||||||
|
watch(showColon, (v) => {
|
||||||
|
if (v) {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
showColon.value = false;
|
||||||
|
}, 30);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
const now = new Date();
|
||||||
|
now.setMinutes(now.getMinutes() + (new Date().getTimezoneOffset() + props.offset));
|
||||||
|
hh.value = now.getHours().toString().padStart(2, '0');
|
||||||
|
mm.value = now.getMinutes().toString().padStart(2, '0');
|
||||||
|
ss.value = now.getSeconds().toString().padStart(2, '0');
|
||||||
|
ms.value = Math.floor(now.getMilliseconds() / 10).toString().padStart(2, '0');
|
||||||
|
if (now.getSeconds() !== prevSec) showColon.value = true;
|
||||||
|
prevSec = now.getSeconds();
|
||||||
|
};
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
watch(() => props.showMs, () => {
|
||||||
|
if (intervalId) window.clearInterval(intervalId);
|
||||||
|
intervalId = window.setInterval(tick, props.showMs ? 10 : 1000);
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.clearInterval(intervalId);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.zjobosdg {
|
||||||
|
> .colon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 1s ease;
|
||||||
|
|
||||||
|
&.showColon {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -59,7 +59,7 @@ const isThumbnailAvailable = computed(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
|
|
||||||
> .icon-sub {
|
> .icon-sub {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import XDrive from './drive.vue';
|
import XDrive from './drive.vue';
|
||||||
import XWindow from '@/components/ui/window.vue';
|
import XWindow from '@/components/ui/window.vue';
|
||||||
|
@@ -26,7 +26,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<button class="menu _button" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
|
<button class="menu _button" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
|
||||||
</nav>
|
</nav>
|
||||||
<div ref="main" class="main"
|
<div
|
||||||
|
ref="main" class="main"
|
||||||
:class="{ uploading: uploadings.length > 0, fetching }"
|
:class="{ uploading: uploadings.length > 0, fetching }"
|
||||||
@dragover.prevent.stop="onDragover"
|
@dragover.prevent.stop="onDragover"
|
||||||
@dragenter="onDragenter"
|
@dragenter="onDragenter"
|
||||||
@@ -142,7 +143,7 @@ const isDragSource = ref(false);
|
|||||||
const fetching = ref(true);
|
const fetching = ref(true);
|
||||||
|
|
||||||
const ilFilesObserver = new IntersectionObserver(
|
const ilFilesObserver = new IntersectionObserver(
|
||||||
(entries) => entries.some((entry) => entry.isIntersecting) && !fetching.value && moreFiles.value && fetchMoreFiles()
|
(entries) => entries.some((entry) => entry.isIntersecting) && !fetching.value && moreFiles.value && fetchMoreFiles(),
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(folder, () => emit('cd', folder.value));
|
watch(folder, () => emit('cd', folder.value));
|
||||||
@@ -232,7 +233,7 @@ function onDrop(ev: DragEvent): any {
|
|||||||
removeFile(file.id);
|
removeFile(file.id);
|
||||||
os.api('drive/files/update', {
|
os.api('drive/files/update', {
|
||||||
fileId: file.id,
|
fileId: file.id,
|
||||||
folderId: folder.value ? folder.value.id : null
|
folderId: folder.value ? folder.value.id : null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
@@ -248,7 +249,7 @@ function onDrop(ev: DragEvent): any {
|
|||||||
removeFolder(droppedFolder.id);
|
removeFolder(droppedFolder.id);
|
||||||
os.api('drive/folders/update', {
|
os.api('drive/folders/update', {
|
||||||
folderId: droppedFolder.id,
|
folderId: droppedFolder.id,
|
||||||
parentId: folder.value ? folder.value.id : null
|
parentId: folder.value ? folder.value.id : null,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// noop
|
// noop
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@@ -256,13 +257,13 @@ function onDrop(ev: DragEvent): any {
|
|||||||
case 'detected-circular-definition':
|
case 'detected-circular-definition':
|
||||||
os.alert({
|
os.alert({
|
||||||
title: i18n.ts.unableToProcess,
|
title: i18n.ts.unableToProcess,
|
||||||
text: i18n.ts.circularReferenceFolder
|
text: i18n.ts.circularReferenceFolder,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: i18n.ts.somethingHappened
|
text: i18n.ts.somethingHappened,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -278,17 +279,17 @@ function urlUpload() {
|
|||||||
os.inputText({
|
os.inputText({
|
||||||
title: i18n.ts.uploadFromUrl,
|
title: i18n.ts.uploadFromUrl,
|
||||||
type: 'url',
|
type: 'url',
|
||||||
placeholder: i18n.ts.uploadFromUrlDescription
|
placeholder: i18n.ts.uploadFromUrlDescription,
|
||||||
}).then(({ canceled, result: url }) => {
|
}).then(({ canceled, result: url }) => {
|
||||||
if (canceled || !url) return;
|
if (canceled || !url) return;
|
||||||
os.api('drive/files/upload-from-url', {
|
os.api('drive/files/upload-from-url', {
|
||||||
url: url,
|
url: url,
|
||||||
folderId: folder.value ? folder.value.id : undefined
|
folderId: folder.value ? folder.value.id : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
os.alert({
|
os.alert({
|
||||||
title: i18n.ts.uploadFromUrlRequested,
|
title: i18n.ts.uploadFromUrlRequested,
|
||||||
text: i18n.ts.uploadFromUrlMayTakeTime
|
text: i18n.ts.uploadFromUrlMayTakeTime,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -296,12 +297,12 @@ function urlUpload() {
|
|||||||
function createFolder() {
|
function createFolder() {
|
||||||
os.inputText({
|
os.inputText({
|
||||||
title: i18n.ts.createFolder,
|
title: i18n.ts.createFolder,
|
||||||
placeholder: i18n.ts.folderName
|
placeholder: i18n.ts.folderName,
|
||||||
}).then(({ canceled, result: name }) => {
|
}).then(({ canceled, result: name }) => {
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
os.api('drive/folders/create', {
|
os.api('drive/folders/create', {
|
||||||
name: name,
|
name: name,
|
||||||
parentId: folder.value ? folder.value.id : undefined
|
parentId: folder.value ? folder.value.id : undefined,
|
||||||
}).then(createdFolder => {
|
}).then(createdFolder => {
|
||||||
addFolder(createdFolder, true);
|
addFolder(createdFolder, true);
|
||||||
});
|
});
|
||||||
@@ -312,12 +313,12 @@ function renameFolder(folderToRename: Misskey.entities.DriveFolder) {
|
|||||||
os.inputText({
|
os.inputText({
|
||||||
title: i18n.ts.renameFolder,
|
title: i18n.ts.renameFolder,
|
||||||
placeholder: i18n.ts.inputNewFolderName,
|
placeholder: i18n.ts.inputNewFolderName,
|
||||||
default: folderToRename.name
|
default: folderToRename.name,
|
||||||
}).then(({ canceled, result: name }) => {
|
}).then(({ canceled, result: name }) => {
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
os.api('drive/folders/update', {
|
os.api('drive/folders/update', {
|
||||||
folderId: folderToRename.id,
|
folderId: folderToRename.id,
|
||||||
name: name
|
name: name,
|
||||||
}).then(updatedFolder => {
|
}).then(updatedFolder => {
|
||||||
// FIXME: 画面を更新するために自分自身に移動
|
// FIXME: 画面を更新するために自分自身に移動
|
||||||
move(updatedFolder);
|
move(updatedFolder);
|
||||||
@@ -327,7 +328,7 @@ function renameFolder(folderToRename: Misskey.entities.DriveFolder) {
|
|||||||
|
|
||||||
function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) {
|
function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) {
|
||||||
os.api('drive/folders/delete', {
|
os.api('drive/folders/delete', {
|
||||||
folderId: folderToDelete.id
|
folderId: folderToDelete.id,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// 削除時に親フォルダに移動
|
// 削除時に親フォルダに移動
|
||||||
move(folderToDelete.parentId);
|
move(folderToDelete.parentId);
|
||||||
@@ -337,15 +338,15 @@ function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) {
|
|||||||
os.alert({
|
os.alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: i18n.ts.unableToDelete,
|
title: i18n.ts.unableToDelete,
|
||||||
text: i18n.ts.hasChildFilesOrFolders
|
text: i18n.ts.hasChildFilesOrFolders,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: i18n.ts.unableToDelete
|
text: i18n.ts.unableToDelete,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +412,7 @@ function move(target?: Misskey.entities.DriveFolder) {
|
|||||||
fetching.value = true;
|
fetching.value = true;
|
||||||
|
|
||||||
os.api('drive/folders/show', {
|
os.api('drive/folders/show', {
|
||||||
folderId: target
|
folderId: target,
|
||||||
}).then(folderToMove => {
|
}).then(folderToMove => {
|
||||||
folder.value = folderToMove;
|
folder.value = folderToMove;
|
||||||
hierarchyFolders.value = [];
|
hierarchyFolders.value = [];
|
||||||
@@ -510,7 +511,7 @@ async function fetch() {
|
|||||||
|
|
||||||
const foldersPromise = os.api('drive/folders', {
|
const foldersPromise = os.api('drive/folders', {
|
||||||
folderId: folder.value ? folder.value.id : null,
|
folderId: folder.value ? folder.value.id : null,
|
||||||
limit: foldersMax + 1
|
limit: foldersMax + 1,
|
||||||
}).then(fetchedFolders => {
|
}).then(fetchedFolders => {
|
||||||
if (fetchedFolders.length === foldersMax + 1) {
|
if (fetchedFolders.length === foldersMax + 1) {
|
||||||
moreFolders.value = true;
|
moreFolders.value = true;
|
||||||
@@ -522,7 +523,7 @@ async function fetch() {
|
|||||||
const filesPromise = os.api('drive/files', {
|
const filesPromise = os.api('drive/files', {
|
||||||
folderId: folder.value ? folder.value.id : null,
|
folderId: folder.value ? folder.value.id : null,
|
||||||
type: props.type,
|
type: props.type,
|
||||||
limit: filesMax + 1
|
limit: filesMax + 1,
|
||||||
}).then(fetchedFiles => {
|
}).then(fetchedFiles => {
|
||||||
if (fetchedFiles.length === filesMax + 1) {
|
if (fetchedFiles.length === filesMax + 1) {
|
||||||
moreFiles.value = true;
|
moreFiles.value = true;
|
||||||
@@ -549,7 +550,7 @@ function fetchMoreFiles() {
|
|||||||
folderId: folder.value ? folder.value.id : null,
|
folderId: folder.value ? folder.value.id : null,
|
||||||
type: props.type,
|
type: props.type,
|
||||||
untilId: files.value[files.value.length - 1].id,
|
untilId: files.value[files.value.length - 1].id,
|
||||||
limit: max + 1
|
limit: max + 1,
|
||||||
}).then(files => {
|
}).then(files => {
|
||||||
if (files.length === max + 1) {
|
if (files.length === max + 1) {
|
||||||
moreFiles.value = true;
|
moreFiles.value = true;
|
||||||
@@ -569,30 +570,30 @@ function getMenu() {
|
|||||||
ref: keepOriginal,
|
ref: keepOriginal,
|
||||||
}, null, {
|
}, null, {
|
||||||
text: i18n.ts.addFile,
|
text: i18n.ts.addFile,
|
||||||
type: 'label'
|
type: 'label',
|
||||||
}, {
|
}, {
|
||||||
text: i18n.ts.upload,
|
text: i18n.ts.upload,
|
||||||
icon: 'fas fa-upload',
|
icon: 'fas fa-upload',
|
||||||
action: () => { selectLocalFile(); }
|
action: () => { selectLocalFile(); },
|
||||||
}, {
|
}, {
|
||||||
text: i18n.ts.fromUrl,
|
text: i18n.ts.fromUrl,
|
||||||
icon: 'fas fa-link',
|
icon: 'fas fa-link',
|
||||||
action: () => { urlUpload(); }
|
action: () => { urlUpload(); },
|
||||||
}, null, {
|
}, null, {
|
||||||
text: folder.value ? folder.value.name : i18n.ts.drive,
|
text: folder.value ? folder.value.name : i18n.ts.drive,
|
||||||
type: 'label'
|
type: 'label',
|
||||||
}, folder.value ? {
|
}, folder.value ? {
|
||||||
text: i18n.ts.renameFolder,
|
text: i18n.ts.renameFolder,
|
||||||
icon: 'fas fa-i-cursor',
|
icon: 'fas fa-i-cursor',
|
||||||
action: () => { renameFolder(folder.value); }
|
action: () => { renameFolder(folder.value); },
|
||||||
} : undefined, folder.value ? {
|
} : undefined, folder.value ? {
|
||||||
text: i18n.ts.deleteFolder,
|
text: i18n.ts.deleteFolder,
|
||||||
icon: 'fas fa-trash-alt',
|
icon: 'fas fa-trash-alt',
|
||||||
action: () => { deleteFolder(folder.value as Misskey.entities.DriveFolder); }
|
action: () => { deleteFolder(folder.value as Misskey.entities.DriveFolder); },
|
||||||
} : undefined, {
|
} : undefined, {
|
||||||
text: i18n.ts.createFolder,
|
text: i18n.ts.createFolder,
|
||||||
icon: 'fas fa-folder-plus',
|
icon: 'fas fa-folder-plus',
|
||||||
action: () => { createFolder(); }
|
action: () => { createFolder(); },
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,14 +663,14 @@ onBeforeUnmount(() => {
|
|||||||
> .path {
|
> .path {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
line-height: 50px;
|
line-height: 42px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
line-height: 50px;
|
line-height: 42px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@keydown.enter="toggle"
|
@keydown.enter="toggle"
|
||||||
>
|
>
|
||||||
<span ref="button" v-adaptive-border v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button" @click.prevent="toggle">
|
<span ref="button" v-adaptive-border v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff" class="button" @click.prevent="toggle">
|
||||||
<i class="check fas fa-check"></i>
|
<i class="check fas fa-check"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="label">
|
<span class="label">
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
import { toRefs, Ref } from 'vue';
|
import { toRefs, Ref } from 'vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import Ripple from '@/components/ripple.vue';
|
import Ripple from '@/components/ripple.vue';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: boolean | Ref<boolean>;
|
modelValue: boolean | Ref<boolean>;
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="caption"><slot name="caption"></slot></div>
|
<div class="caption"><slot name="caption"></slot></div>
|
||||||
|
|
||||||
<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-check"></i> {{ $ts.save }}</MkButton>
|
<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-check"></i> {{ i18n.ts.save }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -38,10 +38,11 @@ import { onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from '
|
|||||||
import { debounce } from 'throttle-debounce';
|
import { debounce } from 'throttle-debounce';
|
||||||
import MkButton from '@/components/ui/button.vue';
|
import MkButton from '@/components/ui/button.vue';
|
||||||
import { useInterval } from '@/scripts/use-interval';
|
import { useInterval } from '@/scripts/use-interval';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string | number;
|
modelValue: string | number;
|
||||||
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time';
|
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search';
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@@ -77,9 +78,9 @@ const inputEl = ref<HTMLElement>();
|
|||||||
const prefixEl = ref<HTMLElement>();
|
const prefixEl = ref<HTMLElement>();
|
||||||
const suffixEl = ref<HTMLElement>();
|
const suffixEl = ref<HTMLElement>();
|
||||||
const height =
|
const height =
|
||||||
props.small ? 38 :
|
props.small ? 36 :
|
||||||
props.large ? 42 :
|
props.large ? 40 :
|
||||||
40;
|
38;
|
||||||
|
|
||||||
const focus = () => inputEl.value.focus();
|
const focus = () => inputEl.value.focus();
|
||||||
const onInput = (ev: KeyboardEvent) => {
|
const onInput = (ev: KeyboardEvent) => {
|
||||||
|
@@ -19,33 +19,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
props: {
|
to: string;
|
||||||
to: {
|
active?: boolean;
|
||||||
type: String,
|
external?: boolean;
|
||||||
required: true
|
behavior?: null | 'window' | 'browser' | 'modalWindow';
|
||||||
},
|
inline?: boolean;
|
||||||
active: {
|
}>();
|
||||||
type: Boolean,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
external: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
behavior: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
inline: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -61,7 +44,7 @@ export default defineComponent({
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 12px 14px 12px 14px;
|
padding: 10px 14px;
|
||||||
background: var(--buttonBg);
|
background: var(--buttonBg);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
@@ -18,34 +18,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
props: {
|
modelValue: any;
|
||||||
modelValue: {
|
value: any;
|
||||||
required: false,
|
disabled: boolean;
|
||||||
},
|
}>();
|
||||||
value: {
|
|
||||||
required: false,
|
const emit = defineEmits<{
|
||||||
},
|
(ev: 'update:modelValue', value: any): void;
|
||||||
disabled: {
|
}>();
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
let checked = $computed(() => props.modelValue === props.value);
|
||||||
},
|
|
||||||
},
|
function toggle(): void {
|
||||||
computed: {
|
if (props.disabled) return;
|
||||||
checked(): boolean {
|
emit('update:modelValue', props.value);
|
||||||
return this.modelValue === this.value;
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggle() {
|
|
||||||
if (this.disabled) return;
|
|
||||||
this.$emit('update:modelValue', this.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -54,13 +45,13 @@ export default defineComponent({
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 9px 12px;
|
padding: 8px 10px;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
background-color: var(--panel);
|
background-color: var(--panel);
|
||||||
background-clip: padding-box !important;
|
background-clip: padding-box !important;
|
||||||
border: solid 1px var(--panel);
|
border: solid 1px var(--panel);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transition: all 0.3s;
|
transition: all 0.2s;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
@@ -189,7 +189,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
|
|||||||
height: 3px;
|
height: 3px;
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
|
|
||||||
> .highlight {
|
> .highlight {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="caption"><slot name="caption"></slot></div>
|
<div class="caption"><slot name="caption"></slot></div>
|
||||||
|
|
||||||
<MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
|
<MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -31,6 +31,7 @@ import { onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs, VNode,
|
|||||||
import MkButton from '@/components/ui/button.vue';
|
import MkButton from '@/components/ui/button.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { useInterval } from '@/scripts/use-interval';
|
import { useInterval } from '@/scripts/use-interval';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string;
|
modelValue: string;
|
||||||
@@ -63,9 +64,9 @@ const prefixEl = ref(null);
|
|||||||
const suffixEl = ref(null);
|
const suffixEl = ref(null);
|
||||||
const container = ref(null);
|
const container = ref(null);
|
||||||
const height =
|
const height =
|
||||||
props.small ? 38 :
|
props.small ? 36 :
|
||||||
props.large ? 42 :
|
props.large ? 40 :
|
||||||
40;
|
38;
|
||||||
|
|
||||||
const focus = () => inputEl.value.focus();
|
const focus = () => inputEl.value.focus();
|
||||||
const onInput = (ev) => {
|
const onInput = (ev) => {
|
||||||
@@ -144,6 +145,8 @@ const onClick = (ev: MouseEvent) => {
|
|||||||
} else if (Array.isArray(vnode.children)) { // 何故かフラグメントになってくることがある
|
} else if (Array.isArray(vnode.children)) { // 何故かフラグメントになってくることがある
|
||||||
const fragment = vnode;
|
const fragment = vnode;
|
||||||
scanOptions(fragment.children);
|
scanOptions(fragment.children);
|
||||||
|
} else if (vnode.props == null) { // v-if で条件が false のときにこうなる
|
||||||
|
// nop?
|
||||||
} else {
|
} else {
|
||||||
const option = vnode;
|
const option = vnode;
|
||||||
pushOption(option);
|
pushOption(option);
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@keydown.enter="toggle"
|
@keydown.enter="toggle"
|
||||||
>
|
>
|
||||||
<span ref="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button" @click.prevent="toggle">
|
<span ref="button" v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff" class="button" @click.prevent="toggle">
|
||||||
<div class="knob"></div>
|
<div class="knob"></div>
|
||||||
</span>
|
</span>
|
||||||
<span class="label">
|
<span class="label">
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { toRefs, Ref } from 'vue';
|
import { toRefs, Ref } from 'vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: boolean | Ref<boolean>;
|
modelValue: boolean | Ref<boolean>;
|
||||||
|
@@ -2,7 +2,8 @@
|
|||||||
<div class="adhpbeos">
|
<div class="adhpbeos">
|
||||||
<div class="label" @click="focus"><slot name="label"></slot></div>
|
<div class="label" @click="focus"><slot name="label"></slot></div>
|
||||||
<div class="input" :class="{ disabled, focused, tall, pre }">
|
<div class="input" :class="{ disabled, focused, tall, pre }">
|
||||||
<textarea ref="inputEl"
|
<textarea
|
||||||
|
ref="inputEl"
|
||||||
v-model="v"
|
v-model="v"
|
||||||
v-adaptive-border
|
v-adaptive-border
|
||||||
:class="{ code, _monospace: code }"
|
:class="{ code, _monospace: code }"
|
||||||
@@ -21,14 +22,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="caption"><slot name="caption"></slot></div>
|
<div class="caption"><slot name="caption"></slot></div>
|
||||||
|
|
||||||
<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
|
<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||||
import MkButton from '@/components/ui/button.vue';
|
|
||||||
import { debounce } from 'throttle-debounce';
|
import { debounce } from 'throttle-debounce';
|
||||||
|
import MkButton from '@/components/ui/button.vue';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -37,66 +39,66 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
required: {
|
required: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
readonly: {
|
readonly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
pattern: {
|
pattern: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
autofocus: {
|
autofocus: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
spellcheck: {
|
spellcheck: {
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
tall: {
|
tall: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
pre: {
|
pre: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
debounce: {
|
debounce: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
manualSave: {
|
manualSave: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -166,6 +168,7 @@ export default defineComponent({
|
|||||||
onInput,
|
onInput,
|
||||||
onKeydown,
|
onKeydown,
|
||||||
updated,
|
updated,
|
||||||
|
i18n,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@@ -50,7 +50,7 @@ function onContextmenu(ev) {
|
|||||||
icon: 'fas fa-expand-alt',
|
icon: 'fas fa-expand-alt',
|
||||||
text: i18n.ts.showInPage,
|
text: i18n.ts.showInPage,
|
||||||
action: () => {
|
action: () => {
|
||||||
router.push(props.to);
|
router.push(props.to, 'forcePage');
|
||||||
},
|
},
|
||||||
}, null, {
|
}, null, {
|
||||||
icon: 'fas fa-external-link-alt',
|
icon: 'fas fa-external-link-alt',
|
||||||
@@ -79,7 +79,7 @@ function popout() {
|
|||||||
popout_(props.to);
|
popout_(props.to);
|
||||||
}
|
}
|
||||||
|
|
||||||
function nav() {
|
function nav(ev: MouseEvent) {
|
||||||
if (props.behavior === 'browser') {
|
if (props.behavior === 'browser') {
|
||||||
location.href = props.to;
|
location.href = props.to;
|
||||||
return;
|
return;
|
||||||
@@ -93,6 +93,10 @@ function nav() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
router.push(props.to);
|
if (ev.shiftKey) {
|
||||||
|
return openWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
router.push(props.to, ev.ctrlKey ? 'forcePage' : null);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<div v-if="!showMenu" class="main" :class="ad.place">
|
<div v-if="!showMenu" class="main" :class="ad.place">
|
||||||
<a :href="ad.url" target="_blank">
|
<a :href="ad.url" target="_blank">
|
||||||
<img :src="ad.imageUrl">
|
<img :src="ad.imageUrl">
|
||||||
<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle"></span></button>
|
<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle info-circle"></span></button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="menu">
|
<div v-else class="menu">
|
||||||
@@ -135,13 +135,19 @@ export default defineComponent({
|
|||||||
display: block;
|
display: block;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .menu {
|
> .menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 1px;
|
||||||
right: 0;
|
right: 1px;
|
||||||
background: var(--panel);
|
|
||||||
|
> .info-circle {
|
||||||
|
border: 3px solid var(--panel);
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--panel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,68 +1,41 @@
|
|||||||
char2filePath<template>
|
<template>
|
||||||
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
||||||
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
||||||
<span v-else-if="char && useOsNativeEmojis">{{ char }}</span>
|
<span v-else-if="char && useOsNativeEmojis">{{ char }}</span>
|
||||||
<span v-else>{{ emoji }}</span>
|
<span v-else>{{ emoji }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { computed, defineComponent, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { CustomEmoji } from 'misskey-js/built/entities';
|
||||||
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
|
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
|
||||||
import { char2filePath } from '@/scripts/twemoji-base';
|
import { char2filePath } from '@/scripts/twemoji-base';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { instance } from '@/instance';
|
import { instance } from '@/instance';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
props: {
|
emoji: string;
|
||||||
emoji: {
|
normal?: boolean;
|
||||||
type: String,
|
noStyle?: boolean;
|
||||||
required: true
|
customEmojis?: CustomEmoji[];
|
||||||
},
|
isReaction?: boolean;
|
||||||
normal: {
|
}>();
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
noStyle: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
customEmojis: {
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
isReaction: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(props) {
|
const isCustom = computed(() => props.emoji.startsWith(':'));
|
||||||
const isCustom = computed(() => props.emoji.startsWith(':'));
|
const char = computed(() => isCustom.value ? null : props.emoji);
|
||||||
const char = computed(() => isCustom.value ? null : props.emoji);
|
const useOsNativeEmojis = computed(() => defaultStore.state.useOsNativeEmojis && !props.isReaction);
|
||||||
const useOsNativeEmojis = computed(() => defaultStore.state.useOsNativeEmojis && !props.isReaction);
|
const ce = computed(() => props.customEmojis ?? instance.emojis ?? []);
|
||||||
const ce = computed(() => props.customEmojis || instance.emojis || []);
|
const customEmoji = computed(() => isCustom.value ? ce.value.find(x => x.name === props.emoji.substr(1, props.emoji.length - 2)) : null);
|
||||||
const customEmoji = computed(() => isCustom.value ? ce.value.find(x => x.name === props.emoji.substr(1, props.emoji.length - 2)) : null);
|
const url = computed(() => {
|
||||||
const url = computed(() => {
|
if (char.value) {
|
||||||
if (char.value) {
|
return char2filePath(char.value);
|
||||||
return char2filePath(char.value);
|
} else {
|
||||||
} else {
|
return defaultStore.state.disableShowingAnimatedImages
|
||||||
return defaultStore.state.disableShowingAnimatedImages
|
? getStaticImageUrl(customEmoji.value.url)
|
||||||
? getStaticImageUrl(customEmoji.value.url)
|
: customEmoji.value.url;
|
||||||
: customEmoji.value.url;
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
const alt = computed(() => customEmoji.value ? `:${customEmoji.value.name}:` : char.value);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url,
|
|
||||||
char,
|
|
||||||
alt,
|
|
||||||
customEmoji,
|
|
||||||
useOsNativeEmojis,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
const alt = computed(() => customEmoji.value ? `:${customEmoji.value.name}:` : char.value);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -2,14 +2,15 @@
|
|||||||
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
||||||
<div class="mjndxjcg">
|
<div class="mjndxjcg">
|
||||||
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
|
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
|
||||||
<p><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</p>
|
<p><i class="fas fa-exclamation-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
|
||||||
<MkButton class="button" @click="() => $emit('retry')">{{ $ts.retry }}</MkButton>
|
<MkButton class="button" @click="() => $emit('retry')">{{ i18n.ts.retry }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import MkButton from '@/components/ui/button.vue';
|
import MkButton from '@/components/ui/button.vue';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -16,9 +16,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useCssModule } from 'vue';
|
import { } from 'vue';
|
||||||
|
|
||||||
useCssModule();
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!narrow || hideTitle" class="tabs">
|
<div v-if="!narrow || hideTitle" class="tabs">
|
||||||
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = el" v-tooltip="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = el" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
||||||
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
||||||
<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span>
|
<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="buttons right">
|
<div class="buttons right">
|
||||||
<template v-for="action in actions">
|
<template v-for="action in actions">
|
||||||
<button v-tooltip="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
<button v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,12 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<KeepAlive :max="defaultStore.state.numberOfPageCache">
|
<KeepAlive :max="defaultStore.state.numberOfPageCache">
|
||||||
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
|
<Suspense>
|
||||||
|
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
|
||||||
|
|
||||||
|
<template #fallback>
|
||||||
|
Loading...
|
||||||
|
</template>
|
||||||
|
</Suspense>
|
||||||
</KeepAlive>
|
</KeepAlive>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { inject, nextTick, onMounted, onUnmounted, watch } from 'vue';
|
import { inject, nextTick, onBeforeUnmount, onMounted, onUnmounted, provide, watch } from 'vue';
|
||||||
import { Router } from '@/nirax';
|
import { Resolved, Router } from '@/nirax';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -19,19 +25,37 @@ if (router == null) {
|
|||||||
throw new Error('no router provided');
|
throw new Error('no router provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentPageComponent = $shallowRef(router.getCurrentComponent());
|
const currentDepth = inject('routerCurrentDepth', 0);
|
||||||
let currentPageProps = $ref(router.getCurrentProps());
|
provide('routerCurrentDepth', currentDepth + 1);
|
||||||
let key = $ref(router.getCurrentKey());
|
|
||||||
|
|
||||||
function onChange({ route, props: newProps, key: newKey }) {
|
function resolveNested(current: Resolved, d = 0): Resolved | null {
|
||||||
currentPageComponent = route.component;
|
if (d === currentDepth) {
|
||||||
currentPageProps = newProps;
|
return current;
|
||||||
key = newKey;
|
} else {
|
||||||
|
if (current.child) {
|
||||||
|
return resolveNested(current.child, d + 1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const current = resolveNested(router.current)!;
|
||||||
|
let currentPageComponent = $shallowRef(current.route.component);
|
||||||
|
let currentPageProps = $ref(current.props);
|
||||||
|
let key = $ref(current.route.path + JSON.stringify(Object.fromEntries(current.props)));
|
||||||
|
|
||||||
|
function onChange({ resolved, key: newKey }) {
|
||||||
|
const current = resolveNested(resolved);
|
||||||
|
if (current == null) return;
|
||||||
|
currentPageComponent = current.route.component;
|
||||||
|
currentPageProps = current.props;
|
||||||
|
key = current.route.path + JSON.stringify(Object.fromEntries(current.props));
|
||||||
}
|
}
|
||||||
|
|
||||||
router.addListener('change', onChange);
|
router.addListener('change', onChange);
|
||||||
|
|
||||||
onUnmounted(() => {
|
onBeforeUnmount(() => {
|
||||||
router.removeListener('change', onChange);
|
router.removeListener('change', onChange);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@@ -20,7 +20,7 @@ const props = withDefaults(defineProps<{
|
|||||||
const _time = typeof props.time === 'string' ? new Date(props.time) : props.time;
|
const _time = typeof props.time === 'string' ? new Date(props.time) : props.time;
|
||||||
const absolute = _time.toLocaleString();
|
const absolute = _time.toLocaleString();
|
||||||
|
|
||||||
let now = $ref(new Date());
|
let now = $shallowRef(new Date());
|
||||||
const relative = $computed(() => {
|
const relative = $computed(() => {
|
||||||
const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/;
|
const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/;
|
||||||
return (
|
return (
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<component :is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
<component
|
||||||
|
:is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||||
@contextmenu.stop="() => {}"
|
@contextmenu.stop="() => {}"
|
||||||
>
|
>
|
||||||
<template v-if="!self">
|
<template v-if="!self">
|
||||||
@@ -23,14 +24,7 @@ import { toUnicode as decodePunycode } from 'punycode/';
|
|||||||
import { url as local } from '@/config';
|
import { url as local } from '@/config';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { useTooltip } from '@/scripts/use-tooltip';
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
import { safeURIDecode } from '@/scripts/safe-uri-decode';
|
||||||
function safeURIDecode(str: string) {
|
|
||||||
try {
|
|
||||||
return decodeURIComponent(str);
|
|
||||||
} catch {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -42,7 +36,7 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const self = props.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
|
@@ -4,29 +4,29 @@
|
|||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="selects" style="display: flex;">
|
<div class="selects" style="display: flex;">
|
||||||
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
|
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
|
||||||
<optgroup :label="$ts.federation">
|
<optgroup :label="i18n.ts.federation">
|
||||||
<option value="federation">{{ $ts._charts.federation }}</option>
|
<option value="federation">{{ i18n.ts._charts.federation }}</option>
|
||||||
<option value="ap-request">{{ $ts._charts.apRequest }}</option>
|
<option value="ap-request">{{ i18n.ts._charts.apRequest }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$ts.users">
|
<optgroup :label="i18n.ts.users">
|
||||||
<option value="users">{{ $ts._charts.usersIncDec }}</option>
|
<option value="users">{{ i18n.ts._charts.usersIncDec }}</option>
|
||||||
<option value="users-total">{{ $ts._charts.usersTotal }}</option>
|
<option value="users-total">{{ i18n.ts._charts.usersTotal }}</option>
|
||||||
<option value="active-users">{{ $ts._charts.activeUsers }}</option>
|
<option value="active-users">{{ i18n.ts._charts.activeUsers }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$ts.notes">
|
<optgroup :label="i18n.ts.notes">
|
||||||
<option value="notes">{{ $ts._charts.notesIncDec }}</option>
|
<option value="notes">{{ i18n.ts._charts.notesIncDec }}</option>
|
||||||
<option value="local-notes">{{ $ts._charts.localNotesIncDec }}</option>
|
<option value="local-notes">{{ i18n.ts._charts.localNotesIncDec }}</option>
|
||||||
<option value="remote-notes">{{ $ts._charts.remoteNotesIncDec }}</option>
|
<option value="remote-notes">{{ i18n.ts._charts.remoteNotesIncDec }}</option>
|
||||||
<option value="notes-total">{{ $ts._charts.notesTotal }}</option>
|
<option value="notes-total">{{ i18n.ts._charts.notesTotal }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$ts.drive">
|
<optgroup :label="i18n.ts.drive">
|
||||||
<option value="drive-files">{{ $ts._charts.filesIncDec }}</option>
|
<option value="drive-files">{{ i18n.ts._charts.filesIncDec }}</option>
|
||||||
<option value="drive">{{ $ts._charts.storageUsageIncDec }}</option>
|
<option value="drive">{{ i18n.ts._charts.storageUsageIncDec }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</MkSelect>
|
</MkSelect>
|
||||||
<MkSelect v-model="chartSpan" style="margin: 0 0 0 10px;">
|
<MkSelect v-model="chartSpan" style="margin: 0 0 0 10px;">
|
||||||
<option value="hour">{{ $ts.perHour }}</option>
|
<option value="hour">{{ i18n.ts.perHour }}</option>
|
||||||
<option value="day">{{ $ts.perDay }}</option>
|
<option value="day">{{ i18n.ts.perDay }}</option>
|
||||||
</MkSelect>
|
</MkSelect>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
@@ -71,6 +71,7 @@ import MkSelect from '@/components/form/select.vue';
|
|||||||
import MkChart from '@/components/chart.vue';
|
import MkChart from '@/components/chart.vue';
|
||||||
import { useChartTooltip } from '@/scripts/use-chart-tooltip';
|
import { useChartTooltip } from '@/scripts/use-chart-tooltip';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
Chart.register(
|
Chart.register(
|
||||||
ArcElement,
|
ArcElement,
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import { instanceName } from '@/config';
|
import { instanceName } from '@/config';
|
||||||
|
import { instance as Instance } from '@/instance';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
instance?: {
|
instance?: {
|
||||||
@@ -19,7 +20,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
// if no instance data is given, this is for the local instance
|
// if no instance data is given, this is for the local instance
|
||||||
const instance = props.instance ?? {
|
const instance = props.instance ?? {
|
||||||
faviconUrl: '/favicon.ico',
|
faviconUrl: Instance.iconUrl || Instance.faviconUrl || '/favicon.ico',
|
||||||
name: instanceName,
|
name: instanceName,
|
||||||
themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement)?.content
|
themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement)?.content
|
||||||
};
|
};
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<slot name="value"></slot>
|
<slot name="value"></slot>
|
||||||
<button v-if="copy" v-tooltip="$ts.copy" class="_textButton" style="margin-left: 0.5em;" @click="copy_"><i class="far fa-copy"></i></button>
|
<button v-if="copy" v-tooltip="i18n.ts.copy" class="_textButton" style="margin-left: 0.5em;" @click="copy_"><i class="far fa-copy"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
copy?: string | null;
|
copy?: string | null;
|
||||||
|
@@ -15,20 +15,6 @@
|
|||||||
</MkA>
|
</MkA>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub">
|
|
||||||
<button v-click-anime class="_button" @click="help">
|
|
||||||
<i class="fas fa-question-circle icon"></i>
|
|
||||||
<div class="text">{{ $ts.help }}</div>
|
|
||||||
</button>
|
|
||||||
<MkA v-click-anime to="/about" @click.passive="close()">
|
|
||||||
<i class="fas fa-info-circle icon"></i>
|
|
||||||
<div class="text">{{ $ts.instanceInfo }}</div>
|
|
||||||
</MkA>
|
|
||||||
<MkA v-click-anime to="/about-misskey" @click.passive="close()">
|
|
||||||
<img src="/static-assets/favicon.png" class="icon"/>
|
|
||||||
<div class="text">{{ $ts.aboutMisskey }}</div>
|
|
||||||
</MkA>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</MkModal>
|
</MkModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -36,7 +22,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import MkModal from '@/components/ui/modal.vue';
|
import MkModal from '@/components/ui/modal.vue';
|
||||||
import { menuDef } from '@/menu';
|
import { navbarItemDef } from '@/navbar';
|
||||||
import { instanceName } from '@/config';
|
import { instanceName } from '@/config';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
@@ -62,7 +48,7 @@ const modal = $ref<InstanceType<typeof MkModal>>();
|
|||||||
|
|
||||||
const menu = defaultStore.state.menu;
|
const menu = defaultStore.state.menu;
|
||||||
|
|
||||||
const items = Object.keys(menuDef).filter(k => !menu.includes(k)).map(k => menuDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
|
const items = Object.keys(navbarItemDef).filter(k => !menu.includes(k)).map(k => navbarItemDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
|
||||||
type: def.to ? 'link' : 'button',
|
type: def.to ? 'link' : 'button',
|
||||||
text: i18n.ts[def.title],
|
text: i18n.ts[def.title],
|
||||||
icon: def.icon,
|
icon: def.icon,
|
||||||
@@ -74,28 +60,6 @@ const items = Object.keys(menuDef).filter(k => !menu.includes(k)).map(k => menuD
|
|||||||
function close() {
|
function close() {
|
||||||
modal.close();
|
modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function help(ev: MouseEvent) {
|
|
||||||
os.popupMenu([{
|
|
||||||
type: 'link',
|
|
||||||
to: '/mfm-cheat-sheet',
|
|
||||||
text: i18n.ts._mfm.cheatSheet,
|
|
||||||
icon: 'fas fa-code',
|
|
||||||
}, {
|
|
||||||
type: 'link',
|
|
||||||
to: '/scratchpad',
|
|
||||||
text: i18n.ts.scratchpad,
|
|
||||||
icon: 'fas fa-terminal',
|
|
||||||
}, null, {
|
|
||||||
text: i18n.ts.document,
|
|
||||||
icon: 'fas fa-question-circle',
|
|
||||||
action: () => {
|
|
||||||
window.open('https://misskey-hub.net/help.html', '_blank');
|
|
||||||
},
|
|
||||||
}], ev.currentTarget ?? ev.target);
|
|
||||||
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -76,7 +76,7 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
.wrap {
|
.wrap {
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
animation-play-state: running;
|
animation-play-state: running;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<MkA v-if="url.startsWith('/')" v-user-preview="canonical" :class="[$style.root, { isMe }]" :to="url" :style="{ background: bgCss }">
|
<MkA v-if="url.startsWith('/')" v-user-preview="canonical" class="akbvjaqn" :class="{ isMe }" :to="url" :style="{ background: bgCss }">
|
||||||
<img :class="$style.icon" :src="`/avatar/@${username}@${host}`" alt="">
|
<img class="icon" :src="`/avatar/@${username}@${host}`" alt="">
|
||||||
<span class="main">
|
<span class="main">
|
||||||
<span class="username">@{{ username }}</span>
|
<span class="username">@{{ username }}</span>
|
||||||
<span v-if="(host != localHost) || $store.state.showFullAcct" :class="$style.mainHost">@{{ toUnicode(host) }}</span>
|
<span v-if="(host != localHost) || $store.state.showFullAcct" class="host">@{{ toUnicode(host) }}</span>
|
||||||
</span>
|
</span>
|
||||||
</MkA>
|
</MkA>
|
||||||
<a v-else :class="$style.root" :href="url" target="_blank" rel="noopener" :style="{ background: bgCss }">
|
<a v-else class="akbvjaqn" :href="url" target="_blank" rel="noopener" :style="{ background: bgCss }">
|
||||||
<span class="main">
|
<span class="main">
|
||||||
<span class="username">@{{ username }}</span>
|
<span class="username">@{{ username }}</span>
|
||||||
<span :class="$style.mainHost">@{{ toUnicode(host) }}</span>
|
<span class="host">@{{ toUnicode(host) }}</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { toUnicode } from 'punycode';
|
import { toUnicode } from 'punycode';
|
||||||
import { useCssModule } from 'vue';
|
import { } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { host as localHost } from '@/config';
|
import { host as localHost } from '@/config';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
@@ -37,12 +37,10 @@ const isMe = $i && (
|
|||||||
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
|
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
|
||||||
bg.setAlpha(0.1);
|
bg.setAlpha(0.1);
|
||||||
const bgCss = bg.toRgbString();
|
const bgCss = bg.toRgbString();
|
||||||
|
|
||||||
useCssModule();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" scoped>
|
||||||
.root {
|
.akbvjaqn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 8px 4px 4px;
|
padding: 4px 8px 4px 4px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
@@ -51,18 +49,18 @@ useCssModule();
|
|||||||
&.isMe {
|
&.isMe {
|
||||||
color: var(--mentionMe);
|
color: var(--mentionMe);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
> .icon {
|
||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
margin: 0 0.2em 0 0;
|
margin: 0 0.2em 0 0;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainHost {
|
> .main > .host {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -47,7 +47,7 @@ export default defineComponent({
|
|||||||
render() {
|
render() {
|
||||||
if (this.text == null || this.text === '') return;
|
if (this.text == null || this.text === '') return;
|
||||||
|
|
||||||
const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
|
const ast = (this.plain ? mfm.parseSimple : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
|
||||||
|
|
||||||
const validTime = (t: string | null | undefined) => {
|
const validTime = (t: string | null | undefined) => {
|
||||||
if (t == null) return null;
|
if (t == null) return null;
|
||||||
@@ -312,6 +312,10 @@ export default defineComponent({
|
|||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'plain': {
|
||||||
|
return [h('span', genEl(token.children))];
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
console.error('unrecognized ast type:', token.type);
|
console.error('unrecognized ast type:', token.type);
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
<div v-if="isRenote" class="renote">
|
<div v-if="isRenote" class="renote">
|
||||||
<MkAvatar class="avatar" :user="note.user"/>
|
<MkAvatar class="avatar" :user="note.user"/>
|
||||||
<i class="fas fa-retweet"></i>
|
<i class="fas fa-retweet"></i>
|
||||||
<I18n :src="$ts.renotedBy" tag="span">
|
<I18n :src="i18n.ts.renotedBy" tag="span">
|
||||||
<template #user>
|
<template #user>
|
||||||
<MkA v-user-preview="note.userId" class="name" :to="userPage(note.user)">
|
<MkA v-user-preview="note.userId" class="name" :to="userPage(note.user)">
|
||||||
<MkUserName :user="note.user"/>
|
<MkUserName :user="note.user"/>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div v-show="appearNote.cw == null || showContent" class="content">
|
<div v-show="appearNote.cw == null || showContent" class="content">
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||||
<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
|
<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
|
||||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||||
<a v-if="appearNote.renote != null" class="rp">RN:</a>
|
<a v-if="appearNote.renote != null" class="rp">RN:</a>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
<MkNoteSub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
|
<MkNoteSub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="_panel muted" @click="muted = false">
|
<div v-else class="_panel muted" @click="muted = false">
|
||||||
<I18n :src="$ts.userSaysSomething" tag="small">
|
<I18n :src="i18n.ts.userSaysSomething" tag="small">
|
||||||
<template #name>
|
<template #name>
|
||||||
<MkA v-user-preview="appearNote.userId" class="name" :to="userPage(appearNote.user)">
|
<MkA v-user-preview="appearNote.userId" class="name" :to="userPage(appearNote.user)">
|
||||||
<MkUserName :user="appearNote.user"/>
|
<MkUserName :user="appearNote.user"/>
|
||||||
@@ -390,7 +390,7 @@ if (appearNote.replyId) {
|
|||||||
|
|
||||||
> .article {
|
> .article {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
|
|
||||||
> .header {
|
> .header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -27,7 +27,7 @@ const props = defineProps<{
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
|
|
||||||
&.min-width_350px {
|
&.min-width_350px {
|
||||||
|
@@ -36,7 +36,7 @@ const showContent = $ref(false);
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
|
|
||||||
&.min-width_350px {
|
&.min-width_350px {
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||||
<XCwButton v-model="showContent" :note="appearNote"/>
|
<XCwButton v-model="showContent" :note="appearNote"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="appearNote.cw == null || showContent" class="content" :class="{ collapsed }">
|
<div v-show="appearNote.cw == null || showContent" class="content" :class="{ collapsed, isLong }">
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||||
<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
|
<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
|
||||||
@@ -61,9 +61,12 @@
|
|||||||
<XPoll v-if="appearNote.poll" ref="pollViewer" :note="appearNote" class="poll"/>
|
<XPoll v-if="appearNote.poll" ref="pollViewer" :note="appearNote" class="poll"/>
|
||||||
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" class="url-preview"/>
|
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" class="url-preview"/>
|
||||||
<div v-if="appearNote.renote" class="renote"><XNoteSimple :note="appearNote.renote"/></div>
|
<div v-if="appearNote.renote" class="renote"><XNoteSimple :note="appearNote.renote"/></div>
|
||||||
<button v-if="collapsed" class="fade _button" @click="collapsed = false">
|
<button v-if="isLong && collapsed" class="fade _button" @click="collapsed = false">
|
||||||
<span>{{ i18n.ts.showMore }}</span>
|
<span>{{ i18n.ts.showMore }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-else-if="isLong && !collapsed" class="showLess _button" @click="collapsed = true">
|
||||||
|
<span>{{ i18n.ts.showLess }}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="fas fa-satellite-dish"></i> {{ appearNote.channel.name }}</MkA>
|
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="fas fa-satellite-dish"></i> {{ appearNote.channel.name }}</MkA>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,10 +165,11 @@ const reactButton = ref<HTMLElement>();
|
|||||||
let appearNote = $computed(() => isRenote ? note.renote as misskey.entities.Note : note);
|
let appearNote = $computed(() => isRenote ? note.renote as misskey.entities.Note : note);
|
||||||
const isMyRenote = $i && ($i.id === note.userId);
|
const isMyRenote = $i && ($i.id === note.userId);
|
||||||
const showContent = ref(false);
|
const showContent = ref(false);
|
||||||
const collapsed = ref(appearNote.cw == null && appearNote.text != null && (
|
const isLong = (appearNote.cw == null && appearNote.text != null && (
|
||||||
(appearNote.text.split('\n').length > 9) ||
|
(appearNote.text.split('\n').length > 9) ||
|
||||||
(appearNote.text.length > 500)
|
(appearNote.text.length > 500)
|
||||||
));
|
));
|
||||||
|
const collapsed = ref(appearNote.cw == null && isLong);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const muted = ref(checkWordMute(appearNote, $i, defaultStore.state.mutedWords));
|
const muted = ref(checkWordMute(appearNote, $i, defaultStore.state.mutedWords));
|
||||||
const translation = ref(null);
|
const translation = ref(null);
|
||||||
@@ -293,7 +297,7 @@ function readPromo() {
|
|||||||
position: relative;
|
position: relative;
|
||||||
transition: box-shadow 0.1s ease;
|
transition: box-shadow 0.1s ease;
|
||||||
font-size: 1.05em;
|
font-size: 1.05em;
|
||||||
overflow: hidden; overflow: clip;
|
overflow: clip;
|
||||||
contain: content;
|
contain: content;
|
||||||
|
|
||||||
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
|
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
|
||||||
@@ -442,6 +446,24 @@ function readPromo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
|
&.isLong {
|
||||||
|
> .showLess {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1em;
|
||||||
|
position: sticky;
|
||||||
|
bottom: 1em;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: inline-block;
|
||||||
|
background: var(--popup);
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
border-radius: 999px;
|
||||||
|
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.collapsed {
|
&.collapsed {
|
||||||
position: relative;
|
position: relative;
|
||||||
max-height: 9em;
|
max-height: 9em;
|
||||||
@@ -554,6 +576,13 @@ function readPromo() {
|
|||||||
|
|
||||||
&.max-width_500px {
|
&.max-width_500px {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
> .article {
|
||||||
|
> .avatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.max-width_450px {
|
&.max-width_450px {
|
||||||
@@ -570,8 +599,8 @@ function readPromo() {
|
|||||||
|
|
||||||
> .avatar {
|
> .avatar {
|
||||||
margin: 0 10px 8px 0;
|
margin: 0 10px 8px 0;
|
||||||
width: 50px;
|
width: 46px;
|
||||||
height: 50px;
|
height: 46px;
|
||||||
top: calc(14px + var(--stickyTop, 0px));
|
top: calc(14px + var(--stickyTop, 0px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -592,8 +621,6 @@ function readPromo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.max-width_300px {
|
&.max-width_300px {
|
||||||
font-size: 0.825em;
|
|
||||||
|
|
||||||
> .article {
|
> .article {
|
||||||
> .avatar {
|
> .avatar {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<div class="_fullinfo">
|
<div class="_fullinfo">
|
||||||
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
||||||
<div>{{ $ts.noNotes }}</div>
|
<div>{{ i18n.ts.noNotes }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import XNote from '@/components/note.vue';
|
import XNote from '@/components/note.vue';
|
||||||
import XList from '@/components/date-separated-list.vue';
|
import XList from '@/components/date-separated-list.vue';
|
||||||
import MkPagination from '@/components/ui/pagination.vue';
|
import MkPagination, { Paging } from '@/components/ui/pagination.vue';
|
||||||
import { Paging } from '@/components/ui/pagination.vue';
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
pagination: Paging;
|
pagination: Paging;
|
||||||
|
@@ -61,10 +61,10 @@
|
|||||||
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
|
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
|
||||||
<i class="fas fa-quote-right"></i>
|
<i class="fas fa-quote-right"></i>
|
||||||
</MkA>
|
</MkA>
|
||||||
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
|
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ i18n.ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
|
||||||
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $ts.followRequestAccepted }}</span>
|
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ i18n.ts.followRequestAccepted }}</span>
|
||||||
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $ts.reject }}</button></div></span>
|
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ i18n.ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ i18n.ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ i18n.ts.reject }}</button></div></span>
|
||||||
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $ts.reject }}</button></div></span>
|
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ i18n.ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ i18n.ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ i18n.ts.reject }}</button></div></span>
|
||||||
<span v-if="notification.type === 'app'" class="text">
|
<span v-if="notification.type === 'app'" class="text">
|
||||||
<Mfm :text="notification.body" :nowrap="!full"/>
|
<Mfm :text="notification.body" :nowrap="!full"/>
|
||||||
</span>
|
</span>
|
||||||
@@ -177,13 +177,7 @@ useTooltip(reactionRef, (showing) => {
|
|||||||
|
|
||||||
&.max-width_500px {
|
&.max-width_500px {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
font-size: 0.8em;
|
font-size: 0.85em;
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
clear: both;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .head {
|
> .head {
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<div class="_fullinfo">
|
<div class="_fullinfo">
|
||||||
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
||||||
<div>{{ $ts.noNotifications }}</div>
|
<div>{{ i18n.ts.noNotifications }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ import XNote from '@/components/note.vue';
|
|||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { stream } from '@/stream';
|
import { stream } from '@/stream';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
includeTypes?: typeof notificationTypes[number][];
|
includeTypes?: typeof notificationTypes[number][];
|
||||||
|
@@ -114,7 +114,7 @@ function menu(ev) {
|
|||||||
|
|
||||||
function back() {
|
function back() {
|
||||||
history.pop();
|
history.pop();
|
||||||
router.change(history[history.length - 1].path, history[history.length - 1].key);
|
router.replace(history[history.length - 1].path, history[history.length - 1].key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
@@ -122,7 +122,7 @@ function close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function expand() {
|
function expand() {
|
||||||
mainRouter.push(router.getCurrentPath());
|
mainRouter.push(router.getCurrentPath(), 'forcePage');
|
||||||
windowEl.close();
|
windowEl.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user