Compare commits
14 Commits
58cb7cf179
...
0aaeb6d136
Author | SHA1 | Date |
---|---|---|
|
0aaeb6d136 | |
|
fb277501a0 | |
|
718138509f | |
|
a1ef38a606 | |
|
4a8b7ef23e | |
|
1f17161dfb | |
|
2488708934 | |
|
628a0c71a9 | |
|
b40f5b9021 | |
|
0f79db6a4d | |
|
910e097480 | |
|
a8acbd6e68 | |
|
c19f51a2ab | |
|
1cf370882e |
|
@ -18,8 +18,8 @@ jobs:
|
|||
# Neither Dependabot nor Renovate will change the actual behavior for components.
|
||||
if: >-
|
||||
github.repository == 'misskey-dev/misskey' &&
|
||||
startsWith(github.ref, 'refs/heads/dependabot/') != true &&
|
||||
startsWith(github.ref, 'refs/heads/renovate/') != true
|
||||
startsWith(github.head_ref, 'refs/heads/dependabot/') != true &&
|
||||
startsWith(github.head_ref, 'refs/heads/renovate/') != true
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
|
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
|||
## Unreleased
|
||||
|
||||
### General
|
||||
-
|
||||
|
||||
### Client
|
||||
-
|
||||
|
||||
### Server
|
||||
-
|
||||
|
||||
|
||||
## 2025.4.0
|
||||
|
||||
### General
|
||||
|
@ -61,11 +73,13 @@
|
|||
- Enhance: 2段階認証時のリカバリーコードのファイル名にサーバーURLを含めるように
|
||||
- Enhance: 全体的なブラッシュアップ
|
||||
- Enhance 全体的なパフォーマンス向上
|
||||
- Enhance: ファイルのアップロードでデフォルトで圧縮するかどうかのオプションが廃止され、アップロード時に圧縮するかどうかを選択するようになりました
|
||||
- 画像データの貼り付け、ドロップ時は圧縮されるようになりました
|
||||
- Fix: 読み込み直後にスクロールしようとすると途中で止まる場合があるのを修正
|
||||
- Fix: テーマ切り替え時に一部の色が変わらない問題を修正
|
||||
- Fix: iPadOSでdeck uiをマウスカーソルによってスクロールできない問題を修正
|
||||
- NOTE: 構造上クラシックUIを新しいデザインシステムに移行することが困難なため、クラシックUIが削除されました
|
||||
- デッキUIでカラムを中央寄せにし、メインカラムの左右にウィジェットカラムを配置し、ナビゲーションバーを上部に表示することである程度クラシックUIを再現できます
|
||||
- Fix: iPadOSでdeck uiをマウスカーソルによってスクロールできない問題を修正
|
||||
|
||||
### Server
|
||||
- Enhance 全体的なパフォーマンス向上
|
||||
|
|
|
@ -424,7 +424,7 @@ antennaExcludeBots: "Exclou els bots"
|
|||
antennaKeywordsDescription: "Separar amb espais per la condició AND o amb salts de línia per la condició OR."
|
||||
notifyAntenna: "Notifica'm les publicacions noves"
|
||||
withFileAntenna: "Només les publicacions amb fitxers"
|
||||
hideNotesInSensitiveChannel: "Amaga les notes a canals sensibles "
|
||||
excludeNotesInSensitiveChannel: "Excloure notes a canals sensibles"
|
||||
enableServiceworker: "Activar les notificacions al navegador"
|
||||
antennaUsersDescription: "Llistar un nom d'usuari per línia"
|
||||
caseSensitive: "Sensible a majúscules i minúscules "
|
||||
|
|
|
@ -424,7 +424,7 @@ antennaExcludeBots: "Bot-Accounts ausschließen"
|
|||
antennaKeywordsDescription: "Zum Nutzen einer \"UND\"-Verknüpfung Einträge mit Leerzeichen trennen, zum Nutzen einer \"ODER\"-Verknüpfung Einträge mit einem Zeilenumbruch trennen"
|
||||
notifyAntenna: "Über neue Notizen benachrichtigen"
|
||||
withFileAntenna: "Nur Notizen mit Dateien"
|
||||
hideNotesInSensitiveChannel: "Verstecke Notizen von sensitive Kanäle"
|
||||
excludeNotesInSensitiveChannel: "Schließe Notizen von sensitive Kanäle aus"
|
||||
enableServiceworker: "Push-Benachrichtigungen im Browser aktivieren"
|
||||
antennaUsersDescription: "Benutzernamen getrennt durch Zeilenumbrüche angeben"
|
||||
caseSensitive: "Groß-/Kleinschreibung unterscheiden"
|
||||
|
@ -1343,6 +1343,7 @@ top: "Oben"
|
|||
embed: "Einbetten"
|
||||
settingsMigrating: "Ihre Einstellungen werden gerade migriert, Bitte warten Sie einen Moment... (Sie können die Einstellungen später auch manuell migrieren, indem Sie zu Einstellungen → Sonstiges → Alte Einstellungen migrieren gehen)"
|
||||
readonly: "Nur Lesezugriff"
|
||||
goToDeck: "Zurück zum Deck"
|
||||
_chat:
|
||||
noMessagesYet: "Noch keine Nachrichten"
|
||||
newMessage: "Neue Nachricht"
|
||||
|
|
|
@ -424,7 +424,7 @@ antennaExcludeBots: "Exclude bot accounts"
|
|||
antennaKeywordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition."
|
||||
notifyAntenna: "Notify about new notes"
|
||||
withFileAntenna: "Only notes with files"
|
||||
hideNotesInSensitiveChannel: "Hide notes from sensitive channels"
|
||||
excludeNotesInSensitiveChannel: "Exclude notes from sensitive channels"
|
||||
enableServiceworker: "Enable Push-Notifications for your Browser"
|
||||
antennaUsersDescription: "List one username per line"
|
||||
caseSensitive: "Case sensitive"
|
||||
|
@ -1343,6 +1343,7 @@ top: "Top"
|
|||
embed: "Embed"
|
||||
settingsMigrating: "Settings are being migrated, please wait a moment... (You can also migrate manually later by going to Settings→Others→Migrate old settings)"
|
||||
readonly: "Read only"
|
||||
goToDeck: "Return to Deck"
|
||||
_chat:
|
||||
noMessagesYet: "No messages yet"
|
||||
newMessage: "New message"
|
||||
|
|
|
@ -1715,7 +1715,7 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"withFileAntenna": string;
|
||||
/**
|
||||
* センシティブなチャンネルのノートを非表示
|
||||
* センシティブなチャンネルのノートを除外
|
||||
*/
|
||||
"excludeNotesInSensitiveChannel": string;
|
||||
/**
|
||||
|
|
|
@ -424,7 +424,6 @@ antennaExcludeBots: "Escludere i Bot"
|
|||
antennaKeywordsDescription: "Sparando con uno spazio indichi la condizione E (and). Separando con un a capo, indichi la condizione O (or)."
|
||||
notifyAntenna: "Invia notifiche delle nuove note"
|
||||
withFileAntenna: "Solo note con file in allegato"
|
||||
hideNotesInSensitiveChannel: "Nascondere le Note dai canali espliciti"
|
||||
enableServiceworker: "Abilita ServiceWorker"
|
||||
antennaUsersDescription: "Elenca un nome utente per riga"
|
||||
caseSensitive: "Sensibile alla distinzione tra maiuscole e minuscole"
|
||||
|
|
|
@ -418,13 +418,13 @@ antennas: "안테나"
|
|||
manageAntennas: "안테나 관리"
|
||||
name: "이름"
|
||||
antennaSource: "받을 소스"
|
||||
antennaKeywords: "받을 검색어"
|
||||
antennaExcludeKeywords: "제외할 검색어"
|
||||
antennaKeywords: "받을 키워드"
|
||||
antennaExcludeKeywords: "제외할 키워드"
|
||||
antennaExcludeBots: "봇 계정 제외"
|
||||
antennaKeywordsDescription: "공백으로 구분하는 경우 AND, 줄바꿈으로 구분하는 경우 OR로 지정됩니다"
|
||||
notifyAntenna: "새로운 노트를 알림"
|
||||
withFileAntenna: "파일이 첨부된 노트만"
|
||||
hideNotesInSensitiveChannel: "민감한 채널의 노트 숨기기"
|
||||
excludeNotesInSensitiveChannel: "민감한 채널의 노트 제외"
|
||||
enableServiceworker: "ServiceWorker 사용"
|
||||
antennaUsersDescription: "유저명을 한 줄에 한 명씩 적습니다"
|
||||
caseSensitive: "대소문자를 구분"
|
||||
|
@ -520,7 +520,7 @@ style: "스타일"
|
|||
drawer: "서랍"
|
||||
popup: "팝업"
|
||||
showNoteActionsOnlyHover: "마우스가 올라간 때에만 노트 동작 버튼을 표시하기"
|
||||
showReactionsCount: "노트의 반응 수를 표시하기"
|
||||
showReactionsCount: "노트의 리액션 수를 표시하기"
|
||||
noHistory: "기록이 없습니다"
|
||||
signinHistory: "로그인 기록"
|
||||
enableAdvancedMfm: "고급 MFM을 활성화"
|
||||
|
@ -754,8 +754,8 @@ repliedCount: "받은 답글 수"
|
|||
renotedCount: "받은 리노트 수"
|
||||
followingCount: "팔로우 수"
|
||||
followersCount: "팔로워 수"
|
||||
sentReactionsCount: "반응 수"
|
||||
receivedReactionsCount: "받은 반응 수"
|
||||
sentReactionsCount: "리액션 수"
|
||||
receivedReactionsCount: "받은 리액션 수"
|
||||
pollVotesCount: "투표 수"
|
||||
pollVotedCount: "받은 투표 수"
|
||||
yes: "예"
|
||||
|
@ -868,8 +868,8 @@ configure: "설정하기"
|
|||
postToGallery: "갤러리에 업로드"
|
||||
postToHashtag: "이 해시태그에 게시"
|
||||
gallery: "갤러리"
|
||||
recentPosts: "최근 포스트"
|
||||
popularPosts: "인기 포스트"
|
||||
recentPosts: "최근 게시물"
|
||||
popularPosts: "인기 게시물"
|
||||
shareWithNote: "노트로 공유"
|
||||
ads: "광고"
|
||||
expiration: "기한"
|
||||
|
@ -1056,7 +1056,7 @@ thisPostMayBeAnnoyingHome: "홈에 게시"
|
|||
thisPostMayBeAnnoyingCancel: "그만두기"
|
||||
thisPostMayBeAnnoyingIgnore: "이대로 게시"
|
||||
collapseRenotes: "이미 본 리노트를 간략화하기"
|
||||
collapseRenotesDescription: "반응이나 리노트를 한 노트를 접어서 표시합니다."
|
||||
collapseRenotesDescription: "리액션이나 리노트를 한 노트를 접어서 표시합니다."
|
||||
internalServerError: "내부 서버 오류"
|
||||
internalServerErrorDescription: "내부 서버에서 예기치 않은 오류가 발생했습니다."
|
||||
copyErrorInfo: "오류 정보 복사"
|
||||
|
@ -1080,8 +1080,8 @@ resetPasswordConfirm: "비밀번호를 재설정하시겠습니까?"
|
|||
sensitiveWords: "민감한 단어"
|
||||
sensitiveWordsDescription: "설정한 단어가 포함된 노트의 공개 범위를 '홈'으로 강제합니다. 개행으로 구분하여 여러 개를 지정할 수 있습니다."
|
||||
sensitiveWordsDescription2: "공백으로 구분하면 AND 지정이 되며, 키워드를 슬래시로 둘러싸면 정규 표현식이 됩니다."
|
||||
prohibitedWords: "금지 워드"
|
||||
prohibitedWordsDescription: "설정된 워드가 포함되는 노트를 작성하려고 하면, 에러가 발생하도록 합니다. 줄바꿈으로 구분지어 복수 설정할 수 있습니다."
|
||||
prohibitedWords: "금지 단어"
|
||||
prohibitedWordsDescription: "설정된 단어가 포함되는 노트를 작성하려고 하면, 오류가 발생하도록 합니다. 줄바꿈으로 구분지어 복수 설정할 수 있습니다."
|
||||
prohibitedWordsDescription2: "공백으로 구분하면 AND 지정이 되며, 키워드를 슬래시로 둘러싸면 정규 표현식이 됩니다."
|
||||
hiddenTags: "숨긴 해시태그"
|
||||
hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다."
|
||||
|
@ -1616,53 +1616,53 @@ _achievements:
|
|||
_types:
|
||||
_notes1:
|
||||
title: "미스키 계정 만들었어요"
|
||||
description: "첫 노트를 작성했습니다"
|
||||
description: "첫 노트를 게시했다"
|
||||
flavor: "Misskey에 어서 오세요!"
|
||||
_notes10:
|
||||
title: "몇 가지 노트"
|
||||
description: "10개의 노트를 작성했습니다"
|
||||
description: "10개의 노트를 게시했다"
|
||||
_notes100:
|
||||
title: "많은 노트"
|
||||
description: "100개의 노트를 작성했습니다"
|
||||
description: "100개의 노트를 게시했다"
|
||||
_notes500:
|
||||
title: "노트 범벅"
|
||||
description: "500개의 노트를 작성했습니다"
|
||||
description: "500개의 노트를 게시했다"
|
||||
_notes1000:
|
||||
title: "노트가 산더미"
|
||||
description: "1,000개의 노트를 작성했습니다"
|
||||
description: "1,000개의 노트를 게시했다"
|
||||
_notes5000:
|
||||
title: "솟아나는 노트"
|
||||
description: "5,000개의 노트를 작성했습니다"
|
||||
description: "5,000개의 노트를 게시했다"
|
||||
_notes10000:
|
||||
title: "슈퍼 노트"
|
||||
description: "10,000개의 노트를 작성했습니다"
|
||||
description: "10,000개의 노트를 게시했다"
|
||||
_notes20000:
|
||||
title: "노트가 필요해요"
|
||||
description: "20,000개의 노트를 작성했습니다"
|
||||
title: "노트가 더 필요해요"
|
||||
description: "20,000개의 노트를 게시했다"
|
||||
_notes30000:
|
||||
title: "노트노트노트"
|
||||
description: "30,000개의 노트를 작성했습니다"
|
||||
description: "30,000개의 노트를 게시했다"
|
||||
_notes40000:
|
||||
title: "노트 공장"
|
||||
description: "40,000개의 노트를 작성했습니다"
|
||||
description: "40,000개의 노트를 게시했다"
|
||||
_notes50000:
|
||||
title: "노트 행성"
|
||||
description: "50,000개의 노트를 작성했습니다"
|
||||
description: "50,000개의 노트를 게시했다"
|
||||
_notes60000:
|
||||
title: "노트 퀘이사"
|
||||
description: "60,000개의 노트를 작성했습니다"
|
||||
description: "60,000개의 노트를 게시했다"
|
||||
_notes70000:
|
||||
title: "노트 블랙홀"
|
||||
description: "70,000개의 노트를 작성했습니다"
|
||||
description: "70,000개의 노트를 게시했다"
|
||||
_notes80000:
|
||||
title: "노트 은하"
|
||||
description: "80,000개의 노트를 작성했습니다"
|
||||
description: "80,000개의 노트를 게시했다"
|
||||
_notes90000:
|
||||
title: "노트 우주"
|
||||
description: "90,000개의 노트를 작성했습니다"
|
||||
description: "90,000개의 노트를 게시했다"
|
||||
_notes100000:
|
||||
title: "ALL YOUR NOTE ARE BELONG TO US"
|
||||
description: "100,000개의 노트를 작성했습니다"
|
||||
description: "100,000개의 노트를 게시했다"
|
||||
flavor: "이렇게나 쓸 게 있어요?"
|
||||
_login3:
|
||||
title: "초보자 I"
|
||||
|
@ -1687,175 +1687,175 @@ _achievements:
|
|||
flavor: "그 유저, 미스키스트이다"
|
||||
_login200:
|
||||
title: "단골 I"
|
||||
description: "총 200일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 200일"
|
||||
_login300:
|
||||
title: "단골 II"
|
||||
description: "총 300일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 300일"
|
||||
_login400:
|
||||
title: "단골 III"
|
||||
description: "총 400일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 400일"
|
||||
_login500:
|
||||
title: "베테랑 I"
|
||||
description: "총 500일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 500일"
|
||||
flavor: "제군, 나는 노트가 좋다"
|
||||
_login600:
|
||||
title: "베테랑 II"
|
||||
description: "총 600일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 600일"
|
||||
_login700:
|
||||
title: "베테랑 III"
|
||||
description: "총 700일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 700일"
|
||||
_login800:
|
||||
title: "노트 마스터 I"
|
||||
description: "총 800일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 800일"
|
||||
_login900:
|
||||
title: "노트 마스터 II"
|
||||
description: "총 900일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 900일"
|
||||
_login1000:
|
||||
title: "노트 마스터 III"
|
||||
description: "총 1,000일간 로그인했습니다"
|
||||
description: "총 로그인한 날이 1,000일"
|
||||
flavor: "Misskey를 사용해 주셔서 감사합니다!"
|
||||
_noteClipped1:
|
||||
title: "클립할 수밖에 없었어"
|
||||
description: "처음으로 노트를 클립했습니다"
|
||||
description: "처음으로 노트를 클립했다"
|
||||
_noteFavorited1:
|
||||
title: "별을 바라보는 자"
|
||||
description: "처음으로 노트를 즐겨찾기했습니다"
|
||||
description: "처음으로 노트를 즐겨찾기했다"
|
||||
_myNoteFavorited1:
|
||||
title: "별을 원하는 자"
|
||||
description: "다른 사람이 당신의 노트를 즐겨찾기했습니다"
|
||||
description: "다른 사람이 당신의 노트를 즐겨찾기했다"
|
||||
_profileFilled:
|
||||
title: "준비 완료"
|
||||
description: "프로필 설정을 완료했습니다"
|
||||
description: "프로필 설정을 완료했다"
|
||||
_markedAsCat:
|
||||
title: "나는 고양이다냥!"
|
||||
description: "계정을 고양이로 설정했습니다냥"
|
||||
description: "계정을 고양이로 설정했다냥"
|
||||
flavor: "냐냐냐냐냐냐아아아아앙!"
|
||||
_following1:
|
||||
title: "첫 팔로우"
|
||||
description: "유저를 처음으로 팔로우했습니다"
|
||||
description: "유저를 처음으로 팔로우했다"
|
||||
_following10:
|
||||
title: "팔로우, 팔로우"
|
||||
description: "10명의 유저를 팔로우했습니다"
|
||||
description: "10명의 유저를 팔로우했다"
|
||||
_following50:
|
||||
title: "친구 잔뜩"
|
||||
description: "50명의 유저를 팔로우했습니다"
|
||||
description: "50명의 유저를 팔로우했다"
|
||||
_following100:
|
||||
title: "주소록 한 권으론 부족해"
|
||||
description: "100명의 유저를 팔로우했습니다"
|
||||
description: "100명의 유저를 팔로우했다"
|
||||
_following300:
|
||||
title: "친구가 넘쳐나"
|
||||
description: "300명의 유저를 팔로우했습니다"
|
||||
description: "300명의 유저를 팔로우했다"
|
||||
_followers1:
|
||||
title: "첫 팔로워"
|
||||
description: "유저가 처음으로 팔로잉했습니다"
|
||||
description: "유저가 처음으로 팔로잉했다"
|
||||
_followers10:
|
||||
title: "팔로우 미!"
|
||||
description: "10명의 유저가 팔로우했습니다"
|
||||
description: "10명의 유저가 팔로우했다"
|
||||
_followers50:
|
||||
title: "이곳저곳"
|
||||
description: "50명의 유저가 팔로우했습니다"
|
||||
description: "50명의 유저가 팔로우했다"
|
||||
_followers100:
|
||||
title: "인기왕"
|
||||
description: "100명의 유저가 팔로우했습니다"
|
||||
description: "100명의 유저가 팔로우했다"
|
||||
_followers300:
|
||||
title: "줄 좀 서봐요"
|
||||
description: "100명의 유저가 팔로우했습니다"
|
||||
description: "100명의 유저가 팔로우했다"
|
||||
_followers500:
|
||||
title: "기지국"
|
||||
description: "500명의 유저가 팔로우했습니다"
|
||||
description: "500명의 유저가 팔로우했다"
|
||||
_followers1000:
|
||||
title: "유명인사"
|
||||
description: "1,000명의 유저가 팔로우했습니다"
|
||||
description: "1,000명의 유저가 팔로우했다"
|
||||
_collectAchievements30:
|
||||
title: "도전 과제 콜렉터"
|
||||
description: "30개의 도전과제를 획득했습니다"
|
||||
description: "30개의 도전과제를 획득했다"
|
||||
_viewAchievements3min:
|
||||
title: "저 도전과제 좋아해요"
|
||||
description: "도전 과제 목록을 3분 이상 쳐다봤습니다"
|
||||
description: "도전 과제 목록을 3분 이상 쳐다봤다"
|
||||
_iLoveMisskey:
|
||||
title: "I Love Misskey"
|
||||
description: "\"I ❤ #Misskey\"를 포스트했습니다"
|
||||
description: "\"I ❤ #Misskey\"를 게시했다"
|
||||
flavor: "Misskey를 이용해 주셔서 감사합니다! ― 개발 팀"
|
||||
_foundTreasure:
|
||||
title: "보물찾기"
|
||||
description: "숨겨진 보물을 발견했습니다"
|
||||
description: "숨겨진 보물을 발견했다"
|
||||
_client30min:
|
||||
title: "잠시 쉬어요"
|
||||
description: "클라이언트를 시작하고 30분이 경과하였습니다"
|
||||
description: "클라이언트를 시작하고 30분이 경과했다"
|
||||
_client60min:
|
||||
title: "No \"Miss\" in Misskey"
|
||||
description: "클라이언트를 시작하고 60분이 경과하였습니다"
|
||||
description: "클라이언트를 시작하고 60분이 경과했다"
|
||||
_noteDeletedWithin1min:
|
||||
title: "있었는데요 없었습니다"
|
||||
description: "노트를 포스트한 후 1분 이내에 삭제했습니다"
|
||||
description: "노트를 게시한 후 1분 이내에 삭제했다"
|
||||
_postedAtLateNight:
|
||||
title: "올빼미"
|
||||
description: "한밤중에 노트를 포스트했습니다"
|
||||
description: "한밤중에 노트를 게시했다"
|
||||
flavor: "잠 좀 자세요. 걱정돼요."
|
||||
_postedAt0min0sec:
|
||||
title: "정각"
|
||||
description: "0분 0초 정각에 노트를 작성했습니다"
|
||||
description: "0분 0초 정각에 노트를 게시했다"
|
||||
flavor: "째깍 째깍 째깍 땡!"
|
||||
_selfQuote:
|
||||
title: "혼잣말"
|
||||
description: "자기 노트를 인용했습니다"
|
||||
description: "자기 노트를 인용했다"
|
||||
_htl20npm:
|
||||
title: "타임라인 폭주 중"
|
||||
description: "1분 사이에 홈 타임라인에 노트가 20개 넘게 생성되었습니다"
|
||||
description: "1분 사이에 홈 타임라인에 노트가 20개 넘게 생성되었다"
|
||||
_viewInstanceChart:
|
||||
title: "애널리스트"
|
||||
description: "서버의 차트를 열었습니다"
|
||||
description: "서버의 차트를 열었다"
|
||||
_outputHelloWorldOnScratchpad:
|
||||
title: "Hello, world!"
|
||||
description: "스크래치패드에서 hello world를 출력했습니다"
|
||||
description: "스크래치패드에서 hello world를 출력했다"
|
||||
_open3windows:
|
||||
title: "멀티 윈도우"
|
||||
description: "3개 이상의 창을 열었습니다"
|
||||
description: "3개 이상의 창을 열었다"
|
||||
_driveFolderCircularReference:
|
||||
title: "순환 참조"
|
||||
description: "드라이브 폴더에 스스로를 넣게 했습니다"
|
||||
description: "드라이브 폴더에 스스로를 넣게 했다"
|
||||
_reactWithoutRead:
|
||||
title: "읽고 답하긴 하시는 건가요?"
|
||||
description: "100자가 넘는 노트를 작성한 지 3초 안에 반응했어요"
|
||||
description: "100자가 넘는 노트를 작성한 지 3초 안에 리액션했다"
|
||||
_clickedClickHere:
|
||||
title: "여기를 누르세요"
|
||||
description: "여기를 눌렀습니다"
|
||||
title: "여길 눌러보세요"
|
||||
description: "여기를 눌렀다"
|
||||
_justPlainLucky:
|
||||
title: "그냥 운이 좋았어"
|
||||
description: "매 10초마다 0.01%의 확률로 달성됩니다"
|
||||
description: "매 10초마다 0.01%의 확률로 달성된다"
|
||||
_setNameToSyuilo:
|
||||
title: "신 콤플렉스"
|
||||
description: "이름을 syuilo로 설정했습니다"
|
||||
description: "이름을 syuilo로 설정했다"
|
||||
_passedSinceAccountCreated1:
|
||||
title: "1주년"
|
||||
description: "계정을 생성하고 1년이 지났습니다"
|
||||
description: "계정을 생성하고 1년이 지났다"
|
||||
_passedSinceAccountCreated2:
|
||||
title: "2주년"
|
||||
description: "계정을 생성하고 2년이 지났습니다"
|
||||
description: "계정을 생성하고 2년이 지났다"
|
||||
_passedSinceAccountCreated3:
|
||||
title: "3주년"
|
||||
description: "계정을 생성하고 3년이 지났습니다"
|
||||
description: "계정을 생성하고 3년이 지났다"
|
||||
_loggedInOnBirthday:
|
||||
title: "생일 축하합니다!"
|
||||
description: "생일에 로그인했습니다"
|
||||
description: "생일에 로그인했다"
|
||||
_loggedInOnNewYearsDay:
|
||||
title: "새해 복 많이 받으세요"
|
||||
description: "새해 첫 날에 로그인했습니다"
|
||||
description: "새해 첫 날에 로그인했다"
|
||||
flavor: "올해에도 저희 서버에 관심을 가져 주셔서 감사합니다"
|
||||
_cookieClicked:
|
||||
title: "쿠키를 클릭하는 게임"
|
||||
description: "쿠키를 클릭했습니다"
|
||||
flavor: "소프트웨어 착각하지 않으셨나요?"
|
||||
description: "쿠키를 클릭했다"
|
||||
flavor: "소프트웨어 착각하지 않았어?"
|
||||
_brainDiver:
|
||||
title: "Brain Diver"
|
||||
description: "Brain Diver로의 링크를 첨부했습니다"
|
||||
description: "Brain Diver로의 링크를 첨부했다"
|
||||
flavor: "Misskey-Misskey La-Tu-Ma"
|
||||
_smashTestNotificationButton:
|
||||
title: "테스트 과잉"
|
||||
description: "매우 짧은 시간 안에 알림 테스트를 여러 번 수행했습니다"
|
||||
description: "매우 짧은 시간 안에 알림 테스트를 여러 번 수행했다"
|
||||
_tutorialCompleted:
|
||||
title: "Misskey 입문자 과정 수료증"
|
||||
description: "튜토리얼을 완료했습니다"
|
||||
description: "튜토리얼을 완료했다"
|
||||
_bubbleGameExplodingHead:
|
||||
title: "🤯"
|
||||
description: "버블 게임에서 가장 큰 물건을 내놓았다"
|
||||
|
@ -2565,7 +2565,7 @@ _notification:
|
|||
checkNotificationBehavior: "알림 표시를 체크하기"
|
||||
sendTestNotification: "테스트 알림 보내기"
|
||||
notificationWillBeDisplayedLikeThis: "알림이 이렇게 표시됩니다"
|
||||
reactedBySomeUsers: "{n}명이 반응했습니다"
|
||||
reactedBySomeUsers: "{n}명이 리액션했습니다"
|
||||
likedBySomeUsers: "{n}명이 좋아요를 했습니다"
|
||||
renotedBySomeUsers: "{n}명이 리노트했습니다"
|
||||
followedBySomeUsers: "{n}명에게 팔로우됨"
|
||||
|
@ -2729,7 +2729,7 @@ _moderationLogTypes:
|
|||
deleteAccount: "계정을 삭제"
|
||||
deletePage: "페이지를 삭제"
|
||||
deleteFlash: "Play를 삭제"
|
||||
deleteGalleryPost: "갤러리 포스트를 삭제"
|
||||
deleteGalleryPost: "갤러리 게시물을 삭제"
|
||||
deleteChatRoom: "채팅 룸 삭제"
|
||||
updateProxyAccountDescription: "프록시 계정의 설명 업데이트"
|
||||
_fileViewer:
|
||||
|
@ -2976,8 +2976,8 @@ _captcha:
|
|||
title: "CAPTCHA 검증을 실패했습니다."
|
||||
text: "설정이 올바른지 다시 한 번 확인해보세요."
|
||||
_unknown:
|
||||
title: "CAPTCHA 에러"
|
||||
text: "알 수 없는 에러가 발생했습니다."
|
||||
title: "CAPTCHA 오류"
|
||||
text: "알 수 없는 오류가 발생했습니다."
|
||||
_bootErrors:
|
||||
title: "로딩이 실패함"
|
||||
serverError: "잠시 기다렸다가 다시 로드해도 여전히 문제가 해결되지 않으면 아래 Error ID와 함께 서버 관리자에게 연락해 주세요."
|
||||
|
|
|
@ -424,7 +424,7 @@ antennaExcludeBots: "排除机器人账户"
|
|||
antennaKeywordsDescription: "AND 条件用空格分隔,OR 条件用换行符分隔。"
|
||||
notifyAntenna: "开启通知"
|
||||
withFileAntenna: "仅带有附件的帖子"
|
||||
hideNotesInSensitiveChannel: "隐藏敏感频道内的帖子"
|
||||
excludeNotesInSensitiveChannel: "排除敏感频道内的帖子"
|
||||
enableServiceworker: "启用 ServiceWorker"
|
||||
antennaUsersDescription: "指定用户名,一行一个"
|
||||
caseSensitive: "区分大小写"
|
||||
|
|
|
@ -424,7 +424,6 @@ antennaExcludeBots: "排除機器人帳戶"
|
|||
antennaKeywordsDescription: "空格代表「以及」(AND),換行代表「或者」(OR)"
|
||||
notifyAntenna: "通知有新貼文"
|
||||
withFileAntenna: "僅帶有附件的貼文"
|
||||
hideNotesInSensitiveChannel: "隱藏敏感頻道的貼文"
|
||||
enableServiceworker: "啟用瀏覽器的推播通知"
|
||||
antennaUsersDescription: "填寫使用者名稱,以換行分隔"
|
||||
caseSensitive: "區分大小寫"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.4.0-rc.4",
|
||||
"version": "2025.4.0",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -173,21 +173,21 @@ function customStringify(obj: unknown): string {
|
|||
/**
|
||||
* 要素のノードの中身のテキストを抽出する
|
||||
*/
|
||||
function extractElementText(node: ElementNode): string | null {
|
||||
return extractElementTextChecked(node, node.tag);
|
||||
function extractElementText(node: ElementNode, id: string): string | null {
|
||||
return extractElementTextChecked(node, node.tag, id);
|
||||
}
|
||||
|
||||
function extractElementTextChecked(node: ElementNode, processingNodeName: string): string | null {
|
||||
function extractElementTextChecked(node: ElementNode, processingNodeName: string, id: string): string | null {
|
||||
const result: string[] = [];
|
||||
for (const child of node.children) {
|
||||
const text = extractElementText2Inner(child, processingNodeName);
|
||||
const text = extractElementText2Inner(child, processingNodeName, id);
|
||||
if (text == null) return null;
|
||||
result.push(text);
|
||||
}
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
function extractElementText2Inner(node: TemplateChildNode, processingNodeName: string): string | null {
|
||||
function extractElementText2Inner(node: TemplateChildNode, processingNodeName: string, id: string): string | null {
|
||||
if (node.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
||||
|
||||
switch (node.type) {
|
||||
|
@ -196,16 +196,16 @@ function extractElementText2Inner(node: TemplateChildNode, processingNodeName: s
|
|||
if (expr.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error(`Unexpected COMPOUND_EXPRESSION`);
|
||||
const exprResult = evalExpression(expr.content);
|
||||
if (typeof exprResult !== 'string') {
|
||||
logger.error(`Result of interpolation node is not string at line ${node.loc.start.line}`);
|
||||
logger.error(`Result of interpolation node is not string at line ${id}:${node.loc.start.line}`);
|
||||
return null;
|
||||
}
|
||||
return exprResult;
|
||||
}
|
||||
case NodeTypes.ELEMENT:
|
||||
if (node.tagType === ElementTypes.ELEMENT) {
|
||||
return extractElementTextChecked(node, processingNodeName);
|
||||
return extractElementTextChecked(node, processingNodeName, id);
|
||||
} else {
|
||||
logger.error(`Unexpected ${node.tag} extracting text of ${processingNodeName} ${node.loc.start.line}`);
|
||||
logger.error(`Unexpected ${node.tag} extracting text of ${processingNodeName} ${id}:${node.loc.start.line}`);
|
||||
return null;
|
||||
}
|
||||
case NodeTypes.TEXT:
|
||||
|
@ -217,7 +217,7 @@ function extractElementText2Inner(node: TemplateChildNode, processingNodeName: s
|
|||
case NodeTypes.IF_BRANCH:
|
||||
case NodeTypes.FOR:
|
||||
case NodeTypes.TEXT_CALL:
|
||||
logger.error(`Unexpected controlflow element extracting text of ${processingNodeName} ${node.loc.start.line}`);
|
||||
logger.error(`Unexpected controlflow element extracting text of ${processingNodeName} ${id}:${node.loc.start.line}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ function extractElementText2Inner(node: TemplateChildNode, processingNodeName: s
|
|||
/**
|
||||
* SearchLabel/SearchKeyword/SearchIconを探して抽出する関数
|
||||
*/
|
||||
function extractSugarTags(nodes: TemplateChildNode[]): { label: string | null, keywords: string[], icon: string | null } {
|
||||
function extractSugarTags(nodes: TemplateChildNode[], id: string): { label: string | null, keywords: string[], icon: string | null } {
|
||||
let label: string | null | undefined = undefined;
|
||||
let icon: string | null | undefined = undefined;
|
||||
const keywords: string[] = [];
|
||||
|
@ -242,35 +242,35 @@ function extractSugarTags(nodes: TemplateChildNode[]): { label: string | null, k
|
|||
return false; // SearchMarkerはスキップ
|
||||
case 'SearchLabel':
|
||||
if (label !== undefined) {
|
||||
logger.warn(`Duplicate SearchLabel found, ignoring the second one at ${node.loc.start.line}`);
|
||||
logger.warn(`Duplicate SearchLabel found, ignoring the second one at ${id}:${node.loc.start.line}`);
|
||||
break; // 2つ目のSearchLabelは無視
|
||||
}
|
||||
|
||||
label = extractElementText(node);
|
||||
label = extractElementText(node, id);
|
||||
return;
|
||||
case 'SearchKeyword':
|
||||
const content = extractElementText(node);
|
||||
const content = extractElementText(node, id);
|
||||
if (content) {
|
||||
keywords.push(content);
|
||||
}
|
||||
return;
|
||||
case 'SearchIcon':
|
||||
if (icon !== undefined) {
|
||||
logger.warn(`Duplicate SearchIcon found, ignoring the second one at ${node.loc.start.line}`);
|
||||
logger.warn(`Duplicate SearchIcon found, ignoring the second one at ${id}:${node.loc.start.line}`);
|
||||
break; // 2つ目のSearchIconは無視
|
||||
}
|
||||
|
||||
if (node.children.length !== 1) {
|
||||
logger.error(`SearchIcon must have exactly one child at ${node.loc.start.line}`);
|
||||
logger.error(`SearchIcon must have exactly one child at ${id}:${node.loc.start.line}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const iconNode = node.children[0];
|
||||
if (iconNode.type !== NodeTypes.ELEMENT) {
|
||||
logger.error(`SearchIcon must have a child element at ${node.loc.start.line}`);
|
||||
logger.error(`SearchIcon must have a child element at ${id}:${node.loc.start.line}`);
|
||||
return;
|
||||
}
|
||||
icon = getStringProp(findAttribute(iconNode.props, 'class'));
|
||||
icon = getStringProp(findAttribute(iconNode.props, 'class'), id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -282,7 +282,7 @@ function extractSugarTags(nodes: TemplateChildNode[]): { label: string | null, k
|
|||
return { label: label ?? null, keywords, icon: icon ?? null };
|
||||
}
|
||||
|
||||
function getStringProp(attr: AttributeNode | DirectiveNode | null): string | null {
|
||||
function getStringProp(attr: AttributeNode | DirectiveNode | null, id: string): string | null {
|
||||
switch (attr?.type) {
|
||||
case null:
|
||||
case undefined:
|
||||
|
@ -294,27 +294,27 @@ function getStringProp(attr: AttributeNode | DirectiveNode | null): string | nul
|
|||
if (attr.exp.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error('Unexpected COMPOUND_EXPRESSION');
|
||||
const value = evalExpression(attr.exp.content ?? '');
|
||||
if (typeof value !== 'string') {
|
||||
logger.error(`Expected string value, got ${typeof value} at line ${attr.loc.start.line}`);
|
||||
logger.error(`Expected string value, got ${typeof value} at ${id}:${attr.loc.start.line}`);
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function getStringArrayProp(attr: AttributeNode | DirectiveNode | null): string[] | null {
|
||||
function getStringArrayProp(attr: AttributeNode | DirectiveNode | null, id: string): string[] | null {
|
||||
switch (attr?.type) {
|
||||
case null:
|
||||
case undefined:
|
||||
return null;
|
||||
case NodeTypes.ATTRIBUTE:
|
||||
logger.error(`Expected directive, got attribute at line ${attr.loc.start.line}`);
|
||||
logger.error(`Expected directive, got attribute at ${id}:${attr.loc.start.line}`);
|
||||
return null;
|
||||
case NodeTypes.DIRECTIVE:
|
||||
if (attr.exp == null) return null;
|
||||
if (attr.exp.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error('Unexpected COMPOUND_EXPRESSION');
|
||||
const value = evalExpression(attr.exp.content ?? '');
|
||||
if (!Array.isArray(value) || !value.every(x => typeof x === 'string')) {
|
||||
logger.error(`Expected string array value, got ${typeof value} at line ${attr.loc.start.line}`);
|
||||
logger.error(`Expected string array value, got ${typeof value} at ${id}:${attr.loc.start.line}`);
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
|
@ -354,11 +354,11 @@ function extractUsageInfoFromTemplateAst(
|
|||
};
|
||||
|
||||
// バインドプロパティを取得
|
||||
const path = getStringProp(findAttribute(node.props, 'path'))
|
||||
const icon = getStringProp(findAttribute(node.props, 'icon'))
|
||||
const label = getStringProp(findAttribute(node.props, 'label'))
|
||||
const inlining = getStringArrayProp(findAttribute(node.props, 'inlining'))
|
||||
const keywords = getStringArrayProp(findAttribute(node.props, 'keywords'))
|
||||
const path = getStringProp(findAttribute(node.props, 'path'), id)
|
||||
const icon = getStringProp(findAttribute(node.props, 'icon'), id)
|
||||
const label = getStringProp(findAttribute(node.props, 'label'), id)
|
||||
const inlining = getStringArrayProp(findAttribute(node.props, 'inlining'), id)
|
||||
const keywords = getStringArrayProp(findAttribute(node.props, 'keywords'), id)
|
||||
|
||||
if (path) markerInfo.path = path;
|
||||
if (icon) markerInfo.icon = icon;
|
||||
|
@ -373,7 +373,7 @@ function extractUsageInfoFromTemplateAst(
|
|||
|
||||
// SearchLabelとSearchKeywordを抽出 (AST全体を探索)
|
||||
{
|
||||
const extracted = extractSugarTags(node.children);
|
||||
const extracted = extractSugarTags(node.children, id);
|
||||
if (extracted.label && markerInfo.label) logger.warn(`Duplicate label found for ${markerId} at ${id}:${node.loc.start.line}`);
|
||||
if (extracted.icon && markerInfo.icon) logger.warn(`Duplicate icon found for ${markerId} at ${id}:${node.loc.start.line}`);
|
||||
markerInfo.label = extracted.label ?? markerInfo.label ?? '';
|
||||
|
@ -585,7 +585,7 @@ export class MarkerIdAssigner {
|
|||
}
|
||||
|
||||
// AST で :children 属性が検出された場合、それを更新
|
||||
const childrenValue = getStringArrayProp(childrenProp);
|
||||
const childrenValue = getStringArrayProp(childrenProp, id);
|
||||
if (childrenValue == null) continue;
|
||||
|
||||
const newValue: string[] = [...childrenValue];
|
||||
|
@ -740,7 +740,7 @@ export function pluginCreateSearchIndexVirtualModule(options: Options, asigner:
|
|||
this.addWatchFile(searchIndexFilePath);
|
||||
|
||||
const code = await asigner.getOrLoad(searchIndexFilePath);
|
||||
return generateJavaScriptCode(collectFileMarkers(id, code));
|
||||
return generateJavaScriptCode(collectFileMarkers(searchIndexFilePath, code));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
|
|
@ -266,12 +266,13 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvents> {
|
|||
throw new Error('no route found for: ' + fullPath);
|
||||
}
|
||||
|
||||
if ('redirect' in res.route) {
|
||||
for (let current: PathResolvedResult | undefined = res; current; current = current.child) {
|
||||
if ('redirect' in current.route) {
|
||||
let redirectPath: string;
|
||||
if (typeof res.route.redirect === 'function') {
|
||||
redirectPath = res.route.redirect(res.props);
|
||||
if (typeof current.route.redirect === 'function') {
|
||||
redirectPath = current.route.redirect(current.props);
|
||||
} else {
|
||||
redirectPath = res.route.redirect + (res._parsedRoute.queryString ? '?' + res._parsedRoute.queryString : '') + (res._parsedRoute.hash ? '#' + res._parsedRoute.hash : '');
|
||||
redirectPath = current.route.redirect + (current._parsedRoute.queryString ? '?' + current._parsedRoute.queryString : '') + (current._parsedRoute.hash ? '#' + current._parsedRoute.hash : '');
|
||||
}
|
||||
if (_DEV_) console.log('Redirecting to: ', redirectPath);
|
||||
if (_redirected && this.redirectCount++ > 10) {
|
||||
|
@ -279,6 +280,7 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvents> {
|
|||
}
|
||||
return this.navigate(redirectPath, emitChange, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (res.route.loginRequired && !this.isLoggedIn) {
|
||||
res.route.component = this.notFoundPageComponent;
|
||||
|
|
|
@ -103,7 +103,6 @@ function removeItem(index: number) {
|
|||
|
||||
async function save() {
|
||||
prefer.commit('menu', items.value.map(x => x.type));
|
||||
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
|
|
@ -4,6 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
-->
|
||||
|
||||
<template>
|
||||
<SearchMarker path="/settings/notifications" :label="i18n.ts.notifications" :keywords="['notifications']" icon="ti ti-bell">
|
||||
<div class="_gaps_m">
|
||||
<MkFeatureBanner icon="/client-assets/bell_3d.png" color="#ffff00">
|
||||
<SearchKeyword>{{ i18n.ts._settings.notificationsBanner }}</SearchKeyword>
|
||||
|
@ -62,6 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</SearchMarker>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -33,6 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #value><MkTime :time="$i.createdAt" mode="detail"/></template>
|
||||
</MkKeyValue>
|
||||
|
||||
<SearchMarker :keywords="['role', 'policy']">
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-badges"></i></template>
|
||||
<template #label><SearchLabel>{{ i18n.ts._role.policies }}</SearchLabel></template>
|
||||
|
@ -43,6 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</SearchMarker>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</SearchMarker>
|
||||
|
|
|
@ -540,7 +540,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkPreferenceContainer k="useBlurEffect">
|
||||
<MkSwitch v-model="useBlurEffect">
|
||||
<template #label><SearchLabel>{{ i18n.ts.useBlurEffect }}</SearchLabel></template>
|
||||
<template #caption><SearchLabel>{{ i18n.ts.turnOffToImprovePerformance }}</SearchLabel></template>
|
||||
<template #caption><SearchKeyword>{{ i18n.ts.turnOffToImprovePerformance }}</SearchKeyword></template>
|
||||
</MkSwitch>
|
||||
</MkPreferenceContainer>
|
||||
</SearchMarker>
|
||||
|
@ -549,7 +549,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkPreferenceContainer k="useBlurEffectForModal">
|
||||
<MkSwitch v-model="useBlurEffectForModal">
|
||||
<template #label><SearchLabel>{{ i18n.ts.useBlurEffectForModal }}</SearchLabel></template>
|
||||
<template #caption><SearchLabel>{{ i18n.ts.turnOffToImprovePerformance }}</SearchLabel></template>
|
||||
<template #caption><SearchKeyword>{{ i18n.ts.turnOffToImprovePerformance }}</SearchKeyword></template>
|
||||
</MkSwitch>
|
||||
</MkPreferenceContainer>
|
||||
</SearchMarker>
|
||||
|
@ -558,7 +558,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkPreferenceContainer k="useStickyIcons">
|
||||
<MkSwitch v-model="useStickyIcons">
|
||||
<template #label><SearchLabel>{{ i18n.ts._settings.useStickyIcons }}</SearchLabel></template>
|
||||
<template #caption><SearchLabel>{{ i18n.ts.turnOffToImprovePerformance }}</SearchLabel></template>
|
||||
<template #caption><SearchKeyword>{{ i18n.ts.turnOffToImprovePerformance }}</SearchKeyword></template>
|
||||
</MkSwitch>
|
||||
</MkPreferenceContainer>
|
||||
</SearchMarker>
|
||||
|
|
|
@ -19,8 +19,10 @@ export async function signout() {
|
|||
localStorage.clear();
|
||||
defaultMemoryStorage.clear();
|
||||
|
||||
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
|
||||
indexedDB.deleteDatabase(name);
|
||||
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise<void>((res, rej) => {
|
||||
const delidb = indexedDB.deleteDatabase(name);
|
||||
delidb.onsuccess = () => res();
|
||||
delidb.onerror = e => rej(e);
|
||||
}));
|
||||
|
||||
await Promise.all(idbPromises);
|
||||
|
|
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA :class="$style.item" :activeClass="$style.active" to="/" exact>
|
||||
<i :class="$style.itemIcon" class="ti ti-home ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
|
||||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<template v-for="item in prefer.r.menu.value">
|
||||
<div v-if="item === '-'" :class="$style.divider"></div>
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" class="_button" :class="[$style.item, { [$style.active]: navbarItemDef[item].active }]" :activeClass="$style.active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<i class="ti-fw" :class="[$style.itemIcon, navbarItemDef[item].icon]"></i><span :class="$style.itemText">{{ navbarItemDef[item].title }}</span>
|
||||
|
@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineAsyncComponent, toRef } from 'vue';
|
||||
import { computed, defineAsyncComponent } from 'vue';
|
||||
import { openInstanceMenu } from './common.js';
|
||||
import * as os from '@/os.js';
|
||||
import { navbarItemDef } from '@/navbar.js';
|
||||
|
@ -59,10 +59,9 @@ import { instance } from '@/instance.js';
|
|||
import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
|
||||
import { $i } from '@/i.js';
|
||||
|
||||
const menu = toRef(prefer.s, 'menu');
|
||||
const otherMenuItemIndicated = computed(() => {
|
||||
for (const def in navbarItemDef) {
|
||||
if (menu.value.includes(def)) continue;
|
||||
if (prefer.r.menu.value.includes(def)) continue;
|
||||
if (navbarItemDef[def].indicated) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA v-tooltip.noDelay.right="i18n.ts.timeline" :class="$style.item" :activeClass="$style.active" to="/" exact>
|
||||
<i :class="$style.itemIcon" class="ti ti-home ti-fw" style="viewTransitionName: navbar-homeIcon;"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
|
||||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<template v-for="item in prefer.r.menu.value">
|
||||
<div v-if="item === '-'" :class="$style.divider"></div>
|
||||
<component
|
||||
:is="navbarItemDef[item].to ? 'MkA' : 'button'"
|
||||
|
@ -120,10 +120,9 @@ const iconOnly = computed(() => {
|
|||
return forceIconOnly.value || (store.r.menuDisplay.value === 'sideIcon');
|
||||
});
|
||||
|
||||
const menu = computed(() => prefer.s.menu);
|
||||
const otherMenuItemIndicated = computed(() => {
|
||||
for (const def in navbarItemDef) {
|
||||
if (menu.value.includes(def)) continue;
|
||||
if (prefer.r.menu.value.includes(def)) continue;
|
||||
if (navbarItemDef[def].indicated) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -65,10 +65,11 @@ const hyphens = [
|
|||
];
|
||||
|
||||
const hyphensCodePoints = hyphens.map(code => `\\u{${code.toString(16).padStart(4, '0')}}`);
|
||||
const hyphensRegex = new RegExp(`[${hyphensCodePoints.join('')}]`, 'ug');
|
||||
|
||||
/** ハイフンを統一(ローマ字半角入力時に`ー`と`-`が判定できない問題の調整) */
|
||||
export function normalizeHyphens(str: string) {
|
||||
return str.replace(new RegExp(`[${hyphensCodePoints.join('')}]`, 'ug'), '\u002d');
|
||||
return str.replace(hyphensRegex, '\u002d');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"type": "module",
|
||||
"name": "misskey-js",
|
||||
"version": "2025.4.0-rc.4",
|
||||
"version": "2025.4.0",
|
||||
"description": "Misskey SDK for JavaScript",
|
||||
"license": "MIT",
|
||||
"main": "./built/index.js",
|
||||
|
|
Loading…
Reference in New Issue