mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
migrated to NukeUI from KingFisher
This commit is contained in:
parent
1692ac2c3d
commit
fa758159dc
15 changed files with 502 additions and 365 deletions
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 01/02/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct ModuleAdditionSettingsView: View {
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
|
|
@ -22,7 +22,7 @@ struct ModuleAdditionSettingsView: View {
|
|||
ZStack {
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [
|
||||
colorScheme == .dark ? Color.black : Color.white,
|
||||
colorScheme == .light ? Color.black : Color.white,
|
||||
Color.accentColor.opacity(0.08)
|
||||
]),
|
||||
startPoint: .top,
|
||||
|
|
@ -45,17 +45,24 @@ struct ModuleAdditionSettingsView: View {
|
|||
VStack(spacing: 24) {
|
||||
if let metadata = moduleMetadata {
|
||||
VStack(spacing: 0) {
|
||||
KFImage(URL(string: metadata.iconUrl))
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 90, height: 90)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 22, style: .continuous))
|
||||
.shadow(color: Color.accentColor.opacity(0.18), radius: 10, x: 0, y: 6)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 22)
|
||||
.stroke(Color.accentColor, lineWidth: 2)
|
||||
)
|
||||
.padding(.top, 10)
|
||||
LazyImage(source: URL(string: metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(Color(.systemGray5))
|
||||
}
|
||||
}
|
||||
.frame(width: 90, height: 90)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 22, style: .continuous))
|
||||
.shadow(color: Color.accentColor.opacity(0.18), radius: 10, x: 0, y: 6)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 22)
|
||||
.stroke(Color.accentColor, lineWidth: 2)
|
||||
)
|
||||
.padding(.top, 10)
|
||||
|
||||
VStack(spacing: 6) {
|
||||
Text(metadata.sourceName)
|
||||
|
|
@ -65,12 +72,19 @@ struct ModuleAdditionSettingsView: View {
|
|||
.padding(.top, 6)
|
||||
|
||||
HStack(spacing: 10) {
|
||||
KFImage(URL(string: metadata.author.icon))
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
.shadow(radius: 2)
|
||||
LazyImage(source: URL(string: metadata.author.icon)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color(.systemGray5))
|
||||
}
|
||||
}
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
.shadow(radius: 2)
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(metadata.author.name)
|
||||
.font(.headline)
|
||||
|
|
@ -166,7 +180,7 @@ struct ModuleAdditionSettingsView: View {
|
|||
Text("Add Module")
|
||||
}
|
||||
.font(.headline)
|
||||
.foregroundColor(colorScheme == .dark ? .black : .white)
|
||||
.foregroundColor(colorScheme == .light ? .black : .white)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 14)
|
||||
.background(
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by doomsboygaming on 5/22/25
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AVKit
|
||||
import Kingfisher
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
struct DownloadView: View {
|
||||
@EnvironmentObject var jsController: JSController
|
||||
|
|
@ -741,13 +741,16 @@ struct EnhancedActiveDownloadCard: View {
|
|||
HStack(spacing: 16) {
|
||||
Group {
|
||||
if let imageURL = download.imageURL {
|
||||
KFImage(imageURL)
|
||||
.placeholder {
|
||||
LazyImage(source: imageURL) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
|
|
@ -899,16 +902,18 @@ struct EnhancedDownloadGroupCard: View {
|
|||
NavigationLink(destination: EnhancedShowEpisodesView(group: group, onDelete: onDelete, onPlay: onPlay)) {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 16) {
|
||||
// Poster
|
||||
Group {
|
||||
if let posterURL = group.posterURL {
|
||||
KFImage(posterURL)
|
||||
.placeholder {
|
||||
LazyImage(source: posterURL) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
|
|
@ -921,7 +926,6 @@ struct EnhancedDownloadGroupCard: View {
|
|||
.frame(width: 56, height: 84)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
|
||||
// Content
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(group.title)
|
||||
.font(.headline)
|
||||
|
|
@ -1000,18 +1004,20 @@ struct EnhancedShowEpisodesView: View {
|
|||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 24) {
|
||||
// Header Section
|
||||
VStack(spacing: 20) {
|
||||
HStack(alignment: .top, spacing: 20) {
|
||||
Group {
|
||||
if let posterURL = group.posterURL {
|
||||
KFImage(posterURL)
|
||||
.placeholder {
|
||||
LazyImage(source: posterURL) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
|
|
@ -1192,16 +1198,18 @@ struct EnhancedEpisodeRow: View {
|
|||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 16) {
|
||||
// Thumbnail
|
||||
Group {
|
||||
if let backdropURL = asset.metadata?.backdropURL ?? asset.metadata?.posterURL {
|
||||
KFImage(backdropURL)
|
||||
.placeholder {
|
||||
LazyImage(source: backdropURL) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
|
|
@ -1214,7 +1222,6 @@ struct EnhancedEpisodeRow: View {
|
|||
.frame(width: 100, height: 60)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
|
||||
// Content
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(asset.episodeDisplayName)
|
||||
.font(.headline)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by paul on 29/04/2025.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import UIKit
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
extension View {
|
||||
func circularGradientOutlineTwo() -> some View {
|
||||
|
|
@ -59,28 +59,44 @@ struct BookmarkCell: View {
|
|||
var body: some View {
|
||||
if let module = moduleManager.modules.first(where: { $0.id.uuidString == bookmark.moduleId }) {
|
||||
ZStack {
|
||||
KFImage(URL(string: bookmark.imageUrl))
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: 162, height: 243)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
KFImage(URL(string: module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
)
|
||||
}
|
||||
.padding(8),
|
||||
alignment: .topLeading
|
||||
)
|
||||
LazyImage(source: URL(string: bookmark.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: 162, height: 243)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 162, height: 243)
|
||||
}
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
LazyImage(source: URL(string: module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.padding(8),
|
||||
alignment: .topLeading
|
||||
)
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by paul on 24/05/2025.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import UIKit
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
extension View {
|
||||
func circularGradientOutline() -> some View {
|
||||
|
|
@ -206,75 +206,86 @@ struct FullWidthContinueWatchingCell: View {
|
|||
}) {
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .bottomLeading) {
|
||||
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: geometry.size.width, height: 157.03)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(height: 157.03)
|
||||
.shimmering()
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: geometry.size.width, height: 157.03)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
.overlay(
|
||||
ZStack {
|
||||
ProgressiveBlurView()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
ProgressiveBlurView()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Spacer()
|
||||
Text(item.mediaTitle)
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
|
||||
HStack {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Spacer()
|
||||
Text(item.mediaTitle)
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
|
||||
HStack {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(Int(item.progress * 100))% seen")
|
||||
.font(.caption)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
}
|
||||
Text("\(Int(item.progress * 100))% seen")
|
||||
.font(.caption)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
}
|
||||
.padding(10)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
)
|
||||
}
|
||||
.padding(10)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
)
|
||||
.clipped()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
.shadow(color: .black.opacity(0.3), radius: 3, x: 0, y: 1)
|
||||
)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
LazyImage(source: URL(string: item.module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
KFImage(URL(string: item.module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
)
|
||||
}
|
||||
}
|
||||
.padding(8),
|
||||
alignment: .topLeading
|
||||
)
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
}
|
||||
.frame(height: 157.03)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by Francesco on 05/01/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import UIKit
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
struct LibraryView: View {
|
||||
@EnvironmentObject private var libraryManager: LibraryManager
|
||||
|
|
@ -280,85 +280,96 @@ struct ContinueWatchingCell: View {
|
|||
}
|
||||
}) {
|
||||
ZStack(alignment: .bottomLeading) {
|
||||
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 280, height: 157.03)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 280, height: 157.03)
|
||||
.shimmering()
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 280, height: 157.03)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
.overlay(
|
||||
ZStack {
|
||||
ProgressiveBlurView()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
ProgressiveBlurView()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Spacer()
|
||||
Text(item.mediaTitle)
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
|
||||
HStack {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Spacer()
|
||||
Text(item.mediaTitle)
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
|
||||
HStack {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(Int(item.progress * 100))% seen")
|
||||
.font(.caption)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
}
|
||||
Text("\(Int(item.progress * 100))% seen")
|
||||
.font(.caption)
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
}
|
||||
.padding(10)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
)
|
||||
.clipped()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
.shadow(color: .black.opacity(0.3), radius: 3, x: 0, y: 1)
|
||||
}
|
||||
.padding(10)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
.overlay(
|
||||
ZStack {
|
||||
if item.streamUrl.hasPrefix("file://") {
|
||||
Image(systemName: "arrow.down.app.fill")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 24, height: 24)
|
||||
.foregroundColor(.white)
|
||||
.background(Color.black.cornerRadius(6))
|
||||
.padding(8)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
KFImage(URL(string: item.module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
)
|
||||
.padding(8)
|
||||
}
|
||||
},
|
||||
alignment: .topLeading
|
||||
)
|
||||
.clipped()
|
||||
.cornerRadius(10, corners: [.bottomLeft, .bottomRight])
|
||||
.shadow(color: .black.opacity(0.3), radius: 3, x: 0, y: 1)
|
||||
)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
.overlay(
|
||||
ZStack {
|
||||
if item.streamUrl.hasPrefix("file://") {
|
||||
Image(systemName: "arrow.down.app.fill")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 24, height: 24)
|
||||
.foregroundColor(.white)
|
||||
.background(Color.black.cornerRadius(6))
|
||||
.padding(8)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
LazyImage(source: URL(string: item.module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
)
|
||||
.padding(8)
|
||||
}
|
||||
},
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
.frame(width: 280, height: 157.03)
|
||||
}
|
||||
|
|
@ -525,34 +536,45 @@ struct BookmarkItemView: View {
|
|||
isDetailActive = true
|
||||
}) {
|
||||
ZStack {
|
||||
KFImage(URL(string: item.imageUrl))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: 162, height: 243)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.aspectRatio(2 / 3, contentMode: .fit)
|
||||
.shimmering()
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: 162, height: 243)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
KFImage(URL(string: module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
)
|
||||
}
|
||||
.padding(8),
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(Color.black.opacity(0.5))
|
||||
.frame(width: 28, height: 28)
|
||||
.overlay(
|
||||
LazyImage(source: URL(string: module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.padding(8),
|
||||
alignment: .topLeading
|
||||
)
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by seiike on 01/06/2025.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct AnilistMatchPopupView: View {
|
||||
let seriesTitle: String
|
||||
|
|
@ -32,7 +32,6 @@ struct AnilistMatchPopupView: View {
|
|||
NavigationView {
|
||||
ScrollView {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
// (Optional) A hidden header; can be omitted if empty
|
||||
Text("".uppercased())
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.gray)
|
||||
|
|
@ -62,11 +61,20 @@ struct AnilistMatchPopupView: View {
|
|||
HStack(spacing: 12) {
|
||||
if let cover = result["cover"] as? String,
|
||||
let url = URL(string: cover) {
|
||||
KFImage(url)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 50, height: 70)
|
||||
.cornerRadius(6)
|
||||
LazyImage(source: url) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 50, height: 70)
|
||||
.cornerRadius(6)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: 50, height: 70)
|
||||
.cornerRadius(6)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 18/12/24.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import AVFoundation
|
||||
|
||||
struct EpisodeCell: View {
|
||||
|
|
@ -264,14 +264,28 @@ struct EpisodeCell: View {
|
|||
private var episodeThumbnail: some View {
|
||||
ZStack {
|
||||
if let url = URL(string: episodeImageUrl.isEmpty ? defaultBannerImage : episodeImageUrl) {
|
||||
KFImage(url)
|
||||
.onFailure { error in
|
||||
Logger.shared.log("Failed to load episode image: \(error)", type: "Error")
|
||||
LazyImage(source: url) { state in
|
||||
if let image = state.imageContainer?.image {
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 100, height: 56)
|
||||
.cornerRadius(8)
|
||||
} else if state.error != nil {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: 100, height: 56)
|
||||
.cornerRadius(8)
|
||||
.onAppear {
|
||||
Logger.shared.log("Failed to load episode image: \(state.error?.localizedDescription ?? "Unknown error")", type: "Error")
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: 100, height: 56)
|
||||
.cornerRadius(8)
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 100, height: 56)
|
||||
.cornerRadius(8)
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 05/01/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import SafariServices
|
||||
|
||||
private let tmdbFetcher = TMDBFetcher()
|
||||
|
|
@ -212,46 +212,21 @@ struct MediaInfoView: View {
|
|||
private var mainScrollView: some View {
|
||||
ScrollView {
|
||||
ZStack(alignment: .top) {
|
||||
KFImage(URL(string: imageUrl))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: UIScreen.main.bounds.width, height: 700)
|
||||
.clipped()
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.shimmering()
|
||||
.frame(width: UIScreen.main.bounds.width, height: 700)
|
||||
.clipped()
|
||||
}
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: UIScreen.main.bounds.width, height: 700)
|
||||
.clipped()
|
||||
KFImage(URL(string: imageUrl))
|
||||
.placeholder { EmptyView() }
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: UIScreen.main.bounds.width, height: 700)
|
||||
.clipped()
|
||||
.blur(radius: 30)
|
||||
.mask(
|
||||
LinearGradient(
|
||||
gradient: Gradient(stops: [
|
||||
.init(color: .clear, location: 0.0),
|
||||
.init(color: .clear, location: 0.6),
|
||||
.init(color: .black, location: 0.8),
|
||||
.init(color: .black, location: 1.0)
|
||||
]),
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
)
|
||||
)
|
||||
.overlay(
|
||||
LinearGradient(
|
||||
gradient: Gradient(stops: [
|
||||
.init(color: .clear, location: 0.0),
|
||||
.init(color: .clear, location: 0.7),
|
||||
.init(color: (colorScheme == .dark ? Color.black : Color.white).opacity(0.9), location: 1.0)
|
||||
]),
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
)
|
||||
)
|
||||
}
|
||||
VStack(spacing: 0) {
|
||||
Rectangle()
|
||||
.fill(Color.clear)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by paul on 28/05/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct SearchResultsGrid: View {
|
||||
@AppStorage("mediaColumnsPortrait") private var mediaColumnsPortrait: Int = 2
|
||||
|
|
@ -32,12 +32,22 @@ struct SearchResultsGrid: View {
|
|||
ForEach(items) { item in
|
||||
NavigationLink(destination: MediaInfoView(title: item.title, imageUrl: item.imageUrl, href: item.href, module: selectedModule)) {
|
||||
ZStack {
|
||||
KFImage(URL(string: item.imageUrl))
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
LazyImage(source: URL(string: item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
}
|
||||
}
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 27/01/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct ModuleSelectorMenu: View {
|
||||
let selectedModule: ScrapingModule?
|
||||
|
|
@ -27,11 +27,19 @@ struct ModuleSelectorMenu: View {
|
|||
onModuleSelected(module.id.uuidString)
|
||||
} label: {
|
||||
HStack {
|
||||
KFImage(URL(string: module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 20, height: 20)
|
||||
.cornerRadius(4)
|
||||
LazyImage(source: URL(string: module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 20, height: 20)
|
||||
.cornerRadius(4)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color(.systemGray5))
|
||||
}
|
||||
}
|
||||
|
||||
Text(module.metadata.sourceName)
|
||||
if module.id.uuidString == selectedModuleId {
|
||||
Image(systemName: "checkmark")
|
||||
|
|
@ -48,29 +56,37 @@ struct ModuleSelectorMenu: View {
|
|||
Text(selectedModule.metadata.sourceName)
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
KFImage(URL(string: selectedModule.metadata.iconUrl))
|
||||
.resizable()
|
||||
.frame(width: 36, height: 36)
|
||||
.clipShape(Circle())
|
||||
.background(
|
||||
LazyImage(source: URL(string: selectedModule.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 36, height: 36)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
Circle()
|
||||
.fill(.ultraThinMaterial)
|
||||
.overlay(
|
||||
Circle()
|
||||
.stroke(
|
||||
LinearGradient(
|
||||
gradient: Gradient(stops: [
|
||||
.init(color: Color.accentColor.opacity(gradientOpacity), location: 0),
|
||||
.init(color: Color.accentColor.opacity(0), location: 1)
|
||||
]),
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
),
|
||||
lineWidth: 0.5
|
||||
)
|
||||
)
|
||||
.matchedGeometryEffect(id: "background_circle", in: animation)
|
||||
)
|
||||
.frame(width: 36, height: 36)
|
||||
}
|
||||
}
|
||||
.background(
|
||||
Circle()
|
||||
.fill(.ultraThinMaterial)
|
||||
.overlay(
|
||||
Circle()
|
||||
.stroke(
|
||||
LinearGradient(
|
||||
gradient: Gradient(stops: [
|
||||
.init(color: Color.accentColor.opacity(gradientOpacity), location: 0),
|
||||
.init(color: Color.accentColor.opacity(0), location: 1)
|
||||
]),
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
),
|
||||
lineWidth: 0.5
|
||||
)
|
||||
)
|
||||
.matchedGeometryEffect(id: "background_circle", in: animation)
|
||||
)
|
||||
} else {
|
||||
Text("Select Module")
|
||||
.font(.headline)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 26/05/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
fileprivate struct SettingsSection<Content: View>: View {
|
||||
let title: String
|
||||
|
|
@ -66,14 +66,18 @@ struct SettingsViewAbout: View {
|
|||
VStack(spacing: 24) {
|
||||
SettingsSection(title: "App Info", footer: "Sora/Sulfur will always remain free with no ADs!") {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
KFImage(URL(string: "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/dev/Sora/Assets.xcassets/AppIcons/AppIcon_Default.appiconset/darkmode.png"))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/dev/Sora/Assets.xcassets/AppIcons/AppIcon_Default.appiconset/darkmode.png")) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 100, height: 100)
|
||||
.cornerRadius(20)
|
||||
.shadow(radius: 5)
|
||||
} else {
|
||||
ProgressView()
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
.resizable()
|
||||
.frame(width: 100, height: 100)
|
||||
.cornerRadius(20)
|
||||
.shadow(radius: 5)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Sora")
|
||||
|
|
@ -96,13 +100,17 @@ struct SettingsViewAbout: View {
|
|||
}
|
||||
}) {
|
||||
HStack {
|
||||
KFImage(URL(string: "https://avatars.githubusercontent.com/u/100066266?v=4"))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: "https://avatars.githubusercontent.com/u/100066266?v=4")) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
ProgressView()
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text("cranci1")
|
||||
|
|
@ -205,13 +213,17 @@ struct ContributorView: View {
|
|||
}
|
||||
}) {
|
||||
HStack {
|
||||
KFImage(URL(string: contributor.avatarUrl))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: contributor.avatarUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
ProgressView()
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
Text(contributor.login)
|
||||
.font(.headline)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Francesco on 05/01/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
fileprivate struct SettingsSection<Content: View>: View {
|
||||
let title: String
|
||||
|
|
@ -67,11 +67,19 @@ fileprivate struct ModuleListItemView: View {
|
|||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
HStack {
|
||||
KFImage(URL(string: module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
.padding(.trailing, 10)
|
||||
LazyImage(source: URL(string: module.metadata.iconUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
.padding(.trailing, 10)
|
||||
} else {
|
||||
Circle()
|
||||
.frame(width: 40, height: 40)
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
HStack(alignment: .bottom, spacing: 4) {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by Francesco on 23/03/25.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Security
|
||||
import Kingfisher
|
||||
|
||||
fileprivate struct SettingsSection<Content: View>: View {
|
||||
let title: String
|
||||
|
|
@ -120,18 +120,21 @@ struct SettingsViewTrackers: View {
|
|||
SettingsSection(title: "AniList") {
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .center, spacing: 10) {
|
||||
KFImage(URL(string: "https://raw.githubusercontent.com/cranci1/Ryu/2f10226aa087154974a70c1ec78aa83a47daced9/Ryu/Assets.xcassets/Listing/Anilist.imageset/anilist.png"))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: "https://raw.githubusercontent.com/cranci1/Ryu/2f10226aa087154974a70c1ec78aa83a47daced9/Ryu/Assets.xcassets/Listing/Anilist.imageset/anilist.png")) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 60, height: 60)
|
||||
.clipShape(Rectangle())
|
||||
.cornerRadius(10)
|
||||
.padding(.trailing, 10)
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 60, height: 60)
|
||||
.shimmering()
|
||||
}
|
||||
.resizable()
|
||||
.frame(width: 60, height: 60)
|
||||
.clipShape(Rectangle())
|
||||
.cornerRadius(10)
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("AniList.co")
|
||||
|
|
@ -212,18 +215,21 @@ struct SettingsViewTrackers: View {
|
|||
SettingsSection(title: "Trakt") {
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .center, spacing: 10) {
|
||||
KFImage(URL(string: "https://static-00.iconduck.com/assets.00/trakt-icon-2048x2048-2633ksxg.png"))
|
||||
.placeholder {
|
||||
LazyImage(source: URL(string: "https://static-00.iconduck.com/assets.00/trakt-icon-2048x2048-2633ksxg.png")) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: 60, height: 60)
|
||||
.clipShape(Rectangle())
|
||||
.cornerRadius(10)
|
||||
.padding(.trailing, 10)
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 60, height: 60)
|
||||
.shimmering()
|
||||
}
|
||||
.resizable()
|
||||
.frame(width: 60, height: 60)
|
||||
.clipShape(Rectangle())
|
||||
.cornerRadius(10)
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Trakt.tv")
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
1359ED142D76F49900C13034 /* finTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1359ED132D76F49900C13034 /* finTopView.swift */; };
|
||||
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */; };
|
||||
13637B8A2DE0EA1100BDA2FC /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13637B892DE0EA1100BDA2FC /* UserDefaults.swift */; };
|
||||
13637B8D2DE0ECCC00BDA2FC /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 13637B8C2DE0ECCC00BDA2FC /* Kingfisher */; };
|
||||
13637B902DE0ECD200BDA2FC /* Drops in Frameworks */ = {isa = PBXBuildFile; productRef = 13637B8F2DE0ECD200BDA2FC /* Drops */; };
|
||||
13637B932DE0ECDB00BDA2FC /* MarqueeLabel in Frameworks */ = {isa = PBXBuildFile; productRef = 13637B922DE0ECDB00BDA2FC /* MarqueeLabel */; };
|
||||
136BBE802DB1038000906B5E /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136BBE7F2DB1038000906B5E /* Notification+Name.swift */; };
|
||||
|
|
@ -61,6 +60,7 @@
|
|||
1399FAD62D3AB3DB00E97C31 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1399FAD52D3AB3DB00E97C31 /* Logger.swift */; };
|
||||
13B77E202DA457AA00126FDF /* AniListPushUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B77E1F2DA457AA00126FDF /* AniListPushUpdates.swift */; };
|
||||
13B7F4C12D58FFDD0045714A /* Shimmer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B7F4C02D58FFDD0045714A /* Shimmer.swift */; };
|
||||
13BC689F2DF61327009A0651 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 13BC689E2DF61327009A0651 /* NukeUI */; };
|
||||
13C0E5EA2D5F85EA00E7F619 /* ContinueWatchingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C0E5E92D5F85EA00E7F619 /* ContinueWatchingManager.swift */; };
|
||||
13C0E5EC2D5F85F800E7F619 /* ContinueWatchingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C0E5EB2D5F85F800E7F619 /* ContinueWatchingItem.swift */; };
|
||||
13CBA0882D60F19C00EFE70A /* VTTSubtitlesLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CBA0872D60F19C00EFE70A /* VTTSubtitlesLoader.swift */; };
|
||||
|
|
@ -191,9 +191,9 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13637B8D2DE0ECCC00BDA2FC /* Kingfisher in Frameworks */,
|
||||
13637B902DE0ECD200BDA2FC /* Drops in Frameworks */,
|
||||
13637B932DE0ECDB00BDA2FC /* MarqueeLabel in Frameworks */,
|
||||
13BC689F2DF61327009A0651 /* NukeUI in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -614,9 +614,9 @@
|
|||
);
|
||||
name = Sulfur;
|
||||
packageProductDependencies = (
|
||||
13637B8C2DE0ECCC00BDA2FC /* Kingfisher */,
|
||||
13637B8F2DE0ECD200BDA2FC /* Drops */,
|
||||
13637B922DE0ECDB00BDA2FC /* MarqueeLabel */,
|
||||
13BC689E2DF61327009A0651 /* NukeUI */,
|
||||
);
|
||||
productName = Sora;
|
||||
productReference = 133D7C6A2D2BE2500075467E /* Sulfur.app */;
|
||||
|
|
@ -646,9 +646,9 @@
|
|||
);
|
||||
mainGroup = 133D7C612D2BE2500075467E;
|
||||
packageReferences = (
|
||||
13637B8B2DE0ECCC00BDA2FC /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||
13637B8E2DE0ECD200BDA2FC /* XCRemoteSwiftPackageReference "Drops" */,
|
||||
13637B912DE0ECDB00BDA2FC /* XCRemoteSwiftPackageReference "MarqueeLabel" */,
|
||||
13BC689D2DF61327009A0651 /* XCRemoteSwiftPackageReference "NukeUI" */,
|
||||
);
|
||||
productRefGroup = 133D7C6B2D2BE2500075467E /* Products */;
|
||||
projectDirPath = "";
|
||||
|
|
@ -994,14 +994,6 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
13637B8B2DE0ECCC00BDA2FC /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/onevcat/Kingfisher.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 7.9.1;
|
||||
};
|
||||
};
|
||||
13637B8E2DE0ECD200BDA2FC /* XCRemoteSwiftPackageReference "Drops" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/omaralbeik/Drops.git";
|
||||
|
|
@ -1018,14 +1010,17 @@
|
|||
version = 4.2.1;
|
||||
};
|
||||
};
|
||||
13BC689D2DF61327009A0651 /* XCRemoteSwiftPackageReference "NukeUI" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kean/NukeUI";
|
||||
requirement = {
|
||||
branch = main;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
13637B8C2DE0ECCC00BDA2FC /* Kingfisher */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 13637B8B2DE0ECCC00BDA2FC /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||
productName = Kingfisher;
|
||||
};
|
||||
13637B8F2DE0ECD200BDA2FC /* Drops */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 13637B8E2DE0ECD200BDA2FC /* XCRemoteSwiftPackageReference "Drops" */;
|
||||
|
|
@ -1036,6 +1031,11 @@
|
|||
package = 13637B912DE0ECDB00BDA2FC /* XCRemoteSwiftPackageReference "MarqueeLabel" */;
|
||||
productName = MarqueeLabel;
|
||||
};
|
||||
13BC689E2DF61327009A0651 /* NukeUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 13BC689D2DF61327009A0651 /* XCRemoteSwiftPackageReference "NukeUI" */;
|
||||
productName = NukeUI;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 133D7C622D2BE2500075467E /* Project object */;
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"package": "Kingfisher",
|
||||
"repositoryURL": "https://github.com/onevcat/Kingfisher.git",
|
||||
"package": "Gifu",
|
||||
"repositoryURL": "https://github.com/kaishin/Gifu",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b6f62758f21a8c03cd64f4009c037cfa580a256e",
|
||||
"version": "7.9.1"
|
||||
"revision": "82da0086dea14ca9afc9801234ad8dc4cd9e2738",
|
||||
"version": "3.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -27,6 +27,24 @@
|
|||
"revision": "cffb6938940d3242882e6a2f9170b7890a4729ea",
|
||||
"version": "4.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Nuke",
|
||||
"repositoryURL": "https://github.com/kean/Nuke.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a002b7fd786f2df2ed4333fe73a9727499fd9d97",
|
||||
"version": "10.11.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "NukeUI",
|
||||
"repositoryURL": "https://github.com/kean/NukeUI",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "7338ed8ea76de18598bfafbca0cbdc74300a6b10",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue