mirror of
https://github.com/cranci1/Sora.git
synced 2026-01-11 20:10:24 +00:00
localization + LazyVStack
This commit is contained in:
parent
65f1fcf0d4
commit
73773f3265
3 changed files with 445 additions and 42 deletions
435
Sora/Localizable.xcstrings
Normal file
435
Sora/Localizable.xcstrings
Normal file
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 = "<group>"; };
|
||||
132AF1222D9995C300A0140B /* JSController-Details.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSController-Details.swift"; sourceTree = "<group>"; };
|
||||
132AF1242D9995F900A0140B /* JSController-Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSController-Search.swift"; sourceTree = "<group>"; };
|
||||
13367ECF2DF70819009CB33F /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
133D7C6F2D2BE2500075467E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -322,6 +324,7 @@
|
|||
133D7C6F2D2BE2500075467E /* ContentView.swift */,
|
||||
133D7C712D2BE2520075467E /* Assets.xcassets */,
|
||||
133D7C732D2BE2520075467E /* Preview Content */,
|
||||
13367ECF2DF70819009CB33F /* Localizable.xcstrings */,
|
||||
);
|
||||
path = Sora;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -669,6 +672,7 @@
|
|||
files = (
|
||||
133D7C752D2BE2520075467E /* Preview Assets.xcassets in Resources */,
|
||||
133D7C722D2BE2520075467E /* Assets.xcassets in Resources */,
|
||||
13367ED02DF70819009CB33F /* Localizable.xcstrings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue