mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-20 16:12:50 +00:00
added some more graphical things
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
ce83066ced
commit
083946699d
4 changed files with 117 additions and 117 deletions
|
|
@ -42,6 +42,118 @@ struct HomeView: View {
|
|||
var body: some View {
|
||||
NavigationView {
|
||||
ScrollView {
|
||||
if !continueWatchingItems.isEmpty {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Continue Watching")
|
||||
.font(.headline)
|
||||
.padding(.horizontal, 8)
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 8) {
|
||||
ForEach(Array(continueWatchingItems.reversed())) { item in
|
||||
Button(action: {
|
||||
if UserDefaults.standard.string(forKey: "externalPlayer") == "Sora" {
|
||||
let customMediaPlayer = CustomMediaPlayer(
|
||||
module: item.module,
|
||||
urlString: item.streamUrl,
|
||||
fullUrl: item.fullUrl,
|
||||
title: item.mediaTitle,
|
||||
episodeNumber: item.episodeNumber,
|
||||
onWatchNext: { },
|
||||
subtitlesURL: item.subtitles,
|
||||
episodeImageUrl: item.imageUrl
|
||||
)
|
||||
let hostingController = UIHostingController(rootView: customMediaPlayer)
|
||||
hostingController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(hostingController, animated: true, completion: nil)
|
||||
}
|
||||
} else {
|
||||
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
|
||||
videoPlayerViewController.streamUrl = item.streamUrl
|
||||
videoPlayerViewController.fullUrl = item.fullUrl
|
||||
videoPlayerViewController.episodeImageUrl = item.imageUrl
|
||||
videoPlayerViewController.episodeNumber = item.episodeNumber
|
||||
videoPlayerViewController.mediaTitle = item.mediaTitle
|
||||
videoPlayerViewController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
VStack(alignment: .leading) {
|
||||
ZStack {
|
||||
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
|
||||
.placeholder {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 240, height: 135)
|
||||
.shimmering()
|
||||
}
|
||||
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 240, height: 135)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
.overlay(
|
||||
KFImage(URL(string: item.module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24)
|
||||
.cornerRadius(4)
|
||||
.padding(4),
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color.black.opacity(0.3))
|
||||
.blur(radius: 3)
|
||||
.frame(height: 30)
|
||||
|
||||
ProgressView(value: item.progress)
|
||||
.progressViewStyle(LinearProgressViewStyle(tint: .white))
|
||||
.padding(.horizontal, 8)
|
||||
.scaleEffect(x: 1, y: 1.5, anchor: .center)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.caption)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
Text(item.mediaTitle)
|
||||
.font(.caption)
|
||||
.lineLimit(2)
|
||||
.foregroundColor(.primary)
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.frame(width: 250, height: 190)
|
||||
}
|
||||
.contextMenu {
|
||||
Button(action: { markContinueWatchingItemAsWatched(item: item) }) {
|
||||
Label("Mark as Watched", systemImage: "checkmark.circle")
|
||||
}
|
||||
Button(role: .destructive, action: { removeContinueWatchingItem(item: item) }) {
|
||||
Label("Remove Item", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.frame(height: 190)
|
||||
}
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
HStack(alignment: .bottom, spacing: 5) {
|
||||
Text("Seasonal")
|
||||
|
|
@ -137,118 +249,6 @@ struct HomeView: View {
|
|||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
if !continueWatchingItems.isEmpty {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Continue Watching")
|
||||
.font(.headline)
|
||||
.padding(.horizontal, 8)
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 8) {
|
||||
ForEach(Array(continueWatchingItems.reversed())) { item in
|
||||
Button(action: {
|
||||
if UserDefaults.standard.string(forKey: "externalPlayer") == "Sora" {
|
||||
let customMediaPlayer = CustomMediaPlayer(
|
||||
module: item.module,
|
||||
urlString: item.streamUrl,
|
||||
fullUrl: item.fullUrl,
|
||||
title: item.mediaTitle,
|
||||
episodeNumber: item.episodeNumber,
|
||||
onWatchNext: { },
|
||||
subtitlesURL: item.subtitles,
|
||||
episodeImageUrl: item.imageUrl
|
||||
)
|
||||
let hostingController = UIHostingController(rootView: customMediaPlayer)
|
||||
hostingController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(hostingController, animated: true, completion: nil)
|
||||
}
|
||||
} else {
|
||||
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
|
||||
videoPlayerViewController.streamUrl = item.streamUrl
|
||||
videoPlayerViewController.fullUrl = item.fullUrl
|
||||
videoPlayerViewController.episodeImageUrl = item.imageUrl
|
||||
videoPlayerViewController.episodeNumber = item.episodeNumber
|
||||
videoPlayerViewController.mediaTitle = item.mediaTitle
|
||||
videoPlayerViewController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
VStack(alignment: .leading) {
|
||||
ZStack {
|
||||
KFImage(URL(string: item.imageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : item.imageUrl))
|
||||
.placeholder {
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 240, height: 135)
|
||||
.shimmering()
|
||||
}
|
||||
.setProcessor(RoundCornerImageProcessor(cornerRadius: 10))
|
||||
.resizable()
|
||||
.aspectRatio(16/9, contentMode: .fill)
|
||||
.frame(width: 240, height: 135)
|
||||
.cornerRadius(10)
|
||||
.clipped()
|
||||
.overlay(
|
||||
KFImage(URL(string: item.module.metadata.iconUrl))
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24)
|
||||
.cornerRadius(4)
|
||||
.padding(4),
|
||||
alignment: .topLeading
|
||||
)
|
||||
}
|
||||
.overlay(
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color.black.opacity(0.3))
|
||||
.blur(radius: 3)
|
||||
.frame(height: 30)
|
||||
|
||||
ProgressView(value: item.progress)
|
||||
.progressViewStyle(LinearProgressViewStyle(tint: .white))
|
||||
.padding(.horizontal, 8)
|
||||
.scaleEffect(x: 1, y: 1.5, anchor: .center)
|
||||
},
|
||||
alignment: .bottom
|
||||
)
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text("Episode \(item.episodeNumber)")
|
||||
.font(.caption)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
Text(item.mediaTitle)
|
||||
.font(.caption)
|
||||
.lineLimit(2)
|
||||
.foregroundColor(.primary)
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.frame(width: 250, height: 190)
|
||||
}
|
||||
.contextMenu {
|
||||
Button(action: { markContinueWatchingItemAsWatched(item: item) }) {
|
||||
Label("Mark as Watched", systemImage: "checkmark.circle")
|
||||
}
|
||||
Button(role: .destructive, action: { removeContinueWatchingItem(item: item) }) {
|
||||
Label("Remove Item", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.frame(height: 190)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 16)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ struct SettingsViewData: View {
|
|||
)
|
||||
}
|
||||
}
|
||||
.navigationTitle("App Data")
|
||||
}
|
||||
.navigationTitle("App Data")
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,10 +50,10 @@ struct SettingsViewGeneral: View {
|
|||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Modules")) {
|
||||
Section(header: Text("Modules"), footer: Text("Note that the modules will be replaced only if there is a different version string inside the JSON file.")) {
|
||||
Toggle("Refresh Modules on Launch", isOn: $refreshModulesOnLaunch)
|
||||
}
|
||||
}
|
||||
.navigationTitle("General")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ struct SettingsViewPlayer: View {
|
|||
@AppStorage("rememberPlaySpeed") private var isRememberPlaySpeed = false
|
||||
@AppStorage("holdSpeedPlayer") private var holdSpeedPlayer: Double = 2.0
|
||||
|
||||
private let mediaPlayers = ["Default", "Sora", "VLC", "OutPlayer", "Infuse", "nPlayer"]
|
||||
private let mediaPlayers = ["Default", "VLC", "OutPlayer", "Infuse", "nPlayer", "Sora"]
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section(header: Text("Media Player"), footer: Text("Some features are limited to Sora while others are limited to the Default player, such as ForceLandscape and holdSpeed.")) {
|
||||
Section(header: Text("Media Player"), footer: Text("Some features are limited to Sora while others are limited to the Default player, such as ForceLandscape and holdSpeed. Unfortunately the ForceLandscape doesn't yet working on the Sora Player.")) {
|
||||
HStack {
|
||||
Text("Media Player")
|
||||
Spacer()
|
||||
|
|
|
|||
Loading…
Reference in a new issue