diff --git a/Sora.xcodeproj/project.pbxproj b/Sora.xcodeproj/project.pbxproj index 3826f85..e88ee24 100644 --- a/Sora.xcodeproj/project.pbxproj +++ b/Sora.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 1399FAD42D3AB38C00E97C31 /* SettingsViewLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1399FAD32D3AB38C00E97C31 /* SettingsViewLogger.swift */; }; 1399FAD62D3AB3DB00E97C31 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1399FAD52D3AB3DB00E97C31 /* Logger.swift */; }; 13B7F4C12D58FFDD0045714A /* Shimmer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B7F4C02D58FFDD0045714A /* Shimmer.swift */; }; + 13CBEFDA2D5F7D1200D011EE /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CBEFD92D5F7D1200D011EE /* String.swift */; }; 13D842522D4523B800EBBFA6 /* Drops in Frameworks */ = {isa = PBXBuildFile; productRef = 13D842512D4523B800EBBFA6 /* Drops */; }; 13D842552D45267500EBBFA6 /* DropManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D842542D45267500EBBFA6 /* DropManager.swift */; }; 13D99CF72D4E73C300250A86 /* ModuleAdditionSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D99CF62D4E73C300250A86 /* ModuleAdditionSettingsView.swift */; }; @@ -83,6 +84,7 @@ 1399FAD32D3AB38C00E97C31 /* SettingsViewLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewLogger.swift; sourceTree = ""; }; 1399FAD52D3AB3DB00E97C31 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; 13B7F4C02D58FFDD0045714A /* Shimmer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shimmer.swift; sourceTree = ""; }; + 13CBEFD92D5F7D1200D011EE /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; 13D842542D45267500EBBFA6 /* DropManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropManager.swift; sourceTree = ""; }; 13D99CF62D4E73C300250A86 /* ModuleAdditionSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleAdditionSettingsView.swift; sourceTree = ""; }; 13DC0C412D2EC9BA00D0F966 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; @@ -246,6 +248,7 @@ isa = PBXGroup; children = ( 133D7C872D2BE2640075467E /* URLSession.swift */, + 13CBEFD92D5F7D1200D011EE /* String.swift */, 13103E8A2D58E028000F0673 /* View.swift */, ); path = Extensions; @@ -447,6 +450,7 @@ 13B7F4C12D58FFDD0045714A /* Shimmer.swift in Sources */, 139935662D468C450065CEFF /* ModuleManager.swift in Sources */, 133D7C902D2BE2640075467E /* SettingsView.swift in Sources */, + 13CBEFDA2D5F7D1200D011EE /* String.swift in Sources */, 130C6BFA2D53AB1F00DC1432 /* SettingsViewData.swift in Sources */, 13EA2BD72D32D97400C1EBD7 /* MusicProgressSlider.swift in Sources */, 1E9FF1D32D403E49008AC100 /* SettingsViewLoggerFilter.swift in Sources */, diff --git a/Sora/Tracking Services/AniList/HomePage/DetailsView/AniList-DetailsView.swift b/Sora/Tracking Services/AniList/HomePage/DetailsView/AniList-DetailsView.swift index 87e06e0..3b4d8d1 100644 --- a/Sora/Tracking Services/AniList/HomePage/DetailsView/AniList-DetailsView.swift +++ b/Sora/Tracking Services/AniList/HomePage/DetailsView/AniList-DetailsView.swift @@ -8,18 +8,6 @@ import SwiftUI import Kingfisher -extension String { - var strippedHTML: String { - guard let data = self.data(using: .utf8) else { return self } - let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [ - .documentType: NSAttributedString.DocumentType.html, - .characterEncoding: String.Encoding.utf8.rawValue - ] - let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) - return attributedString?.string ?? self - } -} - struct MediaDetailItem: View { var title: String var value: String @@ -48,7 +36,7 @@ struct AniListDetailsView: View { ProgressView() .padding() } else if let media = mediaInfo { - HStack(alignment: .bottom) { + HStack(alignment: .bottom, spacing: 16) { if let coverDict = media["coverImage"] as? [String: Any], let posterURLString = coverDict["extraLarge"] as? String, let posterURL = URL(string: posterURLString) { @@ -65,12 +53,15 @@ struct AniListDetailsView: View { .frame(width: 150, height: 225) } - if let titleDict = media["title"] as? [String: Any], - let userPreferred = titleDict["userPreferred"] as? String { - Text(userPreferred) - .font(.title3) - .fontWeight(.bold) + VStack(alignment: .leading) { + if let titleDict = media["title"] as? [String: Any], + let userPreferred = titleDict["userPreferred"] as? String { + Text(userPreferred) + .font(.headline) + } } + + Spacer() } .padding() @@ -120,19 +111,6 @@ struct AniListDetailsView: View { Divider() - if let trailer = media["trailer"] as? [String: Any], - let trailerID = trailer["id"] as? String, - let site = trailer["site"] as? String { - if site.lowercased() == "youtube", - let url = URL(string: "https://www.youtube.com/watch?v=\(trailerID)") { - Link("Watch Trailer on YouTube", destination: url) - .padding(.top, 4) - } else { - Text("Trailer available on \(site)") - .padding(.top, 4) - } - } - if let synopsis = media["description"] as? String { Text(synopsis.strippedHTML) .padding(.horizontal) diff --git a/Sora/Utils/Extensions/String.swift b/Sora/Utils/Extensions/String.swift new file mode 100644 index 0000000..660329a --- /dev/null +++ b/Sora/Utils/Extensions/String.swift @@ -0,0 +1,20 @@ +// +// String.swift +// Sora +// +// Created by Francesco on 14/02/25. +// + +import Foundation + +extension String { + var strippedHTML: String { + guard let data = self.data(using: .utf8) else { return self } + let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [ + .documentType: NSAttributedString.DocumentType.html, + .characterEncoding: String.Encoding.utf8.rawValue + ] + let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) + return attributedString?.string ?? self + } +} diff --git a/Sora/Views/LibraryView/LibraryView.swift b/Sora/Views/LibraryView/LibraryView.swift index 83f88c5..cc56534 100644 --- a/Sora/Views/LibraryView/LibraryView.swift +++ b/Sora/Views/LibraryView/LibraryView.swift @@ -40,12 +40,24 @@ struct LibraryView: View { VStack { ZStack(alignment: .bottomTrailing) { KFImage(URL(string: item.imageUrl)) + .placeholder { + RoundedRectangle(cornerRadius: 10) + .fill(Color.gray.opacity(0.3)) + .frame(width: 150, height: 225) + .shimmering() + } .resizable() .aspectRatio(2/3, contentMode: .fill) .cornerRadius(10) .frame(width: 150, height: 225) KFImage(URL(string: module.metadata.iconUrl)) + .placeholder { + Circle() + .fill(Color.gray.opacity(0.3)) + .frame(width: 35, height: 35) + .shimmering() + } .resizable() .aspectRatio(contentMode: .fit) .frame(width: 35, height: 35) diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index 0da3932..f8bd419 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -55,6 +55,12 @@ struct MediaInfoView: View { VStack(alignment: .leading, spacing: 16) { HStack(alignment: .top, spacing: 10) { KFImage(URL(string: imageUrl)) + .placeholder { + RoundedRectangle(cornerRadius: 10) + .fill(Color.gray.opacity(0.3)) + .frame(width: 150, height: 225) + .shimmering() + } .resizable() .aspectRatio(2/3, contentMode: .fill) .cornerRadius(10)