diff --git a/JellyfinPlayer.xcodeproj/project.pbxproj b/JellyfinPlayer.xcodeproj/project.pbxproj
index 6bdb5412..de2c151c 100644
--- a/JellyfinPlayer.xcodeproj/project.pbxproj
+++ b/JellyfinPlayer.xcodeproj/project.pbxproj
@@ -462,7 +462,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 14;
+ CURRENT_PROJECT_VERSION = 15;
DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer/Preview Content\"";
DEVELOPMENT_TEAM = 9R8RREG67J;
ENABLE_BITCODE = NO;
@@ -491,7 +491,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 14;
+ CURRENT_PROJECT_VERSION = 15;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer/Preview Content\"";
DEVELOPMENT_TEAM = 9R8RREG67J;
diff --git a/JellyfinPlayer/ContinueWatchingView.swift b/JellyfinPlayer/ContinueWatchingView.swift
index 07320130..d9b5af60 100644
--- a/JellyfinPlayer/ContinueWatchingView.swift
+++ b/JellyfinPlayer/ContinueWatchingView.swift
@@ -107,74 +107,78 @@ struct ContinueWatchingView: View {
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
- LazyHStack() {
- Spacer().frame(width:16)
- ForEach(resumeItems, id: \.Id) { item in
- NavigationLink(destination: ItemView(item: item)) {
- VStack(alignment: .leading) {
- Spacer().frame(height: 10)
- if(item.Type == "Episode") {
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=550&quality=80&tag=\(item.Image)")!)
- .resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
- .placeholder {
- Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 6, height: 6))!)
- .resizable()
- .frame(width: 320, height: 180)
- .cornerRadius(10)
- }
- .frame(width: 320, height: 180)
- .cornerRadius(10)
- .overlay(
- ZStack {
- Text("S\(String(item.ParentIndexNumber ?? 0)):E\(String(item.IndexNumber ?? 0)) - \(item.Name)")
- .font(.caption)
- .padding(6)
- .foregroundColor(.white)
- }.background(Color.black)
- .opacity(0.8)
- .cornerRadius(10.0)
- .padding(6), alignment: .topTrailing
- )
- .overlay(
- Rectangle()
- .fill(Color(red: 172/255, green: 92/255, blue: 195/255))
- .mask(CustomShape(radius: 10))
- .frame(width: CGFloat((item.ItemProgress/100)*320), height: 7)
+ if(_resumeItems.wrappedValue.count > 0) {
+ LazyHStack() {
+ Spacer().frame(width:16)
+ ForEach(resumeItems, id: \.Id) { item in
+ NavigationLink(destination: ItemView(item: item)) {
+ VStack(alignment: .leading) {
+ Spacer().frame(height: 10)
+ if(item.Type == "Episode") {
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=550&quality=80&tag=\(item.Image)")!)
+ .resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
+ .placeholder {
+ Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 6, height: 6))!)
+ .resizable()
+ .frame(width: 320, height: 180)
+ .cornerRadius(10)
+ }
+ .frame(width: 320, height: 180)
+ .cornerRadius(10)
+ .overlay(
+ ZStack {
+ Text("S\(String(item.ParentIndexNumber ?? 0)):E\(String(item.IndexNumber ?? 0)) - \(item.Name)")
+ .font(.caption)
+ .padding(6)
+ .foregroundColor(.white)
+ }.background(Color.black)
+ .opacity(0.8)
+ .cornerRadius(10.0)
+ .padding(6), alignment: .topTrailing
+ )
+ .overlay(
+ Rectangle()
+ .fill(Color(red: 172/255, green: 92/255, blue: 195/255))
+ .mask(CustomShape(radius: 10))
+ .frame(width: CGFloat((item.ItemProgress/100)*320), height: 7)
+ .padding(0), alignment: .bottomLeading
+ )
+ .shadow(radius: 5)
+ } else {
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=550&quality=80&tag=\(item.Image)")!)
+ .resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
+ .placeholder {
+ Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 6, height: 6))!)
+ .resizable()
+ .frame(width: 320, height: 180)
+ .cornerRadius(10)
+ }
+ .frame(width: 320, height: 180)
+ .cornerRadius(10)
+ .overlay(
+ Rectangle()
+ .fill(Color(red: 172/255, green: 92/255, blue: 195/255))
+ .mask(CustomShape(radius: 10))
+ .frame(width: CGFloat((item.ItemProgress/100)*320), height: 7)
.padding(0), alignment: .bottomLeading
- )
- .shadow(radius: 5)
- } else {
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=550&quality=80&tag=\(item.Image)")!)
- .resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
- .placeholder {
- Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 6, height: 6))!)
- .resizable()
- .frame(width: 320, height: 180)
- .cornerRadius(10)
- }
- .frame(width: 320, height: 180)
- .cornerRadius(10)
- .overlay(
- Rectangle()
- .fill(Color(red: 172/255, green: 92/255, blue: 195/255))
- .mask(CustomShape(radius: 10))
- .frame(width: CGFloat((item.ItemProgress/100)*320), height: 7)
- .padding(0), alignment: .bottomLeading
- )
- .shadow(radius: 5)
- }
- Text("\(item.Type == "Episode" ? item.SeriesName ?? "" : item.Name)")
- .font(.callout)
- .fontWeight(.semibold)
- .foregroundColor(.primary)
- .lineLimit(1)
- .frame(width: 320, alignment: .leading)
- Spacer().frame(height: 5)
- }.padding(.trailing, 5)
+ )
+ .shadow(radius: 5)
+ }
+ Text("\(item.Type == "Episode" ? item.SeriesName ?? "" : item.Name)")
+ .font(.callout)
+ .fontWeight(.semibold)
+ .foregroundColor(.primary)
+ .lineLimit(1)
+ .frame(width: 320, alignment: .leading)
+ Spacer().frame(height: 5)
+ }.padding(.trailing, 5)
+ }
}
- }
- Spacer().frame(width:14)
- }.frame(height: 215)
+ Spacer().frame(width:14)
+ }.frame(height: 215)
+ } else {
+ EmptyView()
+ }
}.onAppear(perform: onAppear)
.frame(height: 215)
.padding(.bottom, 10)
diff --git a/JellyfinPlayer/EpisodeItemView.swift b/JellyfinPlayer/EpisodeItemView.swift
index c63b7555..20526aa6 100644
--- a/JellyfinPlayer/EpisodeItemView.swift
+++ b/JellyfinPlayer/EpisodeItemView.swift
@@ -18,7 +18,13 @@ struct EpisodeItemView: View {
var item: ResumeItem;
@EnvironmentObject var orientationInfo: OrientationInfo
var fullItem: DetailItem;
- @State private var playing: Bool = false;
+ @State private var playing: Bool = false {
+ didSet {
+ if(_playing.wrappedValue == false) {
+ unlockOrientations()
+ }
+ }
+ };
@State private var vc: PreferenceUIHostingController? = nil;
@State private var progressString: String = "";
@State private var viewDidLoad: Bool = false;
diff --git a/JellyfinPlayer/Info.plist b/JellyfinPlayer/Info.plist
index 39262099..de41309f 100644
--- a/JellyfinPlayer/Info.plist
+++ b/JellyfinPlayer/Info.plist
@@ -19,7 +19,7 @@
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
- 14
+ 15
DTXApplicationID
8c1f6941-ec78-480c-b589-b41aca29a52e
DTXBeaconURL
diff --git a/JellyfinPlayer/MovieItemView.swift b/JellyfinPlayer/MovieItemView.swift
index ae5d948e..15fbcd35 100644
--- a/JellyfinPlayer/MovieItemView.swift
+++ b/JellyfinPlayer/MovieItemView.swift
@@ -66,7 +66,13 @@ struct MovieItemView: View {
@State private var isLoading: Bool = true;
var item: ResumeItem;
var fullItem: DetailItem;
- @State private var playing: Bool = false;
+ @State private var playing: Bool = false {
+ didSet {
+ if(_playing.wrappedValue == false) {
+ unlockOrientations()
+ }
+ }
+ };
@State private var vc: PreferenceUIHostingController? = nil;
@State private var progressString: String = "";
@State private var viewDidLoad: Bool = false;
@@ -255,7 +261,7 @@ struct MovieItemView: View {
var body: some View {
if(playing) {
- VideoPlayerView(item: fullItem, playing: $playing).onAppear(perform: lockOrientations)
+ VideoPlayerView(item: fullItem, playing: $playing).onAppear(perform: lockOrientations).onDisappear(perform: unlockOrientations)
} else {
LoadingView(isShowing: $isLoading) {
VStack(alignment:.leading) {
diff --git a/JellyfinPlayer/VideoPlayerView.swift b/JellyfinPlayer/VideoPlayerView.swift
index 60c76b9f..dfee0ca7 100644
--- a/JellyfinPlayer/VideoPlayerView.swift
+++ b/JellyfinPlayer/VideoPlayerView.swift
@@ -274,7 +274,9 @@ struct VideoPlayerView: View {
}
if(_selectedAudioTrack.wrappedValue == -1) {
- _selectedAudioTrack.wrappedValue = _audioTracks.wrappedValue[0].id;
+ if(_audioTracks.wrappedValue.count > 0) {
+ _selectedAudioTrack.wrappedValue = _audioTracks.wrappedValue[0].id;
+ }
}
let streamUrl = streamURL.absoluteString;
@@ -319,6 +321,7 @@ struct VideoPlayerView: View {
_selectedAudioTrack.wrappedValue = _audioTracks.wrappedValue[0].id;
}
+ sendPlayReport()
pbitem = item;
pbitem.subtitles = subtitles;
_isPlaying.wrappedValue = true;