mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-20 08:02:16 +00:00
merge latest dev changes
This commit is contained in:
commit
42a517c0cf
7 changed files with 121 additions and 36 deletions
28
.github/workflows/build.yml
vendored
28
.github/workflows/build.yml
vendored
|
|
@ -1,29 +1,39 @@
|
|||
name: Build and Release IPA
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build IPA
|
||||
runs-on: macOS-latest
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
with:
|
||||
persist-credentials: true
|
||||
|
||||
- name: Run ipabuild.sh
|
||||
run: |
|
||||
chmod +x ipabuild.sh
|
||||
./ipabuild.sh
|
||||
|
||||
- name: Upload IPA artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Sulfur-IPA
|
||||
path: build/Sulfur.ipa
|
||||
compression-level: 0
|
||||
|
||||
- name: Commit and push latest IPA
|
||||
run: |
|
||||
git config user.name "cranci1"
|
||||
git config user.email "cranci1@github.com"
|
||||
|
||||
mkdir -p public-build
|
||||
cp -f build/Sulfur.ipa public-build/Sulfur.ipa
|
||||
|
||||
git add -f public-build/Sulfur.ipa
|
||||
git diff --quiet && git diff --staged --quiet || git commit -m "Auto: Update IPA [skip ci]"
|
||||
git push
|
||||
|
|
|
|||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -63,10 +63,9 @@ DerivedData/
|
|||
*.hmap
|
||||
|
||||
## App packaging
|
||||
*.ipa
|
||||
*.dSYM.zip
|
||||
*.dSYM
|
||||
|
||||
public-build
|
||||
## Playgrounds
|
||||
timeline.xctimeline
|
||||
playground.xcworkspace
|
||||
|
|
@ -131,4 +130,4 @@ iOSInjectionProject/
|
|||
/*.gcno
|
||||
**/xcshareddata/WorkspaceSettings.xcsettings
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos,swift,xcode
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos,swift,xcode
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Sora
|
||||
> Also known as Sulfur, for copyright issues.
|
||||
|
||||
|
||||
<div align="center">
|
||||
|
||||
<img src="https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/Sulfur.png" width="750px">
|
||||
|
|
|
|||
|
|
@ -395,6 +395,14 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
}
|
||||
}
|
||||
|
||||
private func getSegmentsColor() -> Color {
|
||||
if let data = UserDefaults.standard.data(forKey: "segmentsColorData"),
|
||||
let uiColor = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UIColor {
|
||||
return Color(uiColor)
|
||||
}
|
||||
return .yellow
|
||||
}
|
||||
|
||||
func setupPlayerViewController() {
|
||||
playerViewController = AVPlayerViewController()
|
||||
playerViewController.player = player
|
||||
|
|
@ -505,6 +513,8 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
controlsContainerView.addSubview(forwardButton)
|
||||
forwardButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let segmentsColor = self.getSegmentsColor()
|
||||
|
||||
let sliderView = MusicProgressSlider(
|
||||
value: Binding(
|
||||
get: { self.sliderViewModel.sliderValue },
|
||||
|
|
@ -539,8 +549,8 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
},
|
||||
introSegments: sliderViewModel.introSegments, // Added
|
||||
outroSegments: sliderViewModel.outroSegments, // Added
|
||||
introColor: .yellow, // Add your colors here
|
||||
outroColor: .yellow // Or use settings.accentColor
|
||||
introColor: segmentsColor, // Add your colors here
|
||||
outroColor: segmentsColor // Or use settings.accentColor
|
||||
)
|
||||
|
||||
sliderHostingController = UIHostingController(rootView: sliderView)
|
||||
|
|
@ -898,7 +908,9 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
let end = min(1, ed.end.seconds / duration)
|
||||
sliderViewModel.outroSegments.append(start...end)
|
||||
}
|
||||
// Force SwiftUI to update
|
||||
|
||||
let segmentsColor = self.getSegmentsColor()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.sliderHostingController?.rootView = MusicProgressSlider(
|
||||
value: Binding(
|
||||
|
|
@ -922,8 +934,8 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
},
|
||||
introSegments: self.sliderViewModel.introSegments,
|
||||
outroSegments: self.sliderViewModel.outroSegments,
|
||||
introColor: .yellow, // Match your color choices
|
||||
outroColor: .yellow
|
||||
introColor: segmentsColor, // Match your color choices
|
||||
outroColor: segmentsColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1324,6 +1336,10 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
self.topSubtitleLabel.isHidden = true
|
||||
}
|
||||
|
||||
let current = self.currentTimeVal
|
||||
|
||||
let segmentsColor = self.getSegmentsColor()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if let currentItem = self.player.currentItem, currentItem.duration.seconds > 0 {
|
||||
let progress = min(max(self.currentTimeVal / self.duration, 0), 1.0)
|
||||
|
|
@ -1378,8 +1394,8 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
},
|
||||
introSegments: self.sliderViewModel.introSegments,
|
||||
outroSegments: self.sliderViewModel.outroSegments,
|
||||
introColor: .yellow, // Match your color choices
|
||||
outroColor: .yellow
|
||||
introColor: segmentsColor, // Match your color choices
|
||||
outroColor: segmentsColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,15 @@ class ModuleManager: ObservableObject {
|
|||
private let modulesFileName = "modules.json"
|
||||
|
||||
init() {
|
||||
let url = getModulesFilePath()
|
||||
if (!FileManager.default.fileExists(atPath: url.path)) {
|
||||
do {
|
||||
try "[]".write(to: url, atomically: true, encoding: .utf8)
|
||||
Logger.shared.log("Created empty modules file", type: "Info")
|
||||
} catch {
|
||||
Logger.shared.log("Failed to create modules file: \(error.localizedDescription)", type: "Error")
|
||||
}
|
||||
}
|
||||
loadModules()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleModulesSyncCompleted), name: .modulesSyncDidComplete, object: nil)
|
||||
}
|
||||
|
|
@ -23,12 +32,25 @@ class ModuleManager: ObservableObject {
|
|||
}
|
||||
|
||||
@objc private func handleModulesSyncCompleted() {
|
||||
DispatchQueue.main.async {
|
||||
self.loadModules()
|
||||
Task {
|
||||
await self.checkJSModuleFiles()
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
do {
|
||||
let url = self.getModulesFilePath()
|
||||
if FileManager.default.fileExists(atPath: url.path) {
|
||||
self.loadModules()
|
||||
Task {
|
||||
await self.checkJSModuleFiles()
|
||||
}
|
||||
Logger.shared.log("Reloaded modules after iCloud sync")
|
||||
} else {
|
||||
Logger.shared.log("No modules file found after sync", type: "Error")
|
||||
self.modules = []
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("Error handling modules sync: \(error.localizedDescription)", type: "Error")
|
||||
self.modules = []
|
||||
}
|
||||
Logger.shared.log("Reloaded modules after iCloud sync")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,11 +64,36 @@ class ModuleManager: ObservableObject {
|
|||
|
||||
func loadModules() {
|
||||
let url = getModulesFilePath()
|
||||
guard let data = try? Data(contentsOf: url) else { return }
|
||||
modules = (try? JSONDecoder().decode([ScrapingModule].self, from: data)) ?? []
|
||||
|
||||
Task {
|
||||
await checkJSModuleFiles()
|
||||
guard FileManager.default.fileExists(atPath: url.path) else {
|
||||
Logger.shared.log("Modules file does not exist, creating empty one", type: "Info")
|
||||
do {
|
||||
try "[]".write(to: url, atomically: true, encoding: .utf8)
|
||||
modules = []
|
||||
} catch {
|
||||
Logger.shared.log("Failed to create modules file: \(error.localizedDescription)", type: "Error")
|
||||
modules = []
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
do {
|
||||
let decodedModules = try JSONDecoder().decode([ScrapingModule].self, from: data)
|
||||
modules = decodedModules
|
||||
|
||||
Task {
|
||||
await checkJSModuleFiles()
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("Failed to decode modules: \(error.localizedDescription)", type: "Error")
|
||||
try "[]".write(to: url, atomically: true, encoding: .utf8)
|
||||
modules = []
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("Failed to load modules file: \(error.localizedDescription)", type: "Error")
|
||||
modules = []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ struct SettingsViewPlayer: View {
|
|||
@AppStorage("doubleTapSeekEnabled") private var doubleTapSeekEnabled: Bool = false
|
||||
@AppStorage("skipIntroOutroVisible") private var skipIntroOutroVisible: Bool = true
|
||||
|
||||
// @AppStorage("introColor") private var introColor: Color = .yellow
|
||||
//@AppStorage("outroColor") private var outroColor: Color = .yellow
|
||||
|
||||
private let mediaPlayers = ["Default", "VLC", "OutPlayer", "Infuse", "nPlayer", "Sora"]
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -64,10 +61,26 @@ struct SettingsViewPlayer: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Progress bar Marker Colors")) {
|
||||
// ColorPicker("Intro Color", selection: $introColor)
|
||||
//ColorPicker("Outro Color", selection: $outroColor)
|
||||
|
||||
Section(header: Text("Progress bar Marker Color")) {
|
||||
ColorPicker("Segments Color", selection: Binding(
|
||||
get: {
|
||||
if let data = UserDefaults.standard.data(forKey: "segmentsColorData"),
|
||||
let uiColor = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UIColor {
|
||||
return Color(uiColor)
|
||||
}
|
||||
return .yellow
|
||||
},
|
||||
set: { newColor in
|
||||
let uiColor = UIColor(newColor)
|
||||
if let data = try? NSKeyedArchiver.archivedData(
|
||||
withRootObject: uiColor,
|
||||
requiringSecureCoding: false
|
||||
) {
|
||||
UserDefaults.standard.set(data, forKey: "segmentsColorData")
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
Section(header: Text("Skip Settings"), footer : Text("Double tapping the screen on it's sides will skip with the short tap setting.")) {
|
||||
|
|
|
|||
BIN
public-build/Sulfur.ipa
Normal file
BIN
public-build/Sulfur.ipa
Normal file
Binary file not shown.
Loading…
Reference in a new issue