Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8e9717a5fc | ||
![]() |
3e28b296e3 | ||
![]() |
056fef70da | ||
![]() |
55be9cc9d1 | ||
![]() |
3f2ffcea97 | ||
![]() |
b07d037cb5 | ||
![]() |
4feccdfd92 | ||
![]() |
f1ef85b636 | ||
![]() |
cf9266eab9 | ||
![]() |
4a1552fb3c | ||
![]() |
e5863c2867 | ||
![]() |
58211fc6a7 | ||
![]() |
bd54e44b35 | ||
![]() |
e1f2e364a4 | ||
![]() |
186b26e103 | ||
![]() |
74706a8d2c | ||
![]() |
7e2b6b6369 | ||
![]() |
1a2de1a051 | ||
![]() |
83900cbca6 | ||
![]() |
166bc19131 | ||
![]() |
da874f3383 | ||
![]() |
9c30b23358 | ||
![]() |
b8350d5093 | ||
![]() |
58f7af8927 | ||
![]() |
c3b9c7b74b | ||
![]() |
9415618992 | ||
![]() |
1c200c9b94 | ||
![]() |
ce8fa8e423 |
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,13 +1,34 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
12.42.0 (2020/7/19)
|
||||||
|
-------------------
|
||||||
|
*このアップデートでは、データベースのマイグレーション(`npm run migrate`/`yarn migrate`)が必要です。*
|
||||||
|
|
||||||
Next (2020/7/)
|
### ✨Improvements
|
||||||
|
- Deckでマウスホイールを使って横スクロールできるように [e18caa3](https://github.com/syuilo/misskey/commit/e18caa339624b566e76d19d0e132028b6377f7f8), [eb275a6](https://github.com/syuilo/misskey/commit/eb275a62a6ae5699b38cf3bca516d34b44e9d944)
|
||||||
|
- 設定画面を整理 [b663a47](https://github.com/syuilo/misskey/commit/b663a47331000b61010ad91fdc422b60b2eeb660)
|
||||||
|
* アクセシビリティ → アピアランス
|
||||||
|
- リモートで削除されており、ローカルで削除されている若しくは未認知のActorからActivityを受信した場合に、エラーでリトライしないように [#6554](https://github.com/syuilo/misskey/pull/6554)
|
||||||
|
- トークン手動発行機能を実装 [0c1de7b](https://github.com/syuilo/misskey/commit/0c1de7b1b6e9ac10b62d8b3157cb064c79aa21d1), [b9c5e95](https://github.com/syuilo/misskey/commit/b9c5e95b855fcf599b339037d4753252a1f786d4)
|
||||||
|
- AiScriptからAPIにアクセスできるように [b39850d](https://github.com/syuilo/misskey/commit/b39850de012fa7b05959c7f4bbbbade841d186ff)
|
||||||
|
- Blurhashを実装 [3f71b14](https://github.com/syuilo/misskey/commit/3f71b1463719bee476d39b7ceca5a2eea4b5cb67)
|
||||||
|
* avgColor, avatarColor, bannerColor は使われなくなります。
|
||||||
|
- デザイン・挙動の調整 [280eeb9](https://github.com/syuilo/misskey/commit/280eeb9d7539e5b7c8d09dfa21a7679eebb09407)
|
||||||
|
|
||||||
|
### 🐛Fixes
|
||||||
|
- AiScriptのアップデートとプラグインの動作の修正 [705d40a](https://github.com/syuilo/misskey/commit/705d40ab37bedb1e43e4677457497c342517a23d)
|
||||||
|
|
||||||
|
12.41.3 (2020/7/15)
|
||||||
-------------------
|
-------------------
|
||||||
### ✨Improvements
|
### ✨Improvements
|
||||||
- サウンドを追加 [b9e9631](https://github.com/syuilo/misskey/commit/b9e9631195a8ca5ed1386daeacdc835456d52975)
|
- サウンドを追加 [b9e9631](https://github.com/syuilo/misskey/commit/b9e9631195a8ca5ed1386daeacdc835456d52975)
|
||||||
|
|
||||||
### 🐛Fixes
|
### 🐛Fixes
|
||||||
-
|
- サイドバーのsticky動作の修正 [937df57](https://github.com/syuilo/misskey/commit/937df577f1b005ff4da2122e642c5c9f687d0069)
|
||||||
|
- iOS/macOS Safariで投稿フォームやノートメニューをたまに表示できない問題を修正 [9d3beb3](https://github.com/syuilo/misskey/commit/9d3beb3174f87f05c50e2e7304a03d2c55a3f7ec)
|
||||||
|
* windowのstorageイベントが発火すると永続化されたstateのみが残る問題を修正
|
||||||
|
- iOS Safariで設定を選べなくなってしまうことがある問題を修正 [e7f1ab2](https://github.com/syuilo/misskey/commit/e7f1ab2d01f92558ff5e230663d951686390d35a)
|
||||||
|
* Safariのvh計算のバグに対処
|
||||||
|
|
||||||
12.41.2 (2020/7/12)
|
12.41.2 (2020/7/12)
|
||||||
-------------------
|
-------------------
|
||||||
|
@@ -1,6 +1,12 @@
|
|||||||
# Contribution guide
|
# Contribution guide
|
||||||
:v: Thanks for your contributions :v:
|
:v: Thanks for your contributions :v:
|
||||||
|
|
||||||
|
## When you contribute...
|
||||||
|
- 任意のIssueについて、せっかく実装してくださっても、実装方法や設計の認識が揃ってないとマージできない/しないことになりかねないので、初めにそのIssue上で着手することを宣言し、必要に応じて他メンバーと実装方法や設計のすり合わせを行ってください。宣言することは作業が他の人と被るのを防止する効果もあります。
|
||||||
|
- 設計に迷った時はプロジェクトリーダーの判断を仰いでください。
|
||||||
|
- 時間や優先度の都合上、提出してくださったPRが長期間放置されることもありますがご理解ください。
|
||||||
|
- 温度感高めで見てほしいものは責付いてください。
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
|
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
|
||||||
|
|
||||||
|
@@ -193,6 +193,7 @@ rename: "إعادة التسمية"
|
|||||||
avatar: "الصورة الرمزية"
|
avatar: "الصورة الرمزية"
|
||||||
banner: "الصورة الرأسية"
|
banner: "الصورة الرأسية"
|
||||||
nsfw: "محتوى حساس"
|
nsfw: "محتوى حساس"
|
||||||
|
disconnectedFromServer: "قُطِع الإتصال بالخادم"
|
||||||
reload: "انعش"
|
reload: "انعش"
|
||||||
doNothing: "تجاهل"
|
doNothing: "تجاهل"
|
||||||
watch: "راقب"
|
watch: "راقب"
|
||||||
@@ -255,6 +256,7 @@ unregister: "إلغاء التسجيل"
|
|||||||
passwordLessLogin: "لِج مِن دون كلمة سرية"
|
passwordLessLogin: "لِج مِن دون كلمة سرية"
|
||||||
resetPassword: "أعد تعيين كلمتك السرية"
|
resetPassword: "أعد تعيين كلمتك السرية"
|
||||||
newPasswordIs: "كلمتك السرية الجديدة هي {password}"
|
newPasswordIs: "كلمتك السرية الجديدة هي {password}"
|
||||||
|
autoReloadWhenDisconnected: "إنعاش تلقائي عندما يُقطَع الإتصال بالخادم"
|
||||||
autoNoteWatch: "راقب الملاحظات تلقائيا"
|
autoNoteWatch: "راقب الملاحظات تلقائيا"
|
||||||
share: "شارِك"
|
share: "شارِك"
|
||||||
notFound: "غير موجود"
|
notFound: "غير موجود"
|
||||||
@@ -311,6 +313,7 @@ remote: "بُعدي"
|
|||||||
total: "المجموع"
|
total: "المجموع"
|
||||||
weekOverWeekChanges: "أسبوعيا"
|
weekOverWeekChanges: "أسبوعيا"
|
||||||
dayOverDayChanges: "يوميا"
|
dayOverDayChanges: "يوميا"
|
||||||
|
appearance: "المظهر"
|
||||||
clinetSettings: "إعدادات التطبيق"
|
clinetSettings: "إعدادات التطبيق"
|
||||||
accountSettings: "إعدادات الحساب"
|
accountSettings: "إعدادات الحساب"
|
||||||
promotion: "ترقية"
|
promotion: "ترقية"
|
||||||
@@ -341,8 +344,21 @@ addRelay: "إضافة مُرحّل"
|
|||||||
addedRelays: "المرحلات التي تم إضافتها"
|
addedRelays: "المرحلات التي تم إضافتها"
|
||||||
deletedNote: "ملاحظة محذوفة"
|
deletedNote: "ملاحظة محذوفة"
|
||||||
invisibleNote: "ملاحظة مخفية"
|
invisibleNote: "ملاحظة مخفية"
|
||||||
|
poll: "استطلاع رأي"
|
||||||
|
themeEditor: "مصمم القوالب"
|
||||||
|
plugins: "الإضافات"
|
||||||
|
pluginInstallWarn: "يرجى تنصيب إضافات ذات مصدر موثوق منه فقط."
|
||||||
|
smtpHost: "المضيف"
|
||||||
|
smtpUser: "اسم المستخدم"
|
||||||
|
smtpPass: "الكلمة السرية"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "استكشف قوالب المظهر"
|
explore: "استكشف قوالب المظهر"
|
||||||
|
install: "تنصيب قالب"
|
||||||
|
manage: "إدارة القوالب"
|
||||||
|
code: "شيفرة القالب"
|
||||||
|
installed: "تم تنصيب {name}"
|
||||||
|
make: "إنشاء قالب"
|
||||||
|
alpha: "الشفافية"
|
||||||
keys:
|
keys:
|
||||||
messageBg: "خلفية الدردشة"
|
messageBg: "خلفية الدردشة"
|
||||||
_sfx:
|
_sfx:
|
||||||
@@ -392,18 +408,29 @@ _widgets:
|
|||||||
rss: "تدفق RSS"
|
rss: "تدفق RSS"
|
||||||
activity: "النشاط"
|
activity: "النشاط"
|
||||||
photos: "الصور"
|
photos: "الصور"
|
||||||
|
federation: "الفديرالية"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "إخفاء"
|
hide: "إخفاء"
|
||||||
show: "عرض المزيد"
|
show: "عرض المزيد"
|
||||||
chars: "{count} أحرف"
|
chars: "{count} أحرف"
|
||||||
files: "{count} ملفات"
|
files: "{count} ملفات"
|
||||||
_poll:
|
_poll:
|
||||||
|
noOnlyOneChoice: "تحتاج إلى خيارَين على الأقل"
|
||||||
|
choiceN: "الخيار {n}"
|
||||||
|
noMore: "لا يمكنك إضافة خيارات أخرى"
|
||||||
|
canMultipleVote: "السماح بالإجابات المتعددة"
|
||||||
|
expiration: "ينتهي استطلاع الرأي في"
|
||||||
|
infinite: "أبدًا"
|
||||||
at: "تاريخ الإنتهاء"
|
at: "تاريخ الإنتهاء"
|
||||||
|
after: "ينتهي بعد…"
|
||||||
deadlineDate: "تاريخ الانتهاء"
|
deadlineDate: "تاريخ الانتهاء"
|
||||||
deadlineTime: "سا"
|
deadlineTime: "سا"
|
||||||
duration: "المدة"
|
duration: "المدة"
|
||||||
|
votesCount: "{n} أصوات"
|
||||||
|
totalVotes: "المجموع {n} أصوات"
|
||||||
vote: "قم بالتصويت"
|
vote: "قم بالتصويت"
|
||||||
showResult: "اعرض النتائج"
|
showResult: "اعرض النتائج"
|
||||||
|
voted: "تم التصويت"
|
||||||
closed: "انتهى"
|
closed: "انتهى"
|
||||||
remainingDays: "{d} أيام و {h} ساعات متبقية"
|
remainingDays: "{d} أيام و {h} ساعات متبقية"
|
||||||
remainingHours: "{h} ساعات و {m} دقائق متبقية"
|
remainingHours: "{h} ساعات و {m} دقائق متبقية"
|
||||||
@@ -469,6 +496,7 @@ _pages:
|
|||||||
types:
|
types:
|
||||||
array: "القوائم"
|
array: "القوائم"
|
||||||
_notification:
|
_notification:
|
||||||
|
youGotPoll: "شارك {name} في استطلاع الرأي"
|
||||||
youGotMessagingMessageFromUser: "لقد تلقيت رسالة مِن {name}"
|
youGotMessagingMessageFromUser: "لقد تلقيت رسالة مِن {name}"
|
||||||
youGotMessagingMessageFromGroup: "لقد أرسِلَت رسالة إلى الفريق {name}"
|
youGotMessagingMessageFromGroup: "لقد أرسِلَت رسالة إلى الفريق {name}"
|
||||||
youWereFollowed: "يتابعك"
|
youWereFollowed: "يتابعك"
|
||||||
|
@@ -442,7 +442,7 @@ remote: "Fremd"
|
|||||||
total: "Gesamt"
|
total: "Gesamt"
|
||||||
weekOverWeekChanges: "Wöchentlich"
|
weekOverWeekChanges: "Wöchentlich"
|
||||||
dayOverDayChanges: "Täglich"
|
dayOverDayChanges: "Täglich"
|
||||||
accessibility: "Barrierefreiheit"
|
appearance: "Aussehen"
|
||||||
clinetSettings: "Client-Einstellungen"
|
clinetSettings: "Client-Einstellungen"
|
||||||
accountSettings: "Benutzerkonto-Einstellungen"
|
accountSettings: "Benutzerkonto-Einstellungen"
|
||||||
promotion: "Hervorgehoben"
|
promotion: "Hervorgehoben"
|
||||||
@@ -528,6 +528,16 @@ plugins: "Plugins"
|
|||||||
pluginInstallWarn: "Installiere nur vertrauenswürdige Plugins."
|
pluginInstallWarn: "Installiere nur vertrauenswürdige Plugins."
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Deck verlassen"
|
undeck: "Deck verlassen"
|
||||||
|
useBlurEffectForModal: "Weichzeichnungseffekt für Modals verwenden"
|
||||||
|
generateAccessToken: "Zugriffstoken generieren"
|
||||||
|
permission: "Berechtigungen"
|
||||||
|
enableAll: "Alle aktivieren"
|
||||||
|
disableAll: "Alle deaktivieren"
|
||||||
|
tokenRequested: "Benutzerkontozugriff gewähren"
|
||||||
|
pluginTokenRequestedDescription: "Dieses Plugin wird die hier konfigurierten Berechtigungen verwenden können."
|
||||||
|
smtpHost: "Host"
|
||||||
|
smtpUser: "Benutzername"
|
||||||
|
smtpPass: "Passwort"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "Themen erforschen"
|
explore: "Themen erforschen"
|
||||||
install: "Thema installieren"
|
install: "Thema installieren"
|
||||||
@@ -548,7 +558,7 @@ _theme:
|
|||||||
func: "Funktionen"
|
func: "Funktionen"
|
||||||
funcKind: "Funktionstyp"
|
funcKind: "Funktionstyp"
|
||||||
argument: "Parameter"
|
argument: "Parameter"
|
||||||
basedProp: "Name der referenzierten Eigenschaft"
|
basedProp: "Referenzierte Eigenschaft"
|
||||||
alpha: "Transparenz"
|
alpha: "Transparenz"
|
||||||
darken: "Verdunkeln"
|
darken: "Verdunkeln"
|
||||||
lighten: "Erhellen"
|
lighten: "Erhellen"
|
||||||
@@ -713,6 +723,7 @@ _widgets:
|
|||||||
activity: "Aktivität"
|
activity: "Aktivität"
|
||||||
photos: "Fotos"
|
photos: "Fotos"
|
||||||
digitalClock: "Digitaluhr"
|
digitalClock: "Digitaluhr"
|
||||||
|
federation: "Föderation"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Ausblenden"
|
hide: "Ausblenden"
|
||||||
show: "Mehr anzeigen"
|
show: "Mehr anzeigen"
|
||||||
|
@@ -442,7 +442,7 @@ remote: "Remote"
|
|||||||
total: "Total"
|
total: "Total"
|
||||||
weekOverWeekChanges: "Weekly"
|
weekOverWeekChanges: "Weekly"
|
||||||
dayOverDayChanges: "Daily"
|
dayOverDayChanges: "Daily"
|
||||||
accessibility: "Accessibility"
|
appearance: "Appearance"
|
||||||
clinetSettings: "Client Settings"
|
clinetSettings: "Client Settings"
|
||||||
accountSettings: "Account Settings"
|
accountSettings: "Account Settings"
|
||||||
promotion: "Promoted"
|
promotion: "Promoted"
|
||||||
@@ -528,6 +528,16 @@ plugins: "Plugins"
|
|||||||
pluginInstallWarn: "Please do not install untrustworthy plugins."
|
pluginInstallWarn: "Please do not install untrustworthy plugins."
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "Leave Deck"
|
undeck: "Leave Deck"
|
||||||
|
useBlurEffectForModal: "Use blur effect for modals"
|
||||||
|
generateAccessToken: "Generate access token"
|
||||||
|
permission: "Permissions"
|
||||||
|
enableAll: "Enable all"
|
||||||
|
disableAll: "Disable all"
|
||||||
|
tokenRequested: "Grant access to account"
|
||||||
|
pluginTokenRequestedDescription: "This plugin will be able to use the permissions set here."
|
||||||
|
smtpHost: "Host"
|
||||||
|
smtpUser: "Username"
|
||||||
|
smtpPass: "Password"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "Explore Themes"
|
explore: "Explore Themes"
|
||||||
install: "Install theme"
|
install: "Install theme"
|
||||||
@@ -548,7 +558,7 @@ _theme:
|
|||||||
func: "Functions"
|
func: "Functions"
|
||||||
funcKind: "Function type"
|
funcKind: "Function type"
|
||||||
argument: "Argument"
|
argument: "Argument"
|
||||||
basedProp: "Name of the referenced property"
|
basedProp: "Referenced property"
|
||||||
alpha: "Opacity"
|
alpha: "Opacity"
|
||||||
darken: "Darken"
|
darken: "Darken"
|
||||||
lighten: "Lighten"
|
lighten: "Lighten"
|
||||||
@@ -713,6 +723,7 @@ _widgets:
|
|||||||
activity: "Activity"
|
activity: "Activity"
|
||||||
photos: "Photos"
|
photos: "Photos"
|
||||||
digitalClock: "Digital clock"
|
digitalClock: "Digital clock"
|
||||||
|
federation: "Federation"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Hide"
|
hide: "Hide"
|
||||||
show: "Load more"
|
show: "Load more"
|
||||||
|
@@ -442,7 +442,7 @@ remote: "Remoto"
|
|||||||
total: "Total"
|
total: "Total"
|
||||||
weekOverWeekChanges: "Dif semanal"
|
weekOverWeekChanges: "Dif semanal"
|
||||||
dayOverDayChanges: "Dif diaria"
|
dayOverDayChanges: "Dif diaria"
|
||||||
accessibility: "Accesibilidad"
|
appearance: "Apariencia"
|
||||||
clinetSettings: "Ajustes del cliente"
|
clinetSettings: "Ajustes del cliente"
|
||||||
accountSettings: "Ajustes de cuenta"
|
accountSettings: "Ajustes de cuenta"
|
||||||
promotion: "Promovido"
|
promotion: "Promovido"
|
||||||
@@ -526,6 +526,29 @@ leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?"
|
|||||||
manage: "Administrar"
|
manage: "Administrar"
|
||||||
plugins: "Plugins"
|
plugins: "Plugins"
|
||||||
pluginInstallWarn: "Por favor no instale plugins que no son de confianza"
|
pluginInstallWarn: "Por favor no instale plugins que no son de confianza"
|
||||||
|
deck: "Deck"
|
||||||
|
undeck: "Quitar deck"
|
||||||
|
useBlurEffectForModal: "Usar efecto borroso en modales"
|
||||||
|
generateAccessToken: "Generar token de acceso"
|
||||||
|
permission: "Permisos"
|
||||||
|
enableAll: "Activar todo"
|
||||||
|
disableAll: "Desactivar todo"
|
||||||
|
tokenRequested: "Permiso de acceso a la cuenta"
|
||||||
|
pluginTokenRequestedDescription: "Este plugin podrá usar los permisos descritos aquí"
|
||||||
|
useStarForReactionFallback: "En caso de que los emojis de reacciones no sean claros, usar en su lugar una estrella"
|
||||||
|
emailConfig: "Configuración del servidor de correos"
|
||||||
|
enableEmail: "Activar el envío de correos electrónicos"
|
||||||
|
emailConfigInfo: "Usar en caso de validación de correo electrónico y pedido de contraseña"
|
||||||
|
email: "Correo electrónico"
|
||||||
|
smtpConfig: "Configuración del servidor SMTP"
|
||||||
|
smtpHost: "Host"
|
||||||
|
smtpPort: "Puerto"
|
||||||
|
smtpUser: "Nombre de usuario"
|
||||||
|
smtpPass: "Contraseña"
|
||||||
|
emptyToDisableSmtpAuth: "Deje el nombre del usuario y la contraseña en blanco para deshabilitar la autenticación SMTP"
|
||||||
|
smtpSecure: "Usar SSL/TLS implícito en la conexión SMTP"
|
||||||
|
smtpSecureInfo: "Apagar cuando se use STARTTLS"
|
||||||
|
testEmail: "Prueba de envío"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "Explorar temas"
|
explore: "Explorar temas"
|
||||||
install: "Instalar tema"
|
install: "Instalar tema"
|
||||||
@@ -711,6 +734,7 @@ _widgets:
|
|||||||
activity: "Actividad"
|
activity: "Actividad"
|
||||||
photos: "Fotos"
|
photos: "Fotos"
|
||||||
digitalClock: "Reloj digital"
|
digitalClock: "Reloj digital"
|
||||||
|
federation: "Federación"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Ocultar"
|
hide: "Ocultar"
|
||||||
show: "Ver más"
|
show: "Ver más"
|
||||||
@@ -1167,6 +1191,7 @@ _notification:
|
|||||||
_deck:
|
_deck:
|
||||||
alwaysShowMainColumn: "Siempre mostrar la columna principal"
|
alwaysShowMainColumn: "Siempre mostrar la columna principal"
|
||||||
columnAlign: "Alinear columnas"
|
columnAlign: "Alinear columnas"
|
||||||
|
addColumn: "Agregar columna"
|
||||||
_columns:
|
_columns:
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
notifications: "Notificaciones"
|
notifications: "Notificaciones"
|
||||||
|
@@ -442,7 +442,7 @@ remote: "Distant"
|
|||||||
total: "Total"
|
total: "Total"
|
||||||
weekOverWeekChanges: "Diff hebdo"
|
weekOverWeekChanges: "Diff hebdo"
|
||||||
dayOverDayChanges: "Diff quotidien"
|
dayOverDayChanges: "Diff quotidien"
|
||||||
accessibility: "Accessibilité"
|
appearance: "Aspect"
|
||||||
clinetSettings: "Paramètres du client"
|
clinetSettings: "Paramètres du client"
|
||||||
accountSettings: "Paramètres du compte"
|
accountSettings: "Paramètres du compte"
|
||||||
promotion: "Promu"
|
promotion: "Promu"
|
||||||
@@ -522,8 +522,13 @@ expandTweet: "Étendre le tweet"
|
|||||||
themeEditor: "Éditeur de thèmes"
|
themeEditor: "Éditeur de thèmes"
|
||||||
description: "Description"
|
description: "Description"
|
||||||
author: "Auteur·rice"
|
author: "Auteur·rice"
|
||||||
|
leaveConfirm: "Vous avez des modifications non-sauvegardées. Voulez-vous les ignorer ?"
|
||||||
manage: "Gestion"
|
manage: "Gestion"
|
||||||
plugins: "Extensions"
|
plugins: "Extensions"
|
||||||
|
pluginInstallWarn: "N’installez que des extensions provenant de sources de confiance."
|
||||||
|
smtpHost: "Hôte"
|
||||||
|
smtpUser: "Nom d’utilisateur·rice"
|
||||||
|
smtpPass: "Mot de passe"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "Explorer les thèmes"
|
explore: "Explorer les thèmes"
|
||||||
install: "Installer un thème"
|
install: "Installer un thème"
|
||||||
@@ -536,10 +541,12 @@ _theme:
|
|||||||
base: "Base"
|
base: "Base"
|
||||||
defaultValue: "Valeur par défaut"
|
defaultValue: "Valeur par défaut"
|
||||||
color: "Couleur"
|
color: "Couleur"
|
||||||
|
key: "Clé "
|
||||||
func: "Fonction"
|
func: "Fonction"
|
||||||
argument: "Argument"
|
argument: "Argument"
|
||||||
alpha: "Transparence"
|
alpha: "Transparence"
|
||||||
darken: "Assombrir"
|
darken: "Assombrir"
|
||||||
|
importInfo: "Vous pouvez importer un thème vers l’éditeur de thèmes en saisissant son code ici."
|
||||||
keys:
|
keys:
|
||||||
bg: "Arrière-plan"
|
bg: "Arrière-plan"
|
||||||
fg: "Texte"
|
fg: "Texte"
|
||||||
@@ -549,10 +556,15 @@ _theme:
|
|||||||
shadow: "Ombre"
|
shadow: "Ombre"
|
||||||
header: "Entête"
|
header: "Entête"
|
||||||
navBg: "Fond de la barre latérale"
|
navBg: "Fond de la barre latérale"
|
||||||
|
navFg: "Texte de la barre latérale"
|
||||||
|
link: "Lien"
|
||||||
hashtag: "Hashtags"
|
hashtag: "Hashtags"
|
||||||
mention: "Mentionner"
|
mention: "Mentionner"
|
||||||
|
mentionMe: "Mentions (Moi)"
|
||||||
renote: "Renote"
|
renote: "Renote"
|
||||||
divider: "Séparateur"
|
divider: "Séparateur"
|
||||||
|
infoWarnFg: "Texte d’avertissement"
|
||||||
|
badge: "Badge"
|
||||||
messageBg: "Arrière plan de la discussion"
|
messageBg: "Arrière plan de la discussion"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "Nouvelle note"
|
note: "Nouvelle note"
|
||||||
@@ -667,6 +679,8 @@ _widgets:
|
|||||||
rss: "Lecteur de flux RSS"
|
rss: "Lecteur de flux RSS"
|
||||||
activity: "Activité"
|
activity: "Activité"
|
||||||
photos: "Photos"
|
photos: "Photos"
|
||||||
|
digitalClock: "Horloge numérique"
|
||||||
|
federation: "Fédération"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Masquer"
|
hide: "Masquer"
|
||||||
show: "Afficher plus …"
|
show: "Afficher plus …"
|
||||||
@@ -1123,6 +1137,7 @@ _notification:
|
|||||||
_deck:
|
_deck:
|
||||||
alwaysShowMainColumn: "Toujours afficher la colonne principale"
|
alwaysShowMainColumn: "Toujours afficher la colonne principale"
|
||||||
columnAlign: "Aligner les colonnes"
|
columnAlign: "Aligner les colonnes"
|
||||||
|
addColumn: "Ajouter une colonne"
|
||||||
_columns:
|
_columns:
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
|
@@ -104,6 +104,8 @@ unblockConfirm: "ブロック解除しますか?"
|
|||||||
suspendConfirm: "凍結しますか?"
|
suspendConfirm: "凍結しますか?"
|
||||||
unsuspendConfirm: "解凍しますか?"
|
unsuspendConfirm: "解凍しますか?"
|
||||||
selectList: "リストを選択"
|
selectList: "リストを選択"
|
||||||
|
selectAntenna: "アンテナを選択"
|
||||||
|
selectWidget: "ウィジェットを選択"
|
||||||
customEmojis: "カスタム絵文字"
|
customEmojis: "カスタム絵文字"
|
||||||
emoji: "絵文字"
|
emoji: "絵文字"
|
||||||
emojiName: "絵文字名"
|
emojiName: "絵文字名"
|
||||||
@@ -535,6 +537,22 @@ enableAll: "全て有効にする"
|
|||||||
disableAll: "全て無効にする"
|
disableAll: "全て無効にする"
|
||||||
tokenRequested: "アカウントへのアクセス許可"
|
tokenRequested: "アカウントへのアクセス許可"
|
||||||
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を行使できるようになります。"
|
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を行使できるようになります。"
|
||||||
|
notificationType: "通知の種類"
|
||||||
|
edit: "編集"
|
||||||
|
useStarForReactionFallback: "リアクション絵文字が不明な場合、代わりに★を使う"
|
||||||
|
emailConfig: "メールサーバー設定"
|
||||||
|
enableEmail: "メール配信機能を有効化する"
|
||||||
|
emailConfigInfo: "メールアドレスの確認やパスワードリセットの際に使います"
|
||||||
|
email: "メールアドレス"
|
||||||
|
smtpConfig: "SMTP サーバーの設定"
|
||||||
|
smtpHost: "ホスト"
|
||||||
|
smtpPort: "ポート"
|
||||||
|
smtpUser: "ユーザー名"
|
||||||
|
smtpPass: "パスワード"
|
||||||
|
emptyToDisableSmtpAuth: "ユーザー名とパスワードを空欄にすることで、SMTP認証を無効化出来ます"
|
||||||
|
smtpSecure: "SMTP 接続に暗黙的なSSL/TLSを使用する"
|
||||||
|
smtpSecureInfo: "STARTTLS使用時はオフにします。"
|
||||||
|
testEmail: "配信テスト"
|
||||||
|
|
||||||
_theme:
|
_theme:
|
||||||
explore: "テーマを探す"
|
explore: "テーマを探す"
|
||||||
@@ -732,6 +750,7 @@ _widgets:
|
|||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
photos: "フォト"
|
photos: "フォト"
|
||||||
digitalClock: "デジタル時計"
|
digitalClock: "デジタル時計"
|
||||||
|
federation: "連合"
|
||||||
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "隠す"
|
hide: "隠す"
|
||||||
@@ -1210,10 +1229,27 @@ _notification:
|
|||||||
yourFollowRequestAccepted: "フォローリクエストが承認されました"
|
yourFollowRequestAccepted: "フォローリクエストが承認されました"
|
||||||
youWereInvitedToGroup: "グループに招待されました"
|
youWereInvitedToGroup: "グループに招待されました"
|
||||||
|
|
||||||
|
_types:
|
||||||
|
all: "すべて"
|
||||||
|
follow: "フォロー"
|
||||||
|
mention: "メンション"
|
||||||
|
reply: "リプライ"
|
||||||
|
renote: "Renote"
|
||||||
|
quote: "引用"
|
||||||
|
reaction: "リアクション"
|
||||||
|
pollVote: "投票"
|
||||||
|
receiveFollowRequest: "フォローリクエスト"
|
||||||
|
|
||||||
_deck:
|
_deck:
|
||||||
alwaysShowMainColumn: "常にメインカラムを表示"
|
alwaysShowMainColumn: "常にメインカラムを表示"
|
||||||
columnAlign: "カラムの寄せ"
|
columnAlign: "カラムの寄せ"
|
||||||
addColumn: "カラムを追加"
|
addColumn: "カラムを追加"
|
||||||
|
swapLeft: "左に移動"
|
||||||
|
swapRight: "右に移動"
|
||||||
|
swapUp: "上に移動"
|
||||||
|
swapDown: "下に移動"
|
||||||
|
stackLeft: "左に重ねる"
|
||||||
|
popRight: "右に出す"
|
||||||
|
|
||||||
_columns:
|
_columns:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
|
@@ -295,6 +295,7 @@ proxyRemoteFilesDescription: "この設定を入れると、保存しとらん
|
|||||||
driveCapacityPerLocalAccount: "ローカルユーザーひとりあたりのドライブ容量"
|
driveCapacityPerLocalAccount: "ローカルユーザーひとりあたりのドライブ容量"
|
||||||
driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのドライブ容量"
|
driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのドライブ容量"
|
||||||
inMb: "メガバイト単位"
|
inMb: "メガバイト単位"
|
||||||
|
recaptcha: "reCAPTCHA"
|
||||||
avoidMultiCaptchaConfirm: "ぎょうさんのCaptchaをつこてしまうと、仲良うせんことがあるんや。他のCaptchaをなおしとこか?別にキャンセルしてもろうたらCaptchaは消されへんで済むけど知らんで。"
|
avoidMultiCaptchaConfirm: "ぎょうさんのCaptchaをつこてしまうと、仲良うせんことがあるんや。他のCaptchaをなおしとこか?別にキャンセルしてもろうたらCaptchaは消されへんで済むけど知らんで。"
|
||||||
antennas: "アンテナ"
|
antennas: "アンテナ"
|
||||||
manageAntennas: "アンテナいじる"
|
manageAntennas: "アンテナいじる"
|
||||||
@@ -352,6 +353,9 @@ notFoundDescription: "指定されたURLに該当するページはあらへん
|
|||||||
close: "さいなら"
|
close: "さいなら"
|
||||||
joinedGroups: "参加しとるグループ"
|
joinedGroups: "参加しとるグループ"
|
||||||
invites: "来てや"
|
invites: "来てや"
|
||||||
|
smtpHost: "ホスト"
|
||||||
|
smtpUser: "ユーザー名"
|
||||||
|
smtpPass: "パスワード"
|
||||||
_theme:
|
_theme:
|
||||||
keys:
|
keys:
|
||||||
renote: "Renote"
|
renote: "Renote"
|
||||||
@@ -386,6 +390,7 @@ _widgets:
|
|||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
|
federation: "連合"
|
||||||
_cw:
|
_cw:
|
||||||
show: "もっとあるやろ!"
|
show: "もっとあるやろ!"
|
||||||
_poll:
|
_poll:
|
||||||
|
@@ -33,6 +33,8 @@ youHaveNoLists: "Ulac ɣur-k·m ula d yiwet n tabdart"
|
|||||||
remove: "Kkes"
|
remove: "Kkes"
|
||||||
userList: "Tibdarin"
|
userList: "Tibdarin"
|
||||||
uiLanguage: "Tutlayt n wegrudem"
|
uiLanguage: "Tutlayt n wegrudem"
|
||||||
|
smtpUser: "Isem n umseqdac"
|
||||||
|
smtpPass: "Awal uffir"
|
||||||
_theme:
|
_theme:
|
||||||
keys:
|
keys:
|
||||||
mention: "Bder"
|
mention: "Bder"
|
||||||
|
@@ -54,6 +54,8 @@ driveFileDeleteConfirm: "\"{name}\" ಕಡತವನ್ನು ಅಳಿಸಲು
|
|||||||
unfollowConfirm: "{name}ಅನ್ನು ಹಿಂಬಾಲಿಸದಿರುವುದೇ?"
|
unfollowConfirm: "{name}ಅನ್ನು ಹಿಂಬಾಲಿಸದಿರುವುದೇ?"
|
||||||
instances: "ನಿದರ್ಶನ"
|
instances: "ನಿದರ್ಶನ"
|
||||||
remove: "ಅಳಿಸು"
|
remove: "ಅಳಿಸು"
|
||||||
|
smtpUser: "ಬಳಕೆಹೆಸರು"
|
||||||
|
smtpPass: "ಗುಪ್ತಪದ"
|
||||||
_sfx:
|
_sfx:
|
||||||
notification: "ಅಧಿಸೂಚನೆಗಳು"
|
notification: "ಅಧಿಸೂಚನೆಗಳು"
|
||||||
_widgets:
|
_widgets:
|
||||||
|
@@ -442,7 +442,6 @@ remote: "리모트"
|
|||||||
total: "합계"
|
total: "합계"
|
||||||
weekOverWeekChanges: "지난주보다"
|
weekOverWeekChanges: "지난주보다"
|
||||||
dayOverDayChanges: "어제보다"
|
dayOverDayChanges: "어제보다"
|
||||||
accessibility: "접근성"
|
|
||||||
clinetSettings: "클라이언트 설정"
|
clinetSettings: "클라이언트 설정"
|
||||||
accountSettings: "계정 설정"
|
accountSettings: "계정 설정"
|
||||||
promotion: "프로모션"
|
promotion: "프로모션"
|
||||||
@@ -528,6 +527,9 @@ plugins: "플러그인"
|
|||||||
pluginInstallWarn: "신뢰할 수 없는 플러그인은 설치하지 마십시오."
|
pluginInstallWarn: "신뢰할 수 없는 플러그인은 설치하지 마십시오."
|
||||||
deck: "덱"
|
deck: "덱"
|
||||||
undeck: "덱 해제"
|
undeck: "덱 해제"
|
||||||
|
smtpHost: "호스트"
|
||||||
|
smtpUser: "유저명"
|
||||||
|
smtpPass: "비밀번호"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "테마 찾아보기"
|
explore: "테마 찾아보기"
|
||||||
install: "테마 설치"
|
install: "테마 설치"
|
||||||
@@ -665,6 +667,8 @@ _widgets:
|
|||||||
rss: "RSS 리더"
|
rss: "RSS 리더"
|
||||||
activity: "활동"
|
activity: "활동"
|
||||||
photos: "사진"
|
photos: "사진"
|
||||||
|
digitalClock: "디지털 시계"
|
||||||
|
federation: "연합"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "숨기기"
|
hide: "숨기기"
|
||||||
show: "더 보기"
|
show: "더 보기"
|
||||||
@@ -1118,6 +1122,7 @@ _notification:
|
|||||||
youWereInvitedToGroup: "그룹에 초대되었습니다"
|
youWereInvitedToGroup: "그룹에 초대되었습니다"
|
||||||
_deck:
|
_deck:
|
||||||
_columns:
|
_columns:
|
||||||
|
widgets: "위젯"
|
||||||
notifications: "알림"
|
notifications: "알림"
|
||||||
tl: "타임라인"
|
tl: "타임라인"
|
||||||
antenna: "안테나"
|
antenna: "안테나"
|
||||||
|
@@ -31,6 +31,7 @@ importAndExport: "Импорт / Экспорт"
|
|||||||
files: "Файл"
|
files: "Файл"
|
||||||
instances: "Экземпляр"
|
instances: "Экземпляр"
|
||||||
remove: "Удалить"
|
remove: "Удалить"
|
||||||
|
smtpPass: "Пароль"
|
||||||
_sfx:
|
_sfx:
|
||||||
notification: "Уведомления"
|
notification: "Уведомления"
|
||||||
_widgets:
|
_widgets:
|
||||||
|
@@ -442,7 +442,7 @@ remote: "远程"
|
|||||||
total: "总计"
|
total: "总计"
|
||||||
weekOverWeekChanges: "与前一周相比"
|
weekOverWeekChanges: "与前一周相比"
|
||||||
dayOverDayChanges: "与前一日相比"
|
dayOverDayChanges: "与前一日相比"
|
||||||
accessibility: "辅助功能"
|
appearance: "外观"
|
||||||
clinetSettings: "客户端设置"
|
clinetSettings: "客户端设置"
|
||||||
accountSettings: "账户设置"
|
accountSettings: "账户设置"
|
||||||
promotion: "推广"
|
promotion: "推广"
|
||||||
@@ -528,6 +528,17 @@ plugins: "插件"
|
|||||||
pluginInstallWarn: "请不要安装不明来源的插件"
|
pluginInstallWarn: "请不要安装不明来源的插件"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "取消Deck"
|
undeck: "取消Deck"
|
||||||
|
useBlurEffectForModal: "模态框使用模糊效果"
|
||||||
|
generateAccessToken: "生成访问令牌"
|
||||||
|
permission: "权限"
|
||||||
|
enableAll: "启用全部"
|
||||||
|
disableAll: "禁用全部"
|
||||||
|
tokenRequested: "允许访问账户"
|
||||||
|
pluginTokenRequestedDescription: "此插件将能够拥有此处设置的权限"
|
||||||
|
smtpHost: "主机名"
|
||||||
|
smtpPort: "端口"
|
||||||
|
smtpUser: "用户名"
|
||||||
|
smtpPass: "密码"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "寻找主题"
|
explore: "寻找主题"
|
||||||
install: "安装主题"
|
install: "安装主题"
|
||||||
@@ -536,7 +547,7 @@ _theme:
|
|||||||
installed: "{name} 已安装"
|
installed: "{name} 已安装"
|
||||||
alreadyInstalled: "此主题已经安装"
|
alreadyInstalled: "此主题已经安装"
|
||||||
invalid: "主题格式错误"
|
invalid: "主题格式错误"
|
||||||
make: "主题制作"
|
make: "制作主题"
|
||||||
base: "基于"
|
base: "基于"
|
||||||
addConstant: "添加常量"
|
addConstant: "添加常量"
|
||||||
constant: "常量"
|
constant: "常量"
|
||||||
@@ -574,7 +585,7 @@ _theme:
|
|||||||
mention: "提及"
|
mention: "提及"
|
||||||
mentionMe: "提及"
|
mentionMe: "提及"
|
||||||
renote: "转发"
|
renote: "转发"
|
||||||
modalBg: "模块背景"
|
modalBg: "模态框背景"
|
||||||
divider: "分割线"
|
divider: "分割线"
|
||||||
scrollbarHandle: "滚动条"
|
scrollbarHandle: "滚动条"
|
||||||
scrollbarHandleHover: "滚动条(悬停)"
|
scrollbarHandleHover: "滚动条(悬停)"
|
||||||
@@ -596,6 +607,8 @@ _theme:
|
|||||||
wallpaperOverlay: "壁纸叠加层"
|
wallpaperOverlay: "壁纸叠加层"
|
||||||
badge: "徽章"
|
badge: "徽章"
|
||||||
messageBg: "聊天背景"
|
messageBg: "聊天背景"
|
||||||
|
accentDarken: "强调色(暗)"
|
||||||
|
accentLighten: "强调色(亮)"
|
||||||
fgHighlighted: "高亮显示文本"
|
fgHighlighted: "高亮显示文本"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "帖子"
|
note: "帖子"
|
||||||
@@ -711,6 +724,7 @@ _widgets:
|
|||||||
activity: "活动"
|
activity: "活动"
|
||||||
photos: "照片"
|
photos: "照片"
|
||||||
digitalClock: "数字时钟"
|
digitalClock: "数字时钟"
|
||||||
|
federation: "联邦宇宙"
|
||||||
_cw:
|
_cw:
|
||||||
hide: "隐藏"
|
hide: "隐藏"
|
||||||
show: "查看更多"
|
show: "查看更多"
|
||||||
@@ -1167,6 +1181,7 @@ _notification:
|
|||||||
_deck:
|
_deck:
|
||||||
alwaysShowMainColumn: "总是显示主列"
|
alwaysShowMainColumn: "总是显示主列"
|
||||||
columnAlign: "列对齐"
|
columnAlign: "列对齐"
|
||||||
|
addColumn: "添加列"
|
||||||
_columns:
|
_columns:
|
||||||
widgets: "小部件"
|
widgets: "小部件"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
|
@@ -4,13 +4,13 @@ introMisskey: "歡迎! Misskey是一個開源的去中心化的社群網站。
|
|||||||
monthAndDay: "{month}月 {day}日"
|
monthAndDay: "{month}月 {day}日"
|
||||||
search: "搜尋"
|
search: "搜尋"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
username: "用戶名"
|
username: "使用名稱"
|
||||||
password: "密碼"
|
password: "密碼"
|
||||||
fetchingAsApObject: "從Fediverse尋找中..."
|
fetchingAsApObject: "從 Fediverse 查詢中..."
|
||||||
ok: "OK"
|
ok: "確定"
|
||||||
gotIt: "知道了"
|
gotIt: "知道了"
|
||||||
cancel: "取消"
|
cancel: "取消"
|
||||||
enterUsername: "輸入用戶名"
|
enterUsername: "輸入使用者名稱"
|
||||||
renotedBy: "由{user}轉發"
|
renotedBy: "由{user}轉發"
|
||||||
noNotes: "貼文不可用。"
|
noNotes: "貼文不可用。"
|
||||||
noNotifications: "沒有通知"
|
noNotifications: "沒有通知"
|
||||||
@@ -24,11 +24,11 @@ loggingIn: "登入中"
|
|||||||
logout: "登出"
|
logout: "登出"
|
||||||
signup: "註冊"
|
signup: "註冊"
|
||||||
uploading: "上傳中"
|
uploading: "上傳中"
|
||||||
save: "保存"
|
save: "儲存"
|
||||||
users: "用戶"
|
users: "使用者"
|
||||||
addUser: "新增用戶"
|
addUser: "新增使用者"
|
||||||
favorite: "收藏"
|
favorite: "收藏"
|
||||||
favorites: "收藏"
|
favorites: "已加星號"
|
||||||
unfavorite: "取消收藏"
|
unfavorite: "取消收藏"
|
||||||
pin: "置頂"
|
pin: "置頂"
|
||||||
unpin: "取消置頂"
|
unpin: "取消置頂"
|
||||||
@@ -82,7 +82,7 @@ unrenote: "取消轉發貼文"
|
|||||||
quote: "引用"
|
quote: "引用"
|
||||||
pinnedNote: "已置頂的貼文"
|
pinnedNote: "已置頂的貼文"
|
||||||
you: "您"
|
you: "您"
|
||||||
clickToShow: "點擊查看"
|
clickToShow: "按一下以顯示"
|
||||||
sensitive: "敏感內容"
|
sensitive: "敏感內容"
|
||||||
add: "新增"
|
add: "新增"
|
||||||
reaction: "反應"
|
reaction: "反應"
|
||||||
@@ -92,8 +92,8 @@ attachCancel: "移除附件"
|
|||||||
markAsSensitive: "標記為敏感內容"
|
markAsSensitive: "標記為敏感內容"
|
||||||
unmarkAsSensitive: "取消標記為敏感內容"
|
unmarkAsSensitive: "取消標記為敏感內容"
|
||||||
enterFileName: "請輸入檔案名稱"
|
enterFileName: "請輸入檔案名稱"
|
||||||
mute: "禁言"
|
mute: "消音"
|
||||||
unmute: "解除禁言"
|
unmute: "解除消音"
|
||||||
block: "封鎖"
|
block: "封鎖"
|
||||||
unblock: "解除封鎖"
|
unblock: "解除封鎖"
|
||||||
suspend: "凍結"
|
suspend: "凍結"
|
||||||
@@ -108,42 +108,48 @@ emoji: "表情符號"
|
|||||||
emojiName: "表情符號名稱"
|
emojiName: "表情符號名稱"
|
||||||
emojiUrl: "表情符號URL"
|
emojiUrl: "表情符號URL"
|
||||||
addEmoji: "新增表情符號"
|
addEmoji: "新增表情符號"
|
||||||
settingGuide: "推介設定"
|
settingGuide: "推薦設定"
|
||||||
flagAsBot: "此帳戶是Bot"
|
flagAsBot: "此帳戶是Bot"
|
||||||
flagAsCat: "此帳戶是Cat"
|
flagAsCat: "此帳戶是Cat"
|
||||||
autoAcceptFollowed: "自動許可追隨"
|
autoAcceptFollowed: "自動許可追隨"
|
||||||
addAcount: "新增帳戶"
|
addAcount: "新增帳號"
|
||||||
loginFailed: "登入失敗"
|
loginFailed: "登入失敗"
|
||||||
general: "一般"
|
general: "一般"
|
||||||
wallpaper: "壁紙"
|
wallpaper: "桌布"
|
||||||
setWallpaper: "設定桌布"
|
setWallpaper: "設定桌布"
|
||||||
removeWallpaper: "移除壁紙"
|
removeWallpaper: "移除桌布"
|
||||||
searchWith: "搜尋: {q}"
|
searchWith: "搜尋: {q}"
|
||||||
youHaveNoLists: "你沒有任何清單"
|
youHaveNoLists: "沒有任何清單"
|
||||||
followConfirm: "你真的要追隨{name}嗎?"
|
followConfirm: "你真的要關注{name}嗎?"
|
||||||
|
proxyAccount: "代理帳號"
|
||||||
host: "主機"
|
host: "主機"
|
||||||
selectUser: "選擇用戶"
|
selectUser: "選取使用者"
|
||||||
recipient: "收件人"
|
recipient: "發送至"
|
||||||
annotation: "註解"
|
annotation: "註解"
|
||||||
federation: "整合"
|
federation: "聯邦宇宙"
|
||||||
instances: "實例"
|
instances: "實例"
|
||||||
latestStatus: "最後狀態"
|
latestStatus: "最後狀態"
|
||||||
storageUsage: "已使用容量"
|
storageUsage: "已使用容量"
|
||||||
charts: "圖表"
|
charts: "圖表"
|
||||||
perHour: "每小時"
|
perHour: "每小時"
|
||||||
perDay: "每日"
|
perDay: "每日"
|
||||||
|
blockThisInstance: "封鎖此實例"
|
||||||
operations: "操作"
|
operations: "操作"
|
||||||
software: "軟體"
|
software: "軟體"
|
||||||
version: "版本"
|
version: "版本"
|
||||||
|
metadata: "元資料(Metadata)"
|
||||||
withNFiles: "{n}個檔案"
|
withNFiles: "{n}個檔案"
|
||||||
monitor: "監視器"
|
monitor: "監視器"
|
||||||
|
jobQueue: "佇列"
|
||||||
cpuAndMemory: "CPU及記憶體用量"
|
cpuAndMemory: "CPU及記憶體用量"
|
||||||
network: "網路"
|
network: "網路"
|
||||||
|
disk: "硬碟"
|
||||||
instanceInfo: "實例資訊"
|
instanceInfo: "實例資訊"
|
||||||
statistics: "統計"
|
statistics: "統計"
|
||||||
clearQueue: "清除佇列"
|
clearQueue: "清除佇列"
|
||||||
clearQueueConfirmTitle: "確定要清除佇列嗎?"
|
clearQueueConfirmTitle: "確定要清除佇列嗎?"
|
||||||
clearCachedFiles: "清除快取資料"
|
clearCachedFiles: "清除快取資料"
|
||||||
|
clearCachedFilesConfirm: "確定要清除緩存資料嗎?"
|
||||||
blockedInstances: "已封鎖的實例"
|
blockedInstances: "已封鎖的實例"
|
||||||
blockedInstancesDescription: "請逐行輸入需要封鎖的實例。已封鎖的實例將無法與本實例進行通訊。"
|
blockedInstancesDescription: "請逐行輸入需要封鎖的實例。已封鎖的實例將無法與本實例進行通訊。"
|
||||||
muteAndBlock: "禁言 / 封鎖"
|
muteAndBlock: "禁言 / 封鎖"
|
||||||
@@ -153,14 +159,15 @@ noUsers: "無用戶"
|
|||||||
editProfile: "編輯個人檔案"
|
editProfile: "編輯個人檔案"
|
||||||
noteDeleteConfirm: "確定刪除此貼文嗎?"
|
noteDeleteConfirm: "確定刪除此貼文嗎?"
|
||||||
pinLimitExceeded: "不能再置頂更多的貼文了"
|
pinLimitExceeded: "不能再置頂更多的貼文了"
|
||||||
intro: "Misskey安裝作業完成!請創立管理員用戶"
|
intro: "Misskey 部署完成!請開設管理員帳號!"
|
||||||
done: "完成"
|
done: "完成"
|
||||||
processing: "處理中"
|
processing: "處理中"
|
||||||
preview: "預覽"
|
preview: "預覽"
|
||||||
default: "預設"
|
default: "預設"
|
||||||
noCustomEmojis: "沒有表情符號"
|
noCustomEmojis: "沒有表情符號"
|
||||||
customEmojisOfRemote: "來自其他實例的表情符號"
|
customEmojisOfRemote: "來自其他實例的表情符號"
|
||||||
federating: "整合檢索中"
|
noJobs: "沒有任務"
|
||||||
|
federating: "整合搜索中"
|
||||||
blocked: "已封鎖"
|
blocked: "已封鎖"
|
||||||
suspended: "已凍結"
|
suspended: "已凍結"
|
||||||
all: "全部"
|
all: "全部"
|
||||||
@@ -175,12 +182,13 @@ security: "安全性"
|
|||||||
retypedNotMatch: "不相符的輸入內容"
|
retypedNotMatch: "不相符的輸入內容"
|
||||||
currentPassword: "現在的密碼"
|
currentPassword: "現在的密碼"
|
||||||
newPassword: "新的密碼"
|
newPassword: "新的密碼"
|
||||||
newPasswordRetype: "新的密碼(再輸入一次)"
|
newPasswordRetype: "新的密碼(再輸入一次)"
|
||||||
attachFile: "添加附件"
|
attachFile: "添加附件"
|
||||||
more: "更多!"
|
more: "更多!"
|
||||||
featured: "精選"
|
featured: "精選"
|
||||||
usernameOrUserId: "用戶名或用戶ID"
|
usernameOrUserId: "使用者名稱或使用者 ID"
|
||||||
noSuchUser: "用戶不存在"
|
noSuchUser: "使用者不存在"
|
||||||
|
lookup: "查詢"
|
||||||
announcements: "公告"
|
announcements: "公告"
|
||||||
imageUrl: "圖片URL"
|
imageUrl: "圖片URL"
|
||||||
remove: "刪除"
|
remove: "刪除"
|
||||||
@@ -373,6 +381,7 @@ passwordMatched: "密碼一致"
|
|||||||
passwordNotMatched: "密碼不一致"
|
passwordNotMatched: "密碼不一致"
|
||||||
signinFailed: "登入失敗。 請檢查用戶名和密碼。"
|
signinFailed: "登入失敗。 請檢查用戶名和密碼。"
|
||||||
uiLanguage: "介面語言"
|
uiLanguage: "介面語言"
|
||||||
|
youHaveNoGroups: "找不到群組"
|
||||||
tags: "標籤"
|
tags: "標籤"
|
||||||
fontSize: "字體大小"
|
fontSize: "字體大小"
|
||||||
total: "合計"
|
total: "合計"
|
||||||
@@ -389,11 +398,17 @@ install: "安裝"
|
|||||||
uninstall: "解除安裝"
|
uninstall: "解除安裝"
|
||||||
lastUsedDate: "最後上線日期"
|
lastUsedDate: "最後上線日期"
|
||||||
state: "狀態"
|
state: "狀態"
|
||||||
|
ascendingOrder: "昇冪"
|
||||||
|
descendingOrder: "降冪"
|
||||||
|
scratchpad: "暫存記憶體"
|
||||||
output: "輸出"
|
output: "輸出"
|
||||||
deleteAllFiles: "刪除所有檔案"
|
deleteAllFiles: "刪除所有檔案"
|
||||||
deleteAllFilesConfirm: "要删除所有檔案吗?"
|
deleteAllFilesConfirm: "要删除所有檔案吗?"
|
||||||
userSilenced: "該用戶已被禁言。"
|
userSilenced: "該用戶已被禁言。"
|
||||||
deletedNote: "已删除的貼文"
|
deletedNote: "已删除的貼文"
|
||||||
|
smtpHost: "主機"
|
||||||
|
smtpUser: "使用名稱"
|
||||||
|
smtpPass: "密碼"
|
||||||
_theme:
|
_theme:
|
||||||
func: "函数"
|
func: "函数"
|
||||||
keys:
|
keys:
|
||||||
@@ -469,6 +484,7 @@ _widgets:
|
|||||||
rss: "RSS閱讀器"
|
rss: "RSS閱讀器"
|
||||||
activity: "動態"
|
activity: "動態"
|
||||||
photos: "照片"
|
photos: "照片"
|
||||||
|
federation: "聯邦宇宙"
|
||||||
_cw:
|
_cw:
|
||||||
show: "瀏覽更多"
|
show: "瀏覽更多"
|
||||||
files: "{count} 個檔案"
|
files: "{count} 個檔案"
|
||||||
@@ -481,10 +497,10 @@ _visibility:
|
|||||||
followers: "追隨者"
|
followers: "追隨者"
|
||||||
_profile:
|
_profile:
|
||||||
name: "名稱"
|
name: "名稱"
|
||||||
username: "用戶名"
|
username: "使用名稱"
|
||||||
_exportOrImport:
|
_exportOrImport:
|
||||||
followingList: "追隨中"
|
followingList: "追隨中"
|
||||||
muteList: "禁言"
|
muteList: "消音"
|
||||||
blockingList: "封鎖"
|
blockingList: "封鎖"
|
||||||
userLists: "清單"
|
userLists: "清單"
|
||||||
_instanceCharts:
|
_instanceCharts:
|
||||||
|
14
migration/1595676934834-instance-icon-url.ts
Normal file
14
migration/1595676934834-instance-icon-url.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class instanceIconUrl1595676934834 implements MigrationInterface {
|
||||||
|
name = 'instanceIconUrl1595676934834'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "instance" ADD "iconUrl" character varying(256) DEFAULT null`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "iconUrl"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||||
"version": "12.42.0",
|
"version": "12.43.0",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@@ -40,7 +40,24 @@ export default Vue.extend({
|
|||||||
: this.user.avatarUrl;
|
: this.user.avatarUrl;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
'user.avatarBlurhash'() {
|
||||||
|
this.$el.style.color = this.getBlurhashAvgColor(this.user.avatarBlurhash);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$el.style.color = this.getBlurhashAvgColor(this.user.avatarBlurhash);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getBlurhashAvgColor(s) {
|
||||||
|
return typeof s == 'string'
|
||||||
|
? '#' + [...s.slice(2, 6)]
|
||||||
|
.map(x => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~'.indexOf(x))
|
||||||
|
.reduce((a, c) => a * 83 + c, 0)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(6, '0')
|
||||||
|
: undefined;
|
||||||
|
},
|
||||||
onClick(e) {
|
onClick(e) {
|
||||||
this.$emit('click', e);
|
this.$emit('click', e);
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<fa :icon="faSatellite"/><span style="margin-left: 8px;">{{ column.name }}</span>
|
<fa :icon="faSatellite"/><span style="margin-left: 8px;">{{ column.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<x-timeline ref="timeline" src="antenna" :antenna="column.antennaId" @after="() => $emit('loaded')"/>
|
<x-timeline v-if="column.antennaId" ref="timeline" src="antenna" :antenna="column.antennaId" @after="() => $emit('loaded')"/>
|
||||||
</x-column>
|
</x-column>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -33,7 +33,6 @@ export default Vue.extend({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
menu: null,
|
|
||||||
faSatellite
|
faSatellite
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -47,28 +46,36 @@ export default Vue.extend({
|
|||||||
created() {
|
created() {
|
||||||
this.menu = [{
|
this.menu = [{
|
||||||
icon: faCog,
|
icon: faCog,
|
||||||
text: this.$t('antenna'),
|
text: this.$t('selectAntenna'),
|
||||||
action: async () => {
|
action: this.setAntenna
|
||||||
const antennas = await this.$root.api('antennas/list');
|
|
||||||
this.$root.dialog({
|
|
||||||
title: this.$t('antenna'),
|
|
||||||
type: null,
|
|
||||||
select: {
|
|
||||||
items: antennas.map(x => ({
|
|
||||||
value: x, text: x.name
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
showCancelButton: true
|
|
||||||
}).then(({ canceled, result: antenna }) => {
|
|
||||||
if (canceled) return;
|
|
||||||
this.column.antennaId = antenna.id;
|
|
||||||
this.$store.commit('deviceUser/updateDeckColumn', this.column);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
if (this.column.antennaId == null) {
|
||||||
|
this.setAntenna();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
async setAntenna() {
|
||||||
|
const antennas = await this.$root.api('antennas/list');
|
||||||
|
const { canceled, result: antenna } = await this.$root.dialog({
|
||||||
|
title: this.$t('selectAntenna'),
|
||||||
|
type: null,
|
||||||
|
select: {
|
||||||
|
items: antennas.map(x => ({
|
||||||
|
value: x, text: x.name
|
||||||
|
})),
|
||||||
|
default: this.column.antennaId
|
||||||
|
},
|
||||||
|
showCancelButton: true
|
||||||
|
});
|
||||||
|
if (canceled) return;
|
||||||
|
Vue.set(this.column, 'antennaId', antenna.id);
|
||||||
|
this.$store.commit('deviceUser/updateDeckColumn', this.column);
|
||||||
|
},
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
(this.$refs.timeline as any).focus();
|
(this.$refs.timeline as any).focus();
|
||||||
}
|
}
|
||||||
|
@@ -150,37 +150,37 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
}, null, {
|
}, null, {
|
||||||
icon: faArrowLeft,
|
icon: faArrowLeft,
|
||||||
text: this.$t('swap-left'),
|
text: this.$t('_deck.swapLeft'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/swapLeftDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/swapLeftDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: faArrowRight,
|
icon: faArrowRight,
|
||||||
text: this.$t('swap-right'),
|
text: this.$t('_deck.swapRight'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/swapRightDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/swapRightDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}, this.isStacked ? {
|
}, this.isStacked ? {
|
||||||
icon: faArrowUp,
|
icon: faArrowUp,
|
||||||
text: this.$t('swap-up'),
|
text: this.$t('_deck.swapUp'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/swapUpDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/swapUpDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
} : undefined, this.isStacked ? {
|
} : undefined, this.isStacked ? {
|
||||||
icon: faArrowDown,
|
icon: faArrowDown,
|
||||||
text: this.$t('swap-down'),
|
text: this.$t('_deck.swapDown'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/swapDownDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/swapDownDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
} : undefined, null, {
|
} : undefined, null, {
|
||||||
icon: faWindowRestore,
|
icon: faWindowRestore,
|
||||||
text: this.$t('stack-left'),
|
text: this.$t('_deck.stackLeft'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/stackLeftDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/stackLeftDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}, this.isStacked ? {
|
}, this.isStacked ? {
|
||||||
icon: faWindowMaximize,
|
icon: faWindowMaximize,
|
||||||
text: this.$t('pop-right'),
|
text: this.$t('_deck.popRight'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.commit('deviceUser/popRightDeckColumn', this.column.id);
|
this.$store.commit('deviceUser/popRightDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,21 @@
|
|||||||
<x-column :name="name" :column="column" :is-stacked="isStacked" :menu="menu">
|
<x-column :name="name" :column="column" :is-stacked="isStacked" :menu="menu">
|
||||||
<template #header><fa :icon="faEnvelope" style="margin-right: 8px;"/>{{ column.name }}</template>
|
<template #header><fa :icon="faEnvelope" style="margin-right: 8px;"/>{{ column.name }}</template>
|
||||||
|
|
||||||
<x-direct/>
|
<x-notes :pagination="pagination" @before="before()" @after="after()"/>
|
||||||
</x-column>
|
</x-column>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
|
import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import Progress from '../../scripts/loading';
|
||||||
import XColumn from './column.vue';
|
import XColumn from './column.vue';
|
||||||
import XDirect from '../../pages/messages.vue';
|
import XNotes from '../notes.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XColumn,
|
XColumn,
|
||||||
XDirect
|
XNotes
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
@@ -32,8 +33,25 @@ export default Vue.extend({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
menu: null,
|
menu: null,
|
||||||
|
pagination: {
|
||||||
|
endpoint: 'notes/mentions',
|
||||||
|
limit: 10,
|
||||||
|
params: () => ({
|
||||||
|
visibility: 'specified'
|
||||||
|
})
|
||||||
|
},
|
||||||
faEnvelope
|
faEnvelope
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
before() {
|
||||||
|
Progress.start();
|
||||||
|
},
|
||||||
|
|
||||||
|
after() {
|
||||||
|
Progress.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@@ -46,7 +46,7 @@ export default Vue.extend({
|
|||||||
created() {
|
created() {
|
||||||
this.menu = [{
|
this.menu = [{
|
||||||
icon: faCog,
|
icon: faCog,
|
||||||
text: this.$t('list'),
|
text: this.$t('selectList'),
|
||||||
action: this.setList
|
action: this.setList
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
@@ -61,7 +61,7 @@ export default Vue.extend({
|
|||||||
async setList() {
|
async setList() {
|
||||||
const lists = await this.$root.api('users/lists/list');
|
const lists = await this.$root.api('users/lists/list');
|
||||||
const { canceled, result: list } = await this.$root.dialog({
|
const { canceled, result: list } = await this.$root.dialog({
|
||||||
title: this.$t('list'),
|
title: this.$t('selectList'),
|
||||||
type: null,
|
type: null,
|
||||||
select: {
|
select: {
|
||||||
items: lists.map(x => ({
|
items: lists.map(x => ({
|
||||||
|
@@ -2,20 +2,21 @@
|
|||||||
<x-column :column="column" :is-stacked="isStacked" :menu="menu">
|
<x-column :column="column" :is-stacked="isStacked" :menu="menu">
|
||||||
<template #header><fa :icon="faAt" style="margin-right: 8px;"/>{{ column.name }}</template>
|
<template #header><fa :icon="faAt" style="margin-right: 8px;"/>{{ column.name }}</template>
|
||||||
|
|
||||||
<x-mentions/>
|
<x-notes :pagination="pagination" @before="before()" @after="after()"/>
|
||||||
</x-column>
|
</x-column>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faAt } from '@fortawesome/free-solid-svg-icons';
|
import { faAt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import Progress from '../../scripts/loading';
|
||||||
import XColumn from './column.vue';
|
import XColumn from './column.vue';
|
||||||
import XMentions from '../../pages/mentions.vue';
|
import XNotes from '../notes.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XColumn,
|
XColumn,
|
||||||
XMentions
|
XNotes
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
@@ -32,8 +33,22 @@ export default Vue.extend({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
menu: null,
|
menu: null,
|
||||||
|
pagination: {
|
||||||
|
endpoint: 'notes/mentions',
|
||||||
|
limit: 10,
|
||||||
|
},
|
||||||
faAt
|
faAt
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
before() {
|
||||||
|
Progress.start();
|
||||||
|
},
|
||||||
|
|
||||||
|
after() {
|
||||||
|
Progress.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@@ -45,14 +45,14 @@ export default Vue.extend({
|
|||||||
|
|
||||||
this.menu = [{
|
this.menu = [{
|
||||||
icon: faCog,
|
icon: faCog,
|
||||||
text: this.$t('@.notification-type'),
|
text: this.$t('notificationType'),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
title: this.$t('@.notification-type'),
|
title: this.$t('notificationType'),
|
||||||
type: null,
|
type: null,
|
||||||
select: {
|
select: {
|
||||||
items: ['all', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest'].map(x => ({
|
items: ['all', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest'].map(x => ({
|
||||||
value: x, text: this.$t('@.notification-types.' + x)
|
value: x, text: this.$t(`_notification._types.${x}`)
|
||||||
}))
|
}))
|
||||||
default: this.column.notificationType,
|
default: this.column.notificationType,
|
||||||
},
|
},
|
||||||
|
@@ -5,9 +5,12 @@
|
|||||||
<div class="wtdtxvec">
|
<div class="wtdtxvec">
|
||||||
<template v-if="edit">
|
<template v-if="edit">
|
||||||
<header>
|
<header>
|
||||||
<select v-model="widgetAdderSelected" @change="addWidget">
|
<mk-select v-model="widgetAdderSelected" style="margin-bottom: var(--margin)">
|
||||||
<option v-for="widget in widgets" :value="widget" :key="widget">{{ widget }}</option>
|
<template #label>{{ $t('selectWidget') }}</template>
|
||||||
</select>
|
<option v-for="widget in widgets" :value="widget" :key="widget">{{ $t(`_widgets.${widget}`) }}</option>
|
||||||
|
</mk-select>
|
||||||
|
<mk-button inline @click="addWidget" primary><fa :icon="faPlus"/> {{ $t('add') }}</mk-button>
|
||||||
|
<mk-button inline @click="edit = false">{{ $t('close') }}</mk-button>
|
||||||
</header>
|
</header>
|
||||||
<x-draggable
|
<x-draggable
|
||||||
:list="column.widgets"
|
:list="column.widgets"
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
@sort="onWidgetSort"
|
@sort="onWidgetSort"
|
||||||
>
|
>
|
||||||
<div v-for="widget in column.widgets" class="customize-container" :key="widget.id" @click="widgetFunc(widget.id)">
|
<div v-for="widget in column.widgets" class="customize-container" :key="widget.id" @click="widgetFunc(widget.id)">
|
||||||
<button class="remove _button" @click="removeWidget(widget)"><fa :icon="faTimes"/></button>
|
<button class="remove _button" @click.prevent.stop="removeWidget(widget)"><fa :icon="faTimes"/></button>
|
||||||
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" :column="column"/>
|
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" :column="column"/>
|
||||||
</div>
|
</div>
|
||||||
</x-draggable>
|
</x-draggable>
|
||||||
@@ -29,7 +32,9 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as XDraggable from 'vuedraggable';
|
import * as XDraggable from 'vuedraggable';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { faWindowMaximize, faTimes, faCog } from '@fortawesome/free-solid-svg-icons';
|
import { faWindowMaximize, faTimes, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import MkSelect from '../../components/ui/select.vue';
|
||||||
|
import MkButton from '../../components/ui/button.vue';
|
||||||
import XColumn from './column.vue';
|
import XColumn from './column.vue';
|
||||||
import { widgets } from '../../widgets';
|
import { widgets } from '../../widgets';
|
||||||
|
|
||||||
@@ -37,6 +42,8 @@ export default Vue.extend({
|
|||||||
components: {
|
components: {
|
||||||
XColumn,
|
XColumn,
|
||||||
XDraggable,
|
XDraggable,
|
||||||
|
MkSelect,
|
||||||
|
MkButton,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
@@ -56,7 +63,7 @@ export default Vue.extend({
|
|||||||
menu: null,
|
menu: null,
|
||||||
widgetAdderSelected: null,
|
widgetAdderSelected: null,
|
||||||
widgets,
|
widgets,
|
||||||
faWindowMaximize, faTimes
|
faWindowMaximize, faTimes, faPlus
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -80,6 +87,8 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addWidget() {
|
addWidget() {
|
||||||
|
if (this.widgetAdderSelected == null) return;
|
||||||
|
|
||||||
this.$store.commit('deviceUser/addDeckWidget', {
|
this.$store.commit('deviceUser/addDeckWidget', {
|
||||||
id: this.column.id,
|
id: this.column.id,
|
||||||
widget: {
|
widget: {
|
||||||
|
@@ -34,19 +34,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<article class="article">
|
<article class="article">
|
||||||
<mk-avatar class="avatar" :user="appearNote.user"/>
|
<mk-avatar class="avatar" :user="appearNote.user" v-once/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<x-note-header class="header" :note="appearNote" :mini="true"/>
|
<x-note-header class="header" :note="appearNote" :mini="true"/>
|
||||||
<div class="body" v-if="appearNote.deletedAt == null" ref="noteBody">
|
<div class="body" v-if="appearNote.deletedAt == null" ref="noteBody">
|
||||||
<p v-if="appearNote.cw != null" class="cw">
|
<p v-if="appearNote.cw != null" class="cw">
|
||||||
<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" />
|
<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/>
|
||||||
<x-cw-button v-model="showContent" :note="appearNote"/>
|
<x-cw-button v-model="showContent" :note="appearNote"/>
|
||||||
</p>
|
</p>
|
||||||
<div class="content" v-show="appearNote.cw == null || showContent">
|
<div class="content" v-show="appearNote.cw == null || showContent">
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
|
||||||
<router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link>
|
<router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link>
|
||||||
<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
|
<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/>
|
||||||
<a class="rp" v-if="appearNote.renote != null">RN:</a>
|
<a class="rp" v-if="appearNote.renote != null">RN:</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="files" v-if="appearNote.files.length > 0">
|
<div class="files" v-if="appearNote.files.length > 0">
|
||||||
|
@@ -52,9 +52,9 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
timer(): string {
|
timer(): string {
|
||||||
return this.$t(
|
return this.$t(
|
||||||
this.remaining > 86400 ? '_poll.remainingDays' :
|
this.remaining >= 86400 ? '_poll.remainingDays' :
|
||||||
this.remaining > 3600 ? '_poll.remainingHours' :
|
this.remaining >= 3600 ? '_poll.remainingHours' :
|
||||||
this.remaining > 60 ? '_poll.remainingMinutes' : '_poll.remainingSeconds', {
|
this.remaining >= 60 ? '_poll.remainingMinutes' : '_poll.remainingSeconds', {
|
||||||
s: Math.floor(this.remaining % 60),
|
s: Math.floor(this.remaining % 60),
|
||||||
m: Math.floor(this.remaining / 60) % 60,
|
m: Math.floor(this.remaining / 60) % 60,
|
||||||
h: Math.floor(this.remaining / 3600) % 24,
|
h: Math.floor(this.remaining / 3600) % 24,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<x-window @closed="() => { $emit('closed'); destroyDom(); }" :no-padding="true">
|
<x-window @closed="() => { $emit('closed'); destroyDom(); }" :no-padding="true" :width="520" :height="500">
|
||||||
<template #header>{{ instance.host }}</template>
|
<template #header>{{ instance.host }}</template>
|
||||||
<div class="mk-instance-info">
|
<div class="mk-instance-info">
|
||||||
<div class="table info">
|
<div class="table info">
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
<mk-switch v-model="enableGlobalTimeline" @change="save()">{{ $t('enableGlobalTimeline') }}</mk-switch>
|
<mk-switch v-model="enableGlobalTimeline" @change="save()">{{ $t('enableGlobalTimeline') }}</mk-switch>
|
||||||
<mk-info>{{ $t('disablingTimelinesInfo') }}</mk-info>
|
<mk-info>{{ $t('disablingTimelinesInfo') }}</mk-info>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="_content">
|
||||||
|
<mk-switch v-model="useStarForReactionFallback" @change="save()">{{ $t('useStarForReactionFallback') }}</mk-switch>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="_card info">
|
<section class="_card info">
|
||||||
@@ -74,6 +77,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="_card">
|
||||||
|
<div class="_title"><fa :icon="faEnvelope" /> {{ $t('emailConfig') }}</div>
|
||||||
|
<div class="_content">
|
||||||
|
<mk-switch v-model="enableEmail" @change="save()">{{ $t('enableEmail') }}<template #desc>{{ $t('emailConfigInfo') }}</template></mk-switch>
|
||||||
|
<mk-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</mk-input>
|
||||||
|
<div><b>{{ $t('smtpConfig') }}</b></div>
|
||||||
|
<div class="_inputs">
|
||||||
|
<mk-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtpHost') }}</mk-input>
|
||||||
|
<mk-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtpPort') }}</mk-input>
|
||||||
|
</div>
|
||||||
|
<div class="_inputs">
|
||||||
|
<mk-input v-model="smtpUser" :disabled="!enableEmail">{{ $t('smtpUser') }}</mk-input>
|
||||||
|
<mk-input v-model="smtpPass" type="password" :disabled="!enableEmail">{{ $t('smtpPass') }}</mk-input>
|
||||||
|
</div>
|
||||||
|
<mk-info>{{ $t('emptyToDisableSmtpAuth') }}</mk-info>
|
||||||
|
<mk-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtpSecure') }}<template #desc>{{ $t('smtpSecureInfo') }}</template></mk-switch>
|
||||||
|
<div>
|
||||||
|
<mk-button :disabled="!enableEmail" inline @click="testEmail()">{{ $t('testEmail') }}</mk-button>
|
||||||
|
<mk-button :disabled="!enableEmail" primary inline @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</mk-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="_card">
|
<section class="_card">
|
||||||
<div class="_title"><fa :icon="faBolt"/> {{ $t('serviceworker') }}</div>
|
<div class="_title"><fa :icon="faBolt"/> {{ $t('serviceworker') }}</div>
|
||||||
<div class="_content">
|
<div class="_content">
|
||||||
@@ -195,12 +221,19 @@
|
|||||||
<mk-button primary @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</mk-button>
|
<mk-button primary @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</mk-button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section class="_card">
|
||||||
|
<div class="_title"><fa :icon="faArchway" /> Summaly Proxy</div>
|
||||||
|
<div class="_content">
|
||||||
|
<mk-input v-model="summalyProxy">URL</mk-input>
|
||||||
|
<mk-button primary @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</mk-button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faPencilAlt, faShareAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faThumbtack, faUser, faShieldAlt, faKey, faBolt } from '@fortawesome/free-solid-svg-icons';
|
import { faPencilAlt, faShareAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faThumbtack, faUser, faShieldAlt, faKey, faBolt, faArchway } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faTrashAlt, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
import { faTrashAlt, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { faTwitter, faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons';
|
import { faTwitter, faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons';
|
||||||
import MkButton from '../../components/ui/button.vue';
|
import MkButton from '../../components/ui/button.vue';
|
||||||
@@ -243,7 +276,9 @@ export default Vue.extend({
|
|||||||
maintainerEmail: null,
|
maintainerEmail: null,
|
||||||
name: null,
|
name: null,
|
||||||
description: null,
|
description: null,
|
||||||
tosUrl: null,
|
tosUrl: null as string | null,
|
||||||
|
enableEmail: false,
|
||||||
|
email: null,
|
||||||
bannerUrl: null,
|
bannerUrl: null,
|
||||||
iconUrl: null,
|
iconUrl: null,
|
||||||
maxNoteTextLength: 0,
|
maxNoteTextLength: 0,
|
||||||
@@ -279,7 +314,14 @@ export default Vue.extend({
|
|||||||
enableDiscordIntegration: false,
|
enableDiscordIntegration: false,
|
||||||
discordClientId: null,
|
discordClientId: null,
|
||||||
discordClientSecret: null,
|
discordClientSecret: null,
|
||||||
faPencilAlt, faTwitter, faDiscord, faGithub, faShareAlt, faTrashAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faEnvelope, faThumbtack, faUser, faShieldAlt, faKey, faBolt
|
useStarForReactionFallback: false,
|
||||||
|
smtpSecure: false,
|
||||||
|
smtpHost: '',
|
||||||
|
smtpPort: 0,
|
||||||
|
smtpUser: '',
|
||||||
|
smtpPass: '',
|
||||||
|
summalyProxy: '',
|
||||||
|
faPencilAlt, faTwitter, faDiscord, faGithub, faShareAlt, faTrashAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faEnvelope, faThumbtack, faUser, faShieldAlt, faKey, faBolt, faArchway
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -295,6 +337,8 @@ export default Vue.extend({
|
|||||||
this.tosUrl = this.meta.tosUrl;
|
this.tosUrl = this.meta.tosUrl;
|
||||||
this.bannerUrl = this.meta.bannerUrl;
|
this.bannerUrl = this.meta.bannerUrl;
|
||||||
this.iconUrl = this.meta.iconUrl;
|
this.iconUrl = this.meta.iconUrl;
|
||||||
|
this.enableEmail = this.meta.enableEmail;
|
||||||
|
this.email = this.meta.email;
|
||||||
this.maintainerName = this.meta.maintainerName;
|
this.maintainerName = this.meta.maintainerName;
|
||||||
this.maintainerEmail = this.meta.maintainerEmail;
|
this.maintainerEmail = this.meta.maintainerEmail;
|
||||||
this.maxNoteTextLength = this.meta.maxNoteTextLength;
|
this.maxNoteTextLength = this.meta.maxNoteTextLength;
|
||||||
@@ -337,6 +381,13 @@ export default Vue.extend({
|
|||||||
this.enableDiscordIntegration = this.meta.enableDiscordIntegration;
|
this.enableDiscordIntegration = this.meta.enableDiscordIntegration;
|
||||||
this.discordClientId = this.meta.discordClientId;
|
this.discordClientId = this.meta.discordClientId;
|
||||||
this.discordClientSecret = this.meta.discordClientSecret;
|
this.discordClientSecret = this.meta.discordClientSecret;
|
||||||
|
this.useStarForReactionFallback = this.meta.useStarForReactionFallback;
|
||||||
|
this.smtpSecure = this.meta.smtpSecure;
|
||||||
|
this.smtpHost = this.meta.smtpHost;
|
||||||
|
this.smtpPort = this.meta.smtpPort;
|
||||||
|
this.smtpUser = this.meta.smtpUser;
|
||||||
|
this.smtpPass = this.meta.smtpPass;
|
||||||
|
this.summalyProxy = this.meta.summalyProxy;
|
||||||
|
|
||||||
if (this.proxyAccountId) {
|
if (this.proxyAccountId) {
|
||||||
this.$root.api('users/show', { userId: this.proxyAccountId }).then(proxyAccount => {
|
this.$root.api('users/show', { userId: this.proxyAccountId }).then(proxyAccount => {
|
||||||
@@ -412,6 +463,24 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async testEmail() {
|
||||||
|
this.$root.api('admin/send-email', {
|
||||||
|
to: this.maintainerEmail,
|
||||||
|
subject: 'Test email',
|
||||||
|
text: 'Yo'
|
||||||
|
}).then(x => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'success',
|
||||||
|
splash: true
|
||||||
|
});
|
||||||
|
}).catch(e => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: e
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
save(withDialog = false) {
|
save(withDialog = false) {
|
||||||
this.$root.api('admin/update-meta', {
|
this.$root.api('admin/update-meta', {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
@@ -461,6 +530,15 @@ export default Vue.extend({
|
|||||||
enableDiscordIntegration: this.enableDiscordIntegration,
|
enableDiscordIntegration: this.enableDiscordIntegration,
|
||||||
discordClientId: this.discordClientId,
|
discordClientId: this.discordClientId,
|
||||||
discordClientSecret: this.discordClientSecret,
|
discordClientSecret: this.discordClientSecret,
|
||||||
|
enableEmail: this.enableEmail,
|
||||||
|
email: this.email,
|
||||||
|
smtpSecure: this.smtpSecure,
|
||||||
|
smtpHost: this.smtpHost,
|
||||||
|
smtpPort: this.smtpPort,
|
||||||
|
smtpUser: this.smtpUser,
|
||||||
|
smtpPass: this.smtpPass,
|
||||||
|
summalyProxy: this.summalyProxy,
|
||||||
|
useStarForReactionFallback: this.useStarForReactionFallback,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$store.dispatch('instance/fetch');
|
this.$store.dispatch('instance/fetch');
|
||||||
if (withDialog) {
|
if (withDialog) {
|
||||||
|
@@ -44,9 +44,8 @@ export function createAiScriptEnv(vm, opts) {
|
|||||||
|
|
||||||
export function createPluginEnv(vm, opts) {
|
export function createPluginEnv(vm, opts) {
|
||||||
const config = new Map();
|
const config = new Map();
|
||||||
for (const key in opts.plugin.config) {
|
for (const [k, v] of Object.entries(opts.plugin.config)) {
|
||||||
const val = opts.plugin.configData[key] || opts.plugin.config[key].default;
|
config.set(k, jsToVal(opts.plugin.configData[k] || v.default));
|
||||||
config.set(key, jsToVal(val));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
126
src/client/widgets/federation.vue
Normal file
126
src/client/widgets/federation.vue
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<mk-container :show-header="props.showHeader">
|
||||||
|
<template #header><fa :icon="faGlobe"/>{{ $t('_widgets.federation') }}</template>
|
||||||
|
|
||||||
|
<div class="wbrkwalb">
|
||||||
|
<mk-loading v-if="fetching"/>
|
||||||
|
<transition-group tag="div" name="chart" class="instances" v-else>
|
||||||
|
<div v-for="(instance, i) in instances" :key="instance.id" class="instance">
|
||||||
|
<img v-if="instance.iconUrl" :src="instance.iconUrl" alt=""/>
|
||||||
|
<div class="body">
|
||||||
|
<a class="a" :href="'https://' + instance.host" target="_blank" :title="instance.host">{{ instance.host }}</a>
|
||||||
|
<p>{{ instance.softwareName || '?' }} {{ instance.softwareVersion }}</p>
|
||||||
|
</div>
|
||||||
|
<mk-mini-chart class="chart" :src="charts[i].requests.received"/>
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</mk-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { faGlobe } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import MkContainer from '../components/ui/container.vue';
|
||||||
|
import define from './define';
|
||||||
|
import MkMiniChart from '../components/mini-chart.vue';
|
||||||
|
|
||||||
|
export default define({
|
||||||
|
name: 'federation',
|
||||||
|
props: () => ({
|
||||||
|
showHeader: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}).extend({
|
||||||
|
components: {
|
||||||
|
MkContainer, MkMiniChart
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
instances: [],
|
||||||
|
charts: [],
|
||||||
|
fetching: true,
|
||||||
|
faGlobe
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetch();
|
||||||
|
this.clock = setInterval(this.fetch, 1000 * 60);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.clock);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fetch() {
|
||||||
|
const instances = await this.$root.api('federation/instances', {
|
||||||
|
sort: '+lastCommunicatedAt',
|
||||||
|
limit: 5
|
||||||
|
});
|
||||||
|
const charts = await Promise.all(instances.map(i => this.$root.api('charts/instance', { host: i.host, limit: 16, span: 'hour' })));
|
||||||
|
this.instances = instances;
|
||||||
|
this.charts = charts;
|
||||||
|
this.fetching = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.wbrkwalb {
|
||||||
|
$bodyTitleHieght: 18px;
|
||||||
|
$bodyInfoHieght: 16px;
|
||||||
|
|
||||||
|
height: (62px + 1px) + (62px + 1px) + (62px + 1px) + (62px + 1px) + 62px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
> .instances {
|
||||||
|
.chart-move {
|
||||||
|
transition: transform 1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .instance {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 14px 16px;
|
||||||
|
border-bottom: solid 1px var(--divider);
|
||||||
|
|
||||||
|
> img {
|
||||||
|
display: block;
|
||||||
|
width: ($bodyTitleHieght + $bodyInfoHieght);
|
||||||
|
height: ($bodyTitleHieght + $bodyInfoHieght);
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--fg);
|
||||||
|
|
||||||
|
> .a {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: $bodyTitleHieght;
|
||||||
|
}
|
||||||
|
|
||||||
|
> p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 75%;
|
||||||
|
opacity: 0.7;
|
||||||
|
line-height: $bodyInfoHieght;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .chart {
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -11,6 +11,7 @@ Vue.component('mkw-clock', () => import('./clock.vue').then(m => m.default));
|
|||||||
Vue.component('mkw-activity', () => import('./activity.vue').then(m => m.default));
|
Vue.component('mkw-activity', () => import('./activity.vue').then(m => m.default));
|
||||||
Vue.component('mkw-photos', () => import('./photos.vue').then(m => m.default));
|
Vue.component('mkw-photos', () => import('./photos.vue').then(m => m.default));
|
||||||
Vue.component('mkw-digitalClock', () => import('./digital-clock.vue').then(m => m.default));
|
Vue.component('mkw-digitalClock', () => import('./digital-clock.vue').then(m => m.default));
|
||||||
|
Vue.component('mkw-federation', () => import('./federation.vue').then(m => m.default));
|
||||||
|
|
||||||
export const widgets = [
|
export const widgets = [
|
||||||
'memo',
|
'memo',
|
||||||
@@ -23,4 +24,5 @@ export const widgets = [
|
|||||||
'activity',
|
'activity',
|
||||||
'photos',
|
'photos',
|
||||||
'digitalClock',
|
'digitalClock',
|
||||||
|
'federation',
|
||||||
];
|
];
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<router-link class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
<router-link class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
||||||
<p>{{ $t('nUsersMentioned', { n: stat.usersCount }) }}</p>
|
<p>{{ $t('nUsersMentioned', { n: stat.usersCount }) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<x-chart class="chart" :src="stat.chart"/>
|
<mk-mini-chart class="chart" :src="stat.chart"/>
|
||||||
</div>
|
</div>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
import { faHashtag } from '@fortawesome/free-solid-svg-icons';
|
import { faHashtag } from '@fortawesome/free-solid-svg-icons';
|
||||||
import MkContainer from '../components/ui/container.vue';
|
import MkContainer from '../components/ui/container.vue';
|
||||||
import define from './define';
|
import define from './define';
|
||||||
import XChart from './trends.chart.vue';
|
import MkMiniChart from '../components/mini-chart.vue';
|
||||||
|
|
||||||
export default define({
|
export default define({
|
||||||
name: 'hashtags',
|
name: 'hashtags',
|
||||||
@@ -33,7 +33,7 @@ export default define({
|
|||||||
})
|
})
|
||||||
}).extend({
|
}).extend({
|
||||||
components: {
|
components: {
|
||||||
MkContainer, XChart
|
MkContainer, MkMiniChart
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@@ -21,8 +21,8 @@ export function getApLock(uri: string, timeout = 30 * 1000) {
|
|||||||
return lock(`ap-object:${uri}`, timeout);
|
return lock(`ap-object:${uri}`, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNodeinfoLock(host: string, timeout = 30 * 1000) {
|
export function getFetchInstanceMetadataLock(host: string, timeout = 30 * 1000) {
|
||||||
return lock(`nodeinfo:${host}`, timeout);
|
return lock(`instance:${host}`, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getChartInsertLock(lockKey: string, timeout = 30 * 1000) {
|
export function getChartInsertLock(lockKey: string, timeout = 30 * 1000) {
|
||||||
|
@@ -27,6 +27,27 @@ export async function getJson(url: string, accept = 'application/json, */*', tim
|
|||||||
return await res.json();
|
return await res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: HeadersInit) {
|
||||||
|
const res = await fetch(url, {
|
||||||
|
headers: Object.assign({
|
||||||
|
'User-Agent': config.userAgent,
|
||||||
|
Accept: accept
|
||||||
|
}, headers || {}),
|
||||||
|
timeout,
|
||||||
|
agent: getAgentByUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw {
|
||||||
|
name: `StatusError`,
|
||||||
|
statusCode: res.status,
|
||||||
|
message: `${res.status} ${res.statusText}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return await res.text();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get http non-proxy agent
|
* Get http non-proxy agent
|
||||||
*/
|
*/
|
||||||
|
@@ -158,6 +158,11 @@ export class Instance {
|
|||||||
})
|
})
|
||||||
public maintainerEmail: string | null;
|
public maintainerEmail: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 256, nullable: true, default: null,
|
||||||
|
})
|
||||||
|
public iconUrl: string | null;
|
||||||
|
|
||||||
@Column('timestamp with time zone', {
|
@Column('timestamp with time zone', {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
|
@@ -4,7 +4,7 @@ import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-ins
|
|||||||
import Logger from '../../services/logger';
|
import Logger from '../../services/logger';
|
||||||
import { Instances } from '../../models';
|
import { Instances } from '../../models';
|
||||||
import { instanceChart } from '../../services/chart';
|
import { instanceChart } from '../../services/chart';
|
||||||
import { fetchNodeinfo } from '../../services/fetch-nodeinfo';
|
import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata';
|
||||||
import { fetchMeta } from '../../misc/fetch-meta';
|
import { fetchMeta } from '../../misc/fetch-meta';
|
||||||
import { toPuny } from '../../misc/convert-host';
|
import { toPuny } from '../../misc/convert-host';
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export default async (job: Bull.Job) => {
|
|||||||
isNotResponding: false
|
isNotResponding: false
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchNodeinfo(i);
|
fetchInstanceMetadata(i);
|
||||||
|
|
||||||
instanceChart.requestSent(i.host, true);
|
instanceChart.requestSent(i.host, true);
|
||||||
});
|
});
|
||||||
|
@@ -8,7 +8,7 @@ import { instanceChart } from '../../services/chart';
|
|||||||
import { fetchMeta } from '../../misc/fetch-meta';
|
import { fetchMeta } from '../../misc/fetch-meta';
|
||||||
import { toPuny, extractDbHost } from '../../misc/convert-host';
|
import { toPuny, extractDbHost } from '../../misc/convert-host';
|
||||||
import { getApId } from '../../remote/activitypub/type';
|
import { getApId } from '../../remote/activitypub/type';
|
||||||
import { fetchNodeinfo } from '../../services/fetch-nodeinfo';
|
import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata';
|
||||||
import { InboxJobData } from '..';
|
import { InboxJobData } from '..';
|
||||||
import DbResolver from '../../remote/activitypub/db-resolver';
|
import DbResolver from '../../remote/activitypub/db-resolver';
|
||||||
import { resolvePerson } from '../../remote/activitypub/models/person';
|
import { resolvePerson } from '../../remote/activitypub/models/person';
|
||||||
@@ -126,7 +126,7 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
|
|||||||
isNotResponding: false
|
isNotResponding: false
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchNodeinfo(i);
|
fetchInstanceMetadata(i);
|
||||||
|
|
||||||
instanceChart.requestReceived(i.host);
|
instanceChart.requestReceived(i.host);
|
||||||
});
|
});
|
||||||
|
@@ -26,7 +26,7 @@ import { validActor } from '../../../remote/activitypub/type';
|
|||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
import { ensure } from '../../../prelude/ensure';
|
import { ensure } from '../../../prelude/ensure';
|
||||||
import { toArray } from '../../../prelude/array';
|
import { toArray } from '../../../prelude/array';
|
||||||
import { fetchNodeinfo } from '../../../services/fetch-nodeinfo';
|
import { fetchInstanceMetadata } from '../../../services/fetch-instance-metadata';
|
||||||
|
|
||||||
const logger = apLogger;
|
const logger = apLogger;
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
|||||||
registerOrFetchInstanceDoc(host).then(i => {
|
registerOrFetchInstanceDoc(host).then(i => {
|
||||||
Instances.increment({ id: i.id }, 'usersCount', 1);
|
Instances.increment({ id: i.id }, 'usersCount', 1);
|
||||||
instanceChart.newUser(i.host);
|
instanceChart.newUser(i.host);
|
||||||
fetchNodeinfo(i);
|
fetchInstanceMetadata(i);
|
||||||
});
|
});
|
||||||
|
|
||||||
usersChart.update(user!, true);
|
usersChart.update(user!, true);
|
||||||
|
135
src/services/fetch-instance-metadata.ts
Normal file
135
src/services/fetch-instance-metadata.ts
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import { JSDOM } from 'jsdom';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import { getJson, getHtml, getAgentByUrl } from '../misc/fetch';
|
||||||
|
import { Instance } from '../models/entities/instance';
|
||||||
|
import { Instances } from '../models';
|
||||||
|
import { getFetchInstanceMetadataLock } from '../misc/app-lock';
|
||||||
|
import Logger from './logger';
|
||||||
|
import { URL } from 'url';
|
||||||
|
|
||||||
|
const logger = new Logger('metadata', 'cyan');
|
||||||
|
|
||||||
|
export async function fetchInstanceMetadata(instance: Instance): Promise<void> {
|
||||||
|
const unlock = await getFetchInstanceMetadataLock(instance.host);
|
||||||
|
|
||||||
|
const _instance = await Instances.findOne({ host: instance.host });
|
||||||
|
const now = Date.now();
|
||||||
|
if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) {
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`Fetching metadata of ${instance.host} ...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [info, icon] = await Promise.all([
|
||||||
|
fetchNodeinfo(instance).catch(() => null),
|
||||||
|
fetchIconUrl(instance).catch(() => null),
|
||||||
|
]);
|
||||||
|
|
||||||
|
logger.succ(`Successfuly fetched metadata of ${instance.host}`);
|
||||||
|
|
||||||
|
const updates = {
|
||||||
|
infoUpdatedAt: new Date(),
|
||||||
|
} as Record<string, any>;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
updates.softwareName = info.software.name.toLowerCase();
|
||||||
|
updates.softwareVersion = info.software.version;
|
||||||
|
updates.openRegistrations = info.openRegistrations;
|
||||||
|
updates.name = info.metadata ? (info.metadata.nodeName || info.metadata.name || null) : null;
|
||||||
|
updates.description = info.metadata ? (info.metadata.nodeDescription || info.metadata.description || null) : null;
|
||||||
|
updates.maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name || null) : null : null;
|
||||||
|
updates.maintainerEmail = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email || null) : null : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
updates.iconUrl = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Instances.update(instance.id, updates);
|
||||||
|
|
||||||
|
logger.succ(`Successfuly updated metadata of ${instance.host}`);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Failed to update metadata of ${instance.host}: ${e}`);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchNodeinfo(instance: Instance): Promise<Record<string, any>> {
|
||||||
|
logger.info(`Fetching nodeinfo of ${instance.host} ...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const wellknown = await getJson('https://' + instance.host + '/.well-known/nodeinfo')
|
||||||
|
.catch(e => {
|
||||||
|
if (e.statusCode === 404) {
|
||||||
|
throw 'No nodeinfo provided';
|
||||||
|
} else {
|
||||||
|
throw e.statusCode || e.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (wellknown.links == null || !Array.isArray(wellknown.links)) {
|
||||||
|
throw 'No wellknown links';
|
||||||
|
}
|
||||||
|
|
||||||
|
const links = wellknown.links as any[];
|
||||||
|
|
||||||
|
const lnik1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0');
|
||||||
|
const lnik2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0');
|
||||||
|
const lnik2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1');
|
||||||
|
const link = lnik2_1 || lnik2_0 || lnik1_0;
|
||||||
|
|
||||||
|
if (link == null) {
|
||||||
|
throw 'No nodeinfo link provided';
|
||||||
|
}
|
||||||
|
|
||||||
|
const info = await getJson(link.href)
|
||||||
|
.catch(e => {
|
||||||
|
throw e.statusCode || e.message;
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Failed to fetch nodeinfo of ${instance.host}: ${e}`);
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchIconUrl(instance: Instance): Promise<string | null> {
|
||||||
|
logger.info(`Fetching icon URL of ${instance.host} ...`);
|
||||||
|
|
||||||
|
const url = 'https://' + instance.host;
|
||||||
|
|
||||||
|
const html = await getHtml(url);
|
||||||
|
|
||||||
|
const { window } = new JSDOM(html);
|
||||||
|
const doc = window.document;
|
||||||
|
|
||||||
|
const hrefAppleTouchIconPrecomposed = doc.querySelector('link[rel="apple-touch-icon-precomposed"]')?.getAttribute('href');
|
||||||
|
const hrefAppleTouchIcon = doc.querySelector('link[rel="apple-touch-icon"]')?.getAttribute('href');
|
||||||
|
const hrefIcon = doc.querySelector('link[rel="icon"]')?.getAttribute('href');
|
||||||
|
|
||||||
|
const href = hrefAppleTouchIconPrecomposed || hrefAppleTouchIcon || hrefIcon;
|
||||||
|
|
||||||
|
if (href) {
|
||||||
|
return (new URL(href, url)).href;
|
||||||
|
}
|
||||||
|
|
||||||
|
const faviconUrl = url + '/favicon.ico';
|
||||||
|
|
||||||
|
const favicon = await fetch(faviconUrl, {
|
||||||
|
timeout: 10000,
|
||||||
|
agent: getAgentByUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (favicon.ok) {
|
||||||
|
return faviconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@@ -1,72 +0,0 @@
|
|||||||
import { getJson } from '../misc/fetch';
|
|
||||||
import { Instance } from '../models/entities/instance';
|
|
||||||
import { Instances } from '../models';
|
|
||||||
import { getNodeinfoLock } from '../misc/app-lock';
|
|
||||||
import Logger from '../services/logger';
|
|
||||||
|
|
||||||
export const logger = new Logger('nodeinfo', 'cyan');
|
|
||||||
|
|
||||||
export async function fetchNodeinfo(instance: Instance) {
|
|
||||||
const unlock = await getNodeinfoLock(instance.host);
|
|
||||||
|
|
||||||
const _instance = await Instances.findOne({ host: instance.host });
|
|
||||||
const now = Date.now();
|
|
||||||
if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) {
|
|
||||||
unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(`Fetching nodeinfo of ${instance.host} ...`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const wellknown = await getJson('https://' + instance.host + '/.well-known/nodeinfo')
|
|
||||||
.catch(e => {
|
|
||||||
if (e.statusCode === 404) {
|
|
||||||
throw 'No nodeinfo provided';
|
|
||||||
} else {
|
|
||||||
throw e.statusCode || e.message;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (wellknown.links == null || !Array.isArray(wellknown.links)) {
|
|
||||||
throw 'No wellknown links';
|
|
||||||
}
|
|
||||||
|
|
||||||
const links = wellknown.links as any[];
|
|
||||||
|
|
||||||
const lnik1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0');
|
|
||||||
const lnik2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0');
|
|
||||||
const lnik2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1');
|
|
||||||
const link = lnik2_1 || lnik2_0 || lnik1_0;
|
|
||||||
|
|
||||||
if (link == null) {
|
|
||||||
throw 'No nodeinfo link provided';
|
|
||||||
}
|
|
||||||
|
|
||||||
const info = await getJson(link.href)
|
|
||||||
.catch(e => {
|
|
||||||
throw e.statusCode || e.message;
|
|
||||||
});
|
|
||||||
|
|
||||||
await Instances.update(instance.id, {
|
|
||||||
infoUpdatedAt: new Date(),
|
|
||||||
softwareName: info.software.name.toLowerCase(),
|
|
||||||
softwareVersion: info.software.version,
|
|
||||||
openRegistrations: info.openRegistrations,
|
|
||||||
name: info.metadata ? (info.metadata.nodeName || info.metadata.name || null) : null,
|
|
||||||
description: info.metadata ? (info.metadata.nodeDescription || info.metadata.description || null) : null,
|
|
||||||
maintainerName: info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name || null) : null : null,
|
|
||||||
maintainerEmail: info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email || null) : null : null,
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error(`Failed to fetch nodeinfo of ${instance.host}: ${e}`);
|
|
||||||
|
|
||||||
await Instances.update(instance.id, {
|
|
||||||
infoUpdatedAt: new Date(),
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
unlock();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -26,7 +26,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: undefined,
|
width: undefined,
|
||||||
height: undefined,
|
height: undefined,
|
||||||
blurhash: null
|
blurhash: undefined
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 512,
|
width: 512,
|
||||||
height: 512,
|
height: 512,
|
||||||
blurhash: '' // TODO
|
blurhash: 'yFLxJjH[NE}@^PRiN_}Y=aVZNvFxxZ#SwIt7Eg%KIp-ospv~Nex[R6t3xZI:iwt6kWxDafoySgsAfR$*oyM|S2t7$iV[tQNbaKn%xt'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
blurhash: '' // TODO
|
blurhash: 'y8S?Mr-;=~~Xs;%foL?bWVs;xbR%NFay^ms;I-InI-xbs;%gofj[I-s;-WxbI-WUayxb$,NFR*~Wa{R%xbayNFI.oMj[oMNFWB$,WU'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
blurhash: '' // TODO
|
blurhash: 'y8S?Mr-;=~~Xs;%foL?bWVs;xbR%NFay^ms;I-InI-xbs;%gofj[I-s;-WxbI-WUayxb$,NFR*~Wa{R%xbayNFI.oMj[oMNFWB$,WU'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
blurhash: '' // TODO
|
blurhash: 'y74P29kDpdp{k?VDZ#krkCaefkf6fQf5HXZ$krkqadaKaJkCaKkXfkkCf5fkQ8kXZ#VDaKk?krZ~kCf6kDf6f5f6U]krZ#Z#aekrkq'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
blurhash: '' // TODO
|
blurhash: 'yMEKyd1U1?=nZN-2EwofR*oHnijYX6S50J=m]WEVl9JE$SR*xHR;XSX8nQxB-WS6Nts*aKskWnaxR%s*i_n~X6S5=#NgOAs*enoIWU'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
blurhash: '' // TODO
|
blurhash: 'yMEKyd1U1?=nZN-2EwofR*oHnijYX6S50J=m]WEVl9JE$SR*xHR;XSX8nQxB-WS6Nts*aKskWnaxR%s*i_n~X6S5=#NgOAs*enoIWU'
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ describe('Get file info', () => {
|
|||||||
},
|
},
|
||||||
width: 25000,
|
width: 25000,
|
||||||
height: 25000,
|
height: 25000,
|
||||||
blurhash: '' // TODO
|
blurhash: undefined
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@@ -1200,9 +1200,9 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
|
|||||||
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
|
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
|
||||||
|
|
||||||
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.5.5:
|
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.5.5:
|
||||||
version "6.12.2"
|
version "6.12.3"
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
|
||||||
integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==
|
integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal "^3.1.1"
|
fast-deep-equal "^3.1.1"
|
||||||
fast-json-stable-stringify "^2.0.0"
|
fast-json-stable-stringify "^2.0.0"
|
||||||
|
Reference in New Issue
Block a user