sodalive-ios/SodaLive/Sources/Content/Player/ContentPlayerView.swift

214 lines
8.5 KiB
Swift

//
// ContentPlayerView.swift
// SodaLive
//
// Created by klaus on 12/16/24.
//
import SwiftUI
import Kingfisher
import Sliders
struct ContentPlayerView: View {
@StateObject var playerManager = ContentPlayerPlayManager.shared
@Binding var isShowing: Bool
let playlist: [AudioContentPlaylistContent]
var body: some View {
BaseView(isLoading: $playerManager.isLoading) {
VStack(spacing: 0) {
HStack(spacing: 0) {
Spacer()
Image("ic_bottom_white")
.onTapGesture { isShowing = false }
}
Text(playerManager.title)
.font(.custom(Font.medium.rawValue, size: 16))
.foregroundColor(.grayee)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 16)
HStack(spacing: 5.3) {
KFImage(URL(string: playerManager.creatorProfileUrl))
.cancelOnDisappear(true)
.downsampling(size: CGSize(width: 26.7, height: 26.7))
.resizable()
.scaledToFill()
.frame(width: 26.7, height: 26.7)
.clipShape(Circle())
Text(playerManager.nickname)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(.gray90)
Spacer()
}
.padding(.top, 21)
Spacer()
if playerManager.isShowPlaylist {
ScrollView(.vertical) {
LazyVStack(alignment: .leading, spacing: 0) {
ForEach(0..<playerManager.playlist.count, id: \.self) {
let item = playerManager.playlist[$0]
PlaylistContentItemView(item: item)
.padding(13.3)
.frame(maxWidth: .infinity)
.background(
Color.button
.opacity(
item.id == playerManager.id ? 0.2 : 0
)
)
.cornerRadius(6.7)
}
}
}
} else {
KFImage(URL(string: playerManager.coverImageUrl))
.cancelOnDisappear(true)
.downsampling(size: CGSize(width: 240, height: 240))
.resizable()
.scaledToFill()
.frame(width: 240, height: 240)
.cornerRadius(8)
}
Spacer()
if playerManager.duration > 0 {
ValueSlider(
value: $playerManager.currentTime,
in: 0...playerManager.duration,
step: 1.0,
onEditingChanged: { editing in
playerManager.isEditing = editing
if !editing {
playerManager.seek(to: playerManager.currentTime)
}
}
)
.valueSliderStyle(
HorizontalValueSliderStyle(
track: HorizontalValueTrack(
view: Rectangle().foregroundColor(Color.button),
mask: Rectangle()
)
.background(Rectangle().foregroundColor(Color.gray97.opacity(0.3)))
.frame(height: 5.3),
thumbSize: CGSize(width: 10, height: 10),
options: .interactiveTrack
)
)
.frame(height: 11)
}
HStack(spacing: 0) {
Text(secondsToMinutesSeconds(seconds: Int(playerManager.currentTime)))
.font(.custom(Font.medium.rawValue, size: 12))
.foregroundColor(.graybb)
Spacer()
Text(secondsToMinutesSeconds(seconds: Int(playerManager.duration)))
.font(.custom(Font.medium.rawValue, size: 12))
.foregroundColor(.gray77)
}
.padding(.top, 5.3)
HStack(spacing: 0) {
Image("ic_skip_back")
.onTapGesture {
playerManager.playPreviousContent()
}
Spacer()
Image("ic_player_prev_10")
.onTapGesture {
playerManager.seekBackward(seconds: 10)
}
Spacer()
Image(playerManager.isPlaying ? "ic_player_pause" : "ic_player_play")
.onTapGesture {
playerManager.playOrPause()
}
Spacer()
Image("ic_player_next_10")
.onTapGesture {
playerManager.seekForward(seconds: 10)
}
Spacer()
Image("ic_skip_forward")
.onTapGesture {
playerManager.playNextContent()
}
}
.padding(.vertical, 21)
HStack(spacing: 0) {
Spacer()
Image("ic_playlist")
.padding(5)
.background(Color.gray33.opacity(playerManager.isShowPlaylist ? 1 : 0))
.cornerRadius(playerManager.isShowPlaylist ? 6.7 : 0)
.onTapGesture { playerManager.isShowPlaylist.toggle() }
}
}
.padding(20)
.onAppear {
if !playlist.isEmpty {
playerManager.setPlaylist(playlist: playlist)
}
}
}
}
private func secondsToMinutesSeconds(seconds: Int) -> String {
let hours = String(format: "%02d", seconds / 3600)
let minute = String(format: "%02d", (seconds % 3600) / 60)
let second = String(format: "%02d", seconds % 60)
return "\(hours):\(minute):\(second)"
}
}
#Preview {
ContentPlayerView(
isShowing: .constant(true),
playlist: [
AudioContentPlaylistContent(
id: 1,
title: "안녕하세요 오늘은 커버곡을 들려드리려고 해요",
category: "커버곡",
coverUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
duration: "00:30:20",
creatorNickname: "유저1",
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png"
),
AudioContentPlaylistContent(
id: 2,
title: "안녕하세요 오늘은 커버곡을 들려드리려고 해요안녕하세요 오늘은 커버곡을 들려드리려고 해요안녕하세요 오늘은 커버곡을 들려드리려고 해요안녕하세요 오늘은 커버곡을 들려드리려고 해요안녕하세요 오늘은 커버곡을 들려드리려고 해요안녕하세요 오늘은 커버곡을 들려드리려고 해요",
category: "커버곡",
coverUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
duration: "00:30:20",
creatorNickname: "유저1",
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png"
)
]
)
}