diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 1.png b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 1.png new file mode 100644 index 0000000..4048369 Binary files /dev/null and b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 1.png differ diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 2.png b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 2.png new file mode 100644 index 0000000..4048369 Binary files /dev/null and b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut 2.png differ diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut.png b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut.png new file mode 100644 index 0000000..4048369 Binary files /dev/null and b/Sora/Assets.xcassets/AppIcon.appiconset/6hdvom4xz8gc2sut.png differ diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/Contents.json b/Sora/Assets.xcassets/AppIcon.appiconset/Contents.json index c7a15f9..7398b46 100644 --- a/Sora/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Sora/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,34 +1,24 @@ { "images" : [ { - "filename" : "lightmode.png", + "filename" : "6hdvom4xz8gc2sut.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" }, { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "darkmode.png", + "filename" : "6hdvom4xz8gc2sut 1.png", "idiom" : "universal", "platform" : "ios", - "size" : "1024x1024" + "size" : "1024x1024", + "unassigned" : true }, { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "filename" : "tinting.png", + "filename" : "6hdvom4xz8gc2sut 2.png", "idiom" : "universal", "platform" : "ios", - "size" : "1024x1024" + "size" : "1024x1024", + "unassigned" : true } ], "info" : { diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/darkmode.png b/Sora/Assets.xcassets/AppIcon.appiconset/darkmode.png deleted file mode 100644 index c8f6f6f..0000000 Binary files a/Sora/Assets.xcassets/AppIcon.appiconset/darkmode.png and /dev/null differ diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/lightmode.png b/Sora/Assets.xcassets/AppIcon.appiconset/lightmode.png deleted file mode 100644 index 7256d08..0000000 Binary files a/Sora/Assets.xcassets/AppIcon.appiconset/lightmode.png and /dev/null differ diff --git a/Sora/Assets.xcassets/AppIcon.appiconset/tinting.png b/Sora/Assets.xcassets/AppIcon.appiconset/tinting.png deleted file mode 100644 index f55a3d9..0000000 Binary files a/Sora/Assets.xcassets/AppIcon.appiconset/tinting.png and /dev/null differ diff --git a/Sora/Views/LibraryView/AllReading.swift b/Sora/Views/LibraryView/AllReading.swift index 9310acb..d3ab615 100644 --- a/Sora/Views/LibraryView/AllReading.swift +++ b/Sora/Views/LibraryView/AllReading.swift @@ -5,13 +5,14 @@ // Created by paul on 26/06/25. // -import SwiftUI +import UIKit import NukeUI +import SwiftUI struct AllReadingView: View { @Environment(\.dismiss) private var dismiss - - + + @State private var continueReadingItems: [ContinueReadingItem] = [] @State private var isRefreshing: Bool = false @State private var sortOption: SortOption = .dateAdded @@ -204,10 +205,10 @@ struct AllReadingView: View { } else { ForEach(filteredAndSortedItems) { item in FullWidthContinueReadingCell( - item: item, + item: item, markAsRead: { markContinueReadingItemAsRead(item: item) - }, + }, removeItem: { removeContinueReadingItem(item: item) }, @@ -335,18 +336,12 @@ struct FullWidthContinueReadingCell: View { } } } else { - NavigationLink(destination: ReaderView( - moduleId: item.moduleId, - chapterHref: item.href, - chapterTitle: item.chapterTitle, - mediaTitle: item.mediaTitle, - chapterNumber: item.chapterNumber - )) { + Button(action: { + presentReaderView() + }) { cellContent } - .simultaneousGesture(TapGesture().onEnded { - UserDefaults.standard.set(true, forKey: "navigatingToReaderView") - }) + .buttonStyle(PlainButtonStyle()) } } .contextMenu { @@ -445,4 +440,38 @@ struct FullWidthContinueReadingCell: View { } .frame(height: 157.03) } -} + + private func presentReaderView() { + UserDefaults.standard.set(true, forKey: "navigatingToReaderView") + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + let topVC = findTopViewController.findViewController(rootVC) + + if topVC is UIHostingController { + Logger.shared.log("ReaderView is already presented, skipping presentation", type: "Debug") + return + } + } + + let readerView = ReaderView( + moduleId: item.moduleId, + chapterHref: item.href, + chapterTitle: item.chapterTitle, + chapters: [], + mediaTitle: item.mediaTitle, + chapterNumber: item.chapterNumber + ) + + let hostingController = UIHostingController(rootView: readerView) + hostingController.modalPresentationStyle = .overFullScreen + hostingController.modalTransitionStyle = .crossDissolve + + hostingController.isModalInPresentation = true + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + findTopViewController.findViewController(rootVC).present(hostingController, animated: true) + } + } +} diff --git a/Sora/Views/LibraryView/ContinueReadingSection.swift b/Sora/Views/LibraryView/ContinueReadingSection.swift index abba180..20b5409 100644 --- a/Sora/Views/LibraryView/ContinueReadingSection.swift +++ b/Sora/Views/LibraryView/ContinueReadingSection.swift @@ -5,8 +5,9 @@ // Created by paul on 26/06/25. // -import SwiftUI +import UIKit import NukeUI +import SwiftUI struct ContinueReadingSection: View { @Binding var items: [ContinueReadingItem] @@ -67,14 +68,9 @@ struct ContinueReadingCell: View { } var body: some View { - NavigationLink(destination: ReaderView( - moduleId: item.moduleId, - chapterHref: item.href, - chapterTitle: item.chapterTitle, - chapters: [], - mediaTitle: item.mediaTitle, - chapterNumber: item.chapterNumber - )) { + Button(action: { + presentReaderView() + }) { ZStack { LazyImage(url: imageURL) { state in if let image = state.imageContainer?.image { @@ -178,4 +174,38 @@ struct ContinueReadingCell: View { print("Progress: \(item.progress)") } } + + private func presentReaderView() { + UserDefaults.standard.set(true, forKey: "navigatingToReaderView") + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + let topVC = findTopViewController.findViewController(rootVC) + + if topVC is UIHostingController { + Logger.shared.log("ReaderView is already presented, skipping presentation", type: "Debug") + return + } + } + + let readerView = ReaderView( + moduleId: item.moduleId, + chapterHref: item.href, + chapterTitle: item.chapterTitle, + chapters: [], + mediaTitle: item.mediaTitle, + chapterNumber: item.chapterNumber + ) + + let hostingController = UIHostingController(rootView: readerView) + hostingController.modalPresentationStyle = .overFullScreen + hostingController.modalTransitionStyle = .crossDissolve + + hostingController.isModalInPresentation = true + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + findTopViewController.findViewController(rootVC).present(hostingController, animated: true) + } + } } diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index 6313b0a..d3f8e9e 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -728,8 +728,8 @@ struct MediaInfoView: View { if let href = chapter["href"] as? String, let number = chapter["number"] as? Int, let title = chapter["title"] as? String { - NavigationLink( - destination: ReaderView( + Button(action: { + presentReaderView( moduleId: module.id, chapterHref: href, chapterTitle: title, @@ -737,12 +737,7 @@ struct MediaInfoView: View { mediaTitle: self.title, chapterNumber: number ) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - ChapterNavigator.shared.currentChapter = nil - } - } - ) { + }) { ChapterCell( chapterNumber: String(number), chapterTitle: title, @@ -751,17 +746,7 @@ struct MediaInfoView: View { href: href ) } - .simultaneousGesture(TapGesture().onEnded { - UserDefaults.standard.set(true, forKey: "navigatingToReaderView") - ChapterNavigator.shared.currentChapter = ( - moduleId: module.id, - href: href, - title: title, - chapters: chapters, - mediaTitle: self.title, - chapterNumber: number - ) - }) + .buttonStyle(PlainButtonStyle()) .contextMenu { Button(action: { markChapterAsRead(href: href, number: number) @@ -1295,10 +1280,10 @@ struct MediaInfoView: View { let number = chapterToRead["number"] as? Int { UserDefaults.standard.set(true, forKey: "navigatingToReaderView") - ChapterNavigator.shared.currentChapter = ( + presentReaderView( moduleId: module.id, - href: href, - title: title, + chapterHref: href, + chapterTitle: title, chapters: chapters, mediaTitle: self.title, chapterNumber: number @@ -1438,6 +1423,40 @@ struct MediaInfoView: View { } + private func presentReaderView(moduleId: UUID, chapterHref: String, chapterTitle: String, chapters: [[String: Any]], mediaTitle: String, chapterNumber: Int) { + UserDefaults.standard.set(true, forKey: "navigatingToReaderView") + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + let topVC = findTopViewController.findViewController(rootVC) + + if topVC is UIHostingController { + Logger.shared.log("ReaderView is already presented, skipping presentation", type: "Debug") + return + } + } + + let readerView = ReaderView( + moduleId: moduleId, + chapterHref: chapterHref, + chapterTitle: chapterTitle, + chapters: chapters, + mediaTitle: mediaTitle, + chapterNumber: chapterNumber + ) + + let hostingController = UIHostingController(rootView: readerView) + hostingController.modalPresentationStyle = .overFullScreen + hostingController.modalTransitionStyle = .crossDissolve + + hostingController.isModalInPresentation = true + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + findTopViewController.findViewController(rootVC).present(hostingController, animated: true) + } + } + private func openSafariViewController(with urlString: String) { guard let url = URL(string: urlString), UIApplication.shared.canOpenURL(url) else { Logger.shared.log("Unable to open the webpage", type: "Error") diff --git a/Sora/Views/ReaderView/ReaderView.swift b/Sora/Views/ReaderView/ReaderView.swift index e233f42..30dca2f 100644 --- a/Sora/Views/ReaderView/ReaderView.swift +++ b/Sora/Views/ReaderView/ReaderView.swift @@ -123,8 +123,6 @@ struct ReaderView: View { } } - - var body: some View { ZStack(alignment: .bottom) { currentTheme.background.ignoresSafeArea() @@ -267,10 +265,10 @@ struct ReaderView: View { chapterNumber: next.chapterNumber ) - let hostingController = UIHostingController(rootView: nextReader) - hostingController.modalPresentationStyle = .fullScreen + hostingController.modalPresentationStyle = .overFullScreen hostingController.modalTransitionStyle = .crossDissolve + hostingController.isModalInPresentation = true findTopViewController.findViewController(rootVC).present(hostingController, animated: true) } @@ -430,7 +428,7 @@ struct ReaderView: View { ZStack(alignment: .top) { HStack { Button(action: { - dismiss() + dismissReaderView() }) { Image(systemName: "chevron.left") .font(.system(size: 16, weight: .bold)) @@ -794,6 +792,18 @@ struct ReaderView: View { .circularGradientOutline() } + private func dismissReaderView() { + dismiss() + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let rootVC = windowScene.windows.first?.rootViewController { + let topVC = findTopViewController.findViewController(rootVC) + if topVC is UIHostingController { + topVC.dismiss(animated: true) + } + } + } + private func goToNextChapter() { guard let currentIndex = chapters.firstIndex(where: { $0["href"] as? String == chapterHref }), currentIndex + 1 < chapters.count else {