From ad280b1a6b5d043497d16755a5e81c43bd56707c Mon Sep 17 00:00:00 2001 From: leminlimez Date: Tue, 15 Jul 2025 15:13:28 -0400 Subject: [PATCH] gif previews + handle apple wallpapers --- Pocket Poster.xcodeproj/project.pbxproj | 17 ++++++ .../xcshareddata/swiftpm/Package.resolved | 20 ++++++- Pocket Poster/API/DownloadableWallpaper.swift | 10 +++- .../Views/NavigatorViews/ExploreView.swift | 56 +++++++++++++------ 4 files changed, 82 insertions(+), 21 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index cc78c52..2ff02b4 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 6F09B7BB2DEB873F00CDE89C /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = 6F09B7BA2DEB873F00CDE89C /* ZIPFoundation */; }; 6F09BA332E00808300CDE89C /* Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 6F09BA322E00808300CDE89C /* Dynamic */; }; 6FB105552E26D3EC00185A5C /* CachedAsyncImage in Frameworks */ = {isa = PBXBuildFile; productRef = 6FB105542E26D3EC00185A5C /* CachedAsyncImage */; }; + 6FB105602E26DD0A00185A5C /* Giffy in Frameworks */ = {isa = PBXBuildFile; productRef = 6FB1055F2E26DD0A00185A5C /* Giffy */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -34,6 +35,7 @@ files = ( 6FB105552E26D3EC00185A5C /* CachedAsyncImage in Frameworks */, 6F09BA332E00808300CDE89C /* Dynamic in Frameworks */, + 6FB105602E26DD0A00185A5C /* Giffy in Frameworks */, 6F09B7BB2DEB873F00CDE89C /* ZIPFoundation in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -80,6 +82,7 @@ 6F09B7BA2DEB873F00CDE89C /* ZIPFoundation */, 6F09BA322E00808300CDE89C /* Dynamic */, 6FB105542E26D3EC00185A5C /* CachedAsyncImage */, + 6FB1055F2E26DD0A00185A5C /* Giffy */, ); productName = "Pocket Poster"; productReference = 6F09B79D2DEB694B00CDE89C /* Pocket Poster.app */; @@ -113,6 +116,7 @@ 6F09B7B92DEB873F00CDE89C /* XCRemoteSwiftPackageReference "ZIPFoundation" */, 6F09BA312E00808300CDE89C /* XCRemoteSwiftPackageReference "Dynamic" */, 6FB105532E26D3EC00185A5C /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */, + 6FB1055E2E26DD0A00185A5C /* XCRemoteSwiftPackageReference "Giffy" */, ); preferredProjectObjectVersion = 77; productRefGroup = 6F09B79E2DEB694B00CDE89C /* Products */; @@ -378,6 +382,14 @@ minimumVersion = 2.1.1; }; }; + 6FB1055E2E26DD0A00185A5C /* XCRemoteSwiftPackageReference "Giffy" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tfmart/Giffy.git"; + requirement = { + branch = main; + kind = branch; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -396,6 +408,11 @@ package = 6FB105532E26D3EC00185A5C /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */; productName = CachedAsyncImage; }; + 6FB1055F2E26DD0A00185A5C /* Giffy */ = { + isa = XCSwiftPackageProductDependency; + package = 6FB1055E2E26DD0A00185A5C /* XCRemoteSwiftPackageReference "Giffy" */; + productName = Giffy; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 6F09B7952DEB694B00CDE89C /* Project object */; diff --git a/Pocket Poster.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Pocket Poster.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8c6e3da..450dfbe 100644 --- a/Pocket Poster.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Pocket Poster.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "73a600cf677d3bb2b929c60349923a2a4e20e6a9ef10509bf043d2ad2229ca95", + "originHash" : "9d3a39dff9bda7be6921bb553210388e3a68059324656c0ace5f2eb2378819b1", "pins" : [ { "identity" : "dynamic", @@ -10,6 +10,24 @@ "version" : "1.2.0" } }, + { + "identity" : "flanimatedimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flipboard/FLAnimatedImage.git", + "state" : { + "revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f", + "version" : "1.0.17" + } + }, + { + "identity" : "giffy", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tfmart/Giffy.git", + "state" : { + "branch" : "main", + "revision" : "595bd0a0bc292d32da4b26b8bca4347235ab2556" + } + }, { "identity" : "swiftui-cached-async-image", "kind" : "remoteSourceControl", diff --git a/Pocket Poster/API/DownloadableWallpaper.swift b/Pocket Poster/API/DownloadableWallpaper.swift index 9b070ee..e6438d3 100644 --- a/Pocket Poster/API/DownloadableWallpaper.swift +++ b/Pocket Poster/API/DownloadableWallpaper.swift @@ -7,13 +7,13 @@ class DownloadableWallpaper: Identifiable, Codable { var name: String - var description: String + var description: String? var url: String var preview: String - var authors: String + var authors: String? var type: WallpaperType? - init(name: String, description: String, authors: String, preview: String, url: String, version: String) { + init(name: String, description: String?, authors: String?, preview: String, url: String, version: String) { self.name = name self.description = description self.authors = authors @@ -24,4 +24,8 @@ class DownloadableWallpaper: Identifiable, Codable { enum WallpaperType: String, Codable { case custom, apple, template } + + func previewIsGif() -> Bool { + return preview.hasSuffix(".gif") + } } diff --git a/Pocket Poster/Views/NavigatorViews/ExploreView.swift b/Pocket Poster/Views/NavigatorViews/ExploreView.swift index 4f4385d..04f879f 100644 --- a/Pocket Poster/Views/NavigatorViews/ExploreView.swift +++ b/Pocket Poster/Views/NavigatorViews/ExploreView.swift @@ -7,6 +7,7 @@ import SwiftUI import CachedAsyncImage +import Giffy let MIN_SIZE: CGFloat = 165 @@ -50,21 +51,40 @@ struct ExploreView: View { } else { LazyVGrid(columns: gridItemLayout) { ForEach(wallpapers) { wallpaper in - if searchTerm == "" || wallpaper.name.lowercased().contains(searchTerm.lowercased()) || wallpaper.authors.lowercased().contains(searchTerm.lowercased()) { + if searchTerm == "" || wallpaper.name.lowercased().contains(searchTerm.lowercased()) || (wallpaper.authors ?? "").lowercased().contains(searchTerm.lowercased()) { Button(action: { DownloadManager.shared.startTendiesDownload(for: cowabungaAPI.getDownloadURLForWallpaper(wallpaper: wallpaper)) }) { VStack(spacing: 0) { - CachedAsyncImage(url: cowabungaAPI.getPreviewURLForWallpaper(wallpaper: wallpaper), urlCache: .imageCache) { image in - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(maxWidth: .infinity) - .cornerRadius(10, corners: .topLeft) - .cornerRadius(10, corners: .topRight) - } placeholder: { - Color.gray - .frame(height: MIN_SIZE) + if wallpaper.previewIsGif() { + AsyncGiffy(url: cowabungaAPI.getPreviewURLForWallpaper(wallpaper: wallpaper)) { phase in + switch phase { + case .loading: + Color.gray + .frame(height: MIN_SIZE) + case .error: + Color.red + .frame(height: MIN_SIZE) + case .success(let giffy): + giffy + .aspectRatio(contentMode: .fill) + .frame(maxWidth: .infinity) + .cornerRadius(10, corners: .topLeft) + .cornerRadius(10, corners: .topRight) + } + } + } else { + CachedAsyncImage(url: cowabungaAPI.getPreviewURLForWallpaper(wallpaper: wallpaper), urlCache: .imageCache) { image in + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(maxWidth: .infinity) + .cornerRadius(10, corners: .topLeft) + .cornerRadius(10, corners: .topRight) + } placeholder: { + Color.gray + .frame(height: MIN_SIZE) + } } HStack { VStack(spacing: 4) { @@ -74,12 +94,14 @@ struct ExploreView: View { .minimumScaleFactor(0.5) Spacer() } - HStack { - Text(wallpaper.authors) - .foregroundColor(.secondary) - .font(.caption) - .minimumScaleFactor(0.5) - Spacer() + if let authors = wallpaper.authors { + HStack { + Text(authors) + .foregroundColor(.secondary) + .font(.caption) + .minimumScaleFactor(0.5) + Spacer() + } } } .lineLimit(1)