fix broken things being broken.
This commit is contained in:
parent
ee19c67c4a
commit
e0f9c96dfb
|
@ -40,10 +40,11 @@ struct LandscapeItemElement: View {
|
||||||
@State var backgroundURL: URL?
|
@State var backgroundURL: URL?
|
||||||
|
|
||||||
var item: BaseItemDto
|
var item: BaseItemDto
|
||||||
|
var inSeasonView: Bool?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
ImageView(src: (item.type == "Episode" ? item.getSeriesBackdropImage(maxWidth: 445) : item.getBackdropImage(maxWidth: 445)), bh: item.type == "Episode" ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
|
ImageView(src: (item.type == "Episode" && !(inSeasonView ?? false) ? item.getSeriesBackdropImage(maxWidth: 445) : item.getBackdropImage(maxWidth: 445)), bh: item.type == "Episode" ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
|
||||||
.frame(width: 445, height: 250)
|
.frame(width: 445, height: 250)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
|
@ -80,11 +81,19 @@ struct LandscapeItemElement: View {
|
||||||
.shadow(radius: focused ? 10.0 : 0, y: focused ? 10.0 : 0)
|
.shadow(radius: focused ? 10.0 : 0, y: focused ? 10.0 : 0)
|
||||||
.shadow(radius: focused ? 10.0 : 0, y: focused ? 10.0 : 0)
|
.shadow(radius: focused ? 10.0 : 0, y: focused ? 10.0 : 0)
|
||||||
if focused {
|
if focused {
|
||||||
Text(item.type == "Episode" ? "\(item.seriesName ?? "") • S\(String(item.parentIndexNumber ?? 0)):E\(String(item.indexNumber ?? 0))" : item.name ?? "")
|
if(inSeasonView ?? false) {
|
||||||
.font(.callout)
|
Text("\(item.getEpisodeLocator()) • \(item.name ?? "")")
|
||||||
.fontWeight(.semibold)
|
.font(.callout)
|
||||||
.lineLimit(1)
|
.fontWeight(.semibold)
|
||||||
.frame(width: 445)
|
.lineLimit(1)
|
||||||
|
.frame(width: 445)
|
||||||
|
} else {
|
||||||
|
Text(item.type == "Episode" ? "\(item.seriesName ?? "") • \(item.getEpisodeLocator())" : item.name ?? "")
|
||||||
|
.font(.callout)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.lineLimit(1)
|
||||||
|
.frame(width: 445)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Spacer().frame(height: 25)
|
Spacer().frame(height: 25)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct MediaViewActionButton: View {
|
||||||
@Environment(\.isFocused) var envFocused: Bool
|
@Environment(\.isFocused) var envFocused: Bool
|
||||||
@State var focused: Bool = false
|
@State var focused: Bool = false
|
||||||
var icon: String
|
var icon: String
|
||||||
@Binding var scrollView: UIScrollView?
|
var scrollView: Binding<UIScrollView?>?
|
||||||
var iconColor: Color?
|
var iconColor: Color?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -21,9 +21,9 @@ struct MediaViewActionButton: View {
|
||||||
.foregroundColor(focused ? .black : iconColor ?? .white)
|
.foregroundColor(focused ? .black : iconColor ?? .white)
|
||||||
.onChange(of: envFocused) { envFocus in
|
.onChange(of: envFocused) { envFocus in
|
||||||
if(envFocus == true) {
|
if(envFocus == true) {
|
||||||
scrollView?.scrollToTop()
|
scrollView?.wrappedValue?.scrollToTop()
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
||||||
scrollView?.scrollToTop()
|
scrollView?.wrappedValue?.scrollToTop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* 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 2021 Aiden Vigue & Jellyfin Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import JellyfinAPI
|
||||||
|
|
||||||
|
struct EpisodeItemView: View {
|
||||||
|
@ObservedObject var viewModel: EpisodeItemViewModel
|
||||||
|
|
||||||
|
@State var actors: [BaseItemPerson] = [];
|
||||||
|
@State var studio: String? = nil;
|
||||||
|
@State var director: String? = nil;
|
||||||
|
|
||||||
|
func onAppear() {
|
||||||
|
actors = []
|
||||||
|
director = nil
|
||||||
|
studio = nil
|
||||||
|
var actor_index = 0;
|
||||||
|
viewModel.item.people?.forEach { person in
|
||||||
|
if(person.type == "Actor") {
|
||||||
|
if(actor_index < 4) {
|
||||||
|
actors.append(person)
|
||||||
|
}
|
||||||
|
actor_index = actor_index + 1;
|
||||||
|
}
|
||||||
|
if(person.type == "Director") {
|
||||||
|
director = person.name ?? ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
studio = viewModel.item.studios?.first?.name ?? nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
|
||||||
|
.opacity(0.4)
|
||||||
|
LazyVStack(alignment: .leading) {
|
||||||
|
Text(viewModel.item.name ?? "")
|
||||||
|
.font(.title)
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
Text(viewModel.item.seriesName ?? "")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
HStack {
|
||||||
|
if viewModel.item.productionYear != nil {
|
||||||
|
Text(String(viewModel.item.productionYear!)).font(.subheadline)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
Text(viewModel.item.getItemRuntime()).font(.subheadline)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
if viewModel.item.officialRating != nil {
|
||||||
|
Text(viewModel.item.officialRating!).font(.subheadline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
.padding(EdgeInsets(top: 1, leading: 4, bottom: 1, trailing: 4))
|
||||||
|
.overlay(RoundedRectangle(cornerRadius: 2)
|
||||||
|
.stroke(Color.secondary, lineWidth: 1))
|
||||||
|
}
|
||||||
|
}.padding(.top, 15)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
VStack(alignment: .trailing) {
|
||||||
|
if(studio != nil) {
|
||||||
|
Text("STUDIO")
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
Text(studio!)
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.bottom, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(director != nil) {
|
||||||
|
Text("DIRECTOR")
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
Text(director!)
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.bottom, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!actors.isEmpty) {
|
||||||
|
Text("CAST")
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
ForEach(actors, id: \.id) { person in
|
||||||
|
Text(person.name!)
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
if(!(viewModel.item.taglines ?? []).isEmpty) {
|
||||||
|
Text(viewModel.item.taglines?.first ?? "")
|
||||||
|
.font(.body)
|
||||||
|
.italic()
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
}
|
||||||
|
Text(viewModel.item.overview ?? "")
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
VStack {
|
||||||
|
Button {
|
||||||
|
viewModel.updateFavoriteState()
|
||||||
|
} label: {
|
||||||
|
MediaViewActionButton(icon: "heart.fill", iconColor: viewModel.isFavorited ? .red : .white)
|
||||||
|
}
|
||||||
|
Text(viewModel.isFavorited ? "Unfavorite" : "Favorite")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
VStack {
|
||||||
|
NavigationLink(destination: VideoPlayerView(item: viewModel.item)) {
|
||||||
|
MediaViewActionButton(icon: "play.fill")
|
||||||
|
}
|
||||||
|
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : "Play")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
VStack {
|
||||||
|
Button {
|
||||||
|
viewModel.updateWatchState()
|
||||||
|
} label: {
|
||||||
|
MediaViewActionButton(icon: "eye.fill", iconColor: viewModel.isWatched ? .red : .white)
|
||||||
|
}
|
||||||
|
Text(viewModel.isWatched ? "Unwatch" : "Mark Watched")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.top, 15)
|
||||||
|
}
|
||||||
|
}.padding(.top, 50)
|
||||||
|
|
||||||
|
if(!viewModel.similarItems.isEmpty) {
|
||||||
|
Text("More Like This")
|
||||||
|
.font(.headline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
ScrollView(.horizontal) {
|
||||||
|
LazyHStack {
|
||||||
|
Spacer().frame(width: 45)
|
||||||
|
ForEach(viewModel.similarItems, id: \.id) { similarItems in
|
||||||
|
NavigationLink(destination: ItemView(item: similarItems)) {
|
||||||
|
PortraitItemElement(item: similarItems)
|
||||||
|
}.buttonStyle(PlainNavigationLinkButtonStyle())
|
||||||
|
}
|
||||||
|
Spacer().frame(width: 45)
|
||||||
|
}
|
||||||
|
}.padding(EdgeInsets(top: -30, leading: -90, bottom: 0, trailing: -90))
|
||||||
|
.frame(height: 360)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}.padding(EdgeInsets(top: 90, leading: 90, bottom: 0, trailing: 90))
|
||||||
|
}.onAppear(perform: onAppear)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,19 +9,9 @@ import SwiftUI
|
||||||
import Introspect
|
import Introspect
|
||||||
import JellyfinAPI
|
import JellyfinAPI
|
||||||
|
|
||||||
class VideoPlayerItem: ObservableObject {
|
|
||||||
@Published var shouldShowPlayer: Bool = false
|
|
||||||
@Published var itemToPlay: BaseItemDto = BaseItemDto()
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ItemView: View {
|
struct ItemView: View {
|
||||||
private var item: BaseItemDto
|
private var item: BaseItemDto
|
||||||
|
|
||||||
@StateObject private var videoPlayerItem: VideoPlayerItem = VideoPlayerItem()
|
|
||||||
@State private var videoIsLoading: Bool = false; // This variable is only changed by the underlying VLC view.
|
|
||||||
@State private var isLoading: Bool = false
|
|
||||||
@State private var viewDidLoad: Bool = false
|
|
||||||
|
|
||||||
init(item: BaseItemDto) {
|
init(item: BaseItemDto) {
|
||||||
self.item = item
|
self.item = item
|
||||||
}
|
}
|
||||||
|
@ -32,6 +22,10 @@ struct ItemView: View {
|
||||||
MovieItemView(viewModel: .init(item: item))
|
MovieItemView(viewModel: .init(item: item))
|
||||||
} else if item.type == "Series" {
|
} else if item.type == "Series" {
|
||||||
SeriesItemView(viewModel: .init(item: item))
|
SeriesItemView(viewModel: .init(item: item))
|
||||||
|
} else if item.type == "Season" {
|
||||||
|
SeasonItemView(viewModel: .init(item: item))
|
||||||
|
} else if item.type == "Episode" {
|
||||||
|
EpisodeItemView(viewModel: .init(item: item))
|
||||||
} else {
|
} else {
|
||||||
Text("Type: \(item.type ?? "") not implemented yet :(")
|
Text("Type: \(item.type ?? "") not implemented yet :(")
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ struct LibraryView: View {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
} else if !viewModel.items.isEmpty {
|
} else if !viewModel.items.isEmpty {
|
||||||
ScrollView(.vertical) {
|
ScrollView(.vertical) {
|
||||||
Spacer().frame(height: 16)
|
|
||||||
LazyVGrid(columns: tracks) {
|
LazyVGrid(columns: tracks) {
|
||||||
ForEach(viewModel.items, id: \.id) { item in
|
ForEach(viewModel.items, id: \.id) { item in
|
||||||
if(item.type != "Folder") {
|
if(item.type != "Folder") {
|
||||||
|
@ -41,32 +40,13 @@ struct LibraryView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.padding()
|
||||||
Spacer().frame(height: 16)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Text("No results.")
|
Text("No results.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitle(title)
|
/*
|
||||||
.toolbar {
|
|
||||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
|
||||||
if viewModel.hasPreviousPage {
|
|
||||||
Button {
|
|
||||||
viewModel.requestPreviousPage()
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "chevron.left")
|
|
||||||
}.disabled(viewModel.isLoading)
|
|
||||||
}
|
|
||||||
if viewModel.hasNextPage {
|
|
||||||
Button {
|
|
||||||
viewModel.requestNextPage()
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "chevron.right")
|
|
||||||
}.disabled(viewModel.isLoading)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}/*
|
|
||||||
.sheet(isPresented: $isShowingFilterView) {
|
.sheet(isPresented: $isShowingFilterView) {
|
||||||
LibraryFilterView(filters: $viewModel.filters, enabledFilterType: viewModel.enabledFilterType, parentId: viewModel.parentID ?? "")
|
LibraryFilterView(filters: $viewModel.filters, enabledFilterType: viewModel.enabledFilterType, parentId: viewModel.parentID ?? "")
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ struct MovieItemView: View {
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.padding(.top, 15)
|
.padding(.top, 15)
|
||||||
.addFocusGuide(using: focusBag, name: "actionButtons", destinations: [.bottom: "moreLikeThis"], debug: true)
|
.addFocusGuide(using: focusBag, name: "actionButtons", destinations: [.bottom: "moreLikeThis"], debug: false)
|
||||||
}
|
}
|
||||||
}.padding(.top, 50)
|
}.padding(.top, 50)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* 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 2021 Aiden Vigue & Jellyfin Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import JellyfinAPI
|
||||||
|
import SwiftUIFocusGuide
|
||||||
|
|
||||||
|
struct SeasonItemView: View {
|
||||||
|
@ObservedObject var viewModel: SeasonItemViewModel
|
||||||
|
@State var wrappedScrollView: UIScrollView?;
|
||||||
|
|
||||||
|
@StateObject var focusBag = SwiftUIFocusBag()
|
||||||
|
|
||||||
|
@Environment(\.resetFocus) var resetFocus
|
||||||
|
@Namespace private var namespace
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
ImageView(src: viewModel.item.getSeriesBackdropImage(maxWidth: 1920), bh: viewModel.item.getSeriesBackdropImageBlurHash())
|
||||||
|
.opacity(0.4)
|
||||||
|
ScrollView {
|
||||||
|
LazyVStack(alignment: .leading) {
|
||||||
|
Text("\(viewModel.item.seriesName ?? "") • \(viewModel.item.name ?? "")")
|
||||||
|
.font(.title)
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
HStack {
|
||||||
|
if(viewModel.item.productionYear != nil) {
|
||||||
|
Text(String(viewModel.item.productionYear!)).font(.subheadline)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
if viewModel.item.officialRating != nil {
|
||||||
|
Text(viewModel.item.officialRating!).font(.subheadline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
.padding(EdgeInsets(top: 1, leading: 4, bottom: 1, trailing: 4))
|
||||||
|
.overlay(RoundedRectangle(cornerRadius: 2)
|
||||||
|
.stroke(Color.secondary, lineWidth: 1))
|
||||||
|
}
|
||||||
|
if viewModel.item.communityRating != nil {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "star.fill")
|
||||||
|
.foregroundColor(.yellow)
|
||||||
|
.font(.subheadline)
|
||||||
|
Text(String(viewModel.item.communityRating!)).font(.subheadline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
if(!(viewModel.item.taglines ?? []).isEmpty) {
|
||||||
|
Text(viewModel.item.taglines?.first ?? "")
|
||||||
|
.font(.body)
|
||||||
|
.italic()
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
}
|
||||||
|
Text(viewModel.item.overview ?? "")
|
||||||
|
.font(.body)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
VStack {
|
||||||
|
Button {
|
||||||
|
viewModel.updateFavoriteState()
|
||||||
|
} label: {
|
||||||
|
MediaViewActionButton(icon: "heart.fill", scrollView: $wrappedScrollView, iconColor: viewModel.isFavorited ? .red : .white)
|
||||||
|
}.prefersDefaultFocus(in: namespace)
|
||||||
|
Text(viewModel.isFavorited ? "Unfavorite" : "Favorite")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
VStack {
|
||||||
|
Button {
|
||||||
|
viewModel.updateWatchState()
|
||||||
|
} label: {
|
||||||
|
MediaViewActionButton(icon: "eye.fill", scrollView: $wrappedScrollView, iconColor: viewModel.isWatched ? .red : .white)
|
||||||
|
}
|
||||||
|
Text(viewModel.isWatched ? "Unwatch" : "Mark Watched")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
}.padding(.top, 15)
|
||||||
|
Spacer()
|
||||||
|
}.padding(.top, 50)
|
||||||
|
|
||||||
|
if(!viewModel.episodes.isEmpty) {
|
||||||
|
Text("Episodes")
|
||||||
|
.font(.headline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
ScrollView(.horizontal) {
|
||||||
|
LazyHStack {
|
||||||
|
Spacer().frame(width: 45)
|
||||||
|
ForEach(viewModel.episodes, id: \.id) { episode in
|
||||||
|
NavigationLink(destination: ItemView(item: episode)) {
|
||||||
|
LandscapeItemElement(item: episode, inSeasonView: true)
|
||||||
|
}.buttonStyle(PlainNavigationLinkButtonStyle())
|
||||||
|
}
|
||||||
|
Spacer().frame(width: 45)
|
||||||
|
}
|
||||||
|
}.padding(EdgeInsets(top: -30, leading: -90, bottom: 0, trailing: -90))
|
||||||
|
.frame(height: 360)
|
||||||
|
}
|
||||||
|
}.padding(EdgeInsets(top: 90, leading: 90, bottom: 45, trailing: 90))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,21 +19,6 @@ class InfoTabBarViewController: UITabBarController, UIGestureRecognizerDelegate
|
||||||
var infoContainerPos: CGRect?
|
var infoContainerPos: CGRect?
|
||||||
var tabBarHeight: CGFloat = 0
|
var tabBarHeight: CGFloat = 0
|
||||||
|
|
||||||
// override func viewWillAppear(_ animated: Bool) {
|
|
||||||
// tabBar.standardAppearance.backgroundColor = .clear
|
|
||||||
// tabBar.standardAppearance.backgroundImage = UIImage()
|
|
||||||
// tabBar.standardAppearance.backgroundEffect = .none
|
|
||||||
// tabBar.barTintColor = .clear
|
|
||||||
// for view in tabBar.subviews {
|
|
||||||
// print(view.description)
|
|
||||||
//// if view.description.contains("_UIBarBackground") {
|
|
||||||
////
|
|
||||||
//// view.removeFromSuperview()
|
|
||||||
//// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
mediaInfoController = MediaInfoViewController()
|
mediaInfoController = MediaInfoViewController()
|
||||||
|
|
|
@ -52,25 +52,27 @@ struct MediaInfoView: View {
|
||||||
if item.type == "Episode" {
|
if item.type == "Episode" {
|
||||||
Text(item.seriesName ?? "Series")
|
Text(item.seriesName ?? "Series")
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Text(item.name ?? "Episode")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
Text(item.getEpisodeLocator())
|
||||||
|
|
||||||
Text(item.name ?? "Episode")
|
if let date = item.premiereDate {
|
||||||
.foregroundColor(.secondary)
|
Text(formatDate(date: date))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Text(item.name ?? "Movie")
|
Text(item.name ?? "Movie")
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
}
|
}
|
||||||
|
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
if item.type == "Episode" {
|
if(item.type != "Episode") {
|
||||||
Text("S\(item.parentIndexNumber ?? 0) • E\(item.indexNumber ?? 0)")
|
if let year = item.productionYear {
|
||||||
|
Text(String(year))
|
||||||
if let date = item.premiereDate {
|
|
||||||
Text("•")
|
|
||||||
Text(formatDate(date: date))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if let year = item.productionYear {
|
|
||||||
Text(String(year))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.runTimeTicks != nil {
|
if item.runTimeTicks != nil {
|
||||||
|
@ -113,7 +115,7 @@ struct MediaInfoView: View {
|
||||||
|
|
||||||
func formatDate(date: Date) -> String {
|
func formatDate(date: Date) -> String {
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
formatter.dateFormat = "d MMM yyyy"
|
formatter.dateFormat = "MMM d, yyyy"
|
||||||
|
|
||||||
return formatter.string(from: date)
|
return formatter.string(from: date)
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,8 +488,6 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
||||||
let translation = panGestureRecognizer.translation(in: view)
|
let translation = panGestureRecognizer.translation(in: view)
|
||||||
let velocity = panGestureRecognizer.velocity(in: view)
|
let velocity = panGestureRecognizer.velocity(in: view)
|
||||||
|
|
||||||
print(translation)
|
|
||||||
|
|
||||||
// Swiped up - Handle dismissing info panel
|
// Swiped up - Handle dismissing info panel
|
||||||
if translation.y < -200 && (focusedOnTabBar && showingInfoPanel) {
|
if translation.y < -200 && (focusedOnTabBar && showingInfoPanel) {
|
||||||
toggleInfoContainer()
|
toggleInfoContainer()
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
532175402671EE4F005491E6 /* LibraryFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */; };
|
532175402671EE4F005491E6 /* LibraryFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */; };
|
||||||
53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53272531268BF09D0035FBF1 /* MediaViewActionButton.swift */; };
|
53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53272531268BF09D0035FBF1 /* MediaViewActionButton.swift */; };
|
||||||
53272535268BF9710035FBF1 /* SwiftUIFocusGuide in Frameworks */ = {isa = PBXBuildFile; productRef = 53272534268BF9710035FBF1 /* SwiftUIFocusGuide */; };
|
53272535268BF9710035FBF1 /* SwiftUIFocusGuide in Frameworks */ = {isa = PBXBuildFile; productRef = 53272534268BF9710035FBF1 /* SwiftUIFocusGuide */; };
|
||||||
|
53272537268C1DBB0035FBF1 /* SeasonItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53272536268C1DBB0035FBF1 /* SeasonItemView.swift */; };
|
||||||
|
53272539268C20100035FBF1 /* EpisodeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53272538268C20100035FBF1 /* EpisodeItemView.swift */; };
|
||||||
532E68CF267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532E68CE267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift */; };
|
532E68CF267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532E68CE267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift */; };
|
||||||
53313B90265EEA6D00947AA3 /* VideoPlayer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53313B8F265EEA6D00947AA3 /* VideoPlayer.storyboard */; };
|
53313B90265EEA6D00947AA3 /* VideoPlayer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53313B8F265EEA6D00947AA3 /* VideoPlayer.storyboard */; };
|
||||||
53352571265EA0A0006CCA86 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 53352570265EA0A0006CCA86 /* Introspect */; };
|
53352571265EA0A0006CCA86 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 53352570265EA0A0006CCA86 /* Introspect */; };
|
||||||
|
@ -235,6 +237,8 @@
|
||||||
531AC8BE26750DE20091C7EB /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
|
531AC8BE26750DE20091C7EB /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
|
||||||
5321753A2671BCFC005491E6 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
|
5321753A2671BCFC005491E6 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
|
||||||
53272531268BF09D0035FBF1 /* MediaViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaViewActionButton.swift; sourceTree = "<group>"; };
|
53272531268BF09D0035FBF1 /* MediaViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaViewActionButton.swift; sourceTree = "<group>"; };
|
||||||
|
53272536268C1DBB0035FBF1 /* SeasonItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonItemView.swift; sourceTree = "<group>"; };
|
||||||
|
53272538268C20100035FBF1 /* EpisodeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EpisodeItemView.swift; sourceTree = "<group>"; };
|
||||||
532E68CE267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerCastDeviceSelector.swift; sourceTree = "<group>"; };
|
532E68CE267D9F6B007B9F13 /* VideoPlayerCastDeviceSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerCastDeviceSelector.swift; sourceTree = "<group>"; };
|
||||||
53313B8F265EEA6D00947AA3 /* VideoPlayer.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = VideoPlayer.storyboard; sourceTree = "<group>"; };
|
53313B8F265EEA6D00947AA3 /* VideoPlayer.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = VideoPlayer.storyboard; sourceTree = "<group>"; };
|
||||||
5338F74D263B61370014BF09 /* ConnectToServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerView.swift; sourceTree = "<group>"; };
|
5338F74D263B61370014BF09 /* ConnectToServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -467,6 +471,8 @@
|
||||||
53CD2A3F268A49C2002ABD4E /* ItemView.swift */,
|
53CD2A3F268A49C2002ABD4E /* ItemView.swift */,
|
||||||
53CD2A41268A4B38002ABD4E /* MovieItemView.swift */,
|
53CD2A41268A4B38002ABD4E /* MovieItemView.swift */,
|
||||||
53116A16268B919A003024C9 /* SeriesItemView.swift */,
|
53116A16268B919A003024C9 /* SeriesItemView.swift */,
|
||||||
|
53272536268C1DBB0035FBF1 /* SeasonItemView.swift */,
|
||||||
|
53272538268C20100035FBF1 /* EpisodeItemView.swift */,
|
||||||
);
|
);
|
||||||
path = "JellyfinPlayer tvOS";
|
path = "JellyfinPlayer tvOS";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -978,6 +984,7 @@
|
||||||
091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */,
|
||||||
531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */,
|
531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */,
|
||||||
62EC3530267666A5000E9F2D /* SessionManager.swift in Sources */,
|
62EC3530267666A5000E9F2D /* SessionManager.swift in Sources */,
|
||||||
|
53272539268C20100035FBF1 /* EpisodeItemView.swift in Sources */,
|
||||||
531690F7267ACC00005D8AB9 /* LandscapeItemElement.swift in Sources */,
|
531690F7267ACC00005D8AB9 /* LandscapeItemElement.swift in Sources */,
|
||||||
62E632E1267D30CA0063E547 /* LibraryViewModel.swift in Sources */,
|
62E632E1267D30CA0063E547 /* LibraryViewModel.swift in Sources */,
|
||||||
535870A82669D8AE00D05A09 /* StringExtensions.swift in Sources */,
|
535870A82669D8AE00D05A09 /* StringExtensions.swift in Sources */,
|
||||||
|
@ -1006,6 +1013,7 @@
|
||||||
535870AA2669D8AE00D05A09 /* BlurHashDecode.swift in Sources */,
|
535870AA2669D8AE00D05A09 /* BlurHashDecode.swift in Sources */,
|
||||||
53ABFDE5267974EF00886593 /* ViewModel.swift in Sources */,
|
53ABFDE5267974EF00886593 /* ViewModel.swift in Sources */,
|
||||||
531069582684E7EE00CFFDBA /* MediaInfoView.swift in Sources */,
|
531069582684E7EE00CFFDBA /* MediaInfoView.swift in Sources */,
|
||||||
|
53272537268C1DBB0035FBF1 /* SeasonItemView.swift in Sources */,
|
||||||
09389CC526814E4500AE350E /* DeviceProfileBuilder.swift in Sources */,
|
09389CC526814E4500AE350E /* DeviceProfileBuilder.swift in Sources */,
|
||||||
535870A62669D8AE00D05A09 /* LazyView.swift in Sources */,
|
535870A62669D8AE00D05A09 /* LazyView.swift in Sources */,
|
||||||
5321753E2671DE9C005491E6 /* Typings.swift in Sources */,
|
5321753E2671DE9C005491E6 /* Typings.swift in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue