diff --git a/JellyfinPlayer.xcodeproj/project.pbxproj b/JellyfinPlayer.xcodeproj/project.pbxproj
index b01de757..fa91c00a 100644
--- a/JellyfinPlayer.xcodeproj/project.pbxproj
+++ b/JellyfinPlayer.xcodeproj/project.pbxproj
@@ -420,7 +420,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = me.vigue.JellyfinPlayer;
+ MARKETING_VERSION = 0.1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -443,7 +444,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = me.vigue.JellyfinPlayer;
+ MARKETING_VERSION = 0.1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/JellyfinPlayer/.DS_Store b/JellyfinPlayer/.DS_Store
index aaedabfe..b238c67f 100644
Binary files a/JellyfinPlayer/.DS_Store and b/JellyfinPlayer/.DS_Store differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json
index 9221b9bb..6e0452d7 100644
--- a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,41 +1,49 @@
{
"images" : [
{
+ "filename" : "Icon-Spotlight-42.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
+ "filename" : "Icon-60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
+ "filename" : "Icon-Small@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
+ "filename" : "Icon-Small@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
+ "filename" : "Icon-Spotlight-40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
+ "filename" : "Icon-Spotlight-40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
+ "filename" : "Icon-60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
+ "filename" : "Icon-60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
@@ -46,46 +54,55 @@
"size" : "20x20"
},
{
+ "filename" : "Icon-Spotlight-41.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
+ "filename" : "Icon-Small.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
+ "filename" : "Icon-Small@2x-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
+ "filename" : "Icon-Spotlight-40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
+ "filename" : "Icon-Spotlight-40@2x-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
+ "filename" : "Icon-76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
+ "filename" : "Icon-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
+ "filename" : "Icon-iPadPro@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
+ "filename" : "Icon.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60.png
new file mode 100644
index 00000000..14d9f2b4
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
new file mode 100644
index 00000000..3b229423
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
new file mode 100644
index 00000000..7bd4a8e8
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76.png
new file mode 100644
index 00000000..e9f490d4
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
new file mode 100644
index 00000000..dfe42ead
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
new file mode 100644
index 00000000..69ebef93
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
new file mode 100644
index 00000000..e687a70a
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
new file mode 100644
index 00000000..e687a70a
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
new file mode 100644
index 00000000..bac10d91
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png
new file mode 100644
index 00000000..6b59325e
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png
new file mode 100644
index 00000000..ca49928d
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png
new file mode 100644
index 00000000..ca49928d
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png
new file mode 100644
index 00000000..8b8e7cc6
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-41.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-41.png
new file mode 100644
index 00000000..6b59325e
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-41.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-42.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-42.png
new file mode 100644
index 00000000..6b59325e
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-42.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png
new file mode 100644
index 00000000..b6cc054f
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png differ
diff --git a/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon.png b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon.png
new file mode 100644
index 00000000..a8b37858
Binary files /dev/null and b/JellyfinPlayer/Assets.xcassets/AppIcon.appiconset/Icon.png differ
diff --git a/JellyfinPlayer/ConnectToServerView.swift b/JellyfinPlayer/ConnectToServerView.swift
index ffd27d9c..86b8ec29 100644
--- a/JellyfinPlayer/ConnectToServerView.swift
+++ b/JellyfinPlayer/ConnectToServerView.swift
@@ -157,8 +157,8 @@ struct ConnectToServerView: View {
do {
try viewContext.save()
print("Saved to Core Data Store")
- jsi.did = true
_rootIsActive.wrappedValue = false
+ jsi.did = true
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
diff --git a/JellyfinPlayer/ContentView.swift b/JellyfinPlayer/ContentView.swift
index da54b118..e331670e 100644
--- a/JellyfinPlayer/ContentView.swift
+++ b/JellyfinPlayer/ContentView.swift
@@ -271,71 +271,82 @@ struct ContentView: View {
}
var body: some View {
- LoadingView(isShowing: $isLoading) {
- TabView(selection: $tabSelection) {
- NavigationView() {
- VStack {
- NavigationLink(destination: ConnectToServerView(isActive: $needsToSelectServer), isActive: $needsToSelectServer) {
- EmptyView()
- }.isDetailLink(false)
- NavigationLink(destination: ConnectToServerView(skip_server: true, skip_server_prefill: globalData.server, reauth_deviceId: globalData.user?.device_uuid ?? "", isActive: $isSignInErrored), isActive: $isSignInErrored) {
- EmptyView()
- }.isDetailLink(false)
- if(!needsToSelectServer && !isSignInErrored) {
- VStack(alignment: .leading) {
- ScrollView() {
- Spacer().frame(height: self.isPortrait ? 0 : 15)
- ContinueWatchingView()
- NextUpView().padding(EdgeInsets(top: 4, leading: 0, bottom: 0, trailing: 0))
- ForEach(librariesShowRecentlyAdded, id: \.self) { library_id in
- VStack(alignment: .leading) {
- HStack() {
- Text("Latest \(library_names[library_id] ?? "")").font(.title2).fontWeight(.bold).padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 16))
- Spacer()
- NavigationLink(destination: LibraryView(prefill: library_id, names: library_names, libraries: libraries, filter: "&SortBy=DateCreated&SortOrder=Descending")) {
- Text("See All").font(.subheadline).fontWeight(.bold)
- }
- }.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
- LatestMediaView(library: library_id)
- }.padding(EdgeInsets(top: 4, leading: 0, bottom: 0, trailing: 0))
+ if(!jsi.did) {
+ LoadingView(isShowing: $isLoading) {
+ TabView(selection: $tabSelection) {
+ NavigationView() {
+ VStack {
+ NavigationLink(destination: ConnectToServerView(isActive: $needsToSelectServer), isActive: $needsToSelectServer) {
+ EmptyView()
+ }.isDetailLink(false)
+ NavigationLink(destination: ConnectToServerView(skip_server: true, skip_server_prefill: globalData.server, reauth_deviceId: globalData.user?.device_uuid ?? "", isActive: $isSignInErrored), isActive: $isSignInErrored) {
+ EmptyView()
+ }.isDetailLink(false)
+ if(!needsToSelectServer && !isSignInErrored) {
+ VStack(alignment: .leading) {
+ ScrollView() {
+ Spacer().frame(height: self.isPortrait ? 0 : 15)
+ ContinueWatchingView()
+ NextUpView().padding(EdgeInsets(top: 4, leading: 0, bottom: 0, trailing: 0))
+ ForEach(librariesShowRecentlyAdded, id: \.self) { library_id in
+ VStack(alignment: .leading) {
+ HStack() {
+ Text("Latest \(library_names[library_id] ?? "")").font(.title2).fontWeight(.bold).padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 16))
+ Spacer()
+ NavigationLink(destination: LibraryView(prefill: library_id, names: library_names, libraries: libraries, filter: "&SortBy=DateCreated&SortOrder=Descending")) {
+ Text("See All").font(.subheadline).fontWeight(.bold)
+ }
+ }.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
+ LatestMediaView(library: library_id)
+ }.padding(EdgeInsets(top: 4, leading: 0, bottom: 0, trailing: 0))
+ }
+ Spacer().frame(height: 7)
}
- Spacer().frame(height: 7)
+ }
+ }
+ }
+ .navigationTitle("Home")
+ .toolbar {
+ ToolbarItemGroup(placement: .navigationBarTrailing) {
+ Button {
+ print("Settings tapped!")
+ } label: {
+ Image(systemName: "gear")
}
}
}
}
- .navigationTitle("Home")
- .toolbar {
- ToolbarItemGroup(placement: .navigationBarTrailing) {
- Button {
- print("Settings tapped!")
- } label: {
- Image(systemName: "gear")
- }
- }
+ .tabItem({
+ Text("Home")
+ Image(systemName: "house")
+ })
+ .tag("Home")
+ NavigationView() {
+ LibraryView(prefill: "", names: library_names, libraries: libraries)
+ .navigationTitle("Library")
}
+ .tabItem({
+ Text("All Media")
+ Image(systemName: "folder")
+ })
+ .tag("All Media")
+
}
- .tabItem({
- Text("Home")
- Image(systemName: "house")
- })
- .tag("Home")
- NavigationView() {
- LibraryView(prefill: "", names: library_names, libraries: libraries)
- .navigationTitle("Library")
- }
- .tabItem({
- Text("All Media")
- Image(systemName: "folder")
- })
- .tag("All Media")
-
+ }.environmentObject(globalData)
+ .onAppear(perform: startup)
+ .navigationViewStyle(StackNavigationViewStyle())
+ .alert(isPresented: $isNetworkErrored) {
+ Alert(title: Text("Network Error"), message: Text("Couldn't connect to Jellyfin"), dismissButton: .default(Text("Ok")))
}
- }.environmentObject(globalData)
- .onAppear(perform: startup)
- .navigationViewStyle(StackNavigationViewStyle())
- .alert(isPresented: $isNetworkErrored) {
- Alert(title: Text("Network Error"), message: Text("Couldn't connect to Jellyfin"), dismissButton: .default(Text("Ok")))
+ } else {
+ Text("Signing in...")
+ .onAppear(perform: {
+ DispatchQueue.global(qos: .userInitiated).async { [self] in
+ print("Signing in")
+ sleep(3)
+ jsi.did = false
+ }
+ })
}
}
}
diff --git a/JellyfinPlayer/ContinueWatchingView.swift b/JellyfinPlayer/ContinueWatchingView.swift
index 4c9dcc4b..a35abd09 100644
--- a/JellyfinPlayer/ContinueWatchingView.swift
+++ b/JellyfinPlayer/ContinueWatchingView.swift
@@ -81,62 +81,64 @@ struct ContinueWatchingView: View {
if(isLoading == false) {
Spacer().frame(width:16)
ForEach(resumeItems, id: \.Id) { item in
- VStack(alignment: .leading) {
- Spacer().frame(height: 10)
- if(item.Type == "Episode") {
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=560&fillHeight=315&quality=90&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: 32, height: 32))!)
- .resizable()
- .scaledToFit()
- .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(
- RoundedRectangle(cornerRadius: 10, style: .circular)
- .fill(Color(red: 172/255, green: 92/255, blue: 195/255).opacity(0.4))
- .frame(width: CGFloat((item.ItemProgress/100)*320), height: 180)
- .padding(0), alignment: .bottomLeading
- )
- .shadow(radius: 5)
- } else {
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=560&fillHeight=315&quality=90&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: 32, height: 32))!)
- .resizable()
- .scaledToFit()
- .cornerRadius(10)
- }
- .frame(width: 320, height: 180)
- .cornerRadius(10)
- .overlay(
- RoundedRectangle(cornerRadius: 10, style: .circular)
- .fill(Color(red: 172/255, green: 92/255, blue: 195/255).opacity(0.4))
- .frame(width: CGFloat((item.ItemProgress/100)*320), height: 180)
- .padding(0), alignment: .bottomLeading
- )
- .shadow(radius: 5)
- }
- Text("\(item.Type == "Episode" ? item.SeriesName ?? "" : item.Name)")
- .font(.callout)
- .fontWeight(.semibold)
- .foregroundColor(.primary)
- Spacer().frame(height: 5)
- }.padding(.trailing, 5)
+ 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)?fillWidth=560&fillHeight=315&quality=90&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: 32, height: 32))!)
+ .resizable()
+ .scaledToFit()
+ .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(
+ RoundedRectangle(cornerRadius: 10, style: .circular)
+ .fill(Color(red: 172/255, green: 92/255, blue: 195/255).opacity(0.4))
+ .frame(width: CGFloat((item.ItemProgress/100)*320), height: 180)
+ .padding(0), alignment: .bottomLeading
+ )
+ .shadow(radius: 5)
+ } else {
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=560&fillHeight=315&quality=90&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: 32, height: 32))!)
+ .resizable()
+ .scaledToFit()
+ .cornerRadius(10)
+ }
+ .frame(width: 320, height: 180)
+ .cornerRadius(10)
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .circular)
+ .fill(Color(red: 172/255, green: 92/255, blue: 195/255).opacity(0.4))
+ .frame(width: CGFloat((item.ItemProgress/100)*320), height: 180)
+ .padding(0), alignment: .bottomLeading
+ )
+ .shadow(radius: 5)
+ }
+ Text("\(item.Type == "Episode" ? item.SeriesName ?? "" : item.Name)")
+ .font(.callout)
+ .fontWeight(.semibold)
+ .foregroundColor(.primary)
+ Spacer().frame(height: 5)
+ }.padding(.trailing, 5)
+ }
}
Spacer().frame(width:14)
}
diff --git a/JellyfinPlayer/Info.plist b/JellyfinPlayer/Info.plist
index 1655e670..0ba1f6fa 100644
--- a/JellyfinPlayer/Info.plist
+++ b/JellyfinPlayer/Info.plist
@@ -5,7 +5,7 @@
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
- Jellyfin iOS
+ Jellyfin
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
@@ -17,7 +17,7 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 1.0
+ $(MARKETING_VERSION)
CFBundleVersion
1
LSRequiresIPhoneOS
diff --git a/JellyfinPlayer/JellyfinPlayerApp.swift b/JellyfinPlayer/JellyfinPlayerApp.swift
index 49292e08..77cab410 100644
--- a/JellyfinPlayer/JellyfinPlayerApp.swift
+++ b/JellyfinPlayer/JellyfinPlayerApp.swift
@@ -18,22 +18,13 @@ struct JellyfinPlayerApp: App {
var body: some Scene {
WindowGroup {
- if(!jsi.did) {
- ContentView()
- .environment(\.managedObjectContext, persistenceController.container.viewContext)
- .environmentObject(jsi)
- .withHostingWindow() { window in
- window?.rootViewController = PreferenceUIHostingController(wrappedView: ContentView().environment(\.managedObjectContext, persistenceController.container.viewContext)
- .environmentObject(jsi))
- }
- } else {
- Text("Please wait...")
- .onAppear(perform: {
- print("Signing in")
- sleep(1)
- jsi.did = false
- })
- }
+ ContentView()
+ .environment(\.managedObjectContext, persistenceController.container.viewContext)
+ .environmentObject(jsi)
+ .withHostingWindow() { window in
+ window?.rootViewController = PreferenceUIHostingController(wrappedView: ContentView().environment(\.managedObjectContext, persistenceController.container.viewContext)
+ .environmentObject(jsi))
+ }
}
}
}
diff --git a/JellyfinPlayer/LatestMediaView.swift b/JellyfinPlayer/LatestMediaView.swift
index ae932659..0cb0326c 100644
--- a/JellyfinPlayer/LatestMediaView.swift
+++ b/JellyfinPlayer/LatestMediaView.swift
@@ -87,51 +87,53 @@ struct LatestMediaView: View {
HStack() {
Spacer().frame(width:18)
ForEach(resumeItems, id: \.Id) { item in
- VStack(alignment: .leading) {
- if(item.Type == "Series") {
- Spacer().frame(height:10)
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
- .resizable()
- .scaledToFit()
- .cornerRadius(10)
- }
- .frame(width: 100, height: 150)
- .cornerRadius(10)
- .overlay(
- ZStack {
- Text("\(String(item.ItemBadge ?? 0))")
- .font(.caption)
- .padding(3)
- .foregroundColor(.white)
- }.background(Color.black)
- .opacity(0.8)
- .cornerRadius(10.0)
- .padding(3), alignment: .topTrailing
- ).shadow(radius: 6)
- } else {
- Spacer().frame(height:10)
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
- .resizable()
- .scaledToFit()
- .cornerRadius(10)
- }
- .frame(width: 100, height: 150)
- .cornerRadius(10)
- .shadow(radius: 6)
- }
- Text(item.Name)
- .font(.caption)
- .fontWeight(.semibold)
- .foregroundColor(.primary)
- .lineLimit(1)
- Spacer().frame(height:5)
- }.frame(width: 100)
+ NavigationLink(destination: ItemView(item: item)) {
+ VStack(alignment: .leading) {
+ if(item.Type == "Series") {
+ Spacer().frame(height:10)
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
+ .resizable()
+ .scaledToFit()
+ .cornerRadius(10)
+ }
+ .frame(width: 100, height: 150)
+ .cornerRadius(10)
+ .overlay(
+ ZStack {
+ Text("\(String(item.ItemBadge ?? 0))")
+ .font(.caption)
+ .padding(3)
+ .foregroundColor(.white)
+ }.background(Color.black)
+ .opacity(0.8)
+ .cornerRadius(10.0)
+ .padding(3), alignment: .topTrailing
+ ).shadow(radius: 6)
+ } else {
+ Spacer().frame(height:10)
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
+ .resizable()
+ .scaledToFit()
+ .cornerRadius(10)
+ }
+ .frame(width: 100, height: 150)
+ .cornerRadius(10)
+ .shadow(radius: 6)
+ }
+ Text(item.Name)
+ .font(.caption)
+ .fontWeight(.semibold)
+ .foregroundColor(.primary)
+ .lineLimit(1)
+ Spacer().frame(height:5)
+ }.frame(width: 100)
+ }
Spacer().frame(width: 14)
}
Spacer().frame(width:18)
diff --git a/JellyfinPlayer/LibrarySearchView.swift b/JellyfinPlayer/LibrarySearchView.swift
index 64bfa878..2dd62278 100644
--- a/JellyfinPlayer/LibrarySearchView.swift
+++ b/JellyfinPlayer/LibrarySearchView.swift
@@ -32,7 +32,7 @@ struct LibrarySearchView: View {
func onAppear() {
_isLoading.wrappedValue = true;
_items.wrappedValue = [];
- let request = RestRequest(method: .get, url: (globalData.server?.baseURI ?? "") + _url.wrappedValue + "&searchTerm=" + searchQuery)
+ let request = RestRequest(method: .get, url: (globalData.server?.baseURI ?? "") + _url.wrappedValue + "&searchTerm=" + searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
request.headerParameters["X-Emby-Authorization"] = globalData.authHeader
request.contentType = "application/json"
request.acceptType = "application/json"
diff --git a/JellyfinPlayer/LibraryView.swift b/JellyfinPlayer/LibraryView.swift
index d9e62712..181e64ba 100644
--- a/JellyfinPlayer/LibraryView.swift
+++ b/JellyfinPlayer/LibraryView.swift
@@ -274,9 +274,7 @@ struct LibraryView: View {
}.onAppear(perform: listOnAppear).overrideViewPreference(.unspecified).navigationTitle("All Media")
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
- Button {
- print("Search tapped!")
- } label: {
+ NavigationLink(destination: LibrarySearchView(url: "/Users/\(globalData.user?.user_id ?? "")/Items?Limit=60&StartIndex=0&Recursive=true&Fields=PrimaryImageAspectRatio%2CBasicSyncInfo&ImageTypeLimit=1&EnableImageTypes=Primary%2CBackdrop%2CThumb%2CBanner&IncludeItemTypes=Movie,Series\(extraParam)", close: $closeSearch), isActive: $closeSearch) {
Image(systemName: "magnifyingglass")
}
}
diff --git a/JellyfinPlayer/NextUpView.swift b/JellyfinPlayer/NextUpView.swift
index 70e50ae9..56b2d0e0 100644
--- a/JellyfinPlayer/NextUpView.swift
+++ b/JellyfinPlayer/NextUpView.swift
@@ -75,28 +75,35 @@ struct NextUpView: View {
if(isLoading == false) {
Spacer().frame(width:18)
ForEach(resumeItems, id: \.Id) { item in
- VStack(alignment: .leading) {
- Spacer().frame(height:10)
- WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.SeriesId ?? "")/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
- .resizable()
- .scaledToFit()
- .cornerRadius(10)
- }
- .frame(width: 100, height: 150)
- .cornerRadius(10)
- .shadow(radius: 6)
- Text(item.SeriesName ?? "")
- .font(.caption)
- .fontWeight(.semibold)
- .foregroundColor(.primary)
- .lineLimit(1)
- Spacer().frame(height:5)
+ NavigationLink(destination: ItemView(item: item)) {
+ VStack(alignment: .leading) {
+ Spacer().frame(height:10)
+ WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.SeriesId ?? "")/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&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: 32, height: 32))!)
+ .resizable()
+ .scaledToFit()
+ .cornerRadius(10)
+ }
+ .frame(width: 100, height: 150)
+ .cornerRadius(10)
+ .shadow(radius: 6)
+ Text(item.SeriesName ?? "")
+ .font(.caption)
+ .fontWeight(.semibold)
+ .foregroundColor(.primary)
+ .lineLimit(1)
+ Text("S\(String(item.ParentIndexNumber ?? 0))E\(String(item.IndexNumber ?? 0))")
+ .font(.caption)
+ .fontWeight(.semibold)
+ .foregroundColor(.secondary)
+ .lineLimit(1)
+ Spacer().frame(height:5)
+ }
+ .frame(width: 100)
+ Spacer().frame(width:12)
}
- .frame(width: 100)
- Spacer().frame(width:12)
}
Spacer().frame(width:18)
}
diff --git a/JellyfinPlayer/PlayerDemo.swift b/JellyfinPlayer/PlayerDemo.swift
index ef695656..e1bc9ae1 100644
--- a/JellyfinPlayer/PlayerDemo.swift
+++ b/JellyfinPlayer/PlayerDemo.swift
@@ -100,15 +100,13 @@ struct PlayerDemo: View {
_inactivity.wrappedValue = true
}
if((lastPosition == Double(vlcplayer.position) && vlcplayer.state != VLCMediaPlayerState.paused)) {
- if(iterations > 3) {
+ if(iterations > 5) {
_iterations.wrappedValue = 0;
_streamLoading.wrappedValue = true;
- print("Buffering")
}
_iterations.wrappedValue+=1;
} else {
_iterations.wrappedValue = 0;
- print("Not Buffering")
_streamLoading.wrappedValue = false;
}
if(vlcplayer.state == VLCMediaPlayerState.error) {
@@ -204,7 +202,7 @@ struct PlayerDemo: View {
request.headerParameters["X-Emby-Authorization"] = globalData.authHeader
request.contentType = "application/json"
request.acceptType = "application/json"
- request.messageBody = "{\"DeviceProfile\":{\"MaxStreamingBitrate\":120000000,\"MaxStaticBitrate\":100000000,\"MusicStreamingTranscodingBitrate\":384000,\"DirectPlayProfiles\":[{\"Container\":\"webm\",\"Type\":\"Video\",\"VideoCodec\":\"vp8,vp9\",\"AudioCodec\":\"vorbis\"},{\"Container\":\"mp4,m4v,mkv\",\"Type\":\"Video\",\"VideoCodec\":\"hevc,h264,vp8,vp9\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis,dts\"},{\"Container\":\"mov\",\"Type\":\"Video\",\"VideoCodec\":\"h264\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis\"},{\"Container\":\"mp3\",\"Type\":\"Audio\"},{\"Container\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"flac\",\"Type\":\"Audio\"},{\"Container\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"webm\",\"AudioCodec\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"wav\",\"Type\":\"Audio\"}],\"TranscodingProfiles\":[{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"ts\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3\",\"VideoCodec\":\"h264\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"webm\",\"Type\":\"Video\",\"AudioCodec\":\"vorbis\",\"VideoCodec\":\"vpx\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp4\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis\",\"VideoCodec\":\"h264\",\"Context\":\"Static\",\"Protocol\":\"http\"}],\"ContainerProfiles\":[],\"CodecProfiles\":[{\"Type\":\"Video\",\"Codec\":\"h264\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"high|main|baseline|constrained baseline\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"80\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]},{\"Type\":\"Video\",\"Codec\":\"hevc\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"main|main 10\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"190\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]}],\"SubtitleProfiles\":[{\"Format\":\"vtt\",\"Method\":\"External\"},{\"Format\":\"ass\",\"Method\":\"External\"},{\"Format\":\"ssa\",\"Method\":\"External\"}],\"ResponseProfiles\":[{\"Type\":\"Video\",\"Container\":\"m4v\",\"MimeType\":\"video/mp4\"}]}}".data(using: .ascii);
+ request.messageBody = "{\"DeviceProfile\":{\"MaxStreamingBitrate\":70000000,\"MaxStaticBitrate\":150000000,\"MusicStreamingTranscodingBitrate\":384000,\"DirectPlayProfiles\":[{\"Container\":\"webm\",\"Type\":\"Video\",\"VideoCodec\":\"vp8,vp9\",\"AudioCodec\":\"vorbis\"},{\"Container\":\"mp4,m4v,mkv\",\"Type\":\"Video\",\"VideoCodec\":\"hevc,h264,vp8,vp9\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis,dts\"},{\"Container\":\"mov\",\"Type\":\"Video\",\"VideoCodec\":\"h264\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis\"},{\"Container\":\"mp3\",\"Type\":\"Audio\"},{\"Container\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"flac\",\"Type\":\"Audio\"},{\"Container\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"webm\",\"AudioCodec\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"wav\",\"Type\":\"Audio\"}],\"TranscodingProfiles\":[{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"ts\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3\",\"VideoCodec\":\"h264\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"webm\",\"Type\":\"Video\",\"AudioCodec\":\"vorbis\",\"VideoCodec\":\"vpx\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp4\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis\",\"VideoCodec\":\"h264\",\"Context\":\"Static\",\"Protocol\":\"http\"}],\"ContainerProfiles\":[],\"CodecProfiles\":[{\"Type\":\"Video\",\"Codec\":\"h264\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"high|main|baseline|constrained baseline\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"80\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]},{\"Type\":\"Video\",\"Codec\":\"hevc\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"main|main 10\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"190\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]}],\"SubtitleProfiles\":[{\"Format\":\"vtt\",\"Method\":\"External\"},{\"Format\":\"ass\",\"Method\":\"External\"},{\"Format\":\"ssa\",\"Method\":\"External\"},{\"Format\":\"pgssub\",\"Method\":\"Embed\"},{\"Format\":\"pgs\",\"Method\":\"Embed\"},{\"Format\":\"sub\",\"Method\":\"Embed\"}],\"ResponseProfiles\":[{\"Type\":\"Video\",\"Container\":\"m4v\",\"MimeType\":\"video/mp4\"}]}}".data(using: .ascii);
request.responseData() { (result: Result, RestError>) in
switch result {