Merge branch 'develop'
This commit is contained in:
commit
bce48dfee9
|
@ -9,6 +9,15 @@
|
|||
You should also include the user name that made the change.
|
||||
-->
|
||||
|
||||
## 12.113.0 (2022/07/13)
|
||||
|
||||
### Improvements
|
||||
- Support <plain> syntax for MFM
|
||||
|
||||
### Bugfixes
|
||||
- Server: Fix crash at startup if TensorFlow is not supported @mei23
|
||||
- Client: URLエンコードされたルーティングを修正
|
||||
|
||||
## 12.112.3 (2022/07/09)
|
||||
|
||||
### Improvements
|
||||
|
|
|
@ -804,6 +804,10 @@ oneDay: "يوم"
|
|||
oneWeek: "أسبوع"
|
||||
failedToFetchAccountInformation: "تعذر جلب معلومات الحساب"
|
||||
file: "الملفات"
|
||||
reverse: "اقلب"
|
||||
colored: "ملوّن"
|
||||
label: "التسمية"
|
||||
localOnly: "المحلي فقط"
|
||||
_emailUnavailable:
|
||||
used: "هذا البريد الإلكتروني مستخدم"
|
||||
format: "صيغة البريد الإلكتروني غير صالحة"
|
||||
|
|
|
@ -844,6 +844,10 @@ reflectMayTakeTime: "এটির কাজ দেখা যেতে কিছ
|
|||
failedToFetchAccountInformation: "অ্যাকাউন্টের তথ্য উদ্ধার করা যায়নি"
|
||||
rateLimitExceeded: "রেট লিমিট ছাড়িয়ে গেছে "
|
||||
file: "ফাইলগুলি"
|
||||
reverse: "উল্টান"
|
||||
colored: "রঙ্গিন"
|
||||
label: "লেবেল"
|
||||
localOnly: "শুধুমাত্র লোকাল"
|
||||
_emailUnavailable:
|
||||
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
|
||||
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
|
||||
|
|
|
@ -111,6 +111,14 @@ reactionSettingDescription2: "Arrossega per reordenar, fes clic per suprimir, pr
|
|||
rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes"
|
||||
attachCancel: "Eliminar el fitxer adjunt"
|
||||
markAsSensitive: "Marcar com a NSFW"
|
||||
unmarkAsSensitive: "Deixar de marcar com a sensible"
|
||||
enterFileName: "Defineix nom del fitxer"
|
||||
mute: "Silencia"
|
||||
unmute: "Deixa de silenciar"
|
||||
block: "Bloqueja"
|
||||
unblock: "Desbloqueja"
|
||||
suspend: "Suspèn"
|
||||
unsuspend: "Deixa de suspendre"
|
||||
instances: "Instàncies"
|
||||
remove: "Eliminar"
|
||||
nsfw: "NSFW"
|
||||
|
@ -148,6 +156,8 @@ _profile:
|
|||
username: "Nom d'usuari"
|
||||
_exportOrImport:
|
||||
followingList: "Seguint"
|
||||
muteList: "Silencia"
|
||||
blockingList: "Bloqueja"
|
||||
userLists: "Llistes"
|
||||
_pages:
|
||||
script:
|
||||
|
|
|
@ -869,6 +869,32 @@ logoutConfirm: "Wirklich abmelden?"
|
|||
lastActiveDate: "Zuletzt verwendet am"
|
||||
statusbar: "Statusleiste"
|
||||
pleaseSelect: "Wähle eine Option"
|
||||
reverse: "Umkehren"
|
||||
colored: "Farbig"
|
||||
refreshInterval: "Aktualisierungsrate"
|
||||
label: "Beschriftung"
|
||||
type: "Art"
|
||||
speed: "Geschwindigkeit"
|
||||
slow: "Langsam"
|
||||
fast: "Schnell"
|
||||
sensitiveMediaDetection: "Erkennung von NSFW-Medien"
|
||||
localOnly: "Nur Lokal"
|
||||
remoteOnly: "Nur für fremde Instanzen"
|
||||
failedToUpload: "Hochladen fehlgeschlagen"
|
||||
cannotUploadBecauseInappropriate: "Diese Datei kann nicht hochgeladen werden, da Anteile der Datei als möglicherweise NSFW festgestellt wurden."
|
||||
cannotUploadBecauseNoFreeSpace: "Die Datei konnte nicht hochgeladen werden, da dein Drive-Speicherplatz aufgebraucht ist."
|
||||
beta: "Beta"
|
||||
enableAutoSensitive: "NSFW-Automarkierung"
|
||||
enableAutoSensitiveDescription: "Setzt soweit möglich durch Verwendung von Machine Learning automatisch NSFW-Markierungen für Medien, die NSFW-Anteile beinhalten. Auch wenn du diese Option deaktiviert hast, ist sie möglicherweise auf Instanzebene aktiviert."
|
||||
activeEmailValidationDescription: "Aktivert strengere Überprüfung von E-Mail-Adressen, d.h. Testen auf Wegwerfadressen und darauf, ob mit der Adresse tatsächlich kommuniziert werden kann. Ist dies deaktiviert, so wird nur das Format der E-Mail überprüft."
|
||||
_sensitiveMediaDetection:
|
||||
description: "Ermöglicht eine Erleichterung der Servermoderation durch die automatische Erkennungen von NSFW-Medien unter Verwendung von Machine Learning. Hierdurch wird die Serverlast etwas erhöht."
|
||||
sensitivity: "Erkennungssensitivität"
|
||||
sensitivityDescription: "Durch das Senken der Sensitivität kann die Anzahl an Fehlerkennungen (sog. false positives) reduziert werden. Durch ein Erhöhen dieser kann die Anzahl an verpassten Erkennungen (sog. false negatives) reduziert werden."
|
||||
setSensitiveFlagAutomatically: "Als NSFW markieren"
|
||||
setSensitiveFlagAutomaticallyDescription: "Die Resultate der internen Erkennung werden beibehalten, auch wenn diese Option deaktiviert ist."
|
||||
analyzeVideos: "Videoanalyse aktivieren"
|
||||
analyzeVideosDescription: "Analysiert zusätzlich zu Bildern auch Videos. Die Last des Servers wird hierdurch etwas erhöht."
|
||||
_emailUnavailable:
|
||||
used: "Diese Email-Adresse wird bereits verwendet"
|
||||
format: "Das Format dieser Email-Adresse ist ungültig"
|
||||
|
|
|
@ -869,6 +869,32 @@ logoutConfirm: "Really log out?"
|
|||
lastActiveDate: "Last used at"
|
||||
statusbar: "Status bar"
|
||||
pleaseSelect: "Select an option"
|
||||
reverse: "Reverse"
|
||||
colored: "Colored"
|
||||
refreshInterval: "Update interval "
|
||||
label: "Label"
|
||||
type: "Type"
|
||||
speed: "Speed"
|
||||
slow: "Slow"
|
||||
fast: "Fast"
|
||||
sensitiveMediaDetection: "Detection of NSFW media"
|
||||
localOnly: "Local only"
|
||||
remoteOnly: "Remote only"
|
||||
failedToUpload: "Upload failed"
|
||||
cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of it have been detected as potentially NSFW."
|
||||
cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity."
|
||||
beta: "Beta"
|
||||
enableAutoSensitive: "Automatic NSFW-Marking"
|
||||
enableAutoSensitiveDescription: "Allows automatic detection and marking of NSFW media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide."
|
||||
activeEmailValidationDescription: "Enables stricter validation of email addresses, which includes checking for disposable addresses and by whether it can actually be communicated with. When unchecked, only the format of the email is validated."
|
||||
_sensitiveMediaDetection:
|
||||
description: "Reduces the effort of server moderation through automatically recognizing NSFW media via Machine Learning. This will slightly increase the load on the server."
|
||||
sensitivity: "Detection sensitivity"
|
||||
sensitivityDescription: "Reducing the sensitivity will lead to fewer misdetections (false positives) whereas increasing it will lead to fewer missed detections (false negatives)."
|
||||
setSensitiveFlagAutomatically: "Mark as NSFW"
|
||||
setSensitiveFlagAutomaticallyDescription: "The results of the internal detection will be retained even if this option is turned off."
|
||||
analyzeVideos: "Enable analysis of videos"
|
||||
analyzeVideosDescription: "Analyzes videos in addition to images. This will slightly increase the load on the server."
|
||||
_emailUnavailable:
|
||||
used: "This email address is already being used"
|
||||
format: "The format of this email address is invalid"
|
||||
|
|
|
@ -861,6 +861,10 @@ document: "Documento"
|
|||
numberOfPageCache: "Cantidad de páginas cacheadas"
|
||||
numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien puede aumentar la carga y la memoria a usarse"
|
||||
logoutConfirm: "¿Cerrar sesión?"
|
||||
reverse: "Echar de un capirotazo"
|
||||
colored: "Color"
|
||||
label: "Etiqueta"
|
||||
localOnly: "Solo local"
|
||||
_emailUnavailable:
|
||||
used: "Ya fue usado"
|
||||
format: "Formato no válido."
|
||||
|
|
|
@ -839,6 +839,10 @@ rateLimitExceeded: "Limite de taux dépassée"
|
|||
cropImage: "Recadrer l'image"
|
||||
cropImageAsk: "Voulez-vous recadrer cette image ?"
|
||||
file: "Fichiers"
|
||||
reverse: "Inverser"
|
||||
colored: "Coloré"
|
||||
label: "Étiquette"
|
||||
localOnly: "Local seulement"
|
||||
_emailUnavailable:
|
||||
used: "Non disponible"
|
||||
format: "Le format de cette adresse de courriel est invalide"
|
||||
|
|
|
@ -848,6 +848,10 @@ rateLimitExceeded: "Batas sudah terlampaui"
|
|||
cropImage: "potong gambar"
|
||||
cropImageAsk: "Ingin memotong gambar?"
|
||||
file: "Berkas"
|
||||
reverse: "Balik"
|
||||
colored: "Diwarnai"
|
||||
label: "Label"
|
||||
localOnly: "Hanya lokal"
|
||||
_emailUnavailable:
|
||||
used: "Alamat surel ini telah digunakan"
|
||||
format: "Format tidak valid."
|
||||
|
|
|
@ -810,6 +810,10 @@ oneHour: "1 ora"
|
|||
oneDay: "1 giorno"
|
||||
oneWeek: "1 settimana"
|
||||
file: "Allegati"
|
||||
reverse: "Inverti"
|
||||
colored: "Colorato"
|
||||
label: "Etichetta"
|
||||
localOnly: "Soltanto locale"
|
||||
_emailUnavailable:
|
||||
used: "Email già in uso"
|
||||
format: "Formato email non valido"
|
||||
|
|
|
@ -658,6 +658,7 @@ hide: "隠す"
|
|||
searchByGoogle: "探す"
|
||||
indefinitely: "無期限"
|
||||
file: "ファイル"
|
||||
colored: "色付き"
|
||||
_ad:
|
||||
back: "戻る"
|
||||
_gallery:
|
||||
|
|
|
@ -203,6 +203,7 @@ done: "완료"
|
|||
processing: "처리중"
|
||||
preview: "미리보기"
|
||||
default: "기본값"
|
||||
defaultValueIs: "기본값: {value}"
|
||||
noCustomEmojis: "이모지가 없습니다"
|
||||
noJobs: "작업이 없습니다"
|
||||
federating: "연합 중"
|
||||
|
@ -381,6 +382,7 @@ administrator: "관리자"
|
|||
token: "토큰"
|
||||
twoStepAuthentication: "2단계 인증"
|
||||
moderator: "모더레이터"
|
||||
moderation: "모더레이션"
|
||||
nUsersMentioned: "{n}명이 언급함"
|
||||
securityKey: "보안 키"
|
||||
securityKeyName: "키 이름"
|
||||
|
@ -854,9 +856,44 @@ noEmailServerWarning: "메일 서버가 설정되어 있지 않습니다."
|
|||
thereIsUnresolvedAbuseReportWarning: "해결되지 않은 신고가 있습니다."
|
||||
recommended: "추천"
|
||||
check: "체크"
|
||||
driveCapOverrideLabel: "이 유저의 드라이브 용량을 변경"
|
||||
driveCapOverrideCaption: "0 이하를 지정하면 해제됩니다."
|
||||
requireAdminForView: "열람하려면 관리자 계정으로 로그인해야 합니다."
|
||||
isSystemAccount: "시스템에 의해 자동으로 생성되어 관리되는 계정입니다."
|
||||
typeToConfirm: "계속하시려면 {x} 을 입력하세요"
|
||||
deleteAccount: "계정 삭제"
|
||||
document: "문서"
|
||||
numberOfPageCache: "페이지 캐시 수"
|
||||
numberOfPageCacheDescription: "숫자가 클 수록 편리성이 높아지지만, 시스템 자원과 메모리를 더 많이 사용합니다."
|
||||
logoutConfirm: "로그아웃 하시겠습니까?"
|
||||
lastActiveDate: "마지막 이용"
|
||||
pleaseSelect: "선택해 주세요"
|
||||
reverse: "플립"
|
||||
colored: "색 입히기"
|
||||
refreshInterval: "업데이트 주기"
|
||||
label: "라벨"
|
||||
type: "종류"
|
||||
speed: "속도"
|
||||
slow: "느리게"
|
||||
fast: "빠르게"
|
||||
sensitiveMediaDetection: "민감한 미디어 탐지"
|
||||
localOnly: "로컬에만"
|
||||
remoteOnly: "리모트만"
|
||||
failedToUpload: "업로드 실패"
|
||||
cannotUploadBecauseInappropriate: "이 파일은 부적절한 내용을 포함한다고 판단되어 업로드할 수 없습니다."
|
||||
cannotUploadBecauseNoFreeSpace: "드라이브 용량이 부족하여 업로드할 수 없습니다."
|
||||
beta: "베타"
|
||||
enableAutoSensitive: "자동 NSFW 탐지"
|
||||
enableAutoSensitiveDescription: "이용 가능할 경우 기계학습을 통해 자동으로 미디어 NSFW를 설정합니다. 이 기능을 해제하더라도, 인스턴스 정책에 따라 자동으로 설정될 수 있습니다."
|
||||
activeEmailValidationDescription: "유저가 입력한 메일 주소가 일회용 메일인지, 실제로 통신할 수 있는 지 엄격하게 검사합니다. 해제할 경우 이메일 형식에 대해서만 검사합니다."
|
||||
_sensitiveMediaDetection:
|
||||
description: "기계학습을 통해 자동으로 민감한 미디어를 탐지하여, 모더레이션에 참고할 수 있도록 합니다. 서버의 부하를 약간 증가시킵니다."
|
||||
sensitivity: "탐지 민감도"
|
||||
sensitivityDescription: "민감도가 낮을수록 안전한 미디어가 잘못 탐지될 확률이 줄어들며, 높을수록 민감한 미디어가 탐지되지 않을 확률이 줄어듭니다."
|
||||
setSensitiveFlagAutomatically: "자동으로 NSFW로 설정하기"
|
||||
setSensitiveFlagAutomaticallyDescription: "이 설정을 해제해도 탐지 결과는 유지됩니다."
|
||||
analyzeVideos: "동영상도 같이 확인하기"
|
||||
analyzeVideosDescription: "사진 뿐만 아니라 동영상의 NSFW 여부도 탐지합니다. 서버의 부하를 약간 증가시킵니다."
|
||||
_emailUnavailable:
|
||||
used: "이 메일 주소는 사용중입니다"
|
||||
format: "형식이 올바르지 않습니다"
|
||||
|
@ -1215,6 +1252,7 @@ _widgets:
|
|||
photos: "사진"
|
||||
digitalClock: "디지털 시계"
|
||||
federation: "연합"
|
||||
instanceCloud: "인스턴스 구름"
|
||||
postForm: "글 입력란"
|
||||
slideshow: "슬라이드 쇼"
|
||||
button: "버튼"
|
||||
|
@ -1660,6 +1698,9 @@ _deck:
|
|||
stackLeft: "왼쪽에 쌓기"
|
||||
popRight: "오른쪽으로 빼기"
|
||||
profile: "프로파일"
|
||||
introduction: "칼럼을 조합해서 나만의 인터페이스를 구성해 보아요!"
|
||||
introduction2: "나중에라도 화면 우측의 + 버튼을 눌러 새 칼럼을 추가할 수 있습니다."
|
||||
widgetsIntroduction: "칼럼 메뉴의 \"위젯 편집\"에서 위젯을 추가해 주세요"
|
||||
_columns:
|
||||
main: "메인"
|
||||
widgets: "위젯"
|
||||
|
|
|
@ -761,6 +761,9 @@ hide: "Ukryj"
|
|||
searchByGoogle: "Szukaj"
|
||||
indefinitely: "Nigdy"
|
||||
file: "Pliki"
|
||||
reverse: "Odwróć"
|
||||
colored: "Kolorowe"
|
||||
label: "Etykieta"
|
||||
_ffVisibility:
|
||||
public: "Publikuj"
|
||||
_ad:
|
||||
|
|
|
@ -203,6 +203,7 @@ done: "Готово"
|
|||
processing: "Обработка"
|
||||
preview: "Предпросмотр"
|
||||
default: "По умолчанию"
|
||||
defaultValueIs: "По умолчанию: {value}"
|
||||
noCustomEmojis: "Собственные эмодзи отсутствуют"
|
||||
noJobs: "Нет заданий"
|
||||
federating: "Федерируется"
|
||||
|
@ -834,6 +835,16 @@ instanceDefaultLightTheme: "Светлая тема по умолчанию"
|
|||
instanceDefaultDarkTheme: "Темная тема по умолчанию"
|
||||
indefinitely: "вечно"
|
||||
file: "Файлы"
|
||||
recommended: "Рекомендуем"
|
||||
check: "Проверить"
|
||||
driveCapOverrideLabel: "Изменение лимита дискового пространства для этого пользователя"
|
||||
reverse: "Переворот"
|
||||
colored: "Выделена цветом"
|
||||
label: "Метка"
|
||||
localOnly: "Локально"
|
||||
_sensitiveMediaDetection:
|
||||
description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно."
|
||||
setSensitiveFlagAutomatically: "Установить флаг NSFW"
|
||||
_emailUnavailable:
|
||||
used: "Уже используется"
|
||||
format: "Неверный формат"
|
||||
|
|
|
@ -865,6 +865,32 @@ numberOfPageCacheDescription: "Zvýši rýchlosť ale tiež nároky na pamäť."
|
|||
logoutConfirm: "Naozaj sa chcete odhlásiť?"
|
||||
statusbar: "Stavový riadok"
|
||||
pleaseSelect: "Prosím vyberte"
|
||||
reverse: "Preklopiť"
|
||||
colored: "Farebné"
|
||||
refreshInterval: "Interval obnovenia"
|
||||
label: "Popisok"
|
||||
type: "Typ"
|
||||
speed: "Rýchlosť"
|
||||
slow: "Pomaly"
|
||||
fast: "Rýchlo"
|
||||
sensitiveMediaDetection: "Detekcia citlivých médií."
|
||||
localOnly: "Iba lokálne"
|
||||
remoteOnly: "Len vzdialené"
|
||||
failedToUpload: "Nahrávanie zlyhalo"
|
||||
cannotUploadBecauseInappropriate: "Nemožno nahrať, pretože pravdepodobne obsahuje nevhodný obsah."
|
||||
cannotUploadBecauseNoFreeSpace: "Nemožno nahrať kvôli nedostatku voľného úložiska."
|
||||
beta: "Beta"
|
||||
enableAutoSensitive: "Automatická detekcia NSFW"
|
||||
enableAutoSensitiveDescription: "Ak je zapnuté, príznak NSFW sa na médiách automaticky nastaví pomocou strojového učenia. Aj keď je táto funkcia vypnutá, v niektorých prípadoch sa môže nastaviť automaticky."
|
||||
activeEmailValidationDescription: "Dôkladnejšie overí e-mailovú adresu používateľa tým, že zistí, či ide o vyradenú e-mailovú adresu a či sa s ňou dá skutočne komunikovať. Ak nie je začiarknuté, e-mailová adresa sa kontroluje len ako text."
|
||||
_sensitiveMediaDetection:
|
||||
description: "Strojové učenie sa použije na automatickú detekciu citlivých médií na účely ich moderovania. Mierne sa zvýši zaťaženie servera."
|
||||
sensitivity: "Citlivosť detekcie"
|
||||
sensitivityDescription: "Nižšia citlivosť znižuje počet falošne pozitívnych výsledkov (false positives). Vyššia citlivosť znižuje počet falošne negatívnych výsledkov (false negatives)."
|
||||
setSensitiveFlagAutomatically: "Nastaviť príznak NSFW"
|
||||
setSensitiveFlagAutomaticallyDescription: "Aj keď je toto nastavenie vypnuté, výsledok rozhodnutia je interne uložený."
|
||||
analyzeVideos: "Zapnúť analýzu videa"
|
||||
analyzeVideosDescription: "Okrem obrázkov zapne detekciu aj pre videá. Zaťaženie servera sa mierne zvýši."
|
||||
_emailUnavailable:
|
||||
used: "Táto emailová adresa sa už používa"
|
||||
format: "Formát emailovej adresy je nesprávny"
|
||||
|
|
|
@ -795,6 +795,31 @@ whatIsNew: "แสดงการเปลี่ยนแปลง"
|
|||
translate: "แปลภาษา"
|
||||
translatedFrom: "แปลมาจาก {x}"
|
||||
accountDeletionInProgress: "กำลังดำเนินการลบบัญชีอยู่"
|
||||
usernameInfo: "ชื่อที่ระบุบัญชีของคุณจากผู้อื่นในเซิร์ฟเวอร์นี้ คุณสามารถใช้ตัวอักษร (a~z, A~Z), ตัวเลข (0~9) หรือขีดล่าง (_) ชื่อผู้ใช้ไม่สามารถเปลี่ยนแปลงได้ในภายหลัง"
|
||||
aiChanMode: "โหมด Ai "
|
||||
keepCw: "เก็บคำเตือนเนื้อหา"
|
||||
pubSub: "บัญชีผับ/ย่อย"
|
||||
lastCommunication: "การสื่อสารครั้งสุดท้ายล่าสุด"
|
||||
resolved: "คลี่คลายแล้ว"
|
||||
unresolved: "รอการเฉลย"
|
||||
breakFollow: "ลบผู้ติดตาม"
|
||||
itsOn: "เปิดใช้งาน"
|
||||
itsOff: "ปิดใช้งาน"
|
||||
emailRequiredForSignup: "จำเป็นต้องการใช้ที่อยู่อีเมลสำหรับการสมัคร"
|
||||
unread: "ไม่ได้อ่าน"
|
||||
filter: "กรอง"
|
||||
controlPanel: "แผงควบคุม"
|
||||
manageAccounts: "จัดการบัญชี"
|
||||
makeReactionsPublic: "ตั้งค่าประวัติปฏิกิริยาต่อสาธารณะ"
|
||||
makeReactionsPublicDescription: "การทำเช่นนี้จะทำให้รายการปฏิกิริยาที่ผ่านมาของคุณจะปรากฏต่อสาธารณะนะ"
|
||||
classic: "คลาสสิค"
|
||||
muteThread: "ปิดเสียงเธรด"
|
||||
unmuteThread: "เปิดเสียงเธรด"
|
||||
ffVisibility: "การมองเห็นผู้ติดตาม/ผู้ติดตาม"
|
||||
ffVisibilityDescription: "ช่วยให้คุณสามารถกำหนดค่าได้ว่าใครสามารถดูได้ว่าคุณติดตามใครและใครติดตามคุณบ้าง"
|
||||
continueThread: "ดูความต่อเนื่องเธรด"
|
||||
deleteAccountConfirm: "การดำเนินการนี้จะลบบัญชีของคุณอย่างถาวรเลยนะ แน่ใจหรอดำเนินการ?"
|
||||
incorrectPassword: "รหัสผ่านไม่ถูกต้อง"
|
||||
searchByGoogle: "ค้นหา"
|
||||
file: "ไฟล์"
|
||||
_ffVisibility:
|
||||
|
|
|
@ -738,6 +738,10 @@ hide: "Сховати"
|
|||
searchByGoogle: "Пошук"
|
||||
indefinitely: "Ніколи"
|
||||
file: "Файли"
|
||||
reverse: "Перевернути"
|
||||
colored: "Кольоровий"
|
||||
label: "Назва"
|
||||
localOnly: "Локально"
|
||||
_ffVisibility:
|
||||
public: "Опублікувати"
|
||||
_ad:
|
||||
|
|
|
@ -869,6 +869,32 @@ logoutConfirm: "Bạn có chắc muốn đăng xuất?"
|
|||
lastActiveDate: "Lần cuối vào"
|
||||
statusbar: "Thanh trạng thái"
|
||||
pleaseSelect: "Chọn một lựa chọn"
|
||||
reverse: "Lật"
|
||||
colored: "Với màu"
|
||||
refreshInterval: "Cập nhật nội bộ"
|
||||
label: "Nhãn"
|
||||
type: "Loại"
|
||||
speed: "Tốc độ"
|
||||
slow: "Chậm"
|
||||
fast: "Nhanh"
|
||||
sensitiveMediaDetection: "Tự động phát hiện NSFW"
|
||||
localOnly: "Chỉ trên máy chủ"
|
||||
remoteOnly: "Chỉ máy chủ từ xa"
|
||||
failedToUpload: "Tải lên thất bại"
|
||||
cannotUploadBecauseInappropriate: "Không thể tải lên tập tin này vì các phần của tập tin đã được phát hiện có khả năng là NSFW."
|
||||
cannotUploadBecauseNoFreeSpace: "Tải lên không thành công do thiếu dung lượng Drive."
|
||||
beta: "Beta"
|
||||
enableAutoSensitive: "Tự động đánh dấu NSFW"
|
||||
enableAutoSensitiveDescription: "Cho phép tự động phát hiện và đánh dấu media NSFW thông qua học máy, nếu có thể. Ngay cả khi tùy chọn này bị tắt, nó vẫn có thể được bật trên toàn máy chủ."
|
||||
activeEmailValidationDescription: "Cho phép xác minh địa chỉ email chặt chẽ hơn, bao gồm việc kiểm tra các địa chỉ dùng một lần và xem nó có thực sự được giao tiếp hay không. Khi bỏ chọn, chỉ định dạng của email được xác minh."
|
||||
_sensitiveMediaDetection:
|
||||
description: "Giảm nỗ lực kiểm duyệt máy chủ thông qua việc tự động nhận dạng media NSFW thông qua học máy. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
|
||||
sensitivity: "Phát hiện nhạy cảm"
|
||||
sensitivityDescription: "Giảm độ nhạy sẽ dẫn đến ít phát hiện sai hơn (dương tính giả), tăng nó sẽ dẫn đến ít phát hiện sai hơn (âm tính giả)."
|
||||
setSensitiveFlagAutomatically: "Đánh dấu là NSFW"
|
||||
setSensitiveFlagAutomaticallyDescription: "Kết quả của phát hiện nội bộ sẽ được giữ lại ngay cả khi tùy chọn này bị tắt."
|
||||
analyzeVideos: "Bật chuẩn đoán video"
|
||||
analyzeVideosDescription: "Phân tích video bên cạnh hình ảnh. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
|
||||
_emailUnavailable:
|
||||
used: "Địa chỉ email đã được sử dụng"
|
||||
format: "Địa chỉ email không hợp lệ"
|
||||
|
|
|
@ -381,6 +381,7 @@ administrator: "管理员"
|
|||
token: "Token (令牌)"
|
||||
twoStepAuthentication: "两步验证"
|
||||
moderator: "监察员"
|
||||
moderation: "管理"
|
||||
nUsersMentioned: "{n} 被提到"
|
||||
securityKey: "安全密钥"
|
||||
securityKeyName: "密钥名称"
|
||||
|
@ -851,7 +852,40 @@ noEmailServerWarning: "电子邮件服务器未设置。"
|
|||
thereIsUnresolvedAbuseReportWarning: "有未解决的报告"
|
||||
recommended: "推荐"
|
||||
check: "检查"
|
||||
driveCapOverrideCaption: "设定为 0 以下则会解除此限制。"
|
||||
requireAdminForView: "需要使用管理员账户登录才能查看。"
|
||||
isSystemAccount: "该账号由系统自动创建和管理。"
|
||||
typeToConfirm: "输入 {x} 以确认操作。"
|
||||
deleteAccount: "删除账户"
|
||||
numberOfPageCache: "缓存页数"
|
||||
numberOfPageCacheDescription: "设置较高的值会更方便用户,但服务器负载和内存使用量会增加。"
|
||||
logoutConfirm: "是否确认登出?"
|
||||
lastActiveDate: "最后活跃时间"
|
||||
statusbar: "状态栏"
|
||||
pleaseSelect: "请选择"
|
||||
reverse: "翻转"
|
||||
colored: "彩色"
|
||||
refreshInterval: "刷新间隔"
|
||||
label: "标签"
|
||||
speed: "速度"
|
||||
slow: "慢"
|
||||
fast: "快"
|
||||
sensitiveMediaDetection: "检测到敏感媒体"
|
||||
localOnly: "仅限本地"
|
||||
remoteOnly: "仅远程"
|
||||
failedToUpload: "上传失败"
|
||||
cannotUploadBecauseInappropriate: "因为可能含有不适宜的内容,无法上传。"
|
||||
cannotUploadBecauseNoFreeSpace: "因为已无可用空间,无法上传。"
|
||||
beta: "测试"
|
||||
enableAutoSensitive: "自动 NSFW 识别"
|
||||
_sensitiveMediaDetection:
|
||||
description: "可以使用机器学习技术自动检测敏感媒体,以便进行审核。服务器负载将略微增加。"
|
||||
sensitivity: "检测敏感度"
|
||||
sensitivityDescription: "敏感度较低,则误检(假阳性)会减少;敏感度较高,则漏检(假阴性)会减少。"
|
||||
setSensitiveFlagAutomatically: "自动设置 NSFW 标签"
|
||||
setSensitiveFlagAutomaticallyDescription: "即使关闭此配置,识别结果也会在内部保存。"
|
||||
analyzeVideos: "启用对视频的检测"
|
||||
analyzeVideosDescription: "除了静止图像之外,还对视频进行分析。服务器负载会略微增加。"
|
||||
_emailUnavailable:
|
||||
used: "已经被使用过"
|
||||
format: "无效的格式"
|
||||
|
@ -1210,6 +1244,7 @@ _widgets:
|
|||
photos: "照片"
|
||||
digitalClock: "数字时钟"
|
||||
federation: "联邦宇宙"
|
||||
instanceCloud: "实例云"
|
||||
postForm: "投稿窗口"
|
||||
slideshow: "幻灯片展示"
|
||||
button: "按钮"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
_lang_: "繁體中文"
|
||||
headlineMisskey: "貼文連繫網路"
|
||||
introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀"
|
||||
introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「反應」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀"
|
||||
monthAndDay: "{month}月 {day}日"
|
||||
search: "搜尋"
|
||||
notifications: "通知"
|
||||
|
@ -727,7 +727,7 @@ receiveAnnouncementFromInstance: "接收由本實例發出的電郵通知"
|
|||
emailNotification: "郵件通知"
|
||||
publish: "發佈"
|
||||
inChannelSearch: "頻道内搜尋"
|
||||
useReactionPickerForContextMenu: "點擊右鍵開啟回應工具欄"
|
||||
useReactionPickerForContextMenu: "點擊右鍵開啟反應工具欄"
|
||||
typingUsers: "{users}輸入中..."
|
||||
jumpToSpecifiedDate: "跳轉到特定日期"
|
||||
showingPastTimeline: "顯示過往的時間線"
|
||||
|
@ -810,8 +810,8 @@ unread: "未讀"
|
|||
filter: "篩選"
|
||||
controlPanel: "控制台"
|
||||
manageAccounts: "管理帳戶"
|
||||
makeReactionsPublic: "將回應設為公開"
|
||||
makeReactionsPublicDescription: "將您做過的回應設為公開可見。"
|
||||
makeReactionsPublic: "將反應設為公開"
|
||||
makeReactionsPublicDescription: "將您做過的反應設為公開可見。"
|
||||
classic: "經典"
|
||||
muteThread: "將貼文串設為靜音"
|
||||
unmuteThread: "將貼文串的靜音解除"
|
||||
|
@ -869,6 +869,32 @@ logoutConfirm: "確定要登出嗎?"
|
|||
lastActiveDate: "上次使用日期及時間"
|
||||
statusbar: "狀態列"
|
||||
pleaseSelect: "請選擇"
|
||||
reverse: "翻轉"
|
||||
colored: "彩色"
|
||||
refreshInterval: "更新間隔"
|
||||
label: "標籤"
|
||||
type: "類型"
|
||||
speed: "速度"
|
||||
slow: "慢"
|
||||
fast: "快"
|
||||
sensitiveMediaDetection: "敏感性媒體的檢測"
|
||||
localOnly: "僅限本地"
|
||||
remoteOnly: "僅限遠端"
|
||||
failedToUpload: "上傳失敗"
|
||||
cannotUploadBecauseInappropriate: "由於判定可能包含不適當的內容,因此無法上船。"
|
||||
cannotUploadBecauseNoFreeSpace: "由於雲端硬碟沒有可用空間,因此無法上船>"
|
||||
beta: "Beta"
|
||||
enableAutoSensitive: "自動NSFW判定"
|
||||
enableAutoSensitiveDescription: "如果可用,請利用機器學習在媒體上自動設置 NSFW 旗標。 即使關閉此功能,依實例而定也可能會自動設置。"
|
||||
activeEmailValidationDescription: "積極地驗證用戶的電子郵件地址,判斷它是否為免洗地址,或者它是否可以通信。 若關閉,則只會檢查字元是否正確。"
|
||||
_sensitiveMediaDetection:
|
||||
description: "您可以使用機器學習自動檢測敏感媒體並將其用於審核。 伺服器的負荷會稍微增加。"
|
||||
sensitivity: "檢測敏感度"
|
||||
sensitivityDescription: "敏感度低時,誤檢測(偽陽性)會減少。敏感度高時,漏檢(偽陰性)會減少。"
|
||||
setSensitiveFlagAutomatically: "設定 NSFW 旗標"
|
||||
setSensitiveFlagAutomaticallyDescription: "即使將此設定關閉,判定結果也會保留在內部。"
|
||||
analyzeVideos: "啟用影片分析"
|
||||
analyzeVideosDescription: "除了靜止影像以外,也分析影片。伺服器的負荷會稍微增加。"
|
||||
_emailUnavailable:
|
||||
used: "已經在使用中"
|
||||
format: "格式無效"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "12.112.3",
|
||||
"version": "12.113.0",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"devDependencies": {
|
||||
"@types/gulp": "4.0.9",
|
||||
"@types/gulp-rename": "2.0.1",
|
||||
"@typescript-eslint/parser": "5.30.0",
|
||||
"@typescript-eslint/parser": "5.30.6",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "10.3.0",
|
||||
"start-server-and-test": "1.14.0",
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
"chokidar": "^3.3.1",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tensorflow/tfjs-node": "3.18.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bull-board/koa": "4.0.0",
|
||||
"@discordapp/twemoji": "14.0.2",
|
||||
|
@ -23,7 +26,6 @@
|
|||
"@peertube/http-signature": "1.6.0",
|
||||
"@sinonjs/fake-timers": "9.1.2",
|
||||
"@syuilo/aiscript": "0.11.1",
|
||||
"@tensorflow/tfjs-node": "3.18.0",
|
||||
"abort-controller": "3.0.0",
|
||||
"ajv": "8.11.0",
|
||||
"archiver": "5.3.1",
|
||||
|
@ -37,7 +39,7 @@
|
|||
"cbor": "8.1.0",
|
||||
"chalk": "5.0.1",
|
||||
"chalk-template": "0.4.0",
|
||||
"chokidar": "3.3.1",
|
||||
"chokidar": "3.5.3",
|
||||
"cli-highlight": "2.1.11",
|
||||
"color-convert": "2.0.1",
|
||||
"content-disposition": "0.5.4",
|
||||
|
@ -67,15 +69,15 @@
|
|||
"koa-send": "5.0.1",
|
||||
"koa-slow": "2.1.0",
|
||||
"koa-views": "7.0.2",
|
||||
"mfm-js": "0.22.1",
|
||||
"mfm-js": "0.23.0-canary.1",
|
||||
"mime-types": "2.1.35",
|
||||
"misskey-js": "0.0.14",
|
||||
"mocha": "10.0.0",
|
||||
"ms": "3.0.0-canary.1",
|
||||
"multer": "1.4.4",
|
||||
"nested-property": "4.0.0",
|
||||
"node-fetch": "3.2.6",
|
||||
"nodemailer": "6.7.6",
|
||||
"node-fetch": "3.2.8",
|
||||
"nodemailer": "6.7.7",
|
||||
"nsfwjs": "2.4.1",
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "7.0.0",
|
||||
|
@ -106,11 +108,11 @@
|
|||
"style-loader": "3.3.1",
|
||||
"summaly": "2.7.0",
|
||||
"syslog-pro": "1.0.0",
|
||||
"systeminformation": "5.11.22",
|
||||
"systeminformation": "5.12.0",
|
||||
"tinycolor2": "1.4.2",
|
||||
"tmp": "0.2.1",
|
||||
"ts-loader": "9.3.1",
|
||||
"ts-node": "10.8.1",
|
||||
"ts-node": "10.8.2",
|
||||
"tsc-alias": "1.6.11",
|
||||
"tsconfig-paths": "4.0.0",
|
||||
"twemoji-parser": "14.0.0",
|
||||
|
@ -135,7 +137,7 @@
|
|||
"@types/jsdom": "16.2.14",
|
||||
"@types/jsonld": "1.5.6",
|
||||
"@types/jsrsasign": "10.5.1",
|
||||
"@types/koa": "2.13.4",
|
||||
"@types/koa": "2.13.5",
|
||||
"@types/koa-bodyparser": "4.3.7",
|
||||
"@types/koa-cors": "0.0.2",
|
||||
"@types/koa-favicon": "2.0.21",
|
||||
|
@ -147,7 +149,7 @@
|
|||
"@types/koa__multer": "2.0.4",
|
||||
"@types/koa__router": "8.0.11",
|
||||
"@types/mocha": "9.1.1",
|
||||
"@types/node": "18.0.0",
|
||||
"@types/node": "18.0.3",
|
||||
"@types/node-fetch": "3.0.3",
|
||||
"@types/nodemailer": "6.4.4",
|
||||
"@types/oauth": "0.9.1",
|
||||
|
@ -169,10 +171,10 @@
|
|||
"@types/web-push": "3.3.2",
|
||||
"@types/websocket": "1.0.5",
|
||||
"@types/ws": "8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.0",
|
||||
"@typescript-eslint/parser": "5.30.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.6",
|
||||
"@typescript-eslint/parser": "5.30.6",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "8.18.0",
|
||||
"eslint": "8.19.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"execa": "6.1.0",
|
||||
"typescript": "4.7.4"
|
||||
|
|
|
@ -145,6 +145,12 @@ export function toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMenti
|
|||
a.textContent = node.props.content;
|
||||
return a;
|
||||
},
|
||||
|
||||
plain(node) {
|
||||
const el = doc.createElement('span');
|
||||
appendChildren(node.children, el);
|
||||
return el;
|
||||
},
|
||||
};
|
||||
|
||||
appendChildren(nodes, doc.body);
|
||||
|
|
|
@ -8,7 +8,7 @@ import { queueLogger } from '../../logger.js';
|
|||
import { addFile } from '@/services/drive/add-file.js';
|
||||
import { format as dateFormat } from 'date-fns';
|
||||
import { Users, Emojis } from '@/models/index.js';
|
||||
import { } from '@/queue/types.js';
|
||||
import { } from '@/queue/types.js';
|
||||
import { createTemp, createTempDir } from '@/misc/create-temp.js';
|
||||
import { downloadUrl } from '@/misc/download-url.js';
|
||||
import config from '@/config/index.js';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import config from '@/config/index.js';
|
||||
import Resolver from '../resolver.js';
|
||||
import { IObject, IQuestion, isQuestion } from '../type.js';
|
||||
import { IObject, IQuestion, isQuestion } from '../type.js';
|
||||
import { apLogger } from '../logger.js';
|
||||
import { Notes, Polls } from '@/models/index.js';
|
||||
import { IPoll } from '@/models/entities/poll.js';
|
||||
|
|
|
@ -8,7 +8,7 @@ import renderEmoji from './emoji.js';
|
|||
export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
|
||||
const reaction = noteReaction.reaction;
|
||||
|
||||
const object = {
|
||||
const object = {
|
||||
type: 'Like',
|
||||
id: `${config.url}/likes/${noteReaction.id}`,
|
||||
actor: `${config.url}/users/${noteReaction.userId}`,
|
||||
|
|
|
@ -68,11 +68,11 @@ export default (endpoint: IEndpoint, ctx: Koa.Context) => new Promise<void>((res
|
|||
}
|
||||
|
||||
try {
|
||||
UserIps.insert({
|
||||
UserIps.createQueryBuilder().insert().values({
|
||||
createdAt: new Date(),
|
||||
userId: user.id,
|
||||
ip: ip,
|
||||
});
|
||||
}).orIgnore(true).execute();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,15 @@ export async function readNotification(
|
|||
if (notificationIds.length === 0) return;
|
||||
|
||||
// Update documents
|
||||
await Notifications.update({
|
||||
const result = await Notifications.update({
|
||||
id: In(notificationIds),
|
||||
isRead: false,
|
||||
}, {
|
||||
isRead: true,
|
||||
});
|
||||
|
||||
if (result.affected === 0) return;
|
||||
|
||||
if (!await Users.getHasUnreadNotification(userId)) return postReadAllNotifications(userId);
|
||||
else return postReadNotifications(userId, notificationIds);
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
|||
const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description;
|
||||
|
||||
if (newName != null) {
|
||||
const tokens = mfm.parsePlain(newName);
|
||||
const tokens = mfm.parseSimple(newName);
|
||||
emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ const nodeinfo2 = async () => {
|
|||
enableEmail: meta.enableEmail,
|
||||
enableServiceWorker: meta.enableServiceWorker,
|
||||
proxyAccountName: proxyAccount ? proxyAccount.username : null,
|
||||
themeColor: meta.themeColor || '#86b300',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,19 +2,34 @@ import * as fs from 'node:fs';
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname } from 'node:path';
|
||||
import * as nsfw from 'nsfwjs';
|
||||
import * as tf from '@tensorflow/tfjs-node';
|
||||
import si from 'systeminformation';
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
const _dirname = dirname(_filename);
|
||||
|
||||
const REQUIRED_CPU_FLAGS = ['avx2', 'fma'];
|
||||
let isSupportedCpu: undefined | boolean = undefined;
|
||||
|
||||
let model: nsfw.NSFWJS;
|
||||
|
||||
export async function detectSensitive(path: string): Promise<nsfw.predictionType[] | null> {
|
||||
try {
|
||||
if (isSupportedCpu === undefined) {
|
||||
const cpuFlags = await getCpuFlags();
|
||||
isSupportedCpu = REQUIRED_CPU_FLAGS.every(required => cpuFlags.includes(required));
|
||||
}
|
||||
|
||||
if (!isSupportedCpu) {
|
||||
console.error('This CPU cannot use TensorFlow.');
|
||||
return null;
|
||||
}
|
||||
|
||||
const tf = await import('@tensorflow/tfjs-node');
|
||||
|
||||
if (model == null) model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, { size: 299 });
|
||||
|
||||
const buffer = await fs.promises.readFile(path);
|
||||
const image = await tf.node.decodeImage(buffer, 3) as tf.Tensor3D;
|
||||
const image = await tf.node.decodeImage(buffer, 3) as any;
|
||||
try {
|
||||
const predictions = await model.classify(image);
|
||||
return predictions;
|
||||
|
@ -26,3 +41,8 @@ export async function detectSensitive(path: string): Promise<nsfw.predictionType
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function getCpuFlags(): Promise<string[]> {
|
||||
const str = await si.cpuFlags();
|
||||
return str.split(/\s+/);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export async function fetchInstanceMetadata(instance: Instance, force = false):
|
|||
const [favicon, icon, themeColor, name, description] = await Promise.all([
|
||||
fetchFaviconUrl(instance, dom).catch(() => null),
|
||||
fetchIconUrl(instance, dom, manifest).catch(() => null),
|
||||
getThemeColor(dom, manifest).catch(() => null),
|
||||
getThemeColor(info, dom, manifest).catch(() => null),
|
||||
getSiteName(info, dom, manifest).catch(() => null),
|
||||
getDescription(info, dom, manifest).catch(() => null),
|
||||
]);
|
||||
|
@ -208,8 +208,8 @@ async function fetchIconUrl(instance: Instance, doc: DOMWindow['document'] | nul
|
|||
return null;
|
||||
}
|
||||
|
||||
async function getThemeColor(doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
||||
const themeColor = doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') || manifest?.theme_color;
|
||||
async function getThemeColor(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
||||
const themeColor = info?.metadata?.themeColor || doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') || manifest?.theme_color;
|
||||
|
||||
if (themeColor) {
|
||||
const color = new tinycolor(themeColor);
|
||||
|
|
|
@ -64,6 +64,7 @@ export async function pushNotification<T extends keyof pushNotificationsTypes>(u
|
|||
type,
|
||||
body: type === 'notification' ? truncateNotification(body as Packed<'Notification'>) : body,
|
||||
userId,
|
||||
dateTime: (new Date()).getTime(),
|
||||
}), {
|
||||
proxy: config.proxy,
|
||||
}).catch((err: any) => {
|
||||
|
|
|
@ -730,10 +730,10 @@
|
|||
"@types/koa-compose" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/koa@2.13.4":
|
||||
version "2.13.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b"
|
||||
integrity sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==
|
||||
"@types/koa@2.13.5":
|
||||
version "2.13.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.5.tgz#64b3ca4d54e08c0062e89ec666c9f45443b21a61"
|
||||
integrity sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==
|
||||
dependencies:
|
||||
"@types/accepts" "*"
|
||||
"@types/content-disposition" "*"
|
||||
|
@ -800,10 +800,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50"
|
||||
integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA==
|
||||
|
||||
"@types/node@18.0.0":
|
||||
version "18.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
|
||||
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
|
||||
"@types/node@18.0.3":
|
||||
version "18.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.3.tgz#463fc47f13ec0688a33aec75d078a0541a447199"
|
||||
integrity sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==
|
||||
|
||||
"@types/node@^14.11.8":
|
||||
version "14.17.9"
|
||||
|
@ -994,14 +994,14 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.0.tgz#524a11e15c09701733033c96943ecf33f55d9ca1"
|
||||
integrity sha512-lvhRJ2pGe2V9MEU46ELTdiHgiAFZPKtLhiU5wlnaYpMc2+c1R8fh8i80ZAa665drvjHKUJyRRGg3gEm1If54ow==
|
||||
"@typescript-eslint/eslint-plugin@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.6.tgz#9c6017b6c1d04894141b4a87816388967f64c359"
|
||||
integrity sha512-J4zYMIhgrx4MgnZrSDD7sEnQp7FmhKNOaqaOpaoQ/SfdMfRB/0yvK74hTnvH+VQxndZynqs5/Hn4t+2/j9bADg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/type-utils" "5.30.0"
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/type-utils" "5.30.6"
|
||||
"@typescript-eslint/utils" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.2.0"
|
||||
|
@ -1009,69 +1009,69 @@
|
|||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/parser@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.0.tgz#a2184fb5f8ef2bf1db0ae61a43907e2e32aa1b8f"
|
||||
integrity sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==
|
||||
"@typescript-eslint/parser@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.6.tgz#add440db038fa9d777e4ebdaf66da9e7fb7abe92"
|
||||
integrity sha512-gfF9lZjT0p2ZSdxO70Xbw8w9sPPJGfAdjK7WikEjB3fcUI/yr9maUVEdqigBjKincUYNKOmf7QBMiTf719kbrA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/typescript-estree" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz#bf585ee801ab4ad84db2f840174e171a6bb002c7"
|
||||
integrity sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==
|
||||
"@typescript-eslint/scope-manager@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.6.tgz#ce1b49ff5ce47f55518d63dbe8fc9181ddbd1a33"
|
||||
integrity sha512-Hkq5PhLgtVoW1obkqYH0i4iELctEKixkhWLPTYs55doGUKCASvkjOXOd/pisVeLdO24ZX9D6yymJ/twqpJiG3g==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
|
||||
"@typescript-eslint/type-utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.0.tgz#98f3af926a5099153f092d4dad87148df21fbaae"
|
||||
integrity sha512-GF8JZbZqSS+azehzlv/lmQQ3EU3VfWYzCczdZjJRxSEeXDQkqFhCBgFhallLDbPwQOEQ4MHpiPfkjKk7zlmeNg==
|
||||
"@typescript-eslint/type-utils@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.6.tgz#a64aa9acbe609ab77f09f53434a6af2b9685f3af"
|
||||
integrity sha512-GFVVzs2j0QPpM+NTDMXtNmJKlF842lkZKDSanIxf+ArJsGeZUIaeT4jGg+gAgHt7AcQSFwW7htzF/rbAh2jaVA==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
"@typescript-eslint/utils" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/types@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.0.tgz#db7d81d585a3da3801432a9c1d2fafbff125e110"
|
||||
integrity sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==
|
||||
"@typescript-eslint/types@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.6.tgz#86369d0a7af8c67024115ac1da3e8fb2d38907e1"
|
||||
integrity sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz#4565ee8a6d2ac368996e20b2344ea0eab1a8f0bb"
|
||||
integrity sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==
|
||||
"@typescript-eslint/typescript-estree@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.6.tgz#a84a0d6a486f9b54042da1de3d671a2c9f14484e"
|
||||
integrity sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.0.tgz#1dac771fead5eab40d31860716de219356f5f754"
|
||||
integrity sha512-0bIgOgZflLKIcZsWvfklsaQTM3ZUbmtH0rJ1hKyV3raoUYyeZwcjQ8ZUJTzS7KnhNcsVT1Rxs7zeeMHEhGlltw==
|
||||
"@typescript-eslint/utils@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.6.tgz#1de2da14f678e7d187daa6f2e4cdb558ed0609dc"
|
||||
integrity sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/typescript-estree" "5.30.6"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz#07721d23daca2ec4c2da7f1e660d41cd78bacac3"
|
||||
integrity sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==
|
||||
"@typescript-eslint/visitor-keys@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.6.tgz#94dd10bb481c8083378d24de1742a14b38a2678c"
|
||||
integrity sha512-41OiCjdL2mCaSDi2SvYbzFLlqqlm5v1ZW9Ym55wXKL/Rx6OOB1IbuFGo71Fj6Xy90gJDFTlgOS+vbmtGHPTQQA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
|
@ -1278,6 +1278,14 @@ anymatch@~3.1.1:
|
|||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
app-root-path@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad"
|
||||
|
@ -1878,7 +1886,7 @@ cheerio@0.22.0:
|
|||
lodash.reject "^4.4.0"
|
||||
lodash.some "^4.4.0"
|
||||
|
||||
chokidar@3.3.1, chokidar@3.5.3, chokidar@^3.3.1, chokidar@^3.5.3:
|
||||
chokidar@3.5.3, chokidar@^3.3.1, chokidar@^3.5.3:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450"
|
||||
integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==
|
||||
|
@ -2882,10 +2890,10 @@ eslint-visitor-keys@^3.3.0:
|
|||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@8.18.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.18.0.tgz#78d565d16c993d0b73968c523c0446b13da784fd"
|
||||
integrity sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==
|
||||
eslint@8.19.0:
|
||||
version "8.19.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.19.0.tgz#7342a3cbc4fbc5c106a1eefe0fd0b50b6b1a7d28"
|
||||
integrity sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.3.0"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
|
@ -3281,6 +3289,11 @@ fsevents@~2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
|
||||
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
fstream@^1.0.12:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"
|
||||
|
@ -3417,7 +3430,7 @@ github-from-package@0.0.0:
|
|||
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
|
||||
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
|
||||
|
||||
glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0:
|
||||
glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
|
@ -4856,12 +4869,12 @@ methods@^1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
|
||||
mfm-js@0.22.1:
|
||||
version "0.22.1"
|
||||
resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.22.1.tgz#ad5f0b95cc903ca5a5e414e2edf64ac4648dc8c2"
|
||||
integrity sha512-UV5zvDKlWPpBFeABhyCzuOTJ3RwrNrmVpJ+zz/dFX6D/ntEywljgxkfsLamcy0ZSwUAr0O+WQxGHvAwyxUgsAQ==
|
||||
mfm-js@0.23.0-canary.1:
|
||||
version "0.23.0-canary.1"
|
||||
resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.23.0-canary.1.tgz#1b7b7635f18bed9776054406b72e6bd613c8d0eb"
|
||||
integrity sha512-SkMrW1rQAv+mFGtLKN9DSv6vxSREDu8ChmkBl1Ch5sQfp47BhuvcRg5EKGmt3WAQRAOylXYMg8wVYR7C5BHKeA==
|
||||
dependencies:
|
||||
twemoji-parser "14.0.x"
|
||||
twemoji-parser "14.0.0"
|
||||
|
||||
micromatch@^4.0.0, micromatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
|
@ -5283,10 +5296,10 @@ node-fetch@*:
|
|||
fetch-blob "^3.1.4"
|
||||
formdata-polyfill "^4.0.10"
|
||||
|
||||
node-fetch@3.2.6, node-fetch@^3.2.2:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.6.tgz#6d4627181697a9d9674aae0d61548e0d629b31b9"
|
||||
integrity sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==
|
||||
node-fetch@3.2.8:
|
||||
version "3.2.8"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.8.tgz#0d9516dcf43a758d78d6dbe538adf0b1f6a4944e"
|
||||
integrity sha512-KtpD1YhGszhntMpBDyp5lyagk8KIMopC1LEb7cQUAh7zcosaX5uK8HnbNb2i3NTQK3sIawCItS0uFC3QzcLHdg==
|
||||
dependencies:
|
||||
data-uri-to-buffer "^4.0.0"
|
||||
fetch-blob "^3.1.4"
|
||||
|
@ -5299,6 +5312,15 @@ node-fetch@^2.6.1, node-fetch@~2.6.1:
|
|||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-fetch@^3.2.2:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.6.tgz#6d4627181697a9d9674aae0d61548e0d629b31b9"
|
||||
integrity sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==
|
||||
dependencies:
|
||||
data-uri-to-buffer "^4.0.0"
|
||||
fetch-blob "^3.1.4"
|
||||
formdata-polyfill "^4.0.10"
|
||||
|
||||
node-gyp-build@^4.2.3:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
|
||||
|
@ -5325,10 +5347,10 @@ node-gyp@^9.0.0:
|
|||
tar "^6.1.2"
|
||||
which "^2.0.2"
|
||||
|
||||
nodemailer@6.7.6:
|
||||
version "6.7.6"
|
||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.6.tgz#d3de8f644eaa0dad784d1be1375c596de492f3fc"
|
||||
integrity sha512-/6KF/umU7r7X21Y648/yiRLrgkfz0dmpyuo4BfgYWIpnT/jCbkPTvegMfxCsDAu+O810p2L1BGXieMTPp3nJVA==
|
||||
nodemailer@6.7.7:
|
||||
version "6.7.7"
|
||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.7.tgz#e522fbd7507b81c51446d3f79c4603bf00083ddd"
|
||||
integrity sha512-pOLC/s+2I1EXuSqO5Wa34i3kXZG3gugDssH+ZNCevHad65tc8vQlCQpOLaUjopvkRQKm2Cki2aME7fEOPRy3bA==
|
||||
|
||||
nofilter@^2.0.3:
|
||||
version "2.0.3"
|
||||
|
@ -6263,6 +6285,13 @@ readdirp@~3.3.0:
|
|||
dependencies:
|
||||
picomatch "^2.0.7"
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
reconnecting-websocket@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783"
|
||||
|
@ -7006,10 +7035,10 @@ syslog-pro@1.0.0:
|
|||
dependencies:
|
||||
moment "^2.22.2"
|
||||
|
||||
systeminformation@5.11.22:
|
||||
version "5.11.22"
|
||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.22.tgz#52eb78fd6bb48eef372f502b494ff59aacf82c02"
|
||||
integrity sha512-sBZJ/WBCf2vDLeMZaEyVuo+aXylOSmNHHB2cX0jHULFxSBLXHX+QUHYrCvmz+YiflKY3bsahVWX7vwuz1p1QZA==
|
||||
systeminformation@5.12.0:
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.12.0.tgz#1ff8d0b0fef9c2a6f70e1b1f2e681b8cd2d4b78e"
|
||||
integrity sha512-2fa/2cnWxiC/g8v3XX4aEC2CQWl/WJ+JrfLq9f76lxYqkW4DWiU3vJhrEgAzBT07ta73c5wHd0xgMeMo0vBiMQ==
|
||||
|
||||
tapable@^2.2.0:
|
||||
version "2.2.0"
|
||||
|
@ -7203,10 +7232,10 @@ ts-loader@9.3.1:
|
|||
micromatch "^4.0.0"
|
||||
semver "^7.3.4"
|
||||
|
||||
ts-node@10.8.1:
|
||||
version "10.8.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.1.tgz#ea2bd3459011b52699d7e88daa55a45a1af4f066"
|
||||
integrity sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==
|
||||
ts-node@10.8.2:
|
||||
version "10.8.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.2.tgz#3185b75228cef116bf82ffe8762594f54b2a23f2"
|
||||
integrity sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-support" "^0.8.0"
|
||||
"@tsconfig/node10" "^1.0.7"
|
||||
|
@ -7287,7 +7316,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
twemoji-parser@14.0.0, twemoji-parser@14.0.x:
|
||||
twemoji-parser@14.0.0:
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-14.0.0.tgz#13dabcb6d3a261d9efbf58a1666b182033bf2b62"
|
||||
integrity sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"@rollup/plugin-alias": "3.1.9",
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
"@syuilo/aiscript": "0.11.1",
|
||||
"@vitejs/plugin-vue": "3.0.0-beta.1",
|
||||
"@vitejs/plugin-vue": "3.0.0",
|
||||
"@vue/compiler-sfc": "3.2.37",
|
||||
"abort-controller": "3.0.0",
|
||||
"autobind-decorator": "2.4.0",
|
||||
|
@ -40,7 +40,7 @@
|
|||
"json5": "2.2.1",
|
||||
"katex": "0.15.6",
|
||||
"matter-js": "0.18.0",
|
||||
"mfm-js": "0.22.1",
|
||||
"mfm-js": "0.23.0-canary.1",
|
||||
"misskey-js": "0.0.14",
|
||||
"mocha": "10.0.0",
|
||||
"ms": "2.1.3",
|
||||
|
@ -56,7 +56,7 @@
|
|||
"random-seed": "0.3.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rndstr": "1.0.0",
|
||||
"rollup": "2.75.7",
|
||||
"rollup": "2.76.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass": "1.53.0",
|
||||
"seedrandom": "3.0.5",
|
||||
|
@ -74,7 +74,7 @@
|
|||
"uuid": "8.3.2",
|
||||
"v-debounce": "0.1.2",
|
||||
"vanilla-tilt": "1.7.2",
|
||||
"vite": "3.0.0-beta.7",
|
||||
"vite": "3.0.0",
|
||||
"vue": "3.2.37",
|
||||
"vue-prism-editor": "2.0.0-alpha.2",
|
||||
"vuedraggable": "4.0.1",
|
||||
|
@ -100,13 +100,13 @@
|
|||
"@types/uuid": "8.3.4",
|
||||
"@types/websocket": "1.0.5",
|
||||
"@types/ws": "8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.0",
|
||||
"@typescript-eslint/parser": "5.30.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.6",
|
||||
"@typescript-eslint/parser": "5.30.6",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "10.3.0",
|
||||
"eslint": "8.18.0",
|
||||
"eslint": "8.19.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-vue": "9.1.1",
|
||||
"eslint-plugin-vue": "9.2.0",
|
||||
"start-server-and-test": "1.14.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ const render = () => {
|
|||
plugins: [{
|
||||
id: 'vLine',
|
||||
beforeDraw(chart, args, options) {
|
||||
if (chart.tooltip._active && chart.tooltip._active.length) {
|
||||
if (chart.tooltip?._active?.length) {
|
||||
const activePoint = chart.tooltip._active[0];
|
||||
const ctx = chart.ctx;
|
||||
const x = activePoint.element.x;
|
||||
|
|
|
@ -59,7 +59,7 @@ const isThumbnailAvailable = computed(() => {
|
|||
display: flex;
|
||||
background: var(--panel);
|
||||
border-radius: 8px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
|
||||
> .icon-sub {
|
||||
position: absolute;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { } from 'vue';
|
||||
import { } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import XDrive from './drive.vue';
|
||||
import XWindow from '@/components/ui/window.vue';
|
||||
|
|
|
@ -41,7 +41,7 @@ import { useInterval } from '@/scripts/use-interval';
|
|||
|
||||
const props = defineProps<{
|
||||
modelValue: string | number;
|
||||
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time';
|
||||
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search';
|
||||
required?: boolean;
|
||||
readonly?: boolean;
|
||||
disabled?: boolean;
|
||||
|
|
|
@ -189,7 +189,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
|
|||
height: 3px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 999px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
|
||||
> .highlight {
|
||||
position: absolute;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<component :is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||
<component
|
||||
:is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||
@contextmenu.stop="() => {}"
|
||||
>
|
||||
<template v-if="!self">
|
||||
|
@ -23,14 +24,7 @@ import { toUnicode as decodePunycode } from 'punycode/';
|
|||
import { url as local } from '@/config';
|
||||
import * as os from '@/os';
|
||||
import { useTooltip } from '@/scripts/use-tooltip';
|
||||
|
||||
function safeURIDecode(str: string) {
|
||||
try {
|
||||
return decodeURIComponent(str);
|
||||
} catch {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
import { safeURIDecode } from '@/scripts/safe-uri-decode';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
|
@ -42,7 +36,7 @@ export default defineComponent({
|
|||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
}
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const self = props.url.startsWith(local);
|
||||
|
|
|
@ -76,7 +76,7 @@ export default {
|
|||
|
||||
<style lang="scss" module>
|
||||
.wrap {
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
animation-play-state: running;
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<MkA v-if="url.startsWith('/')" v-user-preview="canonical" :class="[$style.root, { isMe }]" :to="url" :style="{ background: bgCss }">
|
||||
<img :class="$style.icon" :src="`/avatar/@${username}@${host}`" alt="">
|
||||
<MkA v-if="url.startsWith('/')" v-user-preview="canonical" class="akbvjaqn" :class="{ isMe }" :to="url" :style="{ background: bgCss }">
|
||||
<img class="icon" :src="`/avatar/@${username}@${host}`" alt="">
|
||||
<span class="main">
|
||||
<span class="username">@{{ username }}</span>
|
||||
<span v-if="(host != localHost) || $store.state.showFullAcct" :class="$style.mainHost">@{{ toUnicode(host) }}</span>
|
||||
<span v-if="(host != localHost) || $store.state.showFullAcct" class="host">@{{ toUnicode(host) }}</span>
|
||||
</span>
|
||||
</MkA>
|
||||
<a v-else :class="$style.root" :href="url" target="_blank" rel="noopener" :style="{ background: bgCss }">
|
||||
<a v-else class="akbvjaqn" :href="url" target="_blank" rel="noopener" :style="{ background: bgCss }">
|
||||
<span class="main">
|
||||
<span class="username">@{{ username }}</span>
|
||||
<span :class="$style.mainHost">@{{ toUnicode(host) }}</span>
|
||||
<span class="host">@{{ toUnicode(host) }}</span>
|
||||
</span>
|
||||
</a>
|
||||
</template>
|
||||
|
@ -41,8 +41,8 @@ const bgCss = bg.toRgbString();
|
|||
useCssModule();
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
<style lang="scss" scoped>
|
||||
.akbvjaqn {
|
||||
display: inline-block;
|
||||
padding: 4px 8px 4px 4px;
|
||||
border-radius: 999px;
|
||||
|
@ -51,18 +51,18 @@ useCssModule();
|
|||
&.isMe {
|
||||
color: var(--mentionMe);
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
object-fit: cover;
|
||||
margin: 0 0.2em 0 0;
|
||||
vertical-align: bottom;
|
||||
border-radius: 100%;
|
||||
}
|
||||
> .icon {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
object-fit: cover;
|
||||
margin: 0 0.2em 0 0;
|
||||
vertical-align: bottom;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.mainHost {
|
||||
opacity: 0.5;
|
||||
> .main > .host {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -47,7 +47,7 @@ export default defineComponent({
|
|||
render() {
|
||||
if (this.text == null || this.text === '') return;
|
||||
|
||||
const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
|
||||
const ast = (this.plain ? mfm.parseSimple : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
|
||||
|
||||
const validTime = (t: string | null | undefined) => {
|
||||
if (t == null) return null;
|
||||
|
@ -312,6 +312,10 @@ export default defineComponent({
|
|||
})];
|
||||
}
|
||||
|
||||
case 'plain': {
|
||||
return [h('span', genEl(token.children))];
|
||||
}
|
||||
|
||||
default: {
|
||||
console.error('unrecognized ast type:', token.type);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ const props = defineProps<{
|
|||
display: flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
font-size: 0.95em;
|
||||
|
||||
&.min-width_350px {
|
||||
|
|
|
@ -36,7 +36,7 @@ const showContent = $ref(false);
|
|||
display: flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
font-size: 0.95em;
|
||||
|
||||
&.min-width_350px {
|
||||
|
|
|
@ -293,7 +293,7 @@ function readPromo() {
|
|||
position: relative;
|
||||
transition: box-shadow 0.1s ease;
|
||||
font-size: 1.05em;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
contain: content;
|
||||
|
||||
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
|
||||
|
|
|
@ -71,7 +71,7 @@ defineExpose({
|
|||
<style lang="scss" scoped>
|
||||
.meijqfqm {
|
||||
position: relative;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ onMounted(() => {
|
|||
width: min-content;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ export default defineComponent({
|
|||
text-decoration: none;
|
||||
background: var(--buttonBg);
|
||||
border-radius: 5px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
box-sizing: border-box;
|
||||
transition: background 0.1s ease;
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ export default defineComponent({
|
|||
|
||||
.ukygtjoj {
|
||||
position: relative;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
contain: content;
|
||||
|
||||
&.naked {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, computed, ref, watch, provide } from 'vue';
|
||||
import { nextTick, onMounted, watch, provide } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import { defaultStore } from '@/store';
|
||||
|
@ -57,13 +57,13 @@ const emit = defineEmits<{
|
|||
|
||||
provide('modal', true);
|
||||
|
||||
const maxHeight = ref<number>();
|
||||
const fixed = ref(false);
|
||||
const transformOrigin = ref('center');
|
||||
const showing = ref(true);
|
||||
const content = ref<HTMLElement>();
|
||||
let maxHeight = $ref<number>();
|
||||
let fixed = $ref(false);
|
||||
let transformOrigin = $ref('center');
|
||||
let showing = $ref(true);
|
||||
let content = $ref<HTMLElement>();
|
||||
const zIndex = os.claimZIndex(props.zPriority);
|
||||
const type = computed(() => {
|
||||
const type = $computed(() => {
|
||||
if (props.preferType === 'auto') {
|
||||
if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') {
|
||||
return 'drawer';
|
||||
|
@ -80,7 +80,7 @@ let contentClicking = false;
|
|||
const close = () => {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
if (props.src) props.src.style.pointerEvents = 'auto';
|
||||
showing.value = false;
|
||||
showing = false;
|
||||
emit('close');
|
||||
};
|
||||
|
||||
|
@ -89,8 +89,8 @@ const onBgClick = () => {
|
|||
emit('click');
|
||||
};
|
||||
|
||||
if (type.value === 'drawer') {
|
||||
maxHeight.value = window.innerHeight / 1.5;
|
||||
if (type === 'drawer') {
|
||||
maxHeight = window.innerHeight / 1.5;
|
||||
}
|
||||
|
||||
const keymap = {
|
||||
|
@ -101,22 +101,21 @@ const MARGIN = 16;
|
|||
|
||||
const align = () => {
|
||||
if (props.src == null) return;
|
||||
if (type.value === 'drawer') return;
|
||||
if (type.value === 'dialog') return;
|
||||
if (type === 'drawer') return;
|
||||
if (type === 'dialog') return;
|
||||
|
||||
const popover = content.value!;
|
||||
if (popover == null) return;
|
||||
if (content == null) return;
|
||||
|
||||
const srcRect = props.src.getBoundingClientRect();
|
||||
|
||||
const width = popover.offsetWidth;
|
||||
const height = popover.offsetHeight;
|
||||
const width = content!.offsetWidth;
|
||||
const height = content!.offsetHeight;
|
||||
|
||||
let left;
|
||||
let top;
|
||||
|
||||
const x = srcRect.left + (fixed.value ? 0 : window.pageXOffset);
|
||||
const y = srcRect.top + (fixed.value ? 0 : window.pageYOffset);
|
||||
const x = srcRect.left + (fixed ? 0 : window.pageXOffset);
|
||||
const y = srcRect.top + (fixed ? 0 : window.pageYOffset);
|
||||
|
||||
if (props.anchor.x === 'center') {
|
||||
left = x + (props.src.offsetWidth / 2) - (width / 2);
|
||||
|
@ -134,7 +133,7 @@ const align = () => {
|
|||
top = y + props.src.offsetHeight;
|
||||
}
|
||||
|
||||
if (fixed.value) {
|
||||
if (fixed) {
|
||||
// 画面から横にはみ出る場合
|
||||
if (left + width > window.innerWidth) {
|
||||
left = window.innerWidth - width;
|
||||
|
@ -147,16 +146,16 @@ const align = () => {
|
|||
if (top + height > (window.innerHeight - MARGIN)) {
|
||||
if (props.noOverlap && props.anchor.x === 'center') {
|
||||
if (underSpace >= (upperSpace / 3)) {
|
||||
maxHeight.value = underSpace;
|
||||
maxHeight = underSpace;
|
||||
} else {
|
||||
maxHeight.value = upperSpace;
|
||||
maxHeight = upperSpace;
|
||||
top = (upperSpace + MARGIN) - height;
|
||||
}
|
||||
} else {
|
||||
top = (window.innerHeight - MARGIN) - height;
|
||||
}
|
||||
} else {
|
||||
maxHeight.value = underSpace;
|
||||
maxHeight = underSpace;
|
||||
}
|
||||
} else {
|
||||
// 画面から横にはみ出る場合
|
||||
|
@ -171,16 +170,16 @@ const align = () => {
|
|||
if (top + height - window.pageYOffset > (window.innerHeight - MARGIN)) {
|
||||
if (props.noOverlap && props.anchor.x === 'center') {
|
||||
if (underSpace >= (upperSpace / 3)) {
|
||||
maxHeight.value = underSpace;
|
||||
maxHeight = underSpace;
|
||||
} else {
|
||||
maxHeight.value = upperSpace;
|
||||
maxHeight = upperSpace;
|
||||
top = window.pageYOffset + ((upperSpace + MARGIN) - height);
|
||||
}
|
||||
} else {
|
||||
top = (window.innerHeight - MARGIN) - height + window.pageYOffset - 1;
|
||||
}
|
||||
} else {
|
||||
maxHeight.value = underSpace;
|
||||
maxHeight = underSpace;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,29 +194,29 @@ const align = () => {
|
|||
let transformOriginX = 'center';
|
||||
let transformOriginY = 'center';
|
||||
|
||||
if (top >= srcRect.top + props.src.offsetHeight + (fixed.value ? 0 : window.pageYOffset)) {
|
||||
if (top >= srcRect.top + props.src.offsetHeight + (fixed ? 0 : window.pageYOffset)) {
|
||||
transformOriginY = 'top';
|
||||
} else if ((top + height) <= srcRect.top + (fixed.value ? 0 : window.pageYOffset)) {
|
||||
} else if ((top + height) <= srcRect.top + (fixed ? 0 : window.pageYOffset)) {
|
||||
transformOriginY = 'bottom';
|
||||
}
|
||||
|
||||
if (left >= srcRect.left + props.src.offsetWidth + (fixed.value ? 0 : window.pageXOffset)) {
|
||||
if (left >= srcRect.left + props.src.offsetWidth + (fixed ? 0 : window.pageXOffset)) {
|
||||
transformOriginX = 'left';
|
||||
} else if ((left + width) <= srcRect.left + (fixed.value ? 0 : window.pageXOffset)) {
|
||||
} else if ((left + width) <= srcRect.left + (fixed ? 0 : window.pageXOffset)) {
|
||||
transformOriginX = 'right';
|
||||
}
|
||||
|
||||
transformOrigin.value = `${transformOriginX} ${transformOriginY}`;
|
||||
transformOrigin = `${transformOriginX} ${transformOriginY}`;
|
||||
|
||||
popover.style.left = left + 'px';
|
||||
popover.style.top = top + 'px';
|
||||
content.style.left = left + 'px';
|
||||
content.style.top = top + 'px';
|
||||
};
|
||||
|
||||
const onOpened = () => {
|
||||
emit('opened');
|
||||
|
||||
// モーダルコンテンツにマウスボタンが押され、コンテンツ外でマウスボタンが離されたときにモーダルバックグラウンドクリックと判定させないためにマウスイベントを監視しフラグ管理する
|
||||
const el = content.value!.children[0];
|
||||
const el = content!.children[0];
|
||||
el.addEventListener('mousedown', ev => {
|
||||
contentClicking = true;
|
||||
window.addEventListener('mouseup', ev => {
|
||||
|
@ -235,7 +234,7 @@ onMounted(() => {
|
|||
// eslint-disable-next-line vue/no-mutating-props
|
||||
props.src.style.pointerEvents = 'none';
|
||||
}
|
||||
fixed.value = (type.value === 'drawer') || (getFixedContainer(props.src) != null);
|
||||
fixed = (type === 'drawer') || (getFixedContainer(props.src) != null);
|
||||
|
||||
await nextTick();
|
||||
|
||||
|
@ -243,10 +242,9 @@ onMounted(() => {
|
|||
}, { immediate: true });
|
||||
|
||||
nextTick(() => {
|
||||
const popover = content.value;
|
||||
new ResizeObserver((entries, observer) => {
|
||||
align();
|
||||
}).observe(popover!);
|
||||
}).observe(content!);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -389,7 +387,7 @@ defineExpose({
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
|
||||
> .content {
|
||||
position: fixed;
|
||||
|
|
|
@ -30,7 +30,7 @@ export default defineComponent({
|
|||
props: {
|
||||
def: {
|
||||
type: Array,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
grid: {
|
||||
type: Boolean,
|
||||
|
@ -64,7 +64,7 @@ export default defineComponent({
|
|||
box-sizing: border-box;
|
||||
padding: 10px 16px 10px 8px;
|
||||
border-radius: 9px;
|
||||
font-size: 0.95em;
|
||||
font-size: 0.9em;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
|
|
@ -105,7 +105,7 @@ function choose(visibility: typeof misskey.noteVisibilities[number]): void {
|
|||
}
|
||||
|
||||
&.active {
|
||||
color: #fff;
|
||||
color: var(--fgOnAccent);
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<header>
|
||||
<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)" class="mk-widget-select">
|
||||
<template #label>{{ $ts.selectWidget }}</template>
|
||||
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ $t(`_widgets.${widget}`) }}</option>
|
||||
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ i18n.t(`_widgets.${widget}`) }}</option>
|
||||
</MkSelect>
|
||||
<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
|
||||
<MkButton inline @click="$emit('exit')">{{ $ts.close }}</MkButton>
|
||||
|
@ -26,79 +26,91 @@
|
|||
</template>
|
||||
</XDraggable>
|
||||
</template>
|
||||
<component :is="`mkw-${widget.name}`" v-for="widget in widgets" v-else :key="widget.id" class="widget" :widget="widget" @updateProps="updateWidget(widget.id, $event)"/>
|
||||
<component :is="`mkw-${widget.name}`" v-for="widget in widgets" v-else :key="widget.id" :ref="el => widgetRefs[widget.id] = el" class="widget" :widget="widget" @updateProps="updateWidget(widget.id, $event)" @contextmenu.stop="onContextmenu(widget, $event)"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, defineAsyncComponent, reactive, ref, computed } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, reactive, ref, computed } from 'vue';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import { widgets as widgetDefs } from '@/widgets';
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XDraggable: defineAsyncComponent(() => import('vuedraggable')),
|
||||
MkSelect,
|
||||
MkButton,
|
||||
},
|
||||
const XDraggable = defineAsyncComponent(() => import('vuedraggable'));
|
||||
|
||||
props: {
|
||||
widgets: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
edit: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
type Widget = {
|
||||
name: string;
|
||||
id: string;
|
||||
data: Record<string, any>;
|
||||
};
|
||||
|
||||
emits: ['updateWidgets', 'addWidget', 'removeWidget', 'updateWidget', 'exit'],
|
||||
const props = defineProps<{
|
||||
widgets: Widget[];
|
||||
edit: boolean;
|
||||
}>();
|
||||
|
||||
setup(props, context) {
|
||||
const widgetRefs = reactive({});
|
||||
const configWidget = (id: string) => {
|
||||
widgetRefs[id].configure();
|
||||
};
|
||||
const widgetAdderSelected = ref(null);
|
||||
const addWidget = () => {
|
||||
if (widgetAdderSelected.value == null) return;
|
||||
const emit = defineEmits<{
|
||||
(ev: 'updateWidgets', widgets: Widget[]): void;
|
||||
(ev: 'addWidget', widget: Widget): void;
|
||||
(ev: 'removeWidget', widget: Widget): void;
|
||||
(ev: 'updateWidget', widget: Partial<Widget>): void;
|
||||
(ev: 'exit'): void;
|
||||
}>();
|
||||
|
||||
context.emit('addWidget', {
|
||||
name: widgetAdderSelected.value,
|
||||
id: uuid(),
|
||||
data: {},
|
||||
});
|
||||
const widgetRefs = {};
|
||||
const configWidget = (id: string) => {
|
||||
widgetRefs[id].configure();
|
||||
};
|
||||
const widgetAdderSelected = ref(null);
|
||||
const addWidget = () => {
|
||||
if (widgetAdderSelected.value == null) return;
|
||||
|
||||
widgetAdderSelected.value = null;
|
||||
};
|
||||
const removeWidget = (widget) => {
|
||||
context.emit('removeWidget', widget);
|
||||
};
|
||||
const updateWidget = (id, data) => {
|
||||
context.emit('updateWidget', { id, data });
|
||||
};
|
||||
const widgets_ = computed({
|
||||
get: () => props.widgets,
|
||||
set: (value) => {
|
||||
context.emit('updateWidgets', value);
|
||||
},
|
||||
});
|
||||
emit('addWidget', {
|
||||
name: widgetAdderSelected.value,
|
||||
id: uuid(),
|
||||
data: {},
|
||||
});
|
||||
|
||||
return {
|
||||
widgetRefs,
|
||||
configWidget,
|
||||
widgetAdderSelected,
|
||||
widgetDefs,
|
||||
addWidget,
|
||||
removeWidget,
|
||||
updateWidget,
|
||||
widgets_,
|
||||
};
|
||||
widgetAdderSelected.value = null;
|
||||
};
|
||||
const removeWidget = (widget) => {
|
||||
emit('removeWidget', widget);
|
||||
};
|
||||
const updateWidget = (id, data) => {
|
||||
emit('updateWidget', { id, data });
|
||||
};
|
||||
const widgets_ = computed({
|
||||
get: () => props.widgets,
|
||||
set: (value) => {
|
||||
emit('updateWidgets', value);
|
||||
},
|
||||
});
|
||||
|
||||
function onContextmenu(widget: Widget, ev: MouseEvent) {
|
||||
const isLink = (el: HTMLElement) => {
|
||||
if (el.tagName === 'A') return true;
|
||||
if (el.parentElement) {
|
||||
return isLink(el.parentElement);
|
||||
}
|
||||
};
|
||||
if (isLink(ev.target)) return;
|
||||
if (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(ev.target.tagName) || ev.target.attributes['contenteditable']) return;
|
||||
if (window.getSelection()?.toString() !== '') return;
|
||||
|
||||
os.contextMenu([{
|
||||
type: 'label',
|
||||
text: i18n.t(`_widgets.${widget.name}`),
|
||||
}, {
|
||||
icon: 'fas fa-cog',
|
||||
text: i18n.ts.settings,
|
||||
action: () => {
|
||||
configWidget(widget.id);
|
||||
},
|
||||
}], ev);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -27,8 +27,8 @@ function getClassOrder(width: number, queue: Value): ClassOrder {
|
|||
...(queue.min ? queue.min.filter(v => width >= v).map(getMinClass) : []),
|
||||
],
|
||||
remove: [
|
||||
...(queue.max ? queue.max.filter(v => width > v).map(getMaxClass) : []),
|
||||
...(queue.min ? queue.min.filter(v => width < v).map(getMinClass) : []),
|
||||
...(queue.max ? queue.max.filter(v => width > v).map(getMaxClass) : []),
|
||||
...(queue.min ? queue.min.filter(v => width < v).map(getMinClass) : []),
|
||||
]
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,401 +39,403 @@ import { reactionPicker } from '@/scripts/reaction-picker';
|
|||
import { getUrlWithoutLoginId } from '@/scripts/login-id';
|
||||
import { getAccountFromId } from '@/scripts/get-account-from-id';
|
||||
|
||||
console.info(`Misskey v${version}`);
|
||||
(async () => {
|
||||
console.info(`Misskey v${version}`);
|
||||
|
||||
if (_DEV_) {
|
||||
console.warn('Development mode!!!');
|
||||
if (_DEV_) {
|
||||
console.warn('Development mode!!!');
|
||||
|
||||
console.info(`vue ${vueVersion}`);
|
||||
console.info(`vue ${vueVersion}`);
|
||||
|
||||
(window as any).$i = $i;
|
||||
(window as any).$store = defaultStore;
|
||||
(window as any).$i = $i;
|
||||
(window as any).$store = defaultStore;
|
||||
|
||||
window.addEventListener('error', event => {
|
||||
console.error(event);
|
||||
/*
|
||||
alert({
|
||||
type: 'error',
|
||||
title: 'DEV: Unhandled error',
|
||||
text: event.message
|
||||
window.addEventListener('error', event => {
|
||||
console.error(event);
|
||||
/*
|
||||
alert({
|
||||
type: 'error',
|
||||
title: 'DEV: Unhandled error',
|
||||
text: event.message
|
||||
});
|
||||
*/
|
||||
});
|
||||
*/
|
||||
|
||||
window.addEventListener('unhandledrejection', event => {
|
||||
console.error(event);
|
||||
/*
|
||||
alert({
|
||||
type: 'error',
|
||||
title: 'DEV: Unhandled promise rejection',
|
||||
text: event.reason
|
||||
});
|
||||
*/
|
||||
});
|
||||
}
|
||||
|
||||
// タッチデバイスでCSSの:hoverを機能させる
|
||||
document.addEventListener('touchend', () => {}, { passive: true });
|
||||
|
||||
// 一斉リロード
|
||||
reloadChannel.addEventListener('message', path => {
|
||||
if (path !== null) location.href = path;
|
||||
else location.reload();
|
||||
});
|
||||
|
||||
window.addEventListener('unhandledrejection', event => {
|
||||
console.error(event);
|
||||
/*
|
||||
alert({
|
||||
type: 'error',
|
||||
title: 'DEV: Unhandled promise rejection',
|
||||
text: event.reason
|
||||
});
|
||||
*/
|
||||
});
|
||||
}
|
||||
|
||||
// タッチデバイスでCSSの:hoverを機能させる
|
||||
document.addEventListener('touchend', () => {}, { passive: true });
|
||||
|
||||
// 一斉リロード
|
||||
reloadChannel.addEventListener('message', path => {
|
||||
if (path !== null) location.href = path;
|
||||
else location.reload();
|
||||
});
|
||||
|
||||
//#region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
|
||||
// TODO: いつの日にか消したい
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
window.addEventListener('resize', () => {
|
||||
//#region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
|
||||
// TODO: いつの日にか消したい
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
});
|
||||
//#endregion
|
||||
window.addEventListener('resize', () => {
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
});
|
||||
//#endregion
|
||||
|
||||
// If mobile, insert the viewport meta tag
|
||||
if (['smartphone', 'tablet'].includes(deviceKind)) {
|
||||
const viewport = document.getElementsByName('viewport').item(0);
|
||||
viewport.setAttribute('content',
|
||||
`${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`);
|
||||
}
|
||||
|
||||
//#region Set lang attr
|
||||
const html = document.documentElement;
|
||||
html.setAttribute('lang', lang);
|
||||
//#endregion
|
||||
|
||||
//#region loginId
|
||||
const params = new URLSearchParams(location.search);
|
||||
const loginId = params.get('loginId');
|
||||
|
||||
if (loginId) {
|
||||
const target = getUrlWithoutLoginId(location.href);
|
||||
|
||||
if (!$i || $i.id !== loginId) {
|
||||
const account = await getAccountFromId(loginId);
|
||||
if (account) {
|
||||
await login(account.token, target);
|
||||
}
|
||||
// If mobile, insert the viewport meta tag
|
||||
if (['smartphone', 'tablet'].includes(deviceKind)) {
|
||||
const viewport = document.getElementsByName('viewport').item(0);
|
||||
viewport.setAttribute('content',
|
||||
`${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`);
|
||||
}
|
||||
|
||||
history.replaceState({ misskey: 'loginId' }, '', target);
|
||||
}
|
||||
//#region Set lang attr
|
||||
const html = document.documentElement;
|
||||
html.setAttribute('lang', lang);
|
||||
//#endregion
|
||||
|
||||
//#endregion
|
||||
//#region loginId
|
||||
const params = new URLSearchParams(location.search);
|
||||
const loginId = params.get('loginId');
|
||||
|
||||
//#region Fetch user
|
||||
if ($i && $i.token) {
|
||||
if (_DEV_) {
|
||||
console.log('account cache found. refreshing...');
|
||||
}
|
||||
if (loginId) {
|
||||
const target = getUrlWithoutLoginId(location.href);
|
||||
|
||||
refreshAccount();
|
||||
} else {
|
||||
if (_DEV_) {
|
||||
console.log('no account cache found.');
|
||||
}
|
||||
|
||||
// 連携ログインの場合用にCookieを参照する
|
||||
const i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1];
|
||||
|
||||
if (i != null && i !== 'null') {
|
||||
if (_DEV_) {
|
||||
console.log('signing...');
|
||||
}
|
||||
|
||||
try {
|
||||
document.body.innerHTML = '<div>Please wait...</div>';
|
||||
await login(i);
|
||||
} catch (err) {
|
||||
// Render the error screen
|
||||
// TODO: ちゃんとしたコンポーネントをレンダリングする(v10とかのトラブルシューティングゲーム付きのやつみたいな)
|
||||
document.body.innerHTML = '<div id="err">Oops!</div>';
|
||||
}
|
||||
} else {
|
||||
if (_DEV_) {
|
||||
console.log('not signed in');
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
const fetchInstanceMetaPromise = fetchInstance();
|
||||
|
||||
fetchInstanceMetaPromise.then(() => {
|
||||
localStorage.setItem('v', instance.version);
|
||||
|
||||
// Init service worker
|
||||
initializeSw();
|
||||
});
|
||||
|
||||
const app = createApp(
|
||||
window.location.search === '?zen' ? defineAsyncComponent(() => import('@/ui/zen.vue')) :
|
||||
!$i ? defineAsyncComponent(() => import('@/ui/visitor.vue')) :
|
||||
ui === 'deck' ? defineAsyncComponent(() => import('@/ui/deck.vue')) :
|
||||
ui === 'classic' ? defineAsyncComponent(() => import('@/ui/classic.vue')) :
|
||||
defineAsyncComponent(() => import('@/ui/universal.vue')),
|
||||
);
|
||||
|
||||
if (_DEV_) {
|
||||
app.config.performance = true;
|
||||
}
|
||||
|
||||
app.config.globalProperties = {
|
||||
$i,
|
||||
$store: defaultStore,
|
||||
$instance: instance,
|
||||
$t: i18n.t,
|
||||
$ts: i18n.ts,
|
||||
};
|
||||
|
||||
widgets(app);
|
||||
directives(app);
|
||||
components(app);
|
||||
|
||||
const splash = document.getElementById('splash');
|
||||
// 念のためnullチェック(HTMLが古い場合があるため(そのうち消す))
|
||||
if (splash) splash.addEventListener('transitionend', () => {
|
||||
splash.remove();
|
||||
});
|
||||
|
||||
// https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210
|
||||
// なぜかinit.tsの内容が2回実行されることがあるため、mountするdivを1つに制限する
|
||||
const rootEl = (() => {
|
||||
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
|
||||
|
||||
const currentEl = document.getElementById(MISSKEY_MOUNT_DIV_ID);
|
||||
|
||||
if (currentEl) {
|
||||
console.warn('multiple import detected');
|
||||
return currentEl;
|
||||
}
|
||||
|
||||
const rootEl = document.createElement('div');
|
||||
rootEl.id = MISSKEY_MOUNT_DIV_ID;
|
||||
document.body.appendChild(rootEl);
|
||||
return rootEl;
|
||||
})();
|
||||
|
||||
app.mount(rootEl);
|
||||
|
||||
// boot.jsのやつを解除
|
||||
window.onerror = null;
|
||||
window.onunhandledrejection = null;
|
||||
|
||||
reactionPicker.init();
|
||||
|
||||
if (splash) {
|
||||
splash.style.opacity = '0';
|
||||
splash.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
// クライアントが更新されたか?
|
||||
const lastVersion = localStorage.getItem('lastVersion');
|
||||
if (lastVersion !== version) {
|
||||
localStorage.setItem('lastVersion', version);
|
||||
|
||||
// テーマリビルドするため
|
||||
localStorage.removeItem('theme');
|
||||
|
||||
try { // 変なバージョン文字列来るとcompareVersionsでエラーになるため
|
||||
if (lastVersion != null && compareVersions(version, lastVersion) === 1) {
|
||||
// ログインしてる場合だけ
|
||||
if ($i) {
|
||||
popup(defineAsyncComponent(() => import('@/components/updated.vue')), {}, {}, 'closed');
|
||||
if (!$i || $i.id !== loginId) {
|
||||
const account = await getAccountFromId(loginId);
|
||||
if (account) {
|
||||
await login(account.token, target);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
history.replaceState({ misskey: 'loginId' }, '', target);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため)
|
||||
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
|
||||
applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'));
|
||||
}, { immediate: localStorage.theme == null });
|
||||
//#endregion
|
||||
|
||||
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter('darkTheme'));
|
||||
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter('lightTheme'));
|
||||
//#region Fetch user
|
||||
if ($i && $i.token) {
|
||||
if (_DEV_) {
|
||||
console.log('account cache found. refreshing...');
|
||||
}
|
||||
|
||||
watch(darkTheme, (theme) => {
|
||||
if (defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
}
|
||||
});
|
||||
|
||||
watch(lightTheme, (theme) => {
|
||||
if (!defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
}
|
||||
});
|
||||
|
||||
//#region Sync dark mode
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', isDeviceDarkmode());
|
||||
}
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addListener(mql => {
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', mql.matches);
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
fetchInstanceMetaPromise.then(() => {
|
||||
if (defaultStore.state.themeInitial) {
|
||||
if (instance.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON5.parse(instance.defaultLightTheme));
|
||||
if (instance.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON5.parse(instance.defaultDarkTheme));
|
||||
defaultStore.set('themeInitial', false);
|
||||
}
|
||||
});
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffectForModal, v => {
|
||||
document.documentElement.style.setProperty('--modalBgFilter', v ? 'blur(4px)' : 'none');
|
||||
}, { immediate: true });
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffect, v => {
|
||||
if (v) {
|
||||
document.documentElement.style.removeProperty('--blur');
|
||||
refreshAccount();
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--blur', 'none');
|
||||
}
|
||||
}, { immediate: true });
|
||||
if (_DEV_) {
|
||||
console.log('no account cache found.');
|
||||
}
|
||||
|
||||
let reloadDialogShowing = false;
|
||||
stream.on('_disconnected_', async () => {
|
||||
if (defaultStore.state.serverDisconnectedBehavior === 'reload') {
|
||||
location.reload();
|
||||
} else if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
|
||||
if (reloadDialogShowing) return;
|
||||
reloadDialogShowing = true;
|
||||
const { canceled } = await confirm({
|
||||
type: 'warning',
|
||||
title: i18n.ts.disconnectedFromServer,
|
||||
text: i18n.ts.reloadConfirm,
|
||||
});
|
||||
reloadDialogShowing = false;
|
||||
if (!canceled) {
|
||||
// 連携ログインの場合用にCookieを参照する
|
||||
const i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1];
|
||||
|
||||
if (i != null && i !== 'null') {
|
||||
if (_DEV_) {
|
||||
console.log('signing...');
|
||||
}
|
||||
|
||||
try {
|
||||
document.body.innerHTML = '<div>Please wait...</div>';
|
||||
await login(i);
|
||||
} catch (err) {
|
||||
// Render the error screen
|
||||
// TODO: ちゃんとしたコンポーネントをレンダリングする(v10とかのトラブルシューティングゲーム付きのやつみたいな)
|
||||
document.body.innerHTML = '<div id="err">Oops!</div>';
|
||||
}
|
||||
} else {
|
||||
if (_DEV_) {
|
||||
console.log('not signed in');
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
const fetchInstanceMetaPromise = fetchInstance();
|
||||
|
||||
fetchInstanceMetaPromise.then(() => {
|
||||
localStorage.setItem('v', instance.version);
|
||||
|
||||
// Init service worker
|
||||
initializeSw();
|
||||
});
|
||||
|
||||
const app = createApp(
|
||||
window.location.search === '?zen' ? defineAsyncComponent(() => import('@/ui/zen.vue')) :
|
||||
!$i ? defineAsyncComponent(() => import('@/ui/visitor.vue')) :
|
||||
ui === 'deck' ? defineAsyncComponent(() => import('@/ui/deck.vue')) :
|
||||
ui === 'classic' ? defineAsyncComponent(() => import('@/ui/classic.vue')) :
|
||||
defineAsyncComponent(() => import('@/ui/universal.vue')),
|
||||
);
|
||||
|
||||
if (_DEV_) {
|
||||
app.config.performance = true;
|
||||
}
|
||||
|
||||
app.config.globalProperties = {
|
||||
$i,
|
||||
$store: defaultStore,
|
||||
$instance: instance,
|
||||
$t: i18n.t,
|
||||
$ts: i18n.ts,
|
||||
};
|
||||
|
||||
widgets(app);
|
||||
directives(app);
|
||||
components(app);
|
||||
|
||||
const splash = document.getElementById('splash');
|
||||
// 念のためnullチェック(HTMLが古い場合があるため(そのうち消す))
|
||||
if (splash) splash.addEventListener('transitionend', () => {
|
||||
splash.remove();
|
||||
});
|
||||
|
||||
// https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210
|
||||
// なぜかinit.tsの内容が2回実行されることがあるため、mountするdivを1つに制限する
|
||||
const rootEl = (() => {
|
||||
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
|
||||
|
||||
const currentEl = document.getElementById(MISSKEY_MOUNT_DIV_ID);
|
||||
|
||||
if (currentEl) {
|
||||
console.warn('multiple import detected');
|
||||
return currentEl;
|
||||
}
|
||||
|
||||
const rootEl = document.createElement('div');
|
||||
rootEl.id = MISSKEY_MOUNT_DIV_ID;
|
||||
document.body.appendChild(rootEl);
|
||||
return rootEl;
|
||||
})();
|
||||
|
||||
app.mount(rootEl);
|
||||
|
||||
// boot.jsのやつを解除
|
||||
window.onerror = null;
|
||||
window.onunhandledrejection = null;
|
||||
|
||||
reactionPicker.init();
|
||||
|
||||
if (splash) {
|
||||
splash.style.opacity = '0';
|
||||
splash.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
// クライアントが更新されたか?
|
||||
const lastVersion = localStorage.getItem('lastVersion');
|
||||
if (lastVersion !== version) {
|
||||
localStorage.setItem('lastVersion', version);
|
||||
|
||||
// テーマリビルドするため
|
||||
localStorage.removeItem('theme');
|
||||
|
||||
try { // 変なバージョン文字列来るとcompareVersionsでエラーになるため
|
||||
if (lastVersion != null && compareVersions(version, lastVersion) === 1) {
|
||||
// ログインしてる場合だけ
|
||||
if ($i) {
|
||||
popup(defineAsyncComponent(() => import('@/components/updated.vue')), {}, {}, 'closed');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため)
|
||||
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
|
||||
applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'));
|
||||
}, { immediate: localStorage.theme == null });
|
||||
|
||||
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter('darkTheme'));
|
||||
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter('lightTheme'));
|
||||
|
||||
watch(darkTheme, (theme) => {
|
||||
if (defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
}
|
||||
});
|
||||
|
||||
watch(lightTheme, (theme) => {
|
||||
if (!defaultStore.state.darkMode) {
|
||||
applyTheme(theme);
|
||||
}
|
||||
});
|
||||
|
||||
//#region Sync dark mode
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', isDeviceDarkmode());
|
||||
}
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addListener(mql => {
|
||||
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
|
||||
defaultStore.set('darkMode', mql.matches);
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
fetchInstanceMetaPromise.then(() => {
|
||||
if (defaultStore.state.themeInitial) {
|
||||
if (instance.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON5.parse(instance.defaultLightTheme));
|
||||
if (instance.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON5.parse(instance.defaultDarkTheme));
|
||||
defaultStore.set('themeInitial', false);
|
||||
}
|
||||
});
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffectForModal, v => {
|
||||
document.documentElement.style.setProperty('--modalBgFilter', v ? 'blur(4px)' : 'none');
|
||||
}, { immediate: true });
|
||||
|
||||
watch(defaultStore.reactiveState.useBlurEffect, v => {
|
||||
if (v) {
|
||||
document.documentElement.style.removeProperty('--blur');
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--blur', 'none');
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
let reloadDialogShowing = false;
|
||||
stream.on('_disconnected_', async () => {
|
||||
if (defaultStore.state.serverDisconnectedBehavior === 'reload') {
|
||||
location.reload();
|
||||
} else if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
|
||||
if (reloadDialogShowing) return;
|
||||
reloadDialogShowing = true;
|
||||
const { canceled } = await confirm({
|
||||
type: 'warning',
|
||||
title: i18n.ts.disconnectedFromServer,
|
||||
text: i18n.ts.reloadConfirm,
|
||||
});
|
||||
reloadDialogShowing = false;
|
||||
if (!canceled) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('emojiAdded', emojiData => {
|
||||
// TODO
|
||||
//store.commit('instance/set', );
|
||||
});
|
||||
|
||||
for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
|
||||
import('./plugin').then(({ install }) => {
|
||||
install(plugin);
|
||||
});
|
||||
}
|
||||
|
||||
const hotkeys = {
|
||||
'd': (): void => {
|
||||
defaultStore.set('darkMode', !defaultStore.state.darkMode);
|
||||
},
|
||||
's': search,
|
||||
};
|
||||
stream.on('emojiAdded', emojiData => {
|
||||
// TODO
|
||||
//store.commit('instance/set', );
|
||||
});
|
||||
|
||||
if ($i) {
|
||||
// only add post shortcuts if logged in
|
||||
hotkeys['p|n'] = post;
|
||||
|
||||
if ($i.isDeleted) {
|
||||
alert({
|
||||
type: 'warning',
|
||||
text: i18n.ts.accountDeletionInProgress,
|
||||
for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
|
||||
import('./plugin').then(({ install }) => {
|
||||
install(plugin);
|
||||
});
|
||||
}
|
||||
|
||||
const lastUsed = localStorage.getItem('lastUsed');
|
||||
if (lastUsed) {
|
||||
const lastUsedDate = parseInt(lastUsed, 10);
|
||||
// 二時間以上前なら
|
||||
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
|
||||
toast(i18n.t('welcomeBackWithName', {
|
||||
name: $i.name || $i.username,
|
||||
}));
|
||||
}
|
||||
}
|
||||
localStorage.setItem('lastUsed', Date.now().toString());
|
||||
const hotkeys = {
|
||||
'd': (): void => {
|
||||
defaultStore.set('darkMode', !defaultStore.state.darkMode);
|
||||
},
|
||||
's': search,
|
||||
};
|
||||
|
||||
if ('Notification' in window) {
|
||||
// 許可を得ていなかったらリクエスト
|
||||
if (Notification.permission === 'default') {
|
||||
Notification.requestPermission();
|
||||
if ($i) {
|
||||
// only add post shortcuts if logged in
|
||||
hotkeys['p|n'] = post;
|
||||
|
||||
if ($i.isDeleted) {
|
||||
alert({
|
||||
type: 'warning',
|
||||
text: i18n.ts.accountDeletionInProgress,
|
||||
});
|
||||
}
|
||||
|
||||
const lastUsed = localStorage.getItem('lastUsed');
|
||||
if (lastUsed) {
|
||||
const lastUsedDate = parseInt(lastUsed, 10);
|
||||
// 二時間以上前なら
|
||||
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
|
||||
toast(i18n.t('welcomeBackWithName', {
|
||||
name: $i.name || $i.username,
|
||||
}));
|
||||
}
|
||||
}
|
||||
localStorage.setItem('lastUsed', Date.now().toString());
|
||||
|
||||
if ('Notification' in window) {
|
||||
// 許可を得ていなかったらリクエスト
|
||||
if (Notification.permission === 'default') {
|
||||
Notification.requestPermission();
|
||||
}
|
||||
}
|
||||
|
||||
const main = markRaw(stream.useChannel('main', null, 'System'));
|
||||
|
||||
// 自分の情報が更新されたとき
|
||||
main.on('meUpdated', i => {
|
||||
updateAccount(i);
|
||||
});
|
||||
|
||||
main.on('readAllNotifications', () => {
|
||||
updateAccount({ hasUnreadNotification: false });
|
||||
});
|
||||
|
||||
main.on('unreadNotification', () => {
|
||||
updateAccount({ hasUnreadNotification: true });
|
||||
});
|
||||
|
||||
main.on('unreadMention', () => {
|
||||
updateAccount({ hasUnreadMentions: true });
|
||||
});
|
||||
|
||||
main.on('readAllUnreadMentions', () => {
|
||||
updateAccount({ hasUnreadMentions: false });
|
||||
});
|
||||
|
||||
main.on('unreadSpecifiedNote', () => {
|
||||
updateAccount({ hasUnreadSpecifiedNotes: true });
|
||||
});
|
||||
|
||||
main.on('readAllUnreadSpecifiedNotes', () => {
|
||||
updateAccount({ hasUnreadSpecifiedNotes: false });
|
||||
});
|
||||
|
||||
main.on('readAllMessagingMessages', () => {
|
||||
updateAccount({ hasUnreadMessagingMessage: false });
|
||||
});
|
||||
|
||||
main.on('unreadMessagingMessage', () => {
|
||||
updateAccount({ hasUnreadMessagingMessage: true });
|
||||
sound.play('chatBg');
|
||||
});
|
||||
|
||||
main.on('readAllAntennas', () => {
|
||||
updateAccount({ hasUnreadAntenna: false });
|
||||
});
|
||||
|
||||
main.on('unreadAntenna', () => {
|
||||
updateAccount({ hasUnreadAntenna: true });
|
||||
sound.play('antenna');
|
||||
});
|
||||
|
||||
main.on('readAllAnnouncements', () => {
|
||||
updateAccount({ hasUnreadAnnouncement: false });
|
||||
});
|
||||
|
||||
main.on('readAllChannels', () => {
|
||||
updateAccount({ hasUnreadChannel: false });
|
||||
});
|
||||
|
||||
main.on('unreadChannel', () => {
|
||||
updateAccount({ hasUnreadChannel: true });
|
||||
sound.play('channel');
|
||||
});
|
||||
|
||||
// トークンが再生成されたとき
|
||||
// このままではMisskeyが利用できないので強制的にサインアウトさせる
|
||||
main.on('myTokenRegenerated', () => {
|
||||
signout();
|
||||
});
|
||||
}
|
||||
|
||||
const main = markRaw(stream.useChannel('main', null, 'System'));
|
||||
|
||||
// 自分の情報が更新されたとき
|
||||
main.on('meUpdated', i => {
|
||||
updateAccount(i);
|
||||
});
|
||||
|
||||
main.on('readAllNotifications', () => {
|
||||
updateAccount({ hasUnreadNotification: false });
|
||||
});
|
||||
|
||||
main.on('unreadNotification', () => {
|
||||
updateAccount({ hasUnreadNotification: true });
|
||||
});
|
||||
|
||||
main.on('unreadMention', () => {
|
||||
updateAccount({ hasUnreadMentions: true });
|
||||
});
|
||||
|
||||
main.on('readAllUnreadMentions', () => {
|
||||
updateAccount({ hasUnreadMentions: false });
|
||||
});
|
||||
|
||||
main.on('unreadSpecifiedNote', () => {
|
||||
updateAccount({ hasUnreadSpecifiedNotes: true });
|
||||
});
|
||||
|
||||
main.on('readAllUnreadSpecifiedNotes', () => {
|
||||
updateAccount({ hasUnreadSpecifiedNotes: false });
|
||||
});
|
||||
|
||||
main.on('readAllMessagingMessages', () => {
|
||||
updateAccount({ hasUnreadMessagingMessage: false });
|
||||
});
|
||||
|
||||
main.on('unreadMessagingMessage', () => {
|
||||
updateAccount({ hasUnreadMessagingMessage: true });
|
||||
sound.play('chatBg');
|
||||
});
|
||||
|
||||
main.on('readAllAntennas', () => {
|
||||
updateAccount({ hasUnreadAntenna: false });
|
||||
});
|
||||
|
||||
main.on('unreadAntenna', () => {
|
||||
updateAccount({ hasUnreadAntenna: true });
|
||||
sound.play('antenna');
|
||||
});
|
||||
|
||||
main.on('readAllAnnouncements', () => {
|
||||
updateAccount({ hasUnreadAnnouncement: false });
|
||||
});
|
||||
|
||||
main.on('readAllChannels', () => {
|
||||
updateAccount({ hasUnreadChannel: false });
|
||||
});
|
||||
|
||||
main.on('unreadChannel', () => {
|
||||
updateAccount({ hasUnreadChannel: true });
|
||||
sound.play('channel');
|
||||
});
|
||||
|
||||
// トークンが再生成されたとき
|
||||
// このままではMisskeyが利用できないので強制的にサインアウトさせる
|
||||
main.on('myTokenRegenerated', () => {
|
||||
signout();
|
||||
});
|
||||
}
|
||||
|
||||
// shortcut
|
||||
document.addEventListener('keydown', makeHotkey(hotkeys));
|
||||
// shortcut
|
||||
document.addEventListener('keydown', makeHotkey(hotkeys));
|
||||
})();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import { EventEmitter } from 'eventemitter3';
|
||||
import { Ref, Component, ref, shallowRef, ShallowRef } from 'vue';
|
||||
import { pleaseLogin } from '@/scripts/please-login';
|
||||
import { safeURIDecode } from '@/scripts/safe-uri-decode';
|
||||
|
||||
type RouteDef = {
|
||||
path: string;
|
||||
|
@ -116,7 +117,7 @@ export class Router extends EventEmitter<{
|
|||
}
|
||||
if (p.wildcard) {
|
||||
if (parts.length !== 0) {
|
||||
props.set(p.name, parts.join('/'));
|
||||
props.set(p.name, safeURIDecode(parts.join('/')));
|
||||
parts = [];
|
||||
}
|
||||
break pathMatchLoop;
|
||||
|
@ -124,10 +125,12 @@ export class Router extends EventEmitter<{
|
|||
if (p.startsWith) {
|
||||
if (parts[0] == null || !parts[0].startsWith(p.startsWith)) continue forEachRouteLoop;
|
||||
|
||||
props.set(p.name, parts[0].substring(p.startsWith.length));
|
||||
props.set(p.name, safeURIDecode(parts[0].substring(p.startsWith.length)));
|
||||
parts.shift();
|
||||
} else {
|
||||
props.set(p.name, parts[0]);
|
||||
if (parts[0]) {
|
||||
props.set(p.name, safeURIDecode(parts[0]));
|
||||
}
|
||||
parts.shift();
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +140,7 @@ export class Router extends EventEmitter<{
|
|||
if (parts.length !== 0) continue forEachRouteLoop;
|
||||
|
||||
if (route.hash != null && hash != null) {
|
||||
props.set(route.hash, hash);
|
||||
props.set(route.hash, safeURIDecode(hash));
|
||||
}
|
||||
|
||||
if (route.query != null && queryString != null) {
|
||||
|
@ -147,7 +150,7 @@ export class Router extends EventEmitter<{
|
|||
for (const q in route.query) {
|
||||
const as = route.query[q];
|
||||
if (queryObject[q]) {
|
||||
props.set(as, queryObject[q]);
|
||||
props.set(as, safeURIDecode(queryObject[q]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<div style="overflow: hidden; overflow: clip;">
|
||||
<div style="overflow: clip;">
|
||||
<MkSpacer :content-max="600" :margin-min="20">
|
||||
<div class="_formRoot znqjceqz">
|
||||
<div id="debug"></div>
|
||||
|
|
|
@ -138,7 +138,7 @@ definePageMetadata(computed(() => ({
|
|||
.fwhjspax {
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ let view = $ref(null);
|
|||
let el = $ref(null);
|
||||
let pageProps = $ref({});
|
||||
let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
|
||||
let noBotProtection = !instance.enableHcaptcha && !instance.enableRecaptcha;
|
||||
let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha;
|
||||
let noEmailServer = !instance.enableEmail;
|
||||
let thereIsUnresolvedAbuseReport = $ref(false);
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ async function renderChart() {
|
|||
plugins: [{
|
||||
id: 'vLine',
|
||||
beforeDraw(chart, args, options) {
|
||||
if (chart.tooltip._active && chart.tooltip._active.length) {
|
||||
if (chart.tooltip?._active?.length) {
|
||||
const activePoint = chart.tooltip._active[0];
|
||||
const ctx = chart.ctx;
|
||||
const x = activePoint.element.x;
|
||||
|
@ -561,7 +561,7 @@ definePageMetadata({
|
|||
> .body {
|
||||
background: var(--panel);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -620,7 +620,7 @@ definePageMetadata({
|
|||
> .body {
|
||||
background: var(--panel);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ definePageMetadata(computed(() => antenna ? {
|
|||
> .tl {
|
||||
background: var(--bg);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
&.min-width_800px {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<template>
|
||||
<MkSpacer :content-max="1200">
|
||||
<MkTab v-model="origin" style="margin-bottom: var(--margin);">
|
||||
<option value="local">{{ $ts.local }}</option>
|
||||
<option value="remote">{{ $ts.remote }}</option>
|
||||
</MkTab>
|
||||
<div v-if="origin === 'local'">
|
||||
<template v-if="tag == null">
|
||||
<MkFolder class="_gap" persist-key="explore-pinned-users">
|
||||
|
@ -57,16 +61,17 @@
|
|||
import { computed, watch } from 'vue';
|
||||
import XUserList from '@/components/user-list.vue';
|
||||
import MkFolder from '@/components/ui/folder.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import number from '@/filters/number';
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { instance } from '@/instance';
|
||||
|
||||
const props = defineProps<{
|
||||
origin: 'local' | 'remote';
|
||||
tag?: string;
|
||||
}>();
|
||||
|
||||
let origin = $ref('local');
|
||||
let tagsEl = $ref<InstanceType<typeof MkFolder>>();
|
||||
let tagsLocal = $ref([]);
|
||||
let tagsRemote = $ref([]);
|
||||
|
|
|
@ -5,11 +5,8 @@
|
|||
<div v-if="tab === 'featured'">
|
||||
<XFeatured/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'localUsers'">
|
||||
<XUsers origin="local"/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'remoteUsers'">
|
||||
<XUsers origin="remote"/>
|
||||
<div v-else-if="tab === 'users'">
|
||||
<XUsers/>
|
||||
</div>
|
||||
<div v-else-if="tab === 'search'">
|
||||
<MkSpacer :content-max="1200">
|
||||
|
@ -75,13 +72,9 @@ const headerTabs = $computed(() => [{
|
|||
icon: 'fas fa-bolt',
|
||||
title: i18n.ts.featured,
|
||||
}, {
|
||||
key: 'localUsers',
|
||||
key: 'users',
|
||||
icon: 'fas fa-users',
|
||||
title: i18n.ts.users,
|
||||
}, {
|
||||
key: 'remoteUsers',
|
||||
icon: 'fas fa-users',
|
||||
title: i18n.ts.remote,
|
||||
}, {
|
||||
key: 'search',
|
||||
title: i18n.ts.search,
|
||||
|
|
|
@ -188,7 +188,7 @@ definePageMetadata({
|
|||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: 10px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
|
||||
> .avatar {
|
||||
display: inline-block;
|
||||
|
|
|
@ -181,7 +181,7 @@ definePageMetadata({
|
|||
> .toggleWrapper {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
padding: 0 100px;
|
||||
|
||||
input {
|
||||
|
|
|
@ -177,7 +177,7 @@ definePageMetadata(computed(() => ({
|
|||
> .tl {
|
||||
background: var(--bg);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -103,7 +103,7 @@ definePageMetadata(computed(() => list ? {
|
|||
> .tl {
|
||||
background: var(--bg);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
&.min-width_800px {
|
||||
|
|
|
@ -90,7 +90,7 @@ export default defineComponent({
|
|||
> .img {
|
||||
height: 128px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ function showMenu(ev) {
|
|||
-webkit-backdrop-filter: var(--blur, blur(15px));
|
||||
backdrop-filter: var(--blur, blur(15px));
|
||||
border-radius: 999px;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
width: 800px;
|
||||
padding: 8px 0;
|
||||
|
||||
|
|
|
@ -8,4 +8,6 @@ export type UnicodeEmojiDef = {
|
|||
}
|
||||
|
||||
// initial converted from https://github.com/muan/emojilib/commit/242fe68be86ed6536843b83f7e32f376468b38fb
|
||||
export const emojilist = (await import('../emojilist.json')).default as UnicodeEmojiDef[];
|
||||
import _emojilist from '../emojilist.json';
|
||||
|
||||
export const emojilist = _emojilist as UnicodeEmojiDef[];
|
||||
|
|
|
@ -16,7 +16,7 @@ export type TextValue = ExprBase & {
|
|||
value: string;
|
||||
};
|
||||
|
||||
export type MultiLineTextValue = ExprBase & {
|
||||
export type MultiLineTextValue = ExprBase & {
|
||||
type: 'multiLineText';
|
||||
value: string;
|
||||
};
|
||||
|
|
|
@ -11,16 +11,15 @@ const fallbackName = (key: string) => `idbfallback::${key}`;
|
|||
let idbAvailable = typeof window !== 'undefined' ? !!window.indexedDB : true;
|
||||
|
||||
if (idbAvailable) {
|
||||
try {
|
||||
await iset('idb-test', 'test');
|
||||
} catch (err) {
|
||||
iset('idb-test', 'test').catch(err => {
|
||||
console.error('idb error', err);
|
||||
console.error('indexedDB is unavailable. It will use localStorage.');
|
||||
idbAvailable = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('indexedDB is unavailable. It will use localStorage.');
|
||||
}
|
||||
|
||||
if (!idbAvailable) console.error('indexedDB is unavailable. It will use localStorage.');
|
||||
|
||||
export async function get(key: string) {
|
||||
if (idbAvailable) return iget(key);
|
||||
return JSON.parse(localStorage.getItem(fallbackName(key)));
|
||||
|
|
7
packages/client/src/scripts/safe-uri-decode.ts
Normal file
7
packages/client/src/scripts/safe-uri-decode.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export function safeURIDecode(str: string): string {
|
||||
try {
|
||||
return decodeURIComponent(str);
|
||||
} catch {
|
||||
return str;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { ref } from 'vue';
|
||||
import { globalEvents } from '@/events';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { globalEvents } from '@/events';
|
||||
|
||||
export type Theme = {
|
||||
id: string;
|
||||
|
@ -31,11 +31,11 @@ export const getBuiltinThemes = () => Promise.all(
|
|||
'd-astro',
|
||||
'd-future',
|
||||
'd-botanical',
|
||||
'd-green-lime',
|
||||
'd-green-orange',
|
||||
'd-cherry',
|
||||
'd-ice',
|
||||
'd-pumpkin',
|
||||
'd-black',
|
||||
].map(name => import(`../themes/${name}.json5`).then(({ default: _default }): Theme => _default))
|
||||
].map(name => import(`../themes/${name}.json5`).then(({ default: _default }): Theme => _default)),
|
||||
);
|
||||
|
||||
export const getBuiltinThemesRef = () => {
|
||||
|
|
|
@ -252,7 +252,7 @@ hr {
|
|||
._panel {
|
||||
background: var(--panel);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
._block {
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
id: '8c539dc1-0fab-4d47-9194-39c508e9bfe1',
|
||||
|
||||
name: 'Mi Black',
|
||||
author: 'syuilo',
|
||||
|
||||
base: 'dark',
|
||||
|
||||
props: {
|
||||
divider: '#2d2d2d',
|
||||
panel: '#131313',
|
||||
panelHeaderBg: '@panel',
|
||||
panelHeaderDivider: '@divider',
|
||||
shadow: 'rgba(255, 255, 255, 0.05)',
|
||||
modalBg: 'rgba(255, 255, 255, 0.1)',
|
||||
},
|
||||
}
|
24
packages/client/src/themes/d-green-lime.json5
Normal file
24
packages/client/src/themes/d-green-lime.json5
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
id: '02816013-8107-440f-877e-865083ffe194',
|
||||
|
||||
name: 'Mi Green+Lime Dark',
|
||||
author: 'syuilo',
|
||||
|
||||
base: 'dark',
|
||||
|
||||
props: {
|
||||
accent: '#b4e900',
|
||||
bg: '#0C1210',
|
||||
fg: '#dee7e4',
|
||||
fgHighlighted: '#fff',
|
||||
fgOnAccent: '#192320',
|
||||
divider: '#e7fffb24',
|
||||
panel: '#192320',
|
||||
panelHeaderBg: '@panel',
|
||||
panelHeaderDivider: '@divider',
|
||||
popup: '#293330',
|
||||
renote: '@accent',
|
||||
mentionMe: '#ffaa00',
|
||||
link: '#24d7ce',
|
||||
},
|
||||
}
|
24
packages/client/src/themes/d-green-orange.json5
Normal file
24
packages/client/src/themes/d-green-orange.json5
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
id: 'dc489603-27b5-424a-9b25-1ff6aec9824a',
|
||||
|
||||
name: 'Mi Green+Orange Dark',
|
||||
author: 'syuilo',
|
||||
|
||||
base: 'dark',
|
||||
|
||||
props: {
|
||||
accent: '#e97f00',
|
||||
bg: '#0C1210',
|
||||
fg: '#dee7e4',
|
||||
fgHighlighted: '#fff',
|
||||
fgOnAccent: '#192320',
|
||||
divider: '#e7fffb24',
|
||||
panel: '#192320',
|
||||
panelHeaderBg: '@panel',
|
||||
panelHeaderDivider: '@divider',
|
||||
popup: '#293330',
|
||||
renote: '@accent',
|
||||
mentionMe: '#b4e900',
|
||||
link: '#24d7ce',
|
||||
},
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
{
|
||||
id: '0b64fef3-02c7-20b5-dd87-b3f77e2b4301',
|
||||
|
||||
name: 'Mi Pumpkin Dark',
|
||||
author: 'syuilo',
|
||||
|
||||
base: 'dark',
|
||||
|
||||
props: {
|
||||
X2: ':darken<2<@panel',
|
||||
X3: 'rgba(255, 255, 255, 0.05)',
|
||||
X4: 'rgba(255, 255, 255, 0.1)',
|
||||
X5: 'rgba(255, 255, 255, 0.05)',
|
||||
X6: 'rgba(255, 255, 255, 0.15)',
|
||||
X7: 'rgba(255, 255, 255, 0.05)',
|
||||
X8: ':lighten<5<@accent',
|
||||
X9: ':darken<5<@accent',
|
||||
bg: 'rgb(37, 32, 47)',
|
||||
fg: '#e0d5c0',
|
||||
X10: ':alpha<0.4<@accent',
|
||||
X11: 'rgba(0, 0, 0, 0.3)',
|
||||
X12: 'rgba(255, 255, 255, 0.1)',
|
||||
X13: 'rgba(255, 255, 255, 0.15)',
|
||||
X14: ':alpha<0.5<@navBg',
|
||||
X15: ':alpha<0<@panel',
|
||||
X16: ':alpha<0.7<@panel',
|
||||
X17: ':alpha<0.8<@bg',
|
||||
cwBg: '#687390',
|
||||
cwFg: '#393f4f',
|
||||
link: 'rgb(172, 193, 68)',
|
||||
warn: '#ecb637',
|
||||
badge: '#31b1ce',
|
||||
error: '#ec4137',
|
||||
focus: ':alpha<0.3<@accent',
|
||||
navBg: '@panel',
|
||||
navFg: '@fg',
|
||||
panel: ':lighten<3<@bg',
|
||||
popup: ':lighten<3<@panel',
|
||||
accent: 'rgb(242, 133, 36)',
|
||||
header: ':alpha<0.7<@panel',
|
||||
infoBg: '#253142',
|
||||
infoFg: '#fff',
|
||||
renote: 'rgb(110, 179, 72)',
|
||||
shadow: 'rgba(0, 0, 0, 0.3)',
|
||||
divider: 'rgba(255, 255, 255, 0.1)',
|
||||
hashtag: 'rgb(188, 90, 255)',
|
||||
mention: 'rgb(72, 179, 139)',
|
||||
modalBg: 'rgba(0, 0, 0, 0.5)',
|
||||
success: '#86b300',
|
||||
buttonBg: 'rgba(255, 255, 255, 0.05)',
|
||||
switchBg: 'rgba(255, 255, 255, 0.15)',
|
||||
acrylicBg: ':alpha<0.5<@bg',
|
||||
cwHoverBg: '#707b97',
|
||||
indicator: '@accent',
|
||||
mentionMe: '@accent',
|
||||
messageBg: '@bg',
|
||||
navActive: '@accent',
|
||||
accentedBg: ':alpha<0.15<@accent',
|
||||
fgOnAccent: '#000',
|
||||
infoWarnBg: '#42321c',
|
||||
infoWarnFg: '#ffbd3e',
|
||||
navHoverFg: ':lighten<17<@fg',
|
||||
dateLabelFg: '@fg',
|
||||
inputBorder: 'rgba(255, 255, 255, 0.1)',
|
||||
panelBorder: '" solid 1px var(--divider)',
|
||||
accentDarken: ':darken<10<@accent',
|
||||
acrylicPanel: ':alpha<0.5<@panel',
|
||||
navIndicator: '@indicator',
|
||||
accentLighten: ':lighten<10<@accent',
|
||||
buttonHoverBg: 'rgba(255, 255, 255, 0.1)',
|
||||
driveFolderBg: ':alpha<0.3<@accent',
|
||||
fgHighlighted: ':lighten<3<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
buttonGradateA: '@accent',
|
||||
buttonGradateB: ':hue<20<@accent',
|
||||
htmlThemeColor: '@bg',
|
||||
panelHighlight: ':lighten<3<@panel',
|
||||
listItemHoverBg: 'rgba(255, 255, 255, 0.03)',
|
||||
scrollbarHandle: 'rgba(255, 255, 255, 0.2)',
|
||||
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
|
||||
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',
|
||||
},
|
||||
}
|
|
@ -64,7 +64,7 @@ const XUserList = defineAsyncComponent(() => import('./statusbar-user-list.vue')
|
|||
width: 100%;
|
||||
line-height: var(--height);
|
||||
height: var(--height);
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
contain: strict;
|
||||
|
||||
> .name {
|
||||
|
|
|
@ -241,7 +241,7 @@ onMounted(() => {
|
|||
border-left: solid 1px var(--divider);
|
||||
border-right: solid 1px var(--divider);
|
||||
border-radius: 0;
|
||||
overflow: hidden; overflow: clip;
|
||||
overflow: clip;
|
||||
--margin: 12px;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { } from 'vue';
|
||||
import { } from 'vue';
|
||||
import XColumn from './column.vue';
|
||||
import XTimeline from '@/components/timeline.vue';
|
||||
import * as os from '@/os';
|
||||
|
|
|
@ -39,15 +39,15 @@ let pointsRenote: any = $ref(null);
|
|||
let pointsTotal: any = $ref(null);
|
||||
|
||||
function dragListen(fn) {
|
||||
window.addEventListener('mousemove', fn);
|
||||
window.addEventListener('mousemove', fn);
|
||||
window.addEventListener('mouseleave', dragClear.bind(null, fn));
|
||||
window.addEventListener('mouseup', dragClear.bind(null, fn));
|
||||
window.addEventListener('mouseup', dragClear.bind(null, fn));
|
||||
}
|
||||
|
||||
function dragClear(fn) {
|
||||
window.removeEventListener('mousemove', fn);
|
||||
window.removeEventListener('mousemove', fn);
|
||||
window.removeEventListener('mouseleave', dragClear);
|
||||
window.removeEventListener('mouseup', dragClear);
|
||||
window.removeEventListener('mouseup', dragClear);
|
||||
}
|
||||
|
||||
function onMousedown(ev) {
|
||||
|
|
|
@ -49,6 +49,7 @@ export default defineConfig(({ command, mode }) => {
|
|||
'chrome100',
|
||||
'firefox100',
|
||||
'safari15',
|
||||
'es2017', // TODO: そのうち消す
|
||||
],
|
||||
manifest: 'manifest.json',
|
||||
rollupOptions: {
|
||||
|
|
|
@ -515,14 +515,14 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.0.tgz#524a11e15c09701733033c96943ecf33f55d9ca1"
|
||||
integrity sha512-lvhRJ2pGe2V9MEU46ELTdiHgiAFZPKtLhiU5wlnaYpMc2+c1R8fh8i80ZAa665drvjHKUJyRRGg3gEm1If54ow==
|
||||
"@typescript-eslint/eslint-plugin@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.6.tgz#9c6017b6c1d04894141b4a87816388967f64c359"
|
||||
integrity sha512-J4zYMIhgrx4MgnZrSDD7sEnQp7FmhKNOaqaOpaoQ/SfdMfRB/0yvK74hTnvH+VQxndZynqs5/Hn4t+2/j9bADg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/type-utils" "5.30.0"
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/type-utils" "5.30.6"
|
||||
"@typescript-eslint/utils" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.2.0"
|
||||
|
@ -530,69 +530,69 @@
|
|||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/parser@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.0.tgz#a2184fb5f8ef2bf1db0ae61a43907e2e32aa1b8f"
|
||||
integrity sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==
|
||||
"@typescript-eslint/parser@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.6.tgz#add440db038fa9d777e4ebdaf66da9e7fb7abe92"
|
||||
integrity sha512-gfF9lZjT0p2ZSdxO70Xbw8w9sPPJGfAdjK7WikEjB3fcUI/yr9maUVEdqigBjKincUYNKOmf7QBMiTf719kbrA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/typescript-estree" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz#bf585ee801ab4ad84db2f840174e171a6bb002c7"
|
||||
integrity sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==
|
||||
"@typescript-eslint/scope-manager@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.6.tgz#ce1b49ff5ce47f55518d63dbe8fc9181ddbd1a33"
|
||||
integrity sha512-Hkq5PhLgtVoW1obkqYH0i4iELctEKixkhWLPTYs55doGUKCASvkjOXOd/pisVeLdO24ZX9D6yymJ/twqpJiG3g==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
|
||||
"@typescript-eslint/type-utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.0.tgz#98f3af926a5099153f092d4dad87148df21fbaae"
|
||||
integrity sha512-GF8JZbZqSS+azehzlv/lmQQ3EU3VfWYzCczdZjJRxSEeXDQkqFhCBgFhallLDbPwQOEQ4MHpiPfkjKk7zlmeNg==
|
||||
"@typescript-eslint/type-utils@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.6.tgz#a64aa9acbe609ab77f09f53434a6af2b9685f3af"
|
||||
integrity sha512-GFVVzs2j0QPpM+NTDMXtNmJKlF842lkZKDSanIxf+ArJsGeZUIaeT4jGg+gAgHt7AcQSFwW7htzF/rbAh2jaVA==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
"@typescript-eslint/utils" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/types@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.0.tgz#db7d81d585a3da3801432a9c1d2fafbff125e110"
|
||||
integrity sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==
|
||||
"@typescript-eslint/types@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.6.tgz#86369d0a7af8c67024115ac1da3e8fb2d38907e1"
|
||||
integrity sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz#4565ee8a6d2ac368996e20b2344ea0eab1a8f0bb"
|
||||
integrity sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==
|
||||
"@typescript-eslint/typescript-estree@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.6.tgz#a84a0d6a486f9b54042da1de3d671a2c9f14484e"
|
||||
integrity sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.0.tgz#1dac771fead5eab40d31860716de219356f5f754"
|
||||
integrity sha512-0bIgOgZflLKIcZsWvfklsaQTM3ZUbmtH0rJ1hKyV3raoUYyeZwcjQ8ZUJTzS7KnhNcsVT1Rxs7zeeMHEhGlltw==
|
||||
"@typescript-eslint/utils@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.6.tgz#1de2da14f678e7d187daa6f2e4cdb558ed0609dc"
|
||||
integrity sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/typescript-estree" "5.30.6"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz#07721d23daca2ec4c2da7f1e660d41cd78bacac3"
|
||||
integrity sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==
|
||||
"@typescript-eslint/visitor-keys@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.6.tgz#94dd10bb481c8083378d24de1742a14b38a2678c"
|
||||
integrity sha512-41OiCjdL2mCaSDi2SvYbzFLlqqlm5v1ZW9Ym55wXKL/Rx6OOB1IbuFGo71Fj6Xy90gJDFTlgOS+vbmtGHPTQQA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
|
@ -600,10 +600,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
|
||||
|
||||
"@vitejs/plugin-vue@3.0.0-beta.1":
|
||||
version "3.0.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-3.0.0-beta.1.tgz#65a6be6ed619955a5edea6115dedcfc5da4ed3f6"
|
||||
integrity sha512-cPVQHIKZkVEQ8qW7+BlbTrGJXNpP2aMKzVhQdTnWK9u6cSDmVdZOXHmKPO2KVvrNpFXXS8R7hHBXMsSApA+XOA==
|
||||
"@vitejs/plugin-vue@3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-3.0.0.tgz#7081e2b3fbe04e291bb85107b9fb57a1fa5e6aeb"
|
||||
integrity sha512-yWP34ArFh/jAeNUDkkLz/kVRLjf5ppJiq4L36f64Cp6dIrMQeYZGDP9xxdemlXfZR9ylN9JgHUl3GzfqOtgYDg==
|
||||
|
||||
"@vue/compiler-core@3.2.37":
|
||||
version "3.2.37"
|
||||
|
@ -1715,10 +1715,10 @@ eslint-plugin-import@2.26.0:
|
|||
resolve "^1.22.0"
|
||||
tsconfig-paths "^3.14.1"
|
||||
|
||||
eslint-plugin-vue@9.1.1:
|
||||
version "9.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.1.1.tgz#341f7533cb041958455138834341d5be01f9f327"
|
||||
integrity sha512-W9n5PB1X2jzC7CK6riG0oAcxjmKrjTF6+keL1rni8n57DZeilx/Fulz+IRJK3lYseLNAygN0I62L7DvioW40Tw==
|
||||
eslint-plugin-vue@9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.2.0.tgz#b7ca02b2ce8218b7586346440fc61c2655db353a"
|
||||
integrity sha512-W2hc+NUXoce8sZtWgZ45miQTy6jNyuSdub5aZ1IBune4JDeAyzucYX0TzkrQ1jMO52sNUDYlCIHDoaNePe0p5g==
|
||||
dependencies:
|
||||
eslint-utils "^3.0.0"
|
||||
natural-compare "^1.4.0"
|
||||
|
@ -1761,10 +1761,10 @@ eslint-visitor-keys@^3.3.0:
|
|||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@8.18.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.18.0.tgz#78d565d16c993d0b73968c523c0446b13da784fd"
|
||||
integrity sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==
|
||||
eslint@8.19.0:
|
||||
version "8.19.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.19.0.tgz#7342a3cbc4fbc5c106a1eefe0fd0b50b6b1a7d28"
|
||||
integrity sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.3.0"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
|
@ -2866,12 +2866,12 @@ merge2@^1.3.0, merge2@^1.4.1:
|
|||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
mfm-js@0.22.1:
|
||||
version "0.22.1"
|
||||
resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.22.1.tgz#ad5f0b95cc903ca5a5e414e2edf64ac4648dc8c2"
|
||||
integrity sha512-UV5zvDKlWPpBFeABhyCzuOTJ3RwrNrmVpJ+zz/dFX6D/ntEywljgxkfsLamcy0ZSwUAr0O+WQxGHvAwyxUgsAQ==
|
||||
mfm-js@0.23.0-canary.1:
|
||||
version "0.23.0-canary.1"
|
||||
resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.23.0-canary.1.tgz#1b7b7635f18bed9776054406b72e6bd613c8d0eb"
|
||||
integrity sha512-SkMrW1rQAv+mFGtLKN9DSv6vxSREDu8ChmkBl1Ch5sQfp47BhuvcRg5EKGmt3WAQRAOylXYMg8wVYR7C5BHKeA==
|
||||
dependencies:
|
||||
twemoji-parser "14.0.x"
|
||||
twemoji-parser "14.0.0"
|
||||
|
||||
micromatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
|
@ -3649,7 +3649,14 @@ rndstr@1.0.0:
|
|||
rangestr "0.0.1"
|
||||
seedrandom "2.4.2"
|
||||
|
||||
rollup@2.75.7, rollup@^2.75.6:
|
||||
rollup@2.76.0:
|
||||
version "2.76.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.76.0.tgz#c69fe03db530ac53fcb9523b3caa0d3c0b9491a1"
|
||||
integrity sha512-9jwRIEY1jOzKLj3nsY/yot41r19ITdQrhs+q3ggNWhr9TQgduHqANvPpS32RNpzGklJu3G1AJfvlZLi/6wFgWA==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^2.75.6:
|
||||
version "2.75.7"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.75.7.tgz#221ff11887ae271e37dcc649ba32ce1590aaa0b9"
|
||||
integrity sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==
|
||||
|
@ -4085,7 +4092,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
twemoji-parser@14.0.0, twemoji-parser@14.0.x:
|
||||
twemoji-parser@14.0.0:
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-14.0.0.tgz#13dabcb6d3a261d9efbf58a1666b182033bf2b62"
|
||||
integrity sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==
|
||||
|
@ -4215,10 +4222,10 @@ verror@1.10.0:
|
|||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vite@3.0.0-beta.7:
|
||||
version "3.0.0-beta.7"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.0-beta.7.tgz#ded6483ef3b9b16dbe3a912a35accb9cc3498530"
|
||||
integrity sha512-yjw154hB229qq5Bl6+/CJSTxC/yIDmDJbaAjE/pdracz3jytNEd2ovk5BvxgZT6+qPiUc2rRH3FgGqiZnweIFw==
|
||||
vite@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.0.tgz#b4675cb9ab83ec0803b9c952ffa6519bcce033a7"
|
||||
integrity sha512-M7phQhY3+fRZa0H+1WzI6N+/onruwPTBTMvaj7TzgZ0v2TE+N2sdLKxJOfOv9CckDWt5C4HmyQP81xB4dwRKzA==
|
||||
dependencies:
|
||||
esbuild "^0.14.47"
|
||||
postcss "^8.4.14"
|
||||
|
|
|
@ -53,7 +53,6 @@ module.exports = {
|
|||
'no-empty-pattern': ['warn'],
|
||||
'no-async-promise-executor': ['off'],
|
||||
'no-useless-escape': ['off'],
|
||||
'no-multi-spaces': ['warn'],
|
||||
'no-multiple-empty-lines': ['error', { 'max': 1 }],
|
||||
'no-control-regex': ['warn'],
|
||||
'no-empty': ['warn'],
|
||||
|
|
|
@ -42,8 +42,12 @@ self.addEventListener('push', ev => {
|
|||
// case 'driveFileCreated':
|
||||
case 'notification':
|
||||
case 'unreadMessagingMessage':
|
||||
// 1日以上経過している場合は無視
|
||||
if ((new Date()).getTime() - data.dateTime > 1000 * 60 * 60 * 24) break;
|
||||
|
||||
// クライアントがあったらストリームに接続しているということなので通知しない
|
||||
if (clients.length != 0) return;
|
||||
if (clients.length !== 0) break;
|
||||
|
||||
return createNotification(data);
|
||||
case 'readAllNotifications':
|
||||
for (const n of await self.registration.getNotifications()) {
|
||||
|
|
|
@ -24,6 +24,7 @@ export type pushNotificationData<K extends keyof pushNotificationDataSourceMap>
|
|||
type: K;
|
||||
body: pushNotificationDataSourceMap[K];
|
||||
userId: string;
|
||||
dateTime: number;
|
||||
};
|
||||
|
||||
export type pushNotificationDataMap = {
|
||||
|
|
56
yarn.lock
56
yarn.lock
|
@ -194,48 +194,48 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/parser@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.0.tgz#a2184fb5f8ef2bf1db0ae61a43907e2e32aa1b8f"
|
||||
integrity sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==
|
||||
"@typescript-eslint/parser@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.6.tgz#add440db038fa9d777e4ebdaf66da9e7fb7abe92"
|
||||
integrity sha512-gfF9lZjT0p2ZSdxO70Xbw8w9sPPJGfAdjK7WikEjB3fcUI/yr9maUVEdqigBjKincUYNKOmf7QBMiTf719kbrA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.6"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/typescript-estree" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz#bf585ee801ab4ad84db2f840174e171a6bb002c7"
|
||||
integrity sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==
|
||||
"@typescript-eslint/scope-manager@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.6.tgz#ce1b49ff5ce47f55518d63dbe8fc9181ddbd1a33"
|
||||
integrity sha512-Hkq5PhLgtVoW1obkqYH0i4iELctEKixkhWLPTYs55doGUKCASvkjOXOd/pisVeLdO24ZX9D6yymJ/twqpJiG3g==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
|
||||
"@typescript-eslint/types@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.0.tgz#db7d81d585a3da3801432a9c1d2fafbff125e110"
|
||||
integrity sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==
|
||||
"@typescript-eslint/types@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.6.tgz#86369d0a7af8c67024115ac1da3e8fb2d38907e1"
|
||||
integrity sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz#4565ee8a6d2ac368996e20b2344ea0eab1a8f0bb"
|
||||
integrity sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==
|
||||
"@typescript-eslint/typescript-estree@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.6.tgz#a84a0d6a486f9b54042da1de3d671a2c9f14484e"
|
||||
integrity sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
"@typescript-eslint/visitor-keys" "5.30.6"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz#07721d23daca2ec4c2da7f1e660d41cd78bacac3"
|
||||
integrity sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==
|
||||
"@typescript-eslint/visitor-keys@5.30.6":
|
||||
version "5.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.6.tgz#94dd10bb481c8083378d24de1742a14b38a2678c"
|
||||
integrity sha512-41OiCjdL2mCaSDi2SvYbzFLlqqlm5v1ZW9Ym55wXKL/Rx6OOB1IbuFGo71Fj6Xy90gJDFTlgOS+vbmtGHPTQQA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.6"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
aggregate-error@^3.0.0:
|
||||
|
|
Loading…
Reference in a new issue