diff --git a/.DS_Store b/.DS_Store index be04e47a..8c6dfbf4 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/JellyfinPlayer/ContinueWatchingView.swift b/JellyfinPlayer/ContinueWatchingView.swift index 9dac7dcf..9a42dd88 100644 --- a/JellyfinPlayer/ContinueWatchingView.swift +++ b/JellyfinPlayer/ContinueWatchingView.swift @@ -37,6 +37,7 @@ struct CustomShape: Shape { struct ContinueWatchingView: View { @Environment(\.managedObjectContext) private var viewContext @EnvironmentObject var globalData: GlobalData + @EnvironmentObject var orientationInfo: OrientationInfo @State var resumeItems: [ResumeItem] = [] @State private var viewDidLoad: Int = 0; @@ -64,7 +65,7 @@ struct ContinueWatchingView: View { for (_,item):(String, JSON) in json["Items"] { // Do something you want let itemObj = ResumeItem() - if(item["PrimaryImageAspectRatio"].double! < 1.0) { + if(item["PrimaryImageAspectRatio"].double ?? 0.0 < 1.0) { //portrait; use backdrop instead itemObj.Image = item["BackdropImageTags"][0].string ?? "" itemObj.ImageType = "Backdrop" diff --git a/JellyfinPlayer/EpisodeItemView.swift b/JellyfinPlayer/EpisodeItemView.swift index ba501beb..be010605 100644 --- a/JellyfinPlayer/EpisodeItemView.swift +++ b/JellyfinPlayer/EpisodeItemView.swift @@ -15,6 +15,7 @@ struct EpisodeItemView: View { @EnvironmentObject var globalData: GlobalData @State private var isLoading: Bool = true; var item: ResumeItem; + @EnvironmentObject var orientationInfo: OrientationInfo var fullItem: DetailItem; @State private var playing: Bool = false; @State private var vc: PreferenceUIHostingController? = nil; @@ -211,7 +212,7 @@ struct EpisodeItemView: View { LoadingView(isShowing: $isLoading) { VStack(alignment:.leading) { if(!isLoading) { - if(isPortrait) { + if(orientationInfo.orientation == .portrait) { GeometryReader { geometry in VStack() { WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.ParentBackdropItemId)/Images/Backdrop?maxWidth=450&quality=90&tag=\(fullItem.Backdrop)")!) diff --git a/JellyfinPlayer/JellyfinPlayerApp.swift b/JellyfinPlayer/JellyfinPlayerApp.swift index 77cab410..cddc3935 100644 --- a/JellyfinPlayer/JellyfinPlayerApp.swift +++ b/JellyfinPlayer/JellyfinPlayerApp.swift @@ -11,6 +11,46 @@ class justSignedIn: ObservableObject { @Published var did: Bool = false } +class OrientationInfo: ObservableObject { + enum Orientation { + case portrait + case landscape + } + + @Published var orientation: Orientation + + private var _observer: NSObjectProtocol? + + init() { + // fairly arbitrary starting value for 'flat' orientations + if UIDevice.current.orientation.isLandscape { + self.orientation = .landscape + } + else { + self.orientation = .portrait + } + + // unowned self because we unregister before self becomes invalid + _observer = NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { [unowned self] note in + guard let device = note.object as? UIDevice else { + return + } + if device.orientation.isPortrait { + self.orientation = .portrait + } + else if device.orientation.isLandscape { + self.orientation = .landscape + } + } + } + + deinit { + if let observer = _observer { + NotificationCenter.default.removeObserver(observer) + } + } +} + @main struct JellyfinPlayerApp: App { let persistenceController = PersistenceController.shared @@ -20,10 +60,11 @@ struct JellyfinPlayerApp: App { WindowGroup { ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) + .environmentObject(OrientationInfo()) .environmentObject(jsi) .withHostingWindow() { window in window?.rootViewController = PreferenceUIHostingController(wrappedView: ContentView().environment(\.managedObjectContext, persistenceController.container.viewContext) - .environmentObject(jsi)) + .environmentObject(jsi).environmentObject(OrientationInfo())) } } } diff --git a/JellyfinPlayer/MovieItemView.swift b/JellyfinPlayer/MovieItemView.swift index cd897181..f0ecd5f1 100644 --- a/JellyfinPlayer/MovieItemView.swift +++ b/JellyfinPlayer/MovieItemView.swift @@ -62,6 +62,7 @@ class CastMember: ObservableObject { struct MovieItemView: View { @EnvironmentObject var globalData: GlobalData + @EnvironmentObject var orientationInfo: OrientationInfo @State private var isLoading: Bool = true; var item: ResumeItem; var fullItem: DetailItem; @@ -258,7 +259,7 @@ struct MovieItemView: View { LoadingView(isShowing: $isLoading) { VStack(alignment:.leading) { if(!isLoading) { - if(isPortrait) { + if(orientationInfo.orientation == .portrait) { GeometryReader { geometry in VStack() { WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.Id)/Images/Backdrop?maxWidth=450&quality=90&tag=\(fullItem.Backdrop)")!) diff --git a/JellyfinPlayer/SeasonItemView.swift b/JellyfinPlayer/SeasonItemView.swift index 10cbcdfb..e6fe3b30 100644 --- a/JellyfinPlayer/SeasonItemView.swift +++ b/JellyfinPlayer/SeasonItemView.swift @@ -13,6 +13,7 @@ import SDWebImageSwiftUI struct SeasonItemView: View { @EnvironmentObject var globalData: GlobalData + @EnvironmentObject var orientationInfo: OrientationInfo @State private var isLoading: Bool = true; var item: ResumeItem; var fullItem: DetailItem; @@ -185,7 +186,7 @@ struct SeasonItemView: View { LoadingView(isShowing: $isLoading) { VStack(alignment:.leading) { if(!isLoading) { - if(isPortrait) { + if(orientationInfo.orientation == .portrait) { GeometryReader { geometry in VStack() { WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.SeriesId ?? "")/Images/Backdrop?maxWidth=750&quality=80&tag=\(item.SeasonImage ?? "")")!) diff --git a/Release Notes.rtf b/Release Notes.rtf index 0db3bb8e..22077e93 100644 --- a/Release Notes.rtf +++ b/Release Notes.rtf @@ -3,8 +3,9 @@ {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} -{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid101\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} -{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} +{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid101\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2} +{\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid201\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid3}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}} \margl1440\margr1440\vieww11520\viewh8400\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 @@ -28,4 +29,13 @@ \pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\pardirnatural\partightenfactor0 \ls2\ilvl0\cf0 {\listtext \uc0\u8259 }Squashed some commits in the repo as sensitive tokens were exposed for Sentry & Dynatrace\ {\listtext \uc0\u8259 }Also adds Fastlane\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 +\cf0 \ +\ + +\f0\b\fs26 1.0.0 (Build: 9)\ +\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\pardirnatural\partightenfactor0 +\ls3\ilvl0\cf0 {\listtext \uc0\u8259 } +\f1\b0 Fixed pointer dereferencing error in ContinueWatchingView:67 +\f0\b \ } \ No newline at end of file