Fix login bug, remove empty homescreen, add landscape MovieItemView

This commit is contained in:
Aiden Vigue 2021-05-20 19:43:44 -04:00
parent ee0f46576e
commit 63f7264902
6 changed files with 488 additions and 275 deletions

View File

@ -11,6 +11,7 @@ import SwiftyRequest
import SwiftyJSON
import CoreData
import KeychainSwift
import Introspect
struct ConnectToServerView: View {
@Environment(\.managedObjectContext) private var viewContext
@ -193,5 +194,8 @@ struct ConnectToServerView: View {
}
.onAppear(perform: start)
.transition(.move(edge:.bottom))
.introspectTabBarController { (UITabBarController) in
UITabBarController.tabBar.isHidden = true
}
}
}

View File

@ -9,6 +9,7 @@ import SwiftUI
import KeychainSwift
import SwiftyRequest
import SwiftyJSON
import Introspect
class GlobalData: ObservableObject {
@Published var user: SignedInUser?
@ -134,9 +135,6 @@ class PreferenceUIHostingController: UIHostingController<AnyView> {
if(_orientations == .landscapeRight) {
let value = UIInterfaceOrientation.landscapeRight.rawValue;
UIDevice.current.setValue(value, forKey: "orientation")
} else {
let value = UIInterfaceOrientation.portrait.rawValue;
UIDevice.current.setValue(value, forKey: "orientation")
}
}
};
@ -186,6 +184,7 @@ struct ContentView: View {
@State private var library_names: [String: String] = [:];
@State private var librariesShowRecentlyAdded: [String] = [];
@State private var libraryPrefillID: String = "";
@State private var showSettingsPopover: Bool = false;
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
@ -309,12 +308,12 @@ struct ContentView: View {
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button {
print("Settings tapped!")
showSettingsPopover = true;
} label: {
Image(systemName: "gear")
}
}
}
}.popover( isPresented: self.$showSettingsPopover, arrowEdge: .bottom) { SettingsView(close: $showSettingsPopover).environmentObject(self.globalData) }
}
.tabItem({
Text("Home")
@ -337,14 +336,15 @@ struct ContentView: View {
.navigationViewStyle(StackNavigationViewStyle())
.alert(isPresented: $isNetworkErrored) {
Alert(title: Text("Network Error"), message: Text("Couldn't connect to Jellyfin"), dismissButton: .default(Text("Ok")))
}.introspectTabBarController { (UITabBarController) in
UITabBarController.tabBar.isHidden = false
}
} else {
Text("Signing in...")
.onAppear(perform: {
DispatchQueue.global(qos: .userInitiated).async { [self] in
print("Signing in")
sleep(3)
jsi.did = false
usleep(500000);
self.jsi.did = false;
}
})
}

View File

@ -75,6 +75,7 @@ struct ContinueWatchingView: View {
}
var body: some View {
if(resumeItems.count != 0) {
VStack(alignment: .leading) {
ScrollView(.horizontal, showsIndicators: false) {
HStack() {
@ -146,8 +147,13 @@ struct ContinueWatchingView: View {
}
.frame(height: 200)
.padding(.bottom, 10)
}
} else {
VStack() {
EmptyView()
}.onAppear(perform: onAppear)
}
}
}
struct ContinueWatchingView_Previews: PreviewProvider {

View File

@ -240,6 +240,14 @@ struct MovieItemView: View {
}
}
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
var isPortrait: Bool {
let result = verticalSizeClass == .regular && horizontalSizeClass == .compact
return result
}
var body: some View {
if(playing) {
PlayerDemo(item: fullItem, playing: $playing).onAppear(perform: lockOrientations)
@ -247,6 +255,7 @@ struct MovieItemView: View {
LoadingView(isShowing: $isLoading) {
VStack(alignment:.leading) {
if(!isLoading) {
if(isPortrait) {
GeometryReader { geometry in
VStack() {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.Id)/Images/Backdrop?maxWidth=3840&quality=90&tag=\(fullItem.Backdrop)")!)
@ -258,8 +267,8 @@ struct MovieItemView: View {
}
.opacity(0.4)
.frame(width: geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing, height: (geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing) * 0.5625)
.aspectRatio(contentMode: .fill)
.frame(width: geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing, height: (geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing) * 0.5625)
.shadow(radius: 5)
.overlay(
HStack() {
@ -428,10 +437,193 @@ struct MovieItemView: View {
}.padding(EdgeInsets(top: 24, leading: 0, bottom: 0, trailing: 0))
}
}
} else {
GeometryReader { geometry in
ZStack() {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.Id)/Images/Backdrop?maxWidth=3840&quality=90&tag=\(fullItem.Backdrop)")!)
.resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
.placeholder {
Image(uiImage: UIImage(blurHash: (fullItem.BackdropBlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : fullItem.BackdropBlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing, height: (geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing) * 0.5625)
}
.opacity(0.4)
.aspectRatio(contentMode: .fill)
.frame(width: geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing, height: (geometry.size.width + geometry.safeAreaInsets.leading + geometry.safeAreaInsets.trailing) * 0.5625)
.edgesIgnoringSafeArea(.all)
HStack() {
VStack() {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(fullItem.Id)/Images/Primary?maxWidth=300&quality=90&tag=\(fullItem.Poster)")!)
.resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
.placeholder {
Image(uiImage: UIImage(blurHash: (fullItem.PosterBlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : fullItem.PosterBlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 120, height: 180)
}
.frame(width: 120, height: 180)
.cornerRadius(10)
.shadow(radius: 5)
Spacer().frame(height: 15)
Button() {
playing = true;
} label: {
HStack() {
Text(fullItem.Progress == 0 ? "Play" : "\(progressString) left").foregroundColor(Color.white).font(.callout).fontWeight(.semibold)
Image(systemName: "play.fill").foregroundColor(Color.white).font(.system(size: 20))
}
.frame(width: 120, height: 35)
.background(Color(UIColor.systemBlue))
.cornerRadius(10)
}.buttonStyle(PlainButtonStyle())
.frame(width: 120, height: 25)
Spacer()
}
ScrollView() {
VStack(alignment: .leading) {
HStack() {
VStack(alignment: .leading) {
Text(fullItem.Name).font(.headline)
.fontWeight(.semibold)
.foregroundColor(.primary)
.fixedSize(horizontal: false, vertical: true)
.offset(x: 11, y: 0)
Spacer().frame(height: 1)
HStack() {
Text(String(fullItem.ProductionYear)).font(.subheadline)
.fontWeight(.medium)
.foregroundColor(.secondary)
.lineLimit(1)
Text(fullItem.Runtime).font(.subheadline)
.fontWeight(.medium)
.foregroundColor(.secondary)
.lineLimit(1)
if(fullItem.OfficialRating != "") {
Text(fullItem.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(fullItem.CommunityRating != "") {
HStack() {
Image(systemName: "star").foregroundColor(.secondary)
Text(fullItem.CommunityRating).font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(.secondary)
.lineLimit(1)
.offset(x: -7, y: 0.7)
}
}
Spacer()
}.frame(maxWidth: .infinity)
.offset(x: 11)
}.frame(maxWidth: .infinity)
Spacer()
HStack() {
Button() {
favorite.toggle()
} label: {
if(!favorite) {
Image(systemName: "heart").foregroundColor(Color.primary).font(.system(size: 20))
} else {
Image(systemName: "heart.fill").foregroundColor(Color(UIColor.systemRed)).font(.system(size: 20))
}
}
Button() {
watched.toggle()
} label: {
if(watched) {
Image(systemName: "checkmark.rectangle.fill").foregroundColor(Color.primary).font(.system(size: 20))
} else {
Image(systemName: "xmark.rectangle").foregroundColor(Color.primary).font(.system(size: 20))
}
}
}
}
if(fullItem.Tagline != "") {
Text(fullItem.Tagline).font(.body).italic().padding(.top, 3).fixedSize(horizontal: false, vertical: true).padding(.leading, 16).padding(.trailing,16)
}
Text(fullItem.Overview).font(.footnote).padding(.top, 3).fixedSize(horizontal: false, vertical: true).padding(.bottom, 3).padding(.leading, 16).padding(.trailing,16)
if(fullItem.Genres.count != 0) {
ScrollView(.horizontal, showsIndicators: false) {
HStack() {
Text("Genres:").font(.callout).fontWeight(.semibold)
ForEach(fullItem.Genres, id: \.Id) {genre in
NavigationLink(destination: LibraryView(extraParams: "&Genres=\(genre.Name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")", title: genre.Name)) {
Text(genre.Name).font(.footnote)
}
}
}.padding(.leading, 16).padding(.trailing,16)
}
}
if(fullItem.Cast.count != 0) {
ScrollView(.horizontal, showsIndicators: false) {
VStack() {
Spacer().frame(height: 8);
HStack() {
Spacer().frame(width: 16)
ForEach(fullItem.Cast, id: \.Id) { cast in
NavigationLink(destination: LibraryView(extraParams: "&PersonIds=\(cast.Id)", title: cast.Name)) {
VStack() {
WebImage(url: cast.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: (cast.ImageBlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : cast.ImageBlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.cornerRadius(10)
}
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.cornerRadius(10).shadow(radius: 6)
Text(cast.Name).font(.footnote).fontWeight(.regular).lineLimit(1).frame(width: 100).foregroundColor(Color.primary)
if(cast.Role != "") {
Text(cast.Role).font(.caption).fontWeight(.medium).lineLimit(1).foregroundColor(Color.secondary).frame(width: 100)
}
}
}
Spacer().frame(width: 10)
}
Spacer().frame(width: 16)
}
}
}.padding(.top, -3)
}
if(fullItem.Directors.count != 0) {
HStack() {
Text("Directors:").font(.callout).fontWeight(.semibold)
Text(fullItem.Directors.joined(separator: ", ")).font(.footnote).lineLimit(1).foregroundColor(Color.secondary)
}.padding(.leading, 16).padding(.trailing,16)
}
if(fullItem.Writers.count != 0) {
HStack() {
Text("Writers:").font(.callout).fontWeight(.semibold)
Text(fullItem.Writers.joined(separator: ", ")).font(.footnote).lineLimit(1).foregroundColor(Color.secondary)
}.padding(.leading, 16).padding(.trailing,16)
}
if(fullItem.Studios.count != 0) {
HStack() {
Text("Studios:").font(.callout).fontWeight(.semibold)
Text(fullItem.Studios.joined(separator: ", ")).font(.footnote).lineLimit(1).foregroundColor(Color.secondary)
}.padding(.leading, 16).padding(.trailing,16)
}
Spacer().frame(height: 195);
}.frame(maxHeight: .infinity)
}.padding(.trailing, 55)
}.padding(.top, 12)
}
}
}
}
}
.navigationBarTitleDisplayMode(.inline)
.navigationTitle("Movie Details")
.navigationTitle(fullItem.Name)
.supportedOrientations(.allButUpsideDown)
.prefersHomeIndicatorAutoHidden(false)
.withHostingWindow() { window in

View File

@ -69,6 +69,7 @@ struct NextUpView: View {
var body: some View {
VStack(alignment: .leading) {
if(resumeItems.count != 0) {
Text("Next Up").font(.title2).fontWeight(.bold).padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
ScrollView(.horizontal, showsIndicators: false) {
HStack() {
@ -109,6 +110,7 @@ struct NextUpView: View {
}
}
}.padding(EdgeInsets(top: -2, leading: 0, bottom: 0, trailing: 0))
}
}.onAppear(perform: onAppear).padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}

View File

@ -8,13 +8,22 @@
import SwiftUI
struct SettingsView: View {
@Binding var close: Bool;
var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
NavigationView() {
Text("SettingsView not implemented.")
.navigationBarTitle("Settings", displayMode: .inline)
.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
Button {
close = false
} label: {
HStack() {
Text("Back").font(.callout)
}
}
}
}
}
}
}