mirror of
https://github.com/cranci1/Sora.git
synced 2026-01-11 20:10:24 +00:00
IBH bug report fixes (Read description) (#197)
This commit is contained in:
parent
019989df4f
commit
5ef6316036
23 changed files with 139 additions and 87 deletions
|
|
@ -5,9 +5,9 @@
|
|||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
"blue" : "0.000",
|
||||
"green" : "0.000",
|
||||
"red" : "0.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
|
@ -23,9 +23,9 @@
|
|||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.000",
|
||||
"green" : "0.000",
|
||||
"red" : "0.000"
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Drops
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
|
||||
class DropManager {
|
||||
static let shared = DropManager()
|
||||
|
|
@ -59,7 +60,8 @@ class DropManager {
|
|||
}
|
||||
|
||||
func info(_ message: String, duration: TimeInterval = 2.0) {
|
||||
let icon = UIImage(systemName: "info.circle.fill")?.withTintColor(.blue, renderingMode: .alwaysOriginal)
|
||||
let accentColor = UIColor(Color.accentColor)
|
||||
let icon = UIImage(systemName: "info.circle.fill")?.withTintColor(accentColor, renderingMode: .alwaysOriginal)
|
||||
showDrop(title: "Info", subtitle: message, duration: duration, icon: icon)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ struct ModuleAdditionSettingsView: View {
|
|||
}
|
||||
.padding(.bottom, 8)
|
||||
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
if let metadata = moduleMetadata {
|
||||
VStack(spacing: 0) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ struct DownloadView: View {
|
|||
if jsController.activeDownloads.isEmpty && jsController.downloadQueue.isEmpty {
|
||||
emptyActiveDownloadsView
|
||||
} else {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 20) {
|
||||
if !jsController.downloadQueue.isEmpty {
|
||||
DownloadSectionView(
|
||||
|
|
@ -109,7 +109,7 @@ struct DownloadView: View {
|
|||
if filteredAndSortedAssets.isEmpty {
|
||||
emptyDownloadsView
|
||||
} else {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 20) {
|
||||
DownloadSummaryCard(
|
||||
totalShows: groupedAssets.count,
|
||||
|
|
@ -888,7 +888,7 @@ struct EnhancedDownloadGroupCard: View {
|
|||
.foregroundStyle(.primary)
|
||||
|
||||
HStack(spacing: 16) {
|
||||
Label("\(group.assetCount)", systemImage: "play.rectangle")
|
||||
Label("\(group.assetCount) \(group.assetCount == 1 ? "Episode" : "Episodes")", systemImage: "play.rectangle")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
|
|
@ -956,7 +956,7 @@ struct EnhancedShowEpisodesView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
VStack(spacing: 20) {
|
||||
HStack(alignment: .top, spacing: 20) {
|
||||
|
|
@ -997,7 +997,7 @@ struct EnhancedShowEpisodesView: View {
|
|||
HStack {
|
||||
Image(systemName: "play.rectangle.fill")
|
||||
.foregroundColor(.accentColor)
|
||||
Text("\(group.assetCount) Episodes")
|
||||
Text("\(group.assetCount) \(group.assetCount == 1 ? "Episode" : "Episodes")")
|
||||
.font(.headline)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ struct AllWatchingView: View {
|
|||
.padding(.horizontal)
|
||||
.padding(.top)
|
||||
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
LazyVStack(spacing: 12) {
|
||||
ForEach(sortedItems) { item in
|
||||
FullWidthContinueWatchingCell(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct BookmarkGridView: View {
|
|||
]
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
LazyVGrid(columns: columns, spacing: 16) {
|
||||
ForEach(bookmarks) { bookmark in
|
||||
BookmarkGridItemView(
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ private struct BookmarksDetailGrid: View {
|
|||
let moduleManager: ModuleManager
|
||||
private let columns = [GridItem(.adaptive(minimum: 150))]
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
LazyVGrid(columns: columns, spacing: 16) {
|
||||
ForEach(bookmarks) { bookmark in
|
||||
BookmarksDetailGridCell(bookmark: bookmark, moduleManager: moduleManager)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct LibraryView: View {
|
|||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
Text("Library")
|
||||
.font(.largeTitle)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ struct AnilistMatchPopupView: View {
|
|||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("".uppercased())
|
||||
.font(.footnote)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ struct TMDBMatchPopupView: View {
|
|||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 0) {
|
||||
if isLoading {
|
||||
ProgressView()
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ struct MediaInfoView: View {
|
|||
|
||||
@ViewBuilder
|
||||
private var mainScrollView: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
ZStack(alignment: .top) {
|
||||
heroImageSection
|
||||
contentContainer
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ struct SearchResultsGrid: View {
|
|||
@AppStorage("mediaColumnsPortrait") private var mediaColumnsPortrait: Int = 2
|
||||
@AppStorage("mediaColumnsLandscape") private var mediaColumnsLandscape: Int = 4
|
||||
@Environment(\.verticalSizeClass) var verticalSizeClass
|
||||
@EnvironmentObject private var libraryManager: LibraryManager
|
||||
@EnvironmentObject private var moduleManager: ModuleManager
|
||||
@State private var showBookmarkToast: Bool = false
|
||||
@State private var toastMessage: String = ""
|
||||
|
||||
let items: [SearchItem]
|
||||
let columns: [GridItem]
|
||||
|
|
@ -28,57 +32,100 @@ struct SearchResultsGrid: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: columnsCount), spacing: 12) {
|
||||
ForEach(items) { item in
|
||||
NavigationLink(destination: MediaInfoView(title: item.title, imageUrl: item.imageUrl, href: item.href, module: selectedModule)) {
|
||||
ZStack {
|
||||
LazyImage(url: URL(string: item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
ZStack {
|
||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: columnsCount), spacing: 12) {
|
||||
ForEach(items) { item in
|
||||
NavigationLink(destination: MediaInfoView(title: item.title, imageUrl: item.imageUrl, href: item.href, module: selectedModule)) {
|
||||
ZStack {
|
||||
LazyImage(url: URL(string: item.imageUrl)) { state in
|
||||
if let uiImage = state.imageContainer?.image {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(0.72, contentMode: .fill)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.tertiary)
|
||||
.frame(width: cellWidth, height: cellWidth * 1.5)
|
||||
.cornerRadius(12)
|
||||
.clipped()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
HStack {
|
||||
Text(item.title)
|
||||
.lineLimit(2)
|
||||
.foregroundColor(.white)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
}
|
||||
.padding(12)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
HStack {
|
||||
Text(item.title)
|
||||
.lineLimit(2)
|
||||
.foregroundColor(.white)
|
||||
.multilineTextAlignment(.leading)
|
||||
Spacer()
|
||||
}
|
||||
.padding(12)
|
||||
.background(
|
||||
LinearGradient(
|
||||
colors: [
|
||||
.black.opacity(0.7),
|
||||
.black.opacity(0.0)
|
||||
],
|
||||
startPoint: .bottom,
|
||||
endPoint: .top
|
||||
)
|
||||
.shadow(color: .black, radius: 4, x: 0, y: 2)
|
||||
)
|
||||
.shadow(color: .black, radius: 4, x: 0, y: 2)
|
||||
)
|
||||
}
|
||||
.frame(width: cellWidth)
|
||||
}
|
||||
.frame(width: cellWidth)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 12))
|
||||
.padding(4)
|
||||
}
|
||||
.clipShape(RoundedRectangle(cornerRadius: 12))
|
||||
.padding(4)
|
||||
}.id(item.href)
|
||||
.id(item.href)
|
||||
.contextMenu {
|
||||
Button(action: {
|
||||
let isBookmarked = libraryManager.isBookmarked(href: item.href, moduleName: selectedModule.metadata.sourceName)
|
||||
libraryManager.toggleBookmark(
|
||||
title: item.title,
|
||||
imageUrl: item.imageUrl,
|
||||
href: item.href,
|
||||
moduleId: selectedModule.id.uuidString,
|
||||
moduleName: selectedModule.metadata.sourceName
|
||||
)
|
||||
DropManager.shared.showDrop(
|
||||
title: isBookmarked ? "Removed from Bookmarks" : "Bookmarked!",
|
||||
subtitle: item.title,
|
||||
duration: 1.0,
|
||||
icon: UIImage(systemName: isBookmarked ? "bookmark.slash" : "bookmark.fill")
|
||||
)
|
||||
}) {
|
||||
Label(libraryManager.isBookmarked(href: item.href, moduleName: selectedModule.metadata.sourceName) ? "Remove Bookmark" : "Bookmark",
|
||||
systemImage: libraryManager.isBookmarked(href: item.href, moduleName: selectedModule.metadata.sourceName) ? "bookmark.slash" : "bookmark")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.top)
|
||||
.padding()
|
||||
|
||||
if showBookmarkToast {
|
||||
VStack {
|
||||
Spacer()
|
||||
Text(toastMessage)
|
||||
.font(.headline)
|
||||
.padding()
|
||||
.background(Color.black.opacity(0.8))
|
||||
.foregroundColor(.white)
|
||||
.cornerRadius(12)
|
||||
.padding(.bottom, 40)
|
||||
.transition(.move(edge: .bottom).combined(with: .opacity))
|
||||
}
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
|
||||
withAnimation { showBookmarkToast = false }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.top)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ struct SearchView: View {
|
|||
.padding(.horizontal, 20)
|
||||
.padding(.top, 20)
|
||||
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
SearchContent(
|
||||
selectedModule: selectedModule,
|
||||
searchQuery: searchQuery,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ fileprivate struct SettingsSection<Content: View>: View {
|
|||
|
||||
struct SettingsViewAbout: View {
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(title: "App Info", footer: "Sora/Sulfur will always remain free with no ads!") {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ struct SettingsViewData: View {
|
|||
@State private var activeAlert: ActiveAlert = .eraseData
|
||||
|
||||
var body: some View {
|
||||
return ScrollView {
|
||||
return ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(
|
||||
title: NSLocalizedString("App Storage", comment: ""),
|
||||
|
|
@ -191,6 +191,7 @@ struct SettingsViewData: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 20)
|
||||
.scrollViewBottomPadding()
|
||||
.navigationTitle(NSLocalizedString("App Data", comment: ""))
|
||||
.onAppear {
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ struct SettingsViewDownloads: View {
|
|||
@State private var isCalculating: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(
|
||||
title: String(localized: "Download Settings"),
|
||||
|
|
@ -309,9 +309,9 @@ struct SettingsViewDownloads: View {
|
|||
}
|
||||
}
|
||||
.padding(.vertical, 20)
|
||||
.scrollViewBottomPadding()
|
||||
.navigationTitle(String(localized: "Downloads"))
|
||||
}
|
||||
.navigationTitle(String(localized: "Downloads"))
|
||||
.scrollViewBottomPadding()
|
||||
.alert(String(localized: "Delete All Downloads"), isPresented: $showClearConfirmation) {
|
||||
Button(String(localized: "Cancel"), role: .cancel) { }
|
||||
Button(String(localized: "Delete All"), role: .destructive) {
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ struct SettingsViewGeneral: View {
|
|||
@State private var showRestartAlert = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(title: NSLocalizedString("Interface", comment: "")) {
|
||||
SettingsPickerRow(
|
||||
|
|
@ -347,8 +347,9 @@ struct SettingsViewGeneral: View {
|
|||
)
|
||||
}
|
||||
}
|
||||
.navigationTitle("General")
|
||||
.padding(.vertical, 20)
|
||||
.scrollViewBottomPadding()
|
||||
.navigationTitle("General")
|
||||
}
|
||||
.navigationTitle(NSLocalizedString("General", comment: ""))
|
||||
.scrollViewBottomPadding()
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ struct SettingsViewLogger: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(title: NSLocalizedString("Logs", comment: "")) {
|
||||
if isLoading {
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ struct SettingsViewLoggerFilter: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(title: NSLocalizedString("Log Types", comment: "")) {
|
||||
ForEach($viewModel.filters) { $filter in
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ struct SettingsViewModule: View {
|
|||
@State private var showLibrary = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
if moduleManager.modules.isEmpty {
|
||||
SettingsSection(title: NSLocalizedString("Modules", comment: "")) {
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ struct SettingsViewPlayer: View {
|
|||
private let qualityOptions = VideoQualityPreference.allCases.map { $0.rawValue }
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(
|
||||
title: NSLocalizedString("Media Player", comment: ""),
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ struct SettingsViewTrackers: View {
|
|||
@State private var isTraktLoading: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
SettingsSection(title: NSLocalizedString("AniList", comment: "")) {
|
||||
VStack(spacing: 0) {
|
||||
|
|
|
|||
|
|
@ -131,10 +131,11 @@ struct SettingsView: View {
|
|||
@Environment(\.colorScheme) var colorScheme
|
||||
@StateObject var settings = Settings()
|
||||
@EnvironmentObject var moduleManager: ModuleManager
|
||||
@State private var isNavigationActive = false
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ScrollView {
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(spacing: 24) {
|
||||
Text("Settings")
|
||||
.font(.largeTitle)
|
||||
|
|
@ -150,7 +151,7 @@ struct SettingsView: View {
|
|||
.foregroundStyle(.gray)
|
||||
.padding(.horizontal, 20)
|
||||
|
||||
NavigationLink(destination: SettingsViewModule()) {
|
||||
NavigationLink(destination: SettingsViewModule().navigationBarBackButtonHidden(false)) {
|
||||
ModulePreviewRow()
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
|
|
@ -163,22 +164,22 @@ struct SettingsView: View {
|
|||
.padding(.horizontal, 20)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
NavigationLink(destination: SettingsViewGeneral()) {
|
||||
NavigationLink(destination: SettingsViewGeneral().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "gearshape", titleKey: "General Preferences")
|
||||
}
|
||||
Divider().padding(.horizontal, 16)
|
||||
|
||||
NavigationLink(destination: SettingsViewPlayer()) {
|
||||
NavigationLink(destination: SettingsViewPlayer().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "play.circle", titleKey: "Video Player")
|
||||
}
|
||||
Divider().padding(.horizontal, 16)
|
||||
|
||||
NavigationLink(destination: SettingsViewDownloads()) {
|
||||
NavigationLink(destination: SettingsViewDownloads().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "arrow.down.circle", titleKey: "Downloads")
|
||||
}
|
||||
Divider().padding(.horizontal, 16)
|
||||
|
||||
NavigationLink(destination: SettingsViewTrackers()) {
|
||||
NavigationLink(destination: SettingsViewTrackers().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "square.stack.3d.up", titleKey: "Trackers")
|
||||
}
|
||||
}
|
||||
|
|
@ -208,12 +209,12 @@ struct SettingsView: View {
|
|||
.padding(.horizontal, 20)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
NavigationLink(destination: SettingsViewData()) {
|
||||
NavigationLink(destination: SettingsViewData().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "folder", titleKey: "Data")
|
||||
}
|
||||
Divider().padding(.horizontal, 16)
|
||||
|
||||
NavigationLink(destination: SettingsViewLogger()) {
|
||||
NavigationLink(destination: SettingsViewLogger().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "doc.text", titleKey: "Logs")
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +244,7 @@ struct SettingsView: View {
|
|||
.padding(.horizontal, 20)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
NavigationLink(destination: SettingsViewAbout()) {
|
||||
NavigationLink(destination: SettingsViewAbout().navigationBarBackButtonHidden(false)) {
|
||||
SettingsNavigationRow(icon: "info.circle", titleKey: "About Sora")
|
||||
}
|
||||
Divider().padding(.horizontal, 16)
|
||||
|
|
|
|||
Loading…
Reference in a new issue