mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-21 08:32:00 +00:00
Commits say it all (#65)
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
This commit is contained in:
commit
648c4ee4ff
4 changed files with 234 additions and 5 deletions
|
|
@ -0,0 +1,136 @@
|
||||||
|
//
|
||||||
|
// VerticalBrightnessSlider.swift
|
||||||
|
// Custom Brighness bar
|
||||||
|
//
|
||||||
|
// Created by Pratik on 08/01/23.
|
||||||
|
// Modified to update screen brightness when used as a brightness slider.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct VerticalBrightnessSlider<T: BinaryFloatingPoint>: View {
|
||||||
|
@Binding var value: T
|
||||||
|
let inRange: ClosedRange<T>
|
||||||
|
let activeFillColor: Color
|
||||||
|
let fillColor: Color
|
||||||
|
let emptyColor: Color
|
||||||
|
let width: CGFloat
|
||||||
|
let onEditingChanged: (Bool) -> Void
|
||||||
|
|
||||||
|
// private variables
|
||||||
|
@State private var localRealProgress: T = 0
|
||||||
|
@State private var localTempProgress: T = 0
|
||||||
|
@GestureState private var isActive: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { bounds in
|
||||||
|
ZStack {
|
||||||
|
GeometryReader { geo in
|
||||||
|
ZStack(alignment: .bottom) {
|
||||||
|
RoundedRectangle(cornerRadius: isActive ? width : width/2, style: .continuous)
|
||||||
|
.fill(emptyColor)
|
||||||
|
RoundedRectangle(cornerRadius: isActive ? width : width/2, style: .continuous)
|
||||||
|
.fill(isActive ? activeFillColor : fillColor)
|
||||||
|
.mask({
|
||||||
|
VStack {
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: max(geo.size.height * CGFloat((localRealProgress + localTempProgress)), 0),
|
||||||
|
alignment: .leading)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Image(systemName: getIconName)
|
||||||
|
.font(.system(size: isActive ? 16 : 12, weight: .medium, design: .rounded))
|
||||||
|
.foregroundColor(isActive ? fillColor : Color.white)
|
||||||
|
.animation(.spring(), value: isActive)
|
||||||
|
.frame(maxHeight: .infinity, alignment: .bottom)
|
||||||
|
.padding(.bottom)
|
||||||
|
.overlay {
|
||||||
|
Image(systemName: getIconName)
|
||||||
|
.font(.system(size: isActive ? 16 : 12, weight: .medium, design: .rounded))
|
||||||
|
.foregroundColor(isActive ? Color.gray : Color.white.opacity(0.8))
|
||||||
|
.animation(.spring(), value: isActive)
|
||||||
|
.frame(maxHeight: .infinity, alignment: .bottom)
|
||||||
|
.padding(.bottom)
|
||||||
|
.mask {
|
||||||
|
VStack {
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: max(geo.size.height * CGFloat((localRealProgress + localTempProgress)), 0),
|
||||||
|
alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//.frame(maxWidth: isActive ? .infinity : 0)
|
||||||
|
// .opacity(isActive ? 1 : 0)
|
||||||
|
}
|
||||||
|
.clipped()
|
||||||
|
}
|
||||||
|
.frame(height: isActive ? bounds.size.height * 1.15 : bounds.size.height, alignment: .center)
|
||||||
|
// .shadow(color: .black.opacity(0.1), radius: isActive ? 20 : 0, x: 0, y: 0)
|
||||||
|
.animation(animation, value: isActive)
|
||||||
|
}
|
||||||
|
.frame(width: bounds.size.width, height: bounds.size.height, alignment: .center)
|
||||||
|
.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local)
|
||||||
|
.updating($isActive) { value, state, transaction in
|
||||||
|
state = true
|
||||||
|
}
|
||||||
|
.onChanged { gesture in
|
||||||
|
localTempProgress = T(-gesture.translation.height / bounds.size.height)
|
||||||
|
value = max(min(getPrgValue(), inRange.upperBound), inRange.lowerBound)
|
||||||
|
}
|
||||||
|
.onEnded { _ in
|
||||||
|
localRealProgress = max(min(localRealProgress + localTempProgress, 1), 0)
|
||||||
|
localTempProgress = 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.onChange(of: isActive) { newValue in
|
||||||
|
value = max(min(getPrgValue(), inRange.upperBound), inRange.lowerBound)
|
||||||
|
onEditingChanged(newValue)
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
localRealProgress = getPrgPercentage(value)
|
||||||
|
}
|
||||||
|
.onChange(of: value) { newValue in
|
||||||
|
if !isActive {
|
||||||
|
localRealProgress = getPrgPercentage(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: isActive ? width * 1.9 : width, alignment: .center)
|
||||||
|
.offset(x: isActive ? -10 : 0)
|
||||||
|
.onChange(of: value) { newValue in
|
||||||
|
UIScreen.main.brightness = CGFloat(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var getIconName: String {
|
||||||
|
let brightnessLevel = CGFloat(localRealProgress + localTempProgress)
|
||||||
|
switch brightnessLevel {
|
||||||
|
case ..<0.2:
|
||||||
|
return "moon.fill"
|
||||||
|
case 0.2..<0.38:
|
||||||
|
return "sun.min"
|
||||||
|
case 0.38..<0.7:
|
||||||
|
return "sun.max"
|
||||||
|
default:
|
||||||
|
return "sun.max.fill"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var animation: Animation {
|
||||||
|
return .spring()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getPrgPercentage(_ value: T) -> T {
|
||||||
|
let range = inRange.upperBound - inRange.lowerBound
|
||||||
|
let correctedStartValue = value - inRange.lowerBound
|
||||||
|
let percentage = correctedStartValue / range
|
||||||
|
return percentage
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getPrgValue() -> T {
|
||||||
|
return ((localRealProgress + localTempProgress) * (inRange.upperBound - inRange.lowerBound)) + inRange.lowerBound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,8 +40,15 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
var currentTimeVal: Double = 0.0
|
var currentTimeVal: Double = 0.0
|
||||||
var duration: Double = 0.0
|
var duration: Double = 0.0
|
||||||
var isVideoLoaded = false
|
var isVideoLoaded = false
|
||||||
var showWatchNextButton = true
|
|
||||||
|
|
||||||
|
var brightnessValue: Double = Double(UIScreen.main.brightness)
|
||||||
|
var brightnessSliderHostingController: UIHostingController<VerticalBrightnessSlider<Double>>?
|
||||||
|
|
||||||
|
private var isHoldPauseEnabled: Bool {
|
||||||
|
UserDefaults.standard.bool(forKey: "holdForPauseEnabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
var showWatchNextButton = true
|
||||||
var watchNextButtonTimer: Timer?
|
var watchNextButtonTimer: Timer?
|
||||||
var isWatchNextRepositioned: Bool = false
|
var isWatchNextRepositioned: Bool = false
|
||||||
var isWatchNextVisible: Bool = false
|
var isWatchNextVisible: Bool = false
|
||||||
|
|
@ -134,7 +141,9 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(fullUrl)")
|
let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(fullUrl)")
|
||||||
if lastPlayedTime > 0 {
|
if lastPlayedTime > 0 {
|
||||||
let seekTime = CMTime(seconds: lastPlayedTime, preferredTimescale: 1)
|
let seekTime = CMTime(seconds: lastPlayedTime, preferredTimescale: 1)
|
||||||
self.player.seek(to: seekTime)
|
self.player.seek(to: seekTime) { [weak self] _ in
|
||||||
|
self?.updateBufferValue()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,6 +160,7 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
loadSubtitleSettings()
|
loadSubtitleSettings()
|
||||||
setupPlayerViewController()
|
setupPlayerViewController()
|
||||||
setupControls()
|
setupControls()
|
||||||
|
brightnessControl()
|
||||||
setupSkipAndDismissGestures()
|
setupSkipAndDismissGestures()
|
||||||
addInvisibleControlOverlays()
|
addInvisibleControlOverlays()
|
||||||
setupSubtitleLabel()
|
setupSubtitleLabel()
|
||||||
|
|
@ -174,6 +184,10 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
self?.checkForHLSStream()
|
self?.checkForHLSStream()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isHoldPauseEnabled {
|
||||||
|
holdForPause()
|
||||||
|
}
|
||||||
|
|
||||||
player.play()
|
player.play()
|
||||||
|
|
||||||
if let url = subtitlesURL, !url.isEmpty {
|
if let url = subtitlesURL, !url.isEmpty {
|
||||||
|
|
@ -405,6 +419,57 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func holdForPause() {
|
||||||
|
let holdForPauseGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleHoldForPause(_:)))
|
||||||
|
holdForPauseGesture.minimumPressDuration = 1
|
||||||
|
holdForPauseGesture.numberOfTouchesRequired = 2
|
||||||
|
view.addGestureRecognizer(holdForPauseGesture)
|
||||||
|
}
|
||||||
|
|
||||||
|
func brightnessControl() {
|
||||||
|
let brightnessSlider = VerticalBrightnessSlider(
|
||||||
|
value: Binding(
|
||||||
|
get: { self.brightnessValue },
|
||||||
|
set: { newValue in
|
||||||
|
self.brightnessValue = newValue
|
||||||
|
}
|
||||||
|
),
|
||||||
|
inRange: 0...1,
|
||||||
|
activeFillColor: .white,
|
||||||
|
fillColor: .white.opacity(0.5),
|
||||||
|
emptyColor: .white.opacity(0.3),
|
||||||
|
width: 22,
|
||||||
|
onEditingChanged: { editing in
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
let brightnessContainer = UIView()
|
||||||
|
brightnessContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
brightnessContainer.backgroundColor = .clear
|
||||||
|
|
||||||
|
controlsContainerView.addSubview(brightnessContainer)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
brightnessContainer.leadingAnchor.constraint(equalTo: controlsContainerView.leadingAnchor, constant: -4),
|
||||||
|
brightnessContainer.centerYAnchor.constraint(equalTo: controlsContainerView.centerYAnchor, constant: -10),
|
||||||
|
brightnessContainer.widthAnchor.constraint(equalToConstant: 22),
|
||||||
|
brightnessContainer.heightAnchor.constraint(equalToConstant: 170)
|
||||||
|
])
|
||||||
|
|
||||||
|
brightnessSliderHostingController = UIHostingController(rootView: brightnessSlider)
|
||||||
|
guard let brightnessSliderView = brightnessSliderHostingController?.view else { return }
|
||||||
|
brightnessSliderView.backgroundColor = .clear
|
||||||
|
brightnessSliderView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
brightnessContainer.addSubview(brightnessSliderView)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
brightnessSliderView.topAnchor.constraint(equalTo: brightnessContainer.topAnchor),
|
||||||
|
brightnessSliderView.bottomAnchor.constraint(equalTo: brightnessContainer.bottomAnchor),
|
||||||
|
brightnessSliderView.leadingAnchor.constraint(equalTo: brightnessContainer.leadingAnchor),
|
||||||
|
brightnessSliderView.trailingAnchor.constraint(equalTo: brightnessContainer.trailingAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
func addInvisibleControlOverlays() {
|
func addInvisibleControlOverlays() {
|
||||||
let playPauseOverlay = UIButton(type: .custom)
|
let playPauseOverlay = UIButton(type: .custom)
|
||||||
|
|
@ -433,9 +498,8 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let swipeDownGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeDown(_:)))
|
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
|
||||||
swipeDownGesture.direction = .down
|
view.addGestureRecognizer(panGesture)
|
||||||
view.addGestureRecognizer(swipeDownGesture)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func showSkipFeedback(direction: String) {
|
func showSkipFeedback(direction: String) {
|
||||||
|
|
@ -966,6 +1030,14 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
|
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func handleHoldForPause(_ gesture: UILongPressGestureRecognizer) {
|
||||||
|
guard isHoldPauseEnabled else { return }
|
||||||
|
|
||||||
|
if gesture.state == .began {
|
||||||
|
togglePlayPause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func speedChangerMenu() -> UIMenu {
|
func speedChangerMenu() -> UIMenu {
|
||||||
let speeds: [Double] = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
|
let speeds: [Double] = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
|
||||||
let playbackSpeedActions = speeds.map { speed in
|
let playbackSpeedActions = speeds.map { speed in
|
||||||
|
|
@ -1385,6 +1457,19 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
|
||||||
|
let translation = gesture.translation(in: view)
|
||||||
|
|
||||||
|
switch gesture.state {
|
||||||
|
case .ended:
|
||||||
|
if translation.y > 100 {
|
||||||
|
dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func beginHoldSpeed() {
|
private func beginHoldSpeed() {
|
||||||
guard let player = player else { return }
|
guard let player = player else { return }
|
||||||
originalRate = player.rate
|
originalRate = player.rate
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ struct SettingsViewPlayer: View {
|
||||||
@AppStorage("holdSpeedPlayer") private var holdSpeedPlayer: Double = 2.0
|
@AppStorage("holdSpeedPlayer") private var holdSpeedPlayer: Double = 2.0
|
||||||
@AppStorage("skipIncrement") private var skipIncrement: Double = 10.0
|
@AppStorage("skipIncrement") private var skipIncrement: Double = 10.0
|
||||||
@AppStorage("skipIncrementHold") private var skipIncrementHold: Double = 30.0
|
@AppStorage("skipIncrementHold") private var skipIncrementHold: Double = 30.0
|
||||||
|
@AppStorage("holdForPauseEnabled") private var holdForPauseEnabled = false
|
||||||
|
|
||||||
private let mediaPlayers = ["Default", "VLC", "OutPlayer", "Infuse", "nPlayer", "Sora"]
|
private let mediaPlayers = ["Default", "VLC", "OutPlayer", "Infuse", "nPlayer", "Sora"]
|
||||||
|
|
||||||
|
|
@ -40,6 +41,9 @@ struct SettingsViewPlayer: View {
|
||||||
|
|
||||||
Toggle("Force Landscape", isOn: $isAlwaysLandscape)
|
Toggle("Force Landscape", isOn: $isAlwaysLandscape)
|
||||||
.tint(.accentColor)
|
.tint(.accentColor)
|
||||||
|
|
||||||
|
Toggle("Two Finger Hold for Pause",isOn: $holdForPauseEnabled)
|
||||||
|
.tint(.accentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: Text("Speed Settings")) {
|
Section(header: Text("Speed Settings")) {
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@
|
||||||
13EA2BD52D32D97400C1EBD7 /* CustomPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD12D32D97400C1EBD7 /* CustomPlayer.swift */; };
|
13EA2BD52D32D97400C1EBD7 /* CustomPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD12D32D97400C1EBD7 /* CustomPlayer.swift */; };
|
||||||
13EA2BD62D32D97400C1EBD7 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */; };
|
13EA2BD62D32D97400C1EBD7 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */; };
|
||||||
13EA2BD92D32D98400C1EBD7 /* NormalPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD82D32D98400C1EBD7 /* NormalPlayer.swift */; };
|
13EA2BD92D32D98400C1EBD7 /* NormalPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13EA2BD82D32D98400C1EBD7 /* NormalPlayer.swift */; };
|
||||||
|
1E3F5EC82D9F16B7003F310F /* VerticalBrightnessSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3F5EC72D9F16B7003F310F /* VerticalBrightnessSlider.swift */; };
|
||||||
1E9FF1D32D403E49008AC100 /* SettingsViewLoggerFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9FF1D22D403E42008AC100 /* SettingsViewLoggerFilter.swift */; };
|
1E9FF1D32D403E49008AC100 /* SettingsViewLoggerFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9FF1D22D403E42008AC100 /* SettingsViewLoggerFilter.swift */; };
|
||||||
1EAC7A322D888BC50083984D /* MusicProgressSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */; };
|
1EAC7A322D888BC50083984D /* MusicProgressSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */; };
|
||||||
73D164D52D8B5B470011A360 /* JavaScriptCore+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */; };
|
73D164D52D8B5B470011A360 /* JavaScriptCore+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */; };
|
||||||
|
|
@ -123,6 +124,7 @@
|
||||||
13EA2BD12D32D97400C1EBD7 /* CustomPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomPlayer.swift; sourceTree = "<group>"; };
|
13EA2BD12D32D97400C1EBD7 /* CustomPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomPlayer.swift; sourceTree = "<group>"; };
|
||||||
13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
||||||
13EA2BD82D32D98400C1EBD7 /* NormalPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NormalPlayer.swift; sourceTree = "<group>"; };
|
13EA2BD82D32D98400C1EBD7 /* NormalPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NormalPlayer.swift; sourceTree = "<group>"; };
|
||||||
|
1E3F5EC72D9F16B7003F310F /* VerticalBrightnessSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalBrightnessSlider.swift; sourceTree = "<group>"; };
|
||||||
1E9FF1D22D403E42008AC100 /* SettingsViewLoggerFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewLoggerFilter.swift; sourceTree = "<group>"; };
|
1E9FF1D22D403E42008AC100 /* SettingsViewLoggerFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewLoggerFilter.swift; sourceTree = "<group>"; };
|
||||||
1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicProgressSlider.swift; sourceTree = "<group>"; };
|
1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicProgressSlider.swift; sourceTree = "<group>"; };
|
||||||
73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JavaScriptCore+Extensions.swift"; sourceTree = "<group>"; };
|
73D164D42D8B5B340011A360 /* JavaScriptCore+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JavaScriptCore+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
|
@ -440,6 +442,7 @@
|
||||||
13EA2BD22D32D97400C1EBD7 /* Components */ = {
|
13EA2BD22D32D97400C1EBD7 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1E3F5EC72D9F16B7003F310F /* VerticalBrightnessSlider.swift */,
|
||||||
13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */,
|
13EA2BD32D32D97400C1EBD7 /* Double+Extension.swift */,
|
||||||
1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */,
|
1EAC7A312D888BC50083984D /* MusicProgressSlider.swift */,
|
||||||
);
|
);
|
||||||
|
|
@ -571,6 +574,7 @@
|
||||||
133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */,
|
133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */,
|
||||||
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */,
|
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */,
|
||||||
1334FF4D2D786C93007E289F /* TMDB-Seasonal.swift in Sources */,
|
1334FF4D2D786C93007E289F /* TMDB-Seasonal.swift in Sources */,
|
||||||
|
1E3F5EC82D9F16B7003F310F /* VerticalBrightnessSlider.swift in Sources */,
|
||||||
13DB468D2D90093A008CBC03 /* Anilist-Login.swift in Sources */,
|
13DB468D2D90093A008CBC03 /* Anilist-Login.swift in Sources */,
|
||||||
73D164D52D8B5B470011A360 /* JavaScriptCore+Extensions.swift in Sources */,
|
73D164D52D8B5B470011A360 /* JavaScriptCore+Extensions.swift in Sources */,
|
||||||
132AF1232D9995C300A0140B /* JSController-Details.swift in Sources */,
|
132AF1232D9995C300A0140B /* JSController-Details.swift in Sources */,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue