diff --git a/CHANGELOG.md b/CHANGELOG.md index 36bc63b0af..cb8ab8f30f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,15 +32,22 @@ - ハッシュタグのノート一覧ページから、そのハッシュタグで投稿するボタンを追加 - アカウント初期設定ウィザードに戻るボタンを追加 - アカウントの初期設定ウィザードにあとでボタンを追加 +- サーバーにカスタム絵文字の種類が多い場合のパフォーマンスの改善 - Fix: URLプレビューで情報が取得できなかった際の挙動を修正 - Fix: Safari、Firefoxでの新規登録時、パスワードマネージャーにメールアドレスが登録されていた挙動を修正 -- fix:ロールタイムラインが無効でも投稿が流れてしまう問題の修正 -- fix:ロールタイムラインにて全ての投稿が流れてしまう問題の修正 +- Fix: ロールタイムラインが無効でも投稿が流れてしまう問題の修正 +- Fix: ロールタイムラインにて全ての投稿が流れてしまう問題の修正 +- Fix: 「アクセストークンの管理」画面でアプリの情報が表示されない問題の修正 +- Fix: Firefoxにおける絵文字ピッカーのTabキーフォーカス問題の修正 +- Fix: フォローボタンがテーマのカラースキームによって視認性が悪くなる問題を修正 + - 新しいプロパティ `fgOnWhite` が追加されました ### Server - bullをbull-mqにアップグレードし、ジョブキューのパフォーマンスを改善 - ストリーミングのパフォーマンスを改善 +- Fix: 無効化されたアンテナにアクセスがあった際に再度有効化するように - Fix: お知らせの画像URLを空にできない問題を修正 +- Fix: i/notificationsのsinceIdが機能しない問題を修正 ## 13.12.2 @@ -365,6 +372,7 @@ Meilisearchの設定に`index`が必要になりました。値はMisskeyサー - アンテナでCWも検索対象にするように - ノートの操作部をホバー時のみ表示するオプションを追加 - サウンドを追加 +- enhance(client): MFMのx2, scale, positionが含まれていたらノートをたたむように - サーバーのパフォーマンスを改善 ### Bugfixes diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 3b97f435d2..5d0fd201b3 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -267,8 +267,8 @@ start: "البداية" home: "الرئيسي" remoteUserCaution: "هذه المعلومات قد لا تكون مكتملة بما أن المستخدم من مثيل بعيد." activity: "النشاط" -images: "الصور" -image: "الصور" +images: "صور" +image: "صور" birthday: "تاريخ الميلاد" yearsOld: "{age} سنة" registeredDate: "انضم في" @@ -1331,7 +1331,7 @@ _pages: text: "نص" textarea: "حقل نصي" section: "قسم" - image: "الصور" + image: "صور" button: "زرّ" note: "ملاحظة مضمّنة" _note: diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 8001a55764..c4c12cb1aa 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1060,6 +1060,8 @@ cancelReactionConfirm: "Möchtest du deine Reaktion wirklich löschen?" changeReactionConfirm: "Möchtest du deine Reaktion wirklich ändern?" later: "Später" goToMisskey: "Zu Misskey" +additionalEmojiDictionary: "Zusätzliche Emoji-Wörterbücher" +installed: "Installiert" _initialAccountSetting: accountCreated: "Dein Konto wurde erfolgreich erstellt!" letsStartAccountSetup: "Lass uns nun dein Konto einrichten." diff --git a/locales/en-US.yml b/locales/en-US.yml index 1af33cb5a7..0f1c7c89fe 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1060,6 +1060,8 @@ cancelReactionConfirm: "Really delete your reaction?" changeReactionConfirm: "Really change your reaction?" later: "Later" goToMisskey: "To Misskey" +additionalEmojiDictionary: "Additional emoji dictionaries" +installed: "Installed" _initialAccountSetting: accountCreated: "Your account was successfully created!" letsStartAccountSetup: "For starters, let's set up your profile." diff --git a/locales/index.d.ts b/locales/index.d.ts index a54268676e..7047f42eff 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1063,6 +1063,8 @@ export interface Locale { "changeReactionConfirm": string; "later": string; "goToMisskey": string; + "additionalEmojiDictionary": string; + "installed": string; "_initialAccountSetting": { "accountCreated": string; "letsStartAccountSetup": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 0ca37caa58..fcba3fb822 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1060,6 +1060,8 @@ cancelReactionConfirm: "リアクションを取り消しますか?" changeReactionConfirm: "リアクションを変更しますか?" later: "あとで" goToMisskey: "Misskeyへ" +additionalEmojiDictionary: "絵文字の追加辞書" +installed: "インストール済み" _initialAccountSetting: accountCreated: "アカウントの作成が完了しました!" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 69ea0d172a..652814ca98 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -47,11 +47,13 @@ copyContent: "内容をコピー" copyLink: "リンクをコピー" delete: "ほかす" deleteAndEdit: "ほかして直す" -deleteAndEditConfirm: "このノートをほかしてもっかい直す?このノートへのリアクション、Renote、返信も全部消えるんやけどそれでもええん?" +deleteAndEditConfirm: "このノートをほかしてもっかい直す?このノートへのツッコミ、Renote、返信も全部消えるんやけどそれでもええん?" addToList: "リストに入れたる" sendMessage: "メッセージを送る" copyRSS: "RSSをコピー" copyUsername: "ユーザー名をコピー" +copyUserId: "ユーザーIDをコピー" +copyNoteId: "ノートIDをコピー" searchUser: "ユーザーを検索" reply: "返事" loadMore: "まだまだあるで!" @@ -1043,6 +1045,10 @@ preventAiLearning: "生成AIの学習に使わんといて" preventAiLearningDescription: "他の文章生成AIとか画像生成AIに、投稿したノートとか画像なんかを勝手に使わんように頼むで。具体的にはnoaiフラグをHTMLレスポンスに含めるんやけど、これ聞いてくれるんはAIの気分次第やから、使われる可能性もちょっとはあるな。" options: "オプション" specifyUser: "ユーザー指定" +rolesThatCanBeUsedThisEmojiAsReaction: "ツッコミとして使えるロール" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ロールが一個も指定されてへんかったら、誰でもツッコミとして使えるで。" +cancelReactionConfirm: "ツッコむんをやっぱやめるか?" +changeReactionConfirm: "ツッコミを別のに変えるか?" _initialAccountSetting: accountCreated: "アカウント作り終わったで。" letsStartAccountSetup: "アカウントの初期設定をしよか。" @@ -1614,7 +1620,7 @@ _timelineTutorial: step2_2: "最初のノートは、自己紹介とか「{name}始めてみたんや」とかがええと思うで。" step3_1: "投稿できた?" step3_2: "あんたのノートがタイムラインに出てきたら成功や。" - step4_1: "ノートには、「リアクション」を付けれるで。" + step4_1: "ノートには、「ツッコミ」を付けれるで。" step4_2: "ツッコむんやったら、ノートの「+」マークを押して、好きな絵文字を選ぶで。" _2fa: alreadyRegistered: "もう設定終わっとるわ。" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 11ab762aa4..c36305137c 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -52,6 +52,8 @@ addToList: "리스트에 추가" sendMessage: "메시지 보내기" copyRSS: "RSS 복사" copyUsername: "유저명 복사" +copyUserId: "유저 ID 복사" +copyNoteId: "노트 ID 복사" searchUser: "사용자 검색" reply: "답글" loadMore: "더 보기" @@ -505,7 +507,7 @@ objectStoragePrefixDesc: "이 Prefix 의 디렉토리 아래에 파일이 저장 objectStorageEndpoint: "Endpoint" objectStorageEndpointDesc: "AWS S3의 경우 공란, 다른 서비스의 경우 각 서비스의 가이드에 맞게 endpoint를 설정해주세요. '' 혹은 ':' 와 같이 지정합니다." objectStorageRegion: "Region" -objectStorageRegionDesc: "'xx-east-1'와 같이 region을 지정해주세요. 사용하는 서비스에 region 개념이 없는 경우 'us-east-1'으로 설정해 주세요. AWS 설정 파일 또는 환경 변수를 참조할 경우에는 비워주세요." +objectStorageRegionDesc: "'xx-east-1'와 같이 region을 지정해 주세요. 사용하는 서비스에 region 개념이 없는 경우 'us-east-1'으로 설정해 주세요. AWS 설정 파일 또는 환경 변수를 참조할 경우에는 비워주세요." objectStorageUseSSL: "SSL 사용" objectStorageUseSSLDesc: "API 호출시 HTTPS 를 사용하지 않는 경우 OFF 로 설정해 주세요" objectStorageUseProxy: "연결에 프록시를 사용" @@ -790,6 +792,7 @@ noMaintainerInformationWarning: "관리자 정보가 설정되어 있지 않습 noBotProtectionWarning: "Bot 방어가 설정되어 있지 않습니다." configure: "설정하기" postToGallery: "갤러리에 업로드" +postToHashtag: "이 해시태그에 게시" gallery: "갤러리" recentPosts: "최근 포스트" popularPosts: "인기 포스트" @@ -823,6 +826,7 @@ translatedFrom: "{x}에서 번역" accountDeletionInProgress: "계정 삭제 작업을 진행하고 있습니다" usernameInfo: "서버상에서 계정을 식별하기 위한 이름. 알파벳(a~z, A~Z), 숫자(0~9) 및 언더바(_)를 사용할 수 있습니다. 사용자명은 나중에 변경할 수 없습니다." aiChanMode: "아이 모드" +devMode: "개발자 모드" keepCw: "CW 유지하기" pubSub: "Pub/Sub 계정" lastCommunication: "마지막 통신" @@ -830,8 +834,10 @@ resolved: "해결됨" unresolved: "해결되지 않음" breakFollow: "팔로워 해제" breakFollowConfirm: "팔로우를 해제하시겠습니까?" -itsOn: "켜짐" -itsOff: "꺼짐" +itsOn: "켜져 있습니다" +itsOff: "꺼져 있습니다" +on: "켜짐" +off: "꺼짐" emailRequiredForSignup: "가입할 때 이메일 주소 입력을 필수로 하기" unread: "읽지 않음" filter: "필터" @@ -986,6 +992,8 @@ cannotBeChangedLater: "나중에 변경할 수 없습니다." reactionAcceptance: "리액션 수신" likeOnly: "좋아요만 받기" likeOnlyForRemote: "리모트에서는 좋아요만 받기" +nonSensitiveOnly: "열람 주의로 설정되지 않았을 때만 받기" +nonSensitiveOnlyForLocalLikeOnlyForRemote: "열람 주의로 설정되지 않았을 때만 받기 (리모트에서는 좋아요만 받기)" rolesAssignedToMe: "나에게 할당된 역할" resetPasswordConfirm: "비밀번호를 재설정하시겠습니까?" sensitiveWords: "민감한 단어" @@ -1043,31 +1051,43 @@ preventAiLearning: "기계학습(생성형 AI)으로의 사용을 거부" preventAiLearningDescription: "외부의 문장 생성 AI나 이미지 생성 AI에 대해 제출한 노트나 이미지 등의 콘텐츠를 학습의 대상으로 사용하지 않도록 요구합니다. 다만, 이 요구사항을 지킬 의무는 없기 때문에 학습을 완전히 방지하는 것은 아닙니다." options: "옵션" specifyUser: "사용자 지정" +failedToPreviewUrl: "미리 볼 수 없음" +update: "업데이트" +rolesThatCanBeUsedThisEmojiAsReaction: "이 이모지를 리액션으로 사용할 수 있는 역할" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "역할을 지정하지 않으면, 누구나 이 이모지를 리액션으로 사용할 수 있습니다." +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "역할은 공개로 설정되어 있어야 합니다." +cancelReactionConfirm: "리액션을 취소하시겠습니까?" +changeReactionConfirm: "리액션을 변경하시겠습니까?" +later: "나중에" +goToMisskey: "Misskey로" +additionalEmojiDictionary: "이모지 추가 사전" +installed: "설치됨" _initialAccountSetting: accountCreated: "계정 생성이 완료되었습니다!" letsStartAccountSetup: "계정의 초기 설정을 진행합니다." letsFillYourProfile: "우선 나의 프로필을 설정해 보아요." profileSetting: "프로필 설정" - privacySetting: "\n프라이버시설정" + privacySetting: "프라이버시 설정" theseSettingsCanEditLater: "이 설정들은 나중에도 변경할 수 있습니다." - youCanEditMoreSettingsInSettingsPageLater: "이 외에도 '설정' 페이지에서 다양한 설정을 나의 입맛에 맛게 조절할 수 있습니다. 꼭 확인해 보세요!" + youCanEditMoreSettingsInSettingsPageLater: "이 외에도 '설정' 페이지에서 다양한 설정을 나의 입맛에 맞게 조절할 수 있습니다. 꼭 확인해 보세요!" followUsers: "관심사가 맞는 유저를 팔로우하여 타임라인을 가꾸어 봅시다." pushNotificationDescription: "푸시 알림을 활성화하면 {name}의 알림을 나의 기기에서 받아볼 수 있게 됩니다." initialAccountSettingCompleted: "초기 설정을 모두 마쳤습니다!" haveFun: "{name}와 함께 즐거운 시간 보내세요!" ifYouNeedLearnMore: "{name}(Misskey)의 사용 방법에 대해 자세히 알아보려면 {link}를 참고해 주세요." - skipAreYouSure: "초기 설정을 넘기시겠습니까?" + skipAreYouSure: "초기 설정을 중단하시겠습니까?" + laterAreYouSure: "초기 설정을 나중에 진행하시겠습니까?" _serverRules: description: "회원 가입 이전에 간단하게 표시할 서버 규칙입니다. 이용 약관의 요약으로 구성하는 것을 추천합니다." _accountMigration: moveFrom: "다른 계정에서 이 계정으로 이사" moveFromSub: "다른 계정에 대한 별칭을 생성" - moveFromLabel: "기존 계정:" + moveFromLabel: "기존 계정 #{n}" moveFromDescription: "다른 계정에서 이 계정으로 팔로워를 가져오려면, 우선 여기에서 별칭을 지정해야 합니다. 반드시 이사하기 전에 지정해야 합니다! 기존 계정을 다음과 같은 형식으로 입력해 주십시오: @person@instance.com" moveTo: "이 계정에서 다른 계정으로 이사" moveToLabel: "이사할 계정:" moveCannotBeUndone: "한 번 이사하면, 두 번 다시 되돌릴 수 없습니다." - moveAccountDescription: "이 작업은 취소할 수 없습니다. 먼저 이사할 계정에서 이 계정에 대한 별칭을 지정하였는지 다시 한 번 확인해 주십시오. 별칭을 지정한 다음, 이사할 계정을 다음과 같은 형식으로 입력해 주십시오: @person@instance.com" + moveAccountDescription: "새 계정으로 이전합니다.\n ・팔로워가 새 계정을 자동으로 팔로우 합니다\n ・이 계정에서 팔로우는 모두 해제됩니다\n ・이 계정으로는 노트 작성 등을 할 수 없게 됩니다\n\n팔로워는 자동으로 이전되지만, 팔로우는 수동으로 진행해야 합니다. 이전하기 전에 이 계정에서 팔로우를 내보내고, 이전 후에는 즉시 이전한 계정에서 가져오기를 진행하십시오.\n리스트・뮤트・차단에 대해서도 마찬가지이므로 수동으로 이전해야 합니다.\n\n(이 설명은 이 서버(Misskey v13.12.0 이후)의 사양입니다. Mastodon 등의 다른 ActivityPub 소프트웨어에서는 작동이 다를 수 있습니다.)" moveAccountHowTo: "계정을 이사하려면 우선 이사갈 계정에서 이 계정에 대한 별칭을 지정해야 합니다.\n별칭을 작성한 다음, 이사갈 계정을 다음과 같이 입력하십시오:\n@username@server.example.com" startMigration: "이사하기" migrationConfirm: "정말로 이 계정을 {account} 으로 이전하시겠습니까? 한 번 이전한 다음에는 취소할 수 없으며, 두 번 다시 원래 상태로 복구할 수 없습니다.\n이사할 계정에서 계정 별칭을 지정하였는지 다시 한 번 확인하십시오." diff --git a/locales/no-NO.yml b/locales/no-NO.yml index 585fb95b3d..ec2900527b 100644 --- a/locales/no-NO.yml +++ b/locales/no-NO.yml @@ -1,5 +1,7 @@ --- _lang_: "Norsk Bokmål" +headlineMisskey: "Et nettverk forbundet med Notes" +introMisskey: "Velkommen! Misskey er en desentralisert mikrobloggtjeneste med åpen kildekode.\nOpprett \"Notes\" for å dele tankene dine med alle rundt deg. 📡\nMed \"reaksjoner\" kan du også raskt gi uttrykk for hva du synes om alles Notes. 👍\nLa oss utforske en ny verden! 🚀" monthAndDay: "{day}-{month}" search: "Søk" notifications: "Varsler" @@ -10,8 +12,10 @@ fetchingAsApObject: "Henter fra Fediverse..." ok: "OK" gotIt: "Skjønner" cancel: "Avbryt" -noThankYou: "Avbryt" +noThankYou: "Ikke nå" enterUsername: "Skriv inn brukernavn" +renotedBy: "Renotes av {user}" +noNotes: "Ingen Notes" noNotifications: "Ingen varsler" instance: "Server" settings: "Innstillinger" @@ -21,7 +25,7 @@ otherSettings: "Andre innstillinger" openInWindow: "Åpne i vindu" profile: "Profil" timeline: "Tidslinje" -noAccountDescription: "Denne brukeren har ikke skrevet sin bio ennå." +noAccountDescription: "Denne brukeren har ikke skrevet sin biografi ennå." login: "Logg inn" loggingIn: "Logget inn" logout: "Logg ut" @@ -30,20 +34,21 @@ uploading: "Laster opp" save: "Lagre" users: "Brukere" addUser: "Legg til bruker" -favorite: "Favoritt" +favorite: "Legg til i favoritter" favorites: "Favoritter" -unfavorite: "Fjern favoritt" +unfavorite: "Fjern fra favoritter" favorited: "Lagt til i favoritter." alreadyFavorited: "Allerede lagt til i favoritter." cantFavorite: "Kunne ikke legge til i favoritter." -pin: "Fest" -unpin: "Opphev festing" +pin: "Fest til profil" +unpin: "Fjern fra profil" copyContent: "Kopier innhold" copyLink: "Kopier lenke" delete: "Slett" deleteAndEdit: "Slett og rediger" +deleteAndEditConfirm: "Er du sikker på at du vil slette denne Noten og redigere den? Du vil miste alle reaksjoner, Renotes og svar på den." addToList: "Legg til i liste" -sendMessage: "Send melding" +sendMessage: "Send en melding" copyRSS: "Kopier RSS" copyUsername: "Kopier brukernavn" searchUser: "Søk brukere" @@ -63,7 +68,9 @@ unfollowConfirm: "Er du sikker på at du vil slutte å følge {name}?" importRequested: "Du har bedt om import. Dette kan ta en stund." lists: "Lister" noLists: "Ingen lister" -following: "Følg" +note: "Note" +notes: "Notes" +following: "Følger" followers: "Følgere" followsYou: "Følger deg" createList: "Opprett liste" @@ -74,14 +81,22 @@ pageLoadError: "Kunne ikke hente side." serverIsDead: "Denne serveren svarer ikke. Vennligst vent en stund og prøv igjen." enterListName: "Skriv inn et navn på listen" privacy: "Personvern" +defaultNoteVisibility: "Standard synlighet" follow: "Følg" followRequest: "Følgeforespørsel" followRequests: "Følgeforespørsel" unfollow: "Avfølg" followRequestPending: "Venter på godkjenning" enterEmoji: "Skriv inn en emoji" +renote: "Renote" +renoted: "Renotet." +cantRenote: "Dette innlegget kan ikke renotes." +cantReRenote: "En Renote kan ikke renotes." quote: "Sitat" -pinned: "Fest" +inChannelRenote: "Renote kun for kanal" +inChannelQuote: "Sitat kun for kanal" +pinnedNote: "Festet Note" +pinned: "Fest til profil" you: "Du" clickToShow: "Klikk for å vise" add: "Legg til" @@ -89,18 +104,21 @@ reaction: "Reaksjon" reactions: "Reaksjoner" reactionSetting: "Reaksjoner som vises i reaksjonsvelgeren" reactionSettingDescription2: "Dra for å endre rekkefølgen, klikk for å slette, trykk \"+\" for å legge til." +rememberNoteVisibility: "Husk innstillingene for synlighet av Notes" attachCancel: "Fjern vedlegg" enterFileName: "Skriv inn filnavn" mute: "Skjul" unmute: "Vis" +renoteMute: "Skjul Renotes" +renoteUnmute: "Vis Renotes" block: "Blokker" unblock: "Opphev blokkering" suspend: "Suspender" -blockConfirm: "Blokker?" +blockConfirm: "Er du sikker på at du vil blokke denne kontoen?" unblockConfirm: "Er du sikker på at du vil oppheve blokkeringen av denne kontoen?" suspendConfirm: "Er du sikker på at du vil suspendere denne kontoen?" -selectList: "Velg liste" -selectChannel: "Velg kanal" +selectList: "Velg en liste" +selectChannel: "Velg en kanal" selectAntenna: "Velg en antenne" selectWidget: "Velg en widget" editWidgets: "Rediger widgeter" @@ -113,6 +131,7 @@ flagAsBot: "Merk denne kontoen som en bot" flagAsBotDescription: "Aktiver dette alternativet hvis denne kontoen styres av et program. Hvis det er aktivert, vil det fungere som et flagg for andre utviklere for å forhindre endeløse interaksjonskjeder med andre roboter og justere Misskeys interne systemer til å behandle denne kontoen som en bot." flagAsCat: "Merk denne kontoen som en katt" flagAsCatDescription: "Aktiver dette alternativet for å merke denne kontoen som en katt." +flagShowTimelineReplies: "Vis svar i tidslinje" addAccount: "Legg til konto" reloadAccountsList: "Last inn kontoliste på nytt" loginFailed: "Kunne ikke logge inn" @@ -120,23 +139,30 @@ general: "Generelt" searchWith: "Søk: {q}" youHaveNoLists: "Du har ingen lister" followConfirm: "Er du sikker på at du vil følge {name}?" -selectUser: "Velg bruker" +host: "Vert" +selectUser: "Velg en bruker" recipient: "Mottaker" annotation: "Kommentarer" federation: "Føderasjon" -instances: "Server" +instances: "Servere" registeredAt: "Registrerte seg" +latestRequestReceivedAt: "Siste forespørsel mottatt" +latestStatus: "Siste status" +charts: "Diagrammer" perHour: "Per time" perDay: "Per dag" stopActivityDelivery: "Slutt å sende aktiviteter" blockThisInstance: "Blokker denne serveren" +operations: "Operasjoner" software: "Programvare" version: "Versjon" +metadata: "Metadata" withNFiles: "{n} fil(er)" network: "Nettverk" +instanceInfo: "Serverinformasjon" statistics: "Statistikk" clearQueue: "Tøm kø" -clearQueueConfirmTitle: "Vil du tømme kø?" +clearQueueConfirmTitle: "Er du sikker på at du vil tømme køen?" blockedInstances: "Blokkerte severe" blockedInstancesDescription: "Skriv opp vertsnavnene til serverne du vil blokkere, atskilt med linjeskift. Serverne i listen vil ikke lenger kunne kommunisere med denne serveren." muteAndBlock: "Skjul og blokker" @@ -144,9 +170,13 @@ mutedUsers: "Skjulte brukere" blockedUsers: "Blokkerte brukere" noUsers: "Det er ingen brukere" editProfile: "Rediger profil" +noteDeleteConfirm: "Er du sikker på at du vil slette denne Noten?" pinLimitExceeded: "Du kan ikke feste flere." +intro: "Installasjonen av Misskey er ferdig! Vennligst opprett en administratorkonto." done: "Ferdig" -noCustomEmojis: "Ingen emoji" +default: "Standard" +defaultValueIs: "Standard: {value}" +noCustomEmojis: "Det er ingen emoji" noJobs: "Det er ingen jobber" blocked: "Blokkert" suspended: "Suspendert" @@ -154,54 +184,72 @@ all: "Alle" notResponding: "Svarer ikke" changePassword: "Endre passord" security: "Sikkerhet" +retypedNotMatch: "Inngangene stemmer ikke overens." +currentPassword: "Nåværende passord" newPassword: "Nytt passord" newPasswordRetype: "Nytt passord (gjenta)" attachFile: "Legg ved filer" more: "Mer!" +noSuchUser: "Bruker ikke funnet" announcements: "Kunngjøringer" remove: "Slett" -removed: "Slettet" +removed: "Vellykket slettet" removeAreYouSure: "Er du sikker på at du vil fjerne \"{x}\"?" deleteAreYouSure: "Er du sikker på at du vil slette \"{x}\"?" saved: "Lagret" upload: "Laste opp" +keepOriginalUploading: "Behold originalbildet" +fromUrl: "Fra URL" +uploadFromUrl: "Last opp fra en URL" +uploadFromUrlDescription: "URL til filen du vil laste opp" explore: "Utforsk" messageRead: "Lest" -agree: "Jeg godtar" +nUsersRead: "lest av {n}" +agreeTo: "Jeg godtar {0}" +agree: "Godta" +agreeBelow: "Jeg godtar følgende" +basicNotesBeforeCreateAccount: "Viktige merknader" termsOfService: "Vilkår for bruk" home: "Hjem" activity: "Aktivitet" images: "Bilder" -image: "Bilder" +image: "Bilde" birthday: "Bursdag" yearsOld: "{age} år gammel" +theme: "Temaer" light: "Lys" dark: "Mørk" +lightThemes: "Lyse temaer" +darkThemes: "Mørke temaer" +syncDeviceDarkMode: "Synkroniser mørkmodus med enhetens innstillinger" fileName: "Filnavn" -selectFile: "Velg fil" -selectFiles: "Velg fil" -selectFolder: "Velg mappe" -selectFolders: "Velg mappe" +selectFile: "Velg en fil" +selectFiles: "Velg filer" +selectFolder: "Velg en mappe" +selectFolders: "Velg mapper" renameFile: "Endre filnavn" folderName: "Mappenavn" -createFolder: "Opprett mappe" +createFolder: "Opprett en mappe" renameFolder: "Endre mappenavn" -deleteFolder: "Slett mappe" -addFile: "Legg til fil" +deleteFolder: "Slett denne mappen" +addFile: "Legg til en fil" emptyFolder: "Denne mappen er tom" unableToDelete: "Kan ikke slette" +inputNewFileName: "Skriv inn et nytt filnavn" +inputNewDescription: "Skriv inn ny bildetekst" +inputNewFolderName: "Skriv inn et nytt mappenavn" circularReferenceFolder: "Målmappen er en undermappe til mappen du ønsker å flytte." hasChildFilesOrFolders: "Siden denne mappen ikke er tom, kan den ikke slettes." copyUrl: "Kopier URL" rename: "Endre navn" avatar: "Avatar" banner: "Banner" -doNothing: "Gjør ingenting" +doNothing: "Ignorer" accept: "Tillatt" reject: "Avslå" instanceName: "Servernavn" instanceDescription: "Serverbeskrivelse" -thisYear: "I år" +thisYear: "År" thisMonth: "Måned" today: "I dag" dayX: "{day}" @@ -216,23 +264,35 @@ registration: "Registrer" enableRegistration: "Aktiver registrering av nye brukere" invite: "Inviter" basicInfo: "Grunnleggende informasjon" -pinnedUsers: "Festete brukrere" +pinnedUsers: "Festede brukrere" pinnedUsersDescription: "Liste over brukernavn atskilt med linjeskift som skal festes i \"Utforsk\" fanen." -pinnedPages: "Festete sider" +pinnedPages: "Festede sider" +pinnedNotes: "Festet Note" hcaptcha: "hCaptcha" enableHcaptcha: "Aktiver hCaptcha" recaptcha: "reCAPTCHA" enableRecaptcha: "Aktiver reCAPTCHA" turnstile: "Turnstile" enableTurnstile: "Aktiver Turnstile" +antennas: "Antenner" name: "Navn" +antennaSource: "Antennekilde" +notifyAntenna: "Varsle om nye Notes" +withFileAntenna: "Bare Notes med filer" +notesAndReplies: "Notes og svar" popularUsers: "Populære brukere" exploreUsersCount: "Det finnes {count} brukere" +exploreFediverse: "Utforsk Fediverse" userList: "Lister" -about: "Infomasjon" +about: "Informasjon" aboutMisskey: "Om Misskey" +newPasswordIs: "Det nye passordet er \"{password}\"." share: "Del" +notFound: "Ikke funnet" +markAsReadAllNotifications: "Merk alle varsler som lest" +markAsReadAllUnreadNotes: "Merk alle Notes som lest" help: "Hjelp" +inputMessageHere: "Skriv inn melding her" close: "Lukk" invites: "Inviter" members: "Medlemmer" @@ -240,30 +300,46 @@ title: "Tittel" text: "Tekst" next: "Neste" retype: "Gjenta" +quoteAttached: "Sitat" +noMessagesYet: "Ingen meldinger ennå" +newMessageExists: "Det er nye meldinger" +onlyOneFileCanBeAttached: "Du kan bare legge ved én fil i en melding" invitations: "Inviter" available: "Tilgjengelig" unavailable: "Utilgjengelig" tooShort: "For kort" tooLong: "For langt" +weakPassword: "Svakt passord" +normalPassword: "Gjennomsnittlig passord" +strongPassword: "Sterkt passord" +signinWith: "Logg inn med {x}" +signinFailed: "Kunne ikke logge inn. Det oppgitte brukernavnet eller passordet er feil." or: "eller" language: "Språk" aboutX: "Om {x}" -category: "Kategorier" +category: "Kategori" createAccount: "Opprett konto" +openImageInNewTab: "Åpne bilder i ny fane" +clientSettings: "Klientinnstillinger" +accountSettings: "Kontoinnstillinger" objectStorageRegion: "Region" objectStorageUseSSL: "Bruk SSL" objectStorageUseProxy: "Bruk Proxy" deleteAll: "Slett alt" +newNoteRecived: "Det er nye Notes" listen: "Lytt" none: "Ingen" +volume: "Volum" chooseEmoji: "Velg emoji" recentUsed: "Sist brukte" install: "Installer" +uninstall: "Avinstaller" nothing: "Ingenting" deleteAllFiles: "Slett alle filer" -deleteAllFilesConfirm: "Vil du slette alle filer?" +deleteAllFilesConfirm: "Er du sikker på at du vil slette alle filer?" +userSuspended: "Denne brukeren har blitt suspendert." accountDeleted: "Kontoen blir slettet" -accountDeletedDescription: "Denne kontoen blir slettet" +accountDeletedDescription: "Denne kontoen har blitt slettet." menu: "Meny" poll: "Avstemning" description: "Beskrivelse" @@ -274,6 +350,7 @@ small: "Liten" notificationType: "Varseltype" edit: "Rediger" email: "E-post" +smtpHost: "Vert" smtpUser: "Brukernavn" smtpPass: "Passord" userSaysSomething: "{name} sa noe" @@ -289,16 +366,25 @@ reportAbuse: "Rappoter" send: "Send" openInNewTab: "Åpne i ny fane" waitingFor: "Venter på {x}" +random: "Tilfeldig" system: "System" +desktop: "Skrivebord" +i18nInfo: "Misskey oversettes til flere språk av frivillige. Du kan hjelpe til på {link}." followingCount: "Følger" followersCount: "Følgere" yes: "Ja" no: "Nei" +contact: "Kontakt" +developer: "Utvikler" +makeExplorable: "Gjør konto synlig i \"Utforsk\"" +makeExplorableDescription: "Hvis du slår av dette, vises ikke kontoen din i \"Utforsk\" delen." left: "Venstre" +nNotes: "{n} Notes" saveAs: "Lagre som" value: "Verdi" deleteConfirm: "Vil du slette?" invalidValue: "Verdien er ugyldig." +closeAccount: "Avslutt konto" emailNotification: "E-postvarsler" inChannelSearch: "Søk i kanal" clear: "Tøm" @@ -312,17 +398,23 @@ accounts: "Kontoer" switch: "Bytt" gallery: "Galleri" ads: "Annonser" +memo: "Notat" high: "Høy" low: "Lav" -sent: "Send" +sent: "Sendt" +received: "Mottatt" learnMore: "Les mer" +misskeyUpdated: "Misskey har blitt oppdatert!" translate: "Oversett" +translatedFrom: "Oversatt fra {x}" unread: "Ulest" manageAccounts: "Administrer konto" classic: "Klassisk" muteThread: "Skjul denne tråden" unmuteThread: "Vis denne tråden" +continueThread: "Vis fortsettelse av tråden" hide: "Skjul" +smartphone: "Smarttelefon" tablet: "Nettbrett" auto: "Automatisk" size: "Størrelse" @@ -338,10 +430,10 @@ check: "Sjekk" deleteAccount: "Slett konto" document: "Dokumenter" logoutConfirm: "Vil du logge ut?" -pleaseSelect: "Vennligst velg" +pleaseSelect: "Velg et alternativ" type: "Type" beta: "Beta" -account: "Kontoer" +account: "Konto" move: "Flytt" pushNotification: "Push-varsler" tools: "Verktøy" @@ -357,6 +449,7 @@ role: "Rolle" color: "Farge" youCannotCreateAnymore: "Du kan ikke opprette flere." cannotPerformTemporary: "Midlertidig utilgjengelig" +achievements: "Prestasjoner" thisPostMayBeAnnoyingCancel: "Avbryt" exploreOtherServers: "Utforsk andre severe" letsLookAtTimeline: "La oss se på tidslinje" @@ -372,6 +465,26 @@ _initialAccountSetting: theseSettingsCanEditLater: "Du kan endre disse innstillingene senere." _achievements: _types: + _notes10: + title: "Noen Notes" + _notes100: + title: "Mange Notes" + _notes500: + title: "Dekket i Notes" + _notes1000: + title: "Et fjell av Notes" + _notes5000: + title: "Overfylte Notes" + _notes10000: + title: "Super Notes" + _notes20000: + title: "Trenger... mer... Notes..." + _notes30000: + title: "Notes Notes Notes!" + _notes40000: + title: "Note fabrikk" + _notes50000: + title: "Planet av Notes" _notes100000: flavor: "Du har jammen mye å si." _noteFavorited1: @@ -400,7 +513,7 @@ _achievements: _justPlainLucky: title: "Rett og slett heldig" _setNameToSyuilo: - description: "Du har satt navnet ditt til \"syuilo\"" + description: "Du satte navnet ditt til \"syuilo\"" _passedSinceAccountCreated1: title: "Ett års jubileum" description: "Det har gått ett år siden kontoen din ble opprettet" @@ -468,15 +581,17 @@ _theme: key: "Nøkkel" keys: link: "Lenke" + renote: "Renote" _sfx: + note: "Notes" notification: "Varsler" _ago: future: "Fremitid" justNow: "Akkurat nå" - secondsAgo: "{n} sekunder siden" - minutesAgo: "{n} minutter siden" - hoursAgo: "{n} timer siden" - daysAgo: "{n} dager siden" + secondsAgo: "{n}s siden" + minutesAgo: "{n}m siden" + hoursAgo: "{n}t siden" + daysAgo: "{n}d siden" weeksAgo: "{n} uker siden" monthsAgo: "{n} måneder siden" yearsAgo: "{n} år siden" @@ -488,6 +603,7 @@ _time: day: "Dager" _timelineTutorial: title: "Hvordan bruke Misskey" + step2_2: "Hva med å skrive en selvpresentasjon, eller bare \"Hei {name}!\" hvis du ikke har lyst?" _2fa: renewTOTPCancel: "Avbryt" _weekday: @@ -500,6 +616,7 @@ _weekday: saturday: "Lørdag" _widgets: profile: "Profil" + instanceInfo: "Serverinformasjon" notifications: "Varsler" timeline: "Tidslinje" calendar: "Kalender" @@ -535,6 +652,7 @@ _postForm: _profile: name: "Navn" username: "Brukernavn" + description: "Biografi" metadataContent: "Innhold" _exportOrImport: followingList: "Følg" @@ -576,13 +694,17 @@ _pages: button: "Knapp" _notification: youWereFollowed: "fulgte deg" + unreadAntennaNote: "Antenne {name}" + achievementEarned: "Prestasjon låst opp" _types: - follow: "Følg" + follow: "Nye følgere" reply: "Svar" - quote: "Sitat" - reaction: "Reaksjon" + renote: "Renotes" + quote: "Sitater" + reaction: "Reaksjoner" _actions: reply: "Svar" + renote: "Renote" _deck: swapLeft: "Flytt til venstre" swapRight: "Flytt til høyre" @@ -594,6 +716,7 @@ _deck: _columns: notifications: "Varsler" tl: "Tidslinje" + antenna: "Antenner" list: "Lister" channel: "Kanaler" direct: "Direkte" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 8c79a4502d..e92449fdb9 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -2,7 +2,7 @@ _lang_: "Русский" headlineMisskey: "Сеть, сплетённая из заметок" introMisskey: "Добро пожаловать! Misskey — это децентрализованный сервис микроблогов с открытым исходным кодом.\nПишите «заметки» — делитесь со всеми происходящим вокруг или рассказывайте о себе 📡\nСтавьте «реакции» — выражайте свои чувства и эмоции от заметок других 👍\nОткройте для себя новый мир 🚀" -poweredByMisskeyDescription: "{name} – один из инстансов (также называемый экземпляром Misskey), использующий платформу с открытым исходным кодом Misskey." +poweredByMisskeyDescription: "{name} – сервис на платформе с открытым исходным кодом Misskey, называемый инстансом Misskey." monthAndDay: "{day}.{month}" search: "Поиск" notifications: "Уведомления" @@ -649,8 +649,8 @@ abuseReported: "Жалоба отправлена. Большое спасибо reporter: "Сообщивший" reporteeOrigin: "О ком сообщено" reporterOrigin: "Кто сообщил" -forwardReport: "Перенаправление отчета на инстант." -forwardReportIsAnonymous: "Удаленный инстант не сможет увидеть вашу информацию и будет отображаться как анонимная системная учетная запись." +forwardReport: "Отправить жалобу на инстанс автора." +forwardReportIsAnonymous: "Жалоба на удалённый инстанс будет отправлена анонимно. Вместо ваших данных у получателя будет отображена системная учётная запись." send: "Отправить" abuseMarkAsResolved: "Отметить жалобу как решённую" openInNewTab: "Открыть в новой вкладке" @@ -823,6 +823,7 @@ translatedFrom: "Перевод. Язык оригинала — {x}" accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи" usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже." aiChanMode: "Режим Ай" +devMode: "Режим разработчика" keepCw: "Сохраняйте Предупреждения о содержимом" pubSub: "Учётные записи Pub/Sub" lastCommunication: "Последнее сообщение" @@ -914,8 +915,8 @@ cannotUploadBecauseInappropriate: "Файл не может быть загру cannotUploadBecauseNoFreeSpace: "Файл не может быть загружен, так как не осталось места на диске" cannotUploadBecauseExceedsFileSizeLimit: "Файл не может быть загружен, так как он превышает лимит размера файла." beta: "Бета" -enableAutoSensitive: "Автоматическое определение NSFW" -enableAutoSensitiveDescription: "Если доступно, используйте машинное обучение для автоматической установки флага NSFW на носителе. Даже если эта функция отключена, она может быть установлена ​​автоматически в зависимости от инстанта." +enableAutoSensitive: "Автоматическое определение содержимого не для всех" +enableAutoSensitiveDescription: "Позволяет определять наличие содержимого не для всех при помощи искусственного интеллекта там, где это возможно. Даже если эту опцию отключить, она всё равно может быть включена на весь инстанс." activeEmailValidationDescription: "Если включено, будет проводиться более строгая проверка адреса электронной почты, в том числе на то, что он действительный и не временный. Если же отключено, то проверяется только корректность написания адреса." navbar: "Панель навигации" shuffle: "Перемешать" @@ -1006,6 +1007,7 @@ noteIdOrUrl: "ID или ссылка на заметку" video: "Видео" videos: "Видео" dataSaver: "Экономия трафика" +renotesList: "Репосты" horizontal: "Сбоку" youFollowing: "Подписки" options: "Настройки ролей" @@ -1180,6 +1182,9 @@ _achievements: _client30min: title: "Перерыв на обед" description: "Прошло 30 минут с момента запуска клиента" + _client60min: + title: "Не наглядеться на Misskey" + description: "Misskey был открыт 60 минут подряд" _noteDeletedWithin1min: title: "Ой, нет!" description: "Заметка удалена через минуту после публикации" @@ -1282,6 +1287,7 @@ _role: canInvite: "Может создавать пригласительные коды" canManageCustomEmojis: "Управлять пользовательскими эмодзи" driveCapacity: "Доступное пространство на «диске»" + alwaysMarkNsfw: "Всегда отмечать файлы как «не для всех»" pinMax: "Доступное количество закреплённых заметок" antennaMax: "Доступное количество антенн" wordMuteMax: "Доступное количество знаков в списке скрытия слов" @@ -1309,7 +1315,7 @@ _sensitiveMediaDetection: description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно." sensitivity: "Чувствительность обнаружения" sensitivityDescription: "Более низкая чувствительность уменьшает количество ложных срабатываний (false positives). Повышение чувствительности уменьшает утечку при обнаружении (ложноотрицательные результаты)." - setSensitiveFlagAutomatically: "Установить флаг NSFW" + setSensitiveFlagAutomatically: "Обозначить как не для всех" setSensitiveFlagAutomaticallyDescription: "Даже если этот параметр отключен, результат оценки сохраняется внутри системы." analyzeVideos: "Анализировать видео?" analyzeVideosDescription: "Анализируйте видео в дополнение к неподвижным изображениям. Нагрузка на сервер немного увеличивается." @@ -1528,6 +1534,16 @@ _time: minute: "мин" hour: "ч" day: "сут" +_timelineTutorial: + title: "Как пользоваться Misskey" + step1_1: "Это лицо Misskey, так называемая лента. Ваш инстанс, {name}, покажет тут все опубликованные на нём заметки в хронологическом порядке." + step1_2: "Здесь есть несколько лент. К примеру «персональная» лента отображает заметки тех, на кого вы подписаны. А «местная» — заметки тех, кого приютил {name}." + step2_1: "Что ж, теперь самое время опубликовать заметку. Если нажать вверху страницы на изображение карандаша, появится форма для текста." + step2_2: "Почему бы не написать немного о себе? Ну, или хотя бы «Привет, {name}»?" + step3_1: "Справились с первой заметкой?" + step3_2: "Отлично, теперь она должна появиться в вашей ленте." + step4_1: "А ещё здесь можно делиться своими реакциями на заметки." + step4_2: "Отмечайте реакции, нажимая на символ «+» под заметкой и выбирая значок по душе." _2fa: alreadyRegistered: "Двухфакторная аутентификация уже настроена." registerTOTP: "Начните настраивать приложение-аутентификатор" @@ -1868,6 +1884,9 @@ _deck: _dialog: charactersExceeded: "Превышено максимальное количество символов! У вас {current} / из {max}" charactersBelow: "Это ниже минимального количества символов! У вас {current} / из {min}" +_disabledTimeline: + title: "Лента отключена" + description: "Ваша текущая роль не позволяет пользоваться этой лентой." _webhookSettings: name: "Название" active: "Вкл." diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index f7d5ab0e6c..9c278ea751 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -52,6 +52,8 @@ addToList: "添加至列表" sendMessage: "发送" copyRSS: "复制RSS" copyUsername: "复制用户名" +copyUserId: "复制用户ID" +copyNoteId: "复制帖子ID" searchUser: "搜索用户" reply: "回复" loadMore: "查看更多" @@ -790,6 +792,7 @@ noMaintainerInformationWarning: "管理人员信息未设置。" noBotProtectionWarning: "Bot保护未设置。" configure: "设置" postToGallery: "发送到图库" +postToHashtag: "投稿到这个标签" gallery: "图库" recentPosts: "最新发布" popularPosts: "热门投稿" @@ -823,6 +826,7 @@ translatedFrom: "从 {x} 翻译" accountDeletionInProgress: "正在删除账户" usernameInfo: "在服务器上唯一标识您的帐户的名称。您可以使用字母 (a ~ z, A ~ Z)、数字 (0 ~ 9) 和下划线 (_)。用户名以后不能更改。" aiChanMode: "小蓝模式" +devMode: "开发者模式" keepCw: "回复时维持隐藏内容" pubSub: "Pub/Sub账户" lastCommunication: "最近通信" @@ -832,6 +836,8 @@ breakFollow: "移除关注者" breakFollowConfirm: "你想取消关注吗?" itsOn: "已开启" itsOff: "已关闭" +on: "开启" +off: "关闭" emailRequiredForSignup: "注册账户需要电子邮件地址" unread: "未读" filter: "筛选" @@ -986,6 +992,8 @@ cannotBeChangedLater: "之后不能再更改。" reactionAcceptance: "接受表情回应" likeOnly: "仅点赞" likeOnlyForRemote: "远程仅点赞" +nonSensitiveOnly: "仅限非敏感内容" +nonSensitiveOnlyForLocalLikeOnlyForRemote: "仅限非敏感内容(远程仅点赞)" rolesAssignedToMe: "指派给自己的角色" resetPasswordConfirm: "确定重置密码?" sensitiveWords: "敏感词" @@ -1043,6 +1051,16 @@ preventAiLearning: "拒绝接受生成式AI的学习" preventAiLearningDescription: "要求文章生成AI或图像生成AI不能够以发布的帖子和图像等内容作为学习对象。这是通过在HTML响应中包含noai标志来实现的,这不能完全阻止AI学习你的发布内容,并不是所有AI都会遵守这类请求。" options: "选项" specifyUser: "用户指定" +failedToPreviewUrl: "无法预览" +update: "更新" +rolesThatCanBeUsedThisEmojiAsReaction: "可以使用表情作为回应的角色" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "在没有指定角色的情况下,任何人都可以使用表情作为回应。" +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "角色必须是公开的。" +cancelReactionConfirm: "要取消回应吗?" +changeReactionConfirm: "要更改回应吗?" +later: "一会再说" +goToMisskey: "去往Misskey" +installed: "已安装" _initialAccountSetting: accountCreated: "账户创建完成了!" letsStartAccountSetup: "来进行帐户的初始设置吧。" @@ -1057,6 +1075,7 @@ _initialAccountSetting: haveFun: "希望{name}在这里玩得开心!" ifYouNeedLearnMore: "关于{name}(Misskey)的使用方法,详见{link}。" skipAreYouSure: "要跳过初始设置吗?" + laterAreYouSure: "要稍后再进行初始设定吗?" _serverRules: description: "在新用户注册前显示服务器的简单规则。推荐显示服务条款的主要内容。" _accountMigration: diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 6044a6532f..04c14b2c65 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1055,6 +1055,11 @@ failedToPreviewUrl: "無法預覽" update: "更新" rolesThatCanBeUsedThisEmojiAsReaction: "可以當成反應使用的角色" rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "如果是未指定角色的情況,則任何人都可以被當成反應來使用。" +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "角色必須是公開的角色。" +cancelReactionConfirm: "要取消做出的反應嗎?" +changeReactionConfirm: "要變更做出的反應嗎?" +later: "稍後再說" +goToMisskey: "往Misskey" _initialAccountSetting: accountCreated: "帳戶已建立完成!" letsStartAccountSetup: "來進行帳戶的初始設定吧。" @@ -1069,6 +1074,7 @@ _initialAccountSetting: haveFun: "盡情享受{name}吧!" ifYouNeedLearnMore: "關於如何使用{name}(Misskey)的詳細資訊,請見{link}。" skipAreYouSure: "要略過初始設定嗎?" + laterAreYouSure: "稍後再重新進行初始設定嗎?" _serverRules: description: "設定伺服器的簡要規則,在新的註冊之前顯示。建議的內容是使用條款的摘要。" _accountMigration: diff --git a/package.json b/package.json index 81522f1e5c..81029514c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "13.13.0-beta.4", + "version": "13.13.0-beta.7", "codename": "nasubi", "repository": { "type": "git", @@ -51,16 +51,16 @@ "gulp-replace": "1.1.4", "gulp-terser": "2.1.0", "js-yaml": "4.1.0", - "typescript": "5.0.4" + "typescript": "5.1.3" }, "devDependencies": { "@types/gulp": "4.0.10", "@types/gulp-rename": "2.0.1", - "@typescript-eslint/eslint-plugin": "5.59.5", - "@typescript-eslint/parser": "5.59.5", + "@typescript-eslint/eslint-plugin": "5.59.8", + "@typescript-eslint/parser": "5.59.8", "cross-env": "7.0.3", "cypress": "12.13.0", - "eslint": "8.40.0", + "eslint": "8.41.0", "start-server-and-test": "2.0.0" }, "optionalDependencies": { diff --git a/packages/backend/package.json b/packages/backend/package.json index 95330b2e43..0b3b1716e9 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -60,27 +60,27 @@ "@discordapp/twemoji": "14.1.2", "@fastify/accepts": "4.1.0", "@fastify/cookie": "8.3.0", - "@fastify/cors": "8.2.1", + "@fastify/cors": "8.3.0", "@fastify/http-proxy": "9.1.0", "@fastify/multipart": "7.6.0", - "@fastify/static": "6.10.1", + "@fastify/static": "6.10.2", "@fastify/view": "7.4.1", "@nestjs/common": "9.4.2", "@nestjs/core": "9.4.2", "@nestjs/testing": "9.4.2", "@peertube/http-signature": "1.7.0", - "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/fake-timers": "10.2.0", "@swc/cli": "0.1.62", - "@swc/core": "1.3.59", + "@swc/core": "1.3.61", "accepts": "1.3.8", "ajv": "8.12.0", "archiver": "5.3.1", "autwh": "0.1.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", - "bullmq": "3.14.1", + "bullmq": "3.15.0", "cacheable-lookup": "6.1.0", - "cbor": "8.1.0", + "cbor": "9.0.0", "chalk": "5.2.0", "chalk-template": "0.4.0", "chokidar": "3.5.3", @@ -96,24 +96,24 @@ "fluent-ffmpeg": "2.1.2", "form-data": "4.0.0", "got": "12.6.0", - "happy-dom": "9.19.2", + "happy-dom": "9.20.3", "hpagent": "1.2.0", "ioredis": "5.3.2", "ip-cidr": "3.1.0", "is-svg": "4.3.2", "js-yaml": "4.1.0", - "jsdom": "21.1.1", + "jsdom": "22.1.0", "json5": "2.2.3", - "jsonld": "8.1.1", + "jsonld": "8.2.0", "jsrsasign": "10.8.6", - "meilisearch": "0.32.4", + "meilisearch": "0.32.5", "mfm-js": "0.23.3", "mime-types": "2.1.35", "misskey-js": "workspace:*", "ms": "3.0.0-canary.1", "nested-property": "4.0.0", "node-fetch": "3.3.1", - "nodemailer": "6.9.2", + "nodemailer": "6.9.3", "nsfwjs": "2.4.2", "oauth": "0.10.0", "os-utils": "0.0.14", @@ -129,7 +129,7 @@ "qrcode": "1.5.3", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.18.0", + "re2": "1.19.0", "redis-lock": "0.1.4", "reflect-metadata": "0.1.13", "rename": "1.0.4", @@ -146,16 +146,16 @@ "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "summaly": "github:misskey-dev/summaly", - "systeminformation": "5.17.12", + "systeminformation": "5.17.16", "tinycolor2": "1.6.0", "tmp": "0.2.1", "tsc-alias": "1.8.6", "tsconfig-paths": "4.2.0", "twemoji-parser": "14.0.0", "typeorm": "0.3.16", - "typescript": "5.0.4", + "typescript": "5.1.3", "ulid": "2.3.0", - "unzipper": "0.10.11", + "unzipper": "0.10.14", "uuid": "9.0.0", "vary": "1.1.2", "web-push": "3.6.1", @@ -173,13 +173,13 @@ "@types/content-disposition": "0.5.5", "@types/escape-regexp": "0.0.1", "@types/fluent-ffmpeg": "2.1.21", - "@types/jest": "29.5.1", + "@types/jest": "29.5.2", "@types/js-yaml": "4.0.5", "@types/jsdom": "21.1.1", "@types/jsonld": "1.5.8", "@types/jsrsasign": "10.5.8", "@types/mime-types": "2.1.1", - "@types/node": "20.2.3", + "@types/node": "20.2.5", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.8", "@types/oauth": "0.9.1", @@ -203,11 +203,11 @@ "@types/web-push": "3.3.2", "@types/websocket": "1.0.5", "@types/ws": "8.5.4", - "@typescript-eslint/eslint-plugin": "5.59.5", - "@typescript-eslint/parser": "5.59.5", + "@typescript-eslint/eslint-plugin": "5.59.8", + "@typescript-eslint/parser": "5.59.8", "aws-sdk-client-mock": "2.1.1", "cross-env": "7.0.3", - "eslint": "8.40.0", + "eslint": "8.41.0", "eslint-plugin-import": "2.27.5", "execa": "6.1.0", "jest": "29.5.0", diff --git a/packages/backend/src/server/api/StreamingApiServerService.ts b/packages/backend/src/server/api/StreamingApiServerService.ts index fdda581ada..893dfe956e 100644 --- a/packages/backend/src/server/api/StreamingApiServerService.ts +++ b/packages/backend/src/server/api/StreamingApiServerService.ts @@ -19,6 +19,8 @@ import type * as http from 'node:http'; @Injectable() export class StreamingApiServerService { #wss: WebSocket.WebSocketServer; + #connections = new Map(); + #cleanConnectionsIntervalId: NodeJS.Timeout | null = null; constructor( @Inject(DI.config) @@ -109,7 +111,9 @@ export class StreamingApiServerService { await stream.listen(ev, connection); - const intervalId = user ? setInterval(() => { + this.#connections.set(connection, Date.now()); + + const userUpdateIntervalId = user ? setInterval(() => { this.usersRepository.update(user.id, { lastActiveDate: new Date(), }); @@ -124,19 +128,34 @@ export class StreamingApiServerService { ev.removeAllListeners(); stream.dispose(); this.redisForSub.off('message', onRedisMessage); - if (intervalId) clearInterval(intervalId); + if (userUpdateIntervalId) clearInterval(userUpdateIntervalId); }); connection.on('message', async (data) => { + this.#connections.set(connection, Date.now()); if (data.toString() === 'ping') { connection.send('pong'); } }); }); + + this.#cleanConnectionsIntervalId = setInterval(() => { + const now = Date.now(); + for (const [connection, lastActive] of this.#connections.entries()) { + if (now - lastActive > 1000 * 60 * 5) { + connection.terminate(); + this.#connections.delete(connection); + } + } + }, 1000 * 60 * 5); } @bindThis public detach(): Promise { + if (this.#cleanConnectionsIntervalId) { + clearInterval(this.#cleanConnectionsIntervalId); + this.#cleanConnectionsIntervalId = null; + } return new Promise((resolve) => { this.#wss.close(() => resolve()); }); diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index dca0f443b7..e756a9b510 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -113,6 +113,7 @@ export default class extends Endpoint { } this.antennasRepository.update(antenna.id, { + isActive: true, lastUsedAt: new Date(), }); diff --git a/packages/backend/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts index cb2e661bfb..05842460cf 100644 --- a/packages/backend/src/server/api/endpoints/auth/accept.ts +++ b/packages/backend/src/server/api/endpoints/auth/accept.ts @@ -55,7 +55,6 @@ export default class extends Endpoint { throw new ApiError(meta.errors.noSuchSession); } - // Generate access token const accessToken = secureRndstr(32, true); // Fetch exist access token @@ -65,7 +64,6 @@ export default class extends Endpoint { }); if (exist == null) { - // Lookup app const app = await this.appsRepository.findOneByOrFail({ id: session.appId }); // Generate Hash @@ -75,7 +73,6 @@ export default class extends Endpoint { const now = new Date(); - // Insert access token doc await this.accessTokensRepository.insert({ id: this.idService.genId(), createdAt: now, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts index ad33398da6..e8985a9cd8 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -1,6 +1,6 @@ import { promisify } from 'node:util'; import bcrypt from 'bcryptjs'; -import * as cbor from 'cbor'; +import cbor from 'cbor'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; diff --git a/packages/backend/src/server/api/endpoints/i/apps.ts b/packages/backend/src/server/api/endpoints/i/apps.ts index 3361e5a4d3..48fb03a8af 100644 --- a/packages/backend/src/server/api/endpoints/i/apps.ts +++ b/packages/backend/src/server/api/endpoints/i/apps.ts @@ -26,7 +26,8 @@ export default class extends Endpoint { ) { super(meta, paramDef, async (ps, me) => { const query = this.accessTokensRepository.createQueryBuilder('token') - .where('token.userId = :userId', { userId: me.id }); + .where('token.userId = :userId', { userId: me.id }) + .leftJoinAndSelect('token.app', 'app'); switch (ps.sort) { case '+createdAt': query.orderBy('token.createdAt', 'DESC'); break; @@ -40,7 +41,7 @@ export default class extends Endpoint { return await Promise.all(tokens.map(token => ({ id: token.id, - name: token.name, + name: token.name ?? token.app?.name, createdAt: token.createdAt, lastUsedAt: token.lastUsedAt, permission: token.permission, diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts index 5f60b2444b..fdb36e745a 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications.ts @@ -91,18 +91,18 @@ export default class extends Endpoint { const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][]; const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][]; - const limit = ps.limit + (ps.untilId ? 1 : 0); // untilIdに指定したものも含まれるため+1 + const limit = ps.limit + (ps.untilId ? 1 : 0) + (ps.sinceId ? 1 : 0); // untilIdに指定したものも含まれるため+1 const notificationsRes = await this.redisClient.xrevrange( `notificationTimeline:${me.id}`, ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+', - '-', + ps.sinceId ? this.idService.parse(ps.sinceId).date.getTime() : '-', 'COUNT', limit); if (notificationsRes.length === 0) { return []; } - let notifications = notificationsRes.map(x => JSON.parse(x[1][1])).filter(x => x.id !== ps.untilId) as Notification[]; + let notifications = notificationsRes.map(x => JSON.parse(x[1][1])).filter(x => x.id !== ps.untilId && x !== ps.sinceId) as Notification[]; if (includeTypes && includeTypes.length > 0) { notifications = notifications.filter(notification => includeTypes.includes(notification.type)); diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index d2a30ff926..f7001ea1cf 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -1,5 +1,6 @@ import { IsNull, LessThanOrEqual, MoreThan } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; +import * as JSON5 from 'json5'; import type { AdsRepository, UsersRepository } from '@/models/index.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -291,8 +292,9 @@ export default class extends Endpoint { iconUrl: instance.iconUrl, backgroundImageUrl: instance.backgroundImageUrl, logoImageUrl: instance.logoImageUrl, - defaultLightTheme: instance.defaultLightTheme, - defaultDarkTheme: instance.defaultDarkTheme, + // クライアントの手間を減らすためあらかじめJSONに変換しておく + defaultLightTheme: instance.defaultLightTheme ? JSON.stringify(JSON5.parse(instance.defaultLightTheme)) : null, + defaultDarkTheme: instance.defaultDarkTheme ? JSON.stringify(JSON5.parse(instance.defaultDarkTheme)) : null, enableEmail: instance.enableEmail, enableServiceWorker: instance.enableServiceWorker, translatorAvailable: instance.deeplAuthKey != null, diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug index 25513cc4cc..69b3f68e05 100644 --- a/packages/backend/src/server/web/views/base.pug +++ b/packages/backend/src/server/web/views/base.pug @@ -35,7 +35,7 @@ html link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg') //- https://github.com/misskey-dev/misskey/issues/9842 - link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v2.17.0') + link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v2.21.0') link(rel='modulepreload' href=`/vite/${clientEntry.file}`) if !config.clientManifestExists diff --git a/packages/backend/test/e2e/2fa.ts b/packages/backend/test/e2e/2fa.ts index 0addb430c9..5da997f28b 100644 --- a/packages/backend/test/e2e/2fa.ts +++ b/packages/backend/test/e2e/2fa.ts @@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import * as crypto from 'node:crypto'; -import * as cbor from 'cbor'; +import cbor from 'cbor'; import * as OTPAuth from 'otpauth'; import { loadConfig } from '../../src/config.js'; import { signup, api, post, react, startServer, waitFire } from '../utils.js'; diff --git a/packages/frontend/.storybook/preview-head.html b/packages/frontend/.storybook/preview-head.html index ab694f64fb..f6a9a4875d 100644 --- a/packages/frontend/.storybook/preview-head.html +++ b/packages/frontend/.storybook/preview-head.html @@ -1,6 +1,6 @@ - + diff --git a/packages/frontend/src/components/MkClickerGame.vue b/packages/frontend/src/components/MkClickerGame.vue index da6439fd2c..a6ab5aded4 100644 --- a/packages/frontend/src/components/MkClickerGame.vue +++ b/packages/frontend/src/components/MkClickerGame.vue @@ -3,7 +3,7 @@
{{ number(cps) }}cps
{{ number(cookies) }}
-
@@ -84,10 +84,6 @@ onUnmounted(() => { margin-bottom: 6px; } -.button { - -} - .img { max-width: 90px; } diff --git a/packages/frontend/src/components/MkContainer.vue b/packages/frontend/src/components/MkContainer.vue index d2d0fa3e4b..af1c57b349 100644 --- a/packages/frontend/src/components/MkContainer.vue +++ b/packages/frontend/src/components/MkContainer.vue @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/components/MkDateSeparatedList.vue b/packages/frontend/src/components/MkDateSeparatedList.vue index d6303f9675..6942a0e6c3 100644 --- a/packages/frontend/src/components/MkDateSeparatedList.vue +++ b/packages/frontend/src/components/MkDateSeparatedList.vue @@ -36,7 +36,7 @@ export default defineComponent({ }, setup(props, { slots, expose }) { - const $style = useCssModule(); + const $style = useCssModule(); // カスタムレンダラなので使っても大丈夫 function getDateText(time: string) { const date = new Date(time).getDate(); const month = new Date(time).getMonth() + 1; diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue index bd4da6c545..4d5df0bba4 100644 --- a/packages/frontend/src/components/MkDialog.vue +++ b/packages/frontend/src/components/MkDialog.vue @@ -4,7 +4,15 @@
-
+
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 093a1ec6d4..cf856fd31f 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -1,7 +1,8 @@ @@ -79,9 +78,16 @@ watch(() => props.image, () => { }); function showMenu(ev: MouseEvent) { - os.popupMenu([...(iAmModerator ? [{ - text: i18n.ts.markAsSensitive, + os.popupMenu([{ + text: i18n.ts.hide, icon: 'ti ti-eye-off', + action: () => { + hide = true; + }, + }, ...(iAmModerator ? [{ + text: i18n.ts.markAsSensitive, + icon: 'ti ti-eye-exclamation', + danger: true, action: () => { os.apiWithDialog('drive/files/update', { fileId: props.image.id, isSensitive: true }); }, @@ -122,34 +128,20 @@ function showMenu(ev: MouseEvent) { background-size: 16px 16px; } -.hide { - display: block; - position: absolute; - border-radius: 6px; - background-color: var(--accentedBg); - -webkit-backdrop-filter: var(--blur, blur(15px)); - backdrop-filter: var(--blur, blur(15px)); - color: var(--accent); - font-size: 0.8em; - padding: 6px 8px; - text-align: center; - top: 12px; - right: 12px; -} - .menu { display: block; position: absolute; - border-radius: 6px; + border-radius: 999px; background-color: rgba(0, 0, 0, 0.3); -webkit-backdrop-filter: var(--blur, blur(15px)); backdrop-filter: var(--blur, blur(15px)); color: #fff; font-size: 0.8em; - padding: 6px 8px; + width: 32px; + height: 32px; text-align: center; - bottom: 12px; - right: 12px; + bottom: 10px; + right: 10px; } .imageContainer { @@ -166,12 +158,10 @@ function showMenu(ev: MouseEvent) { .indicators { display: inline-flex; position: absolute; - top: 12px; - left: 12px; - text-align: center; + top: 10px; + left: 10px; pointer-events: none; opacity: .5; - font-size: 14px; gap: 6px; } @@ -182,7 +172,7 @@ function showMenu(ev: MouseEvent) { color: var(--accentLighten); display: inline-block; font-weight: bold; - font-size: 12px; - padding: 2px 6px; + font-size: 0.8em; + padding: 2px 5px; } diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 0f41ef248f..a0a2450054 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -6,8 +6,11 @@ ref="gallery" :class="[ $style.medias, - count <= 4 ? $style['n' + count] : $style.nMany, - $style[`n1${defaultStore.reactiveState.mediaListWithOneImageAppearance.value}`] + count === 1 ? [$style.n1, { + [$style.n116_9]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '16_9', + [$style.n11_1]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '1_1', + [$style.n12_3]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '2_3', + }] : count === 2 ? $style.n2 : count === 3 ? $style.n3 : count === 4 ? $style.n4 : $style.nMany, ]" > - diff --git a/packages/frontend/src/components/MkMention.vue b/packages/frontend/src/components/MkMention.vue index 481c3710ca..bb256c394b 100644 --- a/packages/frontend/src/components/MkMention.vue +++ b/packages/frontend/src/components/MkMention.vue @@ -2,7 +2,7 @@ - @{{ username }} + @{{ username }} @{{ toUnicode(host) }} diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue index 2697e3e21a..7dd6a8c88f 100644 --- a/packages/frontend/src/components/MkMenu.vue +++ b/packages/frontend/src/components/MkMenu.vue @@ -49,7 +49,7 @@ {{ i18n.ts.none }}
-
+
diff --git a/packages/frontend/src/components/MkModal.vue b/packages/frontend/src/components/MkModal.vue index a33bb2d0e2..bb5c6c7aab 100644 --- a/packages/frontend/src/components/MkModal.vue +++ b/packages/frontend/src/components/MkModal.vue @@ -1,10 +1,30 @@ diff --git a/packages/frontend/src/components/MkPoll.vue b/packages/frontend/src/components/MkPoll.vue index e2ca5603e3..464e340116 100644 --- a/packages/frontend/src/components/MkPoll.vue +++ b/packages/frontend/src/components/MkPoll.vue @@ -1,7 +1,7 @@ - - -