mirror of
https://github.com/cranci1/Sora.git
synced 2026-05-16 06:42:15 +00:00
Merge branch 'dev' into dev
This commit is contained in:
commit
63c7b8229b
9 changed files with 164 additions and 26 deletions
|
|
@ -2,6 +2,10 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||||
|
<array/>
|
||||||
|
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
||||||
|
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.client</key>
|
<key>com.apple.security.network.client</key>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ struct SoraApp: App {
|
||||||
@StateObject private var moduleManager = ModuleManager()
|
@StateObject private var moduleManager = ModuleManager()
|
||||||
@StateObject private var librarykManager = LibraryManager()
|
@StateObject private var librarykManager = LibraryManager()
|
||||||
|
|
||||||
|
init() {
|
||||||
|
_ = iCloudSyncManager.shared
|
||||||
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
ContentView()
|
ContentView()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,13 @@ class ContinueWatchingManager {
|
||||||
static let shared = ContinueWatchingManager()
|
static let shared = ContinueWatchingManager()
|
||||||
private let storageKey = "continueWatchingItems"
|
private let storageKey = "continueWatchingItems"
|
||||||
|
|
||||||
private init() {}
|
private init() {
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(handleiCloudSync), name: .iCloudSyncDidComplete, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleiCloudSync() {
|
||||||
|
NotificationCenter.default.post(name: .ContinueWatchingDidUpdate, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
func save(item: ContinueWatchingItem) {
|
func save(item: ContinueWatchingItem) {
|
||||||
if item.progress >= 0.9 {
|
if item.progress >= 0.9 {
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,6 @@ import Foundation
|
||||||
import FFmpegSupport
|
import FFmpegSupport
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
extension Notification.Name {
|
|
||||||
static let DownloadManagerStatusUpdate = Notification.Name("DownloadManagerStatusUpdate")
|
|
||||||
}
|
|
||||||
|
|
||||||
class DownloadManager {
|
class DownloadManager {
|
||||||
static let shared = DownloadManager()
|
static let shared = DownloadManager()
|
||||||
|
|
||||||
|
|
|
||||||
14
Sora/Utils/Extensions/Notification+Name.swift
Normal file
14
Sora/Utils/Extensions/Notification+Name.swift
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// Notification+Name.swift
|
||||||
|
// Sulfur
|
||||||
|
//
|
||||||
|
// Created by Francesco on 17/04/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Notification.Name {
|
||||||
|
static let iCloudSyncDidComplete = Notification.Name("iCloudSyncDidComplete")
|
||||||
|
static let ContinueWatchingDidUpdate = Notification.Name("ContinueWatchingDidUpdate")
|
||||||
|
static let DownloadManagerStatusUpdate = Notification.Name("DownloadManagerStatusUpdate")
|
||||||
|
}
|
||||||
|
|
@ -190,7 +190,6 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
view.backgroundColor = .black
|
view.backgroundColor = .black
|
||||||
|
|
||||||
setupHoldGesture()
|
setupHoldGesture()
|
||||||
setInitialPlayerRate()
|
|
||||||
loadSubtitleSettings()
|
loadSubtitleSettings()
|
||||||
setupPlayerViewController()
|
setupPlayerViewController()
|
||||||
setupControls()
|
setupControls()
|
||||||
|
|
@ -226,7 +225,6 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
|
|
||||||
volumeViewModel.value = Double(audioSession.outputVolume)
|
volumeViewModel.value = Double(audioSession.outputVolume)
|
||||||
|
|
||||||
|
|
||||||
volumeObserver = audioSession.observe(\.outputVolume, options: [.new]) { [weak self] session, change in
|
volumeObserver = audioSession.observe(\.outputVolume, options: [.new]) { [weak self] session, change in
|
||||||
guard let newVol = change.newValue else { return }
|
guard let newVol = change.newValue else { return }
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
@ -240,8 +238,6 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
playerViewController.allowsVideoFrameAnalysis = false
|
playerViewController.allowsVideoFrameAnalysis = false
|
||||||
}
|
}
|
||||||
|
|
||||||
player.play()
|
|
||||||
|
|
||||||
if let url = subtitlesURL, !url.isEmpty {
|
if let url = subtitlesURL, !url.isEmpty {
|
||||||
subtitlesLoader.load(from: url)
|
subtitlesLoader.load(from: url)
|
||||||
}
|
}
|
||||||
|
|
@ -293,36 +289,36 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
player?.play()
|
||||||
|
setInitialPlayerRate()
|
||||||
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
NotificationCenter.default.addObserver(self,
|
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidChange), name: .AVPlayerItemNewAccessLogEntry, object: nil)
|
||||||
selector: #selector(playerItemDidChange),
|
|
||||||
name: .AVPlayerItemNewAccessLogEntry,
|
|
||||||
object: nil)
|
|
||||||
|
|
||||||
skip85Button?.isHidden = !isSkip85Visible
|
skip85Button?.isHidden = !isSkip85Visible
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
super.viewWillDisappear(animated)
|
super.viewWillDisappear(animated)
|
||||||
|
if let playbackSpeed = player?.rate {
|
||||||
loadedTimeRangesObservation?.invalidate()
|
UserDefaults.standard.set(playbackSpeed, forKey: "lastPlaybackSpeed")
|
||||||
loadedTimeRangesObservation = nil
|
}
|
||||||
|
|
||||||
if let token = timeObserverToken {
|
if let token = timeObserverToken {
|
||||||
player.removeTimeObserver(token)
|
player.removeTimeObserver(token)
|
||||||
timeObserverToken = nil
|
timeObserverToken = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadedTimeRangesObservation?.invalidate()
|
||||||
|
loadedTimeRangesObservation = nil
|
||||||
|
|
||||||
updateTimer?.invalidate()
|
updateTimer?.invalidate()
|
||||||
inactivityTimer?.invalidate()
|
inactivityTimer?.invalidate()
|
||||||
|
|
||||||
player.pause()
|
player.pause()
|
||||||
|
|
||||||
if let playbackSpeed = player?.rate {
|
|
||||||
UserDefaults.standard.set(playbackSpeed, forKey: "lastPlaybackSpeed")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
|
|
@ -1098,7 +1094,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
let finalSkip = holdValue > 0 ? holdValue : 30
|
let finalSkip = holdValue > 0 ? holdValue : 30
|
||||||
currentTimeVal = max(currentTimeVal - finalSkip, 0)
|
currentTimeVal = max(currentTimeVal - finalSkip, 0)
|
||||||
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
||||||
guard let self = self else { return }
|
guard self != nil else { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1109,7 +1105,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
let finalSkip = holdValue > 0 ? holdValue : 30
|
let finalSkip = holdValue > 0 ? holdValue : 30
|
||||||
currentTimeVal = min(currentTimeVal + finalSkip, duration)
|
currentTimeVal = min(currentTimeVal + finalSkip, duration)
|
||||||
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
||||||
guard let self = self else { return }
|
guard self != nil else { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1119,7 +1115,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
let finalSkip = skipValue > 0 ? skipValue : 10
|
let finalSkip = skipValue > 0 ? skipValue : 10
|
||||||
currentTimeVal = max(currentTimeVal - finalSkip, 0)
|
currentTimeVal = max(currentTimeVal - finalSkip, 0)
|
||||||
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
||||||
guard let self = self else { return }
|
guard self != nil else { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1128,7 +1124,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
||||||
let finalSkip = skipValue > 0 ? skipValue : 10
|
let finalSkip = skipValue > 0 ? skipValue : 10
|
||||||
currentTimeVal = min(currentTimeVal + finalSkip, duration)
|
currentTimeVal = min(currentTimeVal + finalSkip, duration)
|
||||||
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
|
||||||
guard let self = self else { return } }
|
guard self != nil else { return } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func handleDoubleTap(_ gesture: UITapGestureRecognizer) {
|
@objc func handleDoubleTap(_ gesture: UITapGestureRecognizer) {
|
||||||
|
|
|
||||||
94
Sora/Utils/iCloudSyncManager/iCloudSyncManager.swift
Normal file
94
Sora/Utils/iCloudSyncManager/iCloudSyncManager.swift
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
//
|
||||||
|
// iCloudSyncManager.swift
|
||||||
|
// Sulfur
|
||||||
|
//
|
||||||
|
// Created by Francesco on 17/04/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class iCloudSyncManager {
|
||||||
|
static let shared = iCloudSyncManager()
|
||||||
|
|
||||||
|
private let defaultsToSync: [String] = [
|
||||||
|
"externalPlayer",
|
||||||
|
"alwaysLandscape",
|
||||||
|
"rememberPlaySpeed",
|
||||||
|
"holdSpeedPlayer",
|
||||||
|
"skipIncrement",
|
||||||
|
"skipIncrementHold",
|
||||||
|
"holdForPauseEnabled",
|
||||||
|
"skip85Visible",
|
||||||
|
"doubleTapSeekEnabled",
|
||||||
|
"selectedModuleId",
|
||||||
|
"mediaColumnsPortrait",
|
||||||
|
"mediaColumnsLandscape",
|
||||||
|
"sendPushUpdates",
|
||||||
|
"sendTraktUpdates",
|
||||||
|
"bookmarkedItems",
|
||||||
|
"continueWatchingItems"
|
||||||
|
]
|
||||||
|
|
||||||
|
private init() {
|
||||||
|
setupSync()
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(willEnterBackground), name: UIApplication.willResignActiveNotification, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupSync() {
|
||||||
|
NSUbiquitousKeyValueStore.default.synchronize()
|
||||||
|
|
||||||
|
syncFromiCloud()
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(iCloudDidChangeExternally), name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, object: NSUbiquitousKeyValueStore.default)
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func willEnterBackground() {
|
||||||
|
syncToiCloud()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func syncFromiCloud() {
|
||||||
|
let iCloud = NSUbiquitousKeyValueStore.default
|
||||||
|
let defaults = UserDefaults.standard
|
||||||
|
|
||||||
|
for key in defaultsToSync {
|
||||||
|
if let value = iCloud.object(forKey: key) {
|
||||||
|
defaults.set(value, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults.synchronize()
|
||||||
|
NotificationCenter.default.post(name: .iCloudSyncDidComplete, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func syncToiCloud() {
|
||||||
|
let iCloud = NSUbiquitousKeyValueStore.default
|
||||||
|
let defaults = UserDefaults.standard
|
||||||
|
|
||||||
|
for key in defaultsToSync {
|
||||||
|
if let value = defaults.object(forKey: key) {
|
||||||
|
iCloud.set(value, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iCloud.synchronize()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func iCloudDidChangeExternally(_ notification: Notification) {
|
||||||
|
guard let userInfo = notification.userInfo,
|
||||||
|
let reason = userInfo[NSUbiquitousKeyValueStoreChangeReasonKey] as? Int else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if reason == NSUbiquitousKeyValueStoreServerChange ||
|
||||||
|
reason == NSUbiquitousKeyValueStoreInitialSyncChange {
|
||||||
|
syncFromiCloud()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func userDefaultsDidChange(_ notification: Notification) {
|
||||||
|
syncToiCloud()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,14 @@ class LibraryManager: ObservableObject {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
loadBookmarks()
|
loadBookmarks()
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(handleiCloudSync), name: .iCloudSyncDidComplete, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleiCloudSync() {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.loadBookmarks()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeBookmark(item: LibraryItem) {
|
func removeBookmark(item: LibraryItem) {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
133F55BB2D33B55100E08EEA /* LibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133F55BA2D33B55100E08EEA /* LibraryManager.swift */; };
|
133F55BB2D33B55100E08EEA /* LibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133F55BA2D33B55100E08EEA /* LibraryManager.swift */; };
|
||||||
1359ED142D76F49900C13034 /* finTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1359ED132D76F49900C13034 /* finTopView.swift */; };
|
1359ED142D76F49900C13034 /* finTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1359ED132D76F49900C13034 /* finTopView.swift */; };
|
||||||
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */; };
|
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */; };
|
||||||
|
136BBE7E2DB102D600906B5E /* iCloudSyncManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136BBE7D2DB102D600906B5E /* iCloudSyncManager.swift */; };
|
||||||
|
136BBE802DB1038000906B5E /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136BBE7F2DB1038000906B5E /* Notification+Name.swift */; };
|
||||||
138AA1B82D2D66FD0021F9DF /* EpisodeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */; };
|
138AA1B82D2D66FD0021F9DF /* EpisodeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */; };
|
||||||
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */; };
|
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */; };
|
||||||
139935662D468C450065CEFF /* ModuleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139935652D468C450065CEFF /* ModuleManager.swift */; };
|
139935662D468C450065CEFF /* ModuleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139935652D468C450065CEFF /* ModuleManager.swift */; };
|
||||||
|
|
@ -96,6 +98,8 @@
|
||||||
133F55BA2D33B55100E08EEA /* LibraryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryManager.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>"; };
|
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>"; };
|
135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewPlayer.swift; sourceTree = "<group>"; };
|
||||||
|
136BBE7D2DB102D600906B5E /* iCloudSyncManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iCloudSyncManager.swift; sourceTree = "<group>"; };
|
||||||
|
136BBE7F2DB1038000906B5E /* Notification+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Name.swift"; sourceTree = "<group>"; };
|
||||||
138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EpisodeCell.swift; sourceTree = "<group>"; };
|
138AA1B62D2D66FD0021F9DF /* EpisodeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EpisodeCell.swift; sourceTree = "<group>"; };
|
||||||
138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressBar.swift; sourceTree = "<group>"; };
|
138AA1B72D2D66FD0021F9DF /* CircularProgressBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressBar.swift; sourceTree = "<group>"; };
|
||||||
139935652D468C450065CEFF /* ModuleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleManager.swift; sourceTree = "<group>"; };
|
139935652D468C450065CEFF /* ModuleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleManager.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -257,6 +261,7 @@
|
||||||
133D7C852D2BE2640075467E /* Utils */ = {
|
133D7C852D2BE2640075467E /* Utils */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
136BBE7C2DB102BE00906B5E /* iCloudSyncManager */,
|
||||||
13DB7CEA2D7DED50004371D3 /* DownloadManager */,
|
13DB7CEA2D7DED50004371D3 /* DownloadManager */,
|
||||||
13C0E5E82D5F85DD00E7F619 /* ContinueWatching */,
|
13C0E5E82D5F85DD00E7F619 /* ContinueWatching */,
|
||||||
13103E8C2D58E037000F0673 /* SkeletonCells */,
|
13103E8C2D58E037000F0673 /* SkeletonCells */,
|
||||||
|
|
@ -275,6 +280,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */,
|
73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */,
|
||||||
|
136BBE7F2DB1038000906B5E /* Notification+Name.swift */,
|
||||||
1327FBA82D758DEA00FC6689 /* UIDevice+Model.swift */,
|
1327FBA82D758DEA00FC6689 /* UIDevice+Model.swift */,
|
||||||
133D7C872D2BE2640075467E /* URLSession.swift */,
|
133D7C872D2BE2640075467E /* URLSession.swift */,
|
||||||
1359ED132D76F49900C13034 /* finTopView.swift */,
|
1359ED132D76F49900C13034 /* finTopView.swift */,
|
||||||
|
|
@ -315,6 +321,14 @@
|
||||||
path = LibraryView;
|
path = LibraryView;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
136BBE7C2DB102BE00906B5E /* iCloudSyncManager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
136BBE7D2DB102D600906B5E /* iCloudSyncManager.swift */,
|
||||||
|
);
|
||||||
|
path = iCloudSyncManager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
1384DCDF2D89BE870094797A /* Helpers */ = {
|
1384DCDF2D89BE870094797A /* Helpers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
|
@ -539,7 +553,9 @@
|
||||||
133D7C902D2BE2640075467E /* SettingsView.swift in Sources */,
|
133D7C902D2BE2640075467E /* SettingsView.swift in Sources */,
|
||||||
132AF1252D9995F900A0140B /* JSController-Search.swift in Sources */,
|
132AF1252D9995F900A0140B /* JSController-Search.swift in Sources */,
|
||||||
13CBEFDA2D5F7D1200D011EE /* String.swift in Sources */,
|
13CBEFDA2D5F7D1200D011EE /* String.swift in Sources */,
|
||||||
|
136BBE7E2DB102D600906B5E /* iCloudSyncManager.swift in Sources */,
|
||||||
1E26E9E72DA9577900B9DC02 /* VolumeSlider.swift in Sources */,
|
1E26E9E72DA9577900B9DC02 /* VolumeSlider.swift in Sources */,
|
||||||
|
136BBE802DB1038000906B5E /* Notification+Name.swift in Sources */,
|
||||||
13DB46902D900A38008CBC03 /* URL.swift in Sources */,
|
13DB46902D900A38008CBC03 /* URL.swift in Sources */,
|
||||||
130C6BFA2D53AB1F00DC1432 /* SettingsViewData.swift in Sources */,
|
130C6BFA2D53AB1F00DC1432 /* SettingsViewData.swift in Sources */,
|
||||||
1E9FF1D32D403E49008AC100 /* SettingsViewLoggerFilter.swift in Sources */,
|
1E9FF1D32D403E49008AC100 /* SettingsViewLoggerFilter.swift in Sources */,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue