From c0734f20196fe7c33a0fab99c1b448d41db01dcc Mon Sep 17 00:00:00 2001 From: Ryu Tae Hyun Date: Sat, 5 Sep 2026 11:36:30 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(room):=20=ED=81=90=EC=99=80=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20UI=20=ED=91=9C=EC=8B=9C=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EB=A5=BC=20=EA=B5=90=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/follow/ui/FollowModal.module.css | 6 ++- src/features/follow/ui/FollowModal.tsx | 8 +++- .../follow/ui/FollowProfileModal.module.css | 4 +- .../add-track/ui/AddTrackModal.module.css | 12 ++--- .../ui/RoomPlaybackJoinedContent.test.tsx | 48 +++++++++++++++---- .../page/ui/RoomPlaybackJoinedContent.tsx | 4 +- .../queue/hooks/useRoomQueuePanel.test.tsx | 4 ++ .../room/queue/hooks/useRoomQueuePanel.ts | 26 ++++++---- .../settings/ui/SettingsModal.module.css | 5 +- src/features/settings/ui/SettingsModal.tsx | 14 +++++- 10 files changed, 99 insertions(+), 32 deletions(-) diff --git a/src/features/follow/ui/FollowModal.module.css b/src/features/follow/ui/FollowModal.module.css index 8fd47324..48185e37 100644 --- a/src/features/follow/ui/FollowModal.module.css +++ b/src/features/follow/ui/FollowModal.module.css @@ -12,6 +12,10 @@ z-index: 1400; } +.overlay[data-dim-backdrop="true"] { + background: rgba(0, 0, 0, 0.64); +} + .modal { --panel-horizontal-padding: 16px; --panel-content-width: 1060px; @@ -22,7 +26,7 @@ calc(var(--panel-content-width) + (var(--panel-horizontal-padding) * 2)), calc(100vw - 32px) ); - height: min(49vh, calc(100vh - 48px)); + height: min(540px, calc(100dvh - 48px)); box-sizing: border-box; overflow: hidden; border: 0.5px solid #d9d9d9; diff --git a/src/features/follow/ui/FollowModal.tsx b/src/features/follow/ui/FollowModal.tsx index f3f14840..340887bf 100644 --- a/src/features/follow/ui/FollowModal.tsx +++ b/src/features/follow/ui/FollowModal.tsx @@ -10,11 +10,16 @@ import type { FollowUser } from "../model/types"; import FollowProfileModal from "./FollowProfileModal"; type FollowModalProps = { + dimBackdrop?: boolean; open: boolean; onClose: () => void; }; -export default function FollowModal({ open, onClose }: FollowModalProps) { +export default function FollowModal({ + dimBackdrop = false, + open, + onClose, +}: FollowModalProps) { const modal = useFollowModalState({ onClose, open }); const addFriendButtonRef = useRef(null); const selectedUserTriggerRef = useRef(null); @@ -49,6 +54,7 @@ export default function FollowModal({ open, onClose }: FollowModalProps) {
{ if (event.target === event.currentTarget) { modal.closeModal(); diff --git a/src/features/follow/ui/FollowProfileModal.module.css b/src/features/follow/ui/FollowProfileModal.module.css index 7a08b1de..88f0f976 100644 --- a/src/features/follow/ui/FollowProfileModal.module.css +++ b/src/features/follow/ui/FollowProfileModal.module.css @@ -34,7 +34,7 @@ box-sizing: border-box; flex-direction: column; height: 100%; - padding: 0 18px 56px; + padding: 16px 18px 56px; background: #ffffff; color: #3c3c3c; } @@ -114,7 +114,7 @@ } .content { - padding: 0 14.4px 44.8px; + padding: 12.8px 14.4px 44.8px; } .actionRow { diff --git a/src/features/playlist/add-track/ui/AddTrackModal.module.css b/src/features/playlist/add-track/ui/AddTrackModal.module.css index b044879b..92e7ac95 100644 --- a/src/features/playlist/add-track/ui/AddTrackModal.module.css +++ b/src/features/playlist/add-track/ui/AddTrackModal.module.css @@ -48,7 +48,7 @@ } .fieldGroup + .fieldGroup { - margin-top: 24px; + margin-top: 40px; } .queueModeFieldset { @@ -59,7 +59,7 @@ } .queueModeFieldset + .fieldGroup { - margin-top: 24px; + margin-top: 40px; } .queueModeLegend { @@ -303,7 +303,7 @@ } .fieldGroup + .fieldGroup { - margin-top: 28px; + margin-top: 40px; } .queueModeFieldset { @@ -311,7 +311,7 @@ } .queueModeFieldset + .fieldGroup { - margin-top: 28px; + margin-top: 40px; } .queueModeLegend, @@ -367,9 +367,9 @@ .title { font-size: 19.2px; } .form { margin-top: 33.6px; } .fieldGroup { gap: 11.2px; } - .fieldGroup + .fieldGroup { margin-top: 19.2px; } + .fieldGroup + .fieldGroup { margin-top: 40px; } .queueModeFieldset { margin-top: 16px; } - .queueModeFieldset + .fieldGroup { margin-top: 19.2px; } + .queueModeFieldset + .fieldGroup { margin-top: 40px; } .queueModeLegend, .queueModeOption { font-size: 12px; } .queueModeLegend { margin-bottom: 9.6px; } .queueModeOption { gap: 8px; padding: 8px 9.6px; border-radius: 6.4px; } diff --git a/src/features/room/page/ui/RoomPlaybackJoinedContent.test.tsx b/src/features/room/page/ui/RoomPlaybackJoinedContent.test.tsx index 3525f1b7..c776c393 100644 --- a/src/features/room/page/ui/RoomPlaybackJoinedContent.test.tsx +++ b/src/features/room/page/ui/RoomPlaybackJoinedContent.test.tsx @@ -99,8 +99,18 @@ vi.mock("@/src/features/room/floating/ui/RoomFloatingWidgets", () => ({ ), })); vi.mock("@/src/features/settings/ui/SettingsModal", () => ({ - default: ({ onClose }: { onClose: () => void }) => ( -
+ default: ({ + dimBackdrop, + onClose, + }: { + dimBackdrop?: boolean; + onClose: () => void; + }) => ( +
@@ -108,8 +118,18 @@ vi.mock("@/src/features/settings/ui/SettingsModal", () => ({ ), })); vi.mock("@/src/features/follow/ui/FollowModal", () => ({ - default: ({ onClose }: { onClose: () => void }) => ( -
+ default: ({ + dimBackdrop, + onClose, + }: { + dimBackdrop?: boolean; + onClose: () => void; + }) => ( +
@@ -181,13 +201,19 @@ describe("RoomPlaybackJoinedContent self modals", () => { renderContent({ isMobileLayout: true }); await user.click(screen.getByRole("button", { name: "모바일 Setting 열기" })); - expect(screen.getByRole("dialog", { name: "Setting modal" })).toBeVisible(); + expect(screen.getByRole("dialog", { name: "Setting modal" })).toHaveAttribute( + "data-dim-backdrop", + "true", + ); await user.click(screen.getByRole("button", { name: "Setting 닫기" })); expect(screen.queryByRole("dialog", { name: "Setting modal" })).toBeNull(); await user.click(screen.getByRole("button", { name: "모바일 Friends 열기" })); - expect(screen.getByRole("dialog", { name: "Friends modal" })).toBeVisible(); + expect(screen.getByRole("dialog", { name: "Friends modal" })).toHaveAttribute( + "data-dim-backdrop", + "true", + ); }); it("데스크톱 draggable widget의 요청도 화면 최상위 modal layer로 전달한다", async () => { @@ -197,12 +223,18 @@ describe("RoomPlaybackJoinedContent self modals", () => { await user.click( screen.getByRole("button", { name: "데스크톱 Setting 열기" }), ); - expect(screen.getByRole("dialog", { name: "Setting modal" })).toBeVisible(); + expect(screen.getByRole("dialog", { name: "Setting modal" })).toHaveAttribute( + "data-dim-backdrop", + "true", + ); await user.click(screen.getByRole("button", { name: "Setting 닫기" })); await user.click( screen.getByRole("button", { name: "데스크톱 Friends 열기" }), ); - expect(screen.getByRole("dialog", { name: "Friends modal" })).toBeVisible(); + expect(screen.getByRole("dialog", { name: "Friends modal" })).toHaveAttribute( + "data-dim-backdrop", + "true", + ); }); }); diff --git a/src/features/room/page/ui/RoomPlaybackJoinedContent.tsx b/src/features/room/page/ui/RoomPlaybackJoinedContent.tsx index be39ef68..8ff51992 100644 --- a/src/features/room/page/ui/RoomPlaybackJoinedContent.tsx +++ b/src/features/room/page/ui/RoomPlaybackJoinedContent.tsx @@ -207,10 +207,10 @@ export default function RoomPlaybackJoinedContent({ const selfModal = ( <> {activeSelfModal === "settings" ? ( - + ) : null} {activeSelfModal === "friends" ? ( - + ) : null} ); diff --git a/src/features/room/queue/hooks/useRoomQueuePanel.test.tsx b/src/features/room/queue/hooks/useRoomQueuePanel.test.tsx index 135eeca7..1619470a 100644 --- a/src/features/room/queue/hooks/useRoomQueuePanel.test.tsx +++ b/src/features/room/queue/hooks/useRoomQueuePanel.test.tsx @@ -210,6 +210,10 @@ describe("useRoomQueuePanel query visibility", () => { historyEntry(1, "user"), historyEntry(2, "other"), historyEntry(3, null), + { + ...historyEntry(5, "user"), + entryId: pendingEntry.entryId, + }, { ...historyEntry(4, "user"), playbackOrigin: "AUTOMATIC_REPLAY", diff --git a/src/features/room/queue/hooks/useRoomQueuePanel.ts b/src/features/room/queue/hooks/useRoomQueuePanel.ts index 74f027e6..8e4e69b5 100644 --- a/src/features/room/queue/hooks/useRoomQueuePanel.ts +++ b/src/features/room/queue/hooks/useRoomQueuePanel.ts @@ -113,15 +113,6 @@ export function useRoomQueuePanel({ (entry: PlaylistEntry) => isEntryRequestedByUser(entry, currentUser), [currentUser], ); - const historyEntries = useMemo( - () => - activeTab === "all" - ? historyQuery.entries - : historyQuery.entries.filter((entry) => - isHistoryEntryRequestedByUser(entry, currentUser), - ), - [activeTab, currentUser, historyQuery.entries], - ); const isAutomaticReplay = currentEntry?.status.playbackOrigin === "AUTOMATIC_REPLAY"; const shouldShowCurrentEntry = @@ -129,6 +120,23 @@ export function useRoomQueuePanel({ (activeTab === "all" || Boolean(currentEntry && isCurrentUserEntry(currentEntry))); const visibleCurrentEntry = shouldShowCurrentEntry ? currentEntry : null; + const visibleCurrentEntryId = visibleCurrentEntry?.entryId; + const historyEntries = useMemo( + () => { + const tabHistoryEntries = activeTab === "all" + ? historyQuery.entries + : historyQuery.entries.filter((entry) => + isHistoryEntryRequestedByUser(entry, currentUser), + ); + + return visibleCurrentEntryId + ? tabHistoryEntries.filter( + (entry) => entry.entryId !== visibleCurrentEntryId, + ) + : tabHistoryEntries; + }, + [activeTab, currentUser, historyQuery.entries, visibleCurrentEntryId], + ); const canDeleteEntry = (entry: PlaylistEntry) => isPendingQueueEntry(entry) && isCurrentUserEntry(entry); const canDeleteEntryAsOwner = (entry: PlaylistEntry) => diff --git a/src/features/settings/ui/SettingsModal.module.css b/src/features/settings/ui/SettingsModal.module.css index fdb261b8..0d004aa4 100644 --- a/src/features/settings/ui/SettingsModal.module.css +++ b/src/features/settings/ui/SettingsModal.module.css @@ -8,6 +8,10 @@ padding: 24px 24px 154px; } +.overlay[data-dim-backdrop="true"] { + background: rgba(0, 0, 0, 0.64); +} + .modal { --panel-horizontal-padding: 16px; --panel-content-width: 1060px; @@ -168,7 +172,6 @@ .modal { --panel-horizontal-padding: 12.8px; --panel-content-width: 848px; - height: 432px; border-radius: 16px; } diff --git a/src/features/settings/ui/SettingsModal.tsx b/src/features/settings/ui/SettingsModal.tsx index 9ed87873..48f3223b 100644 --- a/src/features/settings/ui/SettingsModal.tsx +++ b/src/features/settings/ui/SettingsModal.tsx @@ -6,6 +6,7 @@ import ProfileSettingsTab from "./ProfileSettingsTab"; import styles from "./SettingsModal.module.css"; type SettingsModalProps = { + dimBackdrop?: boolean; open: boolean; onClose: () => void; }; @@ -20,7 +21,11 @@ const settingsTabs: Array<{ { key: "account", label: "계정 관리" }, ]; -export default function SettingsModal({ open, onClose }: SettingsModalProps) { +export default function SettingsModal({ + dimBackdrop = false, + open, + onClose, +}: SettingsModalProps) { const [activeTab, setActiveTab] = useState("profile"); if (!open) { @@ -38,7 +43,12 @@ export default function SettingsModal({ open, onClose }: SettingsModalProps) { } return ( -
+
event.stopPropagation()} From b84fbb37806a03e5b63f8de150b94a3b9b6e9d3a Mon Sep 17 00:00:00 2001 From: Ryu Tae Hyun Date: Sat, 5 Sep 2026 11:38:46 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs(delivery):=20=EB=B0=A9=20=ED=81=90?= =?UTF-8?q?=EC=99=80=20=EB=AA=A8=EB=8B=AC=20UI=20QA=EB=A5=BC=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-summary.md | 18 +++++ .../delivery-state.md | 12 ++++ .../plan.md | 71 +++++++++++++++++++ .../qa-report.md | 35 +++++++++ .../request-summary.md | 11 +++ .../ui-flow.md | 24 +++++++ docs/exec-plans/active/README.md | 2 + 7 files changed, 173 insertions(+) create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/change-summary.md create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/delivery-state.md create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/plan.md create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/qa-report.md create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/request-summary.md create mode 100644 docs/exec-plans/active/2026-09-05-room-queue-modal-polish/ui-flow.md diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/change-summary.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/change-summary.md new file mode 100644 index 00000000..437ee1cf --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/change-summary.md @@ -0,0 +1,18 @@ +# Change Summary + +- commit: `c0734f2 fix(room): 큐와 모달 UI 표시 오류를 교정` +- PR: https://github.com/Queuing-org/frontend/pull/61 + +## Delivered + +- 내 노래 현재 재생곡/history 중복 제거 +- 노래 신청 다음 섹션 간격 40px 통일 +- 방 내부 Settings/Friends dim backdrop +- Friends/Settings 데스크톱 기본 높이 540px +- Friends 사용자 상세 상단 padding 복원 + +## QA + +- targeted/full test, lint, build, diff-check 통과 +- fresh reviewer 최종 `pass` +- browser visual QA는 세션 unavailable로 미실시 diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/delivery-state.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/delivery-state.md new file mode 100644 index 00000000..5e0b7f7f --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/delivery-state.md @@ -0,0 +1,12 @@ +# Delivery State + +- status: ci-pending +- branch: dev +- base: main +- issue: +- pr: https://github.com/Queuing-org/frontend/pull/61 +- selected_skills: queuing-feature-delivery, queuing-orchestrator, queuing-ui-flow, frontend-architecture-guardrails, queuing-qa-reviewer +- local_qa: pass — targeted 5 files/26 tests, lint, full test 155 files/688 tests, build, diff-check, fresh QA pass +- ci: pending +- review_threads: none +- next_action: Draft PR #61 CI와 human visual review를 확인한다. diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/plan.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/plan.md new file mode 100644 index 00000000..7c775a77 --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/plan.md @@ -0,0 +1,71 @@ +# 방 큐·모달 UI 교정 + +## Scope + +- 내 노래 탭에서 현재 재생곡과 같은 history 항목이 중복 표시되지 않게 한다. +- 노래 신청 URL 입력 영역 이후 다음 섹션까지의 간격을 40px로 통일한다. +- 방 내부에서 연 Settings/Friends 모달만 배경을 어둡게 처리한다. +- Friends와 Settings 데스크톱 모달의 기본 높이를 540px로 맞춘다. +- Friends 목록에서 연 프로필 상세의 누락된 상단 패딩을 복원한다. + +## Acceptance Criteria + +- 동일한 `entryId`의 현재곡과 history는 내 노래 타임라인에 한 번만 보인다. +- 일반 URL 폼은 URL 입력 필드 아래부터 선정 이유 타이틀까지 40px이다. +- 재생목록 선택지가 나타난 폼은 선택지 영역 아래부터 선정 이유 타이틀까지 40px이다. +- 방 내부 Settings/Friends가 열리면 방 배경에 dim이 생기고 홈/검색 호출부는 기존 배경을 유지한다. +- Friends와 Settings 데스크톱 기본 모달 높이는 540px이다. +- Friends 프로필 상세의 본문 상단 여백이 일반/compact 레이아웃 비율에 맞게 보인다. + +## Selected Skills + +- queuing-feature-delivery +- queuing-orchestrator +- queuing-ui-flow +- frontend-architecture-guardrails +- queuing-qa-reviewer + +## Ownership + +- 큐 타임라인 파생 데이터: `useRoomQueuePanel` +- 노래 신청 레이아웃: `AddTrackModal.module.css` +- 방 내부 modal dim 여부: `RoomPlaybackJoinedContent`가 호출 문맥을 소유하고 각 modal은 표현 옵션만 받는다. +- Friends/Settings 크기와 Friends 상세 패딩: 각 feature CSS module + +## Commit Slices + +1. `fix(room): 큐와 모달 UI 표시 오류를 교정` +2. `docs(delivery): 방 큐와 모달 UI QA를 기록` + +## Progress + +- [x] 관련 렌더 경로와 CSS 원인 확인 +- [x] 실행 계획/상태 기록 +- [x] 구현 및 targeted test +- [x] lint/test/build +- [x] fresh read-only QA +- [x] feature commit (`c0734f2`), push, Draft PR #61 게시 + +## Verification + +- queue hook 및 room modal targeted Vitest +- `npm run lint` +- `npm run test` +- `npm run build` +- `git diff --check` + +결과: + +- targeted Vitest: 5 files / 26 tests pass +- full Vitest: 155 files / 688 tests pass +- lint: pass +- build: pass +- `git diff --check`: pass +- fresh read-only QA: 1차 `fix`, Settings compact 432px override 제거 후 최종 `pass` +- browser visual QA: 브라우저 세션 unavailable로 미실시 + +## Residual Risk + +- 실제 브라우저의 40px 간격, dim stacking, 프로필 padding 픽셀 배치는 수동 확인이 필요하다. +- compact density는 57.6px 친구 행을 사용하므로 540px에서 약 8행이 보이며, 약 6.5행은 normal density 기준이다. +- 매우 낮은 데스크톱 viewport의 540px Settings 안전 영역은 후속 반응형 QA가 필요하다. diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/qa-report.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/qa-report.md new file mode 100644 index 00000000..67d814be --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/qa-report.md @@ -0,0 +1,35 @@ +# QA Report + +## Result + +`pass` + +## Boundary Review + +- Queue: 화면에 표시되는 현재곡의 `entryId`만 history에서 제거해 현재곡/history 이중 렌더를 방지한다. 자동 재생이나 내 곡이 아닌 현재곡은 기존 history를 유지한다. +- Add track: URL field의 다음 형제가 story field인 경로와 playlist fieldset인 경로를 분리해, 각각 story title 직전 간격을 40px로 맞췄다. +- Room modal: `RoomPlaybackJoinedContent`만 `dimBackdrop`을 활성화한다. Home/Search의 기존 Settings/Follow 호출부는 기본값 `false`를 유지한다. +- Modal height: Friends는 49vh 대신 540px 기준을 사용한다. Settings는 base 540px을 덮던 compact 432px override를 제거했다. +- Follow profile: normal 16px, compact 12.8px 상단 padding을 복원했다. +- API, mutation, React Query cache, websocket 계약 변경은 없다. + +## Fresh Review + +- 1차 판정: `fix` +- finding: Settings compact media query의 432px 높이가 540px 요구를 덮어씀 +- fix: compact height override 제거 +- 최종 판정: `pass`, blocking finding 없음 + +## Verification + +- targeted Vitest: 5 files / 26 tests pass +- `npm run lint`: pass +- `npm run test`: 155 files / 688 tests pass +- `npm run build`: pass +- `git diff --check`: pass + +## Residual Risk + +- 연결 가능한 브라우저 세션이 없어 실제 픽셀 시각 QA는 실행하지 못했다. +- compact density에서 Friends 행 높이는 57.6px이므로 540px modal에 보이는 행 수가 normal density의 약 6.5행과 다르다. +- 매우 낮은 데스크톱 viewport의 세부 반응형은 이번 요청의 비목표다. diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/request-summary.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/request-summary.md new file mode 100644 index 00000000..f7096135 --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/request-summary.md @@ -0,0 +1,11 @@ +# Request Summary + +2026-09-05 사용자 요청: + +1. 내 노래 탭에서 재생 중인 노래가 두 개로 보이는 중복 버그 수정 +2. 유튜브 링크 입력 다음 선정 이유 타이틀까지 40px 간격 적용; 재생목록 선택지가 생기면 그 영역 아래부터 40px 적용 +3. 방 내부 Settings/Friends 모달이 열릴 때 배경 dim 적용 +4. Friends/Settings 탭 기본 높이를 540px로 맞춰 팔로잉 목록 약 6.5개가 보이게 조정 +5. Friends 목록에서 사용자를 눌러 연 프로필 상세의 잘못된 패딩을 기존 프로필 패턴에 맞게 교정 + +첨부 이미지는 1번 중복 버그를 보여 준다. diff --git a/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/ui-flow.md b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/ui-flow.md new file mode 100644 index 00000000..106b2264 --- /dev/null +++ b/docs/exec-plans/active/2026-09-05-room-queue-modal-polish/ui-flow.md @@ -0,0 +1,24 @@ +# UI Flow + +## Queue + +`history query -> useRoomQueuePanel derived historyEntries -> RoomQueueHistoryList` + +- 현재곡 `entryId`는 타임라인 경계에서 별도로 렌더하므로 history 파생 배열에서 제외한다. +- 전체/내 노래 필터 뒤에 동일한 dedupe 규칙을 적용한다. + +## Add Track + +- URL field 다음 형제가 story field이면 40px. +- URL field 다음에 playlist fieldset이 있으면 fieldset 자체 간격은 유지하고 fieldset 다음 story field 간격을 40px. + +## Room Self Modals + +- `RoomPlaybackJoinedContent`가 방 내부 호출 문맥을 소유한다. +- SettingsModal/FollowModal은 `dimBackdrop` 표현 옵션을 받고 방 호출부에서만 활성화한다. +- modal open/close local state와 홈/검색 동작은 변경하지 않는다. + +## Modal Size and Profile Padding + +- desktop Friends/Settings modal은 540px 기준 높이를 사용하며 viewport보다 클 때만 줄어든다. +- Friends profile body에는 일반 16px, compact 12.8px의 상단 패딩을 적용해 기존 80% density 규칙을 유지한다. diff --git a/docs/exec-plans/active/README.md b/docs/exec-plans/active/README.md index d705c17b..5554322b 100644 --- a/docs/exec-plans/active/README.md +++ b/docs/exec-plans/active/README.md @@ -1,5 +1,7 @@ # Active Execution Plans +- [2026-09-05-room-queue-modal-polish](./2026-09-05-room-queue-modal-polish/plan.md): ci-pending — Draft PR #61, 내 노래 현재곡 중복·신청 폼 간격·방 modal dim/높이·Friends 상세 padding 교정 및 로컬 QA 통과 + - [2026-09-02-youtube-playlist-import](./2026-09-02-youtube-playlist-import/plan.md): ci-pending — Draft PR #60, 재생목록 감지 시 현재 영상/재생목록 노래 추가 선택을 요구하고 후속 로컬 QA 통과 - [2026-09-01-room-self-participant-menu](./2026-09-01-room-self-participant-menu/plan.md): ci-pending — Draft PR #59, 내 참가자 첫 행·`(나)`·Settings/Friends modal과 reconnect identity QA 통과