mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-21 00:22:12 +00:00
fixed maybe? at least on my machine
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
07b4a0280e
commit
6989fbfe87
2 changed files with 37 additions and 28 deletions
|
|
@ -709,20 +709,16 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch Next Button Logic:
|
|
||||||
let hideNext = UserDefaults.standard.bool(forKey: "hideNextButton")
|
|
||||||
let isNearEnd = (self.duration - self.currentTimeVal) <= (self.duration * 0.10)
|
let isNearEnd = (self.duration - self.currentTimeVal) <= (self.duration * 0.10)
|
||||||
&& self.currentTimeVal != self.duration
|
&& self.currentTimeVal != self.duration
|
||||||
&& self.showWatchNextButton
|
&& self.showWatchNextButton
|
||||||
&& self.duration != 0
|
&& self.duration != 0
|
||||||
|
|
||||||
if isNearEnd {
|
if isNearEnd {
|
||||||
// First appearance: show the button in its normal position.
|
|
||||||
if !self.isWatchNextVisible {
|
if !self.isWatchNextVisible {
|
||||||
self.isWatchNextVisible = true
|
self.isWatchNextVisible = true
|
||||||
self.watchNextButtonAppearedAt = self.currentTimeVal
|
self.watchNextButtonAppearedAt = self.currentTimeVal
|
||||||
|
|
||||||
// Choose constraints based on current controls visibility.
|
|
||||||
if self.isControlsVisible {
|
if self.isControlsVisible {
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
||||||
|
|
@ -730,7 +726,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
|
||||||
}
|
}
|
||||||
// Soft fade-in.
|
|
||||||
self.watchNextButton.isHidden = false
|
self.watchNextButton.isHidden = false
|
||||||
self.watchNextButton.alpha = 0.0
|
self.watchNextButton.alpha = 0.0
|
||||||
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
|
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
|
||||||
|
|
@ -738,23 +733,19 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
}, completion: nil)
|
}, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// When 5 seconds have elapsed from when the button first appeared:
|
|
||||||
if let appearedAt = self.watchNextButtonAppearedAt,
|
if let appearedAt = self.watchNextButtonAppearedAt,
|
||||||
(self.currentTimeVal - appearedAt) >= 5,
|
(self.currentTimeVal - appearedAt) >= 5,
|
||||||
!self.isWatchNextRepositioned {
|
!self.isWatchNextRepositioned {
|
||||||
// Fade out the button first (even if controls are visible).
|
|
||||||
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
|
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
|
||||||
self.watchNextButton.alpha = 0.0
|
self.watchNextButton.alpha = 0.0
|
||||||
}, completion: { _ in
|
}, completion: { _ in
|
||||||
self.watchNextButton.isHidden = true
|
self.watchNextButton.isHidden = true
|
||||||
// Then lock it to the controls-attached constraints.
|
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
||||||
self.isWatchNextRepositioned = true
|
self.isWatchNextRepositioned = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not near end: reset the watch-next button state.
|
|
||||||
self.watchNextButtonAppearedAt = nil
|
self.watchNextButtonAppearedAt = nil
|
||||||
self.isWatchNextVisible = false
|
self.isWatchNextVisible = false
|
||||||
self.isWatchNextRepositioned = false
|
self.isWatchNextRepositioned = false
|
||||||
|
|
@ -771,7 +762,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
|
|
||||||
func repositionWatchNextButton() {
|
func repositionWatchNextButton() {
|
||||||
self.isWatchNextRepositioned = true
|
self.isWatchNextRepositioned = true
|
||||||
// Update constraints so the button is now attached next to the playback controls.
|
|
||||||
UIView.animate(withDuration: 0.3, animations: {
|
UIView.animate(withDuration: 0.3, animations: {
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
||||||
|
|
@ -799,7 +789,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
self.skip85Button.alpha = self.isControlsVisible ? 0.8 : 0
|
self.skip85Button.alpha = self.isControlsVisible ? 0.8 : 0
|
||||||
|
|
||||||
if self.isControlsVisible {
|
if self.isControlsVisible {
|
||||||
// Always use the controls-attached constraints.
|
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
|
||||||
if self.isWatchNextRepositioned || self.isWatchNextVisible {
|
if self.isWatchNextRepositioned || self.isWatchNextVisible {
|
||||||
|
|
@ -809,7 +798,6 @@ class CustomMediaPlayerViewController: UIViewController {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// When controls are hidden:
|
|
||||||
if !self.isWatchNextRepositioned && self.isWatchNextVisible {
|
if !self.isWatchNextRepositioned && self.isWatchNextVisible {
|
||||||
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
|
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
|
||||||
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
|
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
|
||||||
|
|
|
||||||
|
|
@ -165,23 +165,9 @@ struct SearchView: View {
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
Menu {
|
Menu {
|
||||||
let modulesByLanguage = Dictionary(grouping: moduleManager.modules) { module in
|
ForEach(getModuleLanguageGroups(), id: \.self) { language in
|
||||||
guard let language = module.metadata.language else { return "Unknown" }
|
|
||||||
|
|
||||||
let cleanLanguage = language.replacingOccurrences(
|
|
||||||
of: "\\s*\\([^\\)]*\\)",
|
|
||||||
with: "",
|
|
||||||
options: .regularExpression
|
|
||||||
).trimmingCharacters(in: .whitespaces)
|
|
||||||
|
|
||||||
return cleanLanguage.isEmpty ? "Unknown" : cleanLanguage
|
|
||||||
}
|
|
||||||
|
|
||||||
let sortedLanguages = modulesByLanguage.keys.sorted()
|
|
||||||
|
|
||||||
ForEach(sortedLanguages, id: \.self) { language in
|
|
||||||
Menu(language) {
|
Menu(language) {
|
||||||
ForEach(modulesByLanguage[language] ?? [], id: \.id) { module in
|
ForEach(getModulesForLanguage(language), id: \.id) { module in
|
||||||
Button {
|
Button {
|
||||||
selectedModuleId = module.id.uuidString
|
selectedModuleId = module.id.uuidString
|
||||||
} label: {
|
} label: {
|
||||||
|
|
@ -287,6 +273,41 @@ struct SearchView: View {
|
||||||
return verticalSizeClass == .compact ? mediaColumnsLandscape : mediaColumnsPortrait
|
return verticalSizeClass == .compact ? mediaColumnsLandscape : mediaColumnsPortrait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func cleanLanguageName(_ language: String?) -> String {
|
||||||
|
guard let language = language else { return "Unknown" }
|
||||||
|
|
||||||
|
let cleaned = language.replacingOccurrences(
|
||||||
|
of: "\\s*\\([^\\)]*\\)",
|
||||||
|
with: "",
|
||||||
|
options: .regularExpression
|
||||||
|
).trimmingCharacters(in: .whitespaces)
|
||||||
|
|
||||||
|
return cleaned.isEmpty ? "Unknown" : cleaned
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getModulesByLanguage() -> [String: [ScrapingModule]] {
|
||||||
|
var result = [String: [ScrapingModule]]()
|
||||||
|
|
||||||
|
for module in moduleManager.modules {
|
||||||
|
let language = cleanLanguageName(module.metadata.language)
|
||||||
|
if result[language] == nil {
|
||||||
|
result[language] = [module]
|
||||||
|
} else {
|
||||||
|
result[language]?.append(module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getModuleLanguageGroups() -> [String] {
|
||||||
|
return getModulesByLanguage().keys.sorted()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getModulesForLanguage(_ language: String) -> [ScrapingModule] {
|
||||||
|
return getModulesByLanguage()[language] ?? []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SearchBar: View {
|
struct SearchBar: View {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue