Compare commits
9 Commits
0bd44bca6d
...
c803f842ba
Author | SHA1 | Date |
---|---|---|
|
c803f842ba | |
|
b3f8ce60c6 | |
|
04928ba7d1 | |
|
1b3a8cd97d | |
|
bbe26607eb | |
|
6a2dc2d2d2 | |
|
1febae7128 | |
|
2c63ab6fe3 | |
|
96bc042d67 |
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,4 +1,4 @@
|
|||
## Unreleased
|
||||
## 2025.5.1
|
||||
|
||||
### General
|
||||
- Feat: 非ログインでサーバーを閲覧された際に、サーバー内のコンテンツを非公開にすることができるようになりました
|
||||
|
@ -7,14 +7,22 @@
|
|||
- デフォルト値は「ローカルのコンテンツだけ公開」になっています
|
||||
|
||||
### Client
|
||||
- Feat: サーバー初期設定ウィザードが実装されました
|
||||
- 簡単なウィザードに従うだけで、サーバーに最適な設定が適用されます
|
||||
- Feat: Websocket接続を行わずにMisskeyを利用するNo Websocketモードが実装されました(beta)
|
||||
- サーバーのパフォーマンス向上に寄与することが期待されます
|
||||
- 何らの理由によりWebsocket接続が行えない環境でも快適に利用可能です
|
||||
- 従来のWebsocket接続を行うモードはリアルタイムモードとして再定義されました
|
||||
- チャットなど、一部の機能は引き続き設定に関わらずWebsocket接続が行われます
|
||||
- Enhance: メモリ使用量を軽減しました
|
||||
- Enhance: リプライ元にアンケートがあることが表示されるように
|
||||
- Enhance: ノートのサーバー情報のデザインを改善・パフォーマンス向上
|
||||
(Based on https://github.com/taiyme/misskey/pull/198, https://github.com/taiyme/misskey/pull/211, https://github.com/taiyme/misskey/pull/283)
|
||||
- Fix: "時計"ウィジェット(Clock)において、Transparent設定が有効でも、その背景が透過されない問題を修正
|
||||
|
||||
### Server
|
||||
- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加
|
||||
- Fix: チャットルームが削除された場合・チャットルームから抜けた場合に、未読状態が残り続けることがあるのを修正
|
||||
- Fix: ユーザ除外アンテナをインポートできない問題を修正
|
||||
- Fix: アンテナのセンシティブなチャンネルのノートを含むかどうかの情報がエクスポートされない問題を修正
|
||||
|
||||
|
|
|
@ -2,11 +2,6 @@ import { defineConfig } from 'cypress'
|
|||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
baseUrl: 'http://localhost:61812',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -31,6 +31,15 @@ describe('Before setup instance', () => {
|
|||
// なぜか動かない
|
||||
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
||||
cy.wait('@signup');
|
||||
|
||||
cy.intercept('POST', '/api/admin/update-meta').as('update-meta');
|
||||
|
||||
cy.get('[data-cy-next]').click();
|
||||
cy.get('[data-cy-next]').click();
|
||||
cy.get('[data-cy-server-name] input').type('Testskey');
|
||||
cy.get('[data-cy-server-setup-wizard-apply]').click();
|
||||
|
||||
cy.wait('@update-meta');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
|
@ -215,7 +215,6 @@ noUsers: "ليس هناك مستخدمون"
|
|||
editProfile: "تعديل الملف التعريفي"
|
||||
noteDeleteConfirm: "هل تريد حذف هذه الملاحظة؟"
|
||||
pinLimitExceeded: "لا يمكنك تثبيت الملاحظات بعد الآن."
|
||||
intro: "لقد انتهت عملية تنصيب Misskey. الرجاء إنشاء حساب إداري."
|
||||
done: "تمّ"
|
||||
processing: "المعالجة جارية"
|
||||
preview: "معاينة"
|
||||
|
@ -676,7 +675,6 @@ experimental: "اختباري"
|
|||
developer: "المطور"
|
||||
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
||||
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
||||
showGapBetweenNotesInTimeline: "أظهر فجوات بين المشاركات في الخيط الزمني"
|
||||
left: "يسار"
|
||||
center: "وسط"
|
||||
wide: "عريض"
|
||||
|
|
|
@ -215,7 +215,6 @@ noUsers: "কোন ব্যাবহারকারী নেই"
|
|||
editProfile: "প্রোফাইল সম্পাদনা করুন"
|
||||
noteDeleteConfirm: "আপনি কি নোট ডিলিট করার ব্যাপারে নিশ্চিত?"
|
||||
pinLimitExceeded: "আপনি আর কোন নোট পিন করতে পারবেন না"
|
||||
intro: "Misskey এর ইন্সটলেশন সম্পন্ন হয়েছে!দয়া করে অ্যাডমিন ইউজার তৈরি করুন।"
|
||||
done: "সম্পন্ন"
|
||||
processing: "প্রক্রিয়াধীন..."
|
||||
preview: "পূর্বরূপ দেখুন"
|
||||
|
@ -673,7 +672,6 @@ experimentalFeatures: "পরীক্ষামূলক বৈশিষ্ট
|
|||
developer: "ডেভেলপার"
|
||||
makeExplorable: "অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় দেখান"
|
||||
makeExplorableDescription: "আপনি এটি বন্ধ করলে, আপনার অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় প্রদর্শিত হবে না।"
|
||||
showGapBetweenNotesInTimeline: "টাইমলাইন এবং নোটের মাঝে ফাকা জায়গা রাখুন"
|
||||
duplicate: "প্রতিরূপ"
|
||||
left: "বাম"
|
||||
center: "মাঝখান"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "No hi ha usuaris"
|
|||
editProfile: "Edita el perfil"
|
||||
noteDeleteConfirm: "Segur que voleu eliminar aquesta publicació?"
|
||||
pinLimitExceeded: "No podeu fixar més publicacions"
|
||||
intro: "La instal·lació de Misskey ha acabat! Crea un usuari d'administrador."
|
||||
done: "Fet"
|
||||
processing: "S'està processant..."
|
||||
preview: "Vista prèvia"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "Aquesta és una característica experimental. La sev
|
|||
developer: "Programador"
|
||||
makeExplorable: "Fes que el compte sigui visible a la secció \"Explorar\""
|
||||
makeExplorableDescription: "Si desactives aquesta opció, el teu compte no sortirà a la secció \"Explorar\""
|
||||
showGapBetweenNotesInTimeline: "Notes separades a la línia de temps"
|
||||
duplicate: "Duplicat"
|
||||
left: "Esquerra"
|
||||
center: "Centre"
|
||||
|
@ -1238,7 +1236,6 @@ showAvatarDecorations: "Mostrar les decoracions dels avatars"
|
|||
releaseToRefresh: "Deixar anar per actualitzar"
|
||||
refreshing: "Recarregant..."
|
||||
pullDownToRefresh: "Llisca cap a baix per recarregar"
|
||||
disableStreamingTimeline: "Desactivar l'actualització en temps real de les línies de temps"
|
||||
useGroupedNotifications: "Mostrar les notificacions agrupades "
|
||||
signupPendingError: "Hi ha hagut un problema verificant l'adreça de correu electrònic. L'enllaç pot haver caducat."
|
||||
cwNotationRequired: "Si està activat \"Amagar contingut\" s'ha d'escriure una descripció "
|
||||
|
@ -1434,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Nom del perfil"
|
||||
profileNameDescription: "Estableix un nom que identifiqui aquest dispositiu."
|
||||
profileNameDescription2: "Per exemple: \"PC Principal\", \"Smartphone\", etc"
|
||||
manageProfiles: "Gestionar perfils"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Còpia de seguretat automàtica "
|
||||
restoreFromBackup: "Restaurar des d'una còpia de seguretat"
|
||||
|
|
|
@ -228,7 +228,6 @@ noUsers: "Žádní uživatelé"
|
|||
editProfile: "Upravit můj profil"
|
||||
noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?"
|
||||
pinLimitExceeded: "Nemůžete připnout další poznámky."
|
||||
intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina."
|
||||
done: "Hotovo"
|
||||
processing: "Zpracovávám"
|
||||
preview: "Náhled"
|
||||
|
@ -726,7 +725,6 @@ thisIsExperimentalFeature: "Tohle je experimentální funkce. Její funkce se m
|
|||
developer: "Vývojář"
|
||||
makeExplorable: "Udělat účet viditelný v \"Objevit\""
|
||||
makeExplorableDescription: "Pokud tohle vypnete, tak se účet přestane zobrazovat v sekci \"Objevit\"."
|
||||
showGapBetweenNotesInTimeline: "Zobrazit mezeru mezi příspěvkama na časové ose"
|
||||
duplicate: "Duplikovat"
|
||||
left: "Vlevo"
|
||||
center: "Uprostřed"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "Keine Benutzer gefunden"
|
|||
editProfile: "Profil bearbeiten"
|
||||
noteDeleteConfirm: "Möchtest du diese Notiz wirklich löschen?"
|
||||
pinLimitExceeded: "Du kannst nicht noch mehr Notizen anheften."
|
||||
intro: "Misskey ist installiert! Lass uns nun ein Administratorkonto einrichten."
|
||||
done: "Fertig"
|
||||
processing: "In Bearbeitung …"
|
||||
preview: "Vorschau"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "Dies ist eine experimentelle Funktion. Änderungen a
|
|||
developer: "Entwickler"
|
||||
makeExplorable: "Benutzerkonto in „Erkunden“ sichtbar machen"
|
||||
makeExplorableDescription: "Wenn diese Option deaktiviert ist, ist dein Benutzerkonto nicht im „Erkunden“-Bereich sichtbar."
|
||||
showGapBetweenNotesInTimeline: "Abstände zwischen Notizen auf der Chronik anzeigen"
|
||||
duplicate: "Duplizieren"
|
||||
left: "Links"
|
||||
center: "Mittig"
|
||||
|
@ -1238,7 +1236,6 @@ showAvatarDecorations: "Profilbilddekoration anzeigen"
|
|||
releaseToRefresh: "Zum Aktualisieren loslassen"
|
||||
refreshing: "Wird aktualisiert..."
|
||||
pullDownToRefresh: "Zum Aktualisieren ziehen"
|
||||
disableStreamingTimeline: "Echtzeitaktualisierung der Chronik deaktivieren"
|
||||
useGroupedNotifications: "Benachrichtigungen gruppieren"
|
||||
signupPendingError: "Beim Überprüfen der Mailadresse ist etwas schiefgelaufen. Der Link könnte abgelaufen sein."
|
||||
cwNotationRequired: "Ist \"Inhaltswarnung verwenden\" aktiviert, muss eine Beschreibung gegeben werden."
|
||||
|
@ -1434,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Profilname"
|
||||
profileNameDescription: "Lege einen Namen fest, der dieses Gerät identifiziert."
|
||||
profileNameDescription2: "Beispiel: \"Haupt-PC\", \"Smartphone\""
|
||||
manageProfiles: "Profile verwalten"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Automatische Sicherung"
|
||||
restoreFromBackup: "Wiederherstellen aus der Sicherung"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "There are no users"
|
|||
editProfile: "Edit profile"
|
||||
noteDeleteConfirm: "Are you sure you want to delete this note?"
|
||||
pinLimitExceeded: "You cannot pin any more notes"
|
||||
intro: "Installation of Misskey has been finished! Please create an admin user."
|
||||
done: "Done"
|
||||
processing: "Processing..."
|
||||
preview: "Preview"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "This is an experimental feature. Its functionality i
|
|||
developer: "Developer"
|
||||
makeExplorable: "Make account visible in \"Explore\""
|
||||
makeExplorableDescription: "If you turn this off, your account will not show up in the \"Explore\" section."
|
||||
showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline"
|
||||
duplicate: "Duplicate"
|
||||
left: "Left"
|
||||
center: "Center"
|
||||
|
@ -1238,7 +1236,6 @@ showAvatarDecorations: "Show avatar decorations"
|
|||
releaseToRefresh: "Release to refresh"
|
||||
refreshing: "Refreshing..."
|
||||
pullDownToRefresh: "Pull down to refresh"
|
||||
disableStreamingTimeline: "Disable real-time timeline updates"
|
||||
useGroupedNotifications: "Display grouped notifications"
|
||||
signupPendingError: "There was a problem verifying the email address. The link may have expired."
|
||||
cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided."
|
||||
|
@ -1434,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "Profile name"
|
||||
profileNameDescription: "Set a name that identifies this device."
|
||||
profileNameDescription2: "Example: \"Main PC\", \"Smartphone\""
|
||||
manageProfiles: "Manage Profiles"
|
||||
_preferencesBackup:
|
||||
autoBackup: "Auto backup"
|
||||
restoreFromBackup: "Restore from backup"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "No hay usuarios"
|
|||
editProfile: "Editar perfil"
|
||||
noteDeleteConfirm: "¿Desea borrar esta nota?"
|
||||
pinLimitExceeded: "Ya no se pueden fijar más posts"
|
||||
intro: "¡La instalación de Misskey ha terminado! Crea el usuario administrador."
|
||||
done: "Terminado"
|
||||
processing: "Procesando"
|
||||
preview: "Vista previa"
|
||||
|
@ -784,7 +783,6 @@ thisIsExperimentalFeature: "Se trata de una función experimental. Las especific
|
|||
developer: "Desarrolladores"
|
||||
makeExplorable: "Hacer visible la cuenta en \"Explorar\""
|
||||
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"."
|
||||
showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo"
|
||||
duplicate: "Duplicar"
|
||||
left: "Izquierda"
|
||||
center: "Centrar"
|
||||
|
@ -1237,7 +1235,6 @@ showAvatarDecorations: "Mostrar decoraciones de avatar"
|
|||
releaseToRefresh: "Soltar para recargar"
|
||||
refreshing: "Recargando..."
|
||||
pullDownToRefresh: "Tira hacia abajo para recargar"
|
||||
disableStreamingTimeline: "Desactivar actualizaciones en tiempo real de la línea de tiempo"
|
||||
useGroupedNotifications: "Mostrar notificaciones agrupadas"
|
||||
signupPendingError: "Ha habido un problema al verificar tu dirección de correo electrónico. Es posible que el enlace haya caducado."
|
||||
cwNotationRequired: "Si se ha activado \"ocultar contenido\", es necesario proporcionar una descripción."
|
||||
|
|
|
@ -238,7 +238,6 @@ noUsers: "Il n’y a pas d’utilisateur·rice·s"
|
|||
editProfile: "Modifier votre profil"
|
||||
noteDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note ?"
|
||||
pinLimitExceeded: "Vous ne pouvez plus épingler d’autres notes."
|
||||
intro: "L’installation de Misskey est terminée ! Veuillez créer un compte administrateur."
|
||||
done: "Terminé"
|
||||
processing: "Traitement en cours"
|
||||
preview: "Aperçu"
|
||||
|
@ -760,7 +759,6 @@ thisIsExperimentalFeature: "Ceci est une fonctionnalité expérimentale. Il y a
|
|||
developer: "Développeur"
|
||||
makeExplorable: "Rendre le compte visible sur la page \"Découvrir\"."
|
||||
makeExplorableDescription: "Si vous désactivez cette option, votre compte n'apparaîtra pas sur la page \"Découvrir\"."
|
||||
showGapBetweenNotesInTimeline: "Afficher un écart entre les notes sur la Timeline"
|
||||
duplicate: "Duliquer"
|
||||
left: "Gauche"
|
||||
center: "Centrer"
|
||||
|
@ -1209,7 +1207,6 @@ showAvatarDecorations: "Afficher les décorations d'avatar"
|
|||
releaseToRefresh: "Relâcher pour rafraîchir"
|
||||
refreshing: "Rafraîchissement..."
|
||||
pullDownToRefresh: "Tirer vers le bas pour rafraîchir"
|
||||
disableStreamingTimeline: "Désactiver les mises à jour en temps réel de la ligne du temps"
|
||||
useGroupedNotifications: "Grouper les notifications"
|
||||
signupPendingError: "Un problème est survenu lors de la vérification de votre adresse e-mail. Le lien a peut-être expiré."
|
||||
cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie."
|
||||
|
|
|
@ -241,7 +241,6 @@ noUsers: "Tidak ada pengguna"
|
|||
editProfile: "Sunting profil"
|
||||
noteDeleteConfirm: "Apakah kamu yakin ingin menghapus catatan ini?"
|
||||
pinLimitExceeded: "Kamu tidak dapat menyematkan catatan lagi"
|
||||
intro: "Instalasi Misskey telah selesai! Mohon untuk membuat pengguna admin."
|
||||
done: "Selesai"
|
||||
processing: "Memproses"
|
||||
preview: "Pratinjau"
|
||||
|
@ -761,7 +760,6 @@ thisIsExperimentalFeature: "Fitur ini eksperimental. Fungsionalitas dari fitur i
|
|||
developer: "Pengembang"
|
||||
makeExplorable: "Buat akun tampil di \"Jelajahi\""
|
||||
makeExplorableDescription: "Jika kamu mematikan ini, akun kamu tidak akan muncul di menu \"Jelajahi\""
|
||||
showGapBetweenNotesInTimeline: "Tampilkan jarak diantara catatan pada lini masa"
|
||||
duplicate: "Duplikat"
|
||||
left: "Kiri"
|
||||
center: "Tengah"
|
||||
|
@ -1206,7 +1204,6 @@ showAvatarDecorations: "Tampilkan dekorasi avatar"
|
|||
releaseToRefresh: "Lepaskan untuk memuat ulang"
|
||||
refreshing: "Sedang memuat ulang..."
|
||||
pullDownToRefresh: "Tarik ke bawah untuk memuat ulang"
|
||||
disableStreamingTimeline: "Nonaktifkan pembaharuan lini masa real-time"
|
||||
useGroupedNotifications: "Tampilkan notifikasi secara dikelompokkan"
|
||||
signupPendingError: "Terdapat masalah ketika memverifikasi alamat surel. Tautan kemungkinan telah kedaluwarsa."
|
||||
cwNotationRequired: "Jika \"Sembunyikan konten\" diaktifkan, deskripsi harus disediakan."
|
||||
|
|
|
@ -1022,10 +1022,6 @@ export interface Locale extends ILocale {
|
|||
* これ以上ピン留めできません
|
||||
*/
|
||||
"pinLimitExceeded": string;
|
||||
/**
|
||||
* Misskeyのインストールが完了しました!管理者アカウントを作成しましょう。
|
||||
*/
|
||||
"intro": string;
|
||||
/**
|
||||
* 完了
|
||||
*/
|
||||
|
@ -5413,6 +5409,10 @@ export interface Locale extends ILocale {
|
|||
* スクロールして閉じる
|
||||
*/
|
||||
"scrollToClose": string;
|
||||
/**
|
||||
* アドバイス
|
||||
*/
|
||||
"advice": string;
|
||||
/**
|
||||
* リアルタイムモード
|
||||
*/
|
||||
|
@ -6412,6 +6412,14 @@ export interface Locale extends ILocale {
|
|||
* 脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。
|
||||
*/
|
||||
"deliverSuspendedSoftwareDescription": string;
|
||||
/**
|
||||
* お一人様モード
|
||||
*/
|
||||
"singleUserMode": string;
|
||||
/**
|
||||
* このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。
|
||||
*/
|
||||
"singleUserMode_description": string;
|
||||
/**
|
||||
* 非利用者に対するユーザー作成コンテンツの公開範囲
|
||||
*/
|
||||
|
@ -11670,6 +11678,166 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"serverHostPlaceholder": string;
|
||||
};
|
||||
"_serverSetupWizard": {
|
||||
/**
|
||||
* Misskeyのインストールが完了しました!
|
||||
*/
|
||||
"installCompleted": string;
|
||||
/**
|
||||
* まずは、管理者アカウントを作成しましょう。
|
||||
*/
|
||||
"firstCreateAccount": string;
|
||||
/**
|
||||
* 管理者アカウントが作成されました!
|
||||
*/
|
||||
"accountCreated": string;
|
||||
/**
|
||||
* サーバーの設定
|
||||
*/
|
||||
"serverSetting": string;
|
||||
/**
|
||||
* このウィザードで簡単に最適なサーバーの設定が行えます。
|
||||
*/
|
||||
"youCanEasilyConfigureOptimalServerSettingsWithThisWizard": string;
|
||||
/**
|
||||
* ここでの設定は、あとからでも変更できます。
|
||||
*/
|
||||
"settingsYouMakeHereCanBeChangedLater": string;
|
||||
/**
|
||||
* Misskeyをどのように使いますか?
|
||||
*/
|
||||
"howWillYouUseMisskey": string;
|
||||
"_use": {
|
||||
/**
|
||||
* お一人様サーバー
|
||||
*/
|
||||
"single": string;
|
||||
/**
|
||||
* 自分専用のサーバーとして、一人で使う
|
||||
*/
|
||||
"single_description": string;
|
||||
/**
|
||||
* お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。
|
||||
*/
|
||||
"single_youCanCreateMultipleAccounts": string;
|
||||
/**
|
||||
* グループサーバー
|
||||
*/
|
||||
"group": string;
|
||||
/**
|
||||
* 信頼できる他の利用者を招待して、複数人で使う
|
||||
*/
|
||||
"group_description": string;
|
||||
/**
|
||||
* オープンサーバー
|
||||
*/
|
||||
"open": string;
|
||||
/**
|
||||
* 不特定多数の利用者を受け入れる運営を行う
|
||||
*/
|
||||
"open_description": string;
|
||||
};
|
||||
/**
|
||||
* 不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。
|
||||
*/
|
||||
"openServerAdvice": string;
|
||||
/**
|
||||
* 自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。
|
||||
*/
|
||||
"openServerAntiSpamAdvice": string;
|
||||
/**
|
||||
* どれくらいの人数を想定していますか?
|
||||
*/
|
||||
"howManyUsersDoYouExpect": string;
|
||||
"_scale": {
|
||||
/**
|
||||
* 100人以下 (小規模)
|
||||
*/
|
||||
"small": string;
|
||||
/**
|
||||
* 100人以上1000人以下 (中規模)
|
||||
*/
|
||||
"medium": string;
|
||||
/**
|
||||
* 1000人以上 (大規模)
|
||||
*/
|
||||
"large": string;
|
||||
};
|
||||
/**
|
||||
* 大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。
|
||||
*/
|
||||
"largeScaleServerAdvice": string;
|
||||
/**
|
||||
* Fediverseと接続しますか?
|
||||
*/
|
||||
"doYouConnectToFediverse": string;
|
||||
/**
|
||||
* 分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。
|
||||
*/
|
||||
"doYouConnectToFediverse_description1": string;
|
||||
/**
|
||||
* Fediverseと接続することは「連合」とも呼ばれます。
|
||||
*/
|
||||
"doYouConnectToFediverse_description2": string;
|
||||
/**
|
||||
* 連合可能なサーバーの指定など、高度な設定も後ほど可能です。
|
||||
*/
|
||||
"youCanConfigureMoreFederationSettingsLater": string;
|
||||
/**
|
||||
* 管理者情報
|
||||
*/
|
||||
"adminInfo": string;
|
||||
/**
|
||||
* 問い合わせを受け付けるために使用される管理者情報を設定します。
|
||||
*/
|
||||
"adminInfo_description": string;
|
||||
/**
|
||||
* オープンサーバー、または連合がオンの場合は必ず入力が必要です。
|
||||
*/
|
||||
"adminInfo_mustBeFilled": string;
|
||||
/**
|
||||
* 以下の設定が推奨されます
|
||||
*/
|
||||
"followingSettingsAreRecommended": string;
|
||||
/**
|
||||
* この設定を適用
|
||||
*/
|
||||
"applyTheseSettings": string;
|
||||
/**
|
||||
* 設定をスキップ
|
||||
*/
|
||||
"skipSettings": string;
|
||||
/**
|
||||
* 設定が完了しました!
|
||||
*/
|
||||
"settingsCompleted": string;
|
||||
/**
|
||||
* お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。
|
||||
*/
|
||||
"settingsCompleted_description": string;
|
||||
/**
|
||||
* 詳細なサーバー設定は、「コントロールパネル」から行えます。
|
||||
*/
|
||||
"settingsCompleted_description2": string;
|
||||
/**
|
||||
* 寄付のお願い
|
||||
*/
|
||||
"donationRequest": string;
|
||||
"_donationRequest": {
|
||||
/**
|
||||
* Misskeyは有志によって開発されている無料のソフトウェアです。
|
||||
*/
|
||||
"text1": string;
|
||||
/**
|
||||
* 今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。
|
||||
*/
|
||||
"text2": string;
|
||||
/**
|
||||
* 支援者向け特典もあります!
|
||||
*/
|
||||
"text3": string;
|
||||
};
|
||||
};
|
||||
}
|
||||
declare const locales: {
|
||||
[lang: string]: Locale;
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Non ci sono profili"
|
|||
editProfile: "Modifica profilo"
|
||||
noteDeleteConfirm: "Vuoi davvero eliminare questa Nota?"
|
||||
pinLimitExceeded: "Non puoi fissare altre note "
|
||||
intro: "L'installazione di Misskey è terminata! Si prega di creare il profilo amministratore."
|
||||
done: "Fine"
|
||||
processing: "In elaborazione"
|
||||
preview: "Anteprima"
|
||||
|
@ -784,7 +783,6 @@ thisIsExperimentalFeature: "Questa è una funzionalità sperimentale. Potrebbe e
|
|||
developer: "Sviluppatore"
|
||||
makeExplorable: "Profilo visibile pubblicamente nella pagina \"Esplora\""
|
||||
makeExplorableDescription: "Disabilitando questa opzione, il tuo profilo non verrà elencato nella pagina \"Esplora\"."
|
||||
showGapBetweenNotesInTimeline: "Mostrare un intervallo tra le note sulla timeline"
|
||||
duplicate: "Duplica"
|
||||
left: "Sinistra"
|
||||
center: "Centro"
|
||||
|
@ -1237,7 +1235,6 @@ showAvatarDecorations: "Mostra decorazione della foto profilo"
|
|||
releaseToRefresh: "Rilascia per aggiornare"
|
||||
refreshing: "Aggiornamento..."
|
||||
pullDownToRefresh: "Trascinare per aggiornare"
|
||||
disableStreamingTimeline: "Disabilitare gli aggiornamenti della TL in tempo reale"
|
||||
useGroupedNotifications: "Mostra le notifiche raggruppate"
|
||||
signupPendingError: "Si è verificato un problema durante la verifica del tuo indirizzo email. Potrebbe essere scaduto il collegamento temporaneo."
|
||||
cwNotationRequired: "Devi indicare perché il contenuto è indicato come esplicito."
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "ユーザーはいません"
|
|||
editProfile: "プロフィールを編集"
|
||||
noteDeleteConfirm: "このノートを削除しますか?"
|
||||
pinLimitExceeded: "これ以上ピン留めできません"
|
||||
intro: "Misskeyのインストールが完了しました!管理者アカウントを作成しましょう。"
|
||||
done: "完了"
|
||||
processing: "処理中"
|
||||
preview: "プレビュー"
|
||||
|
@ -1348,6 +1347,7 @@ goToDeck: "デッキへ戻る"
|
|||
federationJobs: "連合ジョブ"
|
||||
driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。<br>\nノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。<br>\n<b>ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。</b><br>\nフォルダを作って整理することもできます。"
|
||||
scrollToClose: "スクロールして閉じる"
|
||||
advice: "アドバイス"
|
||||
realtimeMode: "リアルタイムモード"
|
||||
turnItOn: "オンにする"
|
||||
turnItOff: "オフにする"
|
||||
|
@ -1629,6 +1629,8 @@ _serverSettings:
|
|||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "一定期間モデレーターのアクティビティが検出されなかった場合、スパム防止のためこの設定は自動でオフになります。"
|
||||
deliverSuspendedSoftware: "配信停止中のソフトウェア"
|
||||
deliverSuspendedSoftwareDescription: "脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。"
|
||||
singleUserMode: "お一人様モード"
|
||||
singleUserMode_description: "このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。"
|
||||
userGeneratedContentsVisibilityForVisitor: "非利用者に対するユーザー作成コンテンツの公開範囲"
|
||||
userGeneratedContentsVisibilityForVisitor_description: "モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます。"
|
||||
userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。"
|
||||
|
@ -3121,3 +3123,46 @@ _search:
|
|||
pleaseEnterServerHost: "サーバーのホストを入力してください"
|
||||
pleaseSelectUser: "ユーザーを選択してください"
|
||||
serverHostPlaceholder: "例: misskey.example.com"
|
||||
|
||||
_serverSetupWizard:
|
||||
installCompleted: "Misskeyのインストールが完了しました!"
|
||||
firstCreateAccount: "まずは、管理者アカウントを作成しましょう。"
|
||||
accountCreated: "管理者アカウントが作成されました!"
|
||||
serverSetting: "サーバーの設定"
|
||||
youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "このウィザードで簡単に最適なサーバーの設定が行えます。"
|
||||
settingsYouMakeHereCanBeChangedLater: "ここでの設定は、あとからでも変更できます。"
|
||||
howWillYouUseMisskey: "Misskeyをどのように使いますか?"
|
||||
_use:
|
||||
single: "お一人様サーバー"
|
||||
single_description: "自分専用のサーバーとして、一人で使う"
|
||||
single_youCanCreateMultipleAccounts: "お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。"
|
||||
group: "グループサーバー"
|
||||
group_description: "信頼できる他の利用者を招待して、複数人で使う"
|
||||
open: "オープンサーバー"
|
||||
open_description: "不特定多数の利用者を受け入れる運営を行う"
|
||||
openServerAdvice: "不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。"
|
||||
openServerAntiSpamAdvice: "自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。"
|
||||
howManyUsersDoYouExpect: "どれくらいの人数を想定していますか?"
|
||||
_scale:
|
||||
small: "100人以下 (小規模)"
|
||||
medium: "100人以上1000人以下 (中規模)"
|
||||
large: "1000人以上 (大規模)"
|
||||
largeScaleServerAdvice: "大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。"
|
||||
doYouConnectToFediverse: "Fediverseと接続しますか?"
|
||||
doYouConnectToFediverse_description1: "分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。"
|
||||
doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれます。"
|
||||
youCanConfigureMoreFederationSettingsLater: "連合可能なサーバーの指定など、高度な設定も後ほど可能です。"
|
||||
adminInfo: "管理者情報"
|
||||
adminInfo_description: "問い合わせを受け付けるために使用される管理者情報を設定します。"
|
||||
adminInfo_mustBeFilled: "オープンサーバー、または連合がオンの場合は必ず入力が必要です。"
|
||||
followingSettingsAreRecommended: "以下の設定が推奨されます"
|
||||
applyTheseSettings: "この設定を適用"
|
||||
skipSettings: "設定をスキップ"
|
||||
settingsCompleted: "設定が完了しました!"
|
||||
settingsCompleted_description: "お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。"
|
||||
settingsCompleted_description2: "詳細なサーバー設定は、「コントロールパネル」から行えます。"
|
||||
donationRequest: "寄付のお願い"
|
||||
_donationRequest:
|
||||
text1: "Misskeyは有志によって開発されている無料のソフトウェアです。"
|
||||
text2: "今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。"
|
||||
text3: "支援者向け特典もあります!"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "ユーザーはおらん"
|
|||
editProfile: "プロフィールをいじる"
|
||||
noteDeleteConfirm: "このノートをほかしてええか?"
|
||||
pinLimitExceeded: "これ以上ピン留めできひん"
|
||||
intro: "Misskeyのインストールが完了したで!管理者アカウントを作ってや。"
|
||||
done: "でけた"
|
||||
processing: "処理しとる"
|
||||
preview: "プレビュー"
|
||||
|
@ -781,7 +780,6 @@ thisIsExperimentalFeature: "これは実験的な機能やから、仕様が変
|
|||
developer: "開発者やで"
|
||||
makeExplorable: "アカウントを見つけやすくするで"
|
||||
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らんくなるで。"
|
||||
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示するで"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "真ん中"
|
||||
|
@ -1233,7 +1231,6 @@ showAvatarDecorations: "アイコンのデコレーション映す"
|
|||
releaseToRefresh: "離したらリロード"
|
||||
refreshing: "リロードしとる"
|
||||
pullDownToRefresh: "引っ張ってリロードするで"
|
||||
disableStreamingTimeline: "タイムラインのリアルタイム更新をやめるで"
|
||||
useGroupedNotifications: "通知をグループ分けして出すで"
|
||||
signupPendingError: "メアド確認してたらなんか変なことなったわ。リンクの期限切れてるかもしれん。"
|
||||
cwNotationRequired: "「内容を隠す」んやったら注釈書かなアカンで。"
|
||||
|
|
|
@ -224,7 +224,6 @@ noUsers: "사용자가 어ᇝ십니다"
|
|||
editProfile: "프로필 적기"
|
||||
noteDeleteConfirm: "요 노트럴 뭉캡니꺼?"
|
||||
pinLimitExceeded: "더 몬 붙입니다"
|
||||
intro: "Misskey럴 다 깔앗십니다! 간리자 게정얼 맨걸어 보입시다."
|
||||
done: "햇어예"
|
||||
processing: "처리하고 잇어예"
|
||||
preview: "미리보기"
|
||||
|
|
|
@ -220,6 +220,7 @@ silenceThisInstance: "서버를 사일런스"
|
|||
mediaSilenceThisInstance: "서버의 미디어를 사일런스"
|
||||
operations: "작업"
|
||||
software: "소프트웨어"
|
||||
softwareName: "소프트웨어 이름"
|
||||
version: "버전"
|
||||
metadata: "메타데이터"
|
||||
withNFiles: "{n}개의 파일"
|
||||
|
@ -250,7 +251,6 @@ noUsers: "아무도 없습니다"
|
|||
editProfile: "프로필 수정"
|
||||
noteDeleteConfirm: "이 노트를 삭제하시겠습니까?"
|
||||
pinLimitExceeded: "더 이상 고정할 수 없습니다."
|
||||
intro: "Misskey의 설치가 완료되었습니다! 관리자 계정을 생성해주세요."
|
||||
done: "완료"
|
||||
processing: "처리중"
|
||||
preview: "미리보기"
|
||||
|
@ -784,7 +784,6 @@ thisIsExperimentalFeature: "이 기능은 실험적인 기능입니다. 사양
|
|||
developer: "개발자"
|
||||
makeExplorable: "계정을 쉽게 발견하도록 하기"
|
||||
makeExplorableDescription: "비활성화하면 \"발견하기\"에 나의 계정을 표시하지 않습니다."
|
||||
showGapBetweenNotesInTimeline: "타임라인의 노트 사이를 띄워서 표시"
|
||||
duplicate: "복제"
|
||||
left: "왼쪽"
|
||||
center: "가운데"
|
||||
|
@ -1237,7 +1236,6 @@ showAvatarDecorations: "아바타 장식 표시"
|
|||
releaseToRefresh: "놓아서 새로고침"
|
||||
refreshing: "새로고침 중"
|
||||
pullDownToRefresh: "아래로 내려서 새로고침"
|
||||
disableStreamingTimeline: "타임라인의 실시간 갱신을 무효화하기"
|
||||
useGroupedNotifications: "알림을 그룹화하고 표시"
|
||||
signupPendingError: "메일 주소 확인중에 문제가 발생했습니다. 링크의 유효기간이 지났을 가능성이 있습니다."
|
||||
cwNotationRequired: "'내용을 숨기기'를 체크한 경우 주석을 써야 합니다."
|
||||
|
@ -1346,6 +1344,8 @@ settingsMigrating: "설정을 이전하는 중입니다. 잠시 기다려주십
|
|||
readonly: "읽기 전용"
|
||||
goToDeck: "덱으로 돌아가기"
|
||||
federationJobs: "연합 작업"
|
||||
driveAboutTip: "드라이브는 이전에 업로드한 파일 목록을 표시해요. <br>\n노트에 첨부할 때 다시 사용하거나 나중에 게시할 파일을 미리 업로드할 수 있어요. <br>\n<b>파일을 삭제하면, 지금까지 그 파일을 사용한 모든 장소(노트, 페이지, 아바타, 배너 등)에서도 보이지 않게 되므로 주의해 주세요. 폴더를 만들고 정리할 수도 있어요.</b><br>"
|
||||
scrollToClose: "스크롤하여 닫기"
|
||||
_chat:
|
||||
noMessagesYet: "아직 메시지가 없습니다"
|
||||
newMessage: "새로운 메시지"
|
||||
|
@ -1422,6 +1422,8 @@ _settings:
|
|||
ifOn: "켜져 있을 때"
|
||||
ifOff: "꺼져 있을 때"
|
||||
enableSyncThemesBetweenDevices: "기기 간 설치한 테마 동기화"
|
||||
enablePullToRefresh: "계속해서 갱신"
|
||||
enablePullToRefresh_description: "마우스에서 휠을 누르면서 드래그해요."
|
||||
_chat:
|
||||
showSenderName: "발신자 이름 표시"
|
||||
sendOnEnter: "엔터로 보내기"
|
||||
|
@ -1429,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "프로필 이름"
|
||||
profileNameDescription: "이 디바이스를 식별할 이름을 설정해 주세요."
|
||||
profileNameDescription2: "예: '메인PC', '스마트폰' 등"
|
||||
manageProfiles: "프로파일 관리"
|
||||
_preferencesBackup:
|
||||
autoBackup: "자동 백업"
|
||||
restoreFromBackup: "백업으로 복구"
|
||||
|
@ -1467,6 +1470,7 @@ _delivery:
|
|||
manuallySuspended: "수동 정지 중"
|
||||
goneSuspended: "서버 삭제를 이유로 정지 중"
|
||||
autoSuspendedForNotResponding: "서버 응답 없음을 이유로 정지 중"
|
||||
softwareSuspended: "전달 정지 중인 소프트웨어이므로 정지 중"
|
||||
_bubbleGame:
|
||||
howToPlay: "설명"
|
||||
hold: "홀드"
|
||||
|
@ -1598,6 +1602,8 @@ _serverSettings:
|
|||
openRegistration: "회원 가입을 활성화 하기"
|
||||
openRegistrationWarning: "회원 가입을 개방하는 것은 리스크가 따릅니다. 서버를 항상 감시할 수 있고, 문제가 발생했을 때 바로 대응할 수 있는 상태에서만 활성화 하는 것을 권장합니다."
|
||||
thisSettingWillAutomaticallyOffWhenModeratorsInactive: "일정 기간동안 모더레이터의 활동이 감지되지 않는 경우, 스팸 방지를 위해 이 설정은 자동으로 꺼집니다."
|
||||
deliverSuspendedSoftware: "전달 정지 중인 소프트웨어"
|
||||
deliverSuspendedSoftwareDescription: "취약성 등의 이유로 서버의 소프트웨어 이름 및 버전 범위를 지정하여 전달을 정지할 수 있어요. 이 버전 정보는 서버가 제공한 것이며 신뢰성은 보장되지 않아요. 버전 지정에는 semver의 범위 지정을 사용할 수 있지만, >= 2024.3.1로 지정하면 2024.3.1-custom.0과 같은 custom.0과 같은 custom 버전이 포함되지 않기 때문에 >= 2024.3.1-0과 같이 prerelease를 지정하는 것이 좋아요."
|
||||
_accountMigration:
|
||||
moveFrom: "다른 계정에서 이 계정으로 이사"
|
||||
moveFromSub: "다른 계정에 대한 별칭을 생성"
|
||||
|
@ -1915,6 +1921,7 @@ _role:
|
|||
canManageCustomEmojis: "커스텀 이모지 관리"
|
||||
canManageAvatarDecorations: "아바타 꾸미기 관리"
|
||||
driveCapacity: "드라이브 용량"
|
||||
maxFileSize: "업로드 가능한 최대 파일 크기"
|
||||
alwaysMarkNsfw: "파일을 항상 NSFW로 지정"
|
||||
canUpdateBioMedia: "아바타 및 배너 이미지 변경 허용"
|
||||
pinMax: "고정할 수 있는 노트 수"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Er zijn geen gebruikers."
|
|||
editProfile: "Bewerk Profiel"
|
||||
noteDeleteConfirm: "Ben je zeker dat je dit bericht wil verwijderen?"
|
||||
pinLimitExceeded: "Je kunt geen berichten meer vastprikken"
|
||||
intro: "Installatie van Misskey geëindigd! Maak nu een beheerder aan."
|
||||
done: "Klaar"
|
||||
processing: "Bezig met verwerken"
|
||||
preview: "Voorbeeld"
|
||||
|
@ -784,7 +783,6 @@ thisIsExperimentalFeature: "Dit is een experimentele functie. De functionaliteit
|
|||
developer: "Ontwikkelaar"
|
||||
makeExplorable: "Gebruikersaccount zichtbaar maken in “Verkennen”"
|
||||
makeExplorableDescription: "Als deze optie is uitgeschakeld, is uw gebruikersaccount niet zichtbaar in het gedeelte “Verkennen”."
|
||||
showGapBetweenNotesInTimeline: "Een gat tussen noten op de tijdlijn weergeven"
|
||||
duplicate: "Dupliceren"
|
||||
left: "Links"
|
||||
center: "Center"
|
||||
|
|
|
@ -171,7 +171,6 @@ noUsers: "Det er ingen brukere"
|
|||
editProfile: "Rediger profil"
|
||||
noteDeleteConfirm: "Er du sikker på at du vil slette denne Noten?"
|
||||
pinLimitExceeded: "Du kan ikke feste flere."
|
||||
intro: "Installasjonen av Misskey er ferdig! Vennligst opprett en administratorkonto."
|
||||
done: "Ferdig"
|
||||
default: "Standard"
|
||||
defaultValueIs: "Standard: {value}"
|
||||
|
|
|
@ -230,7 +230,6 @@ noUsers: "Brak użytkowników"
|
|||
editProfile: "Edytuj profil"
|
||||
noteDeleteConfirm: "Czy na pewno chcesz usunąć ten wpis?"
|
||||
pinLimitExceeded: "Nie możesz przypiąć więcej wpisów."
|
||||
intro: "Zakończono instalację Misskey! Utwórz konto administratora."
|
||||
done: "Gotowe"
|
||||
processing: "Przetwarzanie"
|
||||
preview: "Podgląd"
|
||||
|
@ -749,7 +748,6 @@ thisIsExperimentalFeature: "Ta funkcja jest eksperymentalna. Jej funkcjonalnoś
|
|||
developer: "Programista"
|
||||
makeExplorable: "Pokazuj konto na stronie „Eksploruj”"
|
||||
makeExplorableDescription: "Jeżeli wyłączysz tę opcję, Twoje konto nie będzie wyświetlać się w sekcji „Eksploruj”."
|
||||
showGapBetweenNotesInTimeline: "Pokazuj odstęp między wpisami na osi czasu."
|
||||
duplicate: "Duplikuj"
|
||||
left: "Lewo"
|
||||
center: "Wyśsrodkuj"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Sem usuários"
|
|||
editProfile: "Editar Perfil"
|
||||
noteDeleteConfirm: "Deseja excluir esta nota?"
|
||||
pinLimitExceeded: "Não é possível fixar novas notas"
|
||||
intro: "A instalação do Misskey está completa! Crie uma conta de administrador."
|
||||
done: "Concluído"
|
||||
processing: "Em Progresso"
|
||||
preview: "Pré-visualizar"
|
||||
|
@ -784,7 +783,6 @@ thisIsExperimentalFeature: "Este é um recurso experimental. As funções podem
|
|||
developer: "Programador"
|
||||
makeExplorable: "Deixe a sua conta encontrável em \"Explorar\"."
|
||||
makeExplorableDescription: "Se você desativá-lo, outros usuários não poderão encontrar a sua conta na aba Descoberta."
|
||||
showGapBetweenNotesInTimeline: "Mostrar um espaço entre as notas na linha de tempo"
|
||||
duplicate: "Duplicar"
|
||||
left: "Esquerda"
|
||||
center: "Centralizar"
|
||||
|
@ -1237,7 +1235,6 @@ showAvatarDecorations: "Exibir decorações de avatar"
|
|||
releaseToRefresh: "Solte para atualizar"
|
||||
refreshing: "Atualizando..."
|
||||
pullDownToRefresh: "Puxe para baixo para atualizar"
|
||||
disableStreamingTimeline: "Desabilitar atualizações em tempo real da linha do tempo"
|
||||
useGroupedNotifications: "Agrupar notificações"
|
||||
signupPendingError: "Houve um problema ao verificar o endereço de email. O link pode ter expirado."
|
||||
cwNotationRequired: "Se \"Esconder conteúdo\" está habilitado, uma descrição deve ser adicionada."
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Niciun utilizator"
|
|||
editProfile: "Editează profilul"
|
||||
noteDeleteConfirm: "Ești sigur(ă) că vrei să ștergi această notă?"
|
||||
pinLimitExceeded: "Nu poți mai fixa mai multe note"
|
||||
intro: "Misskey s-a instalat! Te rog crează un utilizator admin."
|
||||
done: "Gata"
|
||||
processing: "Se procesează"
|
||||
preview: "Previzualizare"
|
||||
|
@ -784,7 +783,6 @@ thisIsExperimentalFeature: "Aceasta este o funcție experimentală. Funcționali
|
|||
developer: "Dezvoltator"
|
||||
makeExplorable: "Fă-ți contul vizibil în secțiunea„Explorați”"
|
||||
makeExplorableDescription: "Dacă dezactivezi această opțiune, contul dvs. nu va fi vizibil în secțiunea\"Explorați\"."
|
||||
showGapBetweenNotesInTimeline: "Afișați un decalaj între postările de pe cronologie"
|
||||
duplicate: "Duplicat"
|
||||
left: "Stânga"
|
||||
center: "Centru"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "Нет ни одного пользователя"
|
|||
editProfile: "Редактировать профиль"
|
||||
noteDeleteConfirm: "Вы хотите удалить эту заметку?"
|
||||
pinLimitExceeded: "Нельзя закрепить ещё больше заметок"
|
||||
intro: "Установка Misskey завершена! А теперь создайте учетную запись администратора."
|
||||
done: "Готово"
|
||||
processing: "Обработка"
|
||||
preview: "Предпросмотр"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "Это экспериментальная функц
|
|||
developer: "Разработчик"
|
||||
makeExplorable: "Опубликовать профиль в «Обзоре»."
|
||||
makeExplorableDescription: "Если выключить, ваш профиль не будет показан в разделе «Обзор»."
|
||||
showGapBetweenNotesInTimeline: "Показывать разделитель между заметками в ленте"
|
||||
duplicate: "Дубликат"
|
||||
left: "Слева"
|
||||
center: "По центру"
|
||||
|
@ -1200,7 +1198,6 @@ privacyPolicyUrl: "Ссылка на Политику Конфиденциаль
|
|||
attach: "Прикрепить"
|
||||
angle: "Угол"
|
||||
flip: "Переворот"
|
||||
disableStreamingTimeline: "Отключить обновление ленты в режиме реального времени"
|
||||
useGroupedNotifications: "Отображать уведомления сгруппировано"
|
||||
doReaction: "Добавить реакцию"
|
||||
code: "Код"
|
||||
|
|
|
@ -204,7 +204,6 @@ noUsers: "Žiadni používatelia"
|
|||
editProfile: "Upraviť profil"
|
||||
noteDeleteConfirm: "Naozaj chcete odstrániť túto poznámku?"
|
||||
pinLimitExceeded: "Ďalšie poznámky už nemôžete pripnúť."
|
||||
intro: "Inštalácia Misskey je dokončená! Prosím vytvorte administrátora."
|
||||
done: "Hotovo"
|
||||
processing: "Pracujem..."
|
||||
preview: "Náhľad"
|
||||
|
@ -682,7 +681,6 @@ experimentalFeatures: "Experimentálne funkcie"
|
|||
developer: "Vývojár"
|
||||
makeExplorable: "Spraviť účet viditeľný v \"Objavovať\""
|
||||
makeExplorableDescription: "Ak toto vypnete, váš účet sa nezobrazí v sekcii \"Objavovat\"."
|
||||
showGapBetweenNotesInTimeline: "Zobraziť medzeru medzi príspevkami časovej osi."
|
||||
duplicate: "Duplikovať"
|
||||
left: "Naľavo"
|
||||
center: "Stred"
|
||||
|
|
|
@ -211,7 +211,6 @@ noUsers: "Det finns inga användare"
|
|||
editProfile: "Redigera profil"
|
||||
noteDeleteConfirm: "Är du säker på att du vill ta bort denna not?"
|
||||
pinLimitExceeded: "Du kan inte fästa fler noter"
|
||||
intro: "Misskey har installerats! Vänligen skapa en adminanvändare."
|
||||
done: "Klar"
|
||||
processing: "Bearbetar..."
|
||||
preview: "Förhandsvisning"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "ไม่พบผู้ใช้งาน"
|
|||
editProfile: "แก้ไขโปรไฟล์"
|
||||
noteDeleteConfirm: "ต้องการลบโน้ตนี้ใช่ไหม?"
|
||||
pinLimitExceeded: "คุณไม่สามารถปักหมุดโน้ตเพิ่มเติมใดๆได้อีก"
|
||||
intro: "การติดตั้ง Misskey เสร็จสิ้นแล้วนะ! โปรดสร้างผู้ใช้งานที่เป็นผู้ดูแลระบบ"
|
||||
done: "เสร็จสิ้น"
|
||||
processing: "กำลังประมวลผล..."
|
||||
preview: "แสดงตัวอย่าง"
|
||||
|
@ -778,7 +777,6 @@ thisIsExperimentalFeature: "นี่เป็นฟีเจอร์ทดล
|
|||
developer: "สำหรับนักพัฒนา"
|
||||
makeExplorable: "ทำให้บัญชีมองเห็นใน “สำรวจ”"
|
||||
makeExplorableDescription: "ถ้าหากคุณปิดการทำงานนี้ บัญชีของคุณนั้นจะไม่แสดงในส่วน “สำรวจ”"
|
||||
showGapBetweenNotesInTimeline: "แสดงช่องว่างระหว่างโพสต์บนไทม์ไลน์"
|
||||
duplicate: "ทำซ้ำ"
|
||||
left: "ซ้าย"
|
||||
center: "กึ่งกลาง"
|
||||
|
@ -1227,7 +1225,6 @@ showAvatarDecorations: "แสดงตกแต่งอวตาร"
|
|||
releaseToRefresh: "ปล่อยเพื่อรีเฟรช"
|
||||
refreshing: "กำลังรีเฟรช..."
|
||||
pullDownToRefresh: "ดึงลงเพื่อรีเฟรช"
|
||||
disableStreamingTimeline: "ปิดใช้งานอัปเดตไทม์ไลน์แบบเรียลไทม์"
|
||||
useGroupedNotifications: "แสดงผลการแจ้งเตือนแบบกลุ่มแล้ว"
|
||||
signupPendingError: "มีปัญหาในการตรวจสอบที่อยู่อีเมลลิงก์อาจหมดอายุแล้ว"
|
||||
cwNotationRequired: "หากเปิดใช้งาน “ซ่อนเนื้อหา” จะต้องระบุคำอธิบาย"
|
||||
|
|
|
@ -224,7 +224,6 @@ noUsers: "Kullanıcı yok"
|
|||
editProfile: "Profili düzenle"
|
||||
noteDeleteConfirm: "Bu notu silmek istediğinizden emin misiniz?"
|
||||
pinLimitExceeded: "Daha fazla not sabitlenemez"
|
||||
intro: "Misskey yüklemesi tamamlandı! Lütfen yönetici hesabını oluşturun."
|
||||
done: "Tamamlandı"
|
||||
preview: "Önizleme"
|
||||
default: "Varsayılan"
|
||||
|
|
|
@ -208,7 +208,6 @@ noUsers: "Немає користувачів"
|
|||
editProfile: "Редагувати обліковий запис"
|
||||
noteDeleteConfirm: "Ви дійсно хочете видалити цей запис?"
|
||||
pinLimitExceeded: "Більше записів не можна закріпити"
|
||||
intro: "Встановлення Misskey завершено! Будь ласка, створіть обліковий запис адміністратора."
|
||||
done: "Готово"
|
||||
processing: "Обробка"
|
||||
preview: "Попередній перегляд"
|
||||
|
@ -681,7 +680,6 @@ experimentalFeatures: "Експериментальні функції"
|
|||
developer: "Розробник"
|
||||
makeExplorable: "Зробіть обліковий запис видимим у розділі \"Огляд\""
|
||||
makeExplorableDescription: "Вимкніть, щоб обліковий запис не показувався у розділі \"Огляд\"."
|
||||
showGapBetweenNotesInTimeline: "Показувати розрив між записами у стрічці новин"
|
||||
duplicate: "Дублікат"
|
||||
left: "Лівий"
|
||||
center: "Центр"
|
||||
|
|
|
@ -219,7 +219,6 @@ noUsers: "Foydalanuvchilar yo‘q"
|
|||
editProfile: "Profilni o'zgartirish"
|
||||
noteDeleteConfirm: "Haqiqatan ham bu qaydni oʻchirib tashlamoqchimisiz?"
|
||||
pinLimitExceeded: "Siz boshqa qaydlarni mahkamlay olmaysiz"
|
||||
intro: "Misskeyni o'rnatish tugallandi! Iltimos, administrator foydalanuvchi yarating."
|
||||
done: "Bajarildi"
|
||||
processing: "Amaliyotda"
|
||||
preview: "Ko'rish"
|
||||
|
|
|
@ -250,7 +250,6 @@ noUsers: "Chưa có ai"
|
|||
editProfile: "Sửa hồ sơ"
|
||||
noteDeleteConfirm: "Bạn có chắc muốn xóa tút này?"
|
||||
pinLimitExceeded: "Bạn không thể ghim bài viết nữa"
|
||||
intro: "Đã cài đặt Misskey! Xin hãy tạo tài khoản admin."
|
||||
done: "Xong"
|
||||
processing: "Đang xử lý"
|
||||
preview: "Xem trước"
|
||||
|
@ -783,7 +782,6 @@ thisIsExperimentalFeature: "Tính năng này đang trong quá trình thử nghi
|
|||
developer: "Nhà phát triển"
|
||||
makeExplorable: "Không hiện tôi trong \"Khám phá\""
|
||||
makeExplorableDescription: "Nếu bạn tắt, tài khoản của bạn sẽ không hiện trong mục \"Khám phá\"."
|
||||
showGapBetweenNotesInTimeline: "Hiện dải phân cách giữa các tút trên bảng tin"
|
||||
duplicate: "Tạo bản sao"
|
||||
left: "Bên trái"
|
||||
center: "Giữa"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "无用户"
|
|||
editProfile: "编辑资料"
|
||||
noteDeleteConfirm: "确定要删除该帖子吗?"
|
||||
pinLimitExceeded: "无法置顶更多了"
|
||||
intro: "Misskey 的部署结束啦!创建管理员账号吧!"
|
||||
done: "完成"
|
||||
processing: "正在处理"
|
||||
preview: "预览"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "这是一项实验性功能。规范可能会变更
|
|||
developer: "开发者"
|
||||
makeExplorable: "使账号可见。"
|
||||
makeExplorableDescription: "关闭时,账号不会显示在\"发现\"中。"
|
||||
showGapBetweenNotesInTimeline: "时间线上的帖子分开显示。"
|
||||
duplicate: "复制"
|
||||
left: "左"
|
||||
center: "中央"
|
||||
|
@ -1238,7 +1236,6 @@ showAvatarDecorations: "显示头像挂件"
|
|||
releaseToRefresh: "松开以刷新"
|
||||
refreshing: "刷新中"
|
||||
pullDownToRefresh: "下拉以刷新"
|
||||
disableStreamingTimeline: "禁止实时更新时间线"
|
||||
useGroupedNotifications: "分组显示通知"
|
||||
signupPendingError: "确认电子邮件时出现错误。链接可能已过期。"
|
||||
cwNotationRequired: "在启用「隐藏内容」时必须输入注释"
|
||||
|
@ -1348,6 +1345,7 @@ readonly: "只读"
|
|||
goToDeck: "返回至 Deck"
|
||||
federationJobs: "联合作业"
|
||||
driveAboutTip: "网盘可以显示以前上传的文件。<br>\n也可以在发布帖子时重复使用文件,或在发布帖子前预先上传文件。<br>\n<b>删除文件时,其将从至今为止所有用到该文件的地方(如帖子、页面、头像、横幅)消失。</b><br>\n也可以新建文件夹来整理文件。"
|
||||
scrollToClose: "滑动并关闭"
|
||||
_chat:
|
||||
noMessagesYet: "还没有消息"
|
||||
newMessage: "新消息"
|
||||
|
@ -1432,6 +1430,7 @@ _preferencesProfile:
|
|||
profileName: "配置名"
|
||||
profileNameDescription: "请指定用于识别此设备的名称"
|
||||
profileNameDescription2: "如「PC」、「手机」等"
|
||||
manageProfiles: "管理配置文件"
|
||||
_preferencesBackup:
|
||||
autoBackup: "自动备份"
|
||||
restoreFromBackup: "从备份恢复"
|
||||
|
|
|
@ -251,7 +251,6 @@ noUsers: "沒有任何使用者"
|
|||
editProfile: "編輯個人檔案"
|
||||
noteDeleteConfirm: "確定刪除此貼文嗎?"
|
||||
pinLimitExceeded: "不能置頂更多貼文了"
|
||||
intro: "Misskey 部署完成!請建立管理員帳戶。"
|
||||
done: "完成"
|
||||
processing: "處理中"
|
||||
preview: "預覽"
|
||||
|
@ -785,7 +784,6 @@ thisIsExperimentalFeature: "這是一項實驗性功能,其行為會隨需要
|
|||
developer: "開發者"
|
||||
makeExplorable: "使自己的帳戶更容易被找到"
|
||||
makeExplorableDescription: "如果關閉,帳戶將不會被顯示在「探索」頁面中。"
|
||||
showGapBetweenNotesInTimeline: "分開顯示時間軸上的貼文"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "置中"
|
||||
|
@ -1238,7 +1236,6 @@ showAvatarDecorations: "顯示頭像裝飾"
|
|||
releaseToRefresh: "放開以更新內容"
|
||||
refreshing: "載入更新中"
|
||||
pullDownToRefresh: "往下拉來更新內容"
|
||||
disableStreamingTimeline: "停用時間軸的即時更新"
|
||||
useGroupedNotifications: "分組顯示通知訊息"
|
||||
signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。"
|
||||
cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。"
|
||||
|
@ -1434,6 +1431,7 @@ _preferencesProfile:
|
|||
profileName: "設定檔案名稱"
|
||||
profileNameDescription: "設定一個名稱來識別此裝置。"
|
||||
profileNameDescription2: "例如:「主要個人電腦」、「智慧型手機」等"
|
||||
manageProfiles: "管理個人檔案"
|
||||
_preferencesBackup:
|
||||
autoBackup: "自動備份"
|
||||
restoreFromBackup: "從備份還原"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.5.0",
|
||||
"version": "2025.5.1-alpha.0",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -34,7 +34,7 @@
|
|||
"watch": "pnpm dev",
|
||||
"dev": "node scripts/dev.mjs",
|
||||
"lint": "pnpm -r lint",
|
||||
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
|
||||
"cy:open": "pnpm cypress open --config-file=cypress.config.ts",
|
||||
"cy:run": "pnpm cypress run",
|
||||
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||
"e2e-dev-container": "ncp ./.config/cypress-devcontainer.yml ./.config/test.yml && pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class SingleUserMode1746422049376 {
|
||||
name = 'SingleUserMode1746422049376'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "singleUserMode" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "singleUserMode"`);
|
||||
}
|
||||
}
|
|
@ -578,6 +578,20 @@ export class ChatService {
|
|||
|
||||
@bindThis
|
||||
public async deleteRoom(room: MiChatRoom, deleter?: MiUser) {
|
||||
const memberships = (await this.chatRoomMembershipsRepository.findBy({ roomId: room.id })).map(m => ({
|
||||
userId: m.userId,
|
||||
})).concat({ // ownerはmembershipレコードを作らないため
|
||||
userId: room.ownerId,
|
||||
});
|
||||
|
||||
// 未読フラグ削除
|
||||
const redisPipeline = this.redisClient.pipeline();
|
||||
for (const membership of memberships) {
|
||||
redisPipeline.del(`newRoomChatMessageExists:${membership.userId}:${room.id}`);
|
||||
redisPipeline.srem(`newChatMessagesExists:${membership.userId}`, `room:${room.id}`);
|
||||
}
|
||||
await redisPipeline.exec();
|
||||
|
||||
await this.chatRoomsRepository.delete(room.id);
|
||||
|
||||
if (deleter) {
|
||||
|
@ -709,6 +723,12 @@ export class ChatService {
|
|||
public async leaveRoom(userId: MiUser['id'], roomId: MiChatRoom['id']) {
|
||||
const membership = await this.chatRoomMembershipsRepository.findOneByOrFail({ roomId, userId });
|
||||
await this.chatRoomMembershipsRepository.delete(membership.id);
|
||||
|
||||
// 未読フラグを消す (「既読にする」というわけでもないのでreadメソッドは使わないでおく)
|
||||
const redisPipeline = this.redisClient.pipeline();
|
||||
redisPipeline.del(`newRoomChatMessageExists:${userId}:${roomId}`);
|
||||
redisPipeline.srem(`newChatMessagesExists:${userId}`, `room:${roomId}`);
|
||||
await redisPipeline.exec();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
@ -429,6 +429,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
userId: channel.userId,
|
||||
} : undefined,
|
||||
mentions: note.mentions.length > 0 ? note.mentions : undefined,
|
||||
hasPoll: note.hasPoll || undefined,
|
||||
uri: note.uri ?? undefined,
|
||||
url: note.url ?? undefined,
|
||||
|
||||
|
|
|
@ -675,6 +675,11 @@ export class MiMeta {
|
|||
default: [],
|
||||
})
|
||||
public deliverSuspendedSoftware: SoftwareSuspension[];
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public singleUserMode: boolean;
|
||||
}
|
||||
|
||||
export type SoftwareSuspension = {
|
||||
|
|
|
@ -256,6 +256,10 @@ export const packedNoteSchema = {
|
|||
type: 'number',
|
||||
optional: true, nullable: false,
|
||||
},
|
||||
hasPoll: {
|
||||
type: 'boolean',
|
||||
optional: true, nullable: false,
|
||||
},
|
||||
|
||||
myReaction: {
|
||||
type: 'string',
|
||||
|
|
|
@ -546,6 +546,10 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
},
|
||||
singleUserMode: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
ugcVisibilityForVisitor: {
|
||||
type: 'string',
|
||||
enum: ['all', 'local', 'none'],
|
||||
|
@ -696,6 +700,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
federation: instance.federation,
|
||||
federationHosts: instance.federationHosts,
|
||||
deliverSuspendedSoftware: instance.deliverSuspendedSoftware,
|
||||
singleUserMode: instance.singleUserMode,
|
||||
ugcVisibilityForVisitor: instance.ugcVisibilityForVisitor,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -196,6 +196,7 @@ export const paramDef = {
|
|||
required: ['software', 'versionRange'],
|
||||
},
|
||||
},
|
||||
singleUserMode: { type: 'boolean' },
|
||||
ugcVisibilityForVisitor: {
|
||||
type: 'string',
|
||||
enum: ['all', 'local', 'none'],
|
||||
|
@ -694,6 +695,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.federationHosts = ps.federationHosts.filter(Boolean).map(x => x.toLowerCase());
|
||||
}
|
||||
|
||||
if (ps.singleUserMode !== undefined) {
|
||||
set.singleUserMode = ps.singleUserMode;
|
||||
}
|
||||
|
||||
if (ps.ugcVisibilityForVisitor !== undefined) {
|
||||
set.ugcVisibilityForVisitor = ps.ugcVisibilityForVisitor;
|
||||
}
|
||||
|
|
|
@ -154,6 +154,10 @@ onUnmounted(() => {
|
|||
&.naked {
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
|
||||
> .content {
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.scrollable {
|
||||
|
|
|
@ -12,6 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { instanceName as localInstanceName } from '@@/js/config.js';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { instance as localInstance } from '@/instance.js';
|
||||
|
@ -43,10 +44,33 @@ const faviconUrl = computed(() => {
|
|||
return getProxiedImageUrlNullable(imageSrc);
|
||||
});
|
||||
|
||||
type ITickerColors = {
|
||||
readonly bg: string;
|
||||
readonly fg: string;
|
||||
};
|
||||
|
||||
const TICKER_YUV_THRESHOLD = 191 as const;
|
||||
const TICKER_FG_COLOR_LIGHT = '#ffffff' as const;
|
||||
const TICKER_FG_COLOR_DARK = '#2f2f2fcc' as const;
|
||||
|
||||
function getTickerColors(bgHex: string): ITickerColors {
|
||||
const tinycolorInstance = tinycolor(bgHex);
|
||||
const { r, g, b } = tinycolorInstance.toRgb();
|
||||
const yuv = 0.299 * r + 0.587 * g + 0.114 * b;
|
||||
const fgHex = yuv > TICKER_YUV_THRESHOLD ? TICKER_FG_COLOR_DARK : TICKER_FG_COLOR_LIGHT;
|
||||
|
||||
return {
|
||||
fg: fgHex,
|
||||
bg: bgHex,
|
||||
} as const satisfies ITickerColors;
|
||||
}
|
||||
|
||||
const themeColorStyle = computed<CSSProperties>(() => {
|
||||
const themeColor = (props.host == null ? localInstance.themeColor : props.instance?.themeColor) ?? '#777777';
|
||||
const colors = getTickerColors(themeColor);
|
||||
return {
|
||||
background: `linear-gradient(90deg, ${themeColor}, ${themeColor}00)`,
|
||||
background: `linear-gradient(90deg, ${colors.bg}, ${colors.bg}00)`,
|
||||
color: colors.fg,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
@ -60,7 +84,6 @@ $height: 2ex;
|
|||
height: $height;
|
||||
border-radius: 4px 0 0 4px;
|
||||
overflow: clip;
|
||||
color: #fff;
|
||||
|
||||
// text-shadowは重いから使うな
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ function toggle(): void {
|
|||
<style lang="scss" module>
|
||||
.root {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
padding: 7px 10px;
|
||||
|
@ -102,7 +103,8 @@ function toggle(): void {
|
|||
}
|
||||
|
||||
.button {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: none;
|
||||
|
@ -126,7 +128,7 @@ function toggle(): void {
|
|||
}
|
||||
|
||||
.label {
|
||||
margin-left: 28px;
|
||||
margin-left: 8px;
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -5,14 +5,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent, h, ref, watch } from 'vue';
|
||||
import type { VNode } from 'vue';
|
||||
import MkRadio from './MkRadio.vue';
|
||||
import type { VNode } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
required: false,
|
||||
},
|
||||
vertical: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const value = ref(props.modelValue);
|
||||
|
@ -34,7 +38,10 @@ export default defineComponent({
|
|||
options = options.filter(vnode => !(typeof vnode.type === 'symbol' && vnode.type.description === 'v-cmt' && vnode.children === 'v-if'));
|
||||
|
||||
return () => h('div', {
|
||||
class: 'novjtcto',
|
||||
class: [
|
||||
'novjtcto',
|
||||
...(props.vertical ? ['vertical'] : []),
|
||||
],
|
||||
}, [
|
||||
...(label ? [h('div', {
|
||||
class: 'label',
|
||||
|
@ -71,7 +78,7 @@ export default defineComponent({
|
|||
|
||||
> .body {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
@ -84,5 +91,11 @@ export default defineComponent({
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
> .body {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,356 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.root" class="_gaps_m">
|
||||
<MkInput v-model="q_name" data-cy-server-name>
|
||||
<template #label>{{ i18n.ts.instanceName }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkFolder :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts._serverSetupWizard.howWillYouUseMisskey }}</template>
|
||||
<template #icon><i class="ti ti-settings-question"></i></template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<MkRadios v-model="q_use" :vertical="true">
|
||||
<option value="single">
|
||||
<div><i class="ti ti-user"></i> <b>{{ i18n.ts._serverSetupWizard._use.single }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard._use.single_description }}</div>
|
||||
</option>
|
||||
<option value="group">
|
||||
<div><i class="ti ti-lock"></i> <b>{{ i18n.ts._serverSetupWizard._use.group }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard._use.group_description }}</div>
|
||||
</option>
|
||||
<option value="open">
|
||||
<div><i class="ti ti-world"></i> <b>{{ i18n.ts._serverSetupWizard._use.open }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard._use.open_description }}</div>
|
||||
</option>
|
||||
</MkRadios>
|
||||
|
||||
<MkInfo v-if="q_use === 'single'">{{ i18n.ts._serverSetupWizard._use.single_youCanCreateMultipleAccounts }}</MkInfo>
|
||||
<MkInfo v-if="q_use === 'open'" warn><b>{{ i18n.ts.advice }}:</b> {{ i18n.ts._serverSetupWizard.openServerAdvice }}</MkInfo>
|
||||
<MkInfo v-if="q_use === 'open'" warn><b>{{ i18n.ts.advice }}:</b> {{ i18n.ts._serverSetupWizard.openServerAntiSpamAdvice }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="q_use !== 'single'" :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts._serverSetupWizard.howManyUsersDoYouExpect }}</template>
|
||||
<template #icon><i class="ti ti-users"></i></template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<MkRadios v-model="q_scale" :vertical="true">
|
||||
<option value="small"><i class="ti ti-user"></i> {{ i18n.ts._serverSetupWizard._scale.small }}</option>
|
||||
<option value="medium"><i class="ti ti-users"></i> {{ i18n.ts._serverSetupWizard._scale.medium }}</option>
|
||||
<option value="large"><i class="ti ti-users-group"></i> {{ i18n.ts._serverSetupWizard._scale.large }}</option>
|
||||
</MkRadios>
|
||||
|
||||
<MkInfo v-if="q_scale === 'large'"><b>{{ i18n.ts.advice }}:</b> {{ i18n.ts._serverSetupWizard.largeScaleServerAdvice }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts._serverSetupWizard.doYouConnectToFediverse }}</template>
|
||||
<template #icon><i class="ti ti-planet"></i></template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<div>{{ i18n.ts._serverSetupWizard.doYouConnectToFediverse_description1 }}<br>{{ i18n.ts._serverSetupWizard.doYouConnectToFediverse_description2 }}</div>
|
||||
|
||||
<MkRadios v-model="q_federation" :vertical="true">
|
||||
<option value="yes">{{ i18n.ts.yes }}</option>
|
||||
<option value="no">{{ i18n.ts.no }}</option>
|
||||
</MkRadios>
|
||||
|
||||
<MkInfo v-if="q_federation === 'yes'">{{ i18n.ts._serverSetupWizard.youCanConfigureMoreFederationSettingsLater }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="q_use === 'open' || q_federation === 'yes'" :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts._serverSetupWizard.adminInfo }}</template>
|
||||
<template #icon><i class="ti ti-mail"></i></template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<div>{{ i18n.ts._serverSetupWizard.adminInfo_description }}</div>
|
||||
|
||||
<MkInfo warn>{{ i18n.ts._serverSetupWizard.adminInfo_mustBeFilled }}</MkInfo>
|
||||
|
||||
<MkInput v-model="q_adminName">
|
||||
<template #label>{{ i18n.ts.maintainerName }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkInput v-model="q_adminEmail" type="email">
|
||||
<template #label>{{ i18n.ts.maintainerEmail }}</template>
|
||||
</MkInput>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder :defaultOpen="true" :maxHeight="300">
|
||||
<template #label>{{ i18n.ts._serverSetupWizard.followingSettingsAreRecommended }}</template>
|
||||
<template #icon><i class="ti ti-adjustments-alt"></i></template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._serverSettings.singleUserMode }}:</b></div>
|
||||
<div>{{ serverSettings.singleUserMode ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._serverSettings.openRegistration }}:</b></div>
|
||||
<div>{{ !serverSettings.disableRegistration ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts.emailRequiredForSignup }}:</b></div>
|
||||
<div>{{ serverSettings.emailRequiredForSignup ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>Log IP:</b></div>
|
||||
<div>{{ serverSettings.enableIpLogging ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts.federation }}:</b></div>
|
||||
<div>{{ serverSettings.federation === 'none' ? i18n.ts.no : i18n.ts.all }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>FTT:</b></div>
|
||||
<div>{{ serverSettings.enableFanoutTimeline ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>FTT/{{ i18n.ts._serverSettings.fanoutTimelineDbFallback }}:</b></div>
|
||||
<div>{{ serverSettings.enableFanoutTimelineDbFallback ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>RBT:</b></div>
|
||||
<div>{{ serverSettings.enableReactionsBuffering ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.rateLimitFactor }}:</b></div>
|
||||
<div>{{ defaultPolicies.rateLimitFactor }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.driveCapacity }}:</b></div>
|
||||
<div>{{ defaultPolicies.driveCapacityMb }} MB</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.userListMax }}:</b></div>
|
||||
<div>{{ defaultPolicies.userListLimit }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.antennaMax }}:</b></div>
|
||||
<div>{{ defaultPolicies.antennaLimit }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.webhookMax }}:</b></div>
|
||||
<div>{{ defaultPolicies.webhookLimit }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.canImportFollowing }}:</b></div>
|
||||
<div>{{ defaultPolicies.canImportFollowing ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.canImportMuting }}:</b></div>
|
||||
<div>{{ defaultPolicies.canImportMuting ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.canImportBlocking }}:</b></div>
|
||||
<div>{{ defaultPolicies.canImportBlocking ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.canImportUserLists }}:</b></div>
|
||||
<div>{{ defaultPolicies.canImportUserLists ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div><b>{{ i18n.ts._role.baseRole }}/{{ i18n.ts._role._options.canImportAntennas }}:</b></div>
|
||||
<div>{{ defaultPolicies.canImportAntennas ? i18n.ts.yes : i18n.ts.no }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<MkButton gradate large rounded data-cy-server-setup-wizard-apply style="margin: 0 auto;" @click="applySettings">
|
||||
<i class="ti ti-check"></i> {{ i18n.ts._serverSetupWizard.applyTheseSettings }}
|
||||
</MkButton>
|
||||
</template>
|
||||
</MkFolder>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { ROLE_POLICIES } from '@@/js/const.js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkRadios from '@/components/MkRadios.vue';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'finished'): void;
|
||||
}>();
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
token?: string;
|
||||
}>(), {
|
||||
});
|
||||
|
||||
const q_name = ref('');
|
||||
const q_use = ref('single');
|
||||
const q_scale = ref('small');
|
||||
const q_federation = ref('yes');
|
||||
const q_adminName = ref('');
|
||||
const q_adminEmail = ref('');
|
||||
|
||||
const serverSettings = computed<Misskey.entities.AdminUpdateMetaRequest>(() => {
|
||||
let enableReactionsBuffering;
|
||||
if (q_use.value === 'single') {
|
||||
enableReactionsBuffering = false;
|
||||
} else {
|
||||
enableReactionsBuffering = q_scale.value !== 'small';
|
||||
}
|
||||
|
||||
return {
|
||||
singleUserMode: q_use.value === 'single',
|
||||
disableRegistration: q_use.value !== 'open',
|
||||
emailRequiredForSignup: q_use.value === 'open',
|
||||
enableIpLogging: q_use.value === 'open',
|
||||
federation: q_federation.value === 'yes' ? 'all' : 'none',
|
||||
enableFanoutTimeline: true,
|
||||
enableFanoutTimelineDbFallback: q_use.value === 'single',
|
||||
enableReactionsBuffering,
|
||||
};
|
||||
});
|
||||
|
||||
const defaultPolicies = computed<Partial<Record<typeof ROLE_POLICIES[number], any>>>(() => {
|
||||
let driveCapacityMb;
|
||||
if (q_use.value === 'single') {
|
||||
driveCapacityMb = 8192;
|
||||
} else if (q_use.value === 'group') {
|
||||
driveCapacityMb = 1000;
|
||||
} else if (q_use.value === 'open') {
|
||||
driveCapacityMb = 100;
|
||||
}
|
||||
|
||||
let rateLimitFactor;
|
||||
if (q_use.value === 'single') {
|
||||
rateLimitFactor = 0.3;
|
||||
} else if (q_use.value === 'group') {
|
||||
rateLimitFactor = 0.7;
|
||||
} else if (q_use.value === 'open') {
|
||||
if (q_scale.value === 'small') {
|
||||
rateLimitFactor = 1;
|
||||
} else if (q_scale.value === 'medium') {
|
||||
rateLimitFactor = 1.25;
|
||||
} else if (q_scale.value === 'large') {
|
||||
rateLimitFactor = 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
let userListLimit;
|
||||
if (q_use.value === 'single') {
|
||||
userListLimit = 100;
|
||||
} else if (q_use.value === 'group') {
|
||||
userListLimit = 5;
|
||||
} else if (q_use.value === 'open') {
|
||||
userListLimit = 3;
|
||||
}
|
||||
|
||||
let antennaLimit;
|
||||
if (q_use.value === 'single') {
|
||||
antennaLimit = 100;
|
||||
} else if (q_use.value === 'group') {
|
||||
antennaLimit = 5;
|
||||
} else if (q_use.value === 'open') {
|
||||
antennaLimit = 0;
|
||||
}
|
||||
|
||||
let webhookLimit;
|
||||
if (q_use.value === 'single') {
|
||||
webhookLimit = 100;
|
||||
} else if (q_use.value === 'group') {
|
||||
webhookLimit = 0;
|
||||
} else if (q_use.value === 'open') {
|
||||
webhookLimit = 0;
|
||||
}
|
||||
|
||||
let canImportFollowing;
|
||||
if (q_use.value === 'single') {
|
||||
canImportFollowing = true;
|
||||
} else {
|
||||
canImportFollowing = false;
|
||||
}
|
||||
|
||||
let canImportMuting;
|
||||
if (q_use.value === 'single') {
|
||||
canImportMuting = true;
|
||||
} else {
|
||||
canImportMuting = false;
|
||||
}
|
||||
|
||||
let canImportBlocking;
|
||||
if (q_use.value === 'single') {
|
||||
canImportBlocking = true;
|
||||
} else {
|
||||
canImportBlocking = false;
|
||||
}
|
||||
|
||||
let canImportUserLists;
|
||||
if (q_use.value === 'single') {
|
||||
canImportUserLists = true;
|
||||
} else {
|
||||
canImportUserLists = false;
|
||||
}
|
||||
|
||||
let canImportAntennas;
|
||||
if (q_use.value === 'single') {
|
||||
canImportAntennas = true;
|
||||
} else {
|
||||
canImportAntennas = false;
|
||||
}
|
||||
|
||||
return {
|
||||
rateLimitFactor,
|
||||
driveCapacityMb,
|
||||
userListLimit,
|
||||
antennaLimit,
|
||||
webhookLimit,
|
||||
canImportFollowing,
|
||||
canImportMuting,
|
||||
canImportBlocking,
|
||||
canImportUserLists,
|
||||
canImportAntennas,
|
||||
};
|
||||
});
|
||||
|
||||
function applySettings() {
|
||||
const _close = os.waiting();
|
||||
Promise.all([
|
||||
misskeyApi('admin/update-meta', {
|
||||
...serverSettings.value,
|
||||
name: q_name.value === '' ? undefined : q_name.value,
|
||||
maintainerName: q_adminName.value === '' ? undefined : q_adminName.value,
|
||||
maintainerEmail: q_adminEmail.value === '' ? undefined : q_adminEmail.value,
|
||||
}, props.token),
|
||||
misskeyApi('admin/roles/update-default-policies', {
|
||||
policies: defaultPolicies.value,
|
||||
}, props.token),
|
||||
]).then(() => {
|
||||
emit('finished');
|
||||
}).catch((err) => {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: err.code,
|
||||
text: err.message,
|
||||
});
|
||||
}).finally(() => {
|
||||
_close();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
}
|
||||
</style>
|
|
@ -18,8 +18,16 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</details>
|
||||
<details v-if="note.poll">
|
||||
<summary>{{ i18n.ts.poll }}</summary>
|
||||
<MkPoll :noteId="note.id" :poll="note.poll" :author="note.user" :emojiUrls="note.emojis"/>
|
||||
<MkPoll
|
||||
:noteId="note.id"
|
||||
:multiple="note.poll.multiple"
|
||||
:expiresAt="note.poll.expiresAt"
|
||||
:choices="note.poll.choices"
|
||||
:author="note.user"
|
||||
:emojiUrls="note.emojis"
|
||||
/>
|
||||
</details>
|
||||
<MkA v-if="note.hasPoll && note.poll == null" :to="`/notes/${note.id}`">({{ i18n.ts.poll }})</MkA>
|
||||
<button v-if="isLong && collapsed" :class="$style.fade" class="_button" @click="collapsed = false">
|
||||
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
|
|
|
@ -547,18 +547,24 @@ export function success(): Promise<void> {
|
|||
});
|
||||
}
|
||||
|
||||
export function waiting(text?: string | null): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
const showing = ref(true);
|
||||
const { dispose } = popup(MkWaitingDialog, {
|
||||
success: false,
|
||||
showing: showing,
|
||||
text,
|
||||
}, {
|
||||
done: () => resolve(),
|
||||
closed: () => dispose(),
|
||||
});
|
||||
export function waiting(text?: string | null): () => void {
|
||||
window.document.body.setAttribute('inert', 'true');
|
||||
|
||||
const showing = ref(true);
|
||||
const { dispose } = popup(MkWaitingDialog, {
|
||||
success: false,
|
||||
showing: showing,
|
||||
text,
|
||||
}, {
|
||||
closed: () => {
|
||||
window.document.body.removeAttribute('inert');
|
||||
dispose();
|
||||
},
|
||||
});
|
||||
|
||||
return () => {
|
||||
showing.value = false;
|
||||
};
|
||||
}
|
||||
|
||||
export function form<F extends Form>(title: string, f: F): Promise<{ canceled: true, result?: undefined } | { canceled?: false, result: GetFormResultType<F> }> {
|
||||
|
|
|
@ -6,39 +6,126 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<PageWithAnimBg>
|
||||
<div :class="$style.formContainer">
|
||||
<form :class="$style.form" class="_panel" @submit.prevent="submit()">
|
||||
<div :class="$style.form" class="_panel">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="z-index:1;position:relative" viewBox="0 0 854 300">
|
||||
<defs>
|
||||
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#86b300"/><stop offset="100%" stop-color="#4ab300"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<g transform="translate(427, 150) scale(1, 1) translate(-427, -150)">
|
||||
<path d="" fill="url(#linear)" opacity="0.4">
|
||||
<animate
|
||||
attributeName="d"
|
||||
dur="20s"
|
||||
repeatCount="indefinite"
|
||||
keyTimes="0;0.333;0.667;1"
|
||||
calcmod="spline"
|
||||
keySplines="0.2 0 0.2 1;0.2 0 0.2 1;0.2 0 0.2 1"
|
||||
begin="0s"
|
||||
values="M0 0L 0 220Q 213.5 260 427 230T 854 255L 854 0 Z;M0 0L 0 245Q 213.5 260 427 240T 854 230L 854 0 Z;M0 0L 0 265Q 213.5 235 427 265T 854 230L 854 0 Z;M0 0L 0 220Q 213.5 260 427 230T 854 255L 854 0 Z"
|
||||
>
|
||||
</animate>
|
||||
</path>
|
||||
<path d="" fill="url(#linear)" opacity="0.4">
|
||||
<animate
|
||||
attributeName="d"
|
||||
dur="20s"
|
||||
repeatCount="indefinite"
|
||||
keyTimes="0;0.333;0.667;1"
|
||||
calcmod="spline"
|
||||
keySplines="0.2 0 0.2 1;0.2 0 0.2 1;0.2 0 0.2 1"
|
||||
begin="-10s"
|
||||
values="M0 0L 0 235Q 213.5 280 427 250T 854 260L 854 0 Z;M0 0L 0 250Q 213.5 220 427 220T 854 240L 854 0 Z;M0 0L 0 245Q 213.5 225 427 250T 854 265L 854 0 Z;M0 0L 0 235Q 213.5 280 427 250T 854 260L 854 0 Z"
|
||||
>
|
||||
</animate>
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
<div :class="$style.title">
|
||||
<div>Welcome to Misskey!</div>
|
||||
<div :class="$style.version">v{{ version }}</div>
|
||||
</div>
|
||||
<div class="_gaps_m" style="padding: 32px;">
|
||||
<div>{{ i18n.ts.intro }}</div>
|
||||
<MkInput v-model="setupPassword" type="password" data-cy-admin-initial-password>
|
||||
<template #label>{{ i18n.ts.initialPasswordForSetup }} <div v-tooltip:dialog="i18n.ts.initialPasswordForSetupDescription" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
</MkInput>
|
||||
<MkInput v-model="username" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" required data-cy-admin-username>
|
||||
<template #label>{{ i18n.ts.username }}</template>
|
||||
<template #prefix>@</template>
|
||||
<template #suffix>@{{ host }}</template>
|
||||
</MkInput>
|
||||
<MkInput v-model="password" type="password" data-cy-admin-password>
|
||||
<template #label>{{ i18n.ts.password }}</template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
</MkInput>
|
||||
<div>
|
||||
<MkButton gradate large rounded type="submit" :disabled="submitting" data-cy-admin-ok style="margin: 0 auto;">
|
||||
{{ submitting ? i18n.ts.processing : i18n.ts.done }}<MkEllipsis v-if="submitting"/>
|
||||
<div style="padding: 16px 32px 32px 32px;">
|
||||
<form v-if="!accountCreated" class="_gaps_m" @submit.prevent="createAccount()">
|
||||
<div style="text-align: center;" class="_gaps_s">
|
||||
<div><b>{{ i18n.ts._serverSetupWizard.installCompleted }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard.firstCreateAccount }}</div>
|
||||
</div>
|
||||
<MkInput v-model="setupPassword" type="password" data-cy-admin-initial-password>
|
||||
<template #label>{{ i18n.ts.initialPasswordForSetup }} <div v-tooltip:dialog="i18n.ts.initialPasswordForSetupDescription" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
</MkInput>
|
||||
<MkInput v-model="username" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" required data-cy-admin-username>
|
||||
<template #label>{{ i18n.ts.username }} <div v-tooltip:dialog="i18n.ts.usernameInfo" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
|
||||
<template #prefix>@</template>
|
||||
<template #suffix>@{{ host }}</template>
|
||||
</MkInput>
|
||||
<MkInput v-model="password" type="password" data-cy-admin-password>
|
||||
<template #label>{{ i18n.ts.password }}</template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
</MkInput>
|
||||
<div>
|
||||
<MkButton gradate large rounded :disabled="accountCreating" data-cy-admin-ok style="margin: 0 auto;" type="submit">
|
||||
{{ accountCreating ? i18n.ts.processing : i18n.ts.next }}<MkEllipsis v-if="accountCreating"/>
|
||||
</MkButton>
|
||||
</div>
|
||||
</form>
|
||||
<div v-else-if="step === 0" class="_gaps_m">
|
||||
<div style="text-align: center;" class="_gaps_s">
|
||||
<div><b>{{ i18n.ts._serverSetupWizard.accountCreated }}</b></div>
|
||||
</div>
|
||||
<MkButton gradate large rounded data-cy-next style="margin: 0 auto;" @click="step++">
|
||||
{{ i18n.ts.next }}
|
||||
</MkButton>
|
||||
</div>
|
||||
<div v-else-if="step === 1" class="_gaps_m">
|
||||
<div style="text-align: center;" class="_gaps_s">
|
||||
<div><b>{{ i18n.ts._serverSetupWizard.donationRequest }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard._donationRequest.text1 }}<br>{{ i18n.ts._serverSetupWizard._donationRequest.text2 }}<br>{{ i18n.ts._serverSetupWizard._donationRequest.text3 }}</div>
|
||||
</div>
|
||||
<MkLink target="_blank" url="https://misskey-hub.net/docs/donate/" style="margin: 0 auto;">{{ i18n.ts.learnMore }}</MkLink>
|
||||
<div class="_buttonsCenter">
|
||||
<MkButton gradate large rounded data-cy-next style="margin: 0 auto;" @click="step++">
|
||||
{{ i18n.ts.next }}
|
||||
</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="step === 2" class="_gaps_m">
|
||||
<div style="text-align: center;" class="_gaps_s">
|
||||
<div style="font-size: 120%;"><b>{{ i18n.ts._serverSetupWizard.serverSetting }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard.youCanEasilyConfigureOptimalServerSettingsWithThisWizard }}</div>
|
||||
<div>{{ i18n.ts._serverSetupWizard.settingsYouMakeHereCanBeChangedLater }}</div>
|
||||
</div>
|
||||
|
||||
<MkServerSetupWizard :token="token" @finished="onWizardFinished"/>
|
||||
|
||||
<MkButton rounded style="margin: 0 auto;" @click="skipSettings">
|
||||
{{ i18n.ts._serverSetupWizard.skipSettings }}
|
||||
</MkButton>
|
||||
</div>
|
||||
<div v-else-if="step === 3" class="_gaps_m">
|
||||
<div style="text-align: center;" class="_gaps_s">
|
||||
<div><b>{{ i18n.ts._serverSetupWizard.settingsCompleted }}</b></div>
|
||||
<div>{{ i18n.ts._serverSetupWizard.settingsCompleted_description }}</div>
|
||||
<div>{{ i18n.ts._serverSetupWizard.settingsCompleted_description2 }}</div>
|
||||
</div>
|
||||
<div class="_buttonsCenter">
|
||||
<MkButton gradate large rounded data-cy-next style="margin: 0 auto;" @click="finish">
|
||||
{{ i18n.ts.start }}
|
||||
</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</PageWithAnimBg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { host, version } from '@@/js/config.js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
|
@ -46,24 +133,33 @@ import * as os from '@/os.js';
|
|||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { login } from '@/accounts.js';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
import MkServerSetupWizard from '@/components/MkServerSetupWizard.vue';
|
||||
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
const setupPassword = ref('');
|
||||
const submitting = ref(false);
|
||||
const accountCreating = ref(false);
|
||||
const accountCreated = ref(false);
|
||||
const step = ref(0);
|
||||
|
||||
function submit() {
|
||||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
let token;
|
||||
|
||||
function createAccount() {
|
||||
if (accountCreating.value) return;
|
||||
accountCreating.value = true;
|
||||
|
||||
const _close = os.waiting();
|
||||
|
||||
misskeyApi('admin/accounts/create', {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
setupPassword: setupPassword.value === '' ? null : setupPassword.value,
|
||||
}).then(res => {
|
||||
return login(res.token);
|
||||
token = res.token;
|
||||
accountCreated.value = true;
|
||||
}).catch((err) => {
|
||||
submitting.value = false;
|
||||
accountCreating.value = false;
|
||||
|
||||
let title = i18n.ts.somethingHappened;
|
||||
let text = err.message + '\n' + err.id;
|
||||
|
@ -81,8 +177,22 @@ function submit() {
|
|||
title,
|
||||
text,
|
||||
});
|
||||
}).finally(() => {
|
||||
_close();
|
||||
});
|
||||
}
|
||||
|
||||
function onWizardFinished() {
|
||||
step.value++;
|
||||
}
|
||||
|
||||
function skipSettings() {
|
||||
step.value++;
|
||||
}
|
||||
|
||||
function finish() {
|
||||
login(token);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
@ -90,8 +200,7 @@ function submit() {
|
|||
min-height: 100svh;
|
||||
padding: 32px 32px 64px 32px;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
|
@ -100,16 +209,21 @@ function submit() {
|
|||
border-radius: var(--MI-radius);
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
overflow: clip;
|
||||
max-width: 500px;
|
||||
max-width: 550px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
background: var(--MI_THEME-accentedBg);
|
||||
color: var(--MI_THEME-accent);
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="note.files && note.files.length > 0" :class="$style.richcontent">
|
||||
<MkMediaList :mediaList="note.files.slice(0, 4)"/>
|
||||
</div>
|
||||
<div v-if="note.poll">
|
||||
<MkPoll :noteId="note.id" :poll="note.poll" :readOnly="true"/>
|
||||
</div>
|
||||
<div v-if="note.reactionCount > 0" :class="$style.reactions">
|
||||
<!-- TODO -->
|
||||
<!--<MkReactionsViewer :note="note" :maxNumber="16"/>-->
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"type": "module",
|
||||
"name": "misskey-js",
|
||||
"version": "2025.5.0",
|
||||
"version": "2025.5.1-alpha.0",
|
||||
"description": "Misskey SDK for JavaScript",
|
||||
"license": "MIT",
|
||||
"main": "./built/index.js",
|
||||
|
|
|
@ -4481,6 +4481,7 @@ export type components = {
|
|||
url?: string;
|
||||
reactionAndUserPairCache?: string[];
|
||||
clippedCount?: number;
|
||||
hasPoll?: boolean;
|
||||
myReaction?: string | null;
|
||||
};
|
||||
NoteReaction: {
|
||||
|
@ -8780,6 +8781,7 @@ export type operations = {
|
|||
software: string;
|
||||
versionRange: string;
|
||||
}[];
|
||||
singleUserMode: boolean;
|
||||
/** @enum {string} */
|
||||
ugcVisibilityForVisitor: 'all' | 'local' | 'none';
|
||||
};
|
||||
|
@ -11452,6 +11454,7 @@ export type operations = {
|
|||
software: string;
|
||||
versionRange: string;
|
||||
}[];
|
||||
singleUserMode?: boolean;
|
||||
/** @enum {string} */
|
||||
ugcVisibilityForVisitor?: 'all' | 'local' | 'none';
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue