Merge branch 'misskey-dev:develop' into develop
This commit is contained in:
commit
7fb0e8c8a5
@ -36,9 +36,12 @@
|
|||||||
- フォローやお気に入り登録をしていないチャンネルを開く時は概要ページを開くように
|
- フォローやお気に入り登録をしていないチャンネルを開く時は概要ページを開くように
|
||||||
- 画面ビューワをタップした場合、マウスクリックと同様に画像ビューワを閉じるように
|
- 画面ビューワをタップした場合、マウスクリックと同様に画像ビューワを閉じるように
|
||||||
- オフライン時の画面にリロードボタンを追加
|
- オフライン時の画面にリロードボタンを追加
|
||||||
|
- Renote時に公開範囲のデフォルト設定が適用されるように
|
||||||
- Deckで非ルートページにアクセスした際に簡易UIで表示しない設定を追加
|
- Deckで非ルートページにアクセスした際に簡易UIで表示しない設定を追加
|
||||||
- ロール設定画面でロールIDを確認できるように
|
- ロール設定画面でロールIDを確認できるように
|
||||||
- コンテキストメニュー表示時のパフォーマンスを改善
|
- コンテキストメニュー表示時のパフォーマンスを改善
|
||||||
|
- フォロー/フォロワー非公開時の表示を改善
|
||||||
|
- AiScriptを0.14.0に更新
|
||||||
- Fix: サーバーメトリクスが90度傾いている
|
- Fix: サーバーメトリクスが90度傾いている
|
||||||
- Fix: 非ログイン時にクレデンシャルが必要なページに行くとエラーが出る問題を修正
|
- Fix: 非ログイン時にクレデンシャルが必要なページに行くとエラーが出る問題を修正
|
||||||
- Fix: sparkle内にリンクを入れるとクリック不能になる問題の修正
|
- Fix: sparkle内にリンクを入れるとクリック不能になる問題の修正
|
||||||
@ -59,9 +62,11 @@
|
|||||||
- MeilisearchにIndexするノートの範囲を設定できるように
|
- MeilisearchにIndexするノートの範囲を設定できるように
|
||||||
- Export notes with file detail
|
- Export notes with file detail
|
||||||
- Add unix socket support
|
- Add unix socket support
|
||||||
|
- Fix: リモートサーバーに無意味なActivityPubの配信を行うことがあるのを修正
|
||||||
- Fix: Remove Meilisearch index when notes are deleted
|
- Fix: Remove Meilisearch index when notes are deleted
|
||||||
- Fix: 非英語環境でのPostgreSQLのエラーハンドリングを修正
|
- Fix: 非英語環境でのPostgreSQLのエラーハンドリングを修正
|
||||||
- Fix: インスタンスのアイコンがbase64の場合の挙動を修正
|
- Fix: インスタンスのアイコンがbase64の場合の挙動を修正
|
||||||
|
- Fix: ローカルの `Person` を指す `acct` URI を解析するときのバグを修正しました
|
||||||
|
|
||||||
## 13.13.2
|
## 13.13.2
|
||||||
|
|
||||||
|
@ -1996,6 +1996,7 @@ _deck:
|
|||||||
introduction: "Erstelle eine auf dich zugeschneiderte Benutzeroberfläche durch das Aneinanderreihen von Spalten!"
|
introduction: "Erstelle eine auf dich zugeschneiderte Benutzeroberfläche durch das Aneinanderreihen von Spalten!"
|
||||||
introduction2: "Klicke auf das + rechts um wann immer du möchtest neue Spalten hinzuzufügen."
|
introduction2: "Klicke auf das + rechts um wann immer du möchtest neue Spalten hinzuzufügen."
|
||||||
widgetsIntroduction: "Drücke bitte \"Widgets bearbeiten\" im Spaltenmenü und füge ein Widget hinzu."
|
widgetsIntroduction: "Drücke bitte \"Widgets bearbeiten\" im Spaltenmenü und füge ein Widget hinzu."
|
||||||
|
useSimpleUiForNonRootPages: "Simple Benutzeroberfläche für navigierte Seiten verwenden"
|
||||||
_columns:
|
_columns:
|
||||||
main: "Hauptspalte"
|
main: "Hauptspalte"
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
|
@ -1996,6 +1996,7 @@ _deck:
|
|||||||
introduction: "Create the perfect interface for you by arranging columns freely!"
|
introduction: "Create the perfect interface for you by arranging columns freely!"
|
||||||
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
|
introduction2: "Click on the + on the right of the screen to add new colums whenever you want."
|
||||||
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
|
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
|
||||||
|
useSimpleUiForNonRootPages: "Use simple UI for navigated pages"
|
||||||
_columns:
|
_columns:
|
||||||
main: "Main"
|
main: "Main"
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
|
@ -779,10 +779,10 @@ info: "Informazioni"
|
|||||||
userInfo: "Informazioni utente"
|
userInfo: "Informazioni utente"
|
||||||
unknown: "Sconosciuto"
|
unknown: "Sconosciuto"
|
||||||
onlineStatus: "Stato di connessione"
|
onlineStatus: "Stato di connessione"
|
||||||
hideOnlineStatus: "Stato invisibile"
|
hideOnlineStatus: "Modalità invisibile"
|
||||||
hideOnlineStatusDescription: "Abilitare l'opzione di stato invisibile può guastare la praticità di singole funzioni, come la ricerca."
|
hideOnlineStatusDescription: "Attivando questa opzione potresti ridurre l'usabilità di alcune funzioni, come la ricerca."
|
||||||
online: "Online"
|
online: "Online"
|
||||||
active: "Attiv@"
|
active: "Attività"
|
||||||
offline: "Offline"
|
offline: "Offline"
|
||||||
notRecommended: "Sconsigliato"
|
notRecommended: "Sconsigliato"
|
||||||
botProtection: "Protezione contro i bot"
|
botProtection: "Protezione contro i bot"
|
||||||
@ -856,8 +856,8 @@ makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a di
|
|||||||
classic: "Classico"
|
classic: "Classico"
|
||||||
muteThread: "Silenzia la conversazione"
|
muteThread: "Silenzia la conversazione"
|
||||||
unmuteThread: "Riattiva la conversazione"
|
unmuteThread: "Riattiva la conversazione"
|
||||||
ffVisibility: "Ambito pubblico del collegamento"
|
ffVisibility: "Visibilità delle connessioni"
|
||||||
ffVisibilityDescription: "È possibile impostare la portata pubblica delle informazioni sui propri follower/seguaci."
|
ffVisibilityDescription: "Puoi scegliere a chi mostrare le tue relazioni con altri profili nel fediverso."
|
||||||
continueThread: "Altri thread."
|
continueThread: "Altri thread."
|
||||||
deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?"
|
deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?"
|
||||||
incorrectPassword: "La password è errata."
|
incorrectPassword: "La password è errata."
|
||||||
@ -1996,6 +1996,7 @@ _deck:
|
|||||||
introduction: "Combinate le colonne per creare la vostra interfaccia!"
|
introduction: "Combinate le colonne per creare la vostra interfaccia!"
|
||||||
introduction2: "È possibile aggiungere colonne in qualsiasi momento premendo + sulla destra dello schermo."
|
introduction2: "È possibile aggiungere colonne in qualsiasi momento premendo + sulla destra dello schermo."
|
||||||
widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità"
|
widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità"
|
||||||
|
useSimpleUiForNonRootPages: "Visualizza sotto pagine con interfaccia web semplice"
|
||||||
_columns:
|
_columns:
|
||||||
main: "Principale"
|
main: "Principale"
|
||||||
widgets: "Riquadri"
|
widgets: "Riquadri"
|
||||||
|
@ -49,11 +49,15 @@ delete: "삭제"
|
|||||||
deleteAndEdit: "삭제 후 편집"
|
deleteAndEdit: "삭제 후 편집"
|
||||||
deleteAndEditConfirm: "이 노트를 삭제한 뒤 다시 편집하시겠습니까? 이 노트에 대한 리액션, 리노트, 답글 또한 모두 삭제됩니다."
|
deleteAndEditConfirm: "이 노트를 삭제한 뒤 다시 편집하시겠습니까? 이 노트에 대한 리액션, 리노트, 답글 또한 모두 삭제됩니다."
|
||||||
addToList: "리스트에 추가"
|
addToList: "리스트에 추가"
|
||||||
|
addToAntenna: "안테나에 추가"
|
||||||
sendMessage: "메시지 보내기"
|
sendMessage: "메시지 보내기"
|
||||||
copyRSS: "RSS 복사"
|
copyRSS: "RSS 복사"
|
||||||
copyUsername: "유저명 복사"
|
copyUsername: "유저명 복사"
|
||||||
copyUserId: "유저 ID 복사"
|
copyUserId: "유저 ID 복사"
|
||||||
copyNoteId: "노트 ID 복사"
|
copyNoteId: "노트 ID 복사"
|
||||||
|
copyFileId: "파일 ID 복사"
|
||||||
|
copyFolderId: "폴더 ID 복사"
|
||||||
|
copyProfileUrl: "프로필 URL 복사"
|
||||||
searchUser: "사용자 검색"
|
searchUser: "사용자 검색"
|
||||||
reply: "답글"
|
reply: "답글"
|
||||||
loadMore: "더 보기"
|
loadMore: "더 보기"
|
||||||
@ -152,6 +156,8 @@ addEmoji: "이모지 추가"
|
|||||||
settingGuide: "추천 설정"
|
settingGuide: "추천 설정"
|
||||||
cacheRemoteFiles: "리모트 파일을 캐시"
|
cacheRemoteFiles: "리모트 파일을 캐시"
|
||||||
cacheRemoteFilesDescription: "이 설정을 해지하면 리모트 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다."
|
cacheRemoteFilesDescription: "이 설정을 해지하면 리모트 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다."
|
||||||
|
cacheRemoteSensitiveFiles: "리모트의 민감한 파일을 캐시"
|
||||||
|
cacheRemoteSensitiveFilesDescription: "이 설정을 비활성화하면 리모트의 민감한 파일은 캐시하지 않고 리모트에서 직접 가져오도록 합니다."
|
||||||
flagAsBot: "나는 봇입니다"
|
flagAsBot: "나는 봇입니다"
|
||||||
flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 봇이 이를 참고하여 봇 끼리의 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 Bot 운영에 최적화되는 등의 변화가 생깁니다."
|
flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 봇이 이를 참고하여 봇 끼리의 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 Bot 운영에 최적화되는 등의 변화가 생깁니다."
|
||||||
flagAsCat: "나는 고양이다냥"
|
flagAsCat: "나는 고양이다냥"
|
||||||
@ -313,6 +319,7 @@ copyUrl: "URL 복사"
|
|||||||
rename: "이름 변경"
|
rename: "이름 변경"
|
||||||
avatar: "아바타"
|
avatar: "아바타"
|
||||||
banner: "배너"
|
banner: "배너"
|
||||||
|
displayOfSensitiveMedia: "민감한 미디어 표시"
|
||||||
whenServerDisconnected: "서버와의 접속이 끊겼을 때"
|
whenServerDisconnected: "서버와의 접속이 끊겼을 때"
|
||||||
disconnectedFromServer: "서버와의 연결이 끊어졌습니다"
|
disconnectedFromServer: "서버와의 연결이 끊어졌습니다"
|
||||||
reload: "새로고침"
|
reload: "새로고침"
|
||||||
@ -1066,6 +1073,24 @@ installed: "설치됨"
|
|||||||
branding: "브랜딩"
|
branding: "브랜딩"
|
||||||
enableServerMachineStats: "서버의 머신 사양을 공개하기"
|
enableServerMachineStats: "서버의 머신 사양을 공개하기"
|
||||||
enableIdenticonGeneration: "유저마다의 Identicon 생성 유효화"
|
enableIdenticonGeneration: "유저마다의 Identicon 생성 유효화"
|
||||||
|
turnOffToImprovePerformance: "이 기능을 끄면 성능이 향상될 수 있습니다."
|
||||||
|
createInviteCode: "초대 코드 생성"
|
||||||
|
createWithOptions: "옵션을 지정하여 생성"
|
||||||
|
createCount: "초대 수"
|
||||||
|
inviteCodeCreated: "초대 코드 생성됨"
|
||||||
|
inviteLimitExceeded: "초대 코드 생성 한도를 초과했습니다."
|
||||||
|
createLimitRemaining: "초대 한도: {limit}회 남음"
|
||||||
|
inviteLimitResetCycle: " {time}시간 이내에 최대 {limit}개의 초대 코드를 생성할 수 있습니다."
|
||||||
|
expirationDate: "만료 날짜"
|
||||||
|
noExpirationDate: "만료기간 없음"
|
||||||
|
inviteCodeUsedAt: "다음에 사용된 초대 코드"
|
||||||
|
registeredUserUsingInviteCode: "초대 코드 사용 대상"
|
||||||
|
waitingForMailAuth: "이메일 인증 보류 중"
|
||||||
|
inviteCodeCreator: "초대 코드 생성자"
|
||||||
|
usedAt: "사용 시각"
|
||||||
|
unused: "사용되지 않음"
|
||||||
|
used: "사용됨"
|
||||||
|
expired: "만료됨"
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "계정 생성이 완료되었습니다!"
|
accountCreated: "계정 생성이 완료되었습니다!"
|
||||||
letsStartAccountSetup: "계정의 초기 설정을 진행합니다."
|
letsStartAccountSetup: "계정의 초기 설정을 진행합니다."
|
||||||
@ -1376,6 +1401,9 @@ _role:
|
|||||||
ltlAvailable: "로컬 타임라인 보이기"
|
ltlAvailable: "로컬 타임라인 보이기"
|
||||||
canPublicNote: "공개 노트 허용"
|
canPublicNote: "공개 노트 허용"
|
||||||
canInvite: "서버 초대 코드 발행"
|
canInvite: "서버 초대 코드 발행"
|
||||||
|
inviteLimit: "초대 한도"
|
||||||
|
inviteLimitCycle: "초대 발급 간격"
|
||||||
|
inviteExpirationTime: "초대 만료 기간"
|
||||||
canManageCustomEmojis: "커스텀 이모지 관리"
|
canManageCustomEmojis: "커스텀 이모지 관리"
|
||||||
driveCapacity: "드라이브 용량"
|
driveCapacity: "드라이브 용량"
|
||||||
alwaysMarkNsfw: "파일을 항상 NSFW로 지정"
|
alwaysMarkNsfw: "파일을 항상 NSFW로 지정"
|
||||||
@ -1438,6 +1466,7 @@ _ad:
|
|||||||
back: "뒤로"
|
back: "뒤로"
|
||||||
reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기"
|
reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기"
|
||||||
hide: "보이지 않음"
|
hide: "보이지 않음"
|
||||||
|
timezoneinfo: "요일은 서버의 표준 시간대에 따라 결정됩니다."
|
||||||
_forgotPassword:
|
_forgotPassword:
|
||||||
enterEmail: "여기에 계정에 등록한 메일 주소를 입력해 주세요. 입력한 메일 주소로 비밀번호 재설정 링크를 발송합니다."
|
enterEmail: "여기에 계정에 등록한 메일 주소를 입력해 주세요. 입력한 메일 주소로 비밀번호 재설정 링크를 발송합니다."
|
||||||
ifNoEmail: "메일 주소를 등록하지 않은 경우, 관리자에 문의해 주십시오."
|
ifNoEmail: "메일 주소를 등록하지 않은 경우, 관리자에 문의해 주십시오."
|
||||||
@ -1489,6 +1518,10 @@ _aboutMisskey:
|
|||||||
donate: "Misskey에 기부하기"
|
donate: "Misskey에 기부하기"
|
||||||
morePatrons: "이 외에도 다른 많은 분들이 도움을 주시고 계십니다. 감사합니다🥰"
|
morePatrons: "이 외에도 다른 많은 분들이 도움을 주시고 계십니다. 감사합니다🥰"
|
||||||
patrons: "후원자"
|
patrons: "후원자"
|
||||||
|
_displayOfSensitiveMedia:
|
||||||
|
respect: "민감한 콘텐츠로 표시된 미디어 숨기기"
|
||||||
|
ignore: "민감한 콘텐츠로 표시된 미디어 보이기"
|
||||||
|
force: "미디어 항상 숨기기"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "보이지 않음"
|
none: "보이지 않음"
|
||||||
remote: "리모트 유저에게만 보이기"
|
remote: "리모트 유저에게만 보이기"
|
||||||
@ -1963,6 +1996,7 @@ _deck:
|
|||||||
introduction: "칼럼을 조합해서 나만의 인터페이스를 구성해 보아요!"
|
introduction: "칼럼을 조합해서 나만의 인터페이스를 구성해 보아요!"
|
||||||
introduction2: "나중에라도 화면 우측의 + 버튼을 눌러 새 칼럼을 추가할 수 있습니다."
|
introduction2: "나중에라도 화면 우측의 + 버튼을 눌러 새 칼럼을 추가할 수 있습니다."
|
||||||
widgetsIntroduction: "칼럼 메뉴의 \"위젯 편집\"에서 위젯을 추가해 주세요"
|
widgetsIntroduction: "칼럼 메뉴의 \"위젯 편집\"에서 위젯을 추가해 주세요"
|
||||||
|
useSimpleUiForNonRootPages: "루트 이외의 페이지로 접속한 경우 UI 간략화하기"
|
||||||
_columns:
|
_columns:
|
||||||
main: "메인"
|
main: "메인"
|
||||||
widgets: "위젯"
|
widgets: "위젯"
|
||||||
|
@ -20,6 +20,7 @@ noNotes: "ບໍ່ມີຫມາຍເຫດ"
|
|||||||
noNotifications: "ບໍ່ມີການແຈ້ງເຕືອນ"
|
noNotifications: "ບໍ່ມີການແຈ້ງເຕືອນ"
|
||||||
instance: "ອີນສະແຕນ"
|
instance: "ອີນສະແຕນ"
|
||||||
settings: "ກຳນົດຄ່າ"
|
settings: "ກຳນົດຄ່າ"
|
||||||
|
notificationSettings: "ຕັ້ງຄ່າການແຈ້ງເຕືອນ"
|
||||||
basicSettings: "ການຕັ້ງຄ່າພື້ນຖານ"
|
basicSettings: "ການຕັ້ງຄ່າພື້ນຖານ"
|
||||||
otherSettings: "ການຕັ້ງຄ່າອື່ນໆ"
|
otherSettings: "ການຕັ້ງຄ່າອື່ນໆ"
|
||||||
openInWindow: "ເປີດຢູ່ໃນປ່ອງຢ້ຽມ"
|
openInWindow: "ເປີດຢູ່ໃນປ່ອງຢ້ຽມ"
|
||||||
@ -48,9 +49,15 @@ delete: "ລຶບ"
|
|||||||
deleteAndEdit: "ລົບແລະແກ້ໄຂ"
|
deleteAndEdit: "ລົບແລະແກ້ໄຂ"
|
||||||
deleteAndEditConfirm: "ເຈົ້າແນ່ໃຈບໍ່? ທີ່ທ່ານຕ້ອງການທີ່ຈະລຶບບັນທຶກນີ້ແລະແກ້ໄຂມັນ ທ່ານອາດຈະສູນເສຍການໂຕ້ຕອບ, ບັນທຶກ, ແລະການຕອບກັບທັງໝົດ"
|
deleteAndEditConfirm: "ເຈົ້າແນ່ໃຈບໍ່? ທີ່ທ່ານຕ້ອງການທີ່ຈະລຶບບັນທຶກນີ້ແລະແກ້ໄຂມັນ ທ່ານອາດຈະສູນເສຍການໂຕ້ຕອບ, ບັນທຶກ, ແລະການຕອບກັບທັງໝົດ"
|
||||||
addToList: "ເພີ່ມໃສ່ລາຍຊື່"
|
addToList: "ເພີ່ມໃສ່ລາຍຊື່"
|
||||||
|
addToAntenna: "ເພີ່ມໃສ່ເສົາອາກາດ"
|
||||||
sendMessage: "ສົ່ງຂໍ້ຄວາມ"
|
sendMessage: "ສົ່ງຂໍ້ຄວາມ"
|
||||||
copyRSS: "ສຳເນົາ RSS"
|
copyRSS: "ສຳເນົາ RSS"
|
||||||
copyUsername: "ສຳເນົາຊື່ຜູ້ໃຊ້"
|
copyUsername: "ສຳເນົາຊື່ຜູ້ໃຊ້"
|
||||||
|
copyUserId: "ສຳເນົາ ID ຜູ້ໃຊ້"
|
||||||
|
copyNoteId: "ສຳເນົາ ID ບັນທຶກ"
|
||||||
|
copyFileId: "ສຳເນົາ ID ໄຟລ໌"
|
||||||
|
copyFolderId: "ສຳເນົາ ID ໂຟນເດີ"
|
||||||
|
copyProfileUrl: "ສຳເນົາ URL ໂປຣໄຟລ໌"
|
||||||
searchUser: "ຄົ້ນຫາຜູ້ໃຊ້"
|
searchUser: "ຄົ້ນຫາຜູ້ໃຊ້"
|
||||||
reply: "ຕອບໄປທີ"
|
reply: "ຕອບໄປທີ"
|
||||||
loadMore: "ໂຫຼດເພີ່ມເຕີມ"
|
loadMore: "ໂຫຼດເພີ່ມເຕີມ"
|
||||||
@ -109,6 +116,7 @@ sensitive: "NSFW"
|
|||||||
add: "ເພີ່ມ"
|
add: "ເພີ່ມ"
|
||||||
reaction: "ປະຕິກິລິຍາ"
|
reaction: "ປະຕິກິລິຍາ"
|
||||||
reactions: "ປະຕິກິລິຍາ"
|
reactions: "ປະຕິກິລິຍາ"
|
||||||
|
attachCancel: "ເອົາໄຟລ໌ແນບ"
|
||||||
mute: "ປີດສຽງ"
|
mute: "ປີດສຽງ"
|
||||||
unmute: "ເປີດສຽງ"
|
unmute: "ເປີດສຽງ"
|
||||||
block: "ບ໋ອກ"
|
block: "ບ໋ອກ"
|
||||||
@ -116,6 +124,10 @@ unblock: "ຍົກເລີກກາຮົບລັອກ"
|
|||||||
suspend: "ລະງັບ"
|
suspend: "ລະງັບ"
|
||||||
unsuspend: "ເຊົາລະງັບ"
|
unsuspend: "ເຊົາລະງັບ"
|
||||||
selectList: "ເລືອກບັນຊີລາຍການ"
|
selectList: "ເລືອກບັນຊີລາຍການ"
|
||||||
|
editList: "ແກ້ໄຂລາຍຊື່"
|
||||||
|
selectChannel: "ເລືອກຊ່ອງ"
|
||||||
|
selectAntenna: "ເລືອກເສົາອາກາດ"
|
||||||
|
editAntenna: "ແກ້ໄຂເສົາອາກາດ"
|
||||||
selectWidget: "ເລືອກວິກເຈັດ"
|
selectWidget: "ເລືອກວິກເຈັດ"
|
||||||
editWidgets: "ແກ້ໄຂ Widget"
|
editWidgets: "ແກ້ໄຂ Widget"
|
||||||
editWidgetsExit: "ສຳເລັດແລ້ວ"
|
editWidgetsExit: "ສຳເລັດແລ້ວ"
|
||||||
@ -125,6 +137,7 @@ emojis: "ອີໂມຈິ"
|
|||||||
emojiName: "ຊື່ Emoji"
|
emojiName: "ຊື່ Emoji"
|
||||||
emojiUrl: "URL ອີໂມຈິ"
|
emojiUrl: "URL ອີໂມຈິ"
|
||||||
addEmoji: "ຕື່ມອີໂມຈິ"
|
addEmoji: "ຕື່ມອີໂມຈິ"
|
||||||
|
settingGuide: "ການຕັ້ງຄ່າທີ່ແນະນໍາ"
|
||||||
flagAsBot: "ໝາຍບັນຊີນີ້ເປັນບັອດ"
|
flagAsBot: "ໝາຍບັນຊີນີ້ເປັນບັອດ"
|
||||||
flagAsCat: "ໝາຍບັນຊີນີ້ເປັນແມວ"
|
flagAsCat: "ໝາຍບັນຊີນີ້ເປັນແມວ"
|
||||||
flagAsCatDescription: "ເປີດໃຊ້ຕົວເລືອກນີ້ເພື່ອໝາຍບັນຊີນີ້ເປັນແມວ"
|
flagAsCatDescription: "ເປີດໃຊ້ຕົວເລືອກນີ້ເພື່ອໝາຍບັນຊີນີ້ເປັນແມວ"
|
||||||
@ -133,10 +146,13 @@ flagShowTimelineRepliesDescription: "ສະແດງການຕອບກັບ
|
|||||||
autoAcceptFollowed: "ອະນຸມັດອັດຕະໂນມັດຕາມຄຳຮ້ອງຂໍຈາກຜູ້ໃຊ້ທີ່ທ່ານກຳລັງຕິດຕາມຢູ່"
|
autoAcceptFollowed: "ອະນຸມັດອັດຕະໂນມັດຕາມຄຳຮ້ອງຂໍຈາກຜູ້ໃຊ້ທີ່ທ່ານກຳລັງຕິດຕາມຢູ່"
|
||||||
addAccount: "ເພີ່ມບັນຊີ"
|
addAccount: "ເພີ່ມບັນຊີ"
|
||||||
loginFailed: "ການເຂົ້າສູ່ລະບົບບໍ່ສຳເລັດ"
|
loginFailed: "ການເຂົ້າສູ່ລະບົບບໍ່ສຳເລັດ"
|
||||||
|
showOnRemote: "ເບິ່ງຢູ່ໃນຕົວຢ່າງໄລຍະໄກ"
|
||||||
general: "ທົ່ວໄປ"
|
general: "ທົ່ວໄປ"
|
||||||
wallpaper: "ພາບພື້ນຫລັງ"
|
wallpaper: "ພາບພື້ນຫລັງ"
|
||||||
setWallpaper: "ຕັ້ງເປັນພາບພື້ນຫຼັງ"
|
setWallpaper: "ຕັ້ງເປັນພາບພື້ນຫຼັງ"
|
||||||
|
removeWallpaper: "ລຶບຮູບວໍເປເປີອອກ"
|
||||||
searchWith: "ຊອກຫາ: {q}"
|
searchWith: "ຊອກຫາ: {q}"
|
||||||
|
youHaveNoLists: "ທ່ານບໍ່ມີລາຍການໃດໆ"
|
||||||
proxyAccount: "ບັນຊີພຣັອກຊີ"
|
proxyAccount: "ບັນຊີພຣັອກຊີ"
|
||||||
host: "ໂຮດສ"
|
host: "ໂຮດສ"
|
||||||
selectUser: "ເລືອກຜູ້ໃຊ້"
|
selectUser: "ເລືອກຜູ້ໃຊ້"
|
||||||
@ -155,7 +171,9 @@ operations: "ການດຳເນີນງານ"
|
|||||||
software: "ຊອບແວ"
|
software: "ຊອບແວ"
|
||||||
version: "ສະບັບ"
|
version: "ສະບັບ"
|
||||||
metadata: "Metadata"
|
metadata: "Metadata"
|
||||||
|
withNFiles: "{n} ໄຟລ໌(s)"
|
||||||
monitor: "ຈໍພາບ"
|
monitor: "ຈໍພາບ"
|
||||||
|
jobQueue: "ຄິວວຽກ"
|
||||||
cpuAndMemory: "CPU ແລະ ຫນ່ວຍຄວາມຈໍາ"
|
cpuAndMemory: "CPU ແລະ ຫນ່ວຍຄວາມຈໍາ"
|
||||||
network: "ເຄືອຂ່າຍ"
|
network: "ເຄືອຂ່າຍ"
|
||||||
disk: "ດິສກ໌"
|
disk: "ດິສກ໌"
|
||||||
@ -343,6 +361,7 @@ _widgets:
|
|||||||
timeline: "ເສັ້ນກຳນົດເວລາ"
|
timeline: "ເສັ້ນກຳນົດເວລາ"
|
||||||
activity: "ກິດຈະກຳ"
|
activity: "ກິດຈະກຳ"
|
||||||
federation: "ສະຫະພັນ"
|
federation: "ສະຫະພັນ"
|
||||||
|
jobQueue: "ຄິວວຽກ"
|
||||||
_userList:
|
_userList:
|
||||||
chooseList: "ເລືອກບັນຊີລາຍການ"
|
chooseList: "ເລືອກບັນຊີລາຍການ"
|
||||||
_cw:
|
_cw:
|
||||||
|
@ -481,6 +481,7 @@ windowMinimize: "Minimera"
|
|||||||
windowRestore: "Återställ"
|
windowRestore: "Återställ"
|
||||||
pleaseDonate: "Misskey är en gratis programvara som används på {host}. Donera gärna för att göra utvecklingen ständigt, tack!"
|
pleaseDonate: "Misskey är en gratis programvara som används på {host}. Donera gärna för att göra utvecklingen ständigt, tack!"
|
||||||
resetPasswordConfirm: "Återställ verkligen ditt lösenord?"
|
resetPasswordConfirm: "Återställ verkligen ditt lösenord?"
|
||||||
|
dataSaver: "Databesparing"
|
||||||
_achievements:
|
_achievements:
|
||||||
_types:
|
_types:
|
||||||
_open3windows:
|
_open3windows:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
_lang_: "ภาษาไทย"
|
_lang_: "ภาษาไทย"
|
||||||
headlineMisskey: "เชื่อมต่อเครือข่ายโดยโน้ต"
|
headlineMisskey: "เชื่อมต่อระบบ Network ด้วย Note"
|
||||||
introMisskey: "ยินดีต้อนรับจ้าาา! Misskey เป็นบริการไมโครบล็อกโอเพ่นซอร์ส แบบการกระจายอำนาจ\nสร้าง \"โน้ต\" เพื่อแบ่งปันความคิดของคุณกับทุกคนรอบตัวคุณกันเถอะ 📡\nด้วยการ \"รีแอคชั่นผู้คน\" คุณยังสามารถแสดงความรู้สึกของคุณเกี่ยวกับบันทึกของทุกคนได้อย่างรวดเร็ว 👍\n\nแล้วมาท่องสำรวจโลกใบใหม่กันเถอะ! 🚀"
|
introMisskey: "ยินดีต้อนรับทุกคนจ้า! Misskey คือ บริการไมโครบล็อกกิ้ง (MicroBlogging) แบบกระจายศูนย์อำนาจ (Decentralized) \n\nเขียน \"โน้ต (Note)\" เพื่อส่งต่อเรื่องราวของคุณให้ทั้งโลกได้รับรู้📡\nและอย่าลืมที่จะ \"React\" กับเรื่องราวของคนอื่น ๆ ด้วย! 👍\n\nมุ่งสู่โลกใบใหม่กันเถอะ🚀"
|
||||||
poweredByMisskeyDescription: "{name} เป็นส่วนหนึ่งในบริการที่ถูกขับเคลื่อนโดยแพลตฟอร์มโอเพ่นซอร์ส <b>Misskey</b> (เรียกว่า \"อินสแตนซ์ Misskey\")"
|
poweredByMisskeyDescription: "{name} เป็นส่วนหนึ่งในบริการที่ถูกขับเคลื่อนโดยแพลตฟอร์มโอเพ่นซอร์ส <b>Misskey</b> (เรียกว่า \"อินสแตนซ์ Misskey\")"
|
||||||
monthAndDay: "{month}/{day}"
|
monthAndDay: "{month}/{day}"
|
||||||
search: "ค้นหา"
|
search: "ค้นหา"
|
||||||
@ -339,7 +339,7 @@ thisYear: "ปีนี้"
|
|||||||
thisMonth: "เดือนนี้"
|
thisMonth: "เดือนนี้"
|
||||||
today: "วันนี้"
|
today: "วันนี้"
|
||||||
dayX: "{day}"
|
dayX: "{day}"
|
||||||
monthX: "{เดือน}"
|
monthX: "เดือน {month}"
|
||||||
yearX: "{year}"
|
yearX: "{year}"
|
||||||
pages: "หน้า"
|
pages: "หน้า"
|
||||||
integration: "รวบรวม"
|
integration: "รวบรวม"
|
||||||
@ -1996,6 +1996,7 @@ _deck:
|
|||||||
introduction: "สร้างอินเทอร์เฟซที่สมบูรณ์แบบสำหรับคุณโดยจัดเรียงคอลัมน์ได้อย่างอิสระ!"
|
introduction: "สร้างอินเทอร์เฟซที่สมบูรณ์แบบสำหรับคุณโดยจัดเรียงคอลัมน์ได้อย่างอิสระ!"
|
||||||
introduction2: "คลิกที่เครื่องหมาย + ทางขวาของหน้าจอเพื่อเพิ่มคอลัมน์ใหม่ทุกครั้งที่คุณต้องการ"
|
introduction2: "คลิกที่เครื่องหมาย + ทางขวาของหน้าจอเพื่อเพิ่มคอลัมน์ใหม่ทุกครั้งที่คุณต้องการ"
|
||||||
widgetsIntroduction: "กรุณาเลือก \"แก้ไขวิดเจ็ต\" ในเมนูคอลัมน์และเพิ่มวิดเจ็ต"
|
widgetsIntroduction: "กรุณาเลือก \"แก้ไขวิดเจ็ต\" ในเมนูคอลัมน์และเพิ่มวิดเจ็ต"
|
||||||
|
useSimpleUiForNonRootPages: "แสดง UI ของ Root Page อย่างง่าย "
|
||||||
_columns:
|
_columns:
|
||||||
main: "หลัก"
|
main: "หลัก"
|
||||||
widgets: "วิดเจ็ต"
|
widgets: "วิดเจ็ต"
|
||||||
|
@ -156,6 +156,8 @@ addEmoji: "添加表情符号"
|
|||||||
settingGuide: "推荐配置"
|
settingGuide: "推荐配置"
|
||||||
cacheRemoteFiles: "缓存远程文件"
|
cacheRemoteFiles: "缓存远程文件"
|
||||||
cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程服务器载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。"
|
cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程服务器载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。"
|
||||||
|
cacheRemoteSensitiveFiles: "缓存远程敏感媒体文件"
|
||||||
|
cacheRemoteSensitiveFilesDescription: "如果禁用这项设定,远程服务器的敏感媒体将不会被缓存,而是直接链接。"
|
||||||
flagAsBot: "这是一个机器人账号"
|
flagAsBot: "这是一个机器人账号"
|
||||||
flagAsBotDescription: "如果此账户由程序控制,请启用此项。启用后,此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为,并让 Misskey 的内部系统将此账户识别为机器人。"
|
flagAsBotDescription: "如果此账户由程序控制,请启用此项。启用后,此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为,并让 Misskey 的内部系统将此账户识别为机器人。"
|
||||||
flagAsCat: "将这个账户设定为一只猫"
|
flagAsCat: "将这个账户设定为一只猫"
|
||||||
@ -1072,7 +1074,20 @@ branding: "品牌"
|
|||||||
enableServerMachineStats: "公开服务器硬件统计信息"
|
enableServerMachineStats: "公开服务器硬件统计信息"
|
||||||
enableIdenticonGeneration: "启用生成用户 Identicon"
|
enableIdenticonGeneration: "启用生成用户 Identicon"
|
||||||
turnOffToImprovePerformance: "关闭该选项可以提高性能。"
|
turnOffToImprovePerformance: "关闭该选项可以提高性能。"
|
||||||
|
createInviteCode: "发行邀请码"
|
||||||
|
createWithOptions: "使用选项来创建"
|
||||||
|
createCount: "发行数"
|
||||||
inviteCodeCreated: "已创建邀请码"
|
inviteCodeCreated: "已创建邀请码"
|
||||||
|
inviteLimitExceeded: "可供发行的邀请码已达上限。"
|
||||||
|
createLimitRemaining: "可供发行的邀请码:剩余{limit}个"
|
||||||
|
inviteLimitResetCycle: "可以在{time}内发行最多{limit}个邀请码。"
|
||||||
|
expirationDate: "有效日期"
|
||||||
|
noExpirationDate: "不设置有效日期"
|
||||||
|
inviteCodeUsedAt: "邀请码被使用的日期和时间"
|
||||||
|
registeredUserUsingInviteCode: "使用了邀请码的用户"
|
||||||
|
waitingForMailAuth: "等待验证电子邮件"
|
||||||
|
inviteCodeCreator: "发行邀请码的用户"
|
||||||
|
usedAt: "使用时间"
|
||||||
unused: "未使用"
|
unused: "未使用"
|
||||||
used: "已使用"
|
used: "已使用"
|
||||||
expired: "已过期"
|
expired: "已过期"
|
||||||
@ -1386,6 +1401,9 @@ _role:
|
|||||||
ltlAvailable: "查看本地时间线"
|
ltlAvailable: "查看本地时间线"
|
||||||
canPublicNote: "允许公开发帖"
|
canPublicNote: "允许公开发帖"
|
||||||
canInvite: "发放服务器邀请码"
|
canInvite: "发放服务器邀请码"
|
||||||
|
inviteLimit: "可发行邀请码的数量"
|
||||||
|
inviteLimitCycle: "邀请码的发行间隔"
|
||||||
|
inviteExpirationTime: "邀请码的有效日期"
|
||||||
canManageCustomEmojis: "管理自定义表情符号"
|
canManageCustomEmojis: "管理自定义表情符号"
|
||||||
driveCapacity: "网盘容量"
|
driveCapacity: "网盘容量"
|
||||||
alwaysMarkNsfw: "总是将文件标记为 NSFW"
|
alwaysMarkNsfw: "总是将文件标记为 NSFW"
|
||||||
@ -1978,6 +1996,7 @@ _deck:
|
|||||||
introduction: "将各列进行组合以创建您自己的界面!"
|
introduction: "将各列进行组合以创建您自己的界面!"
|
||||||
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
|
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
|
||||||
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"
|
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"
|
||||||
|
useSimpleUiForNonRootPages: "用简易UI表示非根页面"
|
||||||
_columns:
|
_columns:
|
||||||
main: "主列"
|
main: "主列"
|
||||||
widgets: "小工具"
|
widgets: "小工具"
|
||||||
|
@ -1996,6 +1996,7 @@ _deck:
|
|||||||
introduction: "組合欄位來製作屬於自己的介面吧!"
|
introduction: "組合欄位來製作屬於自己的介面吧!"
|
||||||
introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。"
|
introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。"
|
||||||
widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具"
|
widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具"
|
||||||
|
useSimpleUiForNonRootPages: "用簡易UI顯示非根頁面"
|
||||||
_columns:
|
_columns:
|
||||||
main: "主列"
|
main: "主列"
|
||||||
widgets: "小工具"
|
widgets: "小工具"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "13.14.0-beta.5",
|
"version": "13.14.0-beta.6",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -57,24 +57,24 @@
|
|||||||
"@aws-sdk/client-s3": "3.367.0",
|
"@aws-sdk/client-s3": "3.367.0",
|
||||||
"@aws-sdk/lib-storage": "3.367.0",
|
"@aws-sdk/lib-storage": "3.367.0",
|
||||||
"@aws-sdk/node-http-handler": "3.360.0",
|
"@aws-sdk/node-http-handler": "3.360.0",
|
||||||
"@bull-board/api": "5.6.0",
|
"@bull-board/api": "5.6.1",
|
||||||
"@bull-board/fastify": "5.6.0",
|
"@bull-board/fastify": "5.6.1",
|
||||||
"@bull-board/ui": "5.6.0",
|
"@bull-board/ui": "5.6.1",
|
||||||
"@discordapp/twemoji": "14.1.2",
|
"@discordapp/twemoji": "14.1.2",
|
||||||
"@fastify/accepts": "4.2.0",
|
"@fastify/accepts": "4.2.0",
|
||||||
"@fastify/cookie": "8.3.0",
|
"@fastify/cookie": "8.3.0",
|
||||||
"@fastify/cors": "8.3.0",
|
"@fastify/cors": "8.3.0",
|
||||||
"@fastify/http-proxy": "9.2.1",
|
"@fastify/http-proxy": "9.2.1",
|
||||||
"@fastify/multipart": "7.7.0",
|
"@fastify/multipart": "7.7.1",
|
||||||
"@fastify/static": "6.10.2",
|
"@fastify/static": "6.10.2",
|
||||||
"@fastify/view": "8.0.0",
|
"@fastify/view": "8.0.0",
|
||||||
"@nestjs/common": "10.0.5",
|
"@nestjs/common": "10.1.0",
|
||||||
"@nestjs/core": "10.0.5",
|
"@nestjs/core": "10.1.0",
|
||||||
"@nestjs/testing": "10.0.5",
|
"@nestjs/testing": "10.1.0",
|
||||||
"@peertube/http-signature": "1.7.0",
|
"@peertube/http-signature": "1.7.0",
|
||||||
"@sinonjs/fake-timers": "10.3.0",
|
"@sinonjs/fake-timers": "10.3.0",
|
||||||
"@swc/cli": "0.1.62",
|
"@swc/cli": "0.1.62",
|
||||||
"@swc/core": "1.3.69",
|
"@swc/core": "1.3.70",
|
||||||
"accepts": "1.3.8",
|
"accepts": "1.3.8",
|
||||||
"ajv": "8.12.0",
|
"ajv": "8.12.0",
|
||||||
"archiver": "5.3.1",
|
"archiver": "5.3.1",
|
||||||
@ -82,7 +82,7 @@
|
|||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "2.0.5",
|
"blurhash": "2.0.5",
|
||||||
"bullmq": "4.3.0",
|
"bullmq": "4.4.0",
|
||||||
"cacheable-lookup": "7.0.0",
|
"cacheable-lookup": "7.0.0",
|
||||||
"cbor": "9.0.0",
|
"cbor": "9.0.0",
|
||||||
"chalk": "5.3.0",
|
"chalk": "5.3.0",
|
||||||
@ -94,7 +94,7 @@
|
|||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
"deep-email-validator": "0.1.21",
|
"deep-email-validator": "0.1.21",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"fastify": "4.19.2",
|
"fastify": "4.20.0",
|
||||||
"feed": "4.2.2",
|
"feed": "4.2.2",
|
||||||
"file-type": "18.5.0",
|
"file-type": "18.5.0",
|
||||||
"fluent-ffmpeg": "2.1.2",
|
"fluent-ffmpeg": "2.1.2",
|
||||||
|
@ -4,10 +4,9 @@ import { IsNull, In, MoreThan, Not } from 'typeorm';
|
|||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js';
|
||||||
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, Muting, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js';
|
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, Muting, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
|
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
|
||||||
|
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
|
@ -2,6 +2,7 @@ import { URL } from 'node:url';
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { JSDOM } from 'jsdom';
|
import { JSDOM } from 'jsdom';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
|
import * as Redis from 'ioredis';
|
||||||
import type { Instance } from '@/models/entities/Instance.js';
|
import type { Instance } from '@/models/entities/Instance.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
@ -10,7 +11,6 @@ import { HttpRequestService } from '@/core/HttpRequestService.js';
|
|||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||||
import type { DOMWindow } from 'jsdom';
|
import type { DOMWindow } from 'jsdom';
|
||||||
import * as Redis from 'ioredis';
|
|
||||||
|
|
||||||
type NodeInfo = {
|
type NodeInfo = {
|
||||||
openRegistrations?: unknown;
|
openRegistrations?: unknown;
|
||||||
|
@ -574,7 +574,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||||||
where: {
|
where: {
|
||||||
userId: data.reply.userId,
|
userId: data.reply.userId,
|
||||||
threadId: data.reply.threadId ?? data.reply.id,
|
threadId: data.reply.threadId ?? data.reply.id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isThreadMuted) {
|
if (!isThreadMuted) {
|
||||||
|
@ -8,8 +8,9 @@ import type { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
|||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { WebfingerService } from '@/core/WebfingerService.js';
|
import { ILink, WebfingerService } from '@/core/WebfingerService.js';
|
||||||
import { RemoteLoggerService } from '@/core/RemoteLoggerService.js';
|
import { RemoteLoggerService } from '@/core/RemoteLoggerService.js';
|
||||||
|
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
|
||||||
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export class RemoteUserResolveService {
|
|||||||
private utilityService: UtilityService,
|
private utilityService: UtilityService,
|
||||||
private webfingerService: WebfingerService,
|
private webfingerService: WebfingerService,
|
||||||
private remoteLoggerService: RemoteLoggerService,
|
private remoteLoggerService: RemoteLoggerService,
|
||||||
|
private apDbResolverService: ApDbResolverService,
|
||||||
private apPersonService: ApPersonService,
|
private apPersonService: ApPersonService,
|
||||||
) {
|
) {
|
||||||
this.logger = this.remoteLoggerService.logger.createSubLogger('resolve-user');
|
this.logger = this.remoteLoggerService.logger.createSubLogger('resolve-user');
|
||||||
@ -67,6 +69,22 @@ export class RemoteUserResolveService {
|
|||||||
if (user == null) {
|
if (user == null) {
|
||||||
const self = await this.resolveSelf(acctLower);
|
const self = await this.resolveSelf(acctLower);
|
||||||
|
|
||||||
|
if (self.href.startsWith(this.config.url)) {
|
||||||
|
const local = this.apDbResolverService.parseUri(self.href);
|
||||||
|
if (local.local && local.type === 'users') {
|
||||||
|
// the LR points to local
|
||||||
|
return (await this.apDbResolverService
|
||||||
|
.getUserFromApId(self.href)
|
||||||
|
.then((u) => {
|
||||||
|
if (u == null) {
|
||||||
|
throw new Error('local user not found');
|
||||||
|
} else {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
})) as LocalUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
|
this.logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
|
||||||
return await this.apPersonService.createPerson(self.href);
|
return await this.apPersonService.createPerson(self.href);
|
||||||
}
|
}
|
||||||
@ -119,7 +137,7 @@ export class RemoteUserResolveService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async resolveSelf(acctLower: string) {
|
private async resolveSelf(acctLower: string): Promise<ILink> {
|
||||||
this.logger.info(`WebFinger for ${chalk.yellow(acctLower)}`);
|
this.logger.info(`WebFinger for ${chalk.yellow(acctLower)}`);
|
||||||
const finger = await this.webfingerService.webfinger(acctLower).catch(err => {
|
const finger = await this.webfingerService.webfinger(acctLower).catch(err => {
|
||||||
this.logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${ err.statusCode ?? err.message }`);
|
this.logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${ err.statusCode ?? err.message }`);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
|
import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
|
||||||
import { ModuleRef } from '@nestjs/core';
|
import { ModuleRef } from '@nestjs/core';
|
||||||
|
import { IsNull } from 'typeorm';
|
||||||
import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js';
|
import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
@ -21,9 +22,8 @@ import { UserBlockingService } from '@/core/UserBlockingService.js';
|
|||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import Logger from '../logger.js';
|
|
||||||
import { IsNull } from 'typeorm';
|
|
||||||
import { AccountMoveService } from '@/core/AccountMoveService.js';
|
import { AccountMoveService } from '@/core/AccountMoveService.js';
|
||||||
|
import Logger from '../logger.js';
|
||||||
|
|
||||||
const logger = new Logger('following/create');
|
const logger = new Logger('following/create');
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||||||
where: {
|
where: {
|
||||||
followerId: follower.id,
|
followerId: follower.id,
|
||||||
followeeId: followee.id,
|
followeeId: followee.id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (following === null || !following.follower || !following.followee) {
|
if (following === null || !following.follower || !following.followee) {
|
||||||
@ -412,8 +412,8 @@ export class UserFollowingService implements OnModuleInit {
|
|||||||
followerId: user.id,
|
followerId: user.id,
|
||||||
followee: {
|
followee: {
|
||||||
movedToUri: IsNull(),
|
movedToUri: IsNull(),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const nonMovedFollowers = await this.followingsRepository.count({
|
const nonMovedFollowers = await this.followingsRepository.count({
|
||||||
relations: {
|
relations: {
|
||||||
@ -423,8 +423,8 @@ export class UserFollowingService implements OnModuleInit {
|
|||||||
followeeId: user.id,
|
followeeId: user.id,
|
||||||
follower: {
|
follower: {
|
||||||
movedToUri: IsNull(),
|
movedToUri: IsNull(),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
await this.usersRepository.update(
|
await this.usersRepository.update(
|
||||||
{ id: user.id },
|
{ id: user.id },
|
||||||
@ -646,7 +646,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||||||
where: {
|
where: {
|
||||||
followeeId: followee.id,
|
followeeId: followee.id,
|
||||||
followerId: follower.id,
|
followerId: follower.id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!following || !following.followee || !following.follower) return;
|
if (!following || !following.followee || !following.follower) return;
|
||||||
|
@ -52,7 +52,7 @@ export class VideoProcessingService {
|
|||||||
query({
|
query({
|
||||||
thumbnail: '1',
|
thumbnail: '1',
|
||||||
url,
|
url,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@ import { query as urlQuery } from '@/misc/prelude/url.js';
|
|||||||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
type ILink = {
|
export type ILink = {
|
||||||
href: string;
|
href: string;
|
||||||
rel?: string;
|
rel?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type IWebFinger = {
|
export type IWebFinger = {
|
||||||
links: ILink[];
|
links: ILink[];
|
||||||
subject: string;
|
subject: string;
|
||||||
};
|
};
|
||||||
|
@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js';
|
|||||||
import type { AbuseUserReportsRepository } from '@/models/index.js';
|
import type { AbuseUserReportsRepository } from '@/models/index.js';
|
||||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||||
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
|
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
|
||||||
import { UserEntityService } from './UserEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { UserEntityService } from './UserEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AbuseUserReportEntityService {
|
export class AbuseUserReportEntityService {
|
||||||
|
@ -4,8 +4,8 @@ import type { AuthSessionsRepository } from '@/models/index.js';
|
|||||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||||
import type { AuthSession } from '@/models/entities/AuthSession.js';
|
import type { AuthSession } from '@/models/entities/AuthSession.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import { AppEntityService } from './AppEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { AppEntityService } from './AppEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthSessionEntityService {
|
export class AuthSessionEntityService {
|
||||||
|
@ -50,7 +50,7 @@ export class ChannelEntityService {
|
|||||||
const hasUnreadNote = meId ? await this.noteUnreadsRepository.exist({
|
const hasUnreadNote = meId ? await this.noteUnreadsRepository.exist({
|
||||||
where: {
|
where: {
|
||||||
noteChannelId: channel.id,
|
noteChannelId: channel.id,
|
||||||
userId: meId
|
userId: meId,
|
||||||
},
|
},
|
||||||
}) : undefined;
|
}) : undefined;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ import type { FollowRequestsRepository } from '@/models/index.js';
|
|||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import type { FollowRequest } from '@/models/entities/FollowRequest.js';
|
import type { FollowRequest } from '@/models/entities/FollowRequest.js';
|
||||||
import { UserEntityService } from './UserEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { UserEntityService } from './UserEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FollowRequestEntityService {
|
export class FollowRequestEntityService {
|
||||||
|
@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js';
|
|||||||
import type { GalleryLikesRepository } from '@/models/index.js';
|
import type { GalleryLikesRepository } from '@/models/index.js';
|
||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { GalleryLike } from '@/models/entities/GalleryLike.js';
|
import type { GalleryLike } from '@/models/entities/GalleryLike.js';
|
||||||
import { GalleryPostEntityService } from './GalleryPostEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { GalleryPostEntityService } from './GalleryPostEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GalleryLikeEntityService {
|
export class GalleryLikeEntityService {
|
||||||
|
@ -4,8 +4,8 @@ import type { ModerationLogsRepository } from '@/models/index.js';
|
|||||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { ModerationLog } from '@/models/entities/ModerationLog.js';
|
import type { ModerationLog } from '@/models/entities/ModerationLog.js';
|
||||||
import { UserEntityService } from './UserEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { UserEntityService } from './UserEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ModerationLogEntityService {
|
export class ModerationLogEntityService {
|
||||||
|
@ -4,8 +4,8 @@ import type { NoteFavoritesRepository } from '@/models/index.js';
|
|||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import type { NoteFavorite } from '@/models/entities/NoteFavorite.js';
|
import type { NoteFavorite } from '@/models/entities/NoteFavorite.js';
|
||||||
import { NoteEntityService } from './NoteEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { NoteEntityService } from './NoteEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NoteFavoriteEntityService {
|
export class NoteFavoriteEntityService {
|
||||||
|
@ -4,8 +4,8 @@ import type { PageLikesRepository } from '@/models/index.js';
|
|||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import type { PageLike } from '@/models/entities/PageLike.js';
|
import type { PageLike } from '@/models/entities/PageLike.js';
|
||||||
import { PageEntityService } from './PageEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { PageEntityService } from './PageEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PageLikeEntityService {
|
export class PageLikeEntityService {
|
||||||
|
@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js';
|
|||||||
import type { SigninsRepository } from '@/models/index.js';
|
import type { SigninsRepository } from '@/models/index.js';
|
||||||
import type { } from '@/models/entities/Blocking.js';
|
import type { } from '@/models/entities/Blocking.js';
|
||||||
import type { Signin } from '@/models/entities/Signin.js';
|
import type { Signin } from '@/models/entities/Signin.js';
|
||||||
import { UserEntityService } from './UserEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { UserEntityService } from './UserEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SigninEntityService {
|
export class SigninEntityService {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Writable, WritableOptions } from "node:stream";
|
import { Writable, WritableOptions } from 'node:stream';
|
||||||
|
|
||||||
export class DevNull extends Writable implements NodeJS.WritableStream {
|
export class DevNull extends Writable implements NodeJS.WritableStream {
|
||||||
constructor(opts?: WritableOptions) {
|
constructor(opts?: WritableOptions) {
|
||||||
super(opts);
|
super(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
_write (chunk: any, encoding: BufferEncoding, cb: (err?: Error | null) => void) {
|
_write (chunk: any, encoding: BufferEncoding, cb: (err?: Error | null) => void) {
|
||||||
setImmediate(cb);
|
setImmediate(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ const CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
|
|||||||
export const ulidRegExp = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
|
export const ulidRegExp = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
|
||||||
|
|
||||||
export function parseUlid(id: string): { date: Date; } {
|
export function parseUlid(id: string): { date: Date; } {
|
||||||
const timestamp = id.slice(0, 10);
|
const timestamp = id.slice(0, 10);
|
||||||
let time = 0;
|
let time = 0;
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
time = time * 32 + CHARS.indexOf(timestamp[i]);
|
time = time * 32 + CHARS.indexOf(timestamp[i]);
|
||||||
}
|
}
|
||||||
return { date: new Date(time) };
|
return { date: new Date(time) };
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export async function awaitAll<T>(obj: Promiseable<T>): Promise<T> {
|
|||||||
const resolvedValues = await Promise.all(values.map(value =>
|
const resolvedValues = await Promise.all(values.map(value =>
|
||||||
(!value || !value.constructor || value.constructor.name !== 'Object')
|
(!value || !value.constructor || value.constructor.name !== 'Object')
|
||||||
? value
|
? value
|
||||||
: awaitAll(value)
|
: awaitAll(value),
|
||||||
));
|
));
|
||||||
|
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
@ -49,7 +49,6 @@ import { User } from '@/models/entities/User.js';
|
|||||||
import { UserIp } from '@/models/entities/UserIp.js';
|
import { UserIp } from '@/models/entities/UserIp.js';
|
||||||
import { UserKeypair } from '@/models/entities/UserKeypair.js';
|
import { UserKeypair } from '@/models/entities/UserKeypair.js';
|
||||||
import { UserList } from '@/models/entities/UserList.js';
|
import { UserList } from '@/models/entities/UserList.js';
|
||||||
import { UserListFavorite } from './entities/UserListFavorite.js';
|
|
||||||
import { UserListJoining } from '@/models/entities/UserListJoining.js';
|
import { UserListJoining } from '@/models/entities/UserListJoining.js';
|
||||||
import { UserNotePining } from '@/models/entities/UserNotePining.js';
|
import { UserNotePining } from '@/models/entities/UserNotePining.js';
|
||||||
import { UserPending } from '@/models/entities/UserPending.js';
|
import { UserPending } from '@/models/entities/UserPending.js';
|
||||||
@ -64,6 +63,7 @@ import { Role } from '@/models/entities/Role.js';
|
|||||||
import { RoleAssignment } from '@/models/entities/RoleAssignment.js';
|
import { RoleAssignment } from '@/models/entities/RoleAssignment.js';
|
||||||
import { Flash } from '@/models/entities/Flash.js';
|
import { Flash } from '@/models/entities/Flash.js';
|
||||||
import { FlashLike } from '@/models/entities/FlashLike.js';
|
import { FlashLike } from '@/models/entities/FlashLike.js';
|
||||||
|
import { UserListFavorite } from './entities/UserListFavorite.js';
|
||||||
import type { Repository } from 'typeorm';
|
import type { Repository } from 'typeorm';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -9,10 +9,10 @@ import type { DriveFile } from '@/models/entities/DriveFile.js';
|
|||||||
import type { Note } from '@/models/entities/Note.js';
|
import type { Note } from '@/models/entities/Note.js';
|
||||||
import { EmailService } from '@/core/EmailService.js';
|
import { EmailService } from '@/core/EmailService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { SearchService } from '@/core/SearchService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
import type { DbUserDeleteJobData } from '../types.js';
|
import type { DbUserDeleteJobData } from '../types.js';
|
||||||
import { SearchService } from "@/core/SearchService.js";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteAccountProcessorService {
|
export class DeleteAccountProcessorService {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type * as Bull from 'bullmq';
|
|
||||||
|
|
||||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||||
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
|
||||||
import { RelationshipJobData } from '../types.js';
|
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
||||||
|
import { RelationshipJobData } from '../types.js';
|
||||||
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type * as Bull from 'bullmq';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RelationshipProcessorService {
|
export class RelationshipProcessorService {
|
||||||
|
@ -3,6 +3,8 @@ import { fileURLToPath } from 'node:url';
|
|||||||
import { dirname } from 'node:path';
|
import { dirname } from 'node:path';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import rename from 'rename';
|
import rename from 'rename';
|
||||||
|
import sharp from 'sharp';
|
||||||
|
import { sharpBmp } from 'sharp-read-bmp';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { DriveFile, DriveFilesRepository } from '@/models/index.js';
|
import type { DriveFile, DriveFilesRepository } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
@ -18,11 +20,9 @@ import { contentDisposition } from '@/misc/content-disposition.js';
|
|||||||
import { FileInfoService } from '@/core/FileInfoService.js';
|
import { FileInfoService } from '@/core/FileInfoService.js';
|
||||||
import { LoggerService } from '@/core/LoggerService.js';
|
import { LoggerService } from '@/core/LoggerService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
|
|
||||||
import { isMimeImage } from '@/misc/is-mime-image.js';
|
import { isMimeImage } from '@/misc/is-mime-image.js';
|
||||||
import sharp from 'sharp';
|
|
||||||
import { sharpBmp } from 'sharp-read-bmp';
|
|
||||||
import { correctFilename } from '@/misc/correct-filename.js';
|
import { correctFilename } from '@/misc/correct-filename.js';
|
||||||
|
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
|
||||||
|
|
||||||
const _filename = fileURLToPath(import.meta.url);
|
const _filename = fileURLToPath(import.meta.url);
|
||||||
const _dirname = dirname(_filename);
|
const _dirname = dirname(_filename);
|
||||||
@ -180,8 +180,8 @@ export class FileServerService {
|
|||||||
reply.header('Content-Disposition',
|
reply.header('Content-Disposition',
|
||||||
contentDisposition(
|
contentDisposition(
|
||||||
'inline',
|
'inline',
|
||||||
correctFilename(file.filename, image.ext)
|
correctFilename(file.filename, image.ext),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
return image.data;
|
return image.data;
|
||||||
}
|
}
|
||||||
@ -278,11 +278,11 @@ export class FileServerService {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const data = (await sharpBmp(file.path, file.mime, { animated: !('static' in request.query) }))
|
const data = (await sharpBmp(file.path, file.mime, { animated: !('static' in request.query) }))
|
||||||
.resize({
|
.resize({
|
||||||
height: 'emoji' in request.query ? 128 : 320,
|
height: 'emoji' in request.query ? 128 : 320,
|
||||||
withoutEnlargement: true,
|
withoutEnlargement: true,
|
||||||
})
|
})
|
||||||
.webp(webpDefault);
|
.webp(webpDefault);
|
||||||
|
|
||||||
image = {
|
image = {
|
||||||
data,
|
data,
|
||||||
@ -355,8 +355,8 @@ export class FileServerService {
|
|||||||
reply.header('Content-Disposition',
|
reply.header('Content-Disposition',
|
||||||
contentDisposition(
|
contentDisposition(
|
||||||
'inline',
|
'inline',
|
||||||
correctFilename(file.filename, image.ext)
|
correctFilename(file.filename, image.ext),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
return image.data;
|
return image.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { IsNull } from 'typeorm';
|
import { IsNull } from 'typeorm';
|
||||||
import vary from 'vary';
|
import vary from 'vary';
|
||||||
|
import fastifyAccepts from '@fastify/accepts';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { escapeAttribute, escapeValue } from '@/misc/prelude/xml.js';
|
import { escapeAttribute, escapeValue } from '@/misc/prelude/xml.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import * as Acct from '@/misc/acct.js';
|
import * as Acct from '@/misc/acct.js';
|
||||||
import { NodeinfoServerService } from './NodeinfoServerService.js';
|
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import type { FindOptionsWhere } from 'typeorm';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { NodeinfoServerService } from './NodeinfoServerService.js';
|
||||||
|
import type { FindOptionsWhere } from 'typeorm';
|
||||||
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
|
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
|
||||||
import fastifyAccepts from '@fastify/accepts';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WellKnownServerService {
|
export class WellKnownServerService {
|
||||||
|
@ -13,9 +13,9 @@ import { EmailService } from '@/core/EmailService.js';
|
|||||||
import { LocalUser } from '@/models/entities/User.js';
|
import { LocalUser } from '@/models/entities/User.js';
|
||||||
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
||||||
import { SigninService } from './SigninService.js';
|
import { SigninService } from './SigninService.js';
|
||||||
import type { FastifyRequest, FastifyReply } from 'fastify';
|
import type { FastifyRequest, FastifyReply } from 'fastify';
|
||||||
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SignupApiService {
|
export class SignupApiService {
|
||||||
|
@ -91,7 +91,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
|
|
||||||
if (queryarry) {
|
if (queryarry) {
|
||||||
emojis = emojis.filter(emoji =>
|
emojis = emojis.filter(emoji =>
|
||||||
queryarry.includes(`:${emoji.name}:`)
|
queryarry.includes(`:${emoji.name}:`),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
emojis = emojis.filter(emoji =>
|
emojis = emojis.filter(emoji =>
|
||||||
|
@ -5,8 +5,8 @@ import type { UsersRepository, BlockingsRepository } from '@/models/index.js';
|
|||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['account'],
|
tags: ['account'],
|
||||||
@ -88,7 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
where: {
|
where: {
|
||||||
blockerId: blocker.id,
|
blockerId: blocker.id,
|
||||||
blockeeId: blockee.id,
|
blockeeId: blockee.id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
|
@ -2,8 +2,8 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js';
|
import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['account', 'notes', 'clips'],
|
tags: ['account', 'notes', 'clips'],
|
||||||
|
@ -5,8 +5,8 @@ import type { UsersRepository, FollowingsRepository } from '@/models/index.js';
|
|||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['following', 'users'],
|
tags: ['following', 'users'],
|
||||||
|
@ -5,8 +5,8 @@ import type { UsersRepository, FollowingsRepository } from '@/models/index.js';
|
|||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['following', 'users'],
|
tags: ['following', 'users'],
|
||||||
|
@ -23,7 +23,7 @@ export const meta = {
|
|||||||
id: 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a',
|
id: 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a',
|
||||||
kind: 'permission',
|
kind: 'permission',
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -267,7 +267,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const instance = await this.metaService.fetch(true);
|
const instance = await this.metaService.fetch(true);
|
||||||
|
|
||||||
const ads = await this.adsRepository.createQueryBuilder("ads")
|
const ads = await this.adsRepository.createQueryBuilder('ads')
|
||||||
.where('ads.expiresAt > :now', { now: new Date() })
|
.where('ads.expiresAt > :now', { now: new Date() })
|
||||||
.andWhere('ads.startsAt <= :now', { now: new Date() })
|
.andWhere('ads.startsAt <= :now', { now: new Date() })
|
||||||
.andWhere(new Brackets(qb => {
|
.andWhere(new Brackets(qb => {
|
||||||
|
@ -4,8 +4,8 @@ import type { NotesRepository } from '@/models/index.js';
|
|||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['notes'],
|
tags: ['notes'],
|
||||||
|
@ -3,8 +3,8 @@ import type { NotesRepository } from '@/models/index.js';
|
|||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['notes'],
|
tags: ['notes'],
|
||||||
|
@ -3,8 +3,8 @@ import type { PromoReadsRepository } from '@/models/index.js';
|
|||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['notes'],
|
tags: ['notes'],
|
||||||
|
@ -35,7 +35,7 @@ export const meta = {
|
|||||||
code: 'NO_SUCH_REGISTRATION',
|
code: 'NO_SUCH_REGISTRATION',
|
||||||
id: ' b09d8066-8064-5613-efb6-0e963b21d012',
|
id: ' b09d8066-8064-5613-efb6-0e963b21d012',
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -5,8 +5,8 @@ import type { NotesRepository, UsersRepository } from '@/models/index.js';
|
|||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['users'],
|
tags: ['users'],
|
||||||
|
@ -3,9 +3,9 @@ import { isUserRelated } from '@/misc/is-user-related.js';
|
|||||||
import type { Packed } from '@/misc/json-schema.js';
|
import type { Packed } from '@/misc/json-schema.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
import Channel from '../channel.js';
|
import Channel from '../channel.js';
|
||||||
import { StreamMessages } from '../types.js';
|
import { StreamMessages } from '../types.js';
|
||||||
import { RoleService } from '@/core/RoleService.js';
|
|
||||||
|
|
||||||
class RoleTimelineChannel extends Channel {
|
class RoleTimelineChannel extends Channel {
|
||||||
public readonly chName = 'roleTimeline';
|
public readonly chName = 'roleTimeline';
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
"@rollup/plugin-json": "6.0.0",
|
"@rollup/plugin-json": "6.0.0",
|
||||||
"@rollup/plugin-replace": "5.0.2",
|
"@rollup/plugin-replace": "5.0.2",
|
||||||
"@rollup/pluginutils": "5.0.2",
|
"@rollup/pluginutils": "5.0.2",
|
||||||
"@syuilo/aiscript": "0.13.3",
|
"@syuilo/aiscript": "0.14.0",
|
||||||
"@tabler/icons-webfont": "2.25.0",
|
"@tabler/icons-webfont": "2.25.0",
|
||||||
"@vitejs/plugin-vue": "4.2.3",
|
"@vitejs/plugin-vue": "4.2.3",
|
||||||
"@vue-macros/reactivity-transform": "0.3.14",
|
"@vue-macros/reactivity-transform": "0.3.15",
|
||||||
"@vue/compiler-sfc": "3.3.4",
|
"@vue/compiler-sfc": "3.3.4",
|
||||||
"astring": "1.8.6",
|
"astring": "1.8.6",
|
||||||
"autosize": "6.0.1",
|
"autosize": "6.0.1",
|
||||||
@ -54,7 +54,7 @@
|
|||||||
"prismjs": "1.29.0",
|
"prismjs": "1.29.0",
|
||||||
"punycode": "2.3.0",
|
"punycode": "2.3.0",
|
||||||
"querystring": "0.2.1",
|
"querystring": "0.2.1",
|
||||||
"rollup": "3.26.2",
|
"rollup": "3.26.3",
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
"sanitize-html": "2.11.0",
|
"sanitize-html": "2.11.0",
|
||||||
"sass": "1.63.6",
|
"sass": "1.63.6",
|
||||||
@ -76,24 +76,24 @@
|
|||||||
"vuedraggable": "next"
|
"vuedraggable": "next"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@storybook/addon-actions": "7.0.27",
|
"@storybook/addon-actions": "7.1.0",
|
||||||
"@storybook/addon-essentials": "7.0.27",
|
"@storybook/addon-essentials": "7.1.0",
|
||||||
"@storybook/addon-interactions": "7.0.27",
|
"@storybook/addon-interactions": "7.1.0",
|
||||||
"@storybook/addon-links": "7.0.27",
|
"@storybook/addon-links": "7.1.0",
|
||||||
"@storybook/addon-storysource": "7.0.27",
|
"@storybook/addon-storysource": "7.1.0",
|
||||||
"@storybook/addons": "7.0.27",
|
"@storybook/addons": "7.1.0",
|
||||||
"@storybook/blocks": "7.0.27",
|
"@storybook/blocks": "7.1.0",
|
||||||
"@storybook/core-events": "7.0.27",
|
"@storybook/core-events": "7.1.0",
|
||||||
"@storybook/jest": "0.1.0",
|
"@storybook/jest": "0.1.0",
|
||||||
"@storybook/manager-api": "7.0.27",
|
"@storybook/manager-api": "7.1.0",
|
||||||
"@storybook/preview-api": "7.0.27",
|
"@storybook/preview-api": "7.1.0",
|
||||||
"@storybook/react": "7.0.27",
|
"@storybook/react": "7.1.0",
|
||||||
"@storybook/react-vite": "7.0.27",
|
"@storybook/react-vite": "7.1.0",
|
||||||
"@storybook/testing-library": "0.2.0",
|
"@storybook/testing-library": "0.2.0",
|
||||||
"@storybook/theming": "7.0.27",
|
"@storybook/theming": "7.1.0",
|
||||||
"@storybook/types": "7.0.27",
|
"@storybook/types": "7.1.0",
|
||||||
"@storybook/vue3": "7.0.27",
|
"@storybook/vue3": "7.1.0",
|
||||||
"@storybook/vue3-vite": "7.0.27",
|
"@storybook/vue3-vite": "7.1.0",
|
||||||
"@testing-library/jest-dom": "5.16.5",
|
"@testing-library/jest-dom": "5.16.5",
|
||||||
"@testing-library/vue": "7.0.0",
|
"@testing-library/vue": "7.0.0",
|
||||||
"@types/escape-regexp": "0.0.1",
|
"@types/escape-regexp": "0.0.1",
|
||||||
@ -131,7 +131,7 @@
|
|||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"start-server-and-test": "2.0.0",
|
"start-server-and-test": "2.0.0",
|
||||||
"storybook": "7.0.27",
|
"storybook": "7.1.0",
|
||||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||||
"summaly": "github:misskey-dev/summaly",
|
"summaly": "github:misskey-dev/summaly",
|
||||||
"vite-plugin-turbosnap": "1.0.2",
|
"vite-plugin-turbosnap": "1.0.2",
|
||||||
|
@ -259,6 +259,17 @@ useTooltip(renoteButton, async (showing) => {
|
|||||||
}, {}, 'closed');
|
}, {}, 'closed');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type Visibility = 'public' | 'home' | 'followers' | 'specified';
|
||||||
|
|
||||||
|
// defaultStore.state.visibilityがstringなためstringも受け付けている
|
||||||
|
function smallerVisibility(a: Visibility | string, b: Visibility | string): Visibility {
|
||||||
|
if (a === 'specified' || b === 'specified') return 'specified';
|
||||||
|
if (a === 'followers' || b === 'followers') return 'followers';
|
||||||
|
if (a === 'home' || b === 'home') return 'home';
|
||||||
|
// if (a === 'public' || b === 'public')
|
||||||
|
return 'public';
|
||||||
|
}
|
||||||
|
|
||||||
function renote(viaKeyboard = false) {
|
function renote(viaKeyboard = false) {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
showMovedDialog();
|
showMovedDialog();
|
||||||
@ -309,7 +320,12 @@ function renote(viaKeyboard = false) {
|
|||||||
os.popup(MkRippleEffect, { x, y }, {}, 'end');
|
os.popup(MkRippleEffect, { x, y }, {}, 'end');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const configuredVisibility = defaultStore.state.rememberNoteVisibility ? defaultStore.state.visibility : defaultStore.state.defaultNoteVisibility;
|
||||||
|
const localOnly = defaultStore.state.rememberNoteVisibility ? defaultStore.state.localOnly : defaultStore.state.defaultNoteLocalOnly;
|
||||||
|
|
||||||
os.api('notes/create', {
|
os.api('notes/create', {
|
||||||
|
localOnly,
|
||||||
|
visibility: smallerVisibility(appearNote.visibility, configuredVisibility),
|
||||||
renoteId: appearNote.id,
|
renoteId: appearNote.id,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
os.toast(i18n.ts.renoted);
|
os.toast(i18n.ts.renoted);
|
||||||
|
@ -907,6 +907,7 @@ defineExpose({
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
margin-bottom: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.headerLeft {
|
.headerLeft {
|
||||||
@ -1024,7 +1025,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.targetNote {
|
.targetNote {
|
||||||
padding: 0 20px 16px 20px;
|
padding: 10px 20px 16px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.withQuote {
|
.withQuote {
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div :class="$style.status">
|
<div :class="$style.status">
|
||||||
<div :class="$style.statusItem">
|
<div :class="$style.statusItem">
|
||||||
<p :class="$style.statusItemLabel">{{ i18n.ts.notes }}</p><span :class="$style.statusItemValue">{{ user.notesCount }}</span>
|
<p :class="$style.statusItemLabel">{{ i18n.ts.notes }}</p><span :class="$style.statusItemValue">{{ number(user.notesCount) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.statusItem">
|
<div v-if="isFfVisibleForMe(user)" :class="$style.statusItem">
|
||||||
<p :class="$style.statusItemLabel">{{ i18n.ts.following }}</p><span :class="$style.statusItemValue">{{ user.followingCount }}</span>
|
<p :class="$style.statusItemLabel">{{ i18n.ts.following }}</p><span :class="$style.statusItemValue">{{ number(user.followingCount) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.statusItem">
|
<div v-if="isFfVisibleForMe(user)" :class="$style.statusItem">
|
||||||
<p :class="$style.statusItemLabel">{{ i18n.ts.followers }}</p><span :class="$style.statusItemValue">{{ user.followersCount }}</span>
|
<p :class="$style.statusItemLabel">{{ i18n.ts.followers }}</p><span :class="$style.statusItemValue">{{ number(user.followersCount) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MkFollowButton v-if="$i && user.id != $i.id" :class="$style.follow" :user="user" mini/>
|
<MkFollowButton v-if="$i && user.id != $i.id" :class="$style.follow" :user="user" mini/>
|
||||||
@ -31,9 +31,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import MkFollowButton from '@/components/MkFollowButton.vue';
|
import MkFollowButton from '@/components/MkFollowButton.vue';
|
||||||
|
import number from '@/filters/number';
|
||||||
import { userPage } from '@/filters/user';
|
import { userPage } from '@/filters/user';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
import { isFfVisibleForMe } from '@/scripts/isFfVisibleForMe';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
user: misskey.entities.UserDetailed;
|
user: misskey.entities.UserDetailed;
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
<div :class="$style.statusItemLabel">{{ i18n.ts.notes }}</div>
|
<div :class="$style.statusItemLabel">{{ i18n.ts.notes }}</div>
|
||||||
<div>{{ number(user.notesCount) }}</div>
|
<div>{{ number(user.notesCount) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.statusItem">
|
<div v-if="isFfVisibleForMe(user)" :class="$style.statusItem">
|
||||||
<div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
|
<div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
|
||||||
<div>{{ number(user.followingCount) }}</div>
|
<div>{{ number(user.followingCount) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.statusItem">
|
<div v-if="isFfVisibleForMe(user)" :class="$style.statusItem">
|
||||||
<div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
|
<div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
|
||||||
<div>{{ number(user.followersCount) }}</div>
|
<div>{{ number(user.followersCount) }}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -61,6 +61,7 @@ import number from '@/filters/number';
|
|||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
import { isFfVisibleForMe } from '@/scripts/isFfVisibleForMe';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
showing: boolean;
|
showing: boolean;
|
||||||
|
@ -33,7 +33,7 @@ import MkTextarea from '@/components/MkTextarea.vue';
|
|||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import { useRouter } from '@/router';
|
import { useRouter } from '@/router';
|
||||||
|
|
||||||
const PRESET_DEFAULT = `/// @ 0.13.3
|
const PRESET_DEFAULT = `/// @ 0.14.0
|
||||||
|
|
||||||
var name = ""
|
var name = ""
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ Ui:render([
|
|||||||
])
|
])
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PRESET_OMIKUJI = `/// @ 0.13.3
|
const PRESET_OMIKUJI = `/// @ 0.14.0
|
||||||
// ユーザーごとに日替わりのおみくじのプリセット
|
// ユーザーごとに日替わりのおみくじのプリセット
|
||||||
|
|
||||||
// 選択肢
|
// 選択肢
|
||||||
@ -94,7 +94,7 @@ Ui:render([
|
|||||||
])
|
])
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PRESET_SHUFFLE = `/// @ 0.13.3
|
const PRESET_SHUFFLE = `/// @ 0.14.0
|
||||||
// 巻き戻し可能な文字シャッフルのプリセット
|
// 巻き戻し可能な文字シャッフルのプリセット
|
||||||
|
|
||||||
let string = "ペペロンチーノ"
|
let string = "ペペロンチーノ"
|
||||||
@ -173,7 +173,7 @@ var cursor = 0
|
|||||||
do()
|
do()
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PRESET_QUIZ = `/// @ 0.13.3
|
const PRESET_QUIZ = `/// @ 0.14.0
|
||||||
let title = '地理クイズ'
|
let title = '地理クイズ'
|
||||||
|
|
||||||
let qas = [{
|
let qas = [{
|
||||||
@ -286,7 +286,7 @@ qaEls.push(Ui:C:container({
|
|||||||
Ui:render(qaEls)
|
Ui:render(qaEls)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PRESET_TIMELINE = `/// @ 0.13.3
|
const PRESET_TIMELINE = `/// @ 0.14.0
|
||||||
// APIリクエストを行いローカルタイムラインを表示するプリセット
|
// APIリクエストを行いローカルタイムラインを表示するプリセット
|
||||||
|
|
||||||
@fetch() {
|
@fetch() {
|
||||||
|
@ -100,15 +100,15 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<MkA v-click-anime :to="userPage(user)">
|
<MkA :to="userPage(user)">
|
||||||
<b>{{ number(user.notesCount) }}</b>
|
<b>{{ number(user.notesCount) }}</b>
|
||||||
<span>{{ i18n.ts.notes }}</span>
|
<span>{{ i18n.ts.notes }}</span>
|
||||||
</MkA>
|
</MkA>
|
||||||
<MkA v-click-anime :to="userPage(user, 'following')">
|
<MkA v-if="isFfVisibleForMe(user)" :to="userPage(user, 'following')">
|
||||||
<b>{{ number(user.followingCount) }}</b>
|
<b>{{ number(user.followingCount) }}</b>
|
||||||
<span>{{ i18n.ts.following }}</span>
|
<span>{{ i18n.ts.following }}</span>
|
||||||
</MkA>
|
</MkA>
|
||||||
<MkA v-click-anime :to="userPage(user, 'followers')">
|
<MkA v-if="isFfVisibleForMe(user)" :to="userPage(user, 'followers')">
|
||||||
<b>{{ number(user.followersCount) }}</b>
|
<b>{{ number(user.followersCount) }}</b>
|
||||||
<span>{{ i18n.ts.followers }}</span>
|
<span>{{ i18n.ts.followers }}</span>
|
||||||
</MkA>
|
</MkA>
|
||||||
@ -160,6 +160,7 @@ import { dateString } from '@/filters/date';
|
|||||||
import { confetti } from '@/scripts/confetti';
|
import { confetti } from '@/scripts/confetti';
|
||||||
import MkNotes from '@/components/MkNotes.vue';
|
import MkNotes from '@/components/MkNotes.vue';
|
||||||
import { api } from '@/os';
|
import { api } from '@/os';
|
||||||
|
import { isFfVisibleForMe } from '@/scripts/isFfVisibleForMe';
|
||||||
|
|
||||||
const XPhotos = defineAsyncComponent(() => import('./index.photos.vue'));
|
const XPhotos = defineAsyncComponent(() => import('./index.photos.vue'));
|
||||||
const XActivity = defineAsyncComponent(() => import('./index.activity.vue'));
|
const XActivity = defineAsyncComponent(() => import('./index.activity.vue'));
|
||||||
|
11
packages/frontend/src/scripts/isFfVisibleForMe.ts
Normal file
11
packages/frontend/src/scripts/isFfVisibleForMe.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import * as misskey from 'misskey-js';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
|
export function isFfVisibleForMe(user: misskey.entities.UserDetailed): boolean {
|
||||||
|
if ($i && $i.id === user.id) return true;
|
||||||
|
|
||||||
|
if (user.ffVisibility === 'private') return false;
|
||||||
|
if (user.ffVisibility === 'followers' && !user.isFollowing) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
3513
pnpm-lock.yaml
3513
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user