mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
incinerated the buffer indicator, brightness bar restored old code (#74)
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:
parent
c256388497
commit
f58b8b8733
3 changed files with 17 additions and 103 deletions
|
|
@ -11,14 +11,11 @@ import SwiftUI
|
||||||
|
|
||||||
struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
@Binding var value: T
|
@Binding var value: T
|
||||||
@Binding var bufferValue: T // NEW
|
|
||||||
let inRange: ClosedRange<T>
|
let inRange: ClosedRange<T>
|
||||||
|
|
||||||
let activeFillColor: Color
|
let activeFillColor: Color
|
||||||
let fillColor: Color
|
let fillColor: Color
|
||||||
let emptyColor: Color
|
let emptyColor: Color
|
||||||
let height: CGFloat
|
let height: CGFloat
|
||||||
|
|
||||||
let onEditingChanged: (Bool) -> Void
|
let onEditingChanged: (Bool) -> Void
|
||||||
|
|
||||||
@State private var localRealProgress: T = 0
|
@State private var localRealProgress: T = 0
|
||||||
|
|
@ -29,31 +26,9 @@ struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
GeometryReader { bounds in
|
GeometryReader { bounds in
|
||||||
ZStack {
|
ZStack {
|
||||||
VStack {
|
VStack {
|
||||||
// Base track + buffer indicator + current progress
|
|
||||||
ZStack(alignment: .center) {
|
ZStack(alignment: .center) {
|
||||||
|
|
||||||
// Entire background track
|
|
||||||
Capsule()
|
Capsule()
|
||||||
.fill(emptyColor)
|
.fill(emptyColor)
|
||||||
|
|
||||||
// 1) The buffer fill portion (behind the actual progress)
|
|
||||||
Capsule() // NEW
|
|
||||||
.fill(fillColor.opacity(0.3)) // or any "bufferColor"
|
|
||||||
.mask({
|
|
||||||
HStack {
|
|
||||||
Rectangle()
|
|
||||||
.frame(
|
|
||||||
width: max(
|
|
||||||
bounds.size.width * CGFloat(getPrgPercentage(bufferValue)),
|
|
||||||
0
|
|
||||||
),
|
|
||||||
alignment: .leading
|
|
||||||
)
|
|
||||||
Spacer(minLength: 0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 2) The actual playback progress
|
|
||||||
Capsule()
|
Capsule()
|
||||||
.fill(isActive ? activeFillColor : fillColor)
|
.fill(isActive ? activeFillColor : fillColor)
|
||||||
.mask({
|
.mask({
|
||||||
|
|
@ -71,7 +46,6 @@ struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time labels
|
|
||||||
HStack {
|
HStack {
|
||||||
let shouldShowHours = inRange.upperBound >= 3600
|
let shouldShowHours = inRange.upperBound >= 3600
|
||||||
Text(value.asTimeString(style: .positional, showHours: shouldShowHours))
|
Text(value.asTimeString(style: .positional, showHours: shouldShowHours))
|
||||||
|
|
@ -82,8 +56,7 @@ struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
.font(.system(size: 12))
|
.font(.system(size: 12))
|
||||||
.foregroundColor(isActive ? fillColor : emptyColor)
|
.foregroundColor(isActive ? fillColor : emptyColor)
|
||||||
}
|
}
|
||||||
.frame(width: isActive ? bounds.size.width * 1.04 : bounds.size.width,
|
.frame(width: isActive ? bounds.size.width * 1.04 : bounds.size.width, alignment: .center)
|
||||||
alignment: .center)
|
|
||||||
.animation(animation, value: isActive)
|
.animation(animation, value: isActive)
|
||||||
}
|
}
|
||||||
.frame(width: bounds.size.width, height: bounds.size.height, alignment: .center)
|
.frame(width: bounds.size.width, height: bounds.size.height, alignment: .center)
|
||||||
|
|
@ -95,15 +68,15 @@ struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
}
|
}
|
||||||
.onChanged { gesture in
|
.onChanged { gesture in
|
||||||
localTempProgress = T(gesture.translation.width / bounds.size.width)
|
localTempProgress = T(gesture.translation.width / bounds.size.width)
|
||||||
value = clampValue(getPrgValue())
|
value = max(min(getPrgValue(), inRange.upperBound), inRange.lowerBound)
|
||||||
}
|
}
|
||||||
.onEnded { _ in
|
.onEnded { _ in
|
||||||
localRealProgress = getPrgPercentage(value)
|
localRealProgress = max(min(localRealProgress + localTempProgress, 1), 0)
|
||||||
localTempProgress = 0
|
localTempProgress = 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.onChange(of: isActive) { newValue in
|
.onChange(of: isActive) { newValue in
|
||||||
value = clampValue(getPrgValue())
|
value = max(min(getPrgValue(), inRange.upperBound), inRange.lowerBound)
|
||||||
onEditingChanged(newValue)
|
onEditingChanged(newValue)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
|
|
@ -117,26 +90,23 @@ struct MusicProgressSlider<T: BinaryFloatingPoint>: View {
|
||||||
}
|
}
|
||||||
.frame(height: isActive ? height * 1.25 : height, alignment: .center)
|
.frame(height: isActive ? height * 1.25 : height, alignment: .center)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var animation: Animation {
|
private var animation: Animation {
|
||||||
isActive
|
if isActive {
|
||||||
? .spring()
|
return .spring()
|
||||||
: .spring(response: 0.5, dampingFraction: 0.5, blendDuration: 0.6)
|
} else {
|
||||||
|
return .spring(response: 0.5, dampingFraction: 0.5, blendDuration: 0.6)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func clampValue(_ val: T) -> T {
|
private func getPrgPercentage(_ value: T) -> T {
|
||||||
max(min(val, inRange.upperBound), inRange.lowerBound)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getPrgPercentage(_ val: T) -> T {
|
|
||||||
let clampedValue = clampValue(val)
|
|
||||||
let range = inRange.upperBound - inRange.lowerBound
|
let range = inRange.upperBound - inRange.lowerBound
|
||||||
let pct = (clampedValue - inRange.lowerBound) / range
|
let correctedStartValue = value - inRange.lowerBound
|
||||||
return max(min(pct, 1), 0)
|
let percentage = correctedStartValue / range
|
||||||
|
return percentage
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getPrgValue() -> T {
|
private func getPrgValue() -> T {
|
||||||
((localRealProgress + localTempProgress) * (inRange.upperBound - inRange.lowerBound))
|
return ((localRealProgress + localTempProgress) * (inRange.upperBound - inRange.lowerBound)) + inRange.lowerBound
|
||||||
+ inRange.lowerBound
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
var duration: Double = 0.0
|
var duration: Double = 0.0
|
||||||
var isVideoLoaded = false
|
var isVideoLoaded = false
|
||||||
|
|
||||||
var brightnessValue: Double = Double(UIScreen.main.brightness)
|
|
||||||
var brightnessSliderHostingController: UIHostingController<VerticalBrightnessSlider<Double>>?
|
|
||||||
|
|
||||||
private var isHoldPauseEnabled: Bool {
|
private var isHoldPauseEnabled: Bool {
|
||||||
UserDefaults.standard.bool(forKey: "holdForPauseEnabled")
|
UserDefaults.standard.bool(forKey: "holdForPauseEnabled")
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +172,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
loadSubtitleSettings()
|
loadSubtitleSettings()
|
||||||
setupPlayerViewController()
|
setupPlayerViewController()
|
||||||
setupControls()
|
setupControls()
|
||||||
brightnessControl()
|
|
||||||
setupSkipAndDismissGestures()
|
setupSkipAndDismissGestures()
|
||||||
addInvisibleControlOverlays()
|
addInvisibleControlOverlays()
|
||||||
setupSubtitleLabel()
|
setupSubtitleLabel()
|
||||||
|
|
@ -401,10 +397,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
get: { self.sliderViewModel.sliderValue },
|
get: { self.sliderViewModel.sliderValue },
|
||||||
set: { self.sliderViewModel.sliderValue = $0 }
|
set: { self.sliderViewModel.sliderValue = $0 }
|
||||||
),
|
),
|
||||||
bufferValue: Binding(
|
|
||||||
get: { self.sliderViewModel.bufferValue }, // NEW
|
|
||||||
set: { self.sliderViewModel.bufferValue = $0 } // NEW
|
|
||||||
),
|
|
||||||
inRange: 0...(duration > 0 ? duration : 1.0),
|
inRange: 0...(duration > 0 ? duration : 1.0),
|
||||||
activeFillColor: .white,
|
activeFillColor: .white,
|
||||||
fillColor: .white.opacity(0.5),
|
fillColor: .white.opacity(0.5),
|
||||||
|
|
@ -471,49 +463,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
holdForPauseGesture.numberOfTouchesRequired = 2
|
holdForPauseGesture.numberOfTouchesRequired = 2
|
||||||
view.addGestureRecognizer(holdForPauseGesture)
|
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 }
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create the container for the brightness slider
|
|
||||||
let brightnessContainer = UIView()
|
|
||||||
brightnessContainer.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
brightnessContainer.backgroundColor = .clear
|
|
||||||
|
|
||||||
controlsContainerView.addSubview(brightnessContainer)
|
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
brightnessContainer.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
|
|
||||||
brightnessContainer.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor),
|
|
||||||
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)
|
||||||
|
|
@ -959,8 +908,7 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
self.sliderViewModel.sliderValue = max(0, min($0, self.duration))
|
self.sliderViewModel.sliderValue = max(0, min($0, self.duration))
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
bufferValue: Binding(get: { self.sliderViewModel.bufferValue },
|
inRange: 0...(self.duration > 0 ? self.duration : 1.0),
|
||||||
set: { self.sliderViewModel.bufferValue = $0 }), inRange: 0...(self.duration > 0 ? self.duration : 1.0),
|
|
||||||
activeFillColor: .white,
|
activeFillColor: .white,
|
||||||
fillColor: .white.opacity(0.6),
|
fillColor: .white.opacity(0.6),
|
||||||
emptyColor: .white.opacity(0.3),
|
emptyColor: .white.opacity(0.3),
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@
|
||||||
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 */; };
|
||||||
|
|
@ -117,7 +116,6 @@
|
||||||
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>"; };
|
||||||
|
|
@ -408,7 +406,6 @@
|
||||||
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 */,
|
||||||
);
|
);
|
||||||
|
|
@ -537,7 +534,6 @@
|
||||||
133D7C8E2D2BE2640075467E /* LibraryView.swift in Sources */,
|
133D7C8E2D2BE2640075467E /* LibraryView.swift in Sources */,
|
||||||
133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */,
|
133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */,
|
||||||
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.swift in Sources */,
|
138AA1B92D2D66FD0021F9DF /* CircularProgressBar.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