diff --git a/Sora/Localizable.xcstrings b/Sora/Localizable.xcstrings new file mode 100644 index 0000000..d66b847 --- /dev/null +++ b/Sora/Localizable.xcstrings @@ -0,0 +1,435 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "" : { + + }, + "%lld" : { + + }, + "%lld Episodes" : { + + }, + "%lld of %lld" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld of %2$lld" + } + } + } + }, + "%lld-%lld" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld-%2$lld" + } + } + } + }, + "%lld%%" : { + + }, + "%lld%% seen" : { + + }, + "•" : { + + }, + "About" : { + + }, + "Actively downloading media can be tracked from here." : { + + }, + "Add Module" : { + + }, + "AKA Sulfur" : { + + }, + "All Bookmarks" : { + + }, + "All Prev" : { + + }, + "All Watching" : { + + }, + "AniList ID" : { + + }, + "AniList Match" : { + + }, + "AniList.co" : { + + }, + "App Data" : { + + }, + "Are you sure you want to delete '%@'?" : { + + }, + "Are you sure you want to delete all %lld episodes in '%@'?" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Are you sure you want to delete all %1$lld episodes in '%2$@'?" + } + } + } + }, + "Are you sure you want to delete all downloaded assets? You can choose to clear only the library while preserving the downloaded files for future use." : { + + }, + "Are you sure you want to erase all app data? This action cannot be undone." : { + + }, + "Are you sure you want to remove all files in the Documents folder? This will remove all modules." : { + + }, + "Author" : { + + }, + "Bookmark items for an easier access later." : { + + }, + "Bookmarks" : { + + }, + "Cancel" : { + + }, + "Check out some community modules here!" : { + + }, + "Clear" : { + + }, + "Clear All Caches" : { + + }, + "Clear All Downloads" : { + + }, + "Clear Library Only" : { + + }, + "Clear Logs" : { + + }, + "Click the plus button to add a module!" : { + + }, + "Continue Watching" : { + + }, + "Copy to Clipboard" : { + + }, + "Copy URL" : { + + }, + "cranci1" : { + + }, + "Current Cache Size" : { + + }, + "DATA/LOGS" : { + + }, + "Delete" : { + + }, + "Delete All" : { + + }, + "Delete All Downloads" : { + + }, + "Delete All Episodes" : { + + }, + "Delete Download" : { + + }, + "Delete Episode" : { + + }, + "Download" : { + + }, + "Download Episode" : { + + }, + "Downloads" : { + + }, + "Enter the AniList ID for this media" : { + + }, + "Episode %lld" : { + + }, + "Episodes" : { + + }, + "Episodes might not be available yet or there could be an issue with the source." : { + + }, + "Erase" : { + + }, + "Erase App Data" : { + + }, + "Error" : { + + }, + "Failed to load contributors" : { + + }, + "Files Downloaded" : { + + }, + "General" : { + + }, + "INFOS" : { + + }, + "LESS" : { + + }, + "Library" : { + + }, + "Loading Episode %lld..." : { + + }, + "Loading logs..." : { + + }, + "Loading module information..." : { + + }, + "Loading Stream" : { + + }, + "Log Debug Info" : { + + }, + "Log Filters" : { + + }, + "Log In with AniList" : { + + }, + "Log In with Trakt" : { + + }, + "Log Out from AniList" : { + + }, + "Log Out from Trakt" : { + + }, + "Logged in as " : { + + }, + "Logs" : { + + }, + "MAIN" : { + + }, + "Mark All Previous Watched" : { + + }, + "Mark as Watched" : { + + }, + "Match with AniList" : { + + }, + "Matched with: %@" : { + + }, + "Max Concurrent Downloads" : { + + }, + "me frfr" : { + + }, + "Modules" : { + + }, + "MORE" : { + + }, + "No Active Downloads" : { + + }, + "No Data Available" : { + + }, + "No Downloads" : { + + }, + "No episodes available" : { + + }, + "No Episodes Available" : { + + }, + "No items to continue watching." : { + + }, + "No matches found" : { + + }, + "No Module Selected" : { + + }, + "No Modules" : { + + }, + "No Results Found" : { + + }, + "OK" : { + + }, + "Open Community Library" : { + + }, + "Open in AniList" : { + + }, + "Play" : { + + }, + "Player" : { + + }, + "Please select a module from settings" : { + + }, + "Queued" : { + + }, + "Recently watched content will appear here." : { + + }, + "Refresh Storage Info" : { + + }, + "Remove" : { + + }, + "Remove Documents" : { + + }, + "Remove from Bookmarks" : { + + }, + "Remove Item" : { + + }, + "Reset" : { + + }, + "Reset AniList ID" : { + + }, + "Reset Progress" : { + + }, + "Running Sora %@ - cranci1" : { + + }, + "Save" : { + + }, + "Search" : { + + }, + "Search downloads" : { + + }, + "Search for something..." : { + + }, + "Search..." : { + + }, + "Season %lld" : { + + }, + "Select Module" : { + + }, + "Set Custom AniList ID" : { + + }, + "Settings" : { + + }, + "Show More (%lld more characters)" : { + + }, + "Sora" : { + + }, + "Sort" : { + + }, + "Storage Used" : { + + }, + "Tap a title to override the current match." : { + + }, + "The module provided only a single episode, this is most likely a movie, so we decided to make separate screens for these cases." : { + + }, + "Trackers" : { + + }, + "Trakt.tv" : { + + }, + "Try different keywords" : { + + }, + "Use TMDB Poster Image" : { + + }, + "v%@" : { + + }, + "View All" : { + + }, + "Watched" : { + + }, + "Why am I not seeing any episodes?" : { + + }, + "You have no items saved." : { + + }, + "Your downloaded episodes will appear here" : { + + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index be414be..851ea18 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -123,38 +123,6 @@ struct MediaInfoView: View { .ignoresSafeArea(.container, edges: .top) .onAppear { buttonRefreshTrigger.toggle() - - let savedID = UserDefaults.standard.integer(forKey: "custom_anilist_id_\(href)") - if savedID != 0 { customAniListID = savedID } - - if let savedPoster = UserDefaults.standard.string(forKey: "tmdbPosterURL_\(href)") { - self.imageUrl = savedPoster - } - - if !hasFetched { - DropManager.shared.showDrop( - title: "Fetching Data", - subtitle: "Please wait while fetching.", - duration: 0.5, - icon: UIImage(systemName: "arrow.triangle.2.circlepath") - ) - fetchDetails() - - if let savedID = UserDefaults.standard.object(forKey: "custom_anilist_id_\(href)") as? Int { - customAniListID = savedID - itemID = savedID - Logger.shared.log("Using custom AniList ID: \(savedID)", type: "Debug") - } else { - fetchMetadataIDIfNeeded() - } - - hasFetched = true - AnalyticsManager.shared.sendEvent( - event: "MediaInfoView", - additionalData: ["title": title] - ) - } - tabBarController.hideTabBar() } .onChange(of: selectedRange) { newValue in @@ -174,12 +142,8 @@ struct MediaInfoView: View { if let savedPoster = UserDefaults.standard.string(forKey: "tmdbPosterURL_\(href)") { imageUrl = savedPoster } - DropManager.shared.showDrop( - title: "Fetching Data", - subtitle: "Please wait while fetching.", - duration: 0.5, - icon: UIImage(systemName: "arrow.triangle.2.circlepath") - ) + + DropManager.shared.showDrop(title: "Fetching Data", subtitle: "Please wait while fetching.", duration: 0.5, icon: UIImage(systemName: "arrow.triangle.2.circlepath")) fetchDetails() if savedCustomID != 0 { @@ -255,11 +219,12 @@ struct MediaInfoView: View { .clipped() } } + VStack(spacing: 0) { Rectangle() .fill(Color.clear) .frame(height: 400) - VStack(alignment: .leading, spacing: 16) { + LazyVStack(alignment: .leading, spacing: 16) { headerSection if !episodeLinks.isEmpty { episodesSection @@ -289,12 +254,11 @@ struct MediaInfoView: View { .onAppear { UIScrollView.appearance().bounces = false } - .ignoresSafeArea(.container, edges: .top) } @ViewBuilder private var headerSection: some View { - VStack(alignment: .leading, spacing: 8) { + LazyVStack(alignment: .leading, spacing: 8) { Spacer() HStack(spacing: 16) { @@ -449,7 +413,7 @@ struct MediaInfoView: View { @ViewBuilder private var contentSection: some View { - VStack(alignment: .leading, spacing: 20) { + LazyVStack(alignment: .leading, spacing: 20) { playAndBookmarkSection if !episodeLinks.isEmpty { diff --git a/Sulfur.xcodeproj/project.pbxproj b/Sulfur.xcodeproj/project.pbxproj index d9b6d74..6d75d52 100644 --- a/Sulfur.xcodeproj/project.pbxproj +++ b/Sulfur.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 132AF1252D9995F900A0140B /* JSController-Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132AF1242D9995F900A0140B /* JSController-Search.swift */; }; 13367ECC2DF70698009CB33F /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 13367ECB2DF70698009CB33F /* Nuke */; }; 13367ECE2DF70698009CB33F /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 13367ECD2DF70698009CB33F /* NukeUI */; }; + 13367ED02DF70819009CB33F /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 13367ECF2DF70819009CB33F /* Localizable.xcstrings */; }; 133D7C6E2D2BE2500075467E /* SoraApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C6D2D2BE2500075467E /* SoraApp.swift */; }; 133D7C702D2BE2500075467E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C6F2D2BE2500075467E /* ContentView.swift */; }; 133D7C722D2BE2520075467E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 133D7C712D2BE2520075467E /* Assets.xcassets */; }; @@ -124,6 +125,7 @@ 132AF1202D99951700A0140B /* JSController-Streams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSController-Streams.swift"; sourceTree = ""; }; 132AF1222D9995C300A0140B /* JSController-Details.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSController-Details.swift"; sourceTree = ""; }; 132AF1242D9995F900A0140B /* JSController-Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSController-Search.swift"; sourceTree = ""; }; + 13367ECF2DF70819009CB33F /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 133D7C6A2D2BE2500075467E /* Sulfur.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sulfur.app; sourceTree = BUILT_PRODUCTS_DIR; }; 133D7C6D2D2BE2500075467E /* SoraApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoraApp.swift; sourceTree = ""; }; 133D7C6F2D2BE2500075467E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -322,6 +324,7 @@ 133D7C6F2D2BE2500075467E /* ContentView.swift */, 133D7C712D2BE2520075467E /* Assets.xcassets */, 133D7C732D2BE2520075467E /* Preview Content */, + 13367ECF2DF70819009CB33F /* Localizable.xcstrings */, ); path = Sora; sourceTree = ""; @@ -669,6 +672,7 @@ files = ( 133D7C752D2BE2520075467E /* Preview Assets.xcassets in Resources */, 133D7C722D2BE2520075467E /* Assets.xcassets in Resources */, + 13367ED02DF70819009CB33F /* Localizable.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; };