Compare commits
19 Commits
feb2bcdd9e
...
2b8bd591a9
Author | SHA1 | Date |
---|---|---|
|
2b8bd591a9 | |
|
fe38115883 | |
|
6fba73ca13 | |
|
0d33e1f839 | |
|
74f33157a3 | |
|
ae10cad9a7 | |
|
ba9924abdb | |
|
99686801a0 | |
|
f3e0713501 | |
|
7fcbf57a9d | |
|
48232ca57b | |
|
3564bf5c66 | |
|
685fc2bd9d | |
|
6cc0138d1e | |
|
d3228d5570 | |
|
4a8ffe20a7 | |
|
5615675991 | |
|
0c65b8058a | |
|
82bec76cd4 |
|
@ -20,7 +20,9 @@
|
||||||
- Enhance: ウォーターマークにアカウントのQRコードを追加できるように
|
- Enhance: ウォーターマークにアカウントのQRコードを追加できるように
|
||||||
- Enhance: テーマをドラッグ&ドロップできるように
|
- Enhance: テーマをドラッグ&ドロップできるように
|
||||||
- Enhance: 絵文字ピッカーのサイズをより大きくできるように
|
- Enhance: 絵文字ピッカーのサイズをより大きくできるように
|
||||||
|
- Enhance: カスタム絵文字が多い場合にサーバーの絵文字一覧ページがフリーズしないように
|
||||||
- Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上
|
- Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上
|
||||||
|
- Enhance: 「お問い合わせ」ページから、バグの調査等に役立つ情報(OSやブラウザのバージョン等)を取得・コピーできるように
|
||||||
- Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正
|
- Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正
|
||||||
- Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正
|
- Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正
|
||||||
|
|
||||||
|
@ -1073,7 +1075,7 @@
|
||||||
- Fix: カスタム絵文字の画像読み込みに失敗した際はテキストではなくダミー画像を表示 #13487
|
- Fix: カスタム絵文字の画像読み込みに失敗した際はテキストではなくダミー画像を表示 #13487
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
-
|
- Fix: FTT有効かつDBフォールバック有効時、STLのようにタイムラインのソースが複数だとFTTとDBのフォールバック間で取得されないノートがある問題
|
||||||
|
|
||||||
## 2024.3.0
|
## 2024.3.0
|
||||||
|
|
||||||
|
|
|
@ -1010,6 +1010,7 @@ postForm: "أنشئ ملاحظة"
|
||||||
information: "عن"
|
information: "عن"
|
||||||
inMinutes: "د"
|
inMinutes: "د"
|
||||||
inDays: "ي"
|
inDays: "ي"
|
||||||
|
widgets: "التطبيقات المُصغّرة"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "دعوة"
|
invitations: "دعوة"
|
||||||
noHistory: "السجل فارغ"
|
noHistory: "السجل فارغ"
|
||||||
|
|
|
@ -850,6 +850,7 @@ postForm: "নোট লিখুন"
|
||||||
information: "আপনার সম্পর্কে"
|
information: "আপনার সম্পর্কে"
|
||||||
inMinutes: "মিনিট"
|
inMinutes: "মিনিট"
|
||||||
inDays: "দিন"
|
inDays: "দিন"
|
||||||
|
widgets: "উইজেটগুলি"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "আমন্ত্রণ"
|
invitations: "আমন্ত্রণ"
|
||||||
noHistory: "কোনো ইতিহাস নেই"
|
noHistory: "কোনো ইতিহাস নেই"
|
||||||
|
|
|
@ -334,6 +334,7 @@ fileName: "Nom del Fitxer"
|
||||||
selectFile: "Selecciona un fitxer"
|
selectFile: "Selecciona un fitxer"
|
||||||
selectFiles: "Selecciona fitxers"
|
selectFiles: "Selecciona fitxers"
|
||||||
selectFolder: "Selecció de carpeta"
|
selectFolder: "Selecció de carpeta"
|
||||||
|
unselectFolder: "Deixa de seleccionar la carpeta"
|
||||||
selectFolders: "Selecció de carpetes"
|
selectFolders: "Selecció de carpetes"
|
||||||
fileNotSelected: "Cap fitxer seleccionat"
|
fileNotSelected: "Cap fitxer seleccionat"
|
||||||
renameFile: "Canvia el nom del fitxer"
|
renameFile: "Canvia el nom del fitxer"
|
||||||
|
@ -346,6 +347,7 @@ addFile: "Afegeix un fitxer"
|
||||||
showFile: "Mostrar fitxer"
|
showFile: "Mostrar fitxer"
|
||||||
emptyDrive: "El teu Disc és buit"
|
emptyDrive: "El teu Disc és buit"
|
||||||
emptyFolder: "La carpeta està buida"
|
emptyFolder: "La carpeta està buida"
|
||||||
|
dropHereToUpload: "Arrossega els arxius fins aquí per pujar-los al servidor"
|
||||||
unableToDelete: "No es pot eliminar"
|
unableToDelete: "No es pot eliminar"
|
||||||
inputNewFileName: "Introduïu el nom de fitxer nou"
|
inputNewFileName: "Introduïu el nom de fitxer nou"
|
||||||
inputNewDescription: "Escriu el peu de foto."
|
inputNewDescription: "Escriu el peu de foto."
|
||||||
|
@ -1389,6 +1391,9 @@ scheduleToPostOnX: "Programar una nota per {x}"
|
||||||
scheduledToPostOnX: "S'ha programat la nota per {x}"
|
scheduledToPostOnX: "S'ha programat la nota per {x}"
|
||||||
schedule: "Programa"
|
schedule: "Programa"
|
||||||
scheduled: "Programat"
|
scheduled: "Programat"
|
||||||
|
widgets: "Ginys"
|
||||||
|
deviceInfo: "Informació del dispositiu"
|
||||||
|
deviceInfoDescription: "En fer consultes tècniques influir la següent informació pot ajudar a resoldre'l més ràpidament."
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "Qualitat alta"
|
high: "Qualitat alta"
|
||||||
|
@ -2431,6 +2436,7 @@ _auth:
|
||||||
scopeUser: "Opera com si fossis aquest usuari"
|
scopeUser: "Opera com si fossis aquest usuari"
|
||||||
pleaseLogin: "Si us plau, identificat per autoritzar l'aplicació."
|
pleaseLogin: "Si us plau, identificat per autoritzar l'aplicació."
|
||||||
byClickingYouWillBeRedirectedToThisUrl: "Si es garanteix l'accés, seràs redirigit automàticament a la següent adreça URL"
|
byClickingYouWillBeRedirectedToThisUrl: "Si es garanteix l'accés, seràs redirigit automàticament a la següent adreça URL"
|
||||||
|
alreadyAuthorized: "Aquesta aplicació ja té accés."
|
||||||
_antennaSources:
|
_antennaSources:
|
||||||
all: "Totes les publicacions"
|
all: "Totes les publicacions"
|
||||||
homeTimeline: "Publicacions dels usuaris seguits"
|
homeTimeline: "Publicacions dels usuaris seguits"
|
||||||
|
@ -2697,6 +2703,8 @@ _notification:
|
||||||
quote: "Citar"
|
quote: "Citar"
|
||||||
reaction: "Reaccions"
|
reaction: "Reaccions"
|
||||||
pollEnded: "Enquesta terminada"
|
pollEnded: "Enquesta terminada"
|
||||||
|
scheduledNotePosted: "Nota programada amb èxit "
|
||||||
|
scheduledNotePostFailed: "Ha fallat la programació de la nota"
|
||||||
receiveFollowRequest: "Rebuda una petició de seguiment"
|
receiveFollowRequest: "Rebuda una petició de seguiment"
|
||||||
followRequestAccepted: "Petició de seguiment acceptada"
|
followRequestAccepted: "Petició de seguiment acceptada"
|
||||||
roleAssigned: "Rol donat"
|
roleAssigned: "Rol donat"
|
||||||
|
|
|
@ -1109,6 +1109,7 @@ postForm: "Formulář pro odeslání"
|
||||||
information: "Informace"
|
information: "Informace"
|
||||||
inMinutes: "Minut"
|
inMinutes: "Minut"
|
||||||
inDays: "Dnů"
|
inDays: "Dnů"
|
||||||
|
widgets: "Widgety"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Pozvat"
|
invitations: "Pozvat"
|
||||||
noHistory: "Žádná historie"
|
noHistory: "Žádná historie"
|
||||||
|
|
|
@ -1370,6 +1370,7 @@ defaultImageCompressionLevel: "Standard-Bildkomprimierungsstufe"
|
||||||
defaultImageCompressionLevel_description: "Ein niedrigerer Wert erhält die Bildqualität, erhöht aber die Dateigröße. <br>Höhere Werte reduzieren die Dateigröße, verringern aber die Bildqualität."
|
defaultImageCompressionLevel_description: "Ein niedrigerer Wert erhält die Bildqualität, erhöht aber die Dateigröße. <br>Höhere Werte reduzieren die Dateigröße, verringern aber die Bildqualität."
|
||||||
inMinutes: "Minute(n)"
|
inMinutes: "Minute(n)"
|
||||||
inDays: "Tag(en)"
|
inDays: "Tag(en)"
|
||||||
|
widgets: "Widgets"
|
||||||
_order:
|
_order:
|
||||||
newest: "Neueste zuerst"
|
newest: "Neueste zuerst"
|
||||||
oldest: "Älteste zuerst"
|
oldest: "Älteste zuerst"
|
||||||
|
|
|
@ -288,6 +288,7 @@ replies: "Απάντηση"
|
||||||
renotes: "Κοινοποίηση σημειώματος"
|
renotes: "Κοινοποίηση σημειώματος"
|
||||||
postForm: "Φόρμα δημοσίευσης"
|
postForm: "Φόρμα δημοσίευσης"
|
||||||
information: "Πληροφορίες"
|
information: "Πληροφορίες"
|
||||||
|
widgets: "Μαραφέτια"
|
||||||
_chat:
|
_chat:
|
||||||
members: "Μέλη"
|
members: "Μέλη"
|
||||||
home: "Κεντρικό"
|
home: "Κεντρικό"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "Scheduled to note on {x}"
|
||||||
scheduledToPostOnX: "Note is scheduled for {x}"
|
scheduledToPostOnX: "Note is scheduled for {x}"
|
||||||
schedule: "Schedule"
|
schedule: "Schedule"
|
||||||
scheduled: "Scheduled"
|
scheduled: "Scheduled"
|
||||||
|
widgets: "Widgets"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "High quality"
|
high: "High quality"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "Programar una nota para {x}"
|
||||||
scheduledToPostOnX: "La nota está programada para {x}."
|
scheduledToPostOnX: "La nota está programada para {x}."
|
||||||
schedule: "Programado"
|
schedule: "Programado"
|
||||||
scheduled: "Programado"
|
scheduled: "Programado"
|
||||||
|
widgets: "Widgets"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "Calidad alta"
|
high: "Calidad alta"
|
||||||
|
|
|
@ -1273,6 +1273,7 @@ postForm: "Formulaire de publication"
|
||||||
information: "Informations"
|
information: "Informations"
|
||||||
inMinutes: "min"
|
inMinutes: "min"
|
||||||
inDays: "j"
|
inDays: "j"
|
||||||
|
widgets: "Widgets"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Inviter"
|
invitations: "Inviter"
|
||||||
noHistory: "Pas d'historique"
|
noHistory: "Pas d'historique"
|
||||||
|
|
|
@ -1264,6 +1264,7 @@ postForm: "Buat catatan"
|
||||||
information: "Informasi"
|
information: "Informasi"
|
||||||
inMinutes: "menit"
|
inMinutes: "menit"
|
||||||
inDays: "hari"
|
inDays: "hari"
|
||||||
|
widgets: "Widget"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Undang"
|
invitations: "Undang"
|
||||||
noHistory: "Tidak ada riwayat"
|
noHistory: "Tidak ada riwayat"
|
||||||
|
|
|
@ -1354,6 +1354,10 @@ export interface Locale extends ILocale {
|
||||||
* フォルダーを選択
|
* フォルダーを選択
|
||||||
*/
|
*/
|
||||||
"selectFolder": string;
|
"selectFolder": string;
|
||||||
|
/**
|
||||||
|
* フォルダーの選択を解除
|
||||||
|
*/
|
||||||
|
"unselectFolder": string;
|
||||||
/**
|
/**
|
||||||
* フォルダーを選択
|
* フォルダーを選択
|
||||||
*/
|
*/
|
||||||
|
@ -1402,6 +1406,10 @@ export interface Locale extends ILocale {
|
||||||
* フォルダーは空です
|
* フォルダーは空です
|
||||||
*/
|
*/
|
||||||
"emptyFolder": string;
|
"emptyFolder": string;
|
||||||
|
/**
|
||||||
|
* ここにファイルをドロップしてアップロード
|
||||||
|
*/
|
||||||
|
"dropHereToUpload": string;
|
||||||
/**
|
/**
|
||||||
* 削除できません
|
* 削除できません
|
||||||
*/
|
*/
|
||||||
|
@ -5581,6 +5589,14 @@ export interface Locale extends ILocale {
|
||||||
* ウィジェット
|
* ウィジェット
|
||||||
*/
|
*/
|
||||||
"widgets": string;
|
"widgets": string;
|
||||||
|
/**
|
||||||
|
* デバイス情報
|
||||||
|
*/
|
||||||
|
"deviceInfo": string;
|
||||||
|
/**
|
||||||
|
* 技術的なお問い合わせの際に、以下の情報を併記すると問題の解決に役立つことがあります。
|
||||||
|
*/
|
||||||
|
"deviceInfoDescription": string;
|
||||||
"_compression": {
|
"_compression": {
|
||||||
"_quality": {
|
"_quality": {
|
||||||
/**
|
/**
|
||||||
|
@ -9460,6 +9476,10 @@ export interface Locale extends ILocale {
|
||||||
* アクセスを許可すると、自動で以下のURLに遷移します
|
* アクセスを許可すると、自動で以下のURLに遷移します
|
||||||
*/
|
*/
|
||||||
"byClickingYouWillBeRedirectedToThisUrl": string;
|
"byClickingYouWillBeRedirectedToThisUrl": string;
|
||||||
|
/**
|
||||||
|
* このアプリケーションは既にアクセスが許可されています。
|
||||||
|
*/
|
||||||
|
"alreadyAuthorized": string;
|
||||||
};
|
};
|
||||||
"_antennaSources": {
|
"_antennaSources": {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "Pianificare la pubblicazione {x}"
|
||||||
scheduledToPostOnX: "Pubblicazione pianificata {x}"
|
scheduledToPostOnX: "Pubblicazione pianificata {x}"
|
||||||
schedule: "Pianificare"
|
schedule: "Pianificare"
|
||||||
scheduled: "Pianificata"
|
scheduled: "Pianificata"
|
||||||
|
widgets: "Riquadri"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "Alta qualità"
|
high: "Alta qualità"
|
||||||
|
|
|
@ -334,6 +334,7 @@ fileName: "ファイル名"
|
||||||
selectFile: "ファイルを選択"
|
selectFile: "ファイルを選択"
|
||||||
selectFiles: "ファイルを選択"
|
selectFiles: "ファイルを選択"
|
||||||
selectFolder: "フォルダーを選択"
|
selectFolder: "フォルダーを選択"
|
||||||
|
unselectFolder: "フォルダーの選択を解除"
|
||||||
selectFolders: "フォルダーを選択"
|
selectFolders: "フォルダーを選択"
|
||||||
fileNotSelected: "ファイルが選択されていません"
|
fileNotSelected: "ファイルが選択されていません"
|
||||||
renameFile: "ファイル名を変更"
|
renameFile: "ファイル名を変更"
|
||||||
|
@ -346,6 +347,7 @@ addFile: "ファイルを追加"
|
||||||
showFile: "ファイルを表示"
|
showFile: "ファイルを表示"
|
||||||
emptyDrive: "ドライブは空です"
|
emptyDrive: "ドライブは空です"
|
||||||
emptyFolder: "フォルダーは空です"
|
emptyFolder: "フォルダーは空です"
|
||||||
|
dropHereToUpload: "ここにファイルをドロップしてアップロード"
|
||||||
unableToDelete: "削除できません"
|
unableToDelete: "削除できません"
|
||||||
inputNewFileName: "新しいファイル名を入力してください"
|
inputNewFileName: "新しいファイル名を入力してください"
|
||||||
inputNewDescription: "新しいキャプションを入力してください"
|
inputNewDescription: "新しいキャプションを入力してください"
|
||||||
|
@ -1390,6 +1392,8 @@ scheduledToPostOnX: "{x}に投稿が予約されています"
|
||||||
schedule: "予約"
|
schedule: "予約"
|
||||||
scheduled: "予約"
|
scheduled: "予約"
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
|
deviceInfo: "デバイス情報"
|
||||||
|
deviceInfoDescription: "技術的なお問い合わせの際に、以下の情報を併記すると問題の解決に役立つことがあります。"
|
||||||
|
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
|
@ -2484,6 +2488,7 @@ _auth:
|
||||||
scopeUser: "以下のユーザーとして操作しています"
|
scopeUser: "以下のユーザーとして操作しています"
|
||||||
pleaseLogin: "アプリケーションにアクセス許可を与えるには、ログインが必要です。"
|
pleaseLogin: "アプリケーションにアクセス許可を与えるには、ログインが必要です。"
|
||||||
byClickingYouWillBeRedirectedToThisUrl: "アクセスを許可すると、自動で以下のURLに遷移します"
|
byClickingYouWillBeRedirectedToThisUrl: "アクセスを許可すると、自動で以下のURLに遷移します"
|
||||||
|
alreadyAuthorized: "このアプリケーションは既にアクセスが許可されています。"
|
||||||
|
|
||||||
_antennaSources:
|
_antennaSources:
|
||||||
all: "全てのノート"
|
all: "全てのノート"
|
||||||
|
|
|
@ -1337,6 +1337,7 @@ safeModeEnabled: "セーフモードがオンになってるで"
|
||||||
pluginsAreDisabledBecauseSafeMode: "セーフモードがオンやから、プラグインは全部無効化されてるで。"
|
pluginsAreDisabledBecauseSafeMode: "セーフモードがオンやから、プラグインは全部無効化されてるで。"
|
||||||
customCssIsDisabledBecauseSafeMode: "セーフモードがオンやから、カスタムCSSは適用されてへんで。"
|
customCssIsDisabledBecauseSafeMode: "セーフモードがオンやから、カスタムCSSは適用されてへんで。"
|
||||||
themeIsDefaultBecauseSafeMode: "セーフモードがオンの間はデフォルトのテーマを使うで。セーフモードをオフにれば元に戻るで。"
|
themeIsDefaultBecauseSafeMode: "セーフモードがオンの間はデフォルトのテーマを使うで。セーフモードをオフにれば元に戻るで。"
|
||||||
|
widgets: "ウィジェット"
|
||||||
_chat:
|
_chat:
|
||||||
noMessagesYet: "まだメッセージはあらへんで"
|
noMessagesYet: "まだメッセージはあらへんで"
|
||||||
individualChat_description: "特定のユーザーと一対一でチャットができるで。"
|
individualChat_description: "特定のユーザーと一対一でチャットができるで。"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "{x}에 게시를 예약합니다."
|
||||||
scheduledToPostOnX: "{x}에 게시가 예약돼있습니다."
|
scheduledToPostOnX: "{x}에 게시가 예약돼있습니다."
|
||||||
schedule: "예약"
|
schedule: "예약"
|
||||||
scheduled: "예약"
|
scheduled: "예약"
|
||||||
|
widgets: "위젯"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "고품질"
|
high: "고품질"
|
||||||
|
|
|
@ -1042,6 +1042,7 @@ postForm: "Formularz tworzenia wpisu"
|
||||||
information: "Informacje"
|
information: "Informacje"
|
||||||
inMinutes: "minuta"
|
inMinutes: "minuta"
|
||||||
inDays: "dzień"
|
inDays: "dzień"
|
||||||
|
widgets: "Widżety"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Zaproś"
|
invitations: "Zaproś"
|
||||||
noHistory: "Brak historii"
|
noHistory: "Brak historii"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "Agendar nota para {x}"
|
||||||
scheduledToPostOnX: "A nota está agendada para {x}"
|
scheduledToPostOnX: "A nota está agendada para {x}"
|
||||||
schedule: "Agendar"
|
schedule: "Agendar"
|
||||||
scheduled: "Agendado"
|
scheduled: "Agendado"
|
||||||
|
widgets: "Widgets"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "Qualidade alta"
|
high: "Qualidade alta"
|
||||||
|
|
|
@ -1277,6 +1277,7 @@ textCount: "Количество символов"
|
||||||
information: "Описание"
|
information: "Описание"
|
||||||
inMinutes: "мин"
|
inMinutes: "мин"
|
||||||
inDays: "сут"
|
inDays: "сут"
|
||||||
|
widgets: "Виджеты"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Пригласить"
|
invitations: "Пригласить"
|
||||||
noHistory: "История пока пуста"
|
noHistory: "История пока пуста"
|
||||||
|
|
|
@ -915,6 +915,7 @@ postForm: "Napísať poznámku"
|
||||||
information: "Informácie"
|
information: "Informácie"
|
||||||
inMinutes: "min"
|
inMinutes: "min"
|
||||||
inDays: "dní"
|
inDays: "dní"
|
||||||
|
widgets: "Widgety"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Pozvať"
|
invitations: "Pozvať"
|
||||||
noHistory: "Žiadna história"
|
noHistory: "Žiadna história"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "กำหนดเวลาให้โพสต์ไว้
|
||||||
scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}"
|
scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}"
|
||||||
schedule: "กำหนดเวลา"
|
schedule: "กำหนดเวลา"
|
||||||
scheduled: "กำหนดเวลา"
|
scheduled: "กำหนดเวลา"
|
||||||
|
widgets: "วิดเจ็ต"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "คุณภาพสูง"
|
high: "คุณภาพสูง"
|
||||||
|
|
|
@ -1378,6 +1378,7 @@ pluginsAreDisabledBecauseSafeMode: "Güvenli mod etkinleştirildiği için tüm
|
||||||
customCssIsDisabledBecauseSafeMode: "Güvenli mod etkin olduğu için özel CSS uygulanmıyor."
|
customCssIsDisabledBecauseSafeMode: "Güvenli mod etkin olduğu için özel CSS uygulanmıyor."
|
||||||
themeIsDefaultBecauseSafeMode: "Güvenli mod etkinken, varsayılan tema kullanılır. Güvenli modu devre dışı bırakmak bu değişiklikleri geri alır."
|
themeIsDefaultBecauseSafeMode: "Güvenli mod etkinken, varsayılan tema kullanılır. Güvenli modu devre dışı bırakmak bu değişiklikleri geri alır."
|
||||||
thankYouForTestingBeta: "Beta sürümünü test ettiğin için teşekkür ederiz!"
|
thankYouForTestingBeta: "Beta sürümünü test ettiğin için teşekkür ederiz!"
|
||||||
|
widgets: "Widget'lar"
|
||||||
_order:
|
_order:
|
||||||
newest: "Önce yeni"
|
newest: "Önce yeni"
|
||||||
oldest: "Önce eski"
|
oldest: "Önce eski"
|
||||||
|
|
|
@ -921,6 +921,7 @@ postForm: "Створення нотатки"
|
||||||
information: "Інформація"
|
information: "Інформація"
|
||||||
inMinutes: "х"
|
inMinutes: "х"
|
||||||
inDays: "д"
|
inDays: "д"
|
||||||
|
widgets: "Віджети"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Запросити"
|
invitations: "Запросити"
|
||||||
noHistory: "Історія порожня"
|
noHistory: "Історія порожня"
|
||||||
|
|
|
@ -1222,6 +1222,7 @@ migrateOldSettings: "Di chuyển cài đặt cũ"
|
||||||
migrateOldSettings_description: "Thông thường, quá trình này diễn ra tự động, nhưng nếu vì lý do nào đó mà quá trình di chuyển không thành công, bạn có thể kích hoạt thủ công quy trình di chuyển, quá trình này sẽ ghi đè lên thông tin cấu hình hiện tại của bạn."
|
migrateOldSettings_description: "Thông thường, quá trình này diễn ra tự động, nhưng nếu vì lý do nào đó mà quá trình di chuyển không thành công, bạn có thể kích hoạt thủ công quy trình di chuyển, quá trình này sẽ ghi đè lên thông tin cấu hình hiện tại của bạn."
|
||||||
inMinutes: "phút"
|
inMinutes: "phút"
|
||||||
inDays: "ngày"
|
inDays: "ngày"
|
||||||
|
widgets: "Tiện ích"
|
||||||
_chat:
|
_chat:
|
||||||
invitations: "Mời"
|
invitations: "Mời"
|
||||||
noHistory: "Không có dữ liệu"
|
noHistory: "Không có dữ liệu"
|
||||||
|
|
|
@ -56,7 +56,7 @@ deleteAndEdit: "删除并编辑"
|
||||||
deleteAndEditConfirm: "要删除此帖并再次编辑吗?对此帖的所有回应、转发和回复也将被删除。"
|
deleteAndEditConfirm: "要删除此帖并再次编辑吗?对此帖的所有回应、转发和回复也将被删除。"
|
||||||
addToList: "添加至列表"
|
addToList: "添加至列表"
|
||||||
addToAntenna: "添加到天线"
|
addToAntenna: "添加到天线"
|
||||||
sendMessage: "发送"
|
sendMessage: "发送消息"
|
||||||
copyRSS: "复制RSS"
|
copyRSS: "复制RSS"
|
||||||
copyUsername: "复制用户名"
|
copyUsername: "复制用户名"
|
||||||
copyUserId: "复制用户 ID"
|
copyUserId: "复制用户 ID"
|
||||||
|
@ -334,6 +334,7 @@ fileName: "文件名称"
|
||||||
selectFile: "选择文件"
|
selectFile: "选择文件"
|
||||||
selectFiles: "选择文件"
|
selectFiles: "选择文件"
|
||||||
selectFolder: "选择文件夹"
|
selectFolder: "选择文件夹"
|
||||||
|
unselectFolder: "取消全选文件夹"
|
||||||
selectFolders: "选择多个文件夹"
|
selectFolders: "选择多个文件夹"
|
||||||
fileNotSelected: "未选择文件"
|
fileNotSelected: "未选择文件"
|
||||||
renameFile: "重命名文件"
|
renameFile: "重命名文件"
|
||||||
|
@ -346,6 +347,7 @@ addFile: "添加文件"
|
||||||
showFile: "显示文件"
|
showFile: "显示文件"
|
||||||
emptyDrive: "网盘中无文件"
|
emptyDrive: "网盘中无文件"
|
||||||
emptyFolder: "此文件夹中无文件"
|
emptyFolder: "此文件夹中无文件"
|
||||||
|
dropHereToUpload: "将文件拖动到这里来上传"
|
||||||
unableToDelete: "无法删除"
|
unableToDelete: "无法删除"
|
||||||
inputNewFileName: "请输入新文件名"
|
inputNewFileName: "请输入新文件名"
|
||||||
inputNewDescription: "请输入新标题"
|
inputNewDescription: "请输入新标题"
|
||||||
|
@ -1389,6 +1391,9 @@ scheduleToPostOnX: "预定在 {x} 发出"
|
||||||
scheduledToPostOnX: "已预定在 {x} 发出"
|
scheduledToPostOnX: "已预定在 {x} 发出"
|
||||||
schedule: "定时"
|
schedule: "定时"
|
||||||
scheduled: "定时"
|
scheduled: "定时"
|
||||||
|
widgets: "小工具"
|
||||||
|
deviceInfo: "设备信息"
|
||||||
|
deviceInfoDescription: "咨询技术问题时,将以下信息一并发送有助于解决问题。"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "高质量"
|
high: "高质量"
|
||||||
|
@ -2431,6 +2436,7 @@ _auth:
|
||||||
scopeUser: "以下面的用户进行操作"
|
scopeUser: "以下面的用户进行操作"
|
||||||
pleaseLogin: "在对应用进行授权许可之前,请先登录"
|
pleaseLogin: "在对应用进行授权许可之前,请先登录"
|
||||||
byClickingYouWillBeRedirectedToThisUrl: "允许访问后将会自动重定向到以下 URL"
|
byClickingYouWillBeRedirectedToThisUrl: "允许访问后将会自动重定向到以下 URL"
|
||||||
|
alreadyAuthorized: "此应用已有访问许可。"
|
||||||
_antennaSources:
|
_antennaSources:
|
||||||
all: "所有帖子"
|
all: "所有帖子"
|
||||||
homeTimeline: "已关注用户的帖子"
|
homeTimeline: "已关注用户的帖子"
|
||||||
|
@ -2697,6 +2703,8 @@ _notification:
|
||||||
quote: "引用"
|
quote: "引用"
|
||||||
reaction: "回应"
|
reaction: "回应"
|
||||||
pollEnded: "问卷调查结束"
|
pollEnded: "问卷调查结束"
|
||||||
|
scheduledNotePosted: "定时发送成功"
|
||||||
|
scheduledNotePostFailed: "定时发送失败"
|
||||||
receiveFollowRequest: "收到关注请求"
|
receiveFollowRequest: "收到关注请求"
|
||||||
followRequestAccepted: "关注请求已通过"
|
followRequestAccepted: "关注请求已通过"
|
||||||
roleAssigned: "授予的角色"
|
roleAssigned: "授予的角色"
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ scheduleToPostOnX: "排定在 {x} 發布"
|
||||||
scheduledToPostOnX: "已排定在 {x} 發布貼文"
|
scheduledToPostOnX: "已排定在 {x} 發布貼文"
|
||||||
schedule: "排定"
|
schedule: "排定"
|
||||||
scheduled: "排定"
|
scheduled: "排定"
|
||||||
|
widgets: "小工具"
|
||||||
_compression:
|
_compression:
|
||||||
_quality:
|
_quality:
|
||||||
high: "高品質"
|
high: "高品質"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2025.10.0-beta.1",
|
"version": "2025.10.0-beta.2",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -40,6 +40,7 @@ type TimelineOptions = {
|
||||||
excludePureRenotes: boolean;
|
excludePureRenotes: boolean;
|
||||||
ignoreAuthorFromUserSuspension?: boolean;
|
ignoreAuthorFromUserSuspension?: boolean;
|
||||||
dbFallback: (untilId: string | null, sinceId: string | null, limit: number) => Promise<MiNote[]>,
|
dbFallback: (untilId: string | null, sinceId: string | null, limit: number) => Promise<MiNote[]>,
|
||||||
|
preventEmptyTimelineDbFallback?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -73,12 +74,20 @@ export class FanoutTimelineEndpointService {
|
||||||
|
|
||||||
const redisResult = await this.fanoutTimelineService.getMulti(ps.redisTimelines, ps.untilId, ps.sinceId);
|
const redisResult = await this.fanoutTimelineService.getMulti(ps.redisTimelines, ps.untilId, ps.sinceId);
|
||||||
|
|
||||||
// TODO: いい感じにgetMulti内でソート済だからuniqするときにredisResultが全てソート済なのを利用して再ソートを避けたい
|
// オプション無効時、取得したredisResultのうち、2つ以上ソースがあり、1つでも空であればDBにフォールバックする
|
||||||
const redisResultIds = Array.from(new Set(redisResult.flat(1))).sort(idCompare);
|
let shouldFallbackToDb = ps.useDbFallback &&
|
||||||
|
(ps.preventEmptyTimelineDbFallback !== true && redisResult.length > 1 && redisResult.some(ids => ids.length === 0));
|
||||||
|
|
||||||
|
// 取得したresultの中で最古のIDのうち、最も新しいものを取得
|
||||||
|
const fttThresholdId = redisResult.map(ids => ids[0]).sort()[0];
|
||||||
|
|
||||||
|
// TODO: いい感じにgetMulti内でソート済だからuniqするときにredisResultが全てソート済なのを利用して再ソートを避けたい
|
||||||
|
const redisResultIds = shouldFallbackToDb ? [] : Array.from(new Set(redisResult.flat(1))).sort(idCompare);
|
||||||
|
|
||||||
|
let noteIds = redisResultIds.filter(id => id >= fttThresholdId).slice(0, ps.limit);
|
||||||
|
|
||||||
let noteIds = redisResultIds.slice(0, ps.limit);
|
|
||||||
const oldestNoteId = ascending ? redisResultIds[0] : redisResultIds[redisResultIds.length - 1];
|
const oldestNoteId = ascending ? redisResultIds[0] : redisResultIds[redisResultIds.length - 1];
|
||||||
const shouldFallbackToDb = noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId;
|
shouldFallbackToDb ||= ps.useDbFallback && (noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId);
|
||||||
|
|
||||||
if (!shouldFallbackToDb) {
|
if (!shouldFallbackToDb) {
|
||||||
let filter = ps.noteFilter ?? (_note => true) as NoteFilter;
|
let filter = ps.noteFilter ?? (_note => true) as NoteFilter;
|
||||||
|
|
|
@ -192,7 +192,7 @@ export const paramDef = {
|
||||||
scheduledAt: { type: 'integer', nullable: true },
|
scheduledAt: { type: 'integer', nullable: true },
|
||||||
isActuallyScheduled: { type: 'boolean', default: false },
|
isActuallyScheduled: { type: 'boolean', default: false },
|
||||||
},
|
},
|
||||||
required: ['visibility', 'visibleUserIds', 'cw', 'hashtag', 'localOnly', 'reactionAcceptance', 'replyId', 'renoteId', 'channelId', 'text', 'fileIds', 'poll', 'scheduledAt', 'isActuallyScheduled'],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -203,22 +203,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const draft = await this.noteDraftService.create(me, {
|
const draft = await this.noteDraftService.create(me, {
|
||||||
fileIds: ps.fileIds,
|
fileIds: ps.fileIds ?? [],
|
||||||
pollChoices: ps.poll?.choices ?? [],
|
pollChoices: ps.poll?.choices ?? [],
|
||||||
pollMultiple: ps.poll?.multiple ?? false,
|
pollMultiple: ps.poll?.multiple ?? false,
|
||||||
pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null,
|
pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null,
|
||||||
pollExpiredAfter: ps.poll?.expiredAfter ?? null,
|
pollExpiredAfter: ps.poll?.expiredAfter ?? null,
|
||||||
hasPoll: ps.poll != null,
|
hasPoll: ps.poll != null,
|
||||||
text: ps.text,
|
text: ps.text ?? null,
|
||||||
replyId: ps.replyId,
|
replyId: ps.replyId ?? null,
|
||||||
renoteId: ps.renoteId,
|
renoteId: ps.renoteId ?? null,
|
||||||
cw: ps.cw,
|
cw: ps.cw ?? null,
|
||||||
hashtag: ps.hashtag,
|
hashtag: ps.hashtag ?? null,
|
||||||
localOnly: ps.localOnly,
|
localOnly: ps.localOnly,
|
||||||
reactionAcceptance: ps.reactionAcceptance,
|
reactionAcceptance: ps.reactionAcceptance,
|
||||||
visibility: ps.visibility,
|
visibility: ps.visibility,
|
||||||
visibleUserIds: ps.visibleUserIds,
|
visibleUserIds: ps.visibleUserIds ?? [],
|
||||||
channelId: ps.channelId,
|
channelId: ps.channelId ?? null,
|
||||||
scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null,
|
scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null,
|
||||||
isActuallyScheduled: ps.isActuallyScheduled,
|
isActuallyScheduled: ps.isActuallyScheduled,
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
|
@ -150,6 +150,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
withFiles: ps.withFiles,
|
withFiles: ps.withFiles,
|
||||||
withRenotes: ps.withRenotes,
|
withRenotes: ps.withRenotes,
|
||||||
}, me),
|
}, me),
|
||||||
|
preventEmptyTimelineDbFallback: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return timeline;
|
return timeline;
|
||||||
|
|
|
@ -5,7 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<template>
|
<template>
|
||||||
<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }, (darkMode ? $style.dark : $style.light)]" v-html="html"></div>
|
<div
|
||||||
|
:class="[$style.codeBlockRoot, {
|
||||||
|
[$style.codeEditor]: codeEditor,
|
||||||
|
[$style.outerStyle]: !codeEditor && withOuterStyle,
|
||||||
|
[$style.dark]: darkMode,
|
||||||
|
[$style.light]: !darkMode,
|
||||||
|
}]" v-html="html"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -15,11 +21,15 @@ import type { BundledLanguage } from 'shiki/langs';
|
||||||
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
|
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
|
||||||
import { store } from '@/store.js';
|
import { store } from '@/store.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
code: string;
|
code: string;
|
||||||
lang?: string;
|
lang?: string;
|
||||||
codeEditor?: boolean;
|
codeEditor?: boolean;
|
||||||
}>();
|
withOuterStyle?: boolean;
|
||||||
|
}>(), {
|
||||||
|
codeEditor: false,
|
||||||
|
withOuterStyle: true,
|
||||||
|
});
|
||||||
|
|
||||||
const highlighter = await getHighlighter();
|
const highlighter = await getHighlighter();
|
||||||
const darkMode = store.r.darkMode;
|
const darkMode = store.r.darkMode;
|
||||||
|
@ -73,17 +83,13 @@ watch(() => props.lang, (to) => {
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
.codeBlockRoot :global(.shiki) {
|
.codeBlockRoot :global(.shiki) {
|
||||||
padding: 1em;
|
|
||||||
margin: 0;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||||
|
|
||||||
color: var(--shiki-fallback);
|
color: var(--shiki-fallback);
|
||||||
background-color: var(--shiki-fallback-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-fallback);
|
color: var(--shiki-fallback);
|
||||||
background-color: var(--shiki-fallback-bg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& pre,
|
& pre,
|
||||||
|
@ -92,26 +98,40 @@ watch(() => props.lang, (to) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.outerStyle.codeBlockRoot :global(.shiki) {
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--MI_THEME-divider);
|
||||||
|
background-color: var(--shiki-fallback-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.light.codeBlockRoot :global(.shiki) {
|
.light.codeBlockRoot :global(.shiki) {
|
||||||
color: var(--shiki-light);
|
color: var(--shiki-light);
|
||||||
background-color: var(--shiki-light-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-light);
|
color: var(--shiki-light);
|
||||||
background-color: var(--shiki-light-bg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.light.outerStyle.codeBlockRoot :global(.shiki),
|
||||||
|
.light.codeEditor.codeBlockRoot :global(.shiki) {
|
||||||
|
background-color: var(--shiki-light-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.dark.codeBlockRoot :global(.shiki) {
|
.dark.codeBlockRoot :global(.shiki) {
|
||||||
color: var(--shiki-dark);
|
color: var(--shiki-dark);
|
||||||
background-color: var(--shiki-dark-bg);
|
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--shiki-dark);
|
color: var(--shiki-dark);
|
||||||
background-color: var(--shiki-dark-bg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark.outerStyle.codeBlockRoot :global(.shiki),
|
||||||
|
.dark.codeEditor.codeBlockRoot :global(.shiki) {
|
||||||
|
background-color: var(--shiki-dark-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.codeBlockRoot.codeEditor {
|
.codeBlockRoot.codeEditor {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -5,15 +5,32 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.codeBlockRoot">
|
<div :class="$style.codeBlockRoot">
|
||||||
<button v-if="copyButton" :class="$style.codeBlockCopyButton" class="_button" @click="copy">
|
<button v-if="copyButton" :class="[$style.codeBlockCopyButton, { [$style.withOuterStyle]: withOuterStyle }]" class="_button" @click="copy">
|
||||||
<i class="ti ti-copy"></i>
|
<i class="ti ti-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<template #fallback>
|
<template #fallback>
|
||||||
<MkLoading/>
|
<pre
|
||||||
|
class="_selectable"
|
||||||
|
:class="[$style.codeBlockFallbackRoot, {
|
||||||
|
[$style.outerStyle]: withOuterStyle,
|
||||||
|
}]"
|
||||||
|
><code :class="$style.codeBlockFallbackCode">Loading...</code></pre>
|
||||||
</template>
|
</template>
|
||||||
<XCode v-if="show && lang" class="_selectable" :code="code" :lang="lang"/>
|
<XCode
|
||||||
<pre v-else-if="show" class="_selectable" :class="$style.codeBlockFallbackRoot"><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
|
v-if="show && lang"
|
||||||
|
class="_selectable"
|
||||||
|
:code="code"
|
||||||
|
:lang="lang"
|
||||||
|
:withOuterStyle="withOuterStyle"
|
||||||
|
/>
|
||||||
|
<pre
|
||||||
|
v-else-if="show"
|
||||||
|
class="_selectable"
|
||||||
|
:class="[$style.codeBlockFallbackRoot, {
|
||||||
|
[$style.outerStyle]: withOuterStyle,
|
||||||
|
}]"
|
||||||
|
><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
|
||||||
<button v-else :class="$style.codePlaceholderRoot" @click="show = true">
|
<button v-else :class="$style.codePlaceholderRoot" @click="show = true">
|
||||||
<div :class="$style.codePlaceholderContainer">
|
<div :class="$style.codePlaceholderContainer">
|
||||||
<div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div>
|
<div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div>
|
||||||
|
@ -26,8 +43,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, ref } from 'vue';
|
import { defineAsyncComponent, ref } from 'vue';
|
||||||
import * as os from '@/os.js';
|
|
||||||
import MkLoading from '@/components/global/MkLoading.vue';
|
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
|
@ -36,10 +51,12 @@ const props = withDefaults(defineProps<{
|
||||||
code: string;
|
code: string;
|
||||||
forceShow?: boolean;
|
forceShow?: boolean;
|
||||||
copyButton?: boolean;
|
copyButton?: boolean;
|
||||||
|
withOuterStyle?: boolean;
|
||||||
lang?: string;
|
lang?: string;
|
||||||
}>(), {
|
}>(), {
|
||||||
copyButton: true,
|
copyButton: true,
|
||||||
forceShow: false,
|
forceShow: false,
|
||||||
|
withOuterStyle: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
|
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
|
||||||
|
@ -58,10 +75,16 @@ function copy() {
|
||||||
|
|
||||||
.codeBlockCopyButton {
|
.codeBlockCopyButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
&.withOuterStyle {
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
@ -70,11 +93,17 @@ function copy() {
|
||||||
.codeBlockFallbackRoot {
|
.codeBlockFallbackRoot {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
padding: 1em;
|
|
||||||
margin: 0;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.outerStyle.codeBlockFallbackRoot {
|
||||||
|
background: var(--MI_THEME-bg);
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--MI_THEME-divider);
|
||||||
|
}
|
||||||
|
|
||||||
.codeBlockFallbackCode {
|
.codeBlockFallbackCode {
|
||||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,18 +35,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-if="select === 'folder'">
|
<div v-if="select === 'folder'">
|
||||||
<template v-if="folder == null">
|
<template v-if="folder == null">
|
||||||
<MkButton v-if="!isRootSelected" @click="isRootSelected = true">
|
<MkButton v-if="!isRootSelected" @click="isRootSelected = true">
|
||||||
<i class="ti ti-square"></i> {{ i18n.ts.selectThisFolder }}
|
<i class="ti ti-square"></i> {{ i18n.ts.selectFolder }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
<MkButton v-else @click="isRootSelected = false">
|
<MkButton v-else @click="isRootSelected = false">
|
||||||
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectThisFolder }}
|
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectFolder }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<MkButton v-if="!selectedFolders.some(f => f.id === folder!.id)" @click="selectedFolders.push(folder)">
|
<MkButton v-if="!selectedFolders.some(f => f.id === folder!.id)" @click="selectedFolders.push(folder)">
|
||||||
<i class="ti ti-square"></i> {{ i18n.ts.selectThisFolder }}
|
<i class="ti ti-square"></i> {{ i18n.ts.selectFolder }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
<MkButton v-else @click="selectedFolders = selectedFolders.filter(f => f.id !== folder!.id)">
|
<MkButton v-else @click="selectedFolders = selectedFolders.filter(f => f.id !== folder!.id)">
|
||||||
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectThisFolder }}
|
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectFolder }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,7 +112,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton v-show="filesPaginator.canFetchOlder.value" :class="$style.loadMore" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
|
<MkButton v-show="filesPaginator.canFetchOlder.value" :class="$style.loadMore" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
|
||||||
|
|
||||||
<div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty">
|
<div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty">
|
||||||
<div v-if="draghover">{{ i18n.ts['empty-draghover'] }}</div>
|
<div v-if="draghover">{{ i18n.ts.dropHereToUpload }}</div>
|
||||||
<div v-if="!draghover && folder == null"><strong>{{ i18n.ts.emptyDrive }}</strong></div>
|
<div v-if="!draghover && folder == null"><strong>{{ i18n.ts.emptyDrive }}</strong></div>
|
||||||
<div v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</div>
|
<div v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -96,7 +96,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
import { nextTick, onMounted, ref, useTemplateRef, watch } from 'vue';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { getBgColor } from '@/utility/get-bg-color.js';
|
import { getBgColor } from '@/utility/get-bg-color.js';
|
||||||
import { pageFolderTeleportCount, popup } from '@/os.js';
|
import { pageFolderTeleportCount, popup } from '@/os.js';
|
||||||
|
@ -119,6 +119,11 @@ const props = withDefaults(defineProps<{
|
||||||
canPage: true,
|
canPage: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(ev: 'opened'): void;
|
||||||
|
(ev: 'closed'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const rootEl = useTemplateRef('rootEl');
|
const rootEl = useTemplateRef('rootEl');
|
||||||
const asPage = props.canPage && deviceKind === 'smartphone' && prefer.s['experimental.enableFolderPageView'];
|
const asPage = props.canPage && deviceKind === 'smartphone' && prefer.s['experimental.enableFolderPageView'];
|
||||||
const bgSame = ref(false);
|
const bgSame = ref(false);
|
||||||
|
@ -164,7 +169,7 @@ function afterLeave(el: Element) {
|
||||||
let pageId = pageFolderTeleportCount.value;
|
let pageId = pageFolderTeleportCount.value;
|
||||||
pageFolderTeleportCount.value += 1000;
|
pageFolderTeleportCount.value += 1000;
|
||||||
|
|
||||||
async function toggle() {
|
async function toggle(ev: MouseEvent) {
|
||||||
if (asPage && !opened.value) {
|
if (asPage && !opened.value) {
|
||||||
pageId++;
|
pageId++;
|
||||||
const { dispose } = await popup(MkFolderPage, {
|
const { dispose } = await popup(MkFolderPage, {
|
||||||
|
@ -192,6 +197,14 @@ onMounted(() => {
|
||||||
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
const myBg = computedStyle.getPropertyValue('--MI_THEME-panel');
|
||||||
bgSame.value = parentBg === myBg;
|
bgSame.value = parentBg === myBg;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(opened, (isOpened) => {
|
||||||
|
if (isOpened) {
|
||||||
|
emit('opened');
|
||||||
|
} else {
|
||||||
|
emit('closed');
|
||||||
|
}
|
||||||
|
}, { flush: 'post' });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
|
@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MkKeyValue>
|
<MkKeyValue>
|
||||||
<template #key>{{ i18n.ts.id }}</template>
|
<template #key>{{ i18n.ts.name }}</template>
|
||||||
<template #value>{{ name }}</template>
|
<template #value>{{ name }}</template>
|
||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
<MkKeyValue>
|
<MkKeyValue>
|
||||||
|
|
|
@ -68,7 +68,7 @@ export type GetMkSelectValueTypesFromDef<T extends MkSelectItem[]> = T[number] e
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup generic="const ITEMS extends MkSelectItem[], MODELT extends OptionValue">
|
<script lang="ts" setup generic="const ITEMS extends MkSelectItem[], MODELT extends OptionValue">
|
||||||
import { onMounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
import { onMounted, nextTick, ref, watch, computed, toRefs, useTemplateRef } from 'vue';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
import type { MenuItem } from '@/types/menu.js';
|
import type { MenuItem } from '@/types/menu.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
|
@ -87,8 +87,8 @@ const props = defineProps<{
|
||||||
|
|
||||||
type ModelTChecked = MODELT & (
|
type ModelTChecked = MODELT & (
|
||||||
MODELT extends GetMkSelectValueTypesFromDef<ITEMS>
|
MODELT extends GetMkSelectValueTypesFromDef<ITEMS>
|
||||||
? unknown
|
? unknown
|
||||||
: 'Error: The type of model does not match the type of items.'
|
: 'Error: The type of model does not match the type of items.'
|
||||||
);
|
);
|
||||||
|
|
||||||
const model = defineModel<ModelTChecked>({ required: true });
|
const model = defineModel<ModelTChecked>({ required: true });
|
||||||
|
@ -97,10 +97,10 @@ const { autofocus } = toRefs(props);
|
||||||
const focused = ref(false);
|
const focused = ref(false);
|
||||||
const opening = ref(false);
|
const opening = ref(false);
|
||||||
const currentValueText = ref<string | null>(null);
|
const currentValueText = ref<string | null>(null);
|
||||||
const inputEl = ref<HTMLObjectElement | null>(null);
|
const inputEl = useTemplateRef('inputEl');
|
||||||
const prefixEl = ref<HTMLElement | null>(null);
|
const prefixEl = useTemplateRef('prefixEl');
|
||||||
const suffixEl = ref<HTMLElement | null>(null);
|
const suffixEl = useTemplateRef('suffixEl');
|
||||||
const container = ref<HTMLElement | null>(null);
|
const container = useTemplateRef('container');
|
||||||
const height =
|
const height =
|
||||||
props.small ? 33 :
|
props.small ? 33 :
|
||||||
props.large ? 39 :
|
props.large ? 39 :
|
||||||
|
|
|
@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</MkFoldableSection>
|
</MkFoldableSection>
|
||||||
|
|
||||||
<MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category ?? '___root___'">
|
<MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category ?? '___root___'" :expanded="false">
|
||||||
<template #header>{{ category || i18n.ts.other }}</template>
|
<template #header>{{ category || i18n.ts.other }}</template>
|
||||||
<div :class="$style.emojis">
|
<div :class="$style.emojis">
|
||||||
<XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" :emoji="emoji"/>
|
<XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" :emoji="emoji"/>
|
||||||
|
|
|
@ -151,7 +151,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="tab === 'announcements'" class="_gaps">
|
<div v-else-if="tab === 'announcements'" class="_gaps">
|
||||||
<MkButton primary rounded @click="createAnnouncement"><i class="ti ti-plus"></i> {{ i18n.ts.new }}</MkButton>
|
<MkButton primary rounded @click="createAnnouncement"><i class="ti ti-plus"></i> {{ i18n.ts.createNew }}</MkButton>
|
||||||
|
|
||||||
<MkSelect v-model="announcementsStatus" :items="announcementsStatusDef">
|
<MkSelect v-model="announcementsStatus" :items="announcementsStatusDef">
|
||||||
<template #label>{{ i18n.ts.filter }}</template>
|
<template #label>{{ i18n.ts.filter }}</template>
|
||||||
|
|
|
@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<h1>{{ i18n.ts._auth.denied }}</h1>
|
<h1>{{ i18n.ts._auth.denied }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="state == 'accepted' && session">
|
<div v-if="state == 'accepted' && session">
|
||||||
<h1>{{ session.app.isAuthorized ? i18n.ts['already-authorized'] : i18n.ts.allowed }}</h1>
|
<h1>{{ session.app.isAuthorized ? i18n.ts._auth.alreadyAuthorized : i18n.ts._auth.accepted }}</h1>
|
||||||
<p v-if="session.app.callbackUrl">
|
<p v-if="session.app.callbackUrl">
|
||||||
{{ i18n.ts._auth.callback }}
|
{{ i18n.ts._auth.callback }}
|
||||||
<MkEllipsis/>
|
<MkEllipsis/>
|
||||||
|
|
|
@ -28,17 +28,37 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<span v-else style="opacity: 0.7;">({{ i18n.ts.none }})</span>
|
<span v-else style="opacity: 0.7;">({{ i18n.ts.none }})</span>
|
||||||
</template>
|
</template>
|
||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
|
<MkFolder @opened="onOpened">
|
||||||
|
<template #icon><i class="ti ti-report-search"></i></template>
|
||||||
|
<template #label>{{ i18n.ts.deviceInfo }}</template>
|
||||||
|
<template #caption>{{ i18n.ts.deviceInfoDescription }}</template>
|
||||||
|
<MkLoading v-if="userEnv == null" />
|
||||||
|
<MkCode v-else lang="json" :code="JSON.stringify(userEnv, null, 2)" style="max-height: 300px; overflow: auto;"/>
|
||||||
|
</MkFolder>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageWithHeader>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { instance } from '@/instance.js';
|
import { instance } from '@/instance.js';
|
||||||
import { definePage } from '@/page.js';
|
import { definePage } from '@/page.js';
|
||||||
|
import { getUserEnvironment } from '@/utility/get-user-environment.js';
|
||||||
|
import type { UserEnvironment } from '@/utility/get-user-environment.js';
|
||||||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||||
|
import MkFolder from '@/components/MkFolder.vue';
|
||||||
import MkLink from '@/components/MkLink.vue';
|
import MkLink from '@/components/MkLink.vue';
|
||||||
|
import MkCode from '@/components/MkCode.vue';
|
||||||
|
|
||||||
|
const userEnv = ref<UserEnvironment | null>(null);
|
||||||
|
|
||||||
|
async function onOpened() {
|
||||||
|
if (userEnv.value == null) {
|
||||||
|
userEnv.value = await getUserEnvironment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
definePage(() => ({
|
definePage(() => ({
|
||||||
title: i18n.ts.inquiry,
|
title: i18n.ts.inquiry,
|
||||||
|
|
|
@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton primary @click="createKey">{{ i18n.ts._registry.createKey }}</MkButton>
|
<MkButton primary @click="createKey">{{ i18n.ts._registry.createKey }}</MkButton>
|
||||||
|
|
||||||
<FormSection v-if="keys">
|
<FormSection v-if="keys">
|
||||||
<template #label>{{ i18n.ts.keys }}</template>
|
<template #label>{{ i18n.ts._registry.keys }}</template>
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<FormLink v-for="key in keys" :to="`/registry/value/${props.domain}/${scope.join('/')}/${key[0]}`" class="_monospace">{{ key[0] }}<template #suffix>{{ key[1].toUpperCase() }}</template></FormLink>
|
<FormLink v-for="key in keys" :to="`/registry/value/${props.domain}/${scope.join('/')}/${key[0]}`" class="_monospace">{{ key[0] }}<template #suffix>{{ key[1].toUpperCase() }}</template></FormLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -159,7 +159,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, computed, onMounted, onUnmounted, onActivated, onDeactivated, nextTick, watch, ref } from 'vue';
|
import { defineAsyncComponent, computed, onMounted, onUnmounted, onActivated, onDeactivated, nextTick, watch, ref, useTemplateRef } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { getScrollContainer } from '@@/js/scroll.js';
|
import { getScrollContainer } from '@@/js/scroll.js';
|
||||||
import MkNote from '@/components/MkNote.vue';
|
import MkNote from '@/components/MkNote.vue';
|
||||||
|
@ -222,9 +222,9 @@ const router = useRouter();
|
||||||
|
|
||||||
const user = ref(props.user);
|
const user = ref(props.user);
|
||||||
const narrow = ref<null | boolean>(null);
|
const narrow = ref<null | boolean>(null);
|
||||||
const rootEl = ref<null | HTMLElement>(null);
|
const rootEl = useTemplateRef('rootEl');
|
||||||
const bannerEl = ref<null | HTMLElement>(null);
|
const bannerEl = useTemplateRef('bannerEl');
|
||||||
const memoTextareaEl = ref<null | HTMLElement>(null);
|
const memoTextareaEl = useTemplateRef('memoTextareaEl');
|
||||||
const memoDraft = ref(props.user.memo);
|
const memoDraft = ref(props.user.memo);
|
||||||
const isEditingMemo = ref(false);
|
const isEditingMemo = ref(false);
|
||||||
const moderationNote = ref(props.user.moderationNote ?? '');
|
const moderationNote = ref(props.user.moderationNote ?? '');
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type UserEnvironment = {
|
||||||
|
os: string;
|
||||||
|
browser: string;
|
||||||
|
userAgent: string;
|
||||||
|
screenWidth: number;
|
||||||
|
screenHeight: number;
|
||||||
|
viaGetHighEntropyValues: true;
|
||||||
|
} | {
|
||||||
|
userAgent: string;
|
||||||
|
screenWidth: number;
|
||||||
|
screenHeight: number;
|
||||||
|
viaGetHighEntropyValues: false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getUserEnvironment(): Promise<UserEnvironment> {
|
||||||
|
if ('userAgentData' in navigator && navigator.userAgentData != null) {
|
||||||
|
try {
|
||||||
|
const uaData: any = await navigator.userAgentData.getHighEntropyValues([
|
||||||
|
'fullVersionList',
|
||||||
|
'platformVersion',
|
||||||
|
]);
|
||||||
|
|
||||||
|
let osVersion = 'v' + uaData.platformVersion;
|
||||||
|
|
||||||
|
if (uaData.platform === 'Windows' && uaData.platformVersion != null) {
|
||||||
|
// https://learn.microsoft.com/ja-jp/microsoft-edge/web-platform/how-to-detect-win11
|
||||||
|
const majorPlatformVersion = parseInt(uaData.platformVersion.split('.')[0]);
|
||||||
|
if (majorPlatformVersion >= 13) {
|
||||||
|
osVersion = '11 or later';
|
||||||
|
} else if (majorPlatformVersion > 0) {
|
||||||
|
osVersion = '10';
|
||||||
|
} else {
|
||||||
|
osVersion = '8.1 or earlier';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const browserData = uaData.fullVersionList.find((item) => !/^\s*not.+a.+brand\s*$/i.test(item.brand));
|
||||||
|
return {
|
||||||
|
os: `${uaData.platform} ${osVersion}`,
|
||||||
|
browser: browserData ? `${browserData.brand} v${browserData.version}` : 'Unknown',
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
screenWidth: window.innerWidth,
|
||||||
|
screenHeight: window.innerHeight,
|
||||||
|
viaGetHighEntropyValues: true,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return getViaUa();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return getViaUa();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getViaUa(): UserEnvironment {
|
||||||
|
return {
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
screenWidth: window.innerWidth,
|
||||||
|
screenHeight: window.innerHeight,
|
||||||
|
viaGetHighEntropyValues: false,
|
||||||
|
};
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<p v-if="widgetProps.folderId == null">
|
<p v-if="widgetProps.folderId == null">
|
||||||
{{ i18n.ts.folder }}
|
{{ i18n.ts.folder }}
|
||||||
</p>
|
</p>
|
||||||
<p v-if="widgetProps.folderId != null && images.length === 0 && !fetching">{{ i18n.ts['no-image'] }}</p>
|
<p v-if="widgetProps.folderId != null && images.length === 0 && !fetching">{{ i18n.ts.nothing }}</p>
|
||||||
<div ref="slideA" class="slide a"></div>
|
<div ref="slideA" class="slide a"></div>
|
||||||
<div ref="slideB" class="slide b"></div>
|
<div ref="slideB" class="slide b"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"name": "misskey-js",
|
"name": "misskey-js",
|
||||||
"version": "2025.10.0-beta.1",
|
"version": "2025.10.0-beta.2",
|
||||||
"description": "Misskey SDK for JavaScript",
|
"description": "Misskey SDK for JavaScript",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
|
|
|
@ -29205,34 +29205,34 @@ export interface operations {
|
||||||
* @default public
|
* @default public
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
visibility: 'public' | 'home' | 'followers' | 'specified';
|
visibility?: 'public' | 'home' | 'followers' | 'specified';
|
||||||
visibleUserIds: string[];
|
visibleUserIds?: string[];
|
||||||
cw: string | null;
|
cw?: string | null;
|
||||||
hashtag: string | null;
|
hashtag?: string | null;
|
||||||
/** @default false */
|
/** @default false */
|
||||||
localOnly: boolean;
|
localOnly?: boolean;
|
||||||
/**
|
/**
|
||||||
* @default null
|
* @default null
|
||||||
* @enum {string|null}
|
* @enum {string|null}
|
||||||
*/
|
*/
|
||||||
reactionAcceptance: null | 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote';
|
reactionAcceptance?: null | 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote';
|
||||||
/** Format: misskey:id */
|
/** Format: misskey:id */
|
||||||
replyId: string | null;
|
replyId?: string | null;
|
||||||
/** Format: misskey:id */
|
/** Format: misskey:id */
|
||||||
renoteId: string | null;
|
renoteId?: string | null;
|
||||||
/** Format: misskey:id */
|
/** Format: misskey:id */
|
||||||
channelId: string | null;
|
channelId?: string | null;
|
||||||
text: string | null;
|
text?: string | null;
|
||||||
fileIds: string[];
|
fileIds?: string[];
|
||||||
poll: {
|
poll?: {
|
||||||
choices: string[];
|
choices: string[];
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
expiresAt?: number | null;
|
expiresAt?: number | null;
|
||||||
expiredAfter?: number | null;
|
expiredAfter?: number | null;
|
||||||
} | null;
|
} | null;
|
||||||
scheduledAt: number | null;
|
scheduledAt?: number | null;
|
||||||
/** @default false */
|
/** @default false */
|
||||||
isActuallyScheduled: boolean;
|
isActuallyScheduled?: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
869
pnpm-lock.yaml
869
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue