From 08619176ba01e7a8696983ff8022e67c3ddfaf71 Mon Sep 17 00:00:00 2001 From: cranci1 <100066266+cranci1@users.noreply.github.com> Date: Sun, 9 Feb 2025 14:11:30 +0100 Subject: [PATCH] uh ong bro im cooked --- Sora.xcodeproj/project.pbxproj | 16 ++++ Sora/Utils/Extensions/View.swift | 14 ++++ Sora/Utils/SkeletonCells/SkeletonCell.swift | 41 ++++++++++ Sora/Views/HomeView.swift | 28 +------ Sora/Views/SearchView.swift | 91 +++++++++++---------- 5 files changed, 123 insertions(+), 67 deletions(-) create mode 100644 Sora/Utils/Extensions/View.swift create mode 100644 Sora/Utils/SkeletonCells/SkeletonCell.swift diff --git a/Sora.xcodeproj/project.pbxproj b/Sora.xcodeproj/project.pbxproj index e9b65af..d9f722f 100644 --- a/Sora.xcodeproj/project.pbxproj +++ b/Sora.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 13103E842D589D8B000F0673 /* AniList-Seasonal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E832D589D8B000F0673 /* AniList-Seasonal.swift */; }; 13103E862D58A328000F0673 /* AniList-Trending.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E852D58A328000F0673 /* AniList-Trending.swift */; }; 13103E892D58A39A000F0673 /* AniListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E882D58A39A000F0673 /* AniListItem.swift */; }; + 13103E8B2D58E028000F0673 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E8A2D58E028000F0673 /* View.swift */; }; + 13103E8E2D58E04A000F0673 /* SkeletonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E8D2D58E04A000F0673 /* SkeletonCell.swift */; }; 131845F92D47C62D00CA7A54 /* SettingsViewGeneral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131845F82D47C62D00CA7A54 /* SettingsViewGeneral.swift */; }; 133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C6D2D2BE2500075467E /* SoraApp.swift */; }; 133D7C702D2BE2500075467E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C6F2D2BE2500075467E /* ContentView.swift */; }; @@ -51,6 +53,8 @@ 13103E832D589D8B000F0673 /* AniList-Seasonal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-Seasonal.swift"; sourceTree = ""; }; 13103E852D58A328000F0673 /* AniList-Trending.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-Trending.swift"; sourceTree = ""; }; 13103E882D58A39A000F0673 /* AniListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AniListItem.swift; sourceTree = ""; }; + 13103E8A2D58E028000F0673 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; }; + 13103E8D2D58E04A000F0673 /* SkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCell.swift; sourceTree = ""; }; 131845F82D47C62D00CA7A54 /* SettingsViewGeneral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewGeneral.swift; sourceTree = ""; }; 133D7C6A2D2BE2500075467E /* Sora.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sora.app; sourceTree = BUILT_PRODUCTS_DIR; }; 133D7C6D2D2BE2500075467E /* SoraApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoraApp.swift; sourceTree = ""; }; @@ -132,6 +136,14 @@ path = Struct; sourceTree = ""; }; + 13103E8C2D58E037000F0673 /* SkeletonCells */ = { + isa = PBXGroup; + children = ( + 13103E8D2D58E04A000F0673 /* SkeletonCell.swift */, + ); + path = SkeletonCells; + sourceTree = ""; + }; 133D7C612D2BE2500075467E = { isa = PBXGroup; children = ( @@ -209,6 +221,7 @@ 133D7C852D2BE2640075467E /* Utils */ = { isa = PBXGroup; children = ( + 13103E8C2D58E037000F0673 /* SkeletonCells */, 13DC0C442D302C6A00D0F966 /* MediaPlayer */, 133D7C862D2BE2640075467E /* Extensions */, 133D7C8A2D2BE2640075467E /* JSLoader */, @@ -224,6 +237,7 @@ isa = PBXGroup; children = ( 133D7C872D2BE2640075467E /* URLSession.swift */, + 13103E8A2D58E028000F0673 /* View.swift */, ); path = Extensions; sourceTree = ""; @@ -419,9 +433,11 @@ 133D7C8F2D2BE2640075467E /* MediaInfoView.swift in Sources */, 13103E892D58A39A000F0673 /* AniListItem.swift in Sources */, 131845F92D47C62D00CA7A54 /* SettingsViewGeneral.swift in Sources */, + 13103E8E2D58E04A000F0673 /* SkeletonCell.swift in Sources */, 133D7C8D2D2BE2640075467E /* HomeView.swift in Sources */, 13EA2BDC2D32D9FF00C1EBD7 /* MiruDataStruct.swift in Sources */, 13D842552D45267500EBBFA6 /* DropManager.swift in Sources */, + 13103E8B2D58E028000F0673 /* View.swift in Sources */, 138AA1B82D2D66FD0021F9DF /* EpisodeCell.swift in Sources */, 133D7C8C2D2BE2640075467E /* SearchView.swift in Sources */, 133D7C942D2BE2640075467E /* JSController.swift in Sources */, diff --git a/Sora/Utils/Extensions/View.swift b/Sora/Utils/Extensions/View.swift new file mode 100644 index 0000000..7c9d375 --- /dev/null +++ b/Sora/Utils/Extensions/View.swift @@ -0,0 +1,14 @@ +// +// View.swift +// Sora +// +// Created by Francesco on 09/02/25. +// + +import SwiftUI + +extension View { + func shimmering() -> some View { + self.modifier(Shimmer()) + } +} diff --git a/Sora/Utils/SkeletonCells/SkeletonCell.swift b/Sora/Utils/SkeletonCells/SkeletonCell.swift new file mode 100644 index 0000000..adf330a --- /dev/null +++ b/Sora/Utils/SkeletonCells/SkeletonCell.swift @@ -0,0 +1,41 @@ +// +// SkeletonCell.swift +// Sora +// +// Created by Francesco on 09/02/25. +// + +import SwiftUI + +struct HomeSkeletonCell: View { + var body: some View { + VStack { + RoundedRectangle(cornerRadius: 10) + .fill(Color.gray.opacity(0.3)) + .frame(width: 130, height: 195) + .cornerRadius(10) + .shimmering() + + RoundedRectangle(cornerRadius: 5) + .fill(Color.gray.opacity(0.3)) + .frame(width: 130, height: 20) + .padding(.top, 4) + .shimmering() + } + } +} + +struct SearchSkeletonCell: View { + var body: some View { + VStack(alignment: .leading, spacing: 8) { + RoundedRectangle(cornerRadius: 10) + .fill(Color.gray.opacity(0.3)) + .frame(width: 150, height: 225) + .shimmering() + RoundedRectangle(cornerRadius: 5) + .fill(Color.gray.opacity(0.3)) + .frame(width: 150, height: 20) + .shimmering() + } + } +} diff --git a/Sora/Views/HomeView.swift b/Sora/Views/HomeView.swift index 430d781..b78bee8 100644 --- a/Sora/Views/HomeView.swift +++ b/Sora/Views/HomeView.swift @@ -39,30 +39,6 @@ struct Shimmer: ViewModifier { } } -extension View { - func shimmering() -> some View { - self.modifier(Shimmer()) - } -} - -struct SkeletonCell: View { - var body: some View { - VStack { - RoundedRectangle(cornerRadius: 10) - .fill(Color.gray.opacity(0.3)) - .frame(width: 130, height: 195) - .cornerRadius(10) - .shimmering() - - RoundedRectangle(cornerRadius: 5) - .fill(Color.gray.opacity(0.3)) - .frame(width: 130, height: 20) - .padding(.top, 4) - .shimmering() - } - } -} - struct HomeView: View { @State private var aniListItems: [AniListItem] = [] @State private var trendingItems: [AniListItem] = [] @@ -111,7 +87,7 @@ struct HomeView: View { HStack(spacing: 8) { if aniListItems.isEmpty { ForEach(0..<5, id: \.self) { _ in - SkeletonCell() + HomeSkeletonCell() } } else { ForEach(aniListItems, id: \.id) { item in @@ -155,7 +131,7 @@ struct HomeView: View { HStack(spacing: 8) { if trendingItems.isEmpty { ForEach(0..<5, id: \.self) { _ in - SkeletonCell() + HomeSkeletonCell() } } else { ForEach(trendingItems, id: \.id) { item in diff --git a/Sora/Views/SearchView.swift b/Sora/Views/SearchView.swift index a7bf8d1..d30938a 100644 --- a/Sora/Views/SearchView.swift +++ b/Sora/Views/SearchView.swift @@ -77,51 +77,53 @@ struct SearchView: View { .shadow(color: Color.black.opacity(0.1), radius: 2, y: 1) } - if isSearching { - VStack(spacing: 8) { - ProgressView() - Text(loadingMessages.randomElement() ?? "Loading...") - .font(.caption) - .foregroundColor(.secondary) - } - .padding() - } else if hasNoResults { - VStack(spacing: 8) { - Image(systemName: "magnifyingglass") - .font(.largeTitle) - .foregroundColor(.secondary) - Text("No Results Found") - .font(.headline) - Text("Try different keywords") - .font(.caption) - .foregroundColor(.secondary) - } - .padding() - .frame(maxWidth: .infinity) - .padding(.top) - } - - LazyVGrid(columns: [GridItem(.adaptive(minimum: 150))], spacing: 16) { - ForEach(searchItems) { item in - NavigationLink(destination: MediaInfoView(title: item.title, imageUrl: item.imageUrl, href: item.href, module: selectedModule!)) { - VStack { - KFImage(URL(string: item.imageUrl)) - .resizable() - .aspectRatio(2/3, contentMode: .fill) - .cornerRadius(10) - .frame(width: 150, height: 225) - - Text(item.title) - .font(.subheadline) - .foregroundColor(Color.primary) - .padding([.leading, .bottom], 8) - .lineLimit(1) + if !searchText.isEmpty { + if isSearching { + LazyVGrid(columns: [GridItem(.adaptive(minimum: 150))], spacing: 16) { + ForEach(0..<6, id: \.self) { _ in + SearchSkeletonCell() } } + .padding(.top) + .padding() + } else if hasNoResults { + VStack(spacing: 8) { + Image(systemName: "magnifyingglass") + .font(.largeTitle) + .foregroundColor(.secondary) + Text("No Results Found") + .font(.headline) + Text("Try different keywords") + .font(.caption) + .foregroundColor(.secondary) + } + .padding() + .frame(maxWidth: .infinity) + .padding(.top) + } else { + LazyVGrid(columns: [GridItem(.adaptive(minimum: 150))], spacing: 16) { + ForEach(searchItems) { item in + NavigationLink(destination: MediaInfoView(title: item.title, imageUrl: item.imageUrl, href: item.href, module: selectedModule!)) { + VStack(alignment: .leading, spacing: 8) { + KFImage(URL(string: item.imageUrl)) + .resizable() + .aspectRatio(2/3, contentMode: .fill) + .cornerRadius(10) + .frame(width: 150, height: 225) + + Text(item.title) + .font(.subheadline) + .foregroundColor(Color.primary) + .padding([.leading, .bottom], 8) + .lineLimit(1) + } + } + } + } + .padding(.top) + .padding() } } - .padding(.top) - .padding() } } .navigationTitle("Search") @@ -168,6 +170,13 @@ struct SearchView: View { performSearch() } } + .onChange(of: searchText) { newValue in + if newValue.isEmpty { + searchItems = [] + hasNoResults = false + isSearching = false + } + } } private func performSearch() {