19 KiB
V2 ActionModal 전환 조사 및 구현
목적
V2 폴더/Group에서 사용하는 SodaDialog, popup, modal, sheet, toast 계열 표시 지점을 조사하고, 1차 전환 후보를 SodaV2ActionModal로 구현한다.
이번 문서는 조사, Phase 1 구현, Phase 2 판단, 검증 기록을 함께 다룬다.
조사 범위
- 앱 코드:
SodaLive/Sources/V2/** - V2에서 직접 호출하는 shared dialog/component:
SodaLive/Sources/Dialog/**SodaLive/Sources/Report/**SodaLive/Sources/Main/**SodaLive/Sources/Content/Detail/**SodaLive/Sources/Settings/Notification/**SodaLive/Sources/Common/**
- 제외:
Pods/**,generated/**,build/**
조사 명령
rg -n --glob '*.swift' 'SodaDialog\(' 'SodaLive/Sources/V2'rg -n --glob '*.swift' '(NotificationSettingsDialog\(|LivePaymentDialog\(|LiveRoomPasswordDialog\(|EventPopupDialogView\(|LiveRoomDonationDialogView\(|CommunityPostPurchaseDialog\(|CheersReportDialogView\(|CreatorCommunityReportView\(|CreatorCommunityMenuView\()' 'SodaLive/Sources/V2'rg -n --glob '*.swift' '(CreatorChannelSortContextPopup\(|CreatorChannelActionPopup\(|CreatorChannelReplyDetailActionPopup\(|\.sodaToast\(|\.sheet\(|fullScreenCover\()' 'SodaLive/Sources/V2'rg -n --glob '*.swift' 'SodaV2ActionModal\(' 'SodaLive/Sources/V2'ast-greppattern:SodaDialog($$$)onSodaLive/Sources/V2
기준 컴포넌트
SodaV2ActionModal
- 정의:
SodaLive/Sources/V2/Component/Modal/SodaV2ActionModal.swift - API:
title: Stringmessage: Stringbutton1: SodaV2ActionModalButton?button2: SodaV2ActionModalButton?onDimmedTap: () -> Void
- 버튼 규칙:
button1은 primary action이며Color.soda400로 표시된다.button2는 secondary action이며Color.white로 표시된다.- 렌더링 순서는
button2가 왼쪽,button1이 오른쪽이다. - 버튼이 1개만 유효하면 primary 스타일로 단독 표시된다.
label또는action이nil이면 해당 버튼은 표시되지 않는다.
- UI 규칙:
- dimmed background:
Color.black.opacity(0.6) - modal width:
340 - background:
Color.gray900 - corner radius:
14
- dimmed background:
1차 전환 후보: 높음
아래 4곳은 V2 내부에서 SodaDialog(...)를 직접 호출하며, 모두 확인/취소 또는 삭제/취소 형태의 action-only dialog다. SodaV2ActionModal 전환 우선순위가 높다.
SodaLive/Sources/V2/Main/MainView.swift
-
authConfirmDialog- 위치:
MainView.swift:285 - 전환 전:
SodaDialog(title: I18n.Main.Auth.dialogTitle, desc: I18n.Main.Auth.liveEntryVerificationDescription, ...) - 상태:
isShowAuthConfirmView - 동작: 본인 인증 안내 후
BootpayUI인증 화면으로 이동하거나 취소 시pendingAction을 비운다. - 적용 결과:
title/message/인증 이동 primary/취소 secondary로SodaV2ActionModal을 적용한다. dimmed tap은 V2 modal 동작에 맞춰 취소 흐름과 동일하게 처리한다.
- 위치:
-
leaveLiveNavigationDialog- 위치:
MainView.swift:303 - 전환 전:
SodaDialog(title: I18n.Common.alertTitle, desc: I18n.LiveRoom.leaveLiveForNavigationDesc, ...) - 상태:
isShowLeaveLiveNavigationDialog - 동작: 라이브 시청 중 외부 이동 시
confirmExternalNavigation()또는cancelExternalNavigation()실행. - 적용 결과: 확인 primary, 취소 secondary로
SodaV2ActionModal을 적용한다. dimmed tap은 V2 modal 동작에 맞춰 취소 흐름과 동일하게 처리한다.
- 위치:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift
-
authConfirmDialog- 위치:
CreatorChannelView.swift:329 - 전환 전:
SodaDialog(title: I18n.Chat.Auth.dialogTitle, desc: I18n.Chat.Auth.dialogDescription, ...) - 상태:
isShowAuthConfirmView - 동작: 인증 안내 후
BootpayUI인증 화면으로 이동하거나 취소 시pendingAction을 비운다. - 적용 결과:
MainView.authConfirmDialog와 같은 패턴으로SodaV2ActionModal을 적용한다. dimmed tap은 V2 modal 동작에 맞춰 취소 흐름과 동일하게 처리한다.
- 위치:
-
community delete confirm
- 위치:
CreatorChannelView.swift:597 - 전환 전:
SodaDialog(title: I18n.Common.postDeleteTitle, desc: I18n.Common.confirmDeleteQuestion, ...) - 상태:
communityViewModel.isShowDeleteConfirm - 동작: 확인 시
communityViewModel.deleteCommunityPost(creatorId:)후 confirm 상태를 닫고, 취소 시 confirm 상태만 닫는다. - 적용 결과: 삭제 primary, 취소 secondary로
SodaV2ActionModal을 적용한다. dimmed tap은 V2 modal 동작에 맞춰 취소와 동일하게isShowDeleteConfirm = false처리한다.
- 위치:
이미 SodaV2ActionModal을 사용하는 기준 사례
구현 시 아래 사용처의 구조를 기준으로 삼는다.
-
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift:347fanTalkDeleteDialog- 팬Talk 삭제 확인.
- 삭제 primary, 취소 secondary, dimmed tap dismiss 패턴.
-
SodaLive/Sources/V2/CreatorChannel/Community/Detail/CreatorChannelCommunityPostDetailView.swift:54- 댓글 삭제 확인.
viewModel.confirmDelete와dismissDeleteDialog분리 패턴.
-
SodaLive/Sources/V2/CreatorChannel/ReplyDetail/CreatorChannelReplyDetailView.swift:49- 답글/댓글 삭제 확인.
viewModel.confirmDelete와dismissDeleteDialog분리 패턴.
-
SodaLive/Sources/V2/CreatorChannel/FanTalk/Write/CreatorChannelFanTalkWriteView.swift:106- 작성 중 나가기 확인.
- primary가 항상 destructive는 아니며, 강조할 CTA를
button1에 둔다.
별도 검토 후보
아래 항목은 V2에서 dialog/popup처럼 표시되지만, 입력 폼/도메인 UI/선택 UI가 포함되어 action-only SodaV2ActionModal로 단순 전환할 수 있는지 별도 판단이 필요하다.
-
SodaLive/Sources/V2/Main/MainView.swift:66NotificationSettingsDialog()- 알림 설정 전용 dialog. 설정 UI 포함 여부 확인 필요.
-
SodaLive/Sources/V2/Main/MainView.swift:74LivePaymentDialog(...)- 유료 라이브 결제/입장 확인. 시작/현재 시간 등 도메인 표시가 있어 단순 전환 전 UX 확인 필요.
-
SodaLive/Sources/V2/Main/MainView.swift:88LiveRoomPasswordDialog(...)- 비밀번호 입력 field가 있어 action-only modal 전환 대상 가능성이 낮다.
-
SodaLive/Sources/V2/Main/MainView.swift:98EventPopupDialogView(eventPopup:)- 이벤트 콘텐츠 팝업. 이미지/콘텐츠 표시 목적이면
SodaV2ActionModal과 목적이 다르다.
-
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift:164LiveRoomDonationDialogView(...)- 후원 금액, 메시지, 비밀후원 입력이 포함된 form dialog. 단순 전환 대상 가능성이 낮다.
-
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift:591CreatorCommunityReportView(...)- 신고 사유 선택 UI. 기존 report flow 재사용 범위로 유지할지 확인 필요.
-
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift:614CommunityPostPurchaseDialog(...)- 유료 게시글 구매 확인. 금액 표시와 구매 action 중심이므로 V2 action modal 통일 여부를 UX 기준으로 결정한다.
-
SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift:114CommunityPostPurchaseDialog(...)- 위와 동일한 구매 확인 dialog.
CreatorChannelView사용처와 함께 판단한다.
-
SodaLive/Sources/V2/CreatorChannel/FanTalk/CreatorChannelFanTalkTabView.swift:129CheersReportDialogView(...)- 신고 사유 선택 dialog. 확인형 action modal과 목적이 다르므로 별도 검토.
전환 대상에서 제외할 가능성이 높은 항목
아래 항목은 이름에 popup/modal/presented가 포함되거나 overlay로 표시되지만, 확인형 dialog가 아니므로 이번 SodaV2ActionModal 전환 대상에서는 제외하는 것이 안전하다.
-
CreatorChannelSortContextPopup- 정의:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelSortContextPopup.swift - 호출:
SodaLive/Sources/V2/Main/Content/All/MainContentAllView.swift:31SodaLive/Sources/V2/CreatorChannel/Live/CreatorChannelLiveTabView.swift:77SodaLive/Sources/V2/CreatorChannel/Audio/CreatorChannelAudioTabView.swift:87SodaLive/Sources/V2/CreatorChannel/Series/CreatorChannelSeriesTabView.swift:66
- 이유: 정렬 선택용 context menu다.
- 정의:
-
CreatorChannelActionPopup/CreatorChannelReplyDetailActionPopup- 정의:
SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkActionPopup.swiftSodaLive/Sources/V2/CreatorChannel/ReplyDetail/Components/CreatorChannelReplyDetailActionPopup.swift
- 호출:
SodaLive/Sources/V2/CreatorChannel/FanTalk/CreatorChannelFanTalkTabView.swift:102SodaLive/Sources/V2/CreatorChannel/Community/Detail/Components/CreatorChannelCommunityPostDetailCommentListView.swift:35SodaLive/Sources/V2/CreatorChannel/ReplyDetail/Components/CreatorChannelReplyDetailFeedView.swift:48
- 이유: 수정/삭제 action 선택용 anchored context popup이며, 실제 삭제 확인은 별도 modal이 담당한다.
- 정의:
-
.sheet(isPresented:)SodaLive/Sources/V2/CreatorChannel/Community/CreatorChannelCommunityTabView.swift:23- 이유: 댓글 리스트 화면 표시용 sheet다.
-
.fullScreenCover(isPresented:)SodaLive/Sources/V2/Main/MainView.swift:118SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift:190- 이유:
BootpayUI인증 화면 presentation이다.
-
.sodaToast(...)- 이유:
isShowPopup네이밍을 쓰는 ViewModel이 많지만 실제 UI는 toast다. action modal 전환 대상이 아니다. - 주요 호출 파일:
SodaLive/Sources/V2/Main/MainView.swiftSodaLive/Sources/V2/Main/Chat/MainChatView.swiftSodaLive/Sources/V2/Main/Content/Overview/ContentOverviewView.swiftSodaLive/Sources/V2/Main/Content/All/MainContentAllView.swiftSodaLive/Sources/V2/Main/Content/Ranking/MainContentRankingView.swiftSodaLive/Sources/V2/Main/Content/Recommendation/MainContentRecommendationView.swiftSodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swiftSodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swiftSodaLive/Sources/V2/CreatorChannel/Community/CreatorChannelCommunityTabView.swiftSodaLive/Sources/V2/CreatorChannel/Community/Detail/CreatorChannelCommunityPostDetailView.swiftSodaLive/Sources/V2/CreatorChannel/ReplyDetail/CreatorChannelReplyDetailView.swiftSodaLive/Sources/V2/CreatorChannel/Live/CreatorChannelLiveTabView.swiftSodaLive/Sources/V2/CreatorChannel/Audio/CreatorChannelAudioTabView.swiftSodaLive/Sources/V2/CreatorChannel/Series/CreatorChannelSeriesTabView.swiftSodaLive/Sources/V2/CreatorChannel/Donation/CreatorChannelDonationTabView.swiftSodaLive/Sources/V2/CreatorChannel/FanTalk/CreatorChannelFanTalkTabView.swiftSodaLive/Sources/V2/CreatorChannel/FanTalk/Write/CreatorChannelFanTalkWriteView.swift
- 이유:
구현 체크리스트
Phase 1: 1차 전환 후보 적용
-
Task 1.1:
MainView.authConfirmDialog를SodaV2ActionModal로 전환- 대상 파일:
SodaLive/Sources/V2/Main/MainView.swift - 검증 기준:
rg "authConfirmDialog|SodaV2ActionModal|SodaDialog" SodaLive/Sources/V2/Main/MainView.swift실행 시authConfirmDialog가SodaV2ActionModal을 사용한다.
- 대상 파일:
-
Task 1.2:
MainView.leaveLiveNavigationDialog를SodaV2ActionModal로 전환- 대상 파일:
SodaLive/Sources/V2/Main/MainView.swift - 검증 기준:
confirmExternalNavigation()/cancelExternalNavigation()호출 흐름이 유지된다.
- 대상 파일:
-
Task 1.3:
CreatorChannelView.authConfirmDialog를SodaV2ActionModal로 전환- 대상 파일:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 검증 기준: 인증 이동, 취소 시
pendingAction = nil흐름이 유지된다.
- 대상 파일:
-
Task 1.4:
CreatorChannelViewcommunity delete confirm을SodaV2ActionModal로 전환- 대상 파일:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 검증 기준: 삭제 확인, 취소, dimmed tap에서
communityViewModel.isShowDeleteConfirm상태가 올바르게 닫힌다.
- 대상 파일:
Phase 2: 별도 검토 후보 판단
-
Task 2.1: 구매/결제 dialog 전환 여부 결정
- 대상 파일:
SodaLive/Sources/Dialog/LivePaymentDialog.swiftSodaLive/Sources/Dialog/CommunityPostPurchaseDialog.swiftSodaLive/Sources/V2/Main/MainView.swiftSodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swiftSodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift
- 검증 기준: action-only modal로 대체 가능한지, 금액/시간 표시가 필요한지 결정이 문서에 남는다.
- 대상 파일:
-
Task 2.2: 입력/신고/이벤트 dialog 제외 여부 결정
- 대상 파일:
SodaLive/Sources/Dialog/LiveRoomPasswordDialog.swiftSodaLive/Sources/Content/Detail/LiveRoomDonationDialogView.swiftSodaLive/Sources/Report/CheersReportDialogView.swiftSodaLive/Sources/Main/EventPopupDialogView.swift
- 검증 기준:
SodaV2ActionModal전환 제외 또는 별도 V2 컴포넌트화 여부가 문서에 남는다.
- 대상 파일:
Phase 2 판단 결과
구매/결제 dialog
-
SodaLive/Sources/Dialog/CommunityPostPurchaseDialog.swift- 결정: 후속 구현에서
SodaV2ActionModal전환 후보로 확정한다. - 이유: 제목, 설명, 취소,
I18n.Dialog.CommunityPostPurchase.viewWithCans(can)확인 CTA만 있는 action-only 구매 확인 dialog다. - V2 호출부:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift,SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift - 후속 전환 방향: 구매 CTA를
button1, 취소를button2, dimmed tap을 취소와 동일하게isShowing = false흐름으로 둔다.
- 결정: 후속 구현에서
-
SodaLive/Sources/Dialog/LivePaymentDialog.swift- 결정: 현재 shared dialog를 유지한다.
- 이유: 기본 확인/취소 구조 외에 유료 라이브 시작 시간, 현재 시간, 추가 설명 영역을 조건부로 표시한다. 현재
SodaV2ActionModal의title/message/buttonsAPI로 단순 대체하면 시간 정보가 손실된다. - V2 호출부:
SodaLive/Sources/V2/Main/MainView.swift - 후속 방향: V2 통일이 필요하면
SodaV2ActionModal확장이 아니라 결제 전용 V2 dialog/component로 별도 설계한다.
입력/신고/이벤트 dialog
-
SodaLive/Sources/Dialog/LiveRoomPasswordDialog.swift- 결정:
SodaV2ActionModal전환 대상에서 제외한다. - 이유: 비밀번호 입력 field, 키보드 대응, 캔 수 조건부 CTA가 있는 input dialog다.
- V2 호출부:
SodaLive/Sources/V2/Main/MainView.swift - 후속 방향: 필요 시 V2 input modal로 별도 컴포넌트화한다.
- 결정:
-
SodaLive/Sources/Content/Detail/LiveRoomDonationDialogView.swift- 결정:
SodaV2ActionModal전환 대상에서 제외한다. - 이유: 후원 금액 입력, 단축 금액 버튼, 비밀 후원 토글, 메시지 입력, 충전 이동, validation toast를 포함한 복합 form/bottom-sheet 성격이다.
- V2 호출부:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 후속 방향: 필요 시 donation 전용 V2 modal/bottom-sheet로 별도 설계한다.
- 결정:
-
SodaLive/Sources/Report/CheersReportDialogView.swift- 결정:
SodaV2ActionModal전환 대상에서 제외한다. - 이유: 신고 사유 radio list 선택 상태가 필요한 selector dialog다.
- V2 호출부:
SodaLive/Sources/V2/CreatorChannel/FanTalk/CreatorChannelFanTalkTabView.swift - 후속 방향: 필요 시 V2 report selector 컴포넌트로 별도 설계한다.
- 결정:
-
SodaLive/Sources/Main/EventPopupDialogView.swift- 결정:
SodaV2ActionModal전환 대상에서 제외한다. - 이유: 원격 이미지 중심 콘텐츠 팝업이며 이미지 탭 상세 이동, 다시 보지 않기, 닫기 액션을 제공한다. 텍스트 확인형 action modal과 목적이 다르다.
- V2 호출부:
SodaLive/Sources/V2/Main/MainView.swift - 후속 방향: 필요 시 이벤트 팝업 전용 V2 component로 별도 설계한다.
- 결정:
검증 기록
- 2026-07-08:
rg와ast-grep로SodaLive/Sources/V2내부SodaDialog(...)직접 호출이 4곳임을 확인했다. 대상은MainView.authConfirmDialog,MainView.leaveLiveNavigationDialog,CreatorChannelView.authConfirmDialog,CreatorChannelViewcommunity delete confirm이다. - 2026-07-08:
rg 'SodaV2ActionModal\(' SodaLive/Sources/V2로 이미 적용된 기준 사례 4곳을 확인했다. 대상은CreatorChannelView.fanTalkDeleteDialog,CreatorChannelCommunityPostDetailView,CreatorChannelReplyDetailView,CreatorChannelFanTalkWriteView다. - 2026-07-08:
rg로 V2에서 호출하는 shared dialog 컴포넌트를 확인하고, 구매/결제/입력/신고/이벤트 dialog는 action-only modal 전환 여부를 별도 검토 후보로 분리했다. - 2026-07-08:
isShowPopup검색 결과의 대부분은.sodaToast(...)상태임을 확인해SodaV2ActionModal전환 대상에서 제외했다. - 2026-07-08: Phase 1 구현으로
MainView.authConfirmDialog,MainView.leaveLiveNavigationDialog,CreatorChannelView.authConfirmDialog,CreatorChannelViewcommunity delete confirm을SodaV2ActionModal로 전환했다. 확인/취소 action은 유지하고, dimmed tap은 V2 modal 동작에 맞춰 각 취소 흐름과 동일하게 연결했다. - 2026-07-08: 전환 후
rg -n --glob '*.swift' 'SodaDialog\(' 'SodaLive/Sources/V2'결과가 없어 V2 내부 직접SodaDialog(...)호출이 남지 않았음을 확인했다. - 2026-07-08:
xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -sdk iphonesimulator -derivedDataPath /tmp/SodaLiveDerivedData-SodaLiveDev CODE_SIGNING_ALLOWED=NO build실행 결과BUILD SUCCEEDED를 확인했다. - 2026-07-08: 기존
SodaDialog는 dimmed tap dismiss가 없지만, 이번 전환에서는SodaV2ActionModal의 현재 UX에 맞춰onDimmedTap을 각 취소 흐름과 동일하게 연결하는 것을 의도된 동작으로 정리했다. - 2026-07-08: Phase 2 구매/결제 dialog 검토 결과,
CommunityPostPurchaseDialog는 action-only 구매 확인 dialog이므로 후속SodaV2ActionModal전환 후보로 확정하고,LivePaymentDialog는 시작/현재 시간 정보 박스와 추가 설명이 있어 shared dialog 유지로 결정했다. - 2026-07-08: Phase 2 입력/신고/이벤트 dialog 검토 결과,
LiveRoomPasswordDialog,LiveRoomDonationDialogView,CheersReportDialogView,EventPopupDialogView는 입력/선택/이미지 콘텐츠 UI를 포함하므로SodaV2ActionModal전환 대상에서 제외하고 필요 시 별도 V2 컴포넌트화 대상으로 결정했다.