Small hotfixes (#29)

This commit is contained in:
cranci 2025-03-04 17:45:20 +01:00 committed by GitHub
commit 087d657ad9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 314 additions and 238 deletions

View file

@ -2,7 +2,7 @@ name: Build and Release IPA
on:
push:
branches:
- main
- dev
jobs:
build:
name: Build IPA
@ -24,6 +24,6 @@ jobs:
- name: Upload IPA artifact
uses: actions/upload-artifact@v4
with:
name: Sora-IPA
path: build/Sora.ipa
name: Sulfur-IPA
path: build/Sulfur.ipa
compression-level: 0

View file

@ -0,0 +1,27 @@
//
// finTopView.swift
// Sulfur
//
// Created by Francesco on 04/03/25.
//
import UIKit
class findTopViewController {
static func findViewController(_ viewController: UIViewController) -> UIViewController {
if let presented = viewController.presentedViewController {
return findViewController(presented)
}
if let navigationController = viewController as? UINavigationController {
return findViewController(navigationController.visibleViewController ?? navigationController)
}
if let tabBarController = viewController as? UITabBarController,
let selected = tabBarController.selectedViewController {
return findViewController(selected)
}
return viewController
}
}

View file

@ -57,6 +57,10 @@ class CustomMediaPlayerViewController: UIViewController {
var sliderViewModel = SliderViewModel()
var isSliderEditing = false
var watchNextButtonNormalConstraints: [NSLayoutConstraint] = []
var watchNextButtonControlsConstraints: [NSLayoutConstraint] = []
var isControlsVisible = false
init(module: ScrapingModule,
urlString: String,
fullUrl: String,
@ -106,8 +110,9 @@ class CustomMediaPlayerViewController: UIViewController {
setupControls()
setupSubtitleLabel()
setupDismissButton()
setupSpeedButton()
setupMenuButton()
setupSpeedButton()
setupWatchNextButton()
addTimeObserver()
startUpdateTimer()
setupAudioSession()
@ -244,17 +249,6 @@ class CustomMediaPlayerViewController: UIViewController {
sliderHostView.heightAnchor.constraint(equalToConstant: 30)
])
watchNextButton = UIButton(type: .system)
watchNextButton.setTitle("Watch Next", for: .normal)
watchNextButton.setImage(UIImage(systemName: "forward.fill"), for: .normal)
watchNextButton.backgroundColor = .white
watchNextButton.layer.cornerRadius = 16
watchNextButton.setTitleColor(.black, for: .normal)
watchNextButton.addTarget(self, action: #selector(watchNextTapped), for: .touchUpInside)
watchNextButton.isHidden = true
controlsContainerView.addSubview(watchNextButton)
watchNextButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
playPauseButton.centerXAnchor.constraint(equalTo: controlsContainerView.centerXAnchor),
playPauseButton.centerYAnchor.constraint(equalTo: controlsContainerView.centerYAnchor),
@ -269,12 +263,7 @@ class CustomMediaPlayerViewController: UIViewController {
forwardButton.centerYAnchor.constraint(equalTo: playPauseButton.centerYAnchor),
forwardButton.leadingAnchor.constraint(equalTo: playPauseButton.trailingAnchor, constant: 30),
forwardButton.widthAnchor.constraint(equalToConstant: 40),
forwardButton.heightAnchor.constraint(equalToConstant: 40),
watchNextButton.trailingAnchor.constraint(equalTo: controlsContainerView.trailingAnchor, constant: -10),
watchNextButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -80),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
forwardButton.heightAnchor.constraint(equalToConstant: 40)
])
}
@ -288,9 +277,9 @@ class CustomMediaPlayerViewController: UIViewController {
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subtitleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
subtitleLabel.bottomAnchor.constraint(equalTo: sliderHostingController?.view.topAnchor ?? view.safeAreaLayoutGuide.bottomAnchor),
subtitleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 20),
subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -20)
subtitleLabel.bottomAnchor.constraint(equalTo: sliderHostingController?.view.bottomAnchor ?? view.safeAreaLayoutGuide.bottomAnchor),
subtitleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 36),
subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -36)
])
}
@ -323,9 +312,10 @@ class CustomMediaPlayerViewController: UIViewController {
controlsContainerView.addSubview(menuButton)
menuButton.translatesAutoresizingMaskIntoConstraints = false
guard let sliderView = sliderHostingController?.view else { return }
NSLayoutConstraint.activate([
menuButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -50),
menuButton.trailingAnchor.constraint(equalTo: speedButton.leadingAnchor),
menuButton.bottomAnchor.constraint(equalTo: sliderView.topAnchor),
menuButton.trailingAnchor.constraint(equalTo: sliderView.trailingAnchor),
menuButton.widthAnchor.constraint(equalToConstant: 40),
menuButton.heightAnchor.constraint(equalToConstant: 40)
])
@ -341,15 +331,46 @@ class CustomMediaPlayerViewController: UIViewController {
controlsContainerView.addSubview(speedButton)
speedButton.translatesAutoresizingMaskIntoConstraints = false
guard let sliderView = sliderHostingController?.view else { return }
NSLayoutConstraint.activate([
speedButton.bottomAnchor.constraint(equalTo: sliderView.topAnchor),
speedButton.trailingAnchor.constraint(equalTo: sliderView.trailingAnchor),
speedButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -50),
speedButton.trailingAnchor.constraint(equalTo: menuButton.leadingAnchor),
speedButton.widthAnchor.constraint(equalToConstant: 40),
speedButton.heightAnchor.constraint(equalToConstant: 40)
])
}
func setupWatchNextButton() {
watchNextButton = UIButton(type: .system)
watchNextButton.setTitle("Watch Next", for: .normal)
watchNextButton.setImage(UIImage(systemName: "forward.fill"), for: .normal)
watchNextButton.tintColor = .black
watchNextButton.backgroundColor = .white
watchNextButton.layer.cornerRadius = 25
watchNextButton.setTitleColor(.black, for: .normal)
watchNextButton.addTarget(self, action: #selector(watchNextTapped), for: .touchUpInside)
watchNextButton.isHidden = true
watchNextButton.alpha = 0.8
view.addSubview(watchNextButton)
watchNextButton.translatesAutoresizingMaskIntoConstraints = false
watchNextButtonNormalConstraints = [
watchNextButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
watchNextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
]
watchNextButtonControlsConstraints = [
watchNextButton.trailingAnchor.constraint(equalTo: speedButton.leadingAnchor),
watchNextButton.bottomAnchor.constraint(equalTo: speedButton.bottomAnchor, constant: -5),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
]
NSLayoutConstraint.activate(watchNextButtonControlsConstraints)
}
func updateSubtitleLabelAppearance() {
subtitleLabel.font = UIFont.systemFont(ofSize: CGFloat(subtitleFontSize))
subtitleLabel.textColor = subtitleUIColor()
@ -405,7 +426,6 @@ class CustomMediaPlayerViewController: UIViewController {
&& self.duration != 0 {
if UserDefaults.standard.bool(forKey: "hideNextButton") {
self.watchNextButton.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.watchNextButton.isHidden = true
}
@ -444,8 +464,22 @@ class CustomMediaPlayerViewController: UIViewController {
}
@objc func toggleControls() {
isControlsVisible.toggle()
UIView.animate(withDuration: 0.2) {
self.controlsContainerView.alpha = self.controlsContainerView.alpha == 0 ? 1 : 0
self.controlsContainerView.alpha = self.isControlsVisible ? 1 : 0
if self.isControlsVisible {
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
self.watchNextButton.alpha = 1.0
} else {
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
self.watchNextButton.alpha = 0.8
}
self.view.layoutIfNeeded()
}
}

View file

@ -148,4 +148,11 @@ class VideoPlayerViewController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
deinit {
player?.pause()
if let timeObserverToken = timeObserverToken {
player?.removeTimeObserver(timeObserverToken)
}
}
}

View file

@ -41,229 +41,231 @@ struct HomeView: View {
var body: some View {
NavigationView {
ScrollView {
if !continueWatchingItems.isEmpty {
VStack(alignment: .leading) {
Text("Continue Watching")
.font(.headline)
.padding(.horizontal, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
ForEach(Array(continueWatchingItems.reversed())) { item in
Button(action: {
if UserDefaults.standard.string(forKey: "externalPlayer") == "Sora" {
let customMediaPlayer = CustomMediaPlayerViewController(
module: item.module,
urlString: item.streamUrl,
fullUrl: item.fullUrl,
title: item.mediaTitle,
episodeNumber: item.episodeNumber,
onWatchNext: { },
subtitlesURL: item.subtitles,
episodeImageUrl: item.imageUrl
)
customMediaPlayer.modalPresentationStyle = .fullScreen
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(customMediaPlayer, animated: true, completion: nil)
VStack {
ScrollView {
if !continueWatchingItems.isEmpty {
LazyVStack(alignment: .leading) {
Text("Continue Watching")
.font(.headline)
.padding(.horizontal, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
ForEach(Array(continueWatchingItems.reversed())) { item in
Button(action: {
if UserDefaults.standard.string(forKey: "externalPlayer") == "Sora" {
let customMediaPlayer = CustomMediaPlayerViewController(
module: item.module,
urlString: item.streamUrl,
fullUrl: item.fullUrl,
title: item.mediaTitle,
episodeNumber: item.episodeNumber,
onWatchNext: { },
subtitlesURL: item.subtitles,
episodeImageUrl: item.imageUrl
)
customMediaPlayer.modalPresentationStyle = .fullScreen
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
findTopViewController.findViewController(rootVC).present(customMediaPlayer, animated: true, completion: nil)
}
} else {
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
videoPlayerViewController.streamUrl = item.streamUrl
videoPlayerViewController.fullUrl = item.fullUrl
videoPlayerViewController.episodeImageUrl = item.imageUrl
videoPlayerViewController.episodeNumber = item.episodeNumber
videoPlayerViewController.mediaTitle = item.mediaTitle
videoPlayerViewController.subtitles = item.subtitles ?? ""
videoPlayerViewController.modalPresentationStyle = .fullScreen
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
findTopViewController.findViewController(rootVC).present(videoPlayerViewController, animated: true, completion: nil)
}
}
} else {
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
videoPlayerViewController.streamUrl = item.streamUrl
videoPlayerViewController.fullUrl = item.fullUrl
videoPlayerViewController.episodeImageUrl = item.imageUrl
videoPlayerViewController.episodeNumber = item.episodeNumber
videoPlayerViewController.mediaTitle = item.mediaTitle
videoPlayerViewController.subtitles = item.subtitles ?? ""
videoPlayerViewController.modalPresentationStyle = .fullScreen
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
}) {
VStack(alignment: .leading) {
ZStack {
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
.placeholder {
RoundedRectangle(cornerRadius: 10)
.fill(Color.gray.opacity(0.3))
.frame(width: 240, height: 135)
.shimmering()
}
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
.resizable()
.aspectRatio(16/9, contentMode: .fill)
.frame(width: 240, height: 135)
.cornerRadius(10)
.clipped()
.overlay(
KFImage(URL(string: item.module.metadata.iconUrl))
.resizable()
.frame(width: 24, height: 24)
.cornerRadius(4)
.padding(4),
alignment: .topLeading
)
}
.overlay(
ZStack {
Rectangle()
.fill(Color.black.opacity(0.3))
.blur(radius: 3)
.frame(height: 30)
ProgressView(value: item.progress)
.progressViewStyle(LinearProgressViewStyle(tint: .white))
.padding(.horizontal, 8)
.scaleEffect(x: 1, y: 1.5, anchor: .center)
},
alignment: .bottom
)
VStack(alignment: .leading) {
Text("Episode \(item.episodeNumber)")
.font(.caption)
.lineLimit(1)
.foregroundColor(.secondary)
Text(item.mediaTitle)
.font(.caption)
.lineLimit(2)
.foregroundColor(.primary)
.multilineTextAlignment(.leading)
}
.padding(.horizontal, 8)
}
.frame(width: 250, height: 190)
}
.contextMenu {
Button(action: { markContinueWatchingItemAsWatched(item: item) }) {
Label("Mark as Watched", systemImage: "checkmark.circle")
}
Button(role: .destructive, action: { removeContinueWatchingItem(item: item) }) {
Label("Remove Item", systemImage: "trash")
}
}
}) {
VStack(alignment: .leading) {
ZStack {
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
}
}
.padding(.horizontal, 8)
}
.frame(height: 190)
}
}
VStack(alignment: .leading, spacing: 16) {
HStack(alignment: .bottom, spacing: 5) {
Text("Seasonal")
.font(.headline)
Text("of \(currentDeviceSeasonAndYear.season) \(String(format: "%d", currentDeviceSeasonAndYear.year))")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.horizontal, 8)
.padding(.top, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
if aniListItems.isEmpty {
ForEach(0..<5, id: \.self) { _ in
HomeSkeletonCell()
}
} else {
ForEach(aniListItems, id: \.id) { item in
NavigationLink(destination: AniListDetailsView(animeID: item.id)) {
VStack {
KFImage(URL(string: item.coverImage.large))
.placeholder {
RoundedRectangle(cornerRadius: 10)
.fill(Color.gray.opacity(0.3))
.frame(width: 240, height: 135)
.frame(width: 130, height: 195)
.shimmering()
}
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
.resizable()
.aspectRatio(16/9, contentMode: .fill)
.frame(width: 240, height: 135)
.scaledToFill()
.frame(width: 130, height: 195)
.cornerRadius(10)
.clipped()
.overlay(
KFImage(URL(string: item.module.metadata.iconUrl))
.resizable()
.frame(width: 24, height: 24)
.cornerRadius(4)
.padding(4),
alignment: .topLeading
)
}
.overlay(
ZStack {
Rectangle()
.fill(Color.black.opacity(0.3))
.blur(radius: 3)
.frame(height: 30)
ProgressView(value: item.progress)
.progressViewStyle(LinearProgressViewStyle(tint: .white))
.padding(.horizontal, 8)
.scaleEffect(x: 1, y: 1.5, anchor: .center)
},
alignment: .bottom
)
VStack(alignment: .leading) {
Text("Episode \(item.episodeNumber)")
.font(.caption)
.lineLimit(1)
.foregroundColor(.secondary)
Text(item.mediaTitle)
Text(item.title.romaji)
.font(.caption)
.lineLimit(2)
.frame(width: 130)
.lineLimit(1)
.multilineTextAlignment(.center)
.foregroundColor(.primary)
.multilineTextAlignment(.leading)
}
.padding(.horizontal, 8)
}
.frame(width: 250, height: 190)
}
.contextMenu {
Button(action: { markContinueWatchingItemAsWatched(item: item) }) {
Label("Mark as Watched", systemImage: "checkmark.circle")
}
Button(role: .destructive, action: { removeContinueWatchingItem(item: item) }) {
Label("Remove Item", systemImage: "trash")
}
}
}
}
.padding(.horizontal, 8)
}
.frame(height: 190)
}
}
VStack(alignment: .leading, spacing: 16) {
HStack(alignment: .bottom, spacing: 5) {
Text("Seasonal")
.font(.headline)
Text("of \(currentDeviceSeasonAndYear.season) \(String(format: "%d", currentDeviceSeasonAndYear.year))")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.horizontal, 8)
.padding(.top, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
if aniListItems.isEmpty {
ForEach(0..<5, id: \.self) { _ in
HomeSkeletonCell()
}
} else {
ForEach(aniListItems, id: \.id) { item in
NavigationLink(destination: AniListDetailsView(animeID: item.id)) {
VStack {
KFImage(URL(string: item.coverImage.large))
.placeholder {
RoundedRectangle(cornerRadius: 10)
.fill(Color.gray.opacity(0.3))
.frame(width: 130, height: 195)
.shimmering()
}
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
.resizable()
.scaledToFill()
.frame(width: 130, height: 195)
.cornerRadius(10)
.clipped()
Text(item.title.romaji)
.font(.caption)
.frame(width: 130)
.lineLimit(1)
.multilineTextAlignment(.center)
.foregroundColor(.primary)
HStack(alignment: .bottom, spacing: 5) {
Text("Trending")
.font(.headline)
Text("on \(trendingDateString)")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.horizontal, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
if trendingItems.isEmpty {
ForEach(0..<5, id: \.self) { _ in
HomeSkeletonCell()
}
} else {
ForEach(trendingItems, id: \.id) { item in
NavigationLink(destination: AniListDetailsView(animeID: item.id)) {
VStack {
KFImage(URL(string: item.coverImage.large))
.placeholder {
RoundedRectangle(cornerRadius: 10)
.fill(Color.gray.opacity(0.3))
.frame(width: 130, height: 195)
.shimmering()
}
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
.resizable()
.scaledToFill()
.frame(width: 130, height: 195)
.cornerRadius(10)
.clipped()
Text(item.title.romaji)
.font(.caption)
.frame(width: 130)
.lineLimit(1)
.multilineTextAlignment(.center)
.foregroundColor(.primary)
}
}
}
}
}
.padding(.horizontal, 8)
}
.padding(.horizontal, 8)
}
HStack(alignment: .bottom, spacing: 5) {
Text("Trending")
.font(.headline)
Text("on \(trendingDateString)")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.horizontal, 8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 8) {
if trendingItems.isEmpty {
ForEach(0..<5, id: \.self) { _ in
HomeSkeletonCell()
}
} else {
ForEach(trendingItems, id: \.id) { item in
NavigationLink(destination: AniListDetailsView(animeID: item.id)) {
VStack {
KFImage(URL(string: item.coverImage.large))
.placeholder {
RoundedRectangle(cornerRadius: 10)
.fill(Color.gray.opacity(0.3))
.frame(width: 130, height: 195)
.shimmering()
}
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
.resizable()
.scaledToFill()
.frame(width: 130, height: 195)
.cornerRadius(10)
.clipped()
Text(item.title.romaji)
.font(.caption)
.frame(width: 130)
.lineLimit(1)
.multilineTextAlignment(.center)
.foregroundColor(.primary)
}
}
}
}
}
.padding(.horizontal, 8)
.padding(.bottom, 16)
}
.navigationTitle("Home")
}
.onAppear {
continueWatchingItems = ContinueWatchingManager.shared.fetchItems()
AnilistServiceSeasonalAnime().fetchSeasonalAnime { items in
if let items = items {
aniListItems = items
}
}
.padding(.bottom, 16)
}
.navigationTitle("Home")
}
.onAppear {
continueWatchingItems = ContinueWatchingManager.shared.fetchItems()
AnilistServiceSeasonalAnime().fetchSeasonalAnime { items in
if let items = items {
aniListItems = items
}
}
AnilistServiceTrendingAnime().fetchTrendingAnime { items in
if let items = items {
trendingItems = items
AnilistServiceTrendingAnime().fetchTrendingAnime { items in
if let items = items {
trendingItems = items
}
}
}
}

View file

@ -519,7 +519,7 @@ struct MediaInfoView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(customMediaPlayer, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(customMediaPlayer, animated: true, completion: nil)
}
return
default:
@ -541,7 +541,7 @@ struct MediaInfoView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(videoPlayerViewController, animated: true, completion: nil)
}
}
}

View file

@ -31,6 +31,8 @@
133D7C942D2BE2640075467E /* JSController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C8B2D2BE2640075467E /* JSController.swift */; };
133D7C972D2BE2AF0075467E /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 133D7C962D2BE2AF0075467E /* Kingfisher */; };
133F55BB2D33B55100E08EEA /* LibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133F55BA2D33B55100E08EEA /* LibraryManager.swift */; };
1359ED142D76F49900C13034 /* finTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1359ED132D76F49900C13034 /* finTopView.swift */; };
1359ED1A2D76FA7D00C13034 /* Drops in Frameworks */ = {isa = PBXBuildFile; productRef = 1359ED192D76FA7D00C13034 /* Drops */; };
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */; };
136F21B92D5B8DD8006409AC /* AniList-MediaInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136F21B82D5B8DD8006409AC /* AniList-MediaInfo.swift */; };
136F21BC2D5B8F29006409AC /* AniList-DetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136F21BB2D5B8F29006409AC /* AniList-DetailsView.swift */; };
@ -44,7 +46,6 @@
13C0E5EC2D5F85F800E7F619 /* ContinueWatchingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C0E5EB2D5F85F800E7F619 /* ContinueWatchingItem.swift */; };
13CBA0882D60F19C00EFE70A /* VTTSubtitlesLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CBA0872D60F19C00EFE70A /* VTTSubtitlesLoader.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 */; };
13DC0C462D302C7500D0F966 /* VideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13DC0C452D302C7500D0F966 /* VideoPlayer.swift */; };
@ -81,6 +82,7 @@
133D7C892D2BE2640075467E /* Modules.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Modules.swift; sourceTree = "<group>"; };
133D7C8B2D2BE2640075467E /* JSController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSController.swift; sourceTree = "<group>"; };
133F55BA2D33B55100E08EEA /* LibraryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryManager.swift; sourceTree = "<group>"; };
1359ED132D76F49900C13034 /* finTopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = finTopView.swift; sourceTree = "<group>"; };
135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewPlayer.swift; sourceTree = "<group>"; };
136F21B82D5B8DD8006409AC /* AniList-MediaInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-MediaInfo.swift"; sourceTree = "<group>"; };
136F21BB2D5B8F29006409AC /* AniList-DetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-DetailsView.swift"; sourceTree = "<group>"; };
@ -110,7 +112,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
13D842522D4523B800EBBFA6 /* Drops in Frameworks */,
1359ED1A2D76FA7D00C13034 /* Drops in Frameworks */,
133D7C972D2BE2AF0075467E /* Kingfisher in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -266,6 +268,7 @@
children = (
1327FBA82D758DEA00FC6689 /* UIDevice+Model.swift */,
133D7C872D2BE2640075467E /* URLSession.swift */,
1359ED132D76F49900C13034 /* finTopView.swift */,
13CBEFD92D5F7D1200D011EE /* String.swift */,
13103E8A2D58E028000F0673 /* View.swift */,
);
@ -405,7 +408,7 @@
name = Sulfur;
packageProductDependencies = (
133D7C962D2BE2AF0075467E /* Kingfisher */,
13D842512D4523B800EBBFA6 /* Drops */,
1359ED192D76FA7D00C13034 /* Drops */,
);
productName = Sora;
productReference = 133D7C6A2D2BE2500075467E /* Sulfur.app */;
@ -436,7 +439,7 @@
mainGroup = 133D7C612D2BE2500075467E;
packageReferences = (
133D7C952D2BE2AF0075467E /* XCRemoteSwiftPackageReference "Kingfisher" */,
13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */,
1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */,
);
productRefGroup = 133D7C6B2D2BE2500075467E /* Products */;
projectDirPath = "";
@ -467,6 +470,7 @@
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */,
1327FBA72D758CEA00FC6689 /* Analytics.swift in Sources */,
13DC0C462D302C7500D0F966 /* VideoPlayer.swift in Sources */,
1359ED142D76F49900C13034 /* finTopView.swift in Sources */,
1399FAD62D3AB3DB00E97C31 /* Logger.swift in Sources */,
13B7F4C12D58FFDD0045714A /* Shimmer.swift in Sources */,
139935662D468C450065CEFF /* ModuleManager.swift in Sources */,
@ -646,6 +650,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Sora/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Sora;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -686,6 +691,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Sora/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Sora;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -742,12 +748,12 @@
version = 7.9.1;
};
};
13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */ = {
1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/omaralbeik/Drops.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.0;
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
@ -758,9 +764,9 @@
package = 133D7C952D2BE2AF0075467E /* XCRemoteSwiftPackageReference "Kingfisher" */;
productName = Kingfisher;
};
13D842512D4523B800EBBFA6 /* Drops */ = {
1359ED192D76FA7D00C13034 /* Drops */ = {
isa = XCSwiftPackageProductDependency;
package = 13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */;
package = 1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */;
productName = Drops;
};
/* End XCSwiftPackageProductDependency section */

View file

@ -5,9 +5,9 @@
"package": "Drops",
"repositoryURL": "https://github.com/omaralbeik/Drops.git",
"state": {
"branch": null,
"revision": "a183ee6f79f21c940092a19c2cba756555422371",
"version": "1.7.0"
"branch": "main",
"revision": "5824681795286c36bdc4a493081a63e64e2a064e",
"version": null
}
},
{