diff --git a/.mocharc.json b/.mocharc.json index fc7fee2154..278a5b310a 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -2,6 +2,6 @@ "extension": ["ts","js","cjs","mjs"], "require": ["ts-node/register", "tsconfig-paths/register"], "slow": 1000, - "timeout": 30000, + "timeout": 35000, "exit": true } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6926ed918f..6dc2e5e226 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,12 +28,7 @@ If your language is not listed in Crowdin, please open an issue. ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) -## Internationalization (i18n) -Misskey uses the Vue.js plugin [Vue I18n](https://github.com/kazupon/vue-i18n). -Documentation of Vue I18n is available at http://kazupon.github.io/vue-i18n/introduction.html . - ## Documentation -* Documents for contributors are located in [`/docs`](/docs). * Documents for instance admins are located in [`/docs`](/docs). * Documents for end users are located in [`/src/docs`](/src/docs). @@ -41,8 +36,8 @@ Documentation of Vue I18n is available at http://kazupon.github.io/vue-i18n/intr * Test codes are located in [`/test`](/test). ## Continuous integration -Misskey uses CircleCI for executing automated tests. -Configuration files are located in [`/.circleci`](/.circleci). +Misskey uses GitHub Actions for executing automated tests. +Configuration files are located in [`/.github/workflows`](/.github/workflows). ## Adding MisskeyRoom items * Use English for material, object and texture names. diff --git a/COPYING b/COPYING index 5abc3e9895..13c13bf938 100644 --- a/COPYING +++ b/COPYING @@ -6,10 +6,6 @@ And is distributed under The GNU Affero General Public License Version 3, you sh Misskey includes several third-party Open-Source softwares. -Unicode emoji regular expressions by Twitter, Inc. -License: MIT -https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md - Emoji keywords for Unicode 11 and below by Mu-An Chiou License: MIT https://github.com/muan/emojilib/blob/master/LICENSE diff --git a/README.md b/README.md index 5cff3619fd..816765af67 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,11 @@ Please see the [Contribution Guide](./CONTRIBUTING.md). To receive updates of this repo, follow [@repo@misskey.io](https://misskey.io/@repo) on fediverse. +Related projects +---------------------------------------------------------------- +- [misskey.js](https://github.com/misskey-dev/misskey.js) - Misskey SDK for JavaScript +- [mfm.js](https://github.com/misskey-dev/mfm.js) - MFM parser + :heart: Backers ---------------------------------------------------------------- diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..2c026a5f33 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Reporting Security Issues + +If you discover a security issue in Misskey, please report it by sending an +email to [syuilotan@yahoo.co.jp](mailto:syuilotan@yahoo.co.jp). + +This will allow us to assess the risk, and make a fix available before we add a +bug report to the GitHub repository. + +Thanks for helping make Misskey safe for everyone. diff --git a/assets/about/banner.svg b/assets/about/banner.svg index 31b6ca95e1..75308c0950 100644 Binary files a/assets/about/banner.svg and b/assets/about/banner.svg differ diff --git a/assets/banner.afdesign b/assets/banner.afdesign index def3e884d3..08b5c1b4a0 100644 Binary files a/assets/banner.afdesign and b/assets/banner.afdesign differ diff --git a/gulpfile.ts b/gulpfile.ts index 660dfb013e..2cdcbdb6fc 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import * as gulp from 'gulp'; -import * as rimraf from 'rimraf'; +import rimraf from 'rimraf'; const replace = require('gulp-replace'); const terser = require('gulp-terser'); const cssnano = require('gulp-cssnano'); diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 631027cb7a..9c20ea7524 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -259,8 +259,6 @@ monthX: "{month}" yearX: "{year}" pages: "الصفحات" integration: "دمج" -connectSerice: "أوصل" -disconnectSerice: "قطع الاتصال" enableLocalTimeline: "تفعيل الخيط المحلي" enableGlobalTimeline: "تفعيل الخيط الزمني الشامل" disablingTimelinesInfo: "سيتمكن المسؤولون ومن تعديل دائمًا و من الوصول إلى جميع المخططات الزمنية ، حتى إذا لم يتم تمكينها." diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 6d62b5345e..995d8eccd8 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -269,8 +269,6 @@ monthX: "{month}" yearX: "{year}" pages: "Stránky" integration: "Integrace" -connectSerice: "Připojit" -disconnectSerice: "Odpojit" enableLocalTimeline: "Povolit lokální čas" enableGlobalTimeline: "Povolit globální čas" registration: "Registrace" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 1f35b9de72..d08858a336 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -279,6 +279,7 @@ emptyDrive: "Drive ist leer" emptyFolder: "Der Ordner ist leer" unableToDelete: "Nicht löschbar" inputNewFileName: "Gib einen neuen Dateinamen ein" +inputNewDescription: "Gib eine neue Beschreibung ein" inputNewFolderName: "Gib einen neuen Ordnernamen ein" circularReferenceFolder: "Der Zielordner ist ein Unterorder des Ordners, den du verschieben möchtest." hasChildFilesOrFolders: "Dieser Ordner kann nicht gelöscht werden, da er nicht leer ist." @@ -310,8 +311,8 @@ monthX: "{month}" yearX: "{year}" pages: "Seiten" integration: "Integration" -connectSerice: "Verbinden" -disconnectSerice: "Trennen" +connectService: "Verbinden" +disconnectService: "Trennen" enableLocalTimeline: "Lokale Chronik aktivieren" enableGlobalTimeline: "Globale Chronik aktivieren" disablingTimelinesInfo: "Administratoren und Moderatoren haben immer Zugriff auf alle Chroniken, auch wenn diese deaktiviert sind." @@ -325,6 +326,7 @@ driveCapacityPerRemoteAccount: "Drive-Kapazität pro Benutzer anderer Instanzen" inMb: "In Megabytes" iconUrl: "Icon-URL" bannerUrl: "Banner-URL" +backgroundImageUrl: "Hintergrundbild-URL" basicInfo: "Basisdaten" pinnedUsers: "Angepinnte Benutzer" pinnedUsersDescription: "Gib einen Benutzernamen pro Zeile ein. Diese werden im \"Erkunden\" Tab angezeigt." @@ -546,6 +548,8 @@ disablePlayer: "Video-Player schließen" expandTweet: "Tweet ausklappen" themeEditor: "Farbthemen-Editor" description: "Beschreibung" +describeFile: "Beschreibung hinzufügen" +enterFileDescription: "Beschreibung eingeben" author: "Autor" leaveConfirm: "Es gibt unspeicherte Änderungen. Möchtest du diese verwerfen?" manage: "Verwaltung" diff --git a/locales/en-US.yml b/locales/en-US.yml index 4cf417d21b..d08f403b9e 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -279,6 +279,7 @@ emptyDrive: "The drive is empty" emptyFolder: "This folder is empty" unableToDelete: "Unable to delete" inputNewFileName: "Enter a new filename" +inputNewDescription: "Enter new caption" inputNewFolderName: "Enter a new folder name" circularReferenceFolder: "The destination folder is a subfolder of the folder you wish to move." hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted." @@ -310,8 +311,8 @@ monthX: "{month}" yearX: "{year} /" pages: "Pages" integration: "Integration" -connectSerice: "Connect" -disconnectSerice: "Disconnect" +connectService: "Connect" +disconnectService: "Disconnect" enableLocalTimeline: "Enable local timeline" enableGlobalTimeline: "Enable global timeline" disablingTimelinesInfo: "Admins and Mods will always have access to all timelines, even if they are not enabled." @@ -325,6 +326,7 @@ driveCapacityPerRemoteAccount: "Drive capacity per remote user" inMb: "In megabytes" iconUrl: "Icon URL" bannerUrl: "Banner image URL" +backgroundImageUrl: "Background image URL" basicInfo: "Basic info" pinnedUsers: "Pinned user" pinnedUsersDescription: "List one username per line. Users listed here will be pinned under \"Explore\" tab." @@ -546,6 +548,8 @@ disablePlayer: "Close video player" expandTweet: "Expand tweet" themeEditor: "Theme editor" description: "Description" +describeFile: "Add caption" +enterFileDescription: "Enter caption" author: "Author" leaveConfirm: "There are unsaved changes. Do you want to discard them?" manage: "Management" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index ae7fba8976..89e170678d 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -309,8 +309,6 @@ monthX: "Mes {month}" yearX: "Año {year}" pages: "Páginas" integration: "Integración" -connectSerice: "Conectarse" -disconnectSerice: "Desconectarse" enableLocalTimeline: "Habilitar linea de tiempo local" enableGlobalTimeline: "Habilitar linea de tiempo global" disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index c62b1c3b6e..161b4553ad 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -279,6 +279,7 @@ emptyDrive: "Le Drive est vide" emptyFolder: "Le dossier est vide" unableToDelete: "Suppression impossible" inputNewFileName: "Entrez un nouveau nom de fichier" +inputNewDescription: "Veuillez entrer une nouvelle description" inputNewFolderName: "Entrez un nouveau nom de dossier" circularReferenceFolder: "Le dossier de destination est un sous-dossier du dossier que vous souhaitez déplacer." hasChildFilesOrFolders: "Impossible de supprimer ce dossier car il n'est pas vide." @@ -310,8 +311,8 @@ monthX: "{month}" yearX: "{year}" pages: "Pages" integration: "Intégrations" -connectSerice: "Connecter" -disconnectSerice: "Déconnecter" +connectService: "Connexion" +disconnectService: "Déconnexion" enableLocalTimeline: "Activer le fil local" enableGlobalTimeline: "Activer le fil global" disablingTimelinesInfo: "Même si vous désactivez ces fils, les administrateur·rice·s et les modérateur·rice·s pourront toujours y accéder." @@ -546,6 +547,8 @@ disablePlayer: "Fermer le lecteur vidéo" expandTweet: "Étendre le tweet" themeEditor: "Éditeur de thèmes" description: "Description" +describeFile: "Ajouter une description d'image" +enterFileDescription: "Saisissez une description" author: "Auteur·rice" leaveConfirm: "Vous avez des modifications non-sauvegardées. Voulez-vous les ignorer ?" manage: "Gestion" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 5f401bc4b1..ed1ac14121 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1,5 +1,5 @@ --- -_lang_: "Bahasa Jepang" +_lang_: "Bahasa Indonesia" headlineMisskey: "Jaringan terhubung melalui note" introMisskey: "Selamat datang! Misskey adalah perangkat mikroblog tercatu bersifat sumber terbuka.\nMulailah menuliskan catatan, bagikan peristiwa terkini, serta ceritakan segala tentangmu.📡\nTunjukkan juga reaksimu pada catatan pengguna lain.👍\nMari jelajahi dunia baru🚀" monthAndDay: "{day} {month}" @@ -310,8 +310,6 @@ monthX: "{month}" yearX: "{year}" pages: "Halaman" integration: "Integrasi" -connectSerice: "Sambungkan" -disconnectSerice: "Putuskan" enableLocalTimeline: "Nyalakan linimasa lokal" enableGlobalTimeline: "Nyalakan linimasa global" disablingTimelinesInfo: "Admin dan Moderator akan selalu memiliki akses ke semua linimasa meskipun linimasa tersebut tidak diaktifkan." @@ -977,9 +975,9 @@ _theme: infoFg: "Teks informasi" infoWarnBg: "Latar belakang peringatan" infoWarnFg: "Teks peringatan" - cwBg: "Latar belakang tombol CW" - cwFg: "Teks tombol CW" - cwHoverBg: "Latar belakang tombol CW (Mengambang)" + cwBg: "Latar belakang tombol Sembunyikan Konten" + cwFg: "Teks tombol Sembunyikan Konten" + cwHoverBg: "Latar belakang tombol Sembunyikan Konten (Mengambang)" toastBg: "Latar belakang pemberitahuan" toastFg: "Teks pemberitahuan" buttonBg: "Latar belakang tombol" @@ -1122,7 +1120,7 @@ _widgets: aiscript: "Konsol AiScript" _cw: hide: "Sembunyikan" - show: "Selebihnya" + show: "Lihat konten" chars: "{count} karakter" files: "{count} berkas" _poll: @@ -1551,7 +1549,7 @@ _pages: fn: "Fungsi" _fn: slots: "Slot" - slots-info: "Pisahkan setiap slow dengan baris baru" + slots-info: "Pisahkan setiap slot dengan baris baru" arg1: "Keluaran" for: "Ulangi" _for: diff --git a/locales/index.js b/locales/index.js index 727e0e3848..35f9972ff7 100644 --- a/locales/index.js +++ b/locales/index.js @@ -21,6 +21,7 @@ const languages = [ 'en-US', 'es-ES', 'fr-FR', + 'id-ID', 'ja-JP', 'ja-KS', 'kab-KAB', diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 69c8152d7f..63b535a476 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -274,6 +274,7 @@ emptyDrive: "Il Drive è vuoto" emptyFolder: "La cartella è vuota" unableToDelete: "Eliminazione impossibile" inputNewFileName: "Inserisci nome del nuovo file" +inputNewDescription: "Inserisci una nuova descrizione" inputNewFolderName: "Inserisci nome della nuova cartella" circularReferenceFolder: "La cartella di destinazione è una sottocartella della cartella che vuoi spostare." hasChildFilesOrFolders: "Impossibile eliminare la cartella perché non è vuota" @@ -305,8 +306,8 @@ monthX: "{month}" yearX: "{year}" pages: "Pagine" integration: "App collegate" -connectSerice: "Connetti" -disconnectSerice: "Disconnetti" +connectService: "Connessione" +disconnectService: "Disconnessione " enableLocalTimeline: "Abilita Timeline locale" enableGlobalTimeline: "Abilita Timeline federata" disablingTimelinesInfo: "Anche se disabiliti queste timeline, gli amministratori e i moderatori potranno sempre accederci." @@ -533,6 +534,8 @@ disablePlayer: "Chiudi lettore video" expandTweet: "Espandi tweet" themeEditor: "Editor di temi" description: "Descrizione" +describeFile: "Aggiungi una descrizione d'immagine" +enterFileDescription: "Inserisci descrizione" author: "Autore" leaveConfirm: "Ci sono delle modifiche ancora non salvate. Vuoi cancellarle?" manage: "Gestione" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 836c3ddfc8..9cad54db99 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -279,6 +279,7 @@ emptyDrive: "ドライブは空です" emptyFolder: "フォルダーは空です" unableToDelete: "削除できません" inputNewFileName: "新しいファイル名を入力してください" +inputNewDescription: "新しいキャプションを入力してください" inputNewFolderName: "新しいフォルダ名を入力してください" circularReferenceFolder: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" hasChildFilesOrFolders: "このフォルダは空でないため、削除できません。" @@ -310,8 +311,8 @@ monthX: "{month}月" yearX: "{year}年" pages: "ページ" integration: "連携" -connectSerice: "接続する" -disconnectSerice: "切断する" +connectService: "接続する" +disconnectService: "切断する" enableLocalTimeline: "ローカルタイムラインを有効にする" enableGlobalTimeline: "グローバルタイムラインを有効にする" disablingTimelinesInfo: "これらのタイムラインを無効化しても、利便性のため管理者およびモデレーターは引き続き利用することができます。" @@ -325,6 +326,7 @@ driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのド inMb: "メガバイト単位" iconUrl: "アイコン画像のURL (faviconなど)" bannerUrl: "バナー画像のURL" +backgroundImageUrl: "背景画像のURL" basicInfo: "基本情報" pinnedUsers: "ピン留めユーザー" pinnedUsersDescription: "「みつける」ページなどにピン留めしたいユーザーを改行で区切って記述します。" @@ -546,6 +548,8 @@ disablePlayer: "プレイヤーを閉じる" expandTweet: "ツイートを展開する" themeEditor: "テーマエディター" description: "説明" +describeFile: "キャプションを付ける" +enterFileDescription: "キャプションを入力" author: "作者" leaveConfirm: "未保存の変更があります。破棄しますか?" manage: "管理" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 6435b5835b..060c7b142d 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -308,8 +308,6 @@ monthX: "{month}月" yearX: "{year}年" pages: "ページ" integration: "連携" -connectSerice: "つなぐ" -disconnectSerice: "切ってまう" enableLocalTimeline: "ローカルタイムラインを使えるようにする" enableGlobalTimeline: "グローバルタイムラインを使えるようにする" disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 49069d258f..f3fce251f6 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -279,6 +279,7 @@ emptyDrive: "드라이브가 비어 있습니다" emptyFolder: "폴더가 비어 있습니다" unableToDelete: "삭제할 수 없습니다" inputNewFileName: "바꿀 파일명을 입력해 주세요" +inputNewDescription: "새 캡션을 입력해 주세요" inputNewFolderName: "바꿀 폴더명을 입력해 주세요" circularReferenceFolder: "지정한 폴더가 이동할 폴더의 하위 폴더입니다." hasChildFilesOrFolders: "이 폴더는 비어있지 않기 때문에 삭제할 수 없습니다." @@ -310,8 +311,8 @@ monthX: "{month}월" yearX: "{year}년" pages: "페이지" integration: "연동" -connectSerice: "접속" -disconnectSerice: "연결 끊기" +connectService: "계정 연동" +disconnectService: "계정 연동 해제" enableLocalTimeline: "로컬 타임라인 활성화" enableGlobalTimeline: "글로벌 타임라인 활성화" disablingTimelinesInfo: "특정 타임라인을 비활성화하더라도 관리자 및 모더레이터는 계속 사용할 수 있습니다." @@ -325,6 +326,7 @@ driveCapacityPerRemoteAccount: "리모트 유저 한 명당 드라이브 용량" inMb: "메가바이트 단위" iconUrl: "아이콘 URL" bannerUrl: "배너 이미지 URL" +backgroundImageUrl: "배경 이미지 URL" basicInfo: "기본 정보" pinnedUsers: "고정된 유저" pinnedUsersDescription: "\"발견하기\" 페이지 등에 고정하고 싶은 유저를 한 줄에 한 명씩 적습니다." @@ -546,6 +548,8 @@ disablePlayer: "플레이어 닫기" expandTweet: "트윗 확장하기" themeEditor: "테마 에디터" description: "설명" +describeFile: "캡션 추가" +enterFileDescription: "캡션 입력" author: "작성자" leaveConfirm: "저장하지 않은 변경사항이 있습니다. 취소하시겠습니까?" manage: "관리" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 4b4c80f7f3..550bda78b0 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -135,6 +135,7 @@ settingGuide: "Proponowana konfiguracja" cacheRemoteFiles: "Przechowuj zdalne pliki w pamięci podręcznej" cacheRemoteFilesDescription: "Gdy ta opcja jest wyłączona, zdalne pliki są ładowane bezpośrednio ze zdalnych instancji. Wyłączenie the opcji zmniejszy użycie powierzchni dyskowej, ale zwiększy transfer, ponieważ miniaturki nie będą generowane." flagAsBot: "To konto jest botem" +flagAsBotDescription: "Jeżeli ten kanał jest kontrolowany przez jakiś program, ustaw tę opcję. Jeżeli włączona, będzie działać jako flaga informująca innych programistów, aby zapobiegać nieskończonej interakcji z różnymi botami i dostosowywać wewnętrzne systemy Misskey, traktując konto jako bota." flagAsCat: "To konto jest kotem" flagAsCatDescription: "Przełącz tę opcję, aby konto było oznaczone jako kot." autoAcceptFollowed: "Automatycznie przyjmuj prośby o możliwość obserwacji od użytkowników, których obserwujesz" @@ -182,6 +183,7 @@ clearQueueConfirmTitle: "Czy na pewno chcesz wyczyścić kolejkę?" clearCachedFiles: "Wyczyść pamięć podręczną" clearCachedFilesConfirm: "Czy na pewno chcesz usunąć wszystkie zdalne pliki z pamięci podręcznej?" blockedInstances: "Zablokowane instancje" +blockedInstancesDescription: "Wypisz nazwy hostów instancji, które powinny zostać zablokowane. Wypisane instancje nie będą mogły dłużej komunikować się z tą instancją." muteAndBlock: "Wycisz / Zablokuj" mutedUsers: "Wyciszeni użytkownicy" blockedUsers: "Zablokowani użytkownicy" @@ -274,6 +276,7 @@ emptyDrive: "Dysk jest pusty" emptyFolder: "Ten katalog jest pusty" unableToDelete: "Nie można usunąć" inputNewFileName: "Wprowadź nową nazwę pliku" +inputNewDescription: "Proszę wpisać nowy napis" inputNewFolderName: "Wprowadź nową nazwę katalogu" circularReferenceFolder: "Katalog docelowy jest podkatalogiem katalogu, który chcesz przenieść." hasChildFilesOrFolders: "Ponieważ ten katalog nie jest pusty, nie może być usunięty." @@ -305,8 +308,6 @@ monthX: "{month}" yearX: "{year}" pages: "Strony" integration: "Integracja" -connectSerice: "Połącz" -disconnectSerice: "Rozłącz" enableLocalTimeline: "Włącz lokalną oś czasu" enableGlobalTimeline: "Włącz globalną oś czasu" disablingTimelinesInfo: "Administratorzy i moderatorzy będą zawsze mieć dostęp do wszystkich osi czasu, nawet gdy są one wyłączone." @@ -532,6 +533,8 @@ disablePlayer: "Zamknij odtwarzacz wideo" expandTweet: "Rozwiń tweet" themeEditor: "Edytor motywu" description: "Opis" +describeFile: "dodaj podpis" +enterFileDescription: "Wprowadź napis" author: "Autor" leaveConfirm: "Są niezapisane zmiany. Czy chcesz je odrzucić?" manage: "Zarządzanie" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 2610403a71..c9700f4c91 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -309,8 +309,6 @@ monthX: "{month} месяц" yearX: "{year} год" pages: "Страницы" integration: "Интеграция" -connectSerice: "Соединение" -disconnectSerice: "Отключение" enableLocalTimeline: "Включить локальную ленту" enableGlobalTimeline: "Включить глобальную ленту" disablingTimelinesInfo: "У администраторов и модераторов есть доступ ко всем лентам, даже если они отключены." diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index bb010ed5f6..3b8e6461c4 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -307,8 +307,6 @@ monthX: "{month}" yearX: "{year}" pages: "Сторінки" integration: "Інтеграція" -connectSerice: "Під’єднати" -disconnectSerice: "Відключитися" enableLocalTimeline: "Увімкнути локальну стрічку" enableGlobalTimeline: "Увімкнути глобальну стрічку" disablingTimelinesInfo: "Адміністратори та модератори завжди мають доступ до всіх стрічок, навіть якщо вони вимкнуті." diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 4754fec4a4..f10a09a329 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -279,6 +279,7 @@ emptyDrive: "驱动器为空" emptyFolder: "空文件夹" unableToDelete: "无法删除" inputNewFileName: "请输入新文件名" +inputNewDescription: "请输入新标题" inputNewFolderName: "请输入新文件名" circularReferenceFolder: "目标文件夹是您要移动的文件夹的子文件夹。" hasChildFilesOrFolders: "此文件夹不为空,无法删除。" @@ -310,8 +311,8 @@ monthX: "{month}月" yearX: "{year}年" pages: "页面" integration: "关联" -connectSerice: "连接" -disconnectSerice: "断开连接" +connectService: "连接" +disconnectService: "断开连接" enableLocalTimeline: "启用本地时间线功能" enableGlobalTimeline: "启用全局时间线" disablingTimelinesInfo: "即使时间线功能被禁用,出于便利性的原因,管理员和数据图表也可以继续使用。" @@ -325,6 +326,7 @@ driveCapacityPerRemoteAccount: "每个远程用户的网盘容量" inMb: "以兆字节(MegaByte)为单位" iconUrl: "图标URL" bannerUrl: "Banner URL" +backgroundImageUrl: "背景图URL" basicInfo: "基本信息" pinnedUsers: "置顶用户" pinnedUsersDescription: "在「发现」页面中使用换行标记想要置顶的用户。" @@ -546,6 +548,8 @@ disablePlayer: "关闭播放器" expandTweet: "展开贴文" themeEditor: "主题编辑器" description: "描述" +describeFile: "添加标题" +enterFileDescription: "输入标题" author: "作者" leaveConfirm: "存在未保存的更改。要放弃更改吗?" manage: "管理" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index e8c7e55531..dd9552a871 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1,18 +1,19 @@ --- _lang_: "繁體中文" -headlineMisskey: "貼文連繫網絡" -introMisskey: "歡迎! Misskey是一個開源且去中心化的社群網絡。\n通過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀" +headlineMisskey: "貼文連繫網路" +introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀" monthAndDay: "{month}月 {day}日" search: "搜尋" notifications: "通知" username: "使用者名稱" password: "密碼" +forgotPassword: "忘記密碼" fetchingAsApObject: "從聯邦宇宙取得中..." ok: "OK" gotIt: "知道了" cancel: "取消" enterUsername: "輸入使用者名稱" -renotedBy: "{user} 轉發了" +renotedBy: "{user} 轉傳了" noNotes: "貼文不可用。" noNotifications: "沒有通知" instance: "實例" @@ -92,9 +93,9 @@ followRequestPending: "追隨許可批准中" enterEmoji: "輸入表情符號" renote: "轉發" unrenote: "取消轉發" -renoted: "轉發成功" +renoted: "轉傳成功" cantRenote: "無法轉發此貼文。" -cantReRenote: "無法轉發之前已經轉發過的內容。" +cantReRenote: "無法轉傳之前已經轉傳過的內容。" quote: "引用" pinnedNote: "已置頂的貼文" pinned: "置頂" @@ -309,8 +310,6 @@ monthX: "{month}月" yearX: "{year}年" pages: "頁面" integration: "整合" -connectSerice: "連線" -disconnectSerice: "中斷連線" enableLocalTimeline: "開啟本地時間軸" enableGlobalTimeline: "啟用公開時間軸" disablingTimelinesInfo: "即使您關閉了時間線功能,管理員和協調人仍可以繼續使用,以方便您。" @@ -733,6 +732,7 @@ noBotProtectionWarning: "尚未設定Bot防護。" configure: "設定" expiration: "期限" middle: "中" +emailNotConfiguredWarning: "沒有設定電子郵件地址" _ad: back: "返回" _gallery: diff --git a/migration/1622679304522-user-profile-description-length.ts b/migration/1622679304522-user-profile-description-length.ts new file mode 100644 index 0000000000..015d1e24b7 --- /dev/null +++ b/migration/1622679304522-user-profile-description-length.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class userProfileDescriptionLength1622679304522 implements MigrationInterface { + name = 'userProfileDescriptionLength1622679304522'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(2048)`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(1024)`, undefined); + } +} diff --git a/migration/1622681548499-log-message-length.ts b/migration/1622681548499-log-message-length.ts new file mode 100644 index 0000000000..ef8c33982b --- /dev/null +++ b/migration/1622681548499-log-message-length.ts @@ -0,0 +1,12 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class logMessageLength1622681548499 implements MigrationInterface { + name = 'logMessageLength1622681548499'; + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(2048)`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(1024)`, undefined); + } +} diff --git a/package.json b/package.json index 4f01c78817..a6b0e5e663 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "version": "12.81.2", + "version": "12.83.0", "codename": "indigo", "repository": { "type": "git", @@ -30,10 +30,9 @@ "format": "gulp format" }, "resolutions": { + "mfm-js/twemoji-parser": "13.1.x", "chokidar": "^3.3.1", - "constantinople": "^4.0.1", - "jsonld/rdf-canonize/node-forge": "0.10.0", - "lodash": "^4.17.20" + "lodash": "^4.17.21" }, "dependencies": { "@babel/plugin-transform-runtime": "7.14.3", @@ -43,7 +42,7 @@ "@koa/router": "9.0.1", "@sentry/browser": "5.29.2", "@sentry/tracing": "5.29.2", - "@sinonjs/fake-timers": "7.0.5", + "@sinonjs/fake-timers": "7.1.2", "@syuilo/aiscript": "0.11.1", "@types/bcryptjs": "2.4.2", "@types/bull": "3.15.1", @@ -58,23 +57,23 @@ "@types/jsdom": "16.2.10", "@types/jsonld": "1.5.5", "@types/katex": "0.11.0", - "@types/koa": "2.13.1", - "@types/koa-bodyparser": "4.3.0", + "@types/koa": "2.13.3", + "@types/koa-bodyparser": "4.3.1", "@types/koa-cors": "0.0.0", "@types/koa-favicon": "2.0.19", "@types/koa-logger": "3.1.1", "@types/koa-mount": "4.0.0", "@types/koa-send": "4.1.2", - "@types/koa-views": "2.0.4", + "@types/koa-views": "7.0.0", "@types/koa__cors": "3.0.2", "@types/koa__multer": "2.0.2", "@types/koa__router": "8.0.4", - "@types/markdown-it": "12.0.1", + "@types/markdown-it": "12.0.2", "@types/matter-js": "0.14.12", "@types/mocha": "8.2.2", - "@types/node": "15.3.1", + "@types/node": "15.12.2", "@types/node-fetch": "2.5.10", - "@types/nodemailer": "6.4.1", + "@types/nodemailer": "6.4.2", "@types/nprogress": "0.2.0", "@types/oauth": "0.9.1", "@types/parse5": "6.0.0", @@ -85,12 +84,12 @@ "@types/qrcode": "1.4.0", "@types/random-seed": "0.3.3", "@types/ratelimiter": "3.4.1", - "@types/redis": "2.8.28", + "@types/redis": "2.8.29", "@types/rename": "1.0.3", "@types/request-stats": "3.0.0", "@types/rimraf": "3.0.0", "@types/seedrandom": "2.4.28", - "@types/sharp": "0.28.1", + "@types/sharp": "0.28.3", "@types/sinonjs__fake-timers": "6.0.2", "@types/speakeasy": "2.0.5", "@types/throttle-debounce": "2.1.0", @@ -102,38 +101,38 @@ "@types/webpack-stream": "3.2.12", "@types/websocket": "1.0.2", "@types/ws": "7.4.4", - "@typescript-eslint/parser": "4.24.0", - "@vue/compiler-sfc": "3.0.11", + "@typescript-eslint/parser": "4.26.1", + "@vue/compiler-sfc": "3.1.1", "abort-controller": "3.0.0", - "apexcharts": "3.26.3", + "apexcharts": "3.27.1", "autobind-decorator": "2.4.0", "autosize": "4.0.4", "autwh": "0.1.0", - "aws-sdk": "2.910.0", + "aws-sdk": "2.923.0", "bcryptjs": "2.4.3", "blurhash": "1.1.3", "broadcast-channel": "3.6.0", - "bull": "3.22.6", + "bull": "3.22.7", "cafy": "15.2.1", "cbor": "7.0.5", "chalk": "4.1.1", "chart.js": "2.9.4", "cli-highlight": "2.1.11", "commander": "7.2.0", - "concurrently": "6.1.0", + "concurrently": "6.2.0", "content-disposition": "0.5.3", - "core-js": "3.12.1", + "core-js": "3.14.0", "crc-32": "1.2.0", - "css-loader": "5.2.4", - "cssnano": "5.0.3", + "css-loader": "5.2.6", + "cssnano": "5.0.5", "dateformat": "4.5.1", "diskusage": "1.1.3", "escape-regexp": "0.0.1", - "eslint": "7.26.0", - "eslint-plugin-vue": "7.9.0", + "eslint": "7.28.0", + "eslint-plugin-vue": "7.10.0", "eventemitter3": "4.0.7", "feed": "4.2.2", - "file-type": "16.4.0", + "file-type": "16.5.0", "fluent-ffmpeg": "2.1.2", "glob": "7.1.7", "got": "11.8.2", @@ -148,12 +147,12 @@ "http-proxy-agent": "4.0.1", "http-signature": "1.3.5", "https-proxy-agent": "5.0.0", - "idb-keyval": "5.0.5", + "idb-keyval": "5.0.6", "insert-text-at-cursor": "0.3.0", "is-root": "2.1.0", "is-svg": "4.3.1", "js-yaml": "4.1.0", - "jsdom": "16.5.3", + "jsdom": "16.6.0", "json5": "2.2.0", "json5-loader": "4.0.1", "jsonld": "4.0.1", @@ -173,23 +172,24 @@ "markdown-it": "12.0.6", "markdown-it-anchor": "7.1.0", "matter-js": "0.17.1", - "mfm-js": "0.16.4", + "mfm-js": "0.18.0", + "misskey-js": "0.0.4", "mocha": "8.4.0", "moji": "0.5.1", "ms": "2.1.3", "multer": "1.4.2", "nested-property": "4.0.0", "node-fetch": "2.6.1", - "nodemailer": "6.6.0", + "nodemailer": "6.6.1", "object-assign-deep": "0.4.0", "os-utils": "0.0.14", "parse5": "6.0.1", "pg": "8.6.0", "portscanner": "2.2.0", - "postcss": "8.2.15", + "postcss": "8.3.0", "postcss-loader": "5.3.0", "prismjs": "1.23.0", - "probe-image-size": "7.1.0", + "probe-image-size": "7.2.1", "promise-limit": "2.7.0", "promise-sequential": "1.1.1", "pug": "3.0.2", @@ -210,35 +210,36 @@ "rimraf": "3.0.2", "rndstr": "1.0.0", "s-age": "1.1.2", - "sass": "1.32.13", - "sass-loader": "11.1.1", + "sass": "1.34.1", + "sass-loader": "12.0.0", "seedrandom": "3.0.5", - "sharp": "0.28.2", + "sharp": "0.28.3", "speakeasy": "2.0.0", "stringz": "2.1.0", "style-loader": "2.0.0", "summaly": "2.4.0", "syslog-pro": "1.0.0", - "systeminformation": "5.6.22", + "systeminformation": "5.7.4", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", "three": "0.117.1", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", "tmp": "0.2.1", - "ts-loader": "9.2.1", - "ts-node": "9.1.1", - "tsc-alias": "1.2.11", + "ts-loader": "9.2.3", + "ts-node": "10.0.0", + "tsc-alias": "1.3.2", "tsconfig-paths": "3.9.0", "tslint": "6.1.3", "tslint-sonarts": "1.9.0", + "twemoji-parser": "13.1.0", "typeorm": "0.2.32", - "typescript": "4.2.4", + "typescript": "4.3.2", "ulid": "2.3.0", "uuid": "8.3.2", "v-debounce": "0.1.2", "vanilla-tilt": "1.7.0", - "vue": "3.0.11", + "vue": "3.1.1", "vue-color": "2.8.1", "vue-json-pretty": "1.7.1", "vue-loader": "16.1.2", @@ -248,10 +249,10 @@ "vue-svg-loader": "0.17.0-beta.2", "vuedraggable": "4.0.1", "web-push": "3.4.4", - "webpack": "5.37.1", - "webpack-cli": "4.7.0", + "webpack": "5.38.1", + "webpack-cli": "4.7.2", "websocket": "1.0.34", - "ws": "7.4.5", + "ws": "7.4.6", "xev": "2.0.1" }, "devDependencies": { diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index 34085cc070..6a0c7f29f2 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -1,11 +1,11 @@ + + diff --git a/src/client/components/media-image.vue b/src/client/components/media-image.vue index 267e4debd2..863eb10272 100644 --- a/src/client/components/media-image.vue +++ b/src/client/components/media-image.vue @@ -1,6 +1,6 @@ @@ -29,12 +29,14 @@ import XList from './date-separated-list.vue'; import XNote from './note.vue'; import { notificationTypes } from '../../types'; import * as os from '@client/os'; +import MkButton from '@client/components/ui/button.vue'; export default defineComponent({ components: { XNotification, XList, XNote, + MkButton, }, mixins: [ @@ -88,7 +90,7 @@ export default defineComponent({ }, mounted() { - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('notification', this.onNotification); this.connection.on('readAllNotifications', () => { diff --git a/src/client/components/post-form-attaches.vue b/src/client/components/post-form-attaches.vue index f832ea87b5..27e20fdfa8 100644 --- a/src/client/components/post-form-attaches.vue +++ b/src/client/components/post-form-attaches.vue @@ -89,6 +89,27 @@ export default defineComponent({ file.name = result; }); }, + + async describe(file) { + os.popup(import("@client/components/media-caption.vue"), { + title: this.$ts.describeFile, + input: { + placeholder: this.$ts.inputNewDescription, + default: file.comment !== null ? file.comment : "", + }, + image: file + }, { + done: result => { + if (!result || result.canceled) return; + let comment = result.result; + os.api('drive/files/update', { + fileId: file.id, + comment: comment.length == 0 ? null : comment + }); + } + }, 'closed'); + }, + showFileMenu(file, ev: MouseEvent) { if (this.menu) return; this.menu = os.modalMenu([{ @@ -99,6 +120,10 @@ export default defineComponent({ text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', action: () => { this.toggleSensitive(file) } + }, { + text: this.$ts.describeFile, + icon: 'fas fa-i-cursor', + action: () => { this.describe(file) } }, { text: this.$ts.attachCancel, icon: 'fas fa-times-circle', diff --git a/src/client/components/timeline.vue b/src/client/components/timeline.vue index 753eba2ba1..c21e1ec2a6 100644 --- a/src/client/components/timeline.vue +++ b/src/client/components/timeline.vue @@ -92,33 +92,33 @@ export default defineComponent({ this.query = { antennaId: this.antenna }; - this.connection = os.stream.connectToChannel('antenna', { + this.connection = os.stream.useChannel('antenna', { antennaId: this.antenna }); this.connection.on('note', prepend); } else if (this.src == 'home') { endpoint = 'notes/timeline'; - this.connection = os.stream.useSharedConnection('homeTimeline'); + this.connection = os.stream.useChannel('homeTimeline'); this.connection.on('note', prepend); - this.connection2 = os.stream.useSharedConnection('main'); + this.connection2 = os.stream.useChannel('main'); this.connection2.on('follow', onChangeFollowing); this.connection2.on('unfollow', onChangeFollowing); } else if (this.src == 'local') { endpoint = 'notes/local-timeline'; - this.connection = os.stream.useSharedConnection('localTimeline'); + this.connection = os.stream.useChannel('localTimeline'); this.connection.on('note', prepend); } else if (this.src == 'social') { endpoint = 'notes/hybrid-timeline'; - this.connection = os.stream.useSharedConnection('hybridTimeline'); + this.connection = os.stream.useChannel('hybridTimeline'); this.connection.on('note', prepend); } else if (this.src == 'global') { endpoint = 'notes/global-timeline'; - this.connection = os.stream.useSharedConnection('globalTimeline'); + this.connection = os.stream.useChannel('globalTimeline'); this.connection.on('note', prepend); } else if (this.src == 'mentions') { endpoint = 'notes/mentions'; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', prepend); } else if (this.src == 'directs') { endpoint = 'notes/mentions'; @@ -130,14 +130,14 @@ export default defineComponent({ prepend(note); } }; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', onNote); } else if (this.src == 'list') { endpoint = 'notes/user-list-timeline'; this.query = { listId: this.list }; - this.connection = os.stream.connectToChannel('userList', { + this.connection = os.stream.useChannel('userList', { listId: this.list }); this.connection.on('note', prepend); @@ -148,7 +148,7 @@ export default defineComponent({ this.query = { channelId: this.channel }; - this.connection = os.stream.connectToChannel('channel', { + this.connection = os.stream.useChannel('channel', { channelId: this.channel }); this.connection.on('note', prepend); diff --git a/src/client/init.ts b/src/client/init.ts index c38d3b5314..a0266222b2 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -224,8 +224,6 @@ fetchInstance().then(() => { initializeSw(); }); -stream.init($i); - const app = createApp(await ( window.location.search === '?zen' ? import('@client/ui/zen.vue') : !$i ? import('@client/ui/visitor.vue') : @@ -357,7 +355,7 @@ if ($i) { } } - const main = stream.useSharedConnection('main', 'System'); + const main = stream.useChannel('main', null, 'System'); // 自分の情報が更新されたとき main.on('meUpdated', i => { @@ -419,10 +417,6 @@ if ($i) { sound.play('channel'); }); - main.on('readAllAnnouncements', () => { - updateAccount({ hasUnreadAnnouncement: false }); - }); - // トークンが再生成されたとき // このままではMisskeyが利用できないので強制的にサインアウトさせる main.on('myTokenRegenerated', () => { diff --git a/src/client/instance.ts b/src/client/instance.ts index 024ff1acbd..04d3353208 100644 --- a/src/client/instance.ts +++ b/src/client/instance.ts @@ -1,26 +1,14 @@ import { computed, reactive } from 'vue'; +import * as Misskey from 'misskey-js'; import { api } from './os'; // TODO: 他のタブと永続化されたstateを同期 -export type Instance = { - emojis: { - category: string; - }[]; - ads: { - id: string; - ratio: number; - place: string; - url: string; - imageUrl: string; - }[]; -}; - const data = localStorage.getItem('instance'); // TODO: instanceをリアクティブにするかは再考の余地あり -export const instance: Instance = reactive(data ? JSON.parse(data) : { +export const instance: Misskey.entities.InstanceMetadata = reactive(data ? JSON.parse(data) : { // TODO: set default values }); diff --git a/src/client/os.ts b/src/client/os.ts index b159cf509d..987844b2d2 100644 --- a/src/client/os.ts +++ b/src/client/os.ts @@ -3,16 +3,16 @@ import { Component, defineAsyncComponent, markRaw, reactive, Ref, ref } from 'vue'; import { EventEmitter } from 'eventemitter3'; import insertTextAtCursor from 'insert-text-at-cursor'; +import * as Misskey from 'misskey-js'; import * as Sentry from '@sentry/browser'; -import Stream from '@client/scripts/stream'; -import { apiUrl, debug } from '@client/config'; +import { apiUrl, debug, url } from '@client/config'; import MkPostFormDialog from '@client/components/post-form-dialog.vue'; import MkWaitingDialog from '@client/components/waiting-dialog.vue'; import { resolve } from '@client/router'; import { $i } from '@client/account'; import { defaultStore } from '@client/store'; -export const stream = markRaw(new Stream()); +export const stream = markRaw(new Misskey.Stream(url, $i)); export const pendingApiRequestsCount = ref(0); let apiRequestsCount = 0; // for debug @@ -20,7 +20,11 @@ export const apiRequests = ref([]); // for debug export const windows = new Map(); -export function api(endpoint: string, data: Record = {}, token?: string | null | undefined) { +const apiClient = new Misskey.api.APIClient({ + origin: url, +}); + +export const api = ((endpoint: string, data: Record = {}, token?: string | null | undefined) => { pendingApiRequestsCount.value++; const onFinally = () => { @@ -56,7 +60,7 @@ export function api(endpoint: string, data: Record = {}, token?: st if (res.status === 200) { resolve(body); if (debug) { - log!.res = markRaw(body); + log!.res = markRaw(JSON.parse(JSON.stringify(body))); log!.state = 'success'; } } else if (res.status === 204) { @@ -90,17 +94,15 @@ export function api(endpoint: string, data: Record = {}, token?: st promise.then(onFinally, onFinally); return promise; -} +}) as typeof apiClient.request; -export function apiWithDialog( +export const apiWithDialog = (( endpoint: string, data: Record = {}, token?: string | null | undefined, - onSuccess?: (res: any) => void, - onFailure?: (e: Error) => void, -) { +) => { const promise = api(endpoint, data, token); - promiseDialog(promise, onSuccess, onFailure ? onFailure : (e) => { + promiseDialog(promise, null, (e) => { dialog({ type: 'error', text: e.message + '\n' + (e as any).id, @@ -108,7 +110,7 @@ export function apiWithDialog( }); return promise; -} +}) as typeof api; export function promiseDialog>( promise: T, diff --git a/src/client/pages/instance/metrics.vue b/src/client/pages/instance/metrics.vue index 18cfe5eee2..407cce9e7f 100644 --- a/src/client/pages/instance/metrics.vue +++ b/src/client/pages/instance/metrics.vue @@ -90,7 +90,7 @@ export default defineComponent({ stats: null, serverInfo: null, connection: null, - queueConnection: os.stream.useSharedConnection('queueStats'), + queueConnection: os.stream.useChannel('queueStats'), memUsage: 0, chartCpuMem: null, chartNet: null, @@ -121,7 +121,7 @@ export default defineComponent({ os.api('admin/server-info', {}).then(res => { this.serverInfo = res; - this.connection = os.stream.useSharedConnection('serverStats'); + this.connection = os.stream.useChannel('serverStats'); this.connection.on('stats', this.onStats); this.connection.on('statsLog', this.onStatsLog); this.connection.send('requestLog', { diff --git a/src/client/pages/instance/overview.vue b/src/client/pages/instance/overview.vue index dca2529e1b..cb9cff9fc5 100644 --- a/src/client/pages/instance/overview.vue +++ b/src/client/pages/instance/overview.vue @@ -92,6 +92,7 @@ export default defineComponent({ version, url, stats: null, + meta: null, fetchStats: () => os.api('stats', {}), fetchServerInfo: () => os.api('admin/server-info', {}), fetchJobs: () => os.api('admin/queue/deliver-delayed', {}), diff --git a/src/client/pages/instance/queue.vue b/src/client/pages/instance/queue.vue index 2dccf48d31..8f56fd74bf 100644 --- a/src/client/pages/instance/queue.vue +++ b/src/client/pages/instance/queue.vue @@ -35,7 +35,7 @@ export default defineComponent({ title: this.$ts.jobQueue, icon: 'fas fa-clipboard-list', }, - connection: os.stream.useSharedConnection('queueStats'), + connection: os.stream.useChannel('queueStats'), } }, diff --git a/src/client/pages/instance/settings.vue b/src/client/pages/instance/settings.vue index 66f01c42c7..b68d784897 100644 --- a/src/client/pages/instance/settings.vue +++ b/src/client/pages/instance/settings.vue @@ -19,6 +19,11 @@ {{ $ts.bannerUrl }} + + + {{ $ts.backgroundImageUrl }} + + {{ $ts.tosUrl }} @@ -88,6 +93,7 @@ export default defineComponent({ maintainerEmail: null, iconUrl: null, bannerUrl: null, + backgroundImageUrl: null, maxNoteTextLength: 0, enableLocalTimeline: false, enableGlobalTimeline: false, @@ -106,6 +112,7 @@ export default defineComponent({ this.tosUrl = meta.tosUrl; this.iconUrl = meta.iconUrl; this.bannerUrl = meta.bannerUrl; + this.backgroundImageUrl = meta.backgroundImageUrl; this.maintainerName = meta.maintainerName; this.maintainerEmail = meta.maintainerEmail; this.maxNoteTextLength = meta.maxNoteTextLength; @@ -120,6 +127,7 @@ export default defineComponent({ tosUrl: this.tosUrl, iconUrl: this.iconUrl, bannerUrl: this.bannerUrl, + backgroundImageUrl: this.backgroundImageUrl, maintainerName: this.maintainerName, maintainerEmail: this.maintainerEmail, maxNoteTextLength: this.maxNoteTextLength, diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue index 9f3323f629..832cce5ab9 100644 --- a/src/client/pages/messaging/index.vue +++ b/src/client/pages/messaging/index.vue @@ -63,7 +63,7 @@ export default defineComponent({ }, mounted() { - this.connection = os.stream.useSharedConnection('messagingIndex'); + this.connection = os.stream.useChannel('messagingIndex'); this.connection.on('message', this.onMessage); this.connection.on('read', this.onRead); diff --git a/src/client/pages/messaging/messaging-room.vue b/src/client/pages/messaging/messaging-room.vue index 44bfd6c51d..f1d55ee288 100644 --- a/src/client/pages/messaging/messaging-room.vue +++ b/src/client/pages/messaging/messaging-room.vue @@ -141,7 +141,7 @@ const Component = defineComponent({ this.group = group; } - this.connection = os.stream.connectToChannel('messaging', { + this.connection = os.stream.useChannel('messaging', { otherparty: this.user ? this.user.id : undefined, group: this.group ? this.group.id : undefined, }); diff --git a/src/client/pages/reversi/game.board.vue b/src/client/pages/reversi/game.board.vue index 78bcf03413..0dd36faced 100644 --- a/src/client/pages/reversi/game.board.vue +++ b/src/client/pages/reversi/game.board.vue @@ -350,6 +350,9 @@ export default defineComponent({