// // ContentMainViewV2.swift // SodaLive // // Created by klaus on 2/21/25. // import SwiftUI import Kingfisher enum ContentMainTab { case HOME case SERIES case CONTENT case ALARM case ASMR case REPLAY case FREE } struct TabItem { let title: String let tab: ContentMainTab } struct ContentMainViewV2: View { @StateObject var contentPlayManager = ContentPlayManager.shared @StateObject var contentPlayerPlayManager = ContentPlayerPlayManager.shared @State private var selectedTab: ContentMainTab = .SERIES @State private var isShowPlayer = false let tabItemList = [ TabItem(title: "홈", tab: .HOME), TabItem(title: "시리즈", tab: .SERIES), TabItem(title: "단편", tab: .CONTENT), TabItem(title: "모닝콜", tab: .ALARM), TabItem(title: "ASMR", tab: .ASMR), TabItem(title: "다시듣기", tab: .REPLAY), TabItem(title: "무료", tab: .FREE) ] init(selectedTab: ContentMainTab = .SERIES) { self._selectedTab = State(initialValue: selectedTab) } var body: some View { NavigationView { ZStack { Color.black.ignoresSafeArea() VStack(spacing: 0) { HStack(spacing: 0) { Text("콘텐츠 마켓") .font(.custom(Font.bold.rawValue, size: 21.3)) .foregroundColor(Color.button) Spacer() Image("ic_content_keep") .onTapGesture { AppState.shared.setAppStep(step: .myBox(currentTab: .orderlist)) } } .padding(.horizontal, 13.3) ScrollViewReader { proxy in ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 8) { ForEach(0..<tabItemList.count, id: \.self) { index in let tabItem = tabItemList[index] Text(tabItem.title) .font( .custom( selectedTab == tabItem.tab ? Font.bold.rawValue : Font.medium.rawValue, size: 16 ) ) .foregroundColor( selectedTab == tabItem.tab ? .button : .graybb ) .padding(.horizontal, 12) .onTapGesture { if selectedTab != tabItem.tab { selectedTab = tabItem.tab proxy.scrollTo(tabItem.tab, anchor: .center) } } .id(tabItem.tab) } } .padding(.vertical, 15) .padding(.horizontal, 13.3) } .onAppear { withAnimation { proxy.scrollTo(selectedTab, anchor: .center) } } .onChange(of: selectedTab) { newTab in withAnimation { if newTab == .HOME { AppState.shared.back() } else { proxy.scrollTo(newTab, anchor: .center) } } } } ZStack { switch selectedTab { case .HOME: EmptyView() case .SERIES: ContentMainTabSeriesView() case .CONTENT: ContentMainTabContentView() case .ALARM: ContentMainTabAlarmView() case .ASMR: ContentMainTabAsmrView() case .REPLAY: ContentMainTabReplayView() case .FREE: ContentMainTabFreeView() } } Spacer() if contentPlayerPlayManager.isShowingMiniPlayer { HStack(spacing: 0) { KFImage(URL(string: contentPlayerPlayManager.coverImageUrl)) .cancelOnDisappear(true) .downsampling( size: CGSize( width: 36.7, height: 36.7 ) ) .resizable() .frame(width: 36.7, height: 36.7) .cornerRadius(5.3) VStack(alignment: .leading, spacing: 2.3) { Text(contentPlayerPlayManager.title) .font(.custom(Font.medium.rawValue, size: 13)) .foregroundColor(Color.grayee) .lineLimit(2) Text(contentPlayerPlayManager.nickname) .font(.custom(Font.medium.rawValue, size: 11)) .foregroundColor(Color.grayd2) } .padding(.horizontal, 10.7) Spacer() Image(contentPlayerPlayManager.isPlaying ? "ic_noti_pause" : "btn_bar_play") .resizable() .frame(width: 25, height: 25) .onTapGesture { contentPlayerPlayManager.playOrPause() } Image("ic_noti_stop") .resizable() .frame(width: 25, height: 25) .padding(.leading, 16) .onTapGesture { contentPlayerPlayManager.resetPlayer() } } .padding(.vertical, 10.7) .padding(.horizontal, 13.3) .background(Color.gray22) .contentShape(Rectangle()) .onTapGesture { isShowPlayer = true } } if contentPlayManager.isShowingMiniPlayer { HStack(spacing: 0) { KFImage(URL(string: contentPlayManager.coverImage)) .cancelOnDisappear(true) .downsampling( size: CGSize( width: 36.7, height: 36.7 ) ) .resizable() .frame(width: 36.7, height: 36.7) .cornerRadius(5.3) VStack(alignment: .leading, spacing: 2.3) { Text(contentPlayManager.title) .font(.custom(Font.medium.rawValue, size: 13)) .foregroundColor(Color.grayee) .lineLimit(2) Text(contentPlayManager.nickname) .font(.custom(Font.medium.rawValue, size: 11)) .foregroundColor(Color.grayd2) } .padding(.horizontal, 10.7) Spacer() Image(contentPlayManager.isPlaying ? "ic_noti_pause" : "btn_bar_play") .resizable() .frame(width: 25, height: 25) .onTapGesture { if contentPlayManager.isPlaying { contentPlayManager.pauseAudio() } else { contentPlayManager .playAudio(contentId: contentPlayManager.contentId) } } Image("ic_noti_stop") .resizable() .frame(width: 25, height: 25) .padding(.leading, 16) .onTapGesture { contentPlayManager.stopAudio() } } .padding(.vertical, 10.7) .padding(.horizontal, 13.3) .background(Color.gray22) .contentShape(Rectangle()) .onTapGesture { AppState.shared .setAppStep( step: .contentDetail(contentId: contentPlayManager.contentId) ) } } } if isShowPlayer { ContentPlayerView(isShowing: $isShowPlayer, playlist: []) } } .navigationBarHidden(true) } } } #Preview { ContentMainViewV2(selectedTab: .SERIES) }