Repository navigation
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 40 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
⛔ Files ignored due to path filters (3)
📒 Files selected for processing (31)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🖥 Frontend Diagnostics Report(No significant changes) Requests by resource type
V8 heap snapshot statistics
📦 Bundle StatsChunk size diff (1 updated, 0 added, 0 removed)
Startup chunk size (0 updated, 0 added, 0 removed)
Startup chunks are the Vite entry for
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mattyatea
added this pull request to stack #79
October 6, 2026 16:06
|
このPRによるapi.jsonの差分 差分はこちら--- base
+++ head
@@ -36511,6 +36511,620 @@
}
}
},
+ "/calls/watch-together/show": {
+ "post": {
+ "operationId": "post___calls___watch-together___show",
+ "summary": "calls/watch-together/show",
+ "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *read:calls*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/calls/watch-together/show.ts"
+ },
+ "tags": [
+ "calls"
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "roomId": {
+ "type": "string",
+ "format": "misskey:id"
+ }
+ },
+ "required": [
+ "roomId"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "queue": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "videoId": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "playing": {
+ "type": "boolean"
+ },
+ "position": {
+ "type": "number"
+ },
+ "updatedAt": {
+ "type": "number"
+ },
+ "revision": {
+ "type": "integer"
+ },
+ "serverTime": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "queue",
+ "videoId",
+ "playing",
+ "position",
+ "updatedAt",
+ "revision",
+ "serverTime"
+ ]
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CALLS_ACCESS_DENIED": {
+ "value": {
+ "error": {
+ "message": "You do not have access to this Calls room.",
+ "code": "CALLS_ACCESS_DENIED",
+ "id": "3a432e2d-51e8-42f4-ae52-d2b0a7b89afa"
+ }
+ }
+ },
+ "CALLS_ATTACHMENT_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The attached room does not exist.",
+ "code": "CALLS_ATTACHMENT_NOT_FOUND",
+ "id": "5985f4cf-84bb-4997-9e68-46f421f29e84"
+ }
+ }
+ },
+ "CALLS_ACTIVE_ATTACHMENT": {
+ "value": {
+ "error": {
+ "message": "An active Calls room already exists for this attachment.",
+ "code": "CALLS_ACTIVE_ATTACHMENT",
+ "id": "4a8fd21d-0d68-4b8d-884c-9970f1d5f1f4"
+ }
+ }
+ },
+ "CALLS_INVALID_STATE": {
+ "value": {
+ "error": {
+ "message": "The Calls room is not in the required state.",
+ "code": "CALLS_INVALID_STATE",
+ "id": "27bbe09b-c516-4c8a-a9fc-4b5c8de79cbb"
+ }
+ }
+ },
+ "CALLS_INVALID_METADATA": {
+ "value": {
+ "error": {
+ "message": "The Calls room metadata is invalid.",
+ "code": "CALLS_INVALID_METADATA",
+ "id": "7fc75953-7ec9-4e2f-aee2-af12a8101971"
+ }
+ }
+ },
+ "CALLS_PARTICIPANT_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The Calls participant does not exist.",
+ "code": "CALLS_PARTICIPANT_NOT_FOUND",
+ "id": "17e679a9-0ad9-4fe0-a09f-92dae12e445a"
+ }
+ }
+ },
+ "CALLS_ROOM_FULL": {
+ "value": {
+ "error": {
+ "message": "The Calls room participant limit has been reached.",
+ "code": "CALLS_ROOM_FULL",
+ "id": "0b5e0eea-8c21-433c-94f9-e2359c57096e"
+ }
+ }
+ },
+ "CALLS_ROOM_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The Calls room does not exist.",
+ "code": "CALLS_ROOM_NOT_FOUND",
+ "id": "09fd2742-0fc7-4222-ad41-1c395427a7d1"
+ }
+ }
+ },
+ "CALLS_STALE_REVISION": {
+ "value": {
+ "error": {
+ "message": "The Calls room revision is stale.",
+ "code": "CALLS_STALE_REVISION",
+ "id": "fde2c128-2b65-4784-a0de-59f20eb901c1"
+ }
+ }
+ },
+ "CALLS_FEATURE_DISABLED": {
+ "value": {
+ "error": {
+ "message": "Misskey Calls is disabled on this instance.",
+ "code": "CALLS_FEATURE_DISABLED",
+ "id": "bc70cfca-3247-4cd5-a9b7-a88b381195af"
+ }
+ }
+ },
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/calls/watch-together/update": {
+ "post": {
+ "operationId": "post___calls___watch-together___update",
+ "summary": "calls/watch-together/update",
+ "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *write:calls*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/calls/watch-together/update.ts"
+ },
+ "tags": [
+ "calls"
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "roomId": {
+ "type": "string",
+ "format": "misskey:id"
+ },
+ "queue": {
+ "type": "array",
+ "maxItems": 50,
+ "items": {
+ "type": "string",
+ "pattern": "^[A-Za-z0-9_-]{11}$"
+ }
+ },
+ "expectedRevision": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "videoId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^[A-Za-z0-9_-]{11}$"
+ },
+ "playing": {
+ "type": "boolean"
+ },
+ "position": {
+ "type": "number",
+ "minimum": 0
+ }
+ },
+ "required": [
+ "roomId",
+ "expectedRevision"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "queue": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "videoId": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "playing": {
+ "type": "boolean"
+ },
+ "position": {
+ "type": "number"
+ },
+ "updatedAt": {
+ "type": "number"
+ },
+ "revision": {
+ "type": "integer"
+ },
+ "serverTime": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "queue",
+ "videoId",
+ "playing",
+ "position",
+ "updatedAt",
+ "revision",
+ "serverTime"
+ ]
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CALLS_ACCESS_DENIED": {
+ "value": {
+ "error": {
+ "message": "You do not have access to this Calls room.",
+ "code": "CALLS_ACCESS_DENIED",
+ "id": "3a432e2d-51e8-42f4-ae52-d2b0a7b89afa"
+ }
+ }
+ },
+ "CALLS_ATTACHMENT_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The attached room does not exist.",
+ "code": "CALLS_ATTACHMENT_NOT_FOUND",
+ "id": "5985f4cf-84bb-4997-9e68-46f421f29e84"
+ }
+ }
+ },
+ "CALLS_ACTIVE_ATTACHMENT": {
+ "value": {
+ "error": {
+ "message": "An active Calls room already exists for this attachment.",
+ "code": "CALLS_ACTIVE_ATTACHMENT",
+ "id": "4a8fd21d-0d68-4b8d-884c-9970f1d5f1f4"
+ }
+ }
+ },
+ "CALLS_INVALID_STATE": {
+ "value": {
+ "error": {
+ "message": "The Calls room is not in the required state.",
+ "code": "CALLS_INVALID_STATE",
+ "id": "27bbe09b-c516-4c8a-a9fc-4b5c8de79cbb"
+ }
+ }
+ },
+ "CALLS_INVALID_METADATA": {
+ "value": {
+ "error": {
+ "message": "The Calls room metadata is invalid.",
+ "code": "CALLS_INVALID_METADATA",
+ "id": "7fc75953-7ec9-4e2f-aee2-af12a8101971"
+ }
+ }
+ },
+ "CALLS_PARTICIPANT_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The Calls participant does not exist.",
+ "code": "CALLS_PARTICIPANT_NOT_FOUND",
+ "id": "17e679a9-0ad9-4fe0-a09f-92dae12e445a"
+ }
+ }
+ },
+ "CALLS_ROOM_FULL": {
+ "value": {
+ "error": {
+ "message": "The Calls room participant limit has been reached.",
+ "code": "CALLS_ROOM_FULL",
+ "id": "0b5e0eea-8c21-433c-94f9-e2359c57096e"
+ }
+ }
+ },
+ "CALLS_ROOM_NOT_FOUND": {
+ "value": {
+ "error": {
+ "message": "The Calls room does not exist.",
+ "code": "CALLS_ROOM_NOT_FOUND",
+ "id": "09fd2742-0fc7-4222-ad41-1c395427a7d1"
+ }
+ }
+ },
+ "CALLS_STALE_REVISION": {
+ "value": {
+ "error": {
+ "message": "The Calls room revision is stale.",
+ "code": "CALLS_STALE_REVISION",
+ "id": "fde2c128-2b65-4784-a0de-59f20eb901c1"
+ }
+ }
+ },
+ "CALLS_FEATURE_DISABLED": {
+ "value": {
+ "error": {
+ "message": "Misskey Calls is disabled on this instance.",
+ "code": "CALLS_FEATURE_DISABLED",
+ "id": "bc70cfca-3247-4cd5-a9b7-a88b381195af"
+ }
+ }
+ },
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "Too many requests",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "RATE_LIMIT_EXCEEDED": {
+ "value": {
+ "error": {
+ "message": "Rate limit exceeded. Please try again later.",
+ "code": "RATE_LIMIT_EXCEEDED",
+ "id": "d5826d14-3982-4d2e-8011-b9e9f02499ef"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/channels/create": {
"post": {
"operationId": "post___channels___create", |
⚙️ Backend Diagnostics ReportMemory: After GC
Only metrics showing significant changes are displayed. V8 Heap Snapshot Statistics
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Calls の Activity に、YouTube の動画を一緒に見る Watch Together を追加します。動画 URL を入力して再生またはキューに追加できます。キューにはサムネイル・タイトル・説明文を表示します。PCなど幅のあるアクティビティ領域では「次に再生」を動画の右側に配置し、狭いウィンドウ・スマホ幅では下に並べます。タイトルと説明文はそれぞれ1行で省略し、スマホ幅でも横に収まります。「今すぐ再生」と削除は、キューの動画を右クリック・長押ししたコンテキストメニューから操作します。既存のリンクプレビューを使うため API キーは不要です。キューはルーム全員で共有し、ホスト・モデレーターが削除・途中の動画への切り替えを行えます。再生終了を受け取った操作権限者が次の動画へ進め、変更は全員に同期します。
ホスト・有効なルームモデレーターが YouTube 標準のボタンやタイムラインで再生・停止・シークすると、他の視聴者も同じ動画と再生位置に追従します。既存のインスタンスモデレーター権限も維持します。
独自の再生ボタン・秒数入力・音量スライダーをなくし、YouTube の操作 UI に統一しました。URL 入力は動画の選択・変更・キューへの追加時だけ表示します。YouTube検索は追加していません。
各自が「視聴を開始」を押してから YouTube プレーヤーに接続します。キューのサムネイルはYouTubeの画像配信先から表示します。音量と自動再生の許可は本人だけに作用します。途中参加・再表示時は現在の状態を取得し、ルーム終了時は再生を止めます。音声なしで視聴するホストも30秒ごとの状態取得で在席期限を更新します。
Why
YouTube を見る Activity を実装する依頼に対応します。操作権限は「ホスト・モデレーターが操作し、他の人は同期して視聴」の指定に従っています。
ベースは Activity の土台 #76(
codex/calls-activities、a5ef420731)。最新develop62d7367944を含む土台を取り込み、Callsの接続完了判定・設定・接続情報とWatch Togetherを維持して競合を解消しています。土台のPR #76のlocale競合も解消済みです。#76 → この PR の順で取り込めます。絵チャ #34 への依存はありません。関連: #17。Additional info (optional)
erDiagram CALLS_ROOM ||--o| WATCH_TOGETHER_STATE : "RedisキーのroomId" CALLS_ROOM { string id PK } WATCH_TOGETHER_STATE { string roomId PK "Redisキーから決定" string videoId "nullなら未選択" boolean playing number position "秒" string_array queue "次に再生する動画ID(最大50本)" number updatedAt "基準時刻ms" integer revision }視聴状態とキューは Redis に7日間保持します。既存 Calls のロック・配信・閲覧権限を使い、処分された参加者への配信も拒否します。API と SDK の型を追加し、RDB entity・migration は変更していません。
roomIdは Redis キーに含み、値には重複して保存しません。最新コミット
022c5bed3aのGitHub Checksは42件成功・条件付きStorybook 1件スキップ。土台のPR #76 (a5ef420731) も26件成功・1件スキップで、両PRとも競合なしです。動作確認記録
リンクプレビューが無効・取得失敗の場合は、キューに動画URLと取得失敗の表示を出します。YouTubeの埋め込み・地域制限・広告とブラウザーの自動再生制限の影響を受けます。自動再生が止められた場合は「再生を許可」を表示します。広告ブロックは含みません(公式パラメーター)。Cloudflareの実音声接続は試験用認証情報のため未検証です。
追加の参加確認fixtureテストは46件通過。テストファイルを単独でlintすると、develop由来のResizeObserverコンストラクターモック2か所が
prefer-arrow-callbackに抵触します(既存の指摘)。変更ソースのlint・SPDX・locale safetyは通過しています。Storybook登録の生成は完了しましたが、事前処理には既存の
.storybook/main.tsの型エラーがあり、本体は未検証です。CI用のテスト設定には、外部音声接続を行わないCallsのダミー設定を追加しました。CHANGELOG 候補:
Enhance: Calls の Activity に YouTube を同期視聴する Watch Together を追加。Checklist