jellyflood/Swiftfin/Views/LiveTVChannelItemElement.swift

125 lines
4.1 KiB
Swift

//
// Swiftfin is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
//
import JellyfinAPI
import SwiftUI
struct LiveTVChannelItemElement: View {
@FocusState
private var focused: Bool
@State
private var loading: Bool = false
@State
private var isFocused: Bool = false
var channel: BaseItemDto
var program: BaseItemDto?
var startString = " "
var endString = " "
var progressPercent = Double(0)
var onSelect: (@escaping (Bool) -> Void) -> Void
private var detailText: String {
guard let program = program else {
return ""
}
var text = ""
if let season = program.parentIndexNumber,
let episode = program.indexNumber
{
text.append("\(season)x\(episode) ")
} else if let episode = program.indexNumber {
text.append("\(episode) ")
}
if let title = program.episodeTitle {
text.append("\(title) ")
}
if let year = program.productionYear {
text.append("\(year) ")
}
if let rating = program.officialRating {
text.append("\(rating)")
}
return text
}
var body: some View {
ZStack {
VStack {
HStack {
Text(channel.number ?? "")
.font(.footnote)
.frame(alignment: .leading)
.padding()
Spacer()
}.frame(alignment: .top)
Spacer()
}
VStack {
ImageView(channel.imageURL(.primary, maxWidth: 128))
.aspectRatio(contentMode: .fit)
.frame(width: 128, alignment: .center)
.padding(.init(top: 8, leading: 0, bottom: 0, trailing: 0))
Text(channel.name ?? "?")
.font(.footnote)
.lineLimit(1)
.frame(alignment: .center)
Text(program?.name ?? L10n.notAvailableSlash)
.font(.body)
.lineLimit(1)
.foregroundColor(.green)
Text(detailText)
.font(.body)
.lineLimit(1)
.foregroundColor(.green)
Spacer()
HStack(alignment: .bottom) {
VStack {
Spacer()
HStack {
Text(startString)
.font(.footnote)
.lineLimit(1)
.frame(alignment: .leading)
Spacer()
Text(endString)
.font(.footnote)
.lineLimit(1)
.frame(alignment: .trailing)
}
GeometryReader { gp in
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: 6)
.fill(Color.gray)
.opacity(0.4)
.frame(minWidth: 100, maxWidth: .infinity, minHeight: 12, maxHeight: 12)
RoundedRectangle(cornerRadius: 6)
.fill(Color.jellyfinPurple)
.frame(width: CGFloat(progressPercent * gp.size.width), height: 12)
}
.frame(alignment: .bottom)
}
}
}
}
.padding()
.opacity(loading ? 0.5 : 1.0)
if loading {
ProgressView()
}
}
.overlay(
RoundedRectangle(cornerRadius: 0)
.stroke(Color.blue, lineWidth: 0)
)
}
}