mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-28 21:38:44 +00:00
uh ong bro im cooked
This commit is contained in:
parent
701a1d6371
commit
08619176ba
5 changed files with 123 additions and 67 deletions
|
|
@ -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 = "<group>"; };
|
||||
13103E852D58A328000F0673 /* AniList-Trending.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-Trending.swift"; sourceTree = "<group>"; };
|
||||
13103E882D58A39A000F0673 /* AniListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AniListItem.swift; sourceTree = "<group>"; };
|
||||
13103E8A2D58E028000F0673 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
|
||||
13103E8D2D58E04A000F0673 /* SkeletonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCell.swift; sourceTree = "<group>"; };
|
||||
131845F82D47C62D00CA7A54 /* SettingsViewGeneral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewGeneral.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
|
|
@ -132,6 +136,14 @@
|
|||
path = Struct;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13103E8C2D58E037000F0673 /* SkeletonCells */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13103E8D2D58E04A000F0673 /* SkeletonCell.swift */,
|
||||
);
|
||||
path = SkeletonCells;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
|
|
@ -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 */,
|
||||
|
|
|
|||
14
Sora/Utils/Extensions/View.swift
Normal file
14
Sora/Utils/Extensions/View.swift
Normal file
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
41
Sora/Utils/SkeletonCells/SkeletonCell.swift
Normal file
41
Sora/Utils/SkeletonCells/SkeletonCell.swift
Normal file
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue