Build 8 (1.0.0)
This commit is contained in:
parent
b49f796a72
commit
ca61e0dd4c
|
@ -188,6 +188,7 @@ struct ContentView: View {
|
|||
@State private var librariesShowRecentlyAdded: [String] = [];
|
||||
@State private var libraryPrefillID: String = "";
|
||||
@State private var showSettingsPopover: Bool = false;
|
||||
@State private var viewDidLoad: Bool = false;
|
||||
|
||||
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
|
||||
|
@ -198,6 +199,10 @@ struct ContentView: View {
|
|||
}
|
||||
|
||||
func startup() {
|
||||
if(_viewDidLoad.wrappedValue) {
|
||||
return
|
||||
}
|
||||
_viewDidLoad.wrappedValue = true;
|
||||
SentrySDK.start { options in
|
||||
options.dsn = "https://75ac77d6af4d406eb989f3d8ef0f119f@o513670.ingest.sentry.io/5778242"
|
||||
options.debug = false // Enabled debug when first installing is always helpful
|
||||
|
@ -274,6 +279,18 @@ struct ContentView: View {
|
|||
_librariesShowRecentlyAdded.wrappedValue = _libraries.wrappedValue.filter { element in
|
||||
return !array2.contains(element)
|
||||
}
|
||||
|
||||
_libraries.wrappedValue.forEach { library in
|
||||
if(_library_names.wrappedValue[library] == nil) {
|
||||
_libraries.wrappedValue.removeAll { ele in
|
||||
if(library == ele) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
@ -301,84 +318,95 @@ struct ContentView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
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))
|
||||
if(needsToSelectServer) {
|
||||
NavigationView() {
|
||||
ConnectToServerView(isActive: $needsToSelectServer)
|
||||
}
|
||||
} else if(isSignInErrored) {
|
||||
NavigationView() {
|
||||
ConnectToServerView(skip_server: true, skip_server_prefill: globalData.server, reauth_deviceId: globalData.user?.device_uuid ?? "", isActive: $isSignInErrored)
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
showSettingsPopover = true;
|
||||
} label: {
|
||||
Image(systemName: "gear")
|
||||
.navigationTitle("Home")
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
showSettingsPopover = true;
|
||||
} label: {
|
||||
Image(systemName: "gear")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.popover( isPresented: self.$showSettingsPopover, arrowEdge: .bottom) { SettingsView(close: $showSettingsPopover).environmentObject(self.globalData) }
|
||||
}
|
||||
.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")
|
||||
|
||||
}.edgesIgnoringSafeArea(isPortrait ? [] : [.leading,.trailing])
|
||||
}.environmentObject(globalData)
|
||||
.edgesIgnoringSafeArea(isPortrait ? [] : [.leading,.trailing])
|
||||
.onAppear(perform: startup)
|
||||
.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.main.async { [self] in
|
||||
usleep(500000);
|
||||
self.jsi.did = false;
|
||||
}.popover( isPresented: self.$showSettingsPopover, arrowEdge: .bottom) { SettingsView(close: $showSettingsPopover).environmentObject(self.globalData) }
|
||||
}
|
||||
.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")
|
||||
|
||||
}.edgesIgnoringSafeArea(isPortrait ? [] : [.leading,.trailing])
|
||||
}.environmentObject(globalData)
|
||||
.edgesIgnoringSafeArea(isPortrait ? [] : [.leading,.trailing])
|
||||
.onAppear(perform: startup)
|
||||
.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.main.async { [self] in
|
||||
_viewDidLoad.wrappedValue = false
|
||||
usleep(500000);
|
||||
self.jsi.did = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,30 @@ import SwiftyRequest
|
|||
import SwiftyJSON
|
||||
import SDWebImageSwiftUI
|
||||
|
||||
struct CustomShape: Shape {
|
||||
let radius: CGFloat
|
||||
|
||||
func path(in rect: CGRect) -> Path {
|
||||
var path = Path()
|
||||
|
||||
let tl = CGPoint(x: rect.minX, y: rect.minY)
|
||||
let tr = CGPoint(x: rect.maxX, y: rect.minY)
|
||||
let br = CGPoint(x: rect.maxX, y: rect.maxY)
|
||||
let bls = CGPoint(x: rect.minX + radius, y: rect.maxY)
|
||||
let blc = CGPoint(x: rect.minX + radius, y: rect.maxY - radius)
|
||||
|
||||
path.move(to: tl)
|
||||
path.addLine(to: tr)
|
||||
path.addLine(to: br)
|
||||
path.addLine(to: bls)
|
||||
path.addRelativeArc(center: blc, radius: radius,
|
||||
startAngle: Angle.degrees(90), delta: Angle.degrees(90))
|
||||
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ContinueWatchingView: View {
|
||||
@Environment(\.managedObjectContext) private var viewContext
|
||||
@EnvironmentObject var globalData: GlobalData
|
||||
|
@ -44,12 +68,18 @@ struct ContinueWatchingView: View {
|
|||
//portrait; use backdrop instead
|
||||
itemObj.Image = item["BackdropImageTags"][0].string ?? ""
|
||||
itemObj.ImageType = "Backdrop"
|
||||
|
||||
if(itemObj.Image == "") {
|
||||
itemObj.Image = item["ParentBackdropImageTags"][0].string ?? ""
|
||||
}
|
||||
|
||||
itemObj.BlurHash = item["ImageBlurHashes"]["Backdrop"][itemObj.Image].string ?? ""
|
||||
} else {
|
||||
itemObj.Image = item["ImageTags"]["Primary"].string ?? ""
|
||||
itemObj.ImageType = "Primary"
|
||||
itemObj.BlurHash = item["ImageBlurHashes"]["Primary"][itemObj.Image].string ?? ""
|
||||
}
|
||||
|
||||
itemObj.Name = item["Name"].string ?? ""
|
||||
itemObj.Type = item["Type"].string ?? ""
|
||||
itemObj.IndexNumber = item["IndexNumber"].int ?? nil
|
||||
|
@ -108,10 +138,11 @@ struct ContinueWatchingView: View {
|
|||
.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
|
||||
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 {
|
||||
|
@ -126,9 +157,10 @@ struct ContinueWatchingView: View {
|
|||
.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)
|
||||
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)
|
||||
|
@ -137,6 +169,8 @@ struct ContinueWatchingView: View {
|
|||
.font(.callout)
|
||||
.fontWeight(.semibold)
|
||||
.foregroundColor(.primary)
|
||||
.lineLimit(1)
|
||||
.frame(width: 320, alignment: .leading)
|
||||
Spacer().frame(height: 5)
|
||||
}.padding(.trailing, 5)
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ struct EpisodeItemView: View {
|
|||
.stroke(Color.secondary, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
if(fullItem.CommunityRating != "") {
|
||||
if(fullItem.CommunityRating != "0") {
|
||||
HStack() {
|
||||
Image(systemName: "star").foregroundColor(.secondary)
|
||||
Text(fullItem.CommunityRating).font(.subheadline)
|
||||
|
@ -275,9 +275,8 @@ struct EpisodeItemView: View {
|
|||
.offset(x: -7, y: 0.7)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}.offset(x: 0, y: -46).padding(.trailing, 16)
|
||||
}.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}.frame(maxWidth: .infinity, alignment: .leading).offset(x: 0, y: -46).padding(.trailing, 16)
|
||||
}.offset(x: 16, y: 40)
|
||||
, alignment: .bottomLeading)
|
||||
VStack(alignment: .leading) {
|
||||
|
@ -466,7 +465,7 @@ struct EpisodeItemView: View {
|
|||
.stroke(Color.secondary, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
if(fullItem.CommunityRating != "") {
|
||||
if(fullItem.CommunityRating != "0") {
|
||||
HStack() {
|
||||
Image(systemName: "star").foregroundColor(.secondary)
|
||||
Text(fullItem.CommunityRating).font(.subheadline)
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>7</string>
|
||||
<key>DTXApplicationID</key>
|
||||
<string>8c1f6941-ec78-480c-b589-b41aca29a52e</string>
|
||||
<key>DTXBeaconURL</key>
|
||||
<string>https://bf64941kgh.bf.dynatrace.com/mbeacon</string>
|
||||
<key>DTXStartupLoadBalancing</key>
|
||||
<true/>
|
||||
<key>DTXUserOptIn</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
@ -42,6 +50,8 @@
|
|||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
@ -53,17 +63,8 @@
|
|||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>DTXApplicationID</key>
|
||||
<string>8c1f6941-ec78-480c-b589-b41aca29a52e</string>
|
||||
<key>DTXBeaconURL</key>
|
||||
<string>https://bf64941kgh.bf.dynatrace.com/mbeacon</string>
|
||||
<key>DTXUserOptIn</key>
|
||||
<true/>
|
||||
<key>DTXStartupLoadBalancing</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -103,10 +103,17 @@ struct LatestMediaView: View {
|
|||
.cornerRadius(10)
|
||||
.overlay(
|
||||
ZStack {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
if(item.ItemBadge == 0) {
|
||||
Image(systemName: "checkmark")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
} else {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}.background(Color.black)
|
||||
.opacity(0.8)
|
||||
.cornerRadius(10.0)
|
||||
|
|
|
@ -34,6 +34,10 @@ struct LibraryFilterView: View {
|
|||
@Binding var close: Bool;
|
||||
|
||||
func onAppear() {
|
||||
if(_viewDidLoad.wrappedValue == true) {
|
||||
return
|
||||
}
|
||||
_viewDidLoad.wrappedValue = true;
|
||||
if(_output.wrappedValue.contains("&Filters=IsUnplayed")) {
|
||||
_onlyUnplayed.wrappedValue = true;
|
||||
}
|
||||
|
@ -55,10 +59,6 @@ struct LibraryFilterView: View {
|
|||
_sortOrder.wrappedValue = sortOrder;
|
||||
|
||||
recalculateFilters()
|
||||
if(_viewDidLoad.wrappedValue == true) {
|
||||
return
|
||||
}
|
||||
_viewDidLoad.wrappedValue = true;
|
||||
_allGenres.wrappedValue = []
|
||||
let url = "/Items/Filters?UserId=\(globalData.user?.user_id ?? "")&ParentId=\(library)"
|
||||
let request = RestRequest(method: .get, url: (globalData.server?.baseURI ?? "") + url)
|
||||
|
@ -98,6 +98,7 @@ struct LibraryFilterView: View {
|
|||
}
|
||||
|
||||
func recalculateFilters() {
|
||||
print("recalcFilters running");
|
||||
output = "";
|
||||
if(_onlyUnplayed.wrappedValue) {
|
||||
output = "&Filters=IsUnPlayed";
|
||||
|
|
|
@ -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.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
|
||||
let request = RestRequest(method: .get, url: (globalData.server?.baseURI ?? "") + _url.wrappedValue + "&searchTerm=" + searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + (_url.wrappedValue.contains("SortBy") ? "" : "&SortBy=Name&SortOrder=Descending"))
|
||||
request.headerParameters["X-Emby-Authorization"] = globalData.authHeader
|
||||
request.contentType = "application/json"
|
||||
request.acceptType = "application/json"
|
||||
|
@ -151,10 +151,17 @@ struct LibrarySearchView: View {
|
|||
.frame(width:100, height: 150)
|
||||
.cornerRadius(10).overlay(
|
||||
ZStack {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
if(item.ItemBadge == 0) {
|
||||
Image(systemName: "checkmark")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
} else {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}.background(Color.black)
|
||||
.opacity(0.8)
|
||||
.cornerRadius(10.0)
|
||||
|
|
|
@ -71,7 +71,7 @@ struct LibraryView: View {
|
|||
_library_names.wrappedValue["favorites"] = "Favorites"
|
||||
|
||||
_library_ids.wrappedValue.append("genres")
|
||||
_library_names.wrappedValue["genres"] = "Genres"
|
||||
_library_names.wrappedValue["genres"] = "Genres - WIP"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,10 +196,17 @@ struct LibraryView: View {
|
|||
.frame(width:100, height: 150)
|
||||
.cornerRadius(10).overlay(
|
||||
ZStack {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
if(item.ItemBadge == 0) {
|
||||
Image(systemName: "checkmark")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
} else {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}.background(Color.black)
|
||||
.opacity(0.8)
|
||||
.cornerRadius(10.0)
|
||||
|
|
|
@ -312,7 +312,7 @@ struct MovieItemView: View {
|
|||
.stroke(Color.secondary, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
if(fullItem.CommunityRating != "") {
|
||||
if(fullItem.CommunityRating != "0") {
|
||||
HStack() {
|
||||
Image(systemName: "star").foregroundColor(.secondary)
|
||||
Text(fullItem.CommunityRating).font(.subheadline)
|
||||
|
@ -322,8 +322,7 @@ struct MovieItemView: View {
|
|||
.offset(x: -7, y: 0.7)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}.offset(x: 0, y: -46).padding(.trailing, 16)
|
||||
}.offset(x: 16, y: 40)
|
||||
, alignment: .bottomLeading)
|
||||
|
@ -512,7 +511,7 @@ struct MovieItemView: View {
|
|||
.stroke(Color.secondary, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
if(fullItem.CommunityRating != "") {
|
||||
if(fullItem.CommunityRating != "0") {
|
||||
HStack() {
|
||||
Image(systemName: "star").foregroundColor(.secondary)
|
||||
Text(fullItem.CommunityRating).font(.subheadline)
|
||||
|
@ -523,9 +522,9 @@ struct MovieItemView: View {
|
|||
}
|
||||
}
|
||||
Spacer()
|
||||
}.frame(maxWidth: .infinity)
|
||||
}.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.offset(x: 14)
|
||||
}.frame(maxWidth: .infinity)
|
||||
}.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Spacer()
|
||||
HStack() {
|
||||
Button() {
|
||||
|
|
|
@ -218,10 +218,12 @@ struct SeasonItemView: View {
|
|||
.foregroundColor(.primary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.offset(y: -4)
|
||||
Text(String(fullItem.ProductionYear)).font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(.secondary)
|
||||
.lineLimit(1)
|
||||
if(fullItem.ProductionYear != 0) {
|
||||
Text(String(fullItem.ProductionYear)).font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(.secondary)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}.offset(x: 0, y: 45)
|
||||
}.offset(x: 16, y: 22)
|
||||
, alignment: .bottomLeading)
|
||||
|
@ -324,9 +326,11 @@ struct SeasonItemView: View {
|
|||
.frame(width: 120, height: 180)
|
||||
.cornerRadius(10)
|
||||
Spacer().frame(height: 4)
|
||||
Text(String(fullItem.ProductionYear)).font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(.secondary)
|
||||
if(fullItem.ProductionYear != 0) {
|
||||
Text(String(fullItem.ProductionYear)).font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
ScrollView() {
|
||||
|
|
|
@ -43,6 +43,11 @@ struct SeriesItemView: View {
|
|||
itemObj.ProductionYear = item["ProductionYear"].int ?? 0
|
||||
itemObj.ItemBadge = item["UserData"]["UnplayedItemCount"].int ?? 0
|
||||
itemObj.Image = item["ImageTags"]["Primary"].string ?? ""
|
||||
|
||||
if(itemObj.Image == "") {
|
||||
itemObj.Image = item["ParentBackdropImageTags"][0].string ?? ""
|
||||
}
|
||||
|
||||
itemObj.ImageType = "Primary"
|
||||
itemObj.SeasonImage = item["ParentBackdropImageTags"][0].string ?? ""
|
||||
itemObj.SeasonImageType = "Backdrop"
|
||||
|
@ -93,10 +98,17 @@ struct SeriesItemView: View {
|
|||
.cornerRadius(10)
|
||||
}.overlay(
|
||||
ZStack {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
if(item.ItemBadge == 0) {
|
||||
Image(systemName: "checkmark")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
} else {
|
||||
Text("\(String(item.ItemBadge ?? 0))")
|
||||
.font(.caption)
|
||||
.padding(3)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}.background(Color.black)
|
||||
.opacity(0.8)
|
||||
.cornerRadius(10.0)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf2580
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
|
||||
{\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}}
|
||||
\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
|
||||
\f0\b\fs26 \cf0 1.0.0 (Build: 8)
|
||||
\f1\b0\fs24 \
|
||||
\
|
||||
\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\pardirnatural\partightenfactor0
|
||||
\ls1\ilvl0\cf0 {\listtext \uc0\u8226 }Fix progress bar on ContinueWatchingView\
|
||||
{\listtext \uc0\u8226 }Sort search if no sorting active\
|
||||
{\listtext \uc0\u8226 }Limit text length on ContinueWatchingView\
|
||||
{\listtext \uc0\u8226 }Fix \'930\'94 for some production years on SeasonItemView\
|
||||
{\listtext \uc0\u8226 }Fix \'930\'94 for some CommunityRatings on EpisodeItemView & MovieItemView\
|
||||
{\listtext \uc0\u8226 }Fix placeholder image for some episodes on ContinueWatchingView\
|
||||
{\listtext \uc0\u8226 }Fix placeholder image for some seasons w/o their own images in SeriesItemView\
|
||||
{\listtext \uc0\u8226 }Show checkmarks instead of \'930\'94 on ItemBadges\
|
||||
{\listtext \uc0\u8226 }Fix having to click twice on selections in LibraryFilterView\
|
||||
{\listtext \uc0\u8226 }Fix bug where sign in page would disappear on orientation change or app relaunch\
|
||||
{\listtext \uc0\u8226 }Fix bug where some users would have access to libraries they were not supposed to see.\
|
||||
{\listtext \uc0\u8226 }Adds Dynatrace session tracking to try and find the cause for random crashes (app is FOOMing)\
|
||||
{\listtext \uc0\u8226 }Fix memory leak when viewing the main page multiple times\
|
||||
\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\
|
||||
}
|
Loading…
Reference in New Issue