feat(i18n): 라이브 룸 하드코딩 문구를 I18n 키로 통일한다
This commit is contained in:
@@ -1690,6 +1690,147 @@ enum I18n {
|
||||
static var enterPeopleRange: String { pick(ko: "인원을 3~999명 사이로 입력해주세요.", en: "Please enter the number of people between 3 and 999.", ja: "人数を3~999名の間で入力してください。") }
|
||||
static var enterPaidPriceMin30: String { pick(ko: "유료 라이브는 30캔 이상 설정해주세요.", en: "For paid live, set at least 30 cans.", ja: "有料ライブは30can以上で設定してください。") }
|
||||
static var enterPassword6: String { pick(ko: "방 입장 비밀번호 6자리를 입력해 주세요.", en: "Please enter a 6-digit room entry password.", ja: "入室パスワード(6桁)を入力してください。") }
|
||||
|
||||
static var createLiveTitle: String { pick(ko: "라이브 만들기", en: "Create live", ja: "ライブを作成") }
|
||||
static var fetchRecentData: String { pick(ko: "최근 데이터 가져오기", en: "Load recent data", ja: "最近のデータを読み込む") }
|
||||
static var thumbnail: String { pick(ko: "썸네일", en: "Thumbnail", ja: "サムネイル") }
|
||||
static var creatorEntrySetting: String { pick(ko: "크리에이터 입장 설정", en: "Creator entry setting", ja: "クリエイター入場設定") }
|
||||
static var openLiveAction: String { pick(ko: "라이브 오픈하기", en: "Open live", ja: "ライブを開始") }
|
||||
|
||||
static var titleLabel: String { pick(ko: "제목", en: "Title", ja: "タイトル") }
|
||||
static var titlePlaceholder: String { pick(ko: "라이브 제목을 입력하세요", en: "Enter live title", ja: "ライブタイトルを入力してください") }
|
||||
static var interestsLabel: String { pick(ko: "관심사", en: "Interests", ja: "関心事") }
|
||||
static var selectInterestsAction: String { pick(ko: "관심사 선택", en: "Select interests", ja: "関心事を選択") }
|
||||
static var noticeLabel: String { pick(ko: "공지", en: "Notice", ja: "お知らせ") }
|
||||
static func noticeCount(_ count: Int) -> String {
|
||||
pick(ko: "\(count)자", en: "\(count) chars", ja: "\(count)字")
|
||||
}
|
||||
static var noticeLimitSuffix: String { pick(ko: " / 1000자", en: " / 1000 chars", ja: " / 1000字") }
|
||||
|
||||
static var timeSettingLabel: String { pick(ko: "시간설정", en: "Time setting", ja: "時間設定") }
|
||||
static var reservationDateLabel: String { pick(ko: "예약 날짜", en: "Reservation date", ja: "予約日") }
|
||||
static var reservationTimeLabel: String { pick(ko: "예약 시간", en: "Reservation time", ja: "予約時間") }
|
||||
static var participantLimitLabel: String { pick(ko: "참여인원 설정", en: "Participant limit", ja: "参加人数設定") }
|
||||
static var participantLimitPlaceholder: String { pick(ko: "최대 인원 999명", en: "Max 999 participants", ja: "最大999人") }
|
||||
static var confirmButton: String { pick(ko: "확인", en: "Confirm", ja: "確認") }
|
||||
|
||||
static var visibilityLabel: String { pick(ko: "공개 설정", en: "Visibility", ja: "公開設定") }
|
||||
static var roomPasswordTitle: String { pick(ko: "방 비밀번호 입력", en: "Enter room password", ja: "入室パスワード入力") }
|
||||
static var roomPasswordPlaceholder: String { pick(ko: "방 입장 비밀번호 6자리를 입력해 주세요.", en: "Enter 6-digit room password", ja: "入室パスワード6桁を入力してください") }
|
||||
static var ageRestrictionLabel: String { pick(ko: "연령 제한", en: "Age restriction", ja: "年齢制限") }
|
||||
static var ticketPriceLabel: String { pick(ko: "티켓 가격", en: "Ticket price", ja: "チケット価格") }
|
||||
static var canUnit: String { pick(ko: "캔", en: "cans", ja: "can") }
|
||||
static func priceOption(_ price: Int) -> String {
|
||||
pick(
|
||||
ko: price == 0 ? "무료" : "\(price) 캔",
|
||||
en: price == 0 ? "Free" : "\(price) cans",
|
||||
ja: price == 0 ? "無料" : "\(price)can"
|
||||
)
|
||||
}
|
||||
|
||||
static var tagSelectionTitle: String { pick(ko: "관심사 선택", en: "Select interests", ja: "関心事を選択") }
|
||||
static var tagSelectionSubtitle: String { pick(ko: "최대 3개까지 선택 가능합니다.", en: "You can select up to 3.", ja: "最大3つまで選択できます。") }
|
||||
static var tagConfirmButton: String { pick(ko: "확인", en: "Confirm", ja: "確認") }
|
||||
|
||||
static var menuTitle: String { pick(ko: "메뉴", en: "Menu", ja: "メニュー") }
|
||||
static var menuActivatePrompt: String { pick(ko: "메뉴를 활성화 하시겠습니까?", en: "Activate menu?", ja: "メニューを有効化しますか?") }
|
||||
static var menuPlaceholder: String { pick(ko: "메뉴판을 작성해주세요.", en: "Please write the menu board.", ja: "メニュー表を入力してください。") }
|
||||
static var saveMenuAction: String { pick(ko: "저장하기", en: "Save", ja: "保存する") }
|
||||
static var menuSavedMessage: String { pick(ko: "저장되었습니다.", en: "Saved.", ja: "保存されました。") }
|
||||
|
||||
static var editLiveTitle: String { pick(ko: "라이브 수정", en: "Edit live", ja: "ライブ編集") }
|
||||
static var editAction: String { pick(ko: "수정하기", en: "Edit", ja: "編集する") }
|
||||
static var entryMessageLabel: String { pick(ko: "입장메시지", en: "Entry message", ja: "入場メッセージ") }
|
||||
static var noChangesMessage: String { pick(ko: "변경사항이 없습니다.", en: "No changes.", ja: "変更事項がありません。") }
|
||||
static var editSuccessMessage: String { pick(ko: "라이브 정보가 수정되었습니다.", en: "Live info has been updated.", ja: "ライブ情報を更新しました。") }
|
||||
static var editFailedMessage: String {
|
||||
pick(
|
||||
ko: "라이브 정보를 수정하지 못했습니다.\n다시 시도해 주세요.",
|
||||
en: "Failed to update live info.\nPlease try again.",
|
||||
ja: "ライブ情報を更新できませんでした。\nもう一度お試しください。"
|
||||
)
|
||||
}
|
||||
|
||||
static var donationHistoryTitle: String { pick(ko: "후원 히스토리", en: "Donation history", ja: "後援履歴") }
|
||||
static var donationHistoryCopied: String { pick(ko: "후원 히스토리가 복사되었습니다.", en: "Donation history copied.", ja: "後援履歴をコピーしました。") }
|
||||
static var donationHistoryEmpty: String { pick(ko: "후원 히스토리가 없습니다.", en: "No donation history.", ja: "後援履歴がありません。") }
|
||||
static var closeAction: String { pick(ko: "닫기", en: "Close", ja: "閉じる") }
|
||||
|
||||
static var donationRankingTitle: String { pick(ko: "현재 라이브 후원랭킹", en: "Current live donation ranking", ja: "現在のライブ後援ランキング") }
|
||||
static var heartRankingTitle: String { pick(ko: "현재 라이브 하트랭킹", en: "Current live heart ranking", ja: "現在のライブハートランキング") }
|
||||
static var totalLabel: String { pick(ko: "전체", en: "Total", ja: "全体") }
|
||||
static var peopleUnit: String { pick(ko: "명", en: "people", ja: "人") }
|
||||
static var sumLabel: String { pick(ko: "합계", en: "Sum", ja: "合計") }
|
||||
static var normalLabel: String { pick(ko: "일반", en: "Normal", ja: "一般") }
|
||||
static var secretLabel: String { pick(ko: "비밀", en: "Secret", ja: "秘密") }
|
||||
static var heartLabel: String { pick(ko: "하트", en: "Heart", ja: "ハート") }
|
||||
|
||||
static var noChattingTitle: String { pick(ko: "채팅금지", en: "Chat ban", ja: "チャット禁止") }
|
||||
static var noChattingQuestion: String { pick(ko: "3분간 채팅금지를 하겠습니까?", en: "Ban chat for 3 minutes?", ja: "3分間チャットを禁止しますか?") }
|
||||
static var profileTitle: String { pick(ko: "프로필", en: "Profile", ja: "プロフィール") }
|
||||
static var inviteSpeakerAction: String { pick(ko: "스피커로 초대", en: "Invite as speaker", ja: "スピーカーに招待") }
|
||||
static var changeListenerAction: String { pick(ko: "리스너 변경", en: "Switch to listener", ja: "リスナーへ変更") }
|
||||
static var staffReleaseAction: String { pick(ko: "스탭 해제", en: "Release staff", ja: "スタッフ解除") }
|
||||
static var staffAssignAction: String { pick(ko: "스탭 지정", en: "Assign staff", ja: "スタッフ指定") }
|
||||
static var kickOutAction: String { pick(ko: "내보내기", en: "Kick out", ja: "退場") }
|
||||
static var noChattingAction: String { pick(ko: "3분간 채팅금지", en: "3-min chat ban", ja: "3分間チャット禁止") }
|
||||
static var shortNoChattingAction: String { pick(ko: "채금", en: "Mute", ja: "チャ禁") }
|
||||
static var requestSpeakerAction: String { pick(ko: "스피커 요청하기", en: "Request speaker", ja: "スピーカー要請") }
|
||||
static var participantTitle: String { pick(ko: "참여자", en: "Participants", ja: "参加者") }
|
||||
static var staffTitle: String { pick(ko: "스탭", en: "Staff", ja: "スタッフ") }
|
||||
static var speakerTitle: String { pick(ko: "스피커", en: "Speaker", ja: "スピーカー") }
|
||||
static var listenerTitle: String { pick(ko: "리스너", en: "Listener", ja: "リスナー") }
|
||||
|
||||
static var rouletteSettingsTitle: String { pick(ko: "룰렛 설정", en: "Roulette settings", ja: "ルーレット設定") }
|
||||
static var rouletteActivatePrompt: String { pick(ko: "룰렛을 활성화 하시겠습니까?", en: "Activate roulette?", ja: "ルーレットを有効化しますか?") }
|
||||
static var rouletteCanSettingTitle: String { pick(ko: "룰렛 금액 설정", en: "Roulette amount", ja: "ルーレット金額設定") }
|
||||
static var rouletteCanPlaceholder: String { pick(ko: "룰렛 금액을 입력해 주세요 (최소 5캔)", en: "Enter roulette amount (min 5 cans)", ja: "ルーレット金額を入力してください(最小5can)") }
|
||||
static var rouletteOptionSettingTitle: String { pick(ko: "룰렛 옵션 설정", en: "Roulette options", ja: "ルーレットオプション設定") }
|
||||
static var rouletteOptionLimitNotice: String { pick(ko: "※ 룰렛 옵션은 최소 2개,\n최대 10개까지 설정할 수 있습니다.", en: "※ You can set 2 to 10 options.", ja: "※ ルーレットオプションは2個以上10個以下で設定できます。") }
|
||||
static var rouletteProbabilitySum: String { pick(ko: "옵션 확률 합계", en: "Total option probability", ja: "オプション確率合計") }
|
||||
static var roulettePreviewAction: String { pick(ko: "미리보기", en: "Preview", ja: "プレビュー") }
|
||||
static var rouletteCompleteAction: String { pick(ko: "설정완료", en: "Complete", ja: "設定完了") }
|
||||
static var roulettePreviewTitle: String { pick(ko: "룰렛 미리보기", en: "Roulette preview", ja: "ルーレットプレビュー") }
|
||||
static func rouletteSpinWithCan(_ can: Int) -> String {
|
||||
pick(ko: "\(can)캔으로 룰렛 돌리기", en: "Spin roulette with \(can) cans", ja: "\(can)canでルーレットを回す")
|
||||
}
|
||||
static func rouletteOptionTitle(_ index: Int) -> String { pick(ko: "옵션 \(index + 1)", en: "Option \(index + 1)", ja: "オプション \(index + 1)") }
|
||||
static var rouletteDeleteAction: String { pick(ko: "삭제", en: "Delete", ja: "削除") }
|
||||
static var rouletteOptionPlaceholder: String { pick(ko: "옵션을 입력하세요", en: "Enter option", ja: "オプションを入力してください") }
|
||||
static var rouletteOptionEmptyError: String { pick(ko: "옵션은 빈칸일 수 없습니다.", en: "Options cannot be empty.", ja: "オプションは空欄にできません。") }
|
||||
static var rouletteProbabilityInvalidError: String { pick(ko: "확률이 100%가 아닙니다", en: "Probability is not 100%.", ja: "確率が100%ではありません。") }
|
||||
static var rouletteNoChangesMessage: String { pick(ko: "변동사항이 없습니다.", en: "No changes.", ja: "変更事項がありません。") }
|
||||
static var rouletteNeedFirstMessage: String { pick(ko: "룰렛 1을 먼저 설정하세요", en: "Set Roulette 1 first.", ja: "先にルーレット1を設定してください。") }
|
||||
static var rouletteNeedFirstAndSecondMessage: String { pick(ko: "룰렛 1과 룰렛 2를 먼저 설정하세요", en: "Set Roulette 1 and 2 first.", ja: "先にルーレット1と2を設定してください。") }
|
||||
static func rouletteSetAsSuccess(_ title: String) -> String { pick(ko: "\(title)로 설정하였습니다.", en: "Set as \(title).", ja: "\(title)に設定しました。") }
|
||||
static func rouletteSetSuccess(_ title: String) -> String { pick(ko: "\(title)을 설정했습니다.", en: "\(title) has been set.", ja: "\(title)を設定しました。") }
|
||||
static func rouletteCreatedSuccess(_ title: String) -> String { pick(ko: "\(title)을 생성했습니다.", en: "\(title) has been created.", ja: "\(title)を作成しました。") }
|
||||
static func rouletteActivatedSuccess(_ title: String) -> String { pick(ko: "\(title)을 활성화 했습니다.", en: "\(title) has been activated.", ja: "\(title)を有効化しました。") }
|
||||
static func rouletteDeactivatedSuccess(_ title: String) -> String { pick(ko: "\(title)을 비활성화 했습니다.", en: "\(title) has been deactivated.", ja: "\(title)を無効化しました。") }
|
||||
static func rouletteChangedSuccess(_ title: String) -> String { pick(ko: "\(title)을 변경했습니다.", en: "\(title) has been changed.", ja: "\(title)を変更しました。") }
|
||||
static var rouletteUnavailableError: String { pick(ko: "룰렛을 사용할 수 없습니다. 다시 시도해 주세요.", en: "Roulette is unavailable. Please try again.", ja: "ルーレットを利用できません。もう一度お試しください。") }
|
||||
|
||||
static var newChatLabel: String { pick(ko: "새로운 채팅", en: "New chat", ja: "新しいチャット") }
|
||||
static var communitySectionTitle: String { pick(ko: "커뮤니티", en: "Community", ja: "コミュニティ") }
|
||||
static var latestFinishedSectionTitle: String { pick(ko: "최근 종료한 라이브", en: "Recently ended live", ja: "最近終了したライブ") }
|
||||
static var noticeTag: String { pick(ko: "[방송공지]", en: "[Notice]", ja: "[お知らせ]") }
|
||||
static var menuTag: String { pick(ko: "[메뉴판]", en: "[Menu]", ja: "[メニュー表]") }
|
||||
|
||||
static var detailViewChannel: String { pick(ko: "채널보기", en: "View channel", ja: "チャンネルを見る") }
|
||||
static var detailEdit: String { pick(ko: "수정", en: "Edit", ja: "編集") }
|
||||
static var detailStartLive: String { pick(ko: "라이브 시작", en: "Start live", ja: "ライブ開始") }
|
||||
static var detailReservationDelete: String { pick(ko: "예약삭제", en: "Delete reservation", ja: "予約削除") }
|
||||
static var detailReservationDone: String { pick(ko: "예약완료", en: "Reserved", ja: "予約完了") }
|
||||
static var detailReservationAction: String { pick(ko: "예약하기", en: "Reserve", ja: "予約する") }
|
||||
static var detailJoinNow: String { pick(ko: "지금 참여하기", en: "Join now", ja: "今すぐ参加") }
|
||||
static var detailReservationParticipant: String { pick(ko: "예약자", en: "Reserved users", ja: "予約者") }
|
||||
static var detailParticipant: String { pick(ko: "참가자", en: "Participants", ja: "参加者") }
|
||||
static var detailCollapse: String { pick(ko: "닫기", en: "Close", ja: "閉じる") }
|
||||
static var detailExpand: String { pick(ko: "펼쳐보기", en: "Expand", ja: "もっと見る") }
|
||||
|
||||
static var speakerRequestSent: String { pick(ko: "스피커 요청을 보냈습니다.\n잠시만 기다려 주세요.", en: "Speaker request sent.\nPlease wait a moment.", ja: "スピーカー要請を送信しました。\nしばらくお待ちください。") }
|
||||
static var speakerCapacityExceeded: String { pick(ko: "스피커 정원을 초과했습니다.", en: "Speaker capacity exceeded.", ja: "スピーカー定員を超えました。") }
|
||||
static func remainingNoChattingMessage(_ seconds: Int) -> String { pick(ko: "\(seconds)초 동안 채팅하실 수 없습니다", en: "You cannot chat for \(seconds) seconds.", ja: "\(seconds)秒間チャットできません。") }
|
||||
}
|
||||
|
||||
enum LiveRoom {
|
||||
@@ -1742,6 +1883,85 @@ enum I18n {
|
||||
|
||||
static var kickOutTitle: String { pick(ko: "내보내기", en: "Kick out", ja: "退場させる") }
|
||||
static var kickOutConfirm: String { pick(ko: "내보내기", en: "Kick out", ja: "退場させる") }
|
||||
static func kickOutQuestion(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 내보내시겠어요?", en: "Kick out \(nickname)?", ja: "\(nickname)さんを退出させますか?")
|
||||
}
|
||||
static func kickedOutMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 내보냈습니다.", en: "\(nickname) has been removed.", ja: "\(nickname)さんを退出させました。")
|
||||
}
|
||||
static func staffReleasedMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 스탭에서 해제했어요.", en: "\(nickname) has been removed from staff.", ja: "\(nickname)さんのスタッフ権限を解除しました。")
|
||||
}
|
||||
static func changedToListenerMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 리스너로 변경했어요.", en: "\(nickname) was changed to listener.", ja: "\(nickname)さんをリスナーに変更しました。")
|
||||
}
|
||||
static func assignedStaffMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 스탭으로 지정했습니다.", en: "\(nickname) was assigned as staff.", ja: "\(nickname)さんをスタッフに指定しました。")
|
||||
}
|
||||
static func noChattingAppliedMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님을 3분간 채팅금지를 하였습니다.", en: "\(nickname) has been chat-banned for 3 minutes.", ja: "\(nickname)さんを3分間チャット禁止にしました。")
|
||||
}
|
||||
static func noChattingByCreatorMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님이 3분간 채팅을 금지하였습니다.", en: "\(nickname) has muted your chat for 3 minutes.", ja: "\(nickname)さんが3分間チャットを禁止しました。")
|
||||
}
|
||||
static var noChattingReleasedMessage: String { pick(ko: "채팅금지가 해제되었습니다.", en: "Chat ban has been lifted.", ja: "チャット禁止が解除されました。") }
|
||||
|
||||
static var becameSpeakerMessage: String { pick(ko: "스피커가 되었어요!", en: "You are now a speaker!", ja: "スピーカーになりました!") }
|
||||
static var atLeastOneCanDonationMessage: String { pick(ko: "1캔 이상 후원하실 수 있습니다.", en: "You can donate 1 can or more.", ja: "1can以上後援できます。") }
|
||||
static var donationFailedMessage: String {
|
||||
pick(
|
||||
ko: "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다.",
|
||||
en: "Donation failed.\nPlease try donating again.\nIf the problem persists, contact customer support.",
|
||||
ja: "後援に失敗しました。\nもう一度後援してください。\n問題が続く場合はカスタマーサポートへお問い合わせください。"
|
||||
)
|
||||
}
|
||||
static var donationRefundFailedMessage: String {
|
||||
pick(
|
||||
ko: "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요.",
|
||||
en: "Failed donation cans were not refunded.\nPlease contact customer support.",
|
||||
ja: "後援失敗分のcanが返金されませんでした。\nカスタマーサポートへお問い合わせください。"
|
||||
)
|
||||
}
|
||||
static var donationStatusFetchFailed: String {
|
||||
pick(ko: "후원현황을 가져오지 못했습니다\n다시 시도해 주세요.", en: "Failed to load donation status.\nPlease try again.", ja: "後援状況を取得できませんでした。\nもう一度お試しください。")
|
||||
}
|
||||
static var heartRankingFetchFailed: String {
|
||||
pick(ko: "하트 랭킹을 가져오지 못했습니다\n다시 시도해 주세요.", en: "Failed to load heart ranking.\nPlease try again.", ja: "ハートランキングを取得できませんでした。\nもう一度お試しください。")
|
||||
}
|
||||
|
||||
static var liveEndedMessage: String { pick(ko: "라이브가 종료되었습니다.", en: "The live has ended.", ja: "ライブが終了しました。") }
|
||||
static func speakerRequestQuestion(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님이 스피커 요청을 했어요!\n스피커로 초대할까요?", en: "\(nickname) requested to be a speaker.\nInvite as speaker?", ja: "\(nickname)さんがスピーカーを要請しました。\nスピーカーに招待しますか?")
|
||||
}
|
||||
static var skipAction: String { pick(ko: "건너뛰기", en: "Skip", ja: "スキップ") }
|
||||
static var maybeLaterAction: String { pick(ko: "다음에요", en: "Maybe later", ja: "あとで") }
|
||||
static var joinAsSpeakerAction: String { pick(ko: "스피커로 참여하기", en: "Join as speaker", ja: "スピーカーとして参加") }
|
||||
static func kickedOutByCreatorMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님이 라이브에서 내보냈습니다.", en: "\(nickname) removed you from the live.", ja: "\(nickname)さんがライブから退出させました。")
|
||||
}
|
||||
static var kickedOutByHostMessage: String { pick(ko: "방장님이 라이브에서 내보냈습니다.", en: "Host removed you from the live.", ja: "配信者がライブから退出させました。") }
|
||||
static func assignedStaffByCreatorMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님이 스탭으로 지정했습니다.", en: "\(nickname) assigned you as staff.", ja: "\(nickname)さんがあなたをスタッフに指定しました。")
|
||||
}
|
||||
static var assignedStaffByHostMessage: String { pick(ko: "방장님이 스탭으로 지정했습니다", en: "Host assigned you as staff.", ja: "配信者があなたをスタッフに指定しました。") }
|
||||
static func releasedStaffByCreatorMessage(_ nickname: String) -> String {
|
||||
pick(ko: "\(nickname)님이 스탭에서 해제했습니다.", en: "\(nickname) removed your staff role.", ja: "\(nickname)さんがあなたのスタッフ権限を解除しました。")
|
||||
}
|
||||
static var releasedStaffByHostMessage: String { pick(ko: "방장님이 스탭에서 해제했습니다.", en: "Host removed your staff role.", ja: "配信者があなたのスタッフ権限を解除しました。") }
|
||||
static func invitePrivateLiveMessage(_ nickname: String, _ shareUrl: String, _ password: String) -> String {
|
||||
pick(
|
||||
ko: "\(nickname)님이 귀하를 보이스온 비공개라이브에 초대하였습니다.\n※ 라이브 참여: \(shareUrl)\n(입장 비밀번호: \(password))",
|
||||
en: "\(nickname) invited you to a private VoiceOn live.\n※ Join live: \(shareUrl)\n(Entry password: \(password))",
|
||||
ja: "\(nickname)さんがあなたをVoiceOn非公開ライブに招待しました。\n※ ライブ参加: \(shareUrl)\n(入場パスワード: \(password))"
|
||||
)
|
||||
}
|
||||
static func invitePublicLiveMessage(_ nickname: String, _ shareUrl: String) -> String {
|
||||
pick(
|
||||
ko: "\(nickname)님이 귀하를 보이스온 공개라이브에 초대하였습니다.\n※ 라이브 참여: \(shareUrl)",
|
||||
en: "\(nickname) invited you to a public VoiceOn live.\n※ Join live: \(shareUrl)",
|
||||
ja: "\(nickname)さんがあなたをVoiceOn公開ライブに招待しました。\n※ ライブ参加: \(shareUrl)"
|
||||
)
|
||||
}
|
||||
|
||||
static var leaveButton: String { pick(ko: "나가기", en: "Leave", ja: "退出") }
|
||||
static var endButton: String { pick(ko: "라이브 종료", en: "End live", ja: "ライブ終了") }
|
||||
@@ -1764,6 +1984,7 @@ enum I18n {
|
||||
static var chatFreezeOnStatusMessageForListener: String { pick(ko: "“🧊 모두들 얼음!” 채팅창이 얼었습니다.", en: "\"🧊 Freeze, everyone!\" The chat is now frozen.", ja: "「🧊 みんなフリーズ!」チャットが凍結されました。") }
|
||||
static var chatFreezeOffStatusMessage: String { pick(ko: "“💧땡! “ 채팅창 얼리기가 해제되었습니다.", en: "\"💧 Ding!\" Chat freeze has been lifted.", ja: "「💧 たん!」チャット凍結が解除されました。") }
|
||||
static var chatFreezeBlockedMessage: String { pick(ko: "🧊 채팅창이 얼었습니다.", en: "🧊 The chat is now frozen.", ja: "🧊 チャットが凍結されました。") }
|
||||
static var chatInputPlaceholder: String { pick(ko: "채팅을 입력하세요", en: "Enter a chat message", ja: "チャットを入力してください") }
|
||||
static var chatDeleteTitle: String { pick(ko: "채팅 삭제", en: "Delete chat", ja: "チャット削除") }
|
||||
}
|
||||
|
||||
@@ -1968,6 +2189,14 @@ enum I18n {
|
||||
pick(ko: "스탭", en: "Staff", ja: "スタッフ")
|
||||
}
|
||||
|
||||
static var rouletteResultQuestionSuffix: String {
|
||||
pick(ko: "님이 룰렛에 당첨된 건?", en: " hit on the roulette?", ja: "さんがルーレットで当たったのは?")
|
||||
}
|
||||
|
||||
static var rouletteWinSuffix: String {
|
||||
pick(ko: " 당첨!", en: " won!", ja: " 当選!")
|
||||
}
|
||||
|
||||
static var donationMemberSuffix: String {
|
||||
pick(ko: "님이", en: "", ja: "さんが")
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ struct LiveRoomRouletteDonationChatItemView: View {
|
||||
.appFont(size: 12)
|
||||
.foregroundColor(.white)
|
||||
|
||||
Text("님의 룰렛 결과?")
|
||||
Text(I18n.LiveChat.rouletteResultQuestionSuffix)
|
||||
.appFont(size: 12, weight: .light)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
@@ -51,7 +51,7 @@ struct LiveRoomRouletteDonationChatItemView: View {
|
||||
|
||||
+
|
||||
|
||||
Text(" 당첨!")
|
||||
Text(I18n.LiveChat.rouletteWinSuffix)
|
||||
.appFont(size: 15)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ struct LiveRoomCreateView: View {
|
||||
.resizable()
|
||||
.frame(width: 20, height: 20)
|
||||
|
||||
Text("라이브 만들기")
|
||||
Text(I18n.CreateLive.createLiveTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ struct LiveRoomCreateView: View {
|
||||
Spacer()
|
||||
|
||||
if viewModel.isShowGetRecentInfoButton {
|
||||
Text("최근 데이터 가져오기")
|
||||
Text(I18n.CreateLive.fetchRecentData)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.vertical, 8)
|
||||
@@ -81,7 +81,7 @@ struct LiveRoomCreateView: View {
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
Text("썸네일")
|
||||
Text(I18n.CreateLive.thumbnail)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(.horizontal, 13.3)
|
||||
@@ -167,7 +167,7 @@ struct LiveRoomCreateView: View {
|
||||
.padding(.top, 33.3)
|
||||
|
||||
VStack(spacing: 13.3) {
|
||||
Text("크리에이터 입장 설정")
|
||||
Text(I18n.CreateLive.creatorEntrySetting)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
@@ -235,7 +235,7 @@ struct LiveRoomCreateView: View {
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text("라이브 오픈하기")
|
||||
Text(I18n.CreateLive.openLiveAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.frame(width: screenSize().width - 26.7, height: 50)
|
||||
@@ -357,13 +357,13 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func TitleInputView() -> some View {
|
||||
VStack(spacing: 0) {
|
||||
Text("제목")
|
||||
Text(I18n.CreateLive.titleLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(.horizontal, 13.3)
|
||||
.frame(width: screenSize().width, alignment: .leading)
|
||||
|
||||
TextField("라이브 제목을 입력하세요", text: $viewModel.title)
|
||||
TextField(I18n.CreateLive.titlePlaceholder, text: $viewModel.title)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
@@ -383,7 +383,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func TagSelectView() -> some View {
|
||||
VStack(alignment: .leading, spacing: 13.3) {
|
||||
Text("관심사")
|
||||
Text(I18n.CreateLive.interestsLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -391,7 +391,7 @@ struct LiveRoomCreateView: View {
|
||||
hideKeyboard()
|
||||
isShowSelectTagView = true
|
||||
}) {
|
||||
Text("관심사 선택")
|
||||
Text(I18n.CreateLive.selectInterestsAction)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.vertical, 13.7)
|
||||
@@ -434,16 +434,16 @@ struct LiveRoomCreateView: View {
|
||||
func ContentInputView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
HStack(spacing: 0) {
|
||||
Text("공지")
|
||||
Text(I18n.CreateLive.noticeLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(viewModel.content.count)자")
|
||||
Text(I18n.CreateLive.noticeCount(viewModel.content.count))
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.mainRed)
|
||||
Text(" / 1000자")
|
||||
Text(I18n.CreateLive.noticeLimitSuffix)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
@@ -463,7 +463,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func TimeSettingView() -> some View {
|
||||
VStack(spacing: 0) {
|
||||
Text("시간설정")
|
||||
Text(I18n.CreateLive.timeSettingLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
@@ -524,7 +524,7 @@ struct LiveRoomCreateView: View {
|
||||
func ReservationDateTimeView(buttonWidth: CGFloat) -> some View {
|
||||
HStack(spacing: 13.3) {
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 날짜")
|
||||
Text(I18n.CreateLive.reservationDateLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -544,7 +544,7 @@ struct LiveRoomCreateView: View {
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 시간")
|
||||
Text(I18n.CreateLive.reservationTimeLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -571,12 +571,12 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func NumberOfPeopleLimitView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("참여인원 설정")
|
||||
Text(I18n.CreateLive.participantLimitLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
|
||||
TextField("최대 인원 999명", text: $viewModel.numberOfPeople)
|
||||
TextField(I18n.CreateLive.participantLimitPlaceholder, text: $viewModel.numberOfPeople)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.multilineTextAlignment(.center)
|
||||
@@ -608,7 +608,7 @@ struct LiveRoomCreateView: View {
|
||||
.frame(width: proxy.size.width)
|
||||
|
||||
Button(action: { self.isShowSelectDateView = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.CreateLive.confirmButton)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(.vertical, 10)
|
||||
@@ -639,7 +639,7 @@ struct LiveRoomCreateView: View {
|
||||
.frame(width: proxy.size.width - 53.4)
|
||||
|
||||
Button(action: { self.isShowSelectTimeView = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.CreateLive.confirmButton)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(.vertical, 10)
|
||||
@@ -656,7 +656,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func RoomTypeSettingView() -> some View {
|
||||
VStack(spacing: 0) {
|
||||
Text("공개 설정")
|
||||
Text(I18n.CreateLive.visibilityLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
@@ -709,12 +709,12 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func RoomPasswordView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("방 비밀번호 입력")
|
||||
Text(I18n.CreateLive.roomPasswordTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
|
||||
TextField("방 입장 비밀번호 6자리를 입력해 주세요.", text: $viewModel.password)
|
||||
TextField(I18n.CreateLive.roomPasswordPlaceholder, text: $viewModel.password)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.multilineTextAlignment(.center)
|
||||
@@ -732,7 +732,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func AdultSettingView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("연령 제한")
|
||||
Text(I18n.CreateLive.ageRestrictionLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
@@ -828,7 +828,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func PriceSettingView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("티켓 가격")
|
||||
Text(I18n.CreateLive.ticketPriceLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
@@ -861,7 +861,7 @@ struct LiveRoomCreateView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateLive.canUnit)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
}
|
||||
@@ -878,7 +878,7 @@ struct LiveRoomCreateView: View {
|
||||
@ViewBuilder
|
||||
func PriceButtonView(price: Int, buttonWidth: CGFloat) -> some View {
|
||||
HStack(spacing: 6.7) {
|
||||
Text(price == 0 ? "무료" : "\(price) 캔")
|
||||
Text(I18n.CreateLive.priceOption(price))
|
||||
.appFont(size: 14.7, weight: viewModel.price == price ? .bold : .medium)
|
||||
.foregroundColor(viewModel.price == price ? Color.button : Color.gray77)
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ struct LiveRoomCreateTagView: View {
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("관심사 선택")
|
||||
Text(I18n.CreateLive.tagSelectionTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
|
||||
Text("최대 3개까지 선택 가능합니다.")
|
||||
Text(I18n.CreateLive.tagSelectionSubtitle)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
}
|
||||
@@ -100,7 +100,7 @@ struct LiveRoomCreateTagView: View {
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, 26.7)
|
||||
|
||||
Text("확인")
|
||||
Text(I18n.CreateLive.tagConfirmButton)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
.padding(.vertical, 16)
|
||||
|
||||
@@ -44,13 +44,13 @@ final class LiveRoomCreateTagViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ struct LiveDetailView: View {
|
||||
.frame(width: 26.7, height: 26.7)
|
||||
.padding(.leading, 6.7)
|
||||
} else {
|
||||
Text("무료")
|
||||
Text(I18n.CreateContent.free)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
}
|
||||
@@ -185,7 +185,7 @@ struct LiveDetailView: View {
|
||||
.resizable()
|
||||
.frame(width: 13.3, height: 13.3)
|
||||
|
||||
Text("채널보기")
|
||||
Text(I18n.CreateLive.detailViewChannel)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.white)
|
||||
.onTapGesture {
|
||||
@@ -278,7 +278,7 @@ struct LiveDetailView: View {
|
||||
if room.manager.id == UserDefaults.int(forKey: .userId) {
|
||||
VStack(spacing: 16.7) {
|
||||
HStack(spacing: 13.3) {
|
||||
Text("수정")
|
||||
Text(I18n.CreateLive.detailEdit)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -294,7 +294,7 @@ struct LiveDetailView: View {
|
||||
AppState.shared.setAppStep(step: .modifyLive(room: room))
|
||||
}
|
||||
|
||||
Text("라이브 시작")
|
||||
Text(I18n.CreateLive.detailStartLive)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -307,7 +307,7 @@ struct LiveDetailView: View {
|
||||
}
|
||||
}
|
||||
|
||||
Text("예약삭제")
|
||||
Text(I18n.CreateLive.detailReservationDelete)
|
||||
.appFont(size: 14, weight: .medium)
|
||||
.foregroundColor(Color(hex: "ff5c49"))
|
||||
.padding(5.3)
|
||||
@@ -323,7 +323,7 @@ struct LiveDetailView: View {
|
||||
}
|
||||
.frame(width: screenSize().width - 26.7)
|
||||
} else if room.isPaid {
|
||||
Text("예약완료")
|
||||
Text(I18n.CreateLive.detailReservationDone)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.padding(.vertical, 16)
|
||||
@@ -336,7 +336,7 @@ struct LiveDetailView: View {
|
||||
onClickReservation()
|
||||
AppState.shared.back()
|
||||
} label: {
|
||||
Text("예약하기")
|
||||
Text(I18n.CreateLive.detailReservationAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -351,7 +351,7 @@ struct LiveDetailView: View {
|
||||
onClickParticipant()
|
||||
AppState.shared.back()
|
||||
} label: {
|
||||
Text("지금 참여하기")
|
||||
Text(I18n.CreateLive.detailJoinNow)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -369,7 +369,7 @@ struct LiveDetailView: View {
|
||||
private func ParticipantView(room: GetRoomDetailResponse) -> some View {
|
||||
if isExpandParticipantArea {
|
||||
HStack(spacing: 0) {
|
||||
Text(room.channelName.isNullOrBlank() ? "예약자" : "참가자")
|
||||
Text(room.channelName.isNullOrBlank() ? I18n.CreateLive.detailReservationParticipant : I18n.CreateLive.detailParticipant)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.graybb)
|
||||
|
||||
@@ -450,7 +450,7 @@ struct LiveDetailView: View {
|
||||
.resizable()
|
||||
.frame(width: 20, height: 20)
|
||||
|
||||
Text(isExpandParticipantArea ? "닫기" : "펼쳐보기")
|
||||
Text(isExpandParticipantArea ? I18n.CreateLive.detailCollapse : I18n.CreateLive.detailExpand)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.graybb)
|
||||
}
|
||||
|
||||
@@ -49,14 +49,14 @@ final class LiveDetailViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
|
||||
@@ -96,13 +96,13 @@ final class LiveDetailViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ struct LiveRoomDonationMessageDialog: View {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("후원 히스토리")
|
||||
Text(I18n.CreateLive.donationHistoryTitle)
|
||||
.appFont(size: 14.7, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
@@ -35,7 +35,7 @@ struct LiveRoomDonationMessageDialog: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("닫기")
|
||||
Text(I18n.CreateLive.closeAction)
|
||||
.appFont(size: 14.7, weight: .light)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.onTapGesture { isShowing = false }
|
||||
@@ -52,14 +52,14 @@ struct LiveRoomDonationMessageDialog: View {
|
||||
}
|
||||
.onTapGesture {
|
||||
UIPasteboard.general.string = donationMessage.donationMessage
|
||||
self.viewModel.errorMessage = "후원 히스토리가 복사되었습니다."
|
||||
self.viewModel.errorMessage = I18n.CreateLive.donationHistoryCopied
|
||||
self.viewModel.isShowPopup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.top, 18.7)
|
||||
} else {
|
||||
Text("후원 히스토리가 없습니다.")
|
||||
Text(I18n.CreateLive.donationHistoryEmpty)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.top, 30)
|
||||
|
||||
@@ -16,7 +16,7 @@ struct LiveRoomDonationMessageItemView: View {
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("\(message.nickname)님이")
|
||||
Text("\(message.nickname)\(I18n.LiveChat.donationMemberSuffix)")
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(.white)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ struct LiveRoomDonationRankingDialog: View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("현재 라이브 후원랭킹")
|
||||
Text(I18n.CreateLive.donationRankingTitle)
|
||||
.appFont(size: 14.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -33,7 +33,7 @@ struct LiveRoomDonationRankingDialog: View {
|
||||
.padding(.top, 25)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("전체")
|
||||
Text(I18n.CreateLive.totalLabel)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -42,7 +42,7 @@ struct LiveRoomDonationRankingDialog: View {
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.leading, 6.7)
|
||||
|
||||
Text("명")
|
||||
Text(I18n.CreateLive.peopleUnit)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ struct LiveRoomDonationRankingItemView: View {
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateLive.canUnit)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
}
|
||||
@@ -63,7 +63,7 @@ struct LiveRoomDonationRankingItemView: View {
|
||||
|
||||
if item.secretCan > 0 {
|
||||
HStack(spacing: 4) {
|
||||
Text("비밀")
|
||||
Text(I18n.CreateLive.secretLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray11)
|
||||
.padding(.horizontal, 3.3)
|
||||
@@ -75,7 +75,7 @@ struct LiveRoomDonationRankingItemView: View {
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "fedc00"))
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateLive.canUnit)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ struct LiveRoomDonationRankingTotalCanView: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Text("합계")
|
||||
Text(I18n.CreateLive.sumLabel)
|
||||
.appFont(size: 13.3, weight: .bold)
|
||||
.foregroundColor(Color.grayd2)
|
||||
|
||||
@@ -23,7 +23,7 @@ struct LiveRoomDonationRankingTotalCanView: View {
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayd2)
|
||||
|
||||
Text("일반")
|
||||
Text(I18n.CreateLive.normalLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
|
||||
@@ -31,7 +31,7 @@ struct LiveRoomDonationRankingTotalCanView: View {
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayd2)
|
||||
|
||||
Text("비밀")
|
||||
Text(I18n.CreateLive.secretLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "fedc00"))
|
||||
|
||||
@@ -55,7 +55,7 @@ struct LiveRoomDonationRankingTotalCanView: View {
|
||||
.foregroundColor(Color(hex: "fedc00"))
|
||||
}
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateLive.canUnit)
|
||||
.appFont(size: 10.7, weight: .medium)
|
||||
.foregroundColor(Color.graybb)
|
||||
.padding(.leading, 4)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct LiveRoomHeartRankingDialog: View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("현재 라이브 하트랭킹")
|
||||
Text(I18n.CreateLive.heartRankingTitle)
|
||||
.appFont(size: 14.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -34,7 +34,7 @@ struct LiveRoomHeartRankingDialog: View {
|
||||
|
||||
if let heartStatus = heartStatus {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Text("합계")
|
||||
Text(I18n.CreateLive.sumLabel)
|
||||
.appFont(size: 13.3, weight: .bold)
|
||||
.foregroundColor(Color.grayd2)
|
||||
|
||||
@@ -44,7 +44,7 @@ struct LiveRoomHeartRankingDialog: View {
|
||||
.appFont(size: 14, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
|
||||
Text("하트")
|
||||
Text(I18n.CreateLive.heartLabel)
|
||||
.appFont(size: 10.7, weight: .medium)
|
||||
.foregroundColor(Color.graybb)
|
||||
.padding(.leading, 4)
|
||||
@@ -56,7 +56,7 @@ struct LiveRoomHeartRankingDialog: View {
|
||||
.padding(.top, 25)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("전체")
|
||||
Text(I18n.CreateLive.totalLabel)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -65,7 +65,7 @@ struct LiveRoomHeartRankingDialog: View {
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.leading, 6.7)
|
||||
|
||||
Text("명")
|
||||
Text(I18n.CreateLive.peopleUnit)
|
||||
.appFont(size: 12, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ struct LiveRoomHeartRankingItemView: View {
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.button)
|
||||
|
||||
Text("하트")
|
||||
Text(I18n.CreateLive.heartLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ struct LiveRoomInfoEditDialog: View {
|
||||
@State private var isAdult = false
|
||||
@State private var isEntryMessageEnabled = true
|
||||
|
||||
let placeholder = "라이브 공지를 입력하세요"
|
||||
let placeholder = I18n.CreateLive.noticePlaceholder
|
||||
|
||||
@StateObject var viewModel: LiveRoomViewModel
|
||||
|
||||
@@ -62,7 +62,7 @@ struct LiveRoomInfoEditDialog: View {
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("라이브 수정")
|
||||
Text(I18n.CreateLive.editLiveTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -131,12 +131,12 @@ struct LiveRoomInfoEditDialog: View {
|
||||
|
||||
if UserDefaults.bool(forKey: .auth) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("연령제한")
|
||||
Text(I18n.CreateLive.ageRestrictionLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("19세 이상")
|
||||
Text(I18n.CreateLive.over19)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -163,7 +163,7 @@ struct LiveRoomInfoEditDialog: View {
|
||||
.padding(.top, 33.3)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("입장메시지")
|
||||
Text(I18n.CreateLive.entryMessageLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -179,7 +179,7 @@ struct LiveRoomInfoEditDialog: View {
|
||||
.padding(.top, 33.3)
|
||||
|
||||
HStack(spacing: 13.3) {
|
||||
Text("취소")
|
||||
Text(I18n.Common.cancel)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.vertical, 16)
|
||||
@@ -195,7 +195,7 @@ struct LiveRoomInfoEditDialog: View {
|
||||
isShowing = false
|
||||
}
|
||||
|
||||
Text("수정하기")
|
||||
Text(I18n.CreateLive.editAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -251,11 +251,11 @@ struct LiveRoomInfoEditDialog: View {
|
||||
@ViewBuilder
|
||||
func TitleInputView() -> some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text("제목")
|
||||
Text(I18n.CreateLive.titleLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
TextField("라이브 제목을 입력하세요", text: $title)
|
||||
TextField(I18n.CreateLive.titlePlaceholder, text: $title)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
@@ -276,16 +276,16 @@ struct LiveRoomInfoEditDialog: View {
|
||||
func ContentInputView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
HStack(spacing: 0) {
|
||||
Text("공지")
|
||||
Text(I18n.CreateLive.noticeLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(notice.count)자")
|
||||
Text(I18n.CreateLive.noticeCount(notice.count))
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.mainRed)
|
||||
Text(" / 1000자")
|
||||
Text(I18n.CreateLive.noticeLimitSuffix)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ struct LiveRoomNoChattingDialogView: View {
|
||||
.frame(width: screenSize().width, height: screenSize().height)
|
||||
|
||||
VStack(spacing: 21) {
|
||||
Text("채팅금지")
|
||||
Text(I18n.CreateLive.noChattingTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
|
||||
@@ -43,12 +43,12 @@ struct LiveRoomNoChattingDialogView: View {
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
}
|
||||
|
||||
Text("3분간 채팅금지를 하겠습니까?")
|
||||
Text(I18n.CreateLive.noChattingQuestion)
|
||||
.appFont(size: 15, weight: .medium)
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
|
||||
HStack(spacing: 13.3) {
|
||||
Text("취소")
|
||||
Text(I18n.Common.cancel)
|
||||
.appFont(size: 15.3, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.vertical, 16)
|
||||
@@ -61,7 +61,7 @@ struct LiveRoomNoChattingDialogView: View {
|
||||
)
|
||||
.onTapGesture { cancelAction() }
|
||||
|
||||
Text("확인")
|
||||
Text(I18n.Common.confirm)
|
||||
.appFont(size: 15.3, weight: .bold)
|
||||
.foregroundColor(Color(hex: "ffffff"))
|
||||
.padding(.vertical, 16)
|
||||
|
||||
@@ -51,7 +51,7 @@ struct LiveRoomProfileDialog: View {
|
||||
|
||||
if isSpeaker {
|
||||
if profileInfo.role == .LISTENER, let onClickInviteSpeaker = onClickInviteSpeaker {
|
||||
Text("스피커로 초대")
|
||||
Text(I18n.CreateLive.inviteSpeakerAction)
|
||||
.appFont(size: 10, weight: .medium)
|
||||
.foregroundColor(.button)
|
||||
.padding(.horizontal, 15.4)
|
||||
@@ -66,7 +66,7 @@ struct LiveRoomProfileDialog: View {
|
||||
|
||||
if (memberId == creatorId || memberId == profileInfo.id) && profileInfo.id != creatorId && profileInfo.role == .SPEAKER,
|
||||
let onClickChangeListener = onClickChangeListener {
|
||||
Text("리스너로 변경")
|
||||
Text(I18n.CreateLive.changeListenerAction)
|
||||
.appFont(size: 10, weight: .medium)
|
||||
.foregroundColor(.button)
|
||||
.padding(.horizontal, 15.4)
|
||||
|
||||
@@ -132,7 +132,7 @@ struct LiveRoomProfileItemUserView: View {
|
||||
Spacer()
|
||||
|
||||
if role == .LISTENER && isStaff {
|
||||
Text("스피커로 초대")
|
||||
Text(I18n.CreateLive.inviteSpeakerAction)
|
||||
.appFont(size: 10, weight: .medium)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 5.5)
|
||||
@@ -149,7 +149,7 @@ struct LiveRoomProfileItemUserView: View {
|
||||
}
|
||||
|
||||
if role == .SPEAKER && (userId == UserDefaults.int(forKey: .userId) || isStaff) {
|
||||
Text("리스너로 변경")
|
||||
Text(I18n.CreateLive.changeListenerAction)
|
||||
.appFont(size: 10, weight: .medium)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 5.5)
|
||||
@@ -162,7 +162,7 @@ struct LiveRoomProfileItemUserView: View {
|
||||
}
|
||||
|
||||
if role != .MANAGER && creatorId == UserDefaults.int(forKey: .userId) {
|
||||
Text("채금")
|
||||
Text(I18n.CreateLive.shortNoChattingAction)
|
||||
.appFont(size: 10, weight: .medium)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 5.5)
|
||||
@@ -206,7 +206,7 @@ struct LiveRoomProfileRequestSpeakerView: View {
|
||||
HStack(spacing: 6.7) {
|
||||
Spacer()
|
||||
Image("ic_request_speak")
|
||||
Text("스피커 요청하기")
|
||||
Text(I18n.CreateLive.requestSpeakerAction)
|
||||
.appFont(size: 13.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
Spacer()
|
||||
|
||||
@@ -35,7 +35,7 @@ struct LiveRoomProfilesDialogView: View {
|
||||
self.profiles.append(
|
||||
AnyView(
|
||||
LiveRoomProfileItemTitleView(
|
||||
title: "스탭",
|
||||
title: I18n.CreateLive.staffTitle,
|
||||
count: roomInfo.managerList.count,
|
||||
totalCount: nil
|
||||
)
|
||||
@@ -71,7 +71,7 @@ struct LiveRoomProfilesDialogView: View {
|
||||
self.profiles.append(
|
||||
AnyView(
|
||||
LiveRoomProfileItemTitleView(
|
||||
title: "스피커",
|
||||
title: I18n.CreateLive.speakerTitle,
|
||||
count: roomInfo.speakerList.count - 1,
|
||||
totalCount: roomInfo.totalAvailableParticipantsCount
|
||||
)
|
||||
@@ -127,7 +127,7 @@ struct LiveRoomProfilesDialogView: View {
|
||||
self.profiles.append(
|
||||
AnyView(
|
||||
LiveRoomProfileItemTitleView(
|
||||
title: "리스너",
|
||||
title: I18n.CreateLive.listenerTitle,
|
||||
count: nil,
|
||||
totalCount: nil
|
||||
)
|
||||
@@ -150,10 +150,10 @@ struct LiveRoomProfilesDialogView: View {
|
||||
onClickInviteSpeaker: {
|
||||
if viewModel.liveRoomInfo!.speakerList.count <= 5 {
|
||||
viewModel.inviteSpeaker(peerId: $0)
|
||||
viewModel.popupContent = "스피커 요청을 보냈습니다.\n잠시만 기다려 주세요."
|
||||
viewModel.popupContent = I18n.CreateLive.speakerRequestSent
|
||||
viewModel.isShowPopup = true
|
||||
} else {
|
||||
viewModel.errorMessage = "스피커 정원을 초과했습니다."
|
||||
viewModel.errorMessage = I18n.CreateLive.speakerCapacityExceeded
|
||||
viewModel.isShowErrorPopup = true
|
||||
}
|
||||
},
|
||||
@@ -173,7 +173,7 @@ struct LiveRoomProfilesDialogView: View {
|
||||
ZStack {
|
||||
VStack(spacing: 16.7) {
|
||||
HStack(spacing: 0) {
|
||||
Text("참여자")
|
||||
Text(I18n.CreateLive.participantTitle)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct LiveRoomUserProfileDialogView: View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("프로필")
|
||||
Text(I18n.CreateLive.profileTitle)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -91,7 +91,7 @@ struct LiveRoomUserProfileDialogView: View {
|
||||
|
||||
HStack(spacing: 8) {
|
||||
if let isSpeaker = userProfile.isSpeaker {
|
||||
Text(isSpeaker ? "리스너 변경" : "스피커 초대")
|
||||
Text(isSpeaker ? I18n.CreateLive.changeListenerAction : I18n.CreateLive.inviteSpeakerAction)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
@@ -114,7 +114,7 @@ struct LiveRoomUserProfileDialogView: View {
|
||||
}
|
||||
|
||||
if let isManager = userProfile.isManager {
|
||||
Text(isManager ? "스탭 해제" : "스탭 지정")
|
||||
Text(isManager ? I18n.CreateLive.staffReleaseAction : I18n.CreateLive.staffAssignAction)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
@@ -138,7 +138,7 @@ struct LiveRoomUserProfileDialogView: View {
|
||||
|
||||
if (userProfile.isSpeaker != nil && !viewModel.isEqualToStaffId(creatorId: userProfile.userId)) ||
|
||||
(userProfile.isSpeaker != nil && userProfile.isManager != nil) {
|
||||
Text("내보내기")
|
||||
Text(I18n.CreateLive.kickOutAction)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
@@ -159,7 +159,7 @@ struct LiveRoomUserProfileDialogView: View {
|
||||
.padding(.top, 21.3)
|
||||
|
||||
if let _ = userProfile.isManager {
|
||||
Text("3분간 채팅금지")
|
||||
Text(I18n.CreateLive.noChattingAction)
|
||||
.appFont(size: 15, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
@@ -27,7 +27,7 @@ struct LiveRoomEditView: View {
|
||||
BaseView(isLoading: $viewModel.isLoading) {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
DetailNavigationBar(title: "라이브 수정")
|
||||
DetailNavigationBar(title: I18n.CreateLive.editLiveTitle)
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
VStack(spacing: 0) {
|
||||
@@ -53,7 +53,7 @@ struct LiveRoomEditView: View {
|
||||
}
|
||||
|
||||
if !viewModel.isLoading {
|
||||
Text("라이브 수정")
|
||||
Text(I18n.CreateLive.editLiveTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.frame(width: screenSize().width - 26.7, height: 50)
|
||||
@@ -94,13 +94,13 @@ struct LiveRoomEditView: View {
|
||||
@ViewBuilder
|
||||
func TitleInputView() -> some View {
|
||||
VStack(spacing: 0) {
|
||||
Text("제목")
|
||||
Text(I18n.CreateLive.titleLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.horizontal, 13.3)
|
||||
.frame(width: screenSize().width, alignment: .leading)
|
||||
|
||||
TextField("라이브 제목을 입력하세요", text: $viewModel.title)
|
||||
TextField(I18n.CreateLive.titlePlaceholder, text: $viewModel.title)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
@@ -121,16 +121,16 @@ struct LiveRoomEditView: View {
|
||||
func ContentInputView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
HStack(spacing: 0) {
|
||||
Text("공지")
|
||||
Text(I18n.CreateLive.noticeLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(viewModel.notice.count)자")
|
||||
Text(I18n.CreateLive.noticeCount(viewModel.notice.count))
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "ff5c49"))
|
||||
Text(" / 1000자")
|
||||
Text(I18n.CreateLive.noticeLimitSuffix)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
}
|
||||
@@ -151,7 +151,7 @@ struct LiveRoomEditView: View {
|
||||
func ReservationDateTimeView(buttonWidth: CGFloat) -> some View {
|
||||
HStack(spacing: 13.3) {
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 날짜")
|
||||
Text(I18n.CreateLive.reservationDateLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
@@ -171,7 +171,7 @@ struct LiveRoomEditView: View {
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 시간")
|
||||
Text(I18n.CreateLive.reservationTimeLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
@@ -198,12 +198,12 @@ struct LiveRoomEditView: View {
|
||||
@ViewBuilder
|
||||
func NumberOfPeopleLimitView() -> some View {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("참여인원 설정")
|
||||
Text(I18n.CreateLive.participantLimitLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
|
||||
TextField("최대 인원 999명", text: $viewModel.numberOfPeople)
|
||||
TextField(I18n.CreateLive.participantLimitPlaceholder, text: $viewModel.numberOfPeople)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.multilineTextAlignment(.center)
|
||||
@@ -285,7 +285,7 @@ struct LiveRoomEditView: View {
|
||||
.frame(width: proxy.size.width)
|
||||
|
||||
Button(action: { self.isShowSelectDateView = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.CreateLive.confirmButton)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.vertical, 10)
|
||||
@@ -316,7 +316,7 @@ struct LiveRoomEditView: View {
|
||||
.frame(width: proxy.size.width - 53.4)
|
||||
|
||||
Button(action: { self.isShowSelectTimeView = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.CreateLive.confirmButton)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.vertical, 10)
|
||||
|
||||
@@ -51,7 +51,7 @@ final class LiveRoomEditViewModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
let placeholder = "라이브 공지를 입력하세요"
|
||||
let placeholder = I18n.CreateLive.noticePlaceholder
|
||||
|
||||
var room: GetRoomDetailResponse? = nil {
|
||||
didSet {
|
||||
@@ -103,7 +103,7 @@ final class LiveRoomEditViewModel: ObservableObject {
|
||||
request.beginDateTimeString == nil &&
|
||||
request.genderRestriction == nil
|
||||
) {
|
||||
self.errorMessage = "변경사항이 없습니다."
|
||||
self.errorMessage = I18n.CreateLive.noChangesMessage
|
||||
self.isShowPopup = true
|
||||
isLoading = false
|
||||
return
|
||||
@@ -135,7 +135,7 @@ final class LiveRoomEditViewModel: ObservableObject {
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.errorMessage = "라이브 정보가 수정되었습니다."
|
||||
self.errorMessage = I18n.CreateLive.editSuccessMessage
|
||||
self.isShowPopup = true
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
@@ -146,19 +146,19 @@ final class LiveRoomEditViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "라이브 정보를 수정 하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.CreateLive.editFailedMessage
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "라이브 정보를 수정 하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.CreateLive.editFailedMessage
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
} else {
|
||||
self.errorMessage = "라이브 정보를 수정 하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.CreateLive.editFailedMessage
|
||||
self.isShowPopup = true
|
||||
self.isLoading = false
|
||||
}
|
||||
@@ -167,20 +167,20 @@ final class LiveRoomEditViewModel: ObservableObject {
|
||||
|
||||
private func validate() -> Bool {
|
||||
if title.trimmingCharacters(in: .whitespaces).isEmpty {
|
||||
self.errorMessage = "제목을 입력해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.enterTitle
|
||||
self.isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
let notice = notice.trimmingCharacters(in: .whitespacesAndNewlines) != placeholder ? notice : ""
|
||||
if notice.isEmpty && notice.count < 5 {
|
||||
self.errorMessage = "공지를 5자 이상 입력해주세요."
|
||||
self.errorMessage = I18n.CreateLive.enterNoticeMin5
|
||||
self.isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
guard let numberOfPeople = Int(numberOfPeople), (numberOfPeople >= 3 && numberOfPeople <= 999) else {
|
||||
self.errorMessage = "인원을 3~999명 사이로 입력해주세요."
|
||||
self.errorMessage = I18n.CreateLive.enterPeopleRange
|
||||
self.isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
@Published var kickOutDesc = ""
|
||||
@Published var kickOutId = 0 {
|
||||
didSet {
|
||||
kickOutDesc = "\(getUserNicknameAndProfileUrl(accountId: kickOutId).nickname)님을 내보내시겠어요?"
|
||||
kickOutDesc = I18n.LiveRoom.kickOutQuestion(getUserNicknameAndProfileUrl(accountId: kickOutId).nickname)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,13 +579,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowErrorPopup = true
|
||||
@@ -674,7 +674,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.isLoading = false
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -726,7 +726,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.popupContent = I18n.LiveRoom.chatFreezeBlockedMessage
|
||||
self.isShowPopup = true
|
||||
} else if isNoChatting {
|
||||
self.popupContent = "\(remainingNoChattingTime)초 동안 채팅하실 수 없습니다"
|
||||
self.popupContent = I18n.CreateLive.remainingNoChattingMessage(remainingNoChattingTime)
|
||||
self.isShowPopup = true
|
||||
} else if !chatMessage.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
let chatId = UUID().uuidString
|
||||
@@ -887,10 +887,10 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
|
||||
func donation(can: Int, message: String = "", isSecret: Bool = false) {
|
||||
if isSecret && can < 10 {
|
||||
popupContent = "비밀 미션은 최소 10캔 이상부터 이용이 가능합니다."
|
||||
popupContent = I18n.LiveRoom.secretMissionMinimumCanMessage
|
||||
isShowPopup = true
|
||||
} else if can < 1 {
|
||||
popupContent = "1캔 이상 후원하실 수 있습니다."
|
||||
popupContent = I18n.LiveRoom.atLeastOneCanDonationMessage
|
||||
isShowPopup = true
|
||||
} else {
|
||||
isLoading = true
|
||||
@@ -916,9 +916,9 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
var rawMessage = ""
|
||||
|
||||
if isSecret {
|
||||
rawMessage = "\(can)캔으로 비밀미션을 보냈습니다.🤫"
|
||||
rawMessage = I18n.LiveChat.canWithUnit(can) + I18n.LiveChat.secretMissionDonationSuffix
|
||||
} else {
|
||||
rawMessage = "\(can)캔을 후원하셨습니다.💰🪙"
|
||||
rawMessage = I18n.LiveChat.canWithUnit(can) + I18n.LiveChat.donationSuffix
|
||||
}
|
||||
|
||||
let donationRawMessage = LiveRoomChatRawMessage(
|
||||
@@ -986,14 +986,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.popupContent = message
|
||||
} else {
|
||||
self.popupContent = "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.popupContent = I18n.LiveRoom.donationFailedMessage
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.popupContent = "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.popupContent = I18n.LiveRoom.donationFailedMessage
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1022,20 +1022,20 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.isLoading = false
|
||||
|
||||
if decoded.success {
|
||||
self.popupContent = "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.popupContent = I18n.LiveRoom.donationFailedMessage
|
||||
self.isShowPopup = true
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
||||
self.popupContent = I18n.LiveRoom.donationRefundFailedMessage
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
||||
self.popupContent = I18n.LiveRoom.donationRefundFailedMessage
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1045,7 +1045,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
func inviteSpeaker(peerId: Int) {
|
||||
agora.sendMessageToPeer(peerId: String(peerId), rawMessage: LiveRoomRequestType.INVITE_SPEAKER.rawValue.data(using: .utf8)!) { [unowned self] _, error in
|
||||
if error == nil {
|
||||
self.popupContent = "스피커 요청을 보냈습니다.\n잠시만 기다려 주세요."
|
||||
self.popupContent = I18n.CreateLive.speakerRequestSent
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1061,9 +1061,9 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self?.getRoomInfo()
|
||||
}
|
||||
|
||||
self.popupContent = "\(getUserNicknameAndProfileUrl(accountId: peerId).nickname)님을 스탭에서 해제했어요."
|
||||
self.popupContent = I18n.LiveRoom.staffReleasedMessage(getUserNicknameAndProfileUrl(accountId: peerId).nickname)
|
||||
} else {
|
||||
self.popupContent = "\(getUserNicknameAndProfileUrl(accountId: peerId).nickname)님을 리스너로 변경했어요."
|
||||
self.popupContent = I18n.LiveRoom.changedToListenerMessage(getUserNicknameAndProfileUrl(accountId: peerId).nickname)
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
@@ -1161,7 +1161,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if decoded.success {
|
||||
self.role = .SPEAKER
|
||||
self.agora.setRole(role: .broadcaster)
|
||||
self.popupContent = "스피커가 되었어요!"
|
||||
self.popupContent = I18n.LiveRoom.becameSpeakerMessage
|
||||
self.isShowPopup = true
|
||||
self.isMute = false
|
||||
self.getRoomInfo()
|
||||
@@ -1257,11 +1257,11 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
|
||||
self.agora.sendRawMessageToGroup(rawMessage: editRoomInfoMessage)
|
||||
} else {
|
||||
self.errorMessage = decoded.message ?? "라이브 정보를 수정하지 못했습니다.\n다시 시도해 주세요."
|
||||
self.errorMessage = decoded.message ?? I18n.CreateLive.editFailedMessage
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "라이브 정보를 수정하지 못했습니다.\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.editFailedMessage
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1270,13 +1270,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
|
||||
func selectMenuPreset(selectedMenuPreset: SelectedMenu) {
|
||||
if menuList.isEmpty && (selectedMenuPreset == .MENU_2 || selectedMenuPreset == .MENU_3) {
|
||||
errorMessage = "메뉴 1을 먼저 설정하세요"
|
||||
errorMessage = I18n.MissionMenu.needMenu1First
|
||||
isShowPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
if menuList.count == 1 && selectedMenuPreset == .MENU_3 {
|
||||
errorMessage = "메뉴 1과 메뉴 2를 먼저 설정하세요"
|
||||
errorMessage = I18n.MissionMenu.needMenu1And2First
|
||||
isShowPopup = true
|
||||
return
|
||||
}
|
||||
@@ -1342,14 +1342,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
onFailure()
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1366,22 +1366,19 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
|
||||
if let shareUrl = createOneLinkUrlWithURLComponents(params: params) {
|
||||
if liveRoomInfo.isPrivateRoom {
|
||||
shareMessage = "\(UserDefaults.string(forKey: .nickname))님이 귀하를 보이스온 비공개라이브에 초대하였습니다.\n" +
|
||||
"※ 라이브 참여: \(shareUrl)\n" +
|
||||
"(입장 비밀번호: \(liveRoomInfo.password!))"
|
||||
shareMessage = I18n.LiveRoom.invitePrivateLiveMessage(UserDefaults.string(forKey: .nickname), shareUrl, liveRoomInfo.password ?? "")
|
||||
} else {
|
||||
shareMessage = "\(UserDefaults.string(forKey: .nickname))님이 귀하를 보이스온 공개라이브에 초대하였습니다.\n" +
|
||||
"※ 라이브 참여: \(shareUrl)"
|
||||
shareMessage = I18n.LiveRoom.invitePublicLiveMessage(UserDefaults.string(forKey: .nickname), shareUrl)
|
||||
}
|
||||
|
||||
isShowShareView = true
|
||||
} else {
|
||||
self.errorMessage = "공유링크를 생성하지 못했습니다.\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.MemberChannel.shareLinkCreateFailed
|
||||
self.isShowErrorPopup = true
|
||||
return
|
||||
}
|
||||
} else {
|
||||
self.errorMessage = "공유링크를 생성하지 못했습니다.\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.MemberChannel.shareLinkCreateFailed
|
||||
self.isShowErrorPopup = true
|
||||
return
|
||||
}
|
||||
@@ -1409,7 +1406,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if decoded.success {
|
||||
let nickname = self.getUserNicknameAndProfileUrl(accountId: targetUserId).nickname
|
||||
self.agora.sendMessageToPeer(peerId: String(targetUserId), rawMessage: LiveRoomRequestType.KICK_OUT.rawValue.data(using: .utf8)!) { [unowned self] _, _ in
|
||||
self.popupContent = "\(nickname)님을 내보냈습니다."
|
||||
self.popupContent = I18n.LiveRoom.kickedOutMessage(nickname)
|
||||
self.isShowPopup = true
|
||||
}
|
||||
self.deleteChatsByUserId(userId: targetUserId)
|
||||
@@ -1459,12 +1456,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.donationStatus = data
|
||||
} else {
|
||||
self.errorMessage = "후원현황을 가져오지 못했습니다\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.LiveRoom.donationStatusFetchFailed
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.errorMessage = "후원현황을 가져오지 못했습니다\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.LiveRoom.donationStatusFetchFailed
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1492,12 +1489,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.heartStatus = data
|
||||
} else {
|
||||
self.errorMessage = "하트 랭킹을 가져오지 못했습니다\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.LiveRoom.heartRankingFetchFailed
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.errorMessage = "하트 랭킹을 가져오지 못했습니다\n다시 시도해 주세요."
|
||||
self.errorMessage = I18n.LiveRoom.heartRankingFetchFailed
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1547,13 +1544,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1599,13 +1596,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1721,21 +1718,21 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponse<[LiveRoomDonationMessage]>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.donationMessageList.removeAll()
|
||||
self.donationMessageList.append(contentsOf: data)
|
||||
self.donationMessageCount = data.count
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.donationMessageList.removeAll()
|
||||
self.donationMessageList.append(contentsOf: data)
|
||||
self.donationMessageCount = data.count
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1766,11 +1763,11 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.donationMessageList.removeAll()
|
||||
self.donationMessageList.append(contentsOf: filteredDonationMessageList)
|
||||
} else {
|
||||
self.errorMessage = "메시지를 삭제하지 못했습니다.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "메시지를 삭제하지 못했습니다.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1795,20 +1792,20 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponse<GetLiveRoomUserProfileResponse>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
userProfile = data
|
||||
isShowUserProfilePopup = true
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
if let data = decoded.data, decoded.success {
|
||||
userProfile = data
|
||||
isShowUserProfilePopup = true
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1837,19 +1834,19 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
getRoomInfo()
|
||||
setManagerMessage()
|
||||
|
||||
self.popupContent = "\(getUserNicknameAndProfileUrl(accountId: userId).nickname)님을 스탭으로 지정했습니다."
|
||||
self.popupContent = I18n.LiveRoom.assignedStaffMessage(getUserNicknameAndProfileUrl(accountId: userId).nickname)
|
||||
self.isShowPopup = true
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1875,7 +1872,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
func setNoChatting() {
|
||||
agora.sendMessageToPeer(peerId: String(noChattingUserId), rawMessage: LiveRoomRequestType.NO_CHATTING.rawValue.data(using: .utf8)!) { [unowned self] _, error in
|
||||
if error == nil {
|
||||
self.popupContent = "\(noChattingUserNickname)님을 3분간 채팅금지를 하였습니다."
|
||||
self.popupContent = I18n.LiveRoom.noChattingAppliedMessage(noChattingUserNickname)
|
||||
self.isShowPopup = true
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||||
@@ -1919,7 +1916,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.reportMessage = "차단하였습니다."
|
||||
self.reportMessage = I18n.MemberChannel.userBlocked
|
||||
self.getUserProfile(userId: reportUserId)
|
||||
onSuccess(reportUserId)
|
||||
|
||||
@@ -1930,13 +1927,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.reportMessage = message
|
||||
} else {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
}
|
||||
}
|
||||
|
||||
self.isShowReportPopup = true
|
||||
} catch {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
self.isShowReportPopup = true
|
||||
}
|
||||
}
|
||||
@@ -1964,7 +1961,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.reportMessage = "차단이 해제 되었습니다."
|
||||
self.reportMessage = I18n.MemberChannel.userUnblocked
|
||||
self.getUserProfile(userId: reportUserId)
|
||||
self.reportUserId = 0
|
||||
self.reportUserNickname = ""
|
||||
@@ -1973,20 +1970,20 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.reportMessage = message
|
||||
} else {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
}
|
||||
}
|
||||
|
||||
self.isShowReportPopup = true
|
||||
} catch {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
self.isShowReportPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func report(type: ReportType, reason: String = "프로필 신고") {
|
||||
func report(type: ReportType, reason: String = I18n.Dialog.MemberProfile.reportProfile) {
|
||||
isLoading = true
|
||||
|
||||
let request = ReportRequest(type: type, reason: reason, reportedMemberId: reportUserId, cheersId: nil, audioContentId: nil)
|
||||
@@ -2013,12 +2010,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.reportMessage = message
|
||||
} else {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowReportPopup = true
|
||||
} catch {
|
||||
self.reportMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.reportMessage = I18n.Common.commonError
|
||||
self.isShowReportPopup = true
|
||||
}
|
||||
}
|
||||
@@ -2037,7 +2034,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
private func startNoChatting() {
|
||||
isNoChatting = true
|
||||
remainingNoChattingTime = noChattingTime
|
||||
popupContent = "\(self.getUserNicknameAndProfileUrl(accountId: liveRoomInfo!.creatorId).nickname)님이 3분간 채팅을 금지하였습니다."
|
||||
popupContent = I18n.LiveRoom.noChattingByCreatorMessage(self.getUserNicknameAndProfileUrl(accountId: liveRoomInfo!.creatorId).nickname)
|
||||
isShowPopup = true
|
||||
|
||||
startCountDown()
|
||||
@@ -2056,7 +2053,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.isNoChatting = false
|
||||
self.timer?.cancel()
|
||||
self.removeNoChatRoom()
|
||||
self.popupContent = "채팅금지가 해제되었습니다."
|
||||
self.popupContent = I18n.LiveRoom.noChattingReleasedMessage
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -2217,12 +2214,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.rouletteUnavailableError
|
||||
}
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.rouletteUnavailableError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -2260,12 +2257,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.rouletteUnavailableError
|
||||
}
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
||||
self.errorMessage = I18n.CreateLive.rouletteUnavailableError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -2367,20 +2364,20 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.isLoading = false
|
||||
|
||||
if decoded.success {
|
||||
self.popupContent = "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.popupContent = I18n.LiveRoom.donationFailedMessage
|
||||
self.isShowPopup = true
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
||||
self.popupContent = I18n.LiveRoom.donationRefundFailedMessage
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.isLoading = false
|
||||
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
||||
self.popupContent = I18n.LiveRoom.donationRefundFailedMessage
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -2978,7 +2975,7 @@ extension LiveRoomViewModel: AgoraRtcEngineDelegate {
|
||||
// 라이브 종료
|
||||
self.deInitAgoraEngine()
|
||||
self.liveRoomInfo = nil
|
||||
AppState.shared.errorMessage = "라이브가 종료되었습니다."
|
||||
AppState.shared.errorMessage = I18n.LiveRoom.liveEndedMessage
|
||||
AppState.shared.isShowErrorPopup = true
|
||||
AppState.shared.roomId = 0
|
||||
} else {
|
||||
@@ -3023,18 +3020,18 @@ extension LiveRoomViewModel: AgoraRtmClientDelegate {
|
||||
}
|
||||
|
||||
if rawMessageString == LiveRoomRequestType.REQUEST_SPEAKER.rawValue {
|
||||
self.popupContent = "\(nickname)님이 스피커 요청을 했어요!\n스퍼커로 초대할까요?"
|
||||
self.popupCancelTitle = "건너뛰기"
|
||||
self.popupContent = I18n.LiveRoom.speakerRequestQuestion(nickname)
|
||||
self.popupCancelTitle = I18n.LiveRoom.skipAction
|
||||
self.popupCancelAction = {
|
||||
self.isShowPopup = false
|
||||
}
|
||||
self.popupConfirmTitle = "스피커로 초대"
|
||||
self.popupConfirmTitle = I18n.CreateLive.inviteSpeakerAction
|
||||
self.popupConfirmAction = {
|
||||
self.isShowPopup = false
|
||||
if self.liveRoomInfo!.speakerList.count <= 5 {
|
||||
self.requestSpeakerAllow(publisher)
|
||||
} else {
|
||||
self.errorMessage = "스피커 정원이 초과되었습니다."
|
||||
self.errorMessage = I18n.CreateLive.speakerCapacityExceeded
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -3043,12 +3040,12 @@ extension LiveRoomViewModel: AgoraRtmClientDelegate {
|
||||
}
|
||||
|
||||
if rawMessageString == LiveRoomRequestType.INVITE_SPEAKER.rawValue && self.role == .LISTENER {
|
||||
self.popupContent = "스피커로 초대되었어요"
|
||||
self.popupCancelTitle = "다음에요"
|
||||
self.popupContent = I18n.CreateLive.inviteSpeakerAction
|
||||
self.popupCancelTitle = I18n.LiveRoom.maybeLaterAction
|
||||
self.popupCancelAction = {
|
||||
self.isShowPopup = false
|
||||
}
|
||||
self.popupConfirmTitle = "스피커로 참여하기"
|
||||
self.popupConfirmTitle = I18n.LiveRoom.joinAsSpeakerAction
|
||||
self.popupConfirmAction = {
|
||||
self.isShowPopup = false
|
||||
self.setSpeaker()
|
||||
@@ -3064,9 +3061,9 @@ extension LiveRoomViewModel: AgoraRtmClientDelegate {
|
||||
|
||||
if rawMessageString == LiveRoomRequestType.KICK_OUT.rawValue {
|
||||
if let roomInfo = self.liveRoomInfo {
|
||||
self.popupContent = "\(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)님이 라이브에서 내보냈습니다."
|
||||
self.popupContent = I18n.LiveRoom.kickedOutByCreatorMessage(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)
|
||||
} else {
|
||||
self.popupContent = "방장님이 라이브에서 내보냈습니다."
|
||||
self.popupContent = I18n.LiveRoom.kickedOutByHostMessage
|
||||
}
|
||||
self.isShowPopup = true
|
||||
|
||||
@@ -3085,18 +3082,18 @@ extension LiveRoomViewModel: AgoraRtmClientDelegate {
|
||||
}
|
||||
|
||||
if let roomInfo = self.liveRoomInfo {
|
||||
self.popupContent = "\(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)님이 스탭으로 지정했습니다."
|
||||
self.popupContent = I18n.LiveRoom.assignedStaffByCreatorMessage(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)
|
||||
} else {
|
||||
self.popupContent = "방장님이 스탭으로 지정했습니다"
|
||||
self.popupContent = I18n.LiveRoom.assignedStaffByHostMessage
|
||||
}
|
||||
self.isShowPopup = true
|
||||
}
|
||||
|
||||
if rawMessageString == LiveRoomRequestType.RELEASE_MANAGER.rawValue {
|
||||
if let roomInfo = self.liveRoomInfo {
|
||||
self.popupContent = "\(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)님이 스탭에서 해제했습니다."
|
||||
self.popupContent = I18n.LiveRoom.releasedStaffByCreatorMessage(self.getUserNicknameAndProfileUrl(accountId: roomInfo.creatorId).nickname)
|
||||
} else {
|
||||
self.popupContent = "방장님이 스탭에서 해제했습니다."
|
||||
self.popupContent = I18n.LiveRoom.releasedStaffByHostMessage
|
||||
}
|
||||
self.isShowPopup = true
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ struct LiveRoomMenuSelectView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text("메뉴")
|
||||
Text(I18n.CreateLive.menuTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("메뉴를 활성화 하시겠습니까?")
|
||||
Text(I18n.CreateLive.menuActivatePrompt)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
@@ -72,7 +72,7 @@ struct LiveRoomMenuSelectView: View {
|
||||
|
||||
TextViewWrapper(
|
||||
text: $menu,
|
||||
placeholder: "메뉴판을 작성해주세요.",
|
||||
placeholder: I18n.CreateLive.menuPlaceholder,
|
||||
textColorHex: "eeeeee",
|
||||
backgroundColorHex: "303030"
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ struct MenuSettingsView: View {
|
||||
var body: some View {
|
||||
BaseView(isLoading: $viewModel.isLoading) {
|
||||
VStack(spacing: 13.3) {
|
||||
DetailNavigationBar(title: "메뉴 설정") {
|
||||
DetailNavigationBar(title: I18n.MemberChannel.menuSettings) {
|
||||
isShowing = false
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ struct MenuSettingsView: View {
|
||||
|
||||
TextViewWrapper(
|
||||
text: $viewModel.menu,
|
||||
placeholder: "메뉴판을 작성해주세요.",
|
||||
placeholder: I18n.CreateLive.menuPlaceholder,
|
||||
textColorHex: "eeeeee",
|
||||
backgroundColorHex: "303030"
|
||||
)
|
||||
@@ -60,7 +60,7 @@ struct MenuSettingsView: View {
|
||||
.cornerRadius(6.7)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Text("저장하기")
|
||||
Text(I18n.CreateLive.saveMenuAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
.padding(.vertical, 16)
|
||||
|
||||
@@ -27,13 +27,13 @@ final class MenuSettingsViewModel: ObservableObject {
|
||||
|
||||
func selectMenuPreset(selectedMenuPreset: SelectedMenu) {
|
||||
if menuList.isEmpty && (selectedMenuPreset == .MENU_2 || selectedMenuPreset == .MENU_3) {
|
||||
errorMessage = "메뉴 1을 먼저 설정하세요"
|
||||
errorMessage = I18n.MissionMenu.needMenu1First
|
||||
isShowPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
if menuList.count == 1 && selectedMenuPreset == .MENU_3 {
|
||||
errorMessage = "메뉴 1과 메뉴 2를 먼저 설정하세요"
|
||||
errorMessage = I18n.MissionMenu.needMenu1And2First
|
||||
isShowPopup = true
|
||||
return
|
||||
}
|
||||
@@ -82,14 +82,14 @@ final class MenuSettingsViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
onFailure()
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ final class MenuSettingsViewModel: ObservableObject {
|
||||
|
||||
func saveMenu() {
|
||||
if selectedMenuText == menu {
|
||||
self.errorMessage = "저장되었습니다."
|
||||
self.errorMessage = I18n.CreateLive.menuSavedMessage
|
||||
self.isShowPopup = true
|
||||
return
|
||||
}
|
||||
@@ -122,20 +122,20 @@ final class MenuSettingsViewModel: ObservableObject {
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.errorMessage = "저장되었습니다."
|
||||
self.errorMessage = I18n.CreateLive.menuSavedMessage
|
||||
self.isShowPopup = true
|
||||
self.getAllMenuPreset(selectedMenu: self.selectedMenu ?? .MENU_1) {}
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ struct RouletteSettingsOptionView: View {
|
||||
var body: some View {
|
||||
VStack(spacing: 6.7) {
|
||||
HStack(spacing: 0) {
|
||||
Text("옵션 \(index + 1)")
|
||||
Text(I18n.CreateLive.rouletteOptionTitle(index))
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
Spacer()
|
||||
|
||||
if index > 1 {
|
||||
Text("삭제")
|
||||
Text(I18n.CreateLive.rouletteDeleteAction)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color(hex: "ff5c49"))
|
||||
.onTapGesture { onClickDelete() }
|
||||
@@ -34,7 +34,7 @@ struct RouletteSettingsOptionView: View {
|
||||
}
|
||||
|
||||
HStack(spacing: 8) {
|
||||
TextField("옵션을 입력하세요", text: $option.title)
|
||||
TextField(I18n.CreateLive.rouletteOptionPlaceholder, text: $option.title)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
|
||||
@@ -28,7 +28,7 @@ struct RouletteSettingsView: View {
|
||||
GeometryReader { proxy in
|
||||
BaseView(isLoading: $viewModel.isLoading) {
|
||||
VStack(spacing: 0) {
|
||||
DetailNavigationBar(title: String(localized: "룰렛 설정")) {
|
||||
DetailNavigationBar(title: I18n.CreateLive.rouletteSettingsTitle) {
|
||||
isShowing = false
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ struct RouletteSettingsView: View {
|
||||
|
||||
if availableActive {
|
||||
HStack(spacing: 0) {
|
||||
Text("룰렛을 활성화 하시겠습니까?")
|
||||
Text(I18n.CreateLive.rouletteActivatePrompt)
|
||||
.appFont(size: 16, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -90,12 +90,12 @@ struct RouletteSettingsView: View {
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 13.3) {
|
||||
Text("룰렛 금액 설정")
|
||||
Text(I18n.CreateLive.rouletteCanSettingTitle)
|
||||
.appFont(size: 16, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
TextField("룰렛 금액을 입력해 주세요 (최소 5캔)", text: Binding(
|
||||
TextField(I18n.CreateLive.rouletteCanPlaceholder, text: Binding(
|
||||
get: {
|
||||
self.viewModel.canText
|
||||
},
|
||||
@@ -117,7 +117,7 @@ struct RouletteSettingsView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateLive.canUnit)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
}
|
||||
@@ -126,12 +126,12 @@ struct RouletteSettingsView: View {
|
||||
.id("roulette_can_input")
|
||||
|
||||
VStack(alignment: .leading, spacing: 21.3) {
|
||||
Text("룰렛 옵션 설정")
|
||||
Text(I18n.CreateLive.rouletteOptionSettingTitle)
|
||||
.appFont(size: 16, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("※ 룰렛 옵션은 최소 2개,\n최대 10개까지 설정할 수 있습니다.")
|
||||
Text(I18n.CreateLive.rouletteOptionLimitNotice)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.mainRed)
|
||||
|
||||
@@ -144,7 +144,7 @@ struct RouletteSettingsView: View {
|
||||
.padding(.top, 26.7)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("옵션 확률 합계")
|
||||
Text(I18n.CreateLive.rouletteProbabilitySum)
|
||||
.appFont(size: 14.7, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -186,7 +186,7 @@ struct RouletteSettingsView: View {
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 13.3) {
|
||||
Text("미리보기")
|
||||
Text(I18n.CreateLive.roulettePreviewAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.button)
|
||||
.padding(.vertical, 16)
|
||||
@@ -200,7 +200,7 @@ struct RouletteSettingsView: View {
|
||||
viewModel.onClickPreview()
|
||||
}
|
||||
|
||||
Text("설정완료")
|
||||
Text(I18n.CreateLive.rouletteCompleteAction)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
.padding(.vertical, 16)
|
||||
@@ -232,7 +232,7 @@ struct RouletteSettingsView: View {
|
||||
if let preview = viewModel.previewData, viewModel.isShowPreview {
|
||||
RoulettePreviewDialog(
|
||||
isShowing: $viewModel.isShowPreview,
|
||||
title: "룰렛 미리보기",
|
||||
title: I18n.CreateLive.roulettePreviewTitle,
|
||||
onClickSpin: nil,
|
||||
previewList: [preview]
|
||||
)
|
||||
|
||||
@@ -86,11 +86,11 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
rouletteList.append(contentsOf: data)
|
||||
selectRoulette(selectedRoulette: .ROULETTE_1)
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
for option in options {
|
||||
if option.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
isLoading = false
|
||||
errorMessage = "옵션은 빈칸일 수 없습니다."
|
||||
errorMessage = I18n.CreateLive.rouletteOptionEmptyError
|
||||
isShowErrorPopup = true
|
||||
return
|
||||
}
|
||||
@@ -137,7 +137,7 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
for option in options {
|
||||
if option.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
isLoading = false
|
||||
errorMessage = "옵션은 빈칸일 수 없습니다."
|
||||
errorMessage = I18n.CreateLive.rouletteOptionEmptyError
|
||||
isShowErrorPopup = true
|
||||
return false
|
||||
}
|
||||
@@ -149,7 +149,7 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
|
||||
if totalPercentage > Float(100.1) || totalPercentage <= Float(99.99) {
|
||||
isLoading = false
|
||||
errorMessage = "확률이 100%가 아닙니다"
|
||||
errorMessage = I18n.CreateLive.rouletteProbabilityInvalidError
|
||||
isShowErrorPopup = true
|
||||
return false
|
||||
}
|
||||
@@ -170,23 +170,23 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
|
||||
switch (self.selectedRoulette) {
|
||||
case .ROULETTE_2:
|
||||
selectedRouletteTitle = "룰렛 2"
|
||||
selectedRouletteTitle = I18n.Common.roulette2
|
||||
|
||||
case .ROULETTE_3:
|
||||
selectedRouletteTitle = "룰렛 3"
|
||||
selectedRouletteTitle = I18n.Common.roulette3
|
||||
|
||||
default:
|
||||
selectedRouletteTitle = "룰렛 1"
|
||||
selectedRouletteTitle = I18n.Common.roulette1
|
||||
}
|
||||
|
||||
if availableActive {
|
||||
if isActive {
|
||||
successMessage = "\(selectedRouletteTitle)로 설정하였습니다."
|
||||
successMessage = I18n.CreateLive.rouletteSetAsSuccess(selectedRouletteTitle)
|
||||
} else {
|
||||
successMessage = "\(selectedRouletteTitle)을 설정했습니다."
|
||||
successMessage = I18n.CreateLive.rouletteSetSuccess(selectedRouletteTitle)
|
||||
}
|
||||
} else {
|
||||
successMessage = "\(selectedRouletteTitle)을 생성했습니다."
|
||||
successMessage = I18n.CreateLive.rouletteCreatedSuccess(selectedRouletteTitle)
|
||||
}
|
||||
|
||||
let request = CreateRouletteRequest(can: can, isActive: isActive, items: items)
|
||||
@@ -209,11 +209,11 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
if decoded.success {
|
||||
onSuccess(isActive, successMessage)
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
|
||||
let selectedRoulette = rouletteList[selectedRoulette!.rawValue]
|
||||
if selectedRoulette.isActive == isActive && selectedRoulette.can == can && selectedRoulette.items == items {
|
||||
self.errorMessage = "변동사항이 없습니다."
|
||||
self.errorMessage = I18n.CreateLive.rouletteNoChangesMessage
|
||||
self.isShowErrorPopup = true
|
||||
self.isLoading = false
|
||||
return
|
||||
@@ -241,23 +241,23 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
|
||||
switch (self.selectedRoulette) {
|
||||
case .ROULETTE_2:
|
||||
selectedRouletteTitle = "룰렛 2"
|
||||
selectedRouletteTitle = I18n.Common.roulette2
|
||||
|
||||
case .ROULETTE_3:
|
||||
selectedRouletteTitle = "룰렛 3"
|
||||
selectedRouletteTitle = I18n.Common.roulette3
|
||||
|
||||
default:
|
||||
selectedRouletteTitle = "룰렛 1"
|
||||
selectedRouletteTitle = I18n.Common.roulette1
|
||||
}
|
||||
|
||||
if availableActive {
|
||||
if isActive {
|
||||
successMessage = "\(selectedRouletteTitle)을 활성화 했습니다."
|
||||
successMessage = I18n.CreateLive.rouletteActivatedSuccess(selectedRouletteTitle)
|
||||
} else {
|
||||
successMessage = "\(selectedRouletteTitle)을 비활성화 했습니다."
|
||||
successMessage = I18n.CreateLive.rouletteDeactivatedSuccess(selectedRouletteTitle)
|
||||
}
|
||||
} else {
|
||||
successMessage = "\(selectedRouletteTitle)을 변경했습니다."
|
||||
successMessage = I18n.CreateLive.rouletteChangedSuccess(selectedRouletteTitle)
|
||||
}
|
||||
|
||||
let request = UpdateRouletteRequest(id: rouletteId, can: can, isActive: isActive, items: items)
|
||||
@@ -280,11 +280,11 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
if decoded.success {
|
||||
onSuccess(isActive, successMessage)
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowErrorPopup = true
|
||||
}
|
||||
}
|
||||
@@ -293,13 +293,13 @@ final class RouletteSettingsViewModel: ObservableObject {
|
||||
|
||||
func selectRoulette(selectedRoulette: SelectedRoulette) {
|
||||
if rouletteList.isEmpty && (selectedRoulette == .ROULETTE_2 || selectedRoulette == .ROULETTE_3) {
|
||||
errorMessage = "룰렛 1을 먼저 설정하세요"
|
||||
errorMessage = I18n.CreateLive.rouletteNeedFirstMessage
|
||||
isShowErrorPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
if rouletteList.count == 1 && selectedRoulette == .ROULETTE_3 {
|
||||
errorMessage = "룰렛 1과 룰렛 2를 먼저 설정하세요"
|
||||
errorMessage = I18n.CreateLive.rouletteNeedFirstAndSecondMessage
|
||||
isShowErrorPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ struct RoulettePreviewDialog: View {
|
||||
if previewList.count > 1 {
|
||||
HStack(spacing: 13.3) {
|
||||
SelectedButtonView(
|
||||
title: "룰렛 1",
|
||||
title: I18n.Common.roulette1,
|
||||
isActive: true,
|
||||
isSelected: selectedRoulette == .ROULETTE_1
|
||||
)
|
||||
@@ -35,7 +35,7 @@ struct RoulettePreviewDialog: View {
|
||||
}
|
||||
|
||||
SelectedButtonView(
|
||||
title: "룰렛 2",
|
||||
title: I18n.Common.roulette2,
|
||||
isActive: true,
|
||||
isSelected: selectedRoulette == .ROULETTE_2,
|
||||
checkImage: "ic_select_check_black",
|
||||
@@ -51,7 +51,7 @@ struct RoulettePreviewDialog: View {
|
||||
|
||||
if previewList.count > 2 {
|
||||
SelectedButtonView(
|
||||
title: "룰렛 3",
|
||||
title: I18n.Common.roulette3,
|
||||
isActive: true,
|
||||
isSelected: selectedRoulette == .ROULETTE_3,
|
||||
bgSelectedColor: Color(hex: "ff14d9"),
|
||||
@@ -68,7 +68,7 @@ struct RoulettePreviewDialog: View {
|
||||
}
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text(title ?? "룰렛")
|
||||
Text(title ?? I18n.CreateLive.roulettePreviewTitle)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
|
||||
@@ -109,7 +109,7 @@ struct RoulettePreviewDialog: View {
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
HStack(spacing: 13.3) {
|
||||
Text("취소")
|
||||
Text(I18n.Common.cancel)
|
||||
.appFont(size: 16, weight: .bold)
|
||||
.foregroundColor(
|
||||
selectedRoulette == .ROULETTE_2 ? Color(hex: "ffcb14") :
|
||||
@@ -131,7 +131,7 @@ struct RoulettePreviewDialog: View {
|
||||
isShowing = false
|
||||
}
|
||||
|
||||
Text("\(previewList[selectedRoulette.rawValue].can)캔으로 룰렛 돌리기")
|
||||
Text(I18n.CreateLive.rouletteSpinWithCan(previewList[selectedRoulette.rawValue].can))
|
||||
.appFont(size: 16, weight: .bold)
|
||||
.foregroundColor(selectedRoulette == .ROULETTE_2 ? .black : .white)
|
||||
.padding(.vertical, 16)
|
||||
|
||||
@@ -17,7 +17,7 @@ struct LiveRoomNewChatView: View {
|
||||
|
||||
HStack(spacing: 6.7) {
|
||||
Image("ic_bottom_white")
|
||||
Text("새로운 채팅")
|
||||
Text(I18n.CreateLive.newChatLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ struct LiveRoomInputChatView: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 6.7) {
|
||||
ChatTextFieldView(text: $chatMessage, placeholder: "채팅을 입력하세요", isEnabled: !isInputDisabled) {
|
||||
ChatTextFieldView(text: $chatMessage, placeholder: I18n.LiveRoom.chatInputPlaceholder, isEnabled: !isInputDisabled) {
|
||||
if sendMessage(chatMessage) {
|
||||
chatMessage = ""
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ struct LiveRoomViewV2: View {
|
||||
}
|
||||
|
||||
if viewModel.isNoChatting {
|
||||
return "\(viewModel.remainingNoChattingTime)초 동안 채팅하실 수 없습니다"
|
||||
return I18n.CreateLive.remainingNoChattingMessage(viewModel.remainingNoChattingTime)
|
||||
}
|
||||
|
||||
return I18n.LiveRoom.chatFreezeBlockedMessage
|
||||
@@ -494,7 +494,7 @@ struct LiveRoomViewV2: View {
|
||||
.padding(.leading, 13.3)
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("[방송공지]")
|
||||
Text(I18n.CreateLive.noticeTag)
|
||||
.appFont(size: 11.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
|
||||
@@ -529,7 +529,7 @@ struct LiveRoomViewV2: View {
|
||||
|
||||
ScrollView(.vertical) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("[메뉴판]")
|
||||
Text(I18n.CreateLive.menuTag)
|
||||
.appFont(size: 11.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
|
||||
@@ -1104,10 +1104,10 @@ struct LiveRoomViewV2: View {
|
||||
private func inviteSpeaker(peerId: Int) {
|
||||
if viewModel.liveRoomInfo!.speakerList.count <= 5 {
|
||||
viewModel.inviteSpeaker(peerId: peerId)
|
||||
self.viewModel.popupContent = "스피커 요청을 보냈습니다.\n잠시만 기다려 주세요."
|
||||
self.viewModel.popupContent = I18n.CreateLive.speakerRequestSent
|
||||
self.viewModel.isShowPopup = true
|
||||
} else {
|
||||
viewModel.popupContent = "스피커 정원을 초과했습니다."
|
||||
viewModel.popupContent = I18n.CreateLive.speakerCapacityExceeded
|
||||
viewModel.isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ struct SectionCommunityPostView: View {
|
||||
var body: some View {
|
||||
VStack(spacing: 16) {
|
||||
HStack(spacing: 0) {
|
||||
Text("커뮤니티")
|
||||
Text(I18n.CreateLive.communitySectionTitle)
|
||||
.appFont(size: 24, weight: .bold)
|
||||
.foregroundColor(.button)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ struct SectionLatestFinishedLiveView: View {
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
HStack(spacing: 0) {
|
||||
Text("최근 종료한 라이브")
|
||||
Text(I18n.CreateLive.latestFinishedSectionTitle)
|
||||
.appFont(size: 24, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
|
||||
@@ -343,48 +343,48 @@
|
||||
- [x] `SodaLive/Sources/Live/Room/Chat/LiveRoomJoinChatItemView.swift`
|
||||
|
||||
#### Group 3 (21-30)
|
||||
- [ ] `SodaLive/Sources/Live/Room/Chat/LiveRoomRouletteDonationChatItemView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Create/Tag/LiveRoomCreateTagView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Create/Tag/LiveRoomCreateTagViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Detail/LiveDetailView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Detail/LiveDetailViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationMessageDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationMessageItemView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingItemView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Chat/LiveRoomRouletteDonationChatItemView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Create/Tag/LiveRoomCreateTagView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Create/Tag/LiveRoomCreateTagViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Detail/LiveDetailView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Detail/LiveDetailViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationMessageDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationMessageItemView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingItemView.swift`
|
||||
|
||||
#### Group 4 (31-40)
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingTotalCanView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomHeartRankingDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomHeartRankingItemView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomInfoEditDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomNoChattingDialogView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfileDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfileItemTitleView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfilesDialogView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Dialog/LiveRoomUserProfileDialogView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Edit/LiveRoomEditView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomDonationRankingTotalCanView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomHeartRankingDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomHeartRankingItemView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomInfoEditDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomNoChattingDialogView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfileDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfileItemTitleView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomProfilesDialogView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Dialog/LiveRoomUserProfileDialogView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Edit/LiveRoomEditView.swift`
|
||||
|
||||
#### Group 5 (41-50)
|
||||
- [ ] `SodaLive/Sources/Live/Room/Edit/LiveRoomEditViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/LiveRoomViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Menu/LiveRoomMenuSelectView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsOptionView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/V2/Component/Button/LiveRoomNewChatView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Edit/LiveRoomEditViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/LiveRoomViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Menu/LiveRoomMenuSelectView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsOptionView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/V2/Component/Button/LiveRoomNewChatView.swift`
|
||||
|
||||
#### Group 6 (51-56)
|
||||
- [ ] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInfoGuestView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInfoHostView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInputChatView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/Room/V2/LiveRoomViewV2.swift`
|
||||
- [ ] `SodaLive/Sources/Live/SectionCommunityPostView.swift`
|
||||
- [ ] `SodaLive/Sources/Live/SectionLatestFinishedLiveView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInfoGuestView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInfoHostView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/V2/Component/View/LiveRoomInputChatView.swift`
|
||||
- [x] `SodaLive/Sources/Live/Room/V2/LiveRoomViewV2.swift`
|
||||
- [x] `SodaLive/Sources/Live/SectionCommunityPostView.swift`
|
||||
- [x] `SodaLive/Sources/Live/SectionLatestFinishedLiveView.swift`
|
||||
|
||||
### Main (3)
|
||||
- [x] `SodaLive/Sources/Main/EventPopupDialogView.swift`
|
||||
@@ -930,3 +930,24 @@
|
||||
- `SodaLive-dev` Debug 빌드는 병렬 실행 시 `build.db` lock으로 1회 실패 후, 단독 재실행에서 성공(`** BUILD SUCCEEDED **`).
|
||||
- 테스트 검증: 두 스킴 모두 `Scheme ... is not currently configured for the test action.`로 테스트 액션 미구성 확인(코드 실패 아님, 스킴 제약).
|
||||
- LSP 진단: SourceKit 단독 해석 환경에서 외부 모듈/프로젝트 심볼 미해결 오류(`RefreshableScrollView`, `Kingfisher`, `AppState` 등)가 보고되나, 동일 변경셋은 `xcodebuild` 실컴파일 통과로 검증 완료.
|
||||
|
||||
### 19차 구현 (Live 모듈 Group 3~6 마감 보정, 2026-04-01)
|
||||
- 무엇/왜/어떻게:
|
||||
- 무엇: Live Group 3~6 마감 단계에서 남아 있던 컴파일 오류(`I18n` 경로 오참조)를 수정하고, 체크리스트와 검증 기록을 최신화했다.
|
||||
- 왜: 기존 치환 반영 이후 `LiveRoomViewModel.swift`의 일부 i18n 경로가 실제 `I18n.swift` 네임스페이스와 불일치해 빌드를 막고 있었기 때문이다.
|
||||
- 어떻게: 오류 라인(1919, 1964, 1986)을 `I18n.swift` 정의와 대조해 정확한 경로로 교정한 뒤, `SodaLive`/`SodaLive-dev` Debug 빌드와 test 액션 상태를 재검증했다.
|
||||
- 실행 명령/도구:
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
|
||||
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test`
|
||||
- `read`/`grep`로 `LiveRoomViewModel.swift`, `I18n.swift`, 계획 문서 대조
|
||||
- 결과:
|
||||
- `LiveRoomViewModel.swift` 경로 교정 완료:
|
||||
- `I18n.LiveRoomPassword.MemberProfile.reportProfile` → `I18n.Dialog.MemberProfile.reportProfile`
|
||||
- `I18n.ChannelManagement.userBlocked` → `I18n.MemberChannel.userBlocked`
|
||||
- `I18n.ChannelManagement.userUnblocked` → `I18n.MemberChannel.userUnblocked`
|
||||
- Live Group 3~6 체크박스 36개 `- [x]` 반영 완료.
|
||||
- 빌드 검증: `SodaLive`, `SodaLive-dev` Debug 빌드 모두 오류 없이 완료(경고만 존재).
|
||||
- 테스트 검증: 두 스킴 모두 `Scheme ... is not currently configured for the test action.`로 test action 미구성 확인(코드 실패 아님, 스킴 제약).
|
||||
- LSP 진단 참고: 단일 파일 진단 시 `No such module 'Moya'`가 보고되나, SourceKit 단독 해석 한계이며 실제 `xcodebuild` 컴파일은 통과했다.
|
||||
|
||||
Reference in New Issue
Block a user