From 30e2b9d028b4a8fec17b1f3b739b2f0c4ff3dc97 Mon Sep 17 00:00:00 2001 From: Aiden Vigue Date: Sun, 27 Jun 2021 11:56:40 -0400 Subject: [PATCH] push --- JellyfinPlayer.xcodeproj/project.pbxproj | 12 +-- .../Components/PortraitItemView.swift | 86 +++++++++++++++++++ JellyfinPlayer/ConnectToServerView.swift | 4 +- JellyfinPlayer/LatestMediaView.swift | 37 +------- JellyfinPlayer/VideoUpNextView.swift | 18 ++-- 5 files changed, 101 insertions(+), 56 deletions(-) create mode 100644 JellyfinPlayer/Components/PortraitItemView.swift diff --git a/JellyfinPlayer.xcodeproj/project.pbxproj b/JellyfinPlayer.xcodeproj/project.pbxproj index 307073b9..3864743e 100644 --- a/JellyfinPlayer.xcodeproj/project.pbxproj +++ b/JellyfinPlayer.xcodeproj/project.pbxproj @@ -1099,7 +1099,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "JellyfinPlayer tvOS/JellyfinPlayer tvOS.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\""; DEVELOPMENT_TEAM = 9R8RREG67J; ENABLE_PREVIEWS = YES; @@ -1127,7 +1127,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "JellyfinPlayer tvOS/JellyfinPlayer tvOS.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\""; DEVELOPMENT_TEAM = 9R8RREG67J; ENABLE_PREVIEWS = YES; @@ -1276,7 +1276,7 @@ CODE_SIGN_ENTITLEMENTS = JellyfinPlayer/JellyfinPlayer.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = 9R8RREG67J; ENABLE_BITCODE = NO; @@ -1310,7 +1310,7 @@ CODE_SIGN_ENTITLEMENTS = JellyfinPlayer/JellyfinPlayer.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = 9R8RREG67J; @@ -1342,7 +1342,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEVELOPMENT_TEAM = 9R8RREG67J; INFOPLIST_FILE = WidgetExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.1; @@ -1367,7 +1367,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEVELOPMENT_TEAM = 9R8RREG67J; INFOPLIST_FILE = WidgetExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.1; diff --git a/JellyfinPlayer/Components/PortraitItemView.swift b/JellyfinPlayer/Components/PortraitItemView.swift new file mode 100644 index 00000000..37bc2045 --- /dev/null +++ b/JellyfinPlayer/Components/PortraitItemView.swift @@ -0,0 +1,86 @@ +// + /* + * 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 PortraitItemView: View { + var item: BaseItemDto + + var body: some View { + NavigationLink(destination: LazyView { ItemView(item: item) }) { + VStack(alignment: .leading) { + ImageView(src: item.type != "Episode" ? item.getPrimaryImage(maxWidth: 100) : item.getSeriesPrimaryImage(maxWidth: 100), bh: item.type != "Episode" ? item.getPrimaryImageBlurHash() : item.getSeriesPrimaryImageBlurHash()) + .frame(width: 100, height: 150) + .cornerRadius(10) + .shadow(radius: 4) + .overlay( + Rectangle() + .fill(Color(red: 172/255, green: 92/255, blue: 195/255)) + .mask(ProgressBar()) + .frame(width: CGFloat(item.userData?.playedPercentage ?? 0), height: 7) + .padding(0), alignment: .bottomLeading + ) + .overlay( + ZStack { + if item.userData?.isFavorite ?? false { + Image(systemName: "circle.fill") + .foregroundColor(.white) + .opacity(0.6) + Image(systemName: "heart.fill") + .foregroundColor(Color(.systemRed)) + .font(.system(size: 10)) + } + } + .padding(.leading, 2) + .padding(.bottom, item.userData?.playedPercentage == nil ? 2 : 9) + .opacity(1) + , alignment: .bottomLeading) + .overlay( + ZStack { + if item.userData?.played ?? false { + Image(systemName: "circle.fill") + .foregroundColor(.white) + Image(systemName: "checkmark.circle.fill") + .foregroundColor(Color(.systemBlue)) + } else { + if(item.userData?.unplayedItemCount != nil) { + Image(systemName: "circle.fill") + .foregroundColor(Color(.systemBlue)) + Text(String(item.userData!.unplayedItemCount ?? 0)) + .foregroundColor(.white) + .font(.caption2) + } + } + }.padding(2) + .opacity(1), alignment: .topTrailing).opacity(1) + Text(item.seriesName ?? item.name ?? "") + .font(.caption) + .fontWeight(.semibold) + .foregroundColor(.primary) + .lineLimit(1) + if(item.type == "Movie" || item.type == "Series") { + Text("\(String(item.productionYear ?? 0)) • \(item.officialRating ?? "N/A")") + .foregroundColor(.secondary) + .font(.caption) + .fontWeight(.medium) + } else if(item.type == "Season") { + Text("\(item.name ?? "") • \(String(item.productionYear ?? 0))") + .foregroundColor(.secondary) + .font(.caption) + .fontWeight(.medium) + } else { + Text("S\(String(item.parentIndexNumber ?? 0)):E\(String(item.indexNumber ?? 0))") + .foregroundColor(.secondary) + .font(.caption) + .fontWeight(.medium) + } + }.frame(width: 100) + } + } +} diff --git a/JellyfinPlayer/ConnectToServerView.swift b/JellyfinPlayer/ConnectToServerView.swift index d3d651bd..5cf7d969 100644 --- a/JellyfinPlayer/ConnectToServerView.swift +++ b/JellyfinPlayer/ConnectToServerView.swift @@ -67,7 +67,7 @@ struct ConnectToServerView: View { Text(publicUser.name ?? "").font(.subheadline).fontWeight(.semibold) Spacer() if publicUser.primaryImageTag != nil { - ImageView(src: URL(string: "\(ServerEnvironment.current.server.baseURI ?? "")/Users/\(publicUser.id ?? "")/Images/Primary?width=180&quality=80&tag=\(publicUser.primaryImageTag!)")!) + ImageView(src: URL(string: "\(ServerEnvironment.current.server.baseURI ?? "")/Users/\(publicUser.id ?? "")/Images/Primary?width=120&quality=80&tag=\(publicUser.primaryImageTag!)")!) .frame(width: 60, height: 60) .cornerRadius(30.0) } else { @@ -160,7 +160,7 @@ struct ConnectToServerView: View { viewModel.passwordSubject.send(password) } .alert(item: $viewModel.errorMessage) { _ in - Alert(title: Text("Error"), message: Text("message"), dismissButton: .default(Text("Try again"))) + Alert(title: Text("Error"), message: Text($viewModel.errorMessage.wrappedValue!), dismissButton: .default(Text("Try again"))) } .navigationTitle("Connect to Server") } diff --git a/JellyfinPlayer/LatestMediaView.swift b/JellyfinPlayer/LatestMediaView.swift index 2595bf18..902891de 100644 --- a/JellyfinPlayer/LatestMediaView.swift +++ b/JellyfinPlayer/LatestMediaView.swift @@ -15,43 +15,10 @@ struct LatestMediaView: View { LazyHStack { ForEach(viewModel.items, id: \.id) { item in if item.type == "Series" || item.type == "Movie" { - NavigationLink(destination: LazyView { ItemView(item: item) }) { - VStack(alignment: .leading) { - ImageView(src: item.getPrimaryImage(maxWidth: 100), bh: item.getPrimaryImageBlurHash()) - .frame(width: 100, height: 150) - .cornerRadius(10) - .shadow(radius: 4) - .overlay( - ZStack { - if item.userData!.played ?? false { - Image(systemName: "circle.fill") - .foregroundColor(.white) - Image(systemName: "checkmark.circle.fill") - .foregroundColor(Color(.systemBlue)) - } - }.padding(2) - .opacity(1), alignment: .topTrailing).opacity(1) - Text(item.seriesName ?? item.name ?? "") - .font(.caption) - .fontWeight(.semibold) - .foregroundColor(.primary) - .lineLimit(1) - if item.productionYear != nil { - Text(String(item.productionYear ?? 0)) - .foregroundColor(.secondary) - .font(.caption) - .fontWeight(.medium) - } else { - Text(item.type!) - .foregroundColor(.secondary) - .font(.caption) - .fontWeight(.medium) - } - }.frame(width: 100) - } + PortraitItemView(item: item) } }.padding(.trailing, 16) }.padding(.leading, 20) - }.frame(height: 195) + }.frame(height: 200) } } diff --git a/JellyfinPlayer/VideoUpNextView.swift b/JellyfinPlayer/VideoUpNextView.swift index 63e92e2a..810bc197 100644 --- a/JellyfinPlayer/VideoUpNextView.swift +++ b/JellyfinPlayer/VideoUpNextView.swift @@ -15,16 +15,9 @@ class UpNextViewModel: ObservableObject { @Published var item: BaseItemDto? = nil var delegate: PlayerViewController? - func episodeAndSeasonNumber() -> String { - if let pID = item?.parentIndexNumber, let id = item?.indexNumber { - return "S\(pID):E\(id)" - } - return "" - } - - func episodeName() -> String { - if let name = item?.name { - return name + func getEpisodeLocator() -> String { + if let seasonNo = item?.parentIndexNumber, let episodeNo = item?.indexNumber { + return "S\(seasonNo):E\(episodeNo)" } return "" } @@ -34,7 +27,6 @@ class UpNextViewModel: ObservableObject { delegate?.setPlayerToNextUp() } } - } struct VideoUpNextView: View { @@ -50,7 +42,7 @@ struct VideoUpNextView: View { Button(action: viewModel.nextUp, label: {image}) if viewModel.largeView { - Text(viewModel.episodeName()) + Text(viewModel.item!.name ?? "") .padding(.trailing, 50) .foregroundColor(.white) .minimumScaleFactor(0.1) @@ -76,7 +68,7 @@ struct VideoUpNextView: View { } var overlayIndicator : some View { - Text(viewModel.episodeAndSeasonNumber()) + Text(viewModel.getEpisodeLocator()) .font(viewModel.largeView ? .title3 : .body) .foregroundColor(.white) .padding(.horizontal, 5)