mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
im even dumber 😭
This commit is contained in:
parent
05c9722142
commit
117639514e
5 changed files with 38 additions and 77 deletions
|
|
@ -32,7 +32,7 @@ struct SoraApp: App {
|
|||
var body: some Scene {
|
||||
WindowGroup {
|
||||
Group {
|
||||
if !UserDefaults.standard.bool(forKey: "hideSplashScreenEnable") {
|
||||
if !UserDefaults.standard.bool(forKey: "hideSplashScreen") {
|
||||
SplashScreenView()
|
||||
} else {
|
||||
ContentView()
|
||||
|
|
@ -102,26 +102,4 @@ struct SoraApp: App {
|
|||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc class AppInfo: NSObject {
|
||||
@objc static let shared = AppInfo()
|
||||
|
||||
@objc func getBundleIdentifier() -> String {
|
||||
return Bundle.main.bundleIdentifier ?? "me.cranci.sulfur"
|
||||
}
|
||||
|
||||
@objc func getDisplayName() -> String {
|
||||
return Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
|
||||
}
|
||||
|
||||
@objc func isValidApp() -> Bool {
|
||||
let bundleId = getBundleIdentifier().lowercased()
|
||||
let displayName = getDisplayName().lowercased()
|
||||
|
||||
let hasValidBundleId = bundleId.contains("sulfur")
|
||||
let hasValidDisplayName = displayName == "sora" || displayName == "sulfur"
|
||||
|
||||
return hasValidBundleId && hasValidDisplayName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,6 @@ import JavaScriptCore
|
|||
extension JSContext {
|
||||
func setupConsoleLogging() {
|
||||
let consoleObject = JSValue(newObjectIn: self)
|
||||
let appInfoBridge = AppInfo.shared
|
||||
|
||||
self.setObject(appInfoBridge, forKeyedSubscript: "AppInfo" as NSString)
|
||||
|
||||
let consoleLogFunction: @convention(block) (String) -> Void = { message in
|
||||
Logger.shared.log(message, type: "Debug")
|
||||
|
|
@ -275,10 +272,33 @@ extension JSContext {
|
|||
self.setObject(atobFunction, forKeyedSubscript: "atob" as NSString)
|
||||
}
|
||||
|
||||
func setupAppInfo() {
|
||||
let bundle = Bundle.main
|
||||
let appInfo = JSValue(newObjectIn: self)
|
||||
|
||||
appInfo?.setValue(bundle.bundleIdentifier ?? "", forProperty: "bundleId")
|
||||
appInfo?.setValue(
|
||||
bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
|
||||
?? bundle.object(forInfoDictionaryKey: "CFBundleName") as? String
|
||||
?? "",
|
||||
forProperty: "displayName"
|
||||
)
|
||||
|
||||
let isValidApp: @convention(block) () -> Bool = {
|
||||
guard let app = appInfo else { return false }
|
||||
return !(app.forProperty("bundleId").toString().isEmpty ||
|
||||
app.forProperty("displayName").toString().isEmpty)
|
||||
}
|
||||
|
||||
appInfo?.setObject(isValidApp, forKeyedSubscript: "isValidApp" as NSString)
|
||||
self.setObject(appInfo, forKeyedSubscript: "AppInfo" as NSString)
|
||||
}
|
||||
|
||||
func setupJavaScriptEnvironment() {
|
||||
setupConsoleLogging()
|
||||
setupNativeFetch()
|
||||
setupFetchV2()
|
||||
setupBase64Functions()
|
||||
setupAppInfo()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@ import NukeUI
|
|||
import SwiftUI
|
||||
import AVFoundation
|
||||
|
||||
|
||||
struct EpisodeCell: View {
|
||||
|
||||
|
||||
let episodeIndex: Int
|
||||
let episode: String
|
||||
let episodeID: Int
|
||||
|
|
@ -26,16 +23,13 @@ struct EpisodeCell: View {
|
|||
let tmdbID: Int?
|
||||
let seasonNumber: Int?
|
||||
|
||||
|
||||
let isMultiSelectMode: Bool
|
||||
let isSelected: Bool
|
||||
let onSelectionChanged: ((Bool) -> Void)?
|
||||
|
||||
|
||||
let onTap: (String) -> Void
|
||||
let onMarkAllPrevious: () -> Void
|
||||
|
||||
|
||||
@State private var episodeTitle = ""
|
||||
@State private var episodeImageUrl = ""
|
||||
@State private var isLoading = true
|
||||
|
|
@ -45,23 +39,19 @@ struct EpisodeCell: View {
|
|||
@State private var downloadAnimationScale: CGFloat = 1.0
|
||||
@State private var activeDownloadTask: AVAssetDownloadTask?
|
||||
|
||||
|
||||
@State private var swipeOffset: CGFloat = 0
|
||||
@State private var isShowingActions = false
|
||||
@State private var actionButtonWidth: CGFloat = 60
|
||||
|
||||
|
||||
@State private var retryAttempts = 0
|
||||
private let maxRetryAttempts = 3
|
||||
private let initialBackoffDelay: TimeInterval = 1.0
|
||||
|
||||
|
||||
@ObservedObject private var jsController = JSController.shared
|
||||
@EnvironmentObject var moduleManager: ModuleManager
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
@AppStorage("selectedAppearance") private var selectedAppearance: Appearance = .system
|
||||
|
||||
|
||||
init(
|
||||
episodeIndex: Int,
|
||||
episode: String,
|
||||
|
|
@ -98,7 +88,7 @@ struct EpisodeCell: View {
|
|||
self.tmdbID = tmdbID
|
||||
self.seasonNumber = seasonNumber
|
||||
|
||||
|
||||
|
||||
let isLightMode = (UserDefaults.standard.string(forKey: "selectedAppearance") == "light") ||
|
||||
((UserDefaults.standard.string(forKey: "selectedAppearance") == "system") &&
|
||||
UITraitCollection.current.userInterfaceStyle == .light)
|
||||
|
|
@ -110,13 +100,10 @@ struct EpisodeCell: View {
|
|||
(isLightMode ? defaultLightBanner : defaultDarkBanner) : defaultBannerImage
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
|
||||
actionButtonsBackground
|
||||
|
||||
|
||||
episodeCellContent
|
||||
.offset(x: swipeOffset)
|
||||
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: swipeOffset)
|
||||
|
|
@ -146,7 +133,6 @@ struct EpisodeCell: View {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private extension EpisodeCell {
|
||||
|
||||
var actionButtonsBackground: some View {
|
||||
|
|
@ -365,7 +351,7 @@ private extension EpisodeCell {
|
|||
}
|
||||
|
||||
func calculateMaxSwipeDistance() -> CGFloat {
|
||||
var buttonCount = 1
|
||||
var buttonCount = 1
|
||||
|
||||
if progress <= 0.9 { buttonCount += 1 }
|
||||
if progress != 0 { buttonCount += 1 }
|
||||
|
|
@ -796,7 +782,7 @@ private extension EpisodeCell {
|
|||
self.retryAttempts = 0
|
||||
|
||||
if UserDefaults.standard.object(forKey: "fetchEpisodeMetadata") == nil ||
|
||||
UserDefaults.standard.bool(forKey: "fetchEpisodeMetadata") {
|
||||
UserDefaults.standard.bool(forKey: "fetchEpisodeMetadata") {
|
||||
self.episodeTitle = title["en"] ?? title.values.first ?? ""
|
||||
|
||||
if !image.isEmpty {
|
||||
|
|
@ -825,9 +811,9 @@ private extension EpisodeCell {
|
|||
let stillPath = json["still_path"] as? String
|
||||
|
||||
let imageUrl = stillPath.map { path in
|
||||
tmdbImageWidth == "original"
|
||||
? "https://image.tmdb.org/t/p/original\(path)"
|
||||
: "https://image.tmdb.org/t/p/w\(tmdbImageWidth)\(path)"
|
||||
tmdbImageWidth == "original"
|
||||
? "https://image.tmdb.org/t/p/original\(path)"
|
||||
: "https://image.tmdb.org/t/p/w\(tmdbImageWidth)\(path)"
|
||||
} ?? ""
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import NukeUI
|
|||
import SwiftUI
|
||||
import SafariServices
|
||||
|
||||
|
||||
private let tmdbFetcher = TMDBFetcher()
|
||||
|
||||
struct MediaItem: Identifiable {
|
||||
|
|
@ -19,9 +18,6 @@ struct MediaItem: Identifiable {
|
|||
let airdate: String
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct MediaInfoView: View {
|
||||
let title: String
|
||||
@State var imageUrl: String
|
||||
|
|
@ -183,8 +179,6 @@ struct MediaInfoView: View {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - View Builders
|
||||
|
||||
@ViewBuilder
|
||||
private var navigationOverlay: some View {
|
||||
VStack {
|
||||
|
|
@ -444,8 +438,6 @@ struct MediaInfoView: View {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Computed Properties for Single Episode
|
||||
|
||||
private var isBookmarked: Bool {
|
||||
libraryManager.isBookmarked(href: href, moduleName: module.metadata.sourceName)
|
||||
}
|
||||
|
|
@ -470,8 +462,6 @@ struct MediaInfoView: View {
|
|||
return "Mark watched"
|
||||
}
|
||||
|
||||
// MARK: - Episodes Section
|
||||
|
||||
@ViewBuilder
|
||||
private var episodesSection: some View {
|
||||
if episodeLinks.count != 1 {
|
||||
|
|
@ -638,8 +628,6 @@ struct MediaInfoView: View {
|
|||
.padding(.vertical, 50)
|
||||
}
|
||||
|
||||
// MARK: - Menu and Action Buttons
|
||||
|
||||
@ViewBuilder
|
||||
private var sourceButton: some View {
|
||||
Button(action: { openSafariViewController(with: href) }) {
|
||||
|
|
@ -737,8 +725,6 @@ struct MediaInfoView: View {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Setup and Lifecycle Methods
|
||||
|
||||
private func setupViewOnAppear() {
|
||||
buttonRefreshTrigger.toggle()
|
||||
tabBarController.hideTabBar()
|
||||
|
|
@ -790,8 +776,6 @@ struct MediaInfoView: View {
|
|||
showLoadingAlert = false
|
||||
}
|
||||
|
||||
// MARK: - Action Methods
|
||||
|
||||
private func copyTitleToClipboard() {
|
||||
UIPasteboard.general.string = title
|
||||
DropManager.shared.showDrop(
|
||||
|
|
@ -895,8 +879,6 @@ struct MediaInfoView: View {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Menu Action Methods
|
||||
|
||||
private func handleAniListMatch(selectedID: Int) {
|
||||
self.customAniListID = selectedID
|
||||
self.itemID = selectedID
|
||||
|
|
@ -951,8 +933,6 @@ struct MediaInfoView: View {
|
|||
)
|
||||
}
|
||||
|
||||
// MARK: - Utility Methods
|
||||
|
||||
private func getBannerImageBasedOnAppearance() -> String {
|
||||
let isLightMode = selectedAppearance == .light || (selectedAppearance == .system && colorScheme == .light)
|
||||
return isLightMode
|
||||
|
|
@ -967,7 +947,7 @@ struct MediaInfoView: View {
|
|||
} else {
|
||||
selectedRange = generateRanges().first ?? 0..<episodeChunkSize
|
||||
}
|
||||
|
||||
|
||||
if let savedSeason = UserDefaults.standard.object(forKey: selectedSeasonKey) as? Int {
|
||||
let maxIndex = max(0, groupedEpisodes().count - 1)
|
||||
selectedSeason = min(savedSeason, maxIndex)
|
||||
|
|
@ -1017,8 +997,6 @@ struct MediaInfoView: View {
|
|||
return cleaned.isEmpty ? "Unknown" : cleaned
|
||||
}
|
||||
|
||||
// MARK: - Playback Methods
|
||||
|
||||
private func playFirstUnwatchedEpisode() {
|
||||
let indices = finishedAndUnfinishedIndices()
|
||||
let finished = indices.finished
|
||||
|
|
@ -1069,9 +1047,9 @@ struct MediaInfoView: View {
|
|||
private func selectNextEpisode() {
|
||||
guard let currentIndex = episodeLinks.firstIndex(where: { $0.number == selectedEpisodeNumber }),
|
||||
currentIndex + 1 < episodeLinks.count else {
|
||||
Logger.shared.log("No more episodes to play", type: "Info")
|
||||
return
|
||||
}
|
||||
Logger.shared.log("No more episodes to play", type: "Info")
|
||||
return
|
||||
}
|
||||
|
||||
let nextEpisode = episodeLinks[currentIndex + 1]
|
||||
selectedEpisodeNumber = nextEpisode.number
|
||||
|
|
@ -1084,8 +1062,6 @@ struct MediaInfoView: View {
|
|||
)
|
||||
}
|
||||
|
||||
// MARK: - Episode Progress Management
|
||||
|
||||
private func markAllPreviousEpisodesAsWatched(ep: EpisodeLink, inSeason: Bool) {
|
||||
let userDefaults = UserDefaults.standard
|
||||
var updates = [String: Double]()
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ struct SettingsViewGeneral: View {
|
|||
@AppStorage("refreshModulesOnLaunch") private var refreshModulesOnLaunch: Bool = true
|
||||
@AppStorage("fetchEpisodeMetadata") private var fetchEpisodeMetadata: Bool = true
|
||||
@AppStorage("analyticsEnabled") private var analyticsEnabled: Bool = false
|
||||
@AppStorage("hideSplashScreenEnable") private var hideSplashScreenEnable: Bool = false
|
||||
@AppStorage("hideSplashScreen") private var hideSplashScreenEnable: Bool = false
|
||||
@AppStorage("metadataProviders") private var metadataProviders: String = "TMDB"
|
||||
@AppStorage("tmdbImageWidth") private var TMDBimageWidht: String = "original"
|
||||
@AppStorage("mediaColumnsPortrait") private var mediaColumnsPortrait: Int = 2
|
||||
|
|
@ -185,7 +185,8 @@ struct SettingsViewGeneral: View {
|
|||
SettingsToggleRow(
|
||||
icon: "wand.and.rays.inverse",
|
||||
title: "Hide Splash Screen",
|
||||
isOn: $hideSplashScreenEnable
|
||||
isOn: $hideSplashScreenEnable,
|
||||
showDivider: false
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue