From 35e58b88ebbca3b9230f422027e8935f84cddd93 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sun, 8 Jun 2025 14:32:58 -0400 Subject: [PATCH 01/35] create singleton for PBManager --- .../Controllers/DownloadManager.swift | 4 +-- .../Controllers/PosterBoardManager.swift | 24 ++++++++++------- Pocket Poster/Pocket_PosterApp.swift | 12 ++++----- Pocket Poster/Views/ContentView.swift | 26 +++++++++---------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Pocket Poster/Controllers/DownloadManager.swift b/Pocket Poster/Controllers/DownloadManager.swift index dae2ac4..a560d5f 100644 --- a/Pocket Poster/Controllers/DownloadManager.swift +++ b/Pocket Poster/Controllers/DownloadManager.swift @@ -19,7 +19,7 @@ class DownloadManager { let (data, response) = try await URLSession.shared.data(for: request) as! (Data, HTTPURLResponse) guard response.statusCode == 200 else { throw URLError(.cannotConnectToHost) } - let newURL = PosterBoardManager.getTendiesStoreURL().appendingPathComponent(getWallpaperNameFromURL(string: url.absoluteString)) + let newURL = PosterBoardManager.shared.getTendiesStoreURL().appendingPathComponent(getWallpaperNameFromURL(string: url.absoluteString)) try data.write(to: newURL) return newURL } @@ -37,7 +37,7 @@ class DownloadManager { url.stopAccessingSecurityScopedResource() } } - let newURL = PosterBoardManager.getTendiesStoreURL().appendingPathComponent(url.lastPathComponent) + let newURL = PosterBoardManager.shared.getTendiesStoreURL().appendingPathComponent(url.lastPathComponent) try FileManager.default.copyItem(at: url, to: newURL) return newURL } diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index 27acf1e..704980a 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -9,13 +9,17 @@ import Foundation import ZIPFoundation import UIKit -class PosterBoardManager { +class PosterBoardManager: ObservableObject { static let ShortcutURL = "https://www.icloud.com/shortcuts/a28d2c02ca11453cb5b8f91c12cfa692" static let WallpapersURL = "https://cowabun.ga/wallpapers" static let MaxTendies = 10 - static func getTendiesStoreURL() -> URL { + static let shared = PosterBoardManager() + + @Published var selectedTendies: [URL] = [] + + func getTendiesStoreURL() -> URL { let tendiesStoreURL = SymHandler.getDocumentsDirectory().appendingPathComponent("KFC Bucket", conformingTo: .directory) // create it if it doesn't exist if !FileManager.default.fileExists(atPath: tendiesStoreURL.path()) { @@ -24,7 +28,7 @@ class PosterBoardManager { return tendiesStoreURL } - static func openPosterBoard() -> Bool { + func openPosterBoard() -> Bool { guard let obj = objc_getClass("LSApplicationWorkspace") as? NSObject else { return false } let workspace = obj.perform(Selector(("defaultWorkspace")))?.takeUnretainedValue() as? NSObject @@ -35,7 +39,7 @@ class PosterBoardManager { return false } - private static func unzipFile(at url: URL) throws -> URL { + private func unzipFile(at url: URL) throws -> URL { let fileName = url.deletingPathExtension().lastPathComponent let fileData = try Data(contentsOf: url) let fileManager = FileManager() @@ -68,13 +72,13 @@ class PosterBoardManager { return destinationURL } - static func runShortcut(named name: String) { + func runShortcut(named name: String) { guard let urlEncodedName = name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: "shortcuts://run-shortcut?name=\(name)") else { return } UIApplication.shared.open(url, options: [:], completionHandler: nil) } - static func getDescriptorsFromTendie(_ url: URL) throws -> [String: [URL]]? { + func getDescriptorsFromTendie(_ url: URL) throws -> [String: [URL]]? { for dir in try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: .skipsHiddenFiles) { let fileName = dir.lastPathComponent if fileName.lowercased() == "container" { @@ -99,7 +103,7 @@ class PosterBoardManager { return nil } - static func randomizeWallpaperId(url: URL) throws { + func randomizeWallpaperId(url: URL) throws { let randomizedID = Int.random(in: 9999...99999) var files = [URL]() if let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) { @@ -157,10 +161,10 @@ class PosterBoardManager { } } - static func applyTendies(_ urls: [URL], appHash: String) throws { + func applyTendies(appHash: String) throws { // organize the descriptors into their respective extensions var extList: [String: [URL]] = [:] - for url in urls { + for url in selectedTendies { let unzippedDir = try unzipFile(at: url) guard let descriptors = try getDescriptorsFromTendie(unzippedDir) else { continue } // TODO: Add error handling extList.merge(descriptors) { (first, second) in first + second } @@ -188,7 +192,7 @@ class PosterBoardManager { } // clean up all possible files - for url in urls { + for url in selectedTendies { try? FileManager.default.removeItem(at: SymHandler.getDocumentsDirectory().appendingPathComponent("UnzipItems", conformingTo: .directory)) try? FileManager.default.removeItem(at: SymHandler.getDocumentsDirectory().appendingPathComponent(url.lastPathComponent)) try? FileManager.default.removeItem(at: SymHandler.getDocumentsDirectory().appendingPathComponent(url.deletingPathExtension().lastPathComponent)) diff --git a/Pocket Poster/Pocket_PosterApp.swift b/Pocket Poster/Pocket_PosterApp.swift index 1e2c098..6a17223 100644 --- a/Pocket Poster/Pocket_PosterApp.swift +++ b/Pocket Poster/Pocket_PosterApp.swift @@ -13,8 +13,6 @@ struct Pocket_PosterApp: App { @AppStorage("finishedTutorial") var finishedTutorial: Bool = false @AppStorage("pbHash") var pbHash: String = "" - @State var selectedTendies: [URL] = [] - @State var downloadURL: String? = nil @State var showDownloadAlert = false @@ -22,7 +20,7 @@ struct Pocket_PosterApp: App { WindowGroup { Group { if finishedTutorial { - ContentView(selectedTendies: $selectedTendies) + ContentView() } else { OnBoardingView(cards: onBoardingCards, isFinished: $finishedTutorial) } @@ -43,7 +41,7 @@ struct Pocket_PosterApp: App { // prohibit to only tendies files if !url.absoluteString.hasSuffix(".tendies") { UIApplication.shared.alert(body: "Only .tendies files can be downloaded!") - } else if selectedTendies.count >= PosterBoardManager.MaxTendies { + } else if PosterBoardManager.shared.selectedTendies.count >= PosterBoardManager.MaxTendies { UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") } else { downloadURL = url.absoluteString.replacingOccurrences(of: "pocketposter://download?url=", with: "") @@ -55,13 +53,13 @@ struct Pocket_PosterApp: App { pbHash = url.absoluteString.replacingOccurrences(of: "pocketposter://app-hash?uuid=", with: "") } else if url.pathExtension == "tendies" { - if selectedTendies.count >= PosterBoardManager.MaxTendies { + if PosterBoardManager.shared.selectedTendies.count >= PosterBoardManager.MaxTendies { UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") } else { // copy it over to the KFC bucket do { let newURL = try DownloadManager.copyTendies(from: url) - selectedTendies.append(newURL) + PosterBoardManager.shared.selectedTendies.append(newURL) Haptic.shared.notify(.success) UIApplication.shared.alert(title: "Successfully imported \(url.lastPathComponent)", body: "") } catch { @@ -81,7 +79,7 @@ struct Pocket_PosterApp: App { Task { do { let newURL = try await DownloadManager.downloadFromURL(string: downloadURL!) - selectedTendies.append(newURL) + PosterBoardManager.shared.selectedTendies.append(newURL) Haptic.shared.notify(.success) UIApplication.shared.dismissAlert(animated: true) } catch { diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 7827070..b89fd09 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -21,7 +21,6 @@ struct ContentView: View { private let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" @State var showTendiesImporter: Bool = false - var selectedTendies: Binding<[URL]> @State var showErrorAlert = false @State var lastError: String? @@ -47,9 +46,9 @@ struct ContentView: View { .listRowInsets(EdgeInsets()) .padding(7) - if !selectedTendies.wrappedValue.isEmpty { + if !PosterBoardManager.shared.selectedTendies.isEmpty { Section { - ForEach(selectedTendies.wrappedValue, id: \.self) { tendie in + ForEach(PosterBoardManager.shared.selectedTendies, id: \.self) { tendie in Text(tendie.deletingPathExtension().lastPathComponent) } .onDelete(perform: delete) @@ -63,23 +62,23 @@ struct ContentView: View { Text("Enter your PosterBoard app hash in Settings.") } else { VStack { - if !selectedTendies.wrappedValue.isEmpty { + if !PosterBoardManager.shared.selectedTendies.isEmpty { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() UIApplication.shared.alert(title: NSLocalizedString("Applying Tendies...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { do { - try PosterBoardManager.applyTendies(selectedTendies.wrappedValue, appHash: pbHash) - selectedTendies.wrappedValue.removeAll() + try PosterBoardManager.shared.applyTendies(appHash: pbHash) + PosterBoardManager.shared.selectedTendies.removeAll() SymHandler.cleanup() // just to be extra sure - try? FileManager.default.removeItem(at: PosterBoardManager.getTendiesStoreURL()) + try? FileManager.default.removeItem(at: PosterBoardManager.shared.getTendiesStoreURL()) Haptic.shared.notify(.success) UIApplication.shared.dismissAlert(animated: false) UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { - if !PosterBoardManager.openPosterBoard() { + if !PosterBoardManager.shared.openPosterBoard() { UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { - PosterBoardManager.runShortcut(named: "PosterBoard") + PosterBoardManager.shared.runShortcut(named: "PosterBoard") }, noCancel: true) } }, noCancel: true) @@ -130,10 +129,10 @@ struct ContentView: View { .fileImporter(isPresented: $showTendiesImporter, allowedContentTypes: [UTType(filenameExtension: "tendies", conformingTo: .data)!], allowsMultipleSelection: true, onCompletion: { result in switch result { case .success(let url): - if selectedTendies.wrappedValue.count + url.count > PosterBoardManager.MaxTendies { + if PosterBoardManager.shared.selectedTendies.count + url.count > PosterBoardManager.MaxTendies { UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") } else { - selectedTendies.wrappedValue.append(contentsOf: url) + PosterBoardManager.shared.selectedTendies.append(contentsOf: url) } case .failure(let error): lastError = error.localizedDescription @@ -154,11 +153,10 @@ struct ContentView: View { } func delete(at offsets: IndexSet) { - selectedTendies.wrappedValue.remove(atOffsets: offsets) + PosterBoardManager.shared.selectedTendies.remove(atOffsets: offsets) } - init(selectedTendies: Binding<[URL]>) { - self.selectedTendies = selectedTendies + init() { // Fix file picker let fixMethod = class_getInstanceMethod(UIDocumentPickerViewController.self, #selector(UIDocumentPickerViewController.fix_init(forOpeningContentTypes:asCopy:)))! let origMethod = class_getInstanceMethod(UIDocumentPickerViewController.self, #selector(UIDocumentPickerViewController.init(forOpeningContentTypes:asCopy:)))! From aaf5051eeb6a54403fa93c043306bb960ef0dc7a Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sun, 8 Jun 2025 18:58:46 -0400 Subject: [PATCH 02/35] video wallpapers --- Pocket Poster.xcodeproj/project.pbxproj | 11 +- .../Controllers/PosterBoardManager.swift | 11 +- Pocket Poster/Controllers/VideoHandler.swift | 224 ++++++++++++++++++ ...e.posterkit.provider.descriptor.identifier | 1 + .../com.apple.posterkit.role.identifier | 1 + .../Resources/VideoCAML/providerInfo.plist | Bin 0 -> 410 bytes .../index.xml | 58 +++++ .../main.caml | 40 ++++ .../Wallpaper.plist | 46 ++++ ...apple.posterkit.provider.contents.userInfo | 14 ++ Pocket Poster/Views/ContentView.swift | 80 ++++++- 11 files changed, 479 insertions(+), 7 deletions(-) create mode 100644 Pocket Poster/Controllers/VideoHandler.swift create mode 100644 Pocket Poster/Resources/VideoCAML/com.apple.posterkit.provider.descriptor.identifier create mode 100644 Pocket Poster/Resources/VideoCAML/com.apple.posterkit.role.identifier create mode 100644 Pocket Poster/Resources/VideoCAML/providerInfo.plist create mode 100644 Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/index.xml create mode 100644 Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/main.caml create mode 100644 Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/Wallpaper.plist create mode 100644 Pocket Poster/Resources/VideoCAML/versions/1/contents/com.apple.posterkit.provider.contents.userInfo diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 5c9db5d..7413994 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -17,6 +17,9 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ 6F09B79F2DEB694B00CDE89C /* Pocket Poster */ = { isa = PBXFileSystemSynchronizedRootGroup; + explicitFolders = ( + Resources/VideoCAML, + ); path = "Pocket Poster"; sourceTree = ""; }; @@ -261,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -278,7 +281,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = "com.lemin.Pocket-Poster"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -293,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -310,7 +313,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = "com.lemin.Pocket-Poster"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index 704980a..87b283d 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -161,9 +161,18 @@ class PosterBoardManager: ObservableObject { } } - func applyTendies(appHash: String) throws { + func applyTendies(appHash: String, videoURL: URL?) throws { // organize the descriptors into their respective extensions var extList: [String: [URL]] = [:] + // create the video first + if let videoURL = videoURL { + do { + let newVideo = try VideoHandler.createCaml(from: videoURL, autoReverses: false) + extList["com.apple.WallpaperKit.CollectionsPoster"] = [newVideo] + } catch { + print(error.localizedDescription) + } + } for url in selectedTendies { let unzippedDir = try unzipFile(at: url) guard let descriptors = try getDescriptorsFromTendie(unzippedDir) else { continue } // TODO: Add error handling diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift new file mode 100644 index 0000000..26b03b0 --- /dev/null +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -0,0 +1,224 @@ +// +// VideoHandler.swift +// Pocket Poster +// +// Created by lemin on 6/8/25. +// + +import Foundation +import AVFoundation +import UIKit + +extension CGImage { + var png: Data? { + guard let mutableData = CFDataCreateMutable(nil, 0), + let destination = CGImageDestinationCreateWithData(mutableData, "public.png" as CFString, 1, nil) else { return nil } + CGImageDestinationAddImage(destination, self, nil) + guard CGImageDestinationFinalize(destination) else { return nil } + return mutableData as Data + } + var jpg: Data? { + let uiimg = UIImage(cgImage: self) + return uiimg.jpegData(compressionQuality: 0.7) + } +} + +class VideoHandler { + static func createCaml(from url: URL, autoReverses: Bool) throws -> URL { + // copy the resources + let descrURL = SymHandler.getDocumentsDirectory().appendingPathComponent(UUID().uuidString, conformingTo: .directory) + try FileManager.default.createDirectory(at: descrURL, withIntermediateDirectories: false) + + print("pre resource") + guard let rc = Bundle.main.url(forResource: "VideoCAML", withExtension: nil) else { throw URLError(.fileDoesNotExist) } + print("post resource") + try FileManager.default.copyItem(at: rc, to: descrURL.appendingPathComponent("videoCAML")) + print("post copy") + + let coreAnimDir = descrURL.appending(path: "videoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Background-810w-1080h@2x~ipad.ca") + let assetsFolder = coreAnimDir.appendingPathComponent("assets", conformingTo: .directory) + if !FileManager.default.fileExists(atPath: assetsFolder.path()) { + try FileManager.default.createDirectory(at: assetsFolder, withIntermediateDirectories: true) + } + + // load the video + let asset = AVURLAsset(url: url) + + let assetImageGenerator = AVAssetImageGenerator(asset: asset) + assetImageGenerator.appliesPreferredTrackTransform = true + assetImageGenerator.apertureMode = AVAssetImageGenerator.ApertureMode.encodedPixels + + // create the caml + guard let track = asset.tracks(withMediaType: .video).first else { + print("Failed to get video track") + throw AVError(.decodeFailed) + } + let size = track.naturalSize.applying(track.preferredTransform) + let width = Int(size.width) + let height = Int(size.height) + let fps = track.nominalFrameRate + let duration = CMTimeGetSeconds(asset.duration) + let totalFrames = Int(fps * Float(duration)) + let animDur = Double(totalFrames) / Double(fps) + var camlData = """ + + + + + +""" + // write the caml + guard let caData = camlData.data(using: .utf8) else { throw URLError(.unknown) } + try caData.write(to: coreAnimDir.appendingPathComponent("main.caml")) + + // write the other info xml + camlData = """ + + + + + assetManifest + assetManifest.caml + documentHeight + \(height) + documentResizesToView + + documentWidth + \(width) + dynamicGuidesEnabled + + geometryFlipped + + guidesEnabled + + interactiveMouseEventsEnabled + + interactiveShowsCursor + + interactiveTouchEventsEnabled + + loopEnd + 0.0 + loopStart + 0.0 + loopingEnabled + + multitouchDisablesMouse + + multitouchEnabled + + presentationMouseEventsEnabled + + presentationShowsCursor + + presentationTouchEventsEnabled + + rootDocument + main.caml + savesWindowFrame + + scalesToFitInPlayer + + showsTouches + + snappingEnabled + + timelineMarkers + [(null)] + touchesColor + 1 1 0 0.8 + unitsInPixelsInPlayer + + + + """ + + guard let xmlData = camlData.data(using: .utf8) else { throw URLError(.unknown) } + try xmlData.write(to: coreAnimDir.appendingPathComponent("index.xml", conformingTo: .xml)) + + return descrURL + } +} diff --git a/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.provider.descriptor.identifier b/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.provider.descriptor.identifier new file mode 100644 index 0000000..5018e06 --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.provider.descriptor.identifier @@ -0,0 +1 @@ +9183 \ No newline at end of file diff --git a/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.role.identifier b/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.role.identifier new file mode 100644 index 0000000..b92284b --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/com.apple.posterkit.role.identifier @@ -0,0 +1 @@ +PRPosterRoleLockScreen \ No newline at end of file diff --git a/Pocket Poster/Resources/VideoCAML/providerInfo.plist b/Pocket Poster/Resources/VideoCAML/providerInfo.plist new file mode 100644 index 0000000000000000000000000000000000000000..81447ade9ddc75457c21e8d348003b973b2fd6d5 GIT binary patch literal 410 zcmYc)$jK}&F)+Bo$i&RT%ErzWp;DGwRGgWg7pan1l$?ed zc4}pD6p)6R6Q+`!lUQ85P_Th%p>P9p18cm1Oty1=URq{)X;ESc&;>q;#U-J|sV<2n zsX(hPiStWHg3Kw&%uQ8xJa&M^<4UPW1Is088Ckg~h+%n&xv3ElW@>SmUoc4PB3bze zzhHl`=~ literal 0 HcmV?d00001 diff --git a/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/index.xml b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/index.xml new file mode 100644 index 0000000..5fa23a9 --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/index.xml @@ -0,0 +1,58 @@ + + + + + assetManifest + assetManifest.caml + documentHeight + 3176 + documentResizesToView + + documentWidth + 3176 + dynamicGuidesEnabled + + geometryFlipped + + guidesEnabled + + interactiveMouseEventsEnabled + + interactiveShowsCursor + + interactiveTouchEventsEnabled + + loopEnd + 0.0 + loopStart + 0.0 + loopingEnabled + + multitouchDisablesMouse + + multitouchEnabled + + presentationMouseEventsEnabled + + presentationShowsCursor + + presentationTouchEventsEnabled + + rootDocument + main.caml + savesWindowFrame + + scalesToFitInPlayer + + showsTouches + + snappingEnabled + + timelineMarkers + [(null)] + touchesColor + 1 1 0 0.8 + unitsInPixelsInPlayer + + + diff --git a/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/main.caml b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/main.caml new file mode 100644 index 0000000..bb97379 --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/9183.Custom_Floating-810w-1080h@2x~ipad.ca/main.caml @@ -0,0 +1,40 @@ + + + + + diff --git a/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/Wallpaper.plist b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/Wallpaper.plist new file mode 100644 index 0000000..54f1f1b --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/versions/1/contents/9183.Custom-810w-1080h@2x~ipad.wallpaper/Wallpaper.plist @@ -0,0 +1,46 @@ + + + + + appearanceAware + + assets + + lockAndHome + + default + + backgroundAnimationFileName + 9183.Custom_Background-810w-1080h@2x~ipad.ca + floatingAnimationFileNameKey + 9183.Custom_Floating-810w-1080h@2x~ipad.ca + identifier + 9183 + name + Chip + type + LayeredAnimation + + + + contentVersion + 2.01 + family + Chip + identifier + 9183 + logicalScreenClass + 810w-1080h@2x~ipad + name + Chip + preferredProminentColor + + dark + #00000 + default + #FFFFFF + + version + 1 + + diff --git a/Pocket Poster/Resources/VideoCAML/versions/1/contents/com.apple.posterkit.provider.contents.userInfo b/Pocket Poster/Resources/VideoCAML/versions/1/contents/com.apple.posterkit.provider.contents.userInfo new file mode 100644 index 0000000..f94f23a --- /dev/null +++ b/Pocket Poster/Resources/VideoCAML/versions/1/contents/com.apple.posterkit.provider.contents.userInfo @@ -0,0 +1,14 @@ + + + + + posterEnvironmentOverrides + + e30= + + wallpaperRepresentingFileName + 9183.Custom-810w-1080h@2x~ipad.wallpaper + wallpaperRepresentingIdentifier + 9999 + + diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index b89fd09..737536d 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -7,6 +7,7 @@ import SwiftUI import UniformTypeIdentifiers +import PhotosUI extension UIDocumentPickerViewController { @objc func fix_init(forOpeningContentTypes contentTypes: [UTType], asCopy: Bool) -> UIDocumentPickerViewController { @@ -14,6 +15,25 @@ extension UIDocumentPickerViewController { } } +struct Movie: Transferable { + let url: URL + + static var transferRepresentation: some TransferRepresentation { + FileRepresentation(contentType: .movie) { movie in + SentTransferredFile(movie.url) + } importing: { received in + let copy = URL.documentsDirectory.appending(path: "movie.mp4") + + if FileManager.default.fileExists(atPath: copy.path()) { + try FileManager.default.removeItem(at: copy) + } + + try FileManager.default.copyItem(at: received.file, to: copy) + return Self.init(url: copy) + } + } +} + struct ContentView: View { // Prefs @AppStorage("pbHash") var pbHash: String = "" @@ -22,6 +42,12 @@ struct ContentView: View { @State var showTendiesImporter: Bool = false + enum LoadState { + case unknown, loading, loaded(Movie), failed + } + @State var selectedVideo: PhotosPickerItem? + @State private var loadState = LoadState.unknown + @State var showErrorAlert = false @State var lastError: String? @State var hideResetHelp: Bool = true @@ -35,6 +61,49 @@ struct ContentView: View { } Section { + VStack { + switch loadState { + case .unknown: + EmptyView() + case .loading: + ProgressView() + case .loaded(let movie): + Text("Video imported") + case .failed: + Text("Import failed") + } + + switch loadState { + case .loaded(let movie): + Button(action: { + selectedVideo = nil + try? FileManager.default.removeItem(at: movie.url) + loadState = .unknown + }) { + Text("Remove Selected Video") + } + .buttonStyle(TintedButton(color: .red, fullwidth: true)) + default: + PhotosPicker("Select Video", selection: $selectedVideo, matching: .videos) + .buttonStyle(TintedButton(color: .yellow, fullwidth: true)) + .onChange(of: selectedVideo) { _ in + Task { + do { + loadState = .loading + + if let movie = try await selectedVideo?.loadTransferable(type: Movie.self) { + loadState = .loaded(movie) + } else { + loadState = .failed + } + } catch { + loadState = .failed + } + } + } + } + } + Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() showTendiesImporter.toggle() @@ -62,14 +131,21 @@ struct ContentView: View { Text("Enter your PosterBoard app hash in Settings.") } else { VStack { - if !PosterBoardManager.shared.selectedTendies.isEmpty { + if !PosterBoardManager.shared.selectedTendies.isEmpty || selectedVideo != nil { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() UIApplication.shared.alert(title: NSLocalizedString("Applying Tendies...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { do { - try PosterBoardManager.shared.applyTendies(appHash: pbHash) + var videoURL: URL? = nil + switch loadState { + case .loaded(let movie): + videoURL = movie.url + default: + videoURL = nil + } + try PosterBoardManager.shared.applyTendies(appHash: pbHash, videoURL: videoURL) PosterBoardManager.shared.selectedTendies.removeAll() SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: PosterBoardManager.shared.getTendiesStoreURL()) From 913110be919f1901e441480c4f9d63ec0ef95d86 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sun, 8 Jun 2025 19:01:09 -0400 Subject: [PATCH 03/35] clean up video --- Pocket Poster/Views/ContentView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 737536d..ef3f0b1 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -149,6 +149,9 @@ struct ContentView: View { PosterBoardManager.shared.selectedTendies.removeAll() SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: PosterBoardManager.shared.getTendiesStoreURL()) + if let videoURL = videoURL { + try? FileManager.default.removeItem(at: videoURL) + } Haptic.shared.notify(.success) UIApplication.shared.dismissAlert(animated: false) UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { From 60aa215d6b0efcc6a61760b38fd583b1cb6570fa Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:13:18 -0400 Subject: [PATCH 04/35] automatic resetting of collections --- Pocket Poster.xcodeproj/project.pbxproj | 4 ++-- .../Controllers/PosterBoardManager.swift | 17 +++++++++++++++++ Pocket Poster/Views/ContentView.swift | 12 +++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 7413994..3412f62 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index 87b283d..a7d8911 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -28,6 +28,23 @@ class PosterBoardManager: ObservableObject { return tendiesStoreURL } + func setSystemLanguage(to new_lang: String) -> Bool { + var langManager: NSObject = NSObject() + if #available(iOS 18.0, *) { + guard let obj = objc_getClass("IPSettingsUtilities") as? NSObject else { return false } + langManager = obj + } else { + guard let obj = objc_getClass("PSLanguageSelector") as? NSObject else { return false } + langManager = obj + } + + if let success = langManager.perform(Selector(("setLanguage:")), with: new_lang) { + return success != nil + } + + return false + } + func openPosterBoard() -> Bool { guard let obj = objc_getClass("LSApplicationWorkspace") as? NSObject else { return false } let workspace = obj.perform(Selector(("defaultWorkspace")))?.takeUnretainedValue() as? NSObject diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index ef3f0b1..f2f41b1 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -174,7 +174,17 @@ struct ContentView: View { .buttonStyle(TintedButton(color: .blue, fullwidth: true)) } Button(action: { - hideResetHelp = false + guard let lang = UserDefaults.standard.stringArray(forKey: "AppleLanguages")?.first else { + hideResetHelp = false // fallback to tutorial + return + } + UIApplication.shared.confirmAlert(title: "Reset Collections", body: "Do you want to reset collections?", onOK: { + if PosterBoardManager.shared.setSystemLanguage(to: lang) { + UIApplication.shared.alert(title: "Collections Successfully Reset!", body: "Your PosterBoard will refresh automatically.") + } else { + UIApplication.shared.alert(body: "The API failed to call correctly.\nSystem Locale Code: \(lang)") + } + }, noCancel: false) }) { Text("Reset Collections") } From c1549ea32661503701717cdfb35dbd8d251e8f7b Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:57:24 -0400 Subject: [PATCH 05/35] fix observing changes --- Pocket Poster/Views/ContentView.swift | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index f2f41b1..815b253 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -38,6 +38,8 @@ struct ContentView: View { // Prefs @AppStorage("pbHash") var pbHash: String = "" + @ObservedObject var pbManager = PosterBoardManager.shared + private let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" @State var showTendiesImporter: Bool = false @@ -115,9 +117,9 @@ struct ContentView: View { .listRowInsets(EdgeInsets()) .padding(7) - if !PosterBoardManager.shared.selectedTendies.isEmpty { + if !pbManager.selectedTendies.isEmpty { Section { - ForEach(PosterBoardManager.shared.selectedTendies, id: \.self) { tendie in + ForEach(pbManager.selectedTendies, id: \.self) { tendie in Text(tendie.deletingPathExtension().lastPathComponent) } .onDelete(perform: delete) @@ -131,7 +133,7 @@ struct ContentView: View { Text("Enter your PosterBoard app hash in Settings.") } else { VStack { - if !PosterBoardManager.shared.selectedTendies.isEmpty || selectedVideo != nil { + if !pbManager.selectedTendies.isEmpty || selectedVideo != nil { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() UIApplication.shared.alert(title: NSLocalizedString("Applying Tendies...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) @@ -145,26 +147,24 @@ struct ContentView: View { default: videoURL = nil } - try PosterBoardManager.shared.applyTendies(appHash: pbHash, videoURL: videoURL) - PosterBoardManager.shared.selectedTendies.removeAll() + try pbManager.applyTendies(appHash: pbHash, videoURL: videoURL) + pbManager.selectedTendies.removeAll() SymHandler.cleanup() // just to be extra sure - try? FileManager.default.removeItem(at: PosterBoardManager.shared.getTendiesStoreURL()) + try? FileManager.default.removeItem(at: pbManager.getTendiesStoreURL()) if let videoURL = videoURL { try? FileManager.default.removeItem(at: videoURL) } Haptic.shared.notify(.success) - UIApplication.shared.dismissAlert(animated: false) UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { - if !PosterBoardManager.shared.openPosterBoard() { + if !pbManager.openPosterBoard() { UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { - PosterBoardManager.shared.runShortcut(named: "PosterBoard") + pbManager.runShortcut(named: "PosterBoard") }, noCancel: true) } }, noCancel: true) } catch { Haptic.shared.notify(.error) SymHandler.cleanup() - UIApplication.shared.dismissAlert(animated: false) UIApplication.shared.alert(body: error.localizedDescription) } } @@ -179,7 +179,7 @@ struct ContentView: View { return } UIApplication.shared.confirmAlert(title: "Reset Collections", body: "Do you want to reset collections?", onOK: { - if PosterBoardManager.shared.setSystemLanguage(to: lang) { + if pbManager.setSystemLanguage(to: lang) { UIApplication.shared.alert(title: "Collections Successfully Reset!", body: "Your PosterBoard will refresh automatically.") } else { UIApplication.shared.alert(body: "The API failed to call correctly.\nSystem Locale Code: \(lang)") @@ -218,10 +218,10 @@ struct ContentView: View { .fileImporter(isPresented: $showTendiesImporter, allowedContentTypes: [UTType(filenameExtension: "tendies", conformingTo: .data)!], allowsMultipleSelection: true, onCompletion: { result in switch result { case .success(let url): - if PosterBoardManager.shared.selectedTendies.count + url.count > PosterBoardManager.MaxTendies { + if pbManager.selectedTendies.count + url.count > PosterBoardManager.MaxTendies { UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") } else { - PosterBoardManager.shared.selectedTendies.append(contentsOf: url) + pbManager.selectedTendies.append(contentsOf: url) } case .failure(let error): lastError = error.localizedDescription @@ -242,7 +242,7 @@ struct ContentView: View { } func delete(at offsets: IndexSet) { - PosterBoardManager.shared.selectedTendies.remove(atOffsets: offsets) + pbManager.selectedTendies.remove(atOffsets: offsets) } init() { From 9ccc8e43179dce5099e8b1a93c8e75305e699427 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:59:28 -0400 Subject: [PATCH 06/35] fix alert dismissing --- Pocket Poster/Views/ContentView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 815b253..7fc0297 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -155,6 +155,7 @@ struct ContentView: View { try? FileManager.default.removeItem(at: videoURL) } Haptic.shared.notify(.success) + UIApplication.shared.dismissAlert(animated: true) UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { if !pbManager.openPosterBoard() { UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { @@ -165,6 +166,7 @@ struct ContentView: View { } catch { Haptic.shared.notify(.error) SymHandler.cleanup() + UIApplication.shared.dismissAlert(animated: true) UIApplication.shared.alert(body: error.localizedDescription) } } From 047c9e9504de5926ab317a7f6b68bf1dc543a66a Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 19:50:42 -0400 Subject: [PATCH 07/35] show the frames being generated in alert --- Pocket Poster.xcodeproj/project.pbxproj | 4 +-- .../Controllers/PosterBoardManager.swift | 1 + Pocket Poster/Controllers/VideoHandler.swift | 4 ++- Pocket Poster/Views/ContentView.swift | 30 +++++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 3412f62..78f3251 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index a7d8911..a052ee7 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -190,6 +190,7 @@ class PosterBoardManager: ObservableObject { print(error.localizedDescription) } } + UIApplication.shared.change(title: "Applying Wallpapers...", body: "Extracting tendies...") for url in selectedTendies { let unzippedDir = try unzipFile(at: url) guard let descriptors = try getDescriptorsFromTendie(unzippedDir) else { continue } // TODO: Add error handling diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift index 26b03b0..2be5816 100644 --- a/Pocket Poster/Controllers/VideoHandler.swift +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -91,11 +91,12 @@ class VideoHandler { while let sampleBuffer = readerOutput.copyNextSampleBuffer(), let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) { + let name = "\(frameCount).jpg" + UIApplication.shared.change(title: "Generating Video...", body: "Creating assets/\(name)...") let ciImage = CIImage(cvPixelBuffer: imageBuffer) let context = CIContext() if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) { - let name = "\(frameCount).jpg" if let img = cgImage.jpg { try img.write(to: assetsFolder.appendingPathComponent(name)) camlData += "\t\t\t\n" @@ -107,6 +108,7 @@ class VideoHandler { } catch { print("Error reading asset: \(error)") } + UIApplication.shared.change(title: "Generating Video...", body: "Creating CAML data...") camlData += """ diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 7fc0297..73c8853 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -136,9 +136,9 @@ struct ContentView: View { if !pbManager.selectedTendies.isEmpty || selectedVideo != nil { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() - UIApplication.shared.alert(title: NSLocalizedString("Applying Tendies...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) + UIApplication.shared.alert(title: NSLocalizedString("Applying Wallpapers...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + DispatchQueue.global(qos: .userInitiated).async { do { var videoURL: URL? = nil switch loadState { @@ -148,26 +148,30 @@ struct ContentView: View { videoURL = nil } try pbManager.applyTendies(appHash: pbHash, videoURL: videoURL) - pbManager.selectedTendies.removeAll() SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: pbManager.getTendiesStoreURL()) if let videoURL = videoURL { try? FileManager.default.removeItem(at: videoURL) } Haptic.shared.notify(.success) - UIApplication.shared.dismissAlert(animated: true) - UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { - if !pbManager.openPosterBoard() { - UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { - pbManager.runShortcut(named: "PosterBoard") - }, noCancel: true) - } - }, noCancel: true) + UIApplication.shared.dismissAlert(animated: false) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { + pbManager.selectedTendies.removeAll() + UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { + if !pbManager.openPosterBoard() { + UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { + pbManager.runShortcut(named: "PosterBoard") + }, noCancel: true) + } + }, noCancel: true) + }) } catch { Haptic.shared.notify(.error) SymHandler.cleanup() - UIApplication.shared.dismissAlert(animated: true) - UIApplication.shared.alert(body: error.localizedDescription) + UIApplication.shared.dismissAlert(animated: false) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { + UIApplication.shared.alert(body: error.localizedDescription) + }) } } }) { From ef444f7c5c0388c6ac93a8032cbe9b73fec6bea5 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 20:58:28 -0400 Subject: [PATCH 08/35] new video adding ui + selecting multiple videos --- .../Controllers/PosterBoardManager.swift | 56 ++++++++-- .../Extensions/LoopingPlayerUIView.swift | 41 +++++++ Pocket Poster/Extensions/PlayerView.swift | 23 ++++ Pocket Poster/Pocket_PosterApp.swift | 2 +- Pocket Poster/Views/ContentView.swift | 82 +------------- .../Views/NavigatorViews/VideoView.swift | 102 ++++++++++++++++++ Pocket Poster/Views/RootView.swift | 23 ++++ 7 files changed, 241 insertions(+), 88 deletions(-) create mode 100644 Pocket Poster/Extensions/LoopingPlayerUIView.swift create mode 100644 Pocket Poster/Extensions/PlayerView.swift create mode 100644 Pocket Poster/Views/NavigatorViews/VideoView.swift create mode 100644 Pocket Poster/Views/RootView.swift diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index a052ee7..b95fbf9 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -8,6 +8,39 @@ import Foundation import ZIPFoundation import UIKit +import CoreTransferable + +struct Movie: Transferable { + let url: URL + + static var transferRepresentation: some TransferRepresentation { + FileRepresentation(contentType: .movie) { movie in + SentTransferredFile(movie.url) + } importing: { received in + let videoFolder = SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory) + if !FileManager.default.fileExists(atPath: videoFolder.path()) { + try? FileManager.default.createDirectory(at: videoFolder, withIntermediateDirectories: true) + } + let copy = videoFolder.appending(path: "\(UUID()).mp4") + + if FileManager.default.fileExists(atPath: copy.path()) { + try FileManager.default.removeItem(at: copy) + } + + try FileManager.default.copyItem(at: received.file, to: copy) + return Self.init(url: copy) + } + } +} + +enum LoadState { + case unknown, loading, loaded(Movie), failed +} + +struct LoadInfo: Identifiable { + var id = UUID() + var loadState: LoadState +} class PosterBoardManager: ObservableObject { static let ShortcutURL = "https://www.icloud.com/shortcuts/a28d2c02ca11453cb5b8f91c12cfa692" @@ -18,6 +51,7 @@ class PosterBoardManager: ObservableObject { static let shared = PosterBoardManager() @Published var selectedTendies: [URL] = [] + @Published var videos: [LoadInfo] = [] func getTendiesStoreURL() -> URL { let tendiesStoreURL = SymHandler.getDocumentsDirectory().appendingPathComponent("KFC Bucket", conformingTo: .directory) @@ -178,16 +212,24 @@ class PosterBoardManager: ObservableObject { } } - func applyTendies(appHash: String, videoURL: URL?) throws { + func applyTendies(appHash: String) throws { // organize the descriptors into their respective extensions var extList: [String: [URL]] = [:] // create the video first - if let videoURL = videoURL { - do { - let newVideo = try VideoHandler.createCaml(from: videoURL, autoReverses: false) - extList["com.apple.WallpaperKit.CollectionsPoster"] = [newVideo] - } catch { - print(error.localizedDescription) + if videos.count > 0 { + extList["com.apple.WallpaperKit.CollectionsPoster"] = [] + for video in videos { + switch video.loadState { + case .loaded(let movie): + do { + let newVideo = try VideoHandler.createCaml(from: movie.url, autoReverses: false) + extList["com.apple.WallpaperKit.CollectionsPoster"]?.append(newVideo) + } catch { + print(error.localizedDescription) + } + default: + print("Video not loaded!") + } } } UIApplication.shared.change(title: "Applying Wallpapers...", body: "Extracting tendies...") diff --git a/Pocket Poster/Extensions/LoopingPlayerUIView.swift b/Pocket Poster/Extensions/LoopingPlayerUIView.swift new file mode 100644 index 0000000..b169828 --- /dev/null +++ b/Pocket Poster/Extensions/LoopingPlayerUIView.swift @@ -0,0 +1,41 @@ +// +// LoopingPlayerUIView.swift +// Pocket Poster +// +// Created by lemin on 6/11/25. +// + +import UIKit +import AVFoundation + +class LoopingPlayerUIView: UIView { + + private var playerLayer = AVPlayerLayer() + private var playerLooper: AVPlayerLooper? + private var player = AVQueuePlayer() + + init(videoURL: URL){ + let asset = AVAsset(url: videoURL) + let item = AVPlayerItem(asset: asset) + + super.init(frame: .zero) + + // Setup the player + playerLayer.player = player + playerLayer.videoGravity = .resizeAspectFill + layer.addSublayer(playerLayer) + + // Create a new player looper with the queue player and template item + playerLooper = AVPlayerLooper(player: player, templateItem: item) + player.play() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + playerLayer.frame = bounds + } +} diff --git a/Pocket Poster/Extensions/PlayerView.swift b/Pocket Poster/Extensions/PlayerView.swift new file mode 100644 index 0000000..1f9d0c1 --- /dev/null +++ b/Pocket Poster/Extensions/PlayerView.swift @@ -0,0 +1,23 @@ +// +// PlayerView.swift +// Pocket Poster +// +// Created by lemin on 6/11/25. +// + +import SwiftUI + +struct PlayerView: UIViewRepresentable { + var videoURL: URL + + init(videoURL: URL) { + self.videoURL = videoURL + } + + func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) { + } + + func makeUIView(context: Context) -> UIView { + return LoopingPlayerUIView(videoURL: videoURL) + } +} diff --git a/Pocket Poster/Pocket_PosterApp.swift b/Pocket Poster/Pocket_PosterApp.swift index 6a17223..22437f0 100644 --- a/Pocket Poster/Pocket_PosterApp.swift +++ b/Pocket Poster/Pocket_PosterApp.swift @@ -20,7 +20,7 @@ struct Pocket_PosterApp: App { WindowGroup { Group { if finishedTutorial { - ContentView() + RootView() } else { OnBoardingView(cards: onBoardingCards, isFinished: $finishedTutorial) } diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 73c8853..adc9e83 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -15,25 +15,6 @@ extension UIDocumentPickerViewController { } } -struct Movie: Transferable { - let url: URL - - static var transferRepresentation: some TransferRepresentation { - FileRepresentation(contentType: .movie) { movie in - SentTransferredFile(movie.url) - } importing: { received in - let copy = URL.documentsDirectory.appending(path: "movie.mp4") - - if FileManager.default.fileExists(atPath: copy.path()) { - try FileManager.default.removeItem(at: copy) - } - - try FileManager.default.copyItem(at: received.file, to: copy) - return Self.init(url: copy) - } - } -} - struct ContentView: View { // Prefs @AppStorage("pbHash") var pbHash: String = "" @@ -44,12 +25,6 @@ struct ContentView: View { @State var showTendiesImporter: Bool = false - enum LoadState { - case unknown, loading, loaded(Movie), failed - } - @State var selectedVideo: PhotosPickerItem? - @State private var loadState = LoadState.unknown - @State var showErrorAlert = false @State var lastError: String? @State var hideResetHelp: Bool = true @@ -63,49 +38,6 @@ struct ContentView: View { } Section { - VStack { - switch loadState { - case .unknown: - EmptyView() - case .loading: - ProgressView() - case .loaded(let movie): - Text("Video imported") - case .failed: - Text("Import failed") - } - - switch loadState { - case .loaded(let movie): - Button(action: { - selectedVideo = nil - try? FileManager.default.removeItem(at: movie.url) - loadState = .unknown - }) { - Text("Remove Selected Video") - } - .buttonStyle(TintedButton(color: .red, fullwidth: true)) - default: - PhotosPicker("Select Video", selection: $selectedVideo, matching: .videos) - .buttonStyle(TintedButton(color: .yellow, fullwidth: true)) - .onChange(of: selectedVideo) { _ in - Task { - do { - loadState = .loading - - if let movie = try await selectedVideo?.loadTransferable(type: Movie.self) { - loadState = .loaded(movie) - } else { - loadState = .failed - } - } catch { - loadState = .failed - } - } - } - } - } - Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() showTendiesImporter.toggle() @@ -133,26 +65,16 @@ struct ContentView: View { Text("Enter your PosterBoard app hash in Settings.") } else { VStack { - if !pbManager.selectedTendies.isEmpty || selectedVideo != nil { + if !pbManager.selectedTendies.isEmpty || !pbManager.videos.isEmpty { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() UIApplication.shared.alert(title: NSLocalizedString("Applying Wallpapers...", comment: ""), body: NSLocalizedString("Please wait", comment: ""), animated: false, withButton: false) DispatchQueue.global(qos: .userInitiated).async { do { - var videoURL: URL? = nil - switch loadState { - case .loaded(let movie): - videoURL = movie.url - default: - videoURL = nil - } - try pbManager.applyTendies(appHash: pbHash, videoURL: videoURL) + try pbManager.applyTendies(appHash: pbHash) SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: pbManager.getTendiesStoreURL()) - if let videoURL = videoURL { - try? FileManager.default.removeItem(at: videoURL) - } Haptic.shared.notify(.success) UIApplication.shared.dismissAlert(animated: false) DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift new file mode 100644 index 0000000..a5000d2 --- /dev/null +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -0,0 +1,102 @@ +// +// VideoView.swift +// Pocket Poster +// +// Created by lemin on 6/11/25. +// + +import SwiftUI +import PhotosUI +import AVKit + +struct VideoView: View { + @ObservedObject var pbManager = PosterBoardManager.shared + + @State var selectedVideo: PhotosPickerItem? + + var body: some View { + VStack { + GeometryReader { geom in + TabView { + ForEach(pbManager.videos) { vid in + ZStack { + switch vid.loadState { + case .unknown: + EmptyView() + case .loading: + ProgressView() + case .loaded(let movie): + PlayerView(videoURL: movie.url) + .scaledToFill() + .frame(width: geom.size.width * 0.7, height: geom.size.height * 0.8) + .clipped() + case .failed: + Text("Failed") + } + } + .frame(width: geom.size.width * 0.7, height: geom.size.height * 0.8) + .shadow(radius: 5) + .background(Color.black.opacity(0.6)) + .cornerRadius(24) + .overlay { + RoundedRectangle(cornerRadius: 24) + .stroke(.gray, lineWidth: 4) + } + } + + // MARK: Select Photo Option + if selectedVideo == nil { + ZStack { + PhotosPicker(selection: $selectedVideo, matching: .videos, label: { + ZStack { + RoundedRectangle(cornerRadius: 24) + .fill(.gray.opacity(0.4)) + + Circle() + .frame(width: 40, height: 40) + .foregroundStyle(.blue) + + Image(systemName: "plus") + .font(.title) + .foregroundStyle(.white) + } + }) + } + .frame(width: geom.size.width * 0.7, height: geom.size.height * 0.8) + .shadow(radius: 5) + .background(Color.black.opacity(0.6)) + .cornerRadius(24) + .overlay { + RoundedRectangle(cornerRadius: 24) + .stroke(.gray, lineWidth: 4) + } + } + } + .onChange(of: selectedVideo) { _ in + if selectedVideo == nil { return } + let id = pbManager.videos.count + pbManager.videos.append(.init(loadState: .loading)) + Task { + do { + if let movie = try await selectedVideo?.loadTransferable(type: Movie.self) { + await MainActor.run { + pbManager.videos[id].loadState = .loaded(movie) + } + } else { + await MainActor.run { + pbManager.videos[id].loadState = .failed + } + } + } catch { + await MainActor.run { + pbManager.videos[id].loadState = .failed + } + } + selectedVideo = nil + } + } + .tabViewStyle(.page) + } + } + } +} diff --git a/Pocket Poster/Views/RootView.swift b/Pocket Poster/Views/RootView.swift new file mode 100644 index 0000000..19bf41d --- /dev/null +++ b/Pocket Poster/Views/RootView.swift @@ -0,0 +1,23 @@ +// +// RootView.swift +// Pocket Poster +// +// Created by lemin on 6/11/25. +// + +import SwiftUI + +struct RootView: View { + var body: some View { + TabView { + ContentView() + .tabItem { + Label("Home", systemImage: "house") + } + VideoView() + .tabItem { + Label("Videos", systemImage: "camera") + } + } + } +} From 5268d31581a14f4a5a6d109cbfb3e5ea34464716 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:43:30 -0400 Subject: [PATCH 09/35] removing videos from selector --- .../Controllers/PosterBoardManager.swift | 6 ++- .../Views/NavigatorViews/VideoView.swift | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index b95fbf9..6170998 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -37,7 +37,11 @@ enum LoadState { case unknown, loading, loaded(Movie), failed } -struct LoadInfo: Identifiable { +struct LoadInfo: Identifiable, Equatable { + static func == (lhs: LoadInfo, rhs: LoadInfo) -> Bool { + lhs.id == rhs.id + } + var id = UUID() var loadState: LoadState } diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index a5000d2..de8ebf8 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -42,7 +42,13 @@ struct VideoView: View { RoundedRectangle(cornerRadius: 24) .stroke(.gray, lineWidth: 4) } + .overlay( + // Delete Button + DeleteButton(video: vid, onDelete: removeVideo), + alignment: .topLeading + ) } + .onDelete(perform: removeVideo) // MARK: Select Photo Option if selectedVideo == nil { @@ -99,4 +105,37 @@ struct VideoView: View { } } } + + func removeVideo(at offsets: IndexSet) { + withAnimation { + pbManager.videos.remove(atOffsets: offsets) + } + } +} + +struct DeleteButton: View { + @Environment(\.editMode) var editMode + + let video: LoadInfo + @ObservedObject var pbManager = PosterBoardManager.shared + let onDelete: (IndexSet) -> () + + var body: some View { + VStack { + Button(action: { + if let index = pbManager.videos.firstIndex(of: video) { + self.onDelete(IndexSet(integer: index)) + } + }) { + Image(systemName: "minus.circle") + .foregroundStyle(.black) + .font(.title2) + .background { + Circle() + .foregroundStyle(.white) + } + } + .offset(x: -8, y: -8) + } + } } From b782d6c7a2c3e9e59e1214078451397478003b14 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:46:04 -0400 Subject: [PATCH 10/35] add a limit of 5 videos --- Pocket Poster/Views/NavigatorViews/VideoView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index de8ebf8..a0775fe 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -51,7 +51,7 @@ struct VideoView: View { .onDelete(perform: removeVideo) // MARK: Select Photo Option - if selectedVideo == nil { + if selectedVideo == nil && pbManager.videos.count < 5 { ZStack { PhotosPicker(selection: $selectedVideo, matching: .videos, label: { ZStack { From 1eab5e5476400fe8b640f6ed7cfe79d4cc54933d Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 11 Jun 2025 22:00:46 -0400 Subject: [PATCH 11/35] add an auto reverses button --- .../Controllers/PosterBoardManager.swift | 3 ++- .../Views/NavigatorViews/VideoView.swift | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index 6170998..d4f3a63 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -43,6 +43,7 @@ struct LoadInfo: Identifiable, Equatable { } var id = UUID() + var autoReverses: Bool = false var loadState: LoadState } @@ -226,7 +227,7 @@ class PosterBoardManager: ObservableObject { switch video.loadState { case .loaded(let movie): do { - let newVideo = try VideoHandler.createCaml(from: movie.url, autoReverses: false) + let newVideo = try VideoHandler.createCaml(from: movie.url, autoReverses: video.autoReverses) extList["com.apple.WallpaperKit.CollectionsPoster"]?.append(newVideo) } catch { print(error.localizedDescription) diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index a0775fe..3a08c31 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -47,6 +47,23 @@ struct VideoView: View { DeleteButton(video: vid, onDelete: removeVideo), alignment: .topLeading ) + .overlay( + // Loops Button + Button(action: { + if let index = pbManager.videos.firstIndex(of: vid) { + pbManager.videos[index].autoReverses = !vid.autoReverses + } + }) { + Image(systemName: "arrow.left.arrow.right.circle") + .font(.title) + .foregroundStyle(.black) + .background { + Circle() + .foregroundStyle(vid.autoReverses ? .blue : .white) + } + }.offset(x: 8, y: -8), + alignment: .topTrailing + ) } .onDelete(perform: removeVideo) From d45a64bb1915583bc8ddea1662c1d03ed649d9d0 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:10:30 -0400 Subject: [PATCH 12/35] absolute value the video resolution --- Pocket Poster.xcodeproj/project.pbxproj | 4 ++-- .../lemin.xcuserdatad/xcschemes/xcschememanagement.plist | 2 +- Pocket Poster/Controllers/VideoHandler.swift | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 78f3251..a2e0def 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist index f3372ed..d7a896f 100644 --- a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Pocket Poster.xcscheme_^#shared#^_ orderHint - 0 + 1 diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift index 2be5816..af9d95a 100644 --- a/Pocket Poster/Controllers/VideoHandler.swift +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -54,8 +54,8 @@ class VideoHandler { throw AVError(.decodeFailed) } let size = track.naturalSize.applying(track.preferredTransform) - let width = Int(size.width) - let height = Int(size.height) + let width = Int(abs(size.width)) + let height = Int(abs(size.height)) let fps = track.nominalFrameRate let duration = CMTimeGetSeconds(asset.duration) let totalFrames = Int(fps * Float(duration)) From 54aa8e20a3a65bef579ee0339f92eb97e923c05d Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:47:27 -0400 Subject: [PATCH 13/35] improve error codes --- Pocket Poster/Error Codes/ApplyError.swift | 30 ++++++++++++++++++++++ Pocket Poster/Views/ContentView.swift | 23 ++++++++++++----- 2 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 Pocket Poster/Error Codes/ApplyError.swift diff --git a/Pocket Poster/Error Codes/ApplyError.swift b/Pocket Poster/Error Codes/ApplyError.swift new file mode 100644 index 0000000..a42ef51 --- /dev/null +++ b/Pocket Poster/Error Codes/ApplyError.swift @@ -0,0 +1,30 @@ +// +// ApplyError.swift +// Pocket Poster +// +// Created by lemin on 6/18/25. +// + +import Foundation + +enum ApplyError: LocalizedError { + // Throw when the app hash is incorrect + case wrongAppHash + + // Throw when the collections need to be reset + case collectionsNeedsReset + + // Throw in all other cases + case unexpected(info: String) + + public var errorDescription: String? { + switch self { + case .wrongAppHash: + return "Your app hash is incorrect. Please set it again." + case .collectionsNeedsReset: + return "The folder is improperly set up. Please tap \"Reset Collections\" and try again." + case .unexpected(let info): + return info + } + } +} diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index adc9e83..11035aa 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -75,8 +75,8 @@ struct ContentView: View { try pbManager.applyTendies(appHash: pbHash) SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: pbManager.getTendiesStoreURL()) - Haptic.shared.notify(.success) UIApplication.shared.dismissAlert(animated: false) + Haptic.shared.notify(.success) DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { pbManager.selectedTendies.removeAll() UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { @@ -87,13 +87,12 @@ struct ContentView: View { } }, noCancel: true) }) + } catch CocoaError.fileWriteUnknown { + presentError(ApplyError.wrongAppHash) + } catch CocoaError.fileWriteFileExists { + presentError(ApplyError.collectionsNeedsReset) } catch { - Haptic.shared.notify(.error) - SymHandler.cleanup() - UIApplication.shared.dismissAlert(animated: false) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { - UIApplication.shared.alert(body: error.localizedDescription) - }) + presentError(ApplyError.unexpected(info: error.localizedDescription)) } } }) { @@ -173,6 +172,16 @@ struct ContentView: View { pbManager.selectedTendies.remove(atOffsets: offsets) } + func presentError(_ error: ApplyError) { + SymHandler.cleanup() + UIApplication.shared.dismissAlert(animated: false) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { + lastError = error.localizedDescription + Haptic.shared.notify(.error) + showErrorAlert = true + }) + } + init() { // Fix file picker let fixMethod = class_getInstanceMethod(UIDocumentPickerViewController.self, #selector(UIDocumentPickerViewController.fix_init(forOpeningContentTypes:asCopy:)))! From d835a401994fc21a655a1bed97f33301d408be12 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 19:09:10 -0400 Subject: [PATCH 14/35] ui improvements + fix error popups not showing --- Pocket Poster/Pocket_PosterApp.swift | 13 +++-------- Pocket Poster/Views/ContentView.swift | 22 ++++++------------- .../Views/NavigatorViews/VideoView.swift | 4 ++-- Pocket Poster/Views/SettingsView.swift | 21 ++++-------------- 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/Pocket Poster/Pocket_PosterApp.swift b/Pocket Poster/Pocket_PosterApp.swift index 22437f0..d2f68aa 100644 --- a/Pocket Poster/Pocket_PosterApp.swift +++ b/Pocket Poster/Pocket_PosterApp.swift @@ -14,7 +14,6 @@ struct Pocket_PosterApp: App { @AppStorage("pbHash") var pbHash: String = "" @State var downloadURL: String? = nil - @State var showDownloadAlert = false var body: some Scene { WindowGroup { @@ -27,14 +26,6 @@ struct Pocket_PosterApp: App { } .transition(.opacity) .animation(.easeOut(duration: 0.5), value: finishedTutorial) - .alert("Download Tendies File", isPresented: $showDownloadAlert) { - Button("OK") { - downloadWallpaper() - } - Button("Cancel", role: .cancel) {} - } message: { - Text("Would you like to download the file \(DownloadManager.getWallpaperNameFromURL(string: downloadURL ?? "/Unknown"))?") - } .onOpenURL(perform: { url in // Download URL if url.absoluteString.starts(with: "pocketposter://download") { @@ -45,7 +36,9 @@ struct Pocket_PosterApp: App { UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") } else { downloadURL = url.absoluteString.replacingOccurrences(of: "pocketposter://download?url=", with: "") - showDownloadAlert = true + UIApplication.shared.confirmAlert(title: "Download Tendies File", body: "Would you like to download the file \(DownloadManager.getWallpaperNameFromURL(string: downloadURL ?? "/Unknown"))?", onOK: { + downloadWallpaper() + }, noCancel: false) } } // App Hash URL diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 11035aa..8936961 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -24,9 +24,6 @@ struct ContentView: View { private let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" @State var showTendiesImporter: Bool = false - - @State var showErrorAlert = false - @State var lastError: String? @State var hideResetHelp: Bool = true var body: some View { @@ -42,7 +39,7 @@ struct ContentView: View { UIImpactFeedbackGenerator(style: .soft).impactOccurred() showTendiesImporter.toggle() }) { - Text("Select Tendies") + Label("Select Tendies", systemImage: "document.circle") } .buttonStyle(TintedButton(color: .green, fullwidth: true)) } @@ -92,11 +89,12 @@ struct ContentView: View { } catch CocoaError.fileWriteFileExists { presentError(ApplyError.collectionsNeedsReset) } catch { + print(error.localizedDescription) presentError(ApplyError.unexpected(info: error.localizedDescription)) } } }) { - Text("Apply") + Label("Apply", systemImage: "checkmark.circle") } .buttonStyle(TintedButton(color: .blue, fullwidth: true)) } @@ -113,7 +111,7 @@ struct ContentView: View { } }, noCancel: false) }) { - Text("Reset Collections") + Label("Reset Collections", systemImage: "arrow.clockwise.circle") } .buttonStyle(TintedButton(color: .red, fullwidth: true)) } @@ -151,15 +149,10 @@ struct ContentView: View { pbManager.selectedTendies.append(contentsOf: url) } case .failure(let error): - lastError = error.localizedDescription - showErrorAlert.toggle() + Haptic.shared.notify(.error) + UIApplication.shared.alert(body: error.localizedDescription) } }) - .alert("Error", isPresented: $showErrorAlert) { - Button("OK") {} - } message: { - Text(lastError ?? "???") - } .overlay { OnBoardingView(cards: resetCollectionsInfo, isFinished: $hideResetHelp) .opacity(hideResetHelp ? 0.0 : 1.0) @@ -176,9 +169,8 @@ struct ContentView: View { SymHandler.cleanup() UIApplication.shared.dismissAlert(animated: false) DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { - lastError = error.localizedDescription Haptic.shared.notify(.error) - showErrorAlert = true + UIApplication.shared.alert(body: error.localizedDescription) }) } diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index 3a08c31..9841c61 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -145,8 +145,8 @@ struct DeleteButton: View { } }) { Image(systemName: "minus.circle") - .foregroundStyle(.black) - .font(.title2) + .foregroundStyle(.red) + .font(.title) .background { Circle() .foregroundStyle(.white) diff --git a/Pocket Poster/Views/SettingsView.swift b/Pocket Poster/Views/SettingsView.swift index 80d07c1..1bfd041 100644 --- a/Pocket Poster/Views/SettingsView.swift +++ b/Pocket Poster/Views/SettingsView.swift @@ -14,10 +14,6 @@ struct SettingsView: View { @State var checkingForHash: Bool = false @State var hashCheckTask: Task? = nil - @State var showErrorAlert = false - @State var errorAlertTitle: String? - @State var errorAlertDescr: String? - var body: some View { List { Section { @@ -54,7 +50,7 @@ struct SettingsView: View { UIImpactFeedbackGenerator(style: .soft).impactOccurred() UserDefaults.standard.set(false, forKey: "finishedTutorial") }) { - Text("Replay Tutorial") + Label("Replay Tutorial", systemImage: "questionmark.circle") } Button(action: { @@ -62,17 +58,13 @@ struct SettingsView: View { do { try PosterBoardManager.clearCache() Haptic.shared.notify(.success) - errorAlertTitle = "App Cache Successfully Cleared!" - errorAlertDescr = "" - showErrorAlert = true + UIApplication.shared.alert(title: "App Cache Successfully Cleared!", body: "") } catch { Haptic.shared.notify(.error) - errorAlertTitle = "Error" - errorAlertDescr = error.localizedDescription - showErrorAlert = true + UIApplication.shared.alert(body: error.localizedDescription) } }) { - Text("Clear App Cache") + Label("Clear App Cache", systemImage: "trash.circle") } .foregroundStyle(.red) } header: { @@ -126,11 +118,6 @@ struct SettingsView: View { Label("Credits", systemImage: "wrench.and.screwdriver") } } - .alert(errorAlertTitle ?? "Error", isPresented: $showErrorAlert) { - Button("OK") {} - } message: { - Text(errorAlertDescr ?? "???") - } } func startWaitForHash() { From bf0d7989bd765e37c06579db3aade58ed16dc681 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 19:32:36 -0400 Subject: [PATCH 15/35] prepare for localizations --- Pocket Poster/Controllers/PosterBoardManager.swift | 2 +- Pocket Poster/Controllers/VideoHandler.swift | 5 +++-- Pocket Poster/Error Codes/ApplyError.swift | 4 ++-- Pocket Poster/Extensions/Alert++.swift | 2 +- Pocket Poster/Pocket_PosterApp.swift | 12 ++++++------ Pocket Poster/Views/ContentView.swift | 12 ++++++------ Pocket Poster/Views/SettingsView.swift | 10 +++++----- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index d4f3a63..4260e12 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -237,7 +237,7 @@ class PosterBoardManager: ObservableObject { } } } - UIApplication.shared.change(title: "Applying Wallpapers...", body: "Extracting tendies...") + UIApplication.shared.change(title: NSLocalizedString("Applying Wallpapers...", comment: ""), body: NSLocalizedString("Extracting tendies...", comment: "happens when unzipping the files")) for url in selectedTendies { let unzippedDir = try unzipFile(at: url) guard let descriptors = try getDescriptorsFromTendie(unzippedDir) else { continue } // TODO: Add error handling diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift index af9d95a..709f09c 100644 --- a/Pocket Poster/Controllers/VideoHandler.swift +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -92,7 +92,8 @@ class VideoHandler { while let sampleBuffer = readerOutput.copyNextSampleBuffer(), let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) { let name = "\(frameCount).jpg" - UIApplication.shared.change(title: "Generating Video...", body: "Creating assets/\(name)...") + let filePathName = "assets/\(name)" + UIApplication.shared.change(title: NSLocalizedString("Generating Video...", comment: ""), body: String(format: NSLocalizedString("Creating %@...", comment: "the message for the current image that is being generated"), filePathName)) let ciImage = CIImage(cvPixelBuffer: imageBuffer) let context = CIContext() @@ -108,7 +109,7 @@ class VideoHandler { } catch { print("Error reading asset: \(error)") } - UIApplication.shared.change(title: "Generating Video...", body: "Creating CAML data...") + UIApplication.shared.change(title: NSLocalizedString("Generating Video...", comment: ""), body: NSLocalizedString("Creating CAML data...", comment: "translate this however you see fits")) camlData += """ diff --git a/Pocket Poster/Error Codes/ApplyError.swift b/Pocket Poster/Error Codes/ApplyError.swift index a42ef51..15c660e 100644 --- a/Pocket Poster/Error Codes/ApplyError.swift +++ b/Pocket Poster/Error Codes/ApplyError.swift @@ -20,9 +20,9 @@ enum ApplyError: LocalizedError { public var errorDescription: String? { switch self { case .wrongAppHash: - return "Your app hash is incorrect. Please set it again." + return NSLocalizedString("Your app hash is incorrect. Please set it again.", comment: "") case .collectionsNeedsReset: - return "The folder is improperly set up. Please tap \"Reset Collections\" and try again." + return NSLocalizedString("The folder is improperly set up. Please tap \"Reset Collections\" and try again.", comment: "") case .unexpected(let info): return info } diff --git a/Pocket Poster/Extensions/Alert++.swift b/Pocket Poster/Extensions/Alert++.swift index e8756a4..f6bd495 100644 --- a/Pocket Poster/Extensions/Alert++.swift +++ b/Pocket Poster/Extensions/Alert++.swift @@ -32,7 +32,7 @@ extension UIApplication { let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" let systemVersion = device.systemVersion - body += "\n\(device.systemName) \(systemVersion), version \(appVersion) build \(appBuild)" + body += "\n\(device.systemName) \(systemVersion), v\(appVersion) build \(appBuild)" } currentUIAlertController = UIAlertController(title: title, message: body, preferredStyle: .alert) diff --git a/Pocket Poster/Pocket_PosterApp.swift b/Pocket Poster/Pocket_PosterApp.swift index d2f68aa..4f27740 100644 --- a/Pocket Poster/Pocket_PosterApp.swift +++ b/Pocket Poster/Pocket_PosterApp.swift @@ -31,12 +31,12 @@ struct Pocket_PosterApp: App { if url.absoluteString.starts(with: "pocketposter://download") { // prohibit to only tendies files if !url.absoluteString.hasSuffix(".tendies") { - UIApplication.shared.alert(body: "Only .tendies files can be downloaded!") + UIApplication.shared.alert(body: NSLocalizedString("Only .tendies files can be downloaded!", comment: "")) } else if PosterBoardManager.shared.selectedTendies.count >= PosterBoardManager.MaxTendies { - UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") + UIApplication.shared.alert(title: NSLocalizedString("Max Tendies Reached", comment: ""), body: String(format: NSLocalizedString("You can only apply %@ descriptors.", comment: ""), "\(PosterBoardManager.MaxTendies)")) } else { downloadURL = url.absoluteString.replacingOccurrences(of: "pocketposter://download?url=", with: "") - UIApplication.shared.confirmAlert(title: "Download Tendies File", body: "Would you like to download the file \(DownloadManager.getWallpaperNameFromURL(string: downloadURL ?? "/Unknown"))?", onOK: { + UIApplication.shared.confirmAlert(title: NSLocalizedString("Download Tendies File", comment: ""), body: String(format: NSLocalizedString("Would you like to download the file %@?", comment: ""), "\(DownloadManager.getWallpaperNameFromURL(string: downloadURL ?? "/Unknown"))"), onOK: { downloadWallpaper() }, noCancel: false) } @@ -47,17 +47,17 @@ struct Pocket_PosterApp: App { } else if url.pathExtension == "tendies" { if PosterBoardManager.shared.selectedTendies.count >= PosterBoardManager.MaxTendies { - UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") + UIApplication.shared.alert(title: NSLocalizedString("Max Tendies Reached", comment: ""), body: String(format: NSLocalizedString("You can only apply %@ descriptors.", comment: ""), "\(PosterBoardManager.MaxTendies)")) } else { // copy it over to the KFC bucket do { let newURL = try DownloadManager.copyTendies(from: url) PosterBoardManager.shared.selectedTendies.append(newURL) Haptic.shared.notify(.success) - UIApplication.shared.alert(title: "Successfully imported \(url.lastPathComponent)", body: "") + UIApplication.shared.alert(title: String(format: NSLocalizedString("Successfully imported %@", comment: ""), "\(url.lastPathComponent)"), body: "") } catch { Haptic.shared.notify(.error) - UIApplication.shared.alert(title: "Failed to import tendies", body: error.localizedDescription) + UIApplication.shared.alert(title: NSLocalizedString("Failed to import tendies", comment: ""), body: error.localizedDescription) } } } diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 8936961..227cbf3 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -76,9 +76,9 @@ struct ContentView: View { Haptic.shared.notify(.success) DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { pbManager.selectedTendies.removeAll() - UIApplication.shared.confirmAlert(title: "Success!", body: "The PosterBoard app will now open. Please close it from the app switcher.", onOK: { + UIApplication.shared.confirmAlert(title: NSLocalizedString("Success!", comment: ""), body: NSLocalizedString("The PosterBoard app will now open. Please close it from the app switcher.", comment: ""), onOK: { if !pbManager.openPosterBoard() { - UIApplication.shared.confirmAlert(title: "Falling Back to Shortcut", body: "PosterBoard failed to open directly. The fallback shortcut will now be opened.", onOK: { + UIApplication.shared.confirmAlert(title: NSLocalizedString("Falling Back to Shortcut", comment: ""), body: NSLocalizedString("PosterBoard failed to open directly. The fallback shortcut will now be opened.", comment: ""), onOK: { pbManager.runShortcut(named: "PosterBoard") }, noCancel: true) } @@ -103,11 +103,11 @@ struct ContentView: View { hideResetHelp = false // fallback to tutorial return } - UIApplication.shared.confirmAlert(title: "Reset Collections", body: "Do you want to reset collections?", onOK: { + UIApplication.shared.confirmAlert(title: NSLocalizedString("Reset Collections", comment: ""), body: NSLocalizedString("Do you want to reset collections?", comment: ""), onOK: { if pbManager.setSystemLanguage(to: lang) { - UIApplication.shared.alert(title: "Collections Successfully Reset!", body: "Your PosterBoard will refresh automatically.") + UIApplication.shared.alert(title: NSLocalizedString("Collections Successfully Reset!", comment: ""), body: NSLocalizedString("Your PosterBoard will refresh automatically.", comment: "")) } else { - UIApplication.shared.alert(body: "The API failed to call correctly.\nSystem Locale Code: \(lang)") + UIApplication.shared.alert(body: NSLocalizedString("The API failed to call correctly.\nSystem Locale Code: ", comment: "") + lang) } }, noCancel: false) }) { @@ -144,7 +144,7 @@ struct ContentView: View { switch result { case .success(let url): if pbManager.selectedTendies.count + url.count > PosterBoardManager.MaxTendies { - UIApplication.shared.alert(title: "Max Tendies Reached", body: "You can only apply \(PosterBoardManager.MaxTendies) descriptors.") + UIApplication.shared.alert(title: NSLocalizedString("Max Tendies Reached", comment: ""), body: String(format: NSLocalizedString("You can only apply %@ descriptors.", comment: ""), "\(PosterBoardManager.MaxTendies)")) } else { pbManager.selectedTendies.append(contentsOf: url) } diff --git a/Pocket Poster/Views/SettingsView.swift b/Pocket Poster/Views/SettingsView.swift index 1bfd041..b70bfc7 100644 --- a/Pocket Poster/Views/SettingsView.swift +++ b/Pocket Poster/Views/SettingsView.swift @@ -58,7 +58,7 @@ struct SettingsView: View { do { try PosterBoardManager.clearCache() Haptic.shared.notify(.success) - UIApplication.shared.alert(title: "App Cache Successfully Cleared!", body: "") + UIApplication.shared.alert(title: NSLocalizedString("App Cache Successfully Cleared!", comment: ""), body: "") } catch { Haptic.shared.notify(.error) UIApplication.shared.alert(body: error.localizedDescription) @@ -110,10 +110,10 @@ struct SettingsView: View { // MARK: Credits Section { LinkCell(imageName: "leminlimez", url: "https://github.com/leminlimez", title: "LeminLimez", contribution: NSLocalizedString("Main Developer", comment: "leminlimez's contribution"), circle: true) - LinkCell(imageName: "serstars", url: "https://github.com/SerStars", title: "SerStars", contribution: "Website Designer", circle: true) - LinkCell(imageName: "Nathan", url: "https://github.com/verygenericname", title: "Nathan", contribution: "Exploit", circle: true) - LinkCell(imageName: "duy", url: "https://github.com/khanhduytran0", title: "DuyKhanhTran", contribution: "Exploit", circle: true) - LinkCell(imageName: "sky", url: "https://bsky.app/profile/did:plc:xykfeb7ieeo335g3aly6vev4", title: "dootskyre", contribution: "Fallback Shortcut Creator", circle: true) + LinkCell(imageName: "serstars", url: "https://github.com/SerStars", title: "SerStars", contribution: NSLocalizedString("Website Designer", comment: ""), circle: true) + LinkCell(imageName: "Nathan", url: "https://github.com/verygenericname", title: "Nathan", contribution: NSLocalizedString("Exploit", comment: ""), circle: true) + LinkCell(imageName: "duy", url: "https://github.com/khanhduytran0", title: "DuyKhanhTran", contribution: NSLocalizedString("Exploit", comment: ""), circle: true) + LinkCell(imageName: "sky", url: "https://bsky.app/profile/did:plc:xykfeb7ieeo335g3aly6vev4", title: "dootskyre", contribution: NSLocalizedString("Fallback Shortcut Creator", comment: ""), circle: true) } header: { Label("Credits", systemImage: "wrench.and.screwdriver") } From a1ce92f3eb44514369a52efc0bf4baae7aa4e32f Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 20:52:17 -0400 Subject: [PATCH 16/35] add spanish and french translations --- .../xcschemes/xcschememanagement.plist | 2 +- Pocket Poster/Localizable.xcstrings | 992 ++++++++++++++++++ .../Pocket-Poster-InfoPlist.xcstrings | 46 + Pocket Poster/Views/ContentView.swift | 2 +- 4 files changed, 1040 insertions(+), 2 deletions(-) create mode 100644 Pocket Poster/Localizable.xcstrings create mode 100644 Pocket Poster/Pocket-Poster-InfoPlist.xcstrings diff --git a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist index d7a896f..f3372ed 100644 --- a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Pocket Poster.xcscheme_^#shared#^_ orderHint - 1 + 0 diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings new file mode 100644 index 0000000..176af5c --- /dev/null +++ b/Pocket Poster/Localizable.xcstrings @@ -0,0 +1,992 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "Actions" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acciones" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actions" + } + } + } + }, + "App Cache Successfully Cleared!" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "El cache de la aplicación fue limpiado con exito!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache de l'application vidé avec succès!" + } + } + } + }, + "App Hash" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hash de l'application" + } + } + } + }, + "Apply" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplicar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appliquer" + } + } + } + }, + "Applying Wallpapers..." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplicando Fondos de Pantalla" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Application de fonds d'écran..." + } + } + } + }, + "Cancel" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancelar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + } + } + }, + "Clear App Cache" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Limpiar cache de aplicación" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache de l'application" + } + } + } + }, + "Collections Successfully Reset!" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Colecciones reiniciadas exitosamente!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialisation des collections réussie!" + } + } + } + }, + "Could not download wallpaper!" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡No se pudo descargar el fondo de pantalla!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erro télécharge le fond d'écran!" + } + } + } + }, + "Create Additional Fallback Method" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crear un método de respaldo adicional" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créer une méthode de secours supplémentaire" + } + } + } + }, + "Creating %@..." : { + "comment" : "the message for the current image that is being generated", + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creando %@..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création %@..." + } + } + } + }, + "Creating CAML data..." : { + "comment" : "translate this however you see fits", + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creando datos CAML..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création de données CAML..." + } + } + } + }, + "Credits" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creditos" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crédits" + } + } + } + }, + "Detect" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detectar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Détecter" + } + } + } + }, + "Do you want to reset collections?" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Quieres reiniciar las colecciones?" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez-vous réinitialiser les collections?" + } + } + } + }, + "Download Fallback Shortcut" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargar acceso directo de respaldo" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger le raccourci de secours" + } + } + } + }, + "Download Tendies File" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargar archivo Tendies" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger un fichier de Tendies" + } + } + } + }, + "Downloading" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargando" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Téléchargement" + } + } + } + }, + "Enter App Hash" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresar el hash de la aplicación" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saisir le App Hash" + } + } + } + }, + "Enter your PosterBoard app hash in Settings." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingrese el hash de su aplicación PosterBoard en Configuración." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entrez votre app hash de PosterBoard dans les Paramètres." + } + } + } + }, + "Error" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur" + } + } + } + }, + "Exploit" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploitation" + } + } + } + }, + "Extracting tendies..." : { + "comment" : "happens when unzipping the files", + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extrayendo tendies..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'extraction des tendies..." + } + } + } + }, + "Failed" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallido" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec" + } + } + } + }, + "Failed to import tendies" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se pudieron importar tendies" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "N'a pas réussi à importer les tendies" + } + } + } + }, + "Fallback Shortcut Creator" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creador de atajos de respaldo" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créateur de raccourcis de secours" + } + } + } + }, + "Falling Back to Shortcut" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Regresar al atajo" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Retomber dans le raccourci" + } + } + } + }, + "Finish" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finalizar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finir" + } + } + } + }, + "Generating Video..." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generando vídeo..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Générer des vidéos..." + } + } + } + }, + "Home" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inicio" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Accueil" + } + } + } + }, + "Join the Discord" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unete a nuestro Discord" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rejoindre le Discord" + } + } + } + }, + "Links" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enlaces" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Liens" + } + } + } + }, + "Main Developer" : { + "comment" : "leminlimez's contribution", + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desarrollador Principal" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Développeur principal" + } + } + } + }, + "Max Tendies Reached" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cantidad Maxima de Tendies alcanzada" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies maximales atteintes" + } + } + } + }, + "Next" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siguiente" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suivant" + } + } + } + }, + "Nugget GitHub" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Github" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + } + } + }, + "OK" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + } + } + }, + "Only .tendies files can be downloaded!" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Solo archivos .tendies pueden ser descargados" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seuls les fichiers .tendies peuvent être téléchargés!" + } + } + } + }, + "Please wait" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Por favor espere" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Veuillez patienter" + } + } + } + }, + "Pocket Poster" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + } + } + }, + "PosterBoard failed to open directly. The fallback shortcut will now be opened." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard no se pudo abrir directamente. Ahora se abrirá el acceso directo alternativo." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard n'a pas pu s'ouvrir directement. Le raccourci de secours sera maintenant ouvert." + } + } + } + }, + "Release" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lanzar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Libération" + } + } + } + }, + "Replay Tutorial" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reproducir de nuevo Tutorial" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Répéter le tutoriel" + } + } + } + }, + "Reset Collections" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reiniciar colecciones" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialiser les Collections" + } + } + } + }, + "Select Tendies" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seleccionar Tendies" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sélectionner Tendies" + } + } + } + }, + "Selected Tendies" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies seleccionado" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies sélectionnées" + } + } + } + }, + "Skip" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saltar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sauter" + } + } + } + }, + "Socials" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociales" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociales" + } + } + } + }, + "Success!" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Logrado!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succès!" + } + } + } + }, + "Successfully imported %@" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Importado correctamente!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Importation réussie %@" + } + } + } + }, + "Support on Ko-Fi" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apoyanos en Ko-Fi" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Support sur Ko-Fi" + } + } + } + }, + "The folder is improperly set up. Please tap \"Reset Collections\" and try again." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "La carpeta no está configurada correctamente. Pulsa \"Restablecer colecciones\" y vuelve a intentarlo." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." + } + } + } + }, + "The PosterBoard app will now open. Please close it from the app switcher." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se abrirá la aplicación PosterBoard. Ciérrela desde el selector de aplicaciones." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'application PosterBoard est maintenant ouverte. Veuillez la fermer à partir du sélecteur d'applications." + } + } + } + }, + "Version %@ (%@)" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Version %1$@ (%2$@)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version %1$@ (%2$@)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version %1$@ (%2$@)" + } + } + } + }, + "Videos" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videos" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vidéos" + } + } + } + }, + "View on GitHub" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ver en GitHub" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voir sur GitHub" + } + } + } + }, + "Website Designer" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diseñador de la pagina" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Concepteur de site web" + } + } + } + }, + "Would you like to download the file %@?" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Quieres descargar el archivo %@?" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez-vous télécharger le fichier %@?" + } + } + } + }, + "You can only apply %@ descriptors." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sólo puedes aplicar descriptores %@." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous ne pouvez appliquer que des descripteurs %@." + } + } + } + }, + "Your app hash is incorrect. Please set it again." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "El hash de tu aplicación es incorrecto. Por favor, configúralo de nuevo." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." + } + } + } + }, + "Your PosterBoard will refresh automatically." : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Su PosterBoard se actualizará automáticamente." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre PosterBoard se rafraîchit automatiquement." + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings new file mode 100644 index 0000000..9f94cbf --- /dev/null +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -0,0 +1,46 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "CFBundleName" : { + "comment" : "Bundle name", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Pocket Poster" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + } + } + }, + "Nugget Wallpaper" : { + "localizations" : { + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Wallpaper" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fond d'écran Nugget" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 227cbf3..67e17d6 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -107,7 +107,7 @@ struct ContentView: View { if pbManager.setSystemLanguage(to: lang) { UIApplication.shared.alert(title: NSLocalizedString("Collections Successfully Reset!", comment: ""), body: NSLocalizedString("Your PosterBoard will refresh automatically.", comment: "")) } else { - UIApplication.shared.alert(body: NSLocalizedString("The API failed to call correctly.\nSystem Locale Code: ", comment: "") + lang) + UIApplication.shared.alert(body: "The API failed to call correctly.\nSystem Locale Code: \(lang)") } }, noCancel: false) }) { From a9cfe59c495792f36110d81d05f96b6520e0e054 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Wed, 18 Jun 2025 22:44:13 -0400 Subject: [PATCH 17/35] fix alert not finding right view controller --- Pocket Poster.xcodeproj/project.pbxproj | 4 ++-- Pocket Poster/Extensions/Alert++.swift | 6 ++++-- Pocket Poster/Views/ContentView.swift | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index a2e0def..07e4182 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster/Extensions/Alert++.swift b/Pocket Poster/Extensions/Alert++.swift index f6bd495..adb3f31 100644 --- a/Pocket Poster/Extensions/Alert++.swift +++ b/Pocket Poster/Extensions/Alert++.swift @@ -9,6 +9,7 @@ import UIKit // credit: sourcelocation & TrollTools var currentUIAlertController: UIAlertController? +var lastDismissTitle: String? fileprivate let errorString = NSLocalizedString("Error", comment: "") @@ -19,6 +20,7 @@ extension UIApplication { func dismissAlert(animated: Bool) { DispatchQueue.main.async { + lastDismissTitle = currentUIAlertController?.title currentUIAlertController?.dismiss(animated: animated) } } @@ -60,8 +62,8 @@ extension UIApplication { } func present(alert: UIAlertController) { - if var topController = self.windows[0].rootViewController { - while let presentedViewController = topController.presentedViewController { + if let window = UIApplication.shared.connectedScenes.map({ $0 as? UIWindowScene }).compactMap({ $0 }).first?.windows.first, var topController = window.rootViewController { + while let presentedViewController = topController.presentedViewController, presentedViewController.title != lastDismissTitle { topController = presentedViewController } diff --git a/Pocket Poster/Views/ContentView.swift b/Pocket Poster/Views/ContentView.swift index 67e17d6..576c748 100644 --- a/Pocket Poster/Views/ContentView.swift +++ b/Pocket Poster/Views/ContentView.swift @@ -73,9 +73,9 @@ struct ContentView: View { SymHandler.cleanup() // just to be extra sure try? FileManager.default.removeItem(at: pbManager.getTendiesStoreURL()) UIApplication.shared.dismissAlert(animated: false) - Haptic.shared.notify(.success) DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { pbManager.selectedTendies.removeAll() + Haptic.shared.notify(.success) UIApplication.shared.confirmAlert(title: NSLocalizedString("Success!", comment: ""), body: NSLocalizedString("The PosterBoard app will now open. Please close it from the app switcher.", comment: ""), onOK: { if !pbManager.openPosterBoard() { UIApplication.shared.confirmAlert(title: NSLocalizedString("Falling Back to Shortcut", comment: ""), body: NSLocalizedString("PosterBoard failed to open directly. The fallback shortcut will now be opened.", comment: ""), onOK: { From 7666e9fcab6d45c65d4e816cbcfd02453ba451b8 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Thu, 19 Jun 2025 01:01:13 -0400 Subject: [PATCH 18/35] add vietnamese --- Pocket Poster/Localizable.xcstrings | 366 ++++++++++++++++++ .../Pocket-Poster-InfoPlist.xcstrings | 12 + 2 files changed, 378 insertions(+) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 176af5c..edfbefb 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -14,6 +14,12 @@ "state" : "translated", "value" : "Actions" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hành Động" + } } } }, @@ -30,6 +36,12 @@ "state" : "translated", "value" : "Cache de l'application vidé avec succès!" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bộ nhớ cache đã được xóa!" + } } } }, @@ -46,6 +58,12 @@ "state" : "translated", "value" : "Hash de l'application" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mã định danh Ứng dụng" + } } } }, @@ -62,6 +80,12 @@ "state" : "translated", "value" : "Appliquer" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Áp dụng" + } } } }, @@ -78,6 +102,12 @@ "state" : "translated", "value" : "Application de fonds d'écran..." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang áp dụng Hình nền..." + } } } }, @@ -94,6 +124,12 @@ "state" : "translated", "value" : "Annuler" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Huỷ" + } } } }, @@ -110,6 +146,12 @@ "state" : "translated", "value" : "Vider le cache de l'application" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Xoá Cache Ứng Dụng" + } } } }, @@ -126,6 +168,12 @@ "state" : "translated", "value" : "Réinitialisation des collections réussie!" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đặt lại thành công Bộ sưu tập!" + } } } }, @@ -142,6 +190,12 @@ "state" : "translated", "value" : "Erro télécharge le fond d'écran!" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Không thể tải xuống hình nền!" + } } } }, @@ -158,6 +212,12 @@ "state" : "translated", "value" : "Créer une méthode de secours supplémentaire" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tạo phương thức dự phòng bổ sung" + } } } }, @@ -175,6 +235,12 @@ "state" : "translated", "value" : "Création %@..." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang tạo %@..." + } } } }, @@ -192,6 +258,12 @@ "state" : "translated", "value" : "Création de données CAML..." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang tạo dữ liệu CAML..." + } } } }, @@ -208,6 +280,12 @@ "state" : "translated", "value" : "Crédits" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đóng góp" + } } } }, @@ -224,6 +302,12 @@ "state" : "translated", "value" : "Détecter" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Phát hiện" + } } } }, @@ -240,6 +324,12 @@ "state" : "translated", "value" : "Voulez-vous réinitialiser les collections?" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn có muốn thiết lập lại các bộ sưu tập?" + } } } }, @@ -256,6 +346,12 @@ "state" : "translated", "value" : "Télécharger le raccourci de secours" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tải xuống phím tắt dự phòng" + } } } }, @@ -272,6 +368,12 @@ "state" : "translated", "value" : "Télécharger un fichier de Tendies" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tải xuống tệp tendies" + } } } }, @@ -288,6 +390,12 @@ "state" : "translated", "value" : "Téléchargement" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang Tải xuống" + } } } }, @@ -304,6 +412,12 @@ "state" : "translated", "value" : "Saisir le App Hash" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhập mã định danh Ứng dụng" + } } } }, @@ -320,6 +434,12 @@ "state" : "translated", "value" : "Entrez votre app hash de PosterBoard dans les Paramètres." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhập mã định danh của PosterBoard trong Cài đặt." + } } } }, @@ -336,6 +456,12 @@ "state" : "translated", "value" : "Erreur" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lỗi" + } } } }, @@ -352,6 +478,12 @@ "state" : "translated", "value" : "Exploitation" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Khai thác" + } } } }, @@ -369,6 +501,12 @@ "state" : "translated", "value" : "L'extraction des tendies..." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang giải nén tendies..." + } } } }, @@ -385,6 +523,12 @@ "state" : "translated", "value" : "Échec" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Thất bại" + } } } }, @@ -401,6 +545,12 @@ "state" : "translated", "value" : "N'a pas réussi à importer les tendies" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhập tendies thất bại" + } } } }, @@ -417,6 +567,12 @@ "state" : "translated", "value" : "Créateur de raccourcis de secours" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bộ tạo phím tắt dự phòng" + } } } }, @@ -433,6 +589,12 @@ "state" : "translated", "value" : "Retomber dans le raccourci" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quay lại phím tắt" + } } } }, @@ -449,6 +611,12 @@ "state" : "translated", "value" : "Finir" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hoàn thành" + } } } }, @@ -465,6 +633,12 @@ "state" : "translated", "value" : "Générer des vidéos..." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đang tạo video..." + } } } }, @@ -481,6 +655,12 @@ "state" : "translated", "value" : "Accueil" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trang chủ" + } } } }, @@ -497,6 +677,12 @@ "state" : "translated", "value" : "Rejoindre le Discord" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tham gia Discord" + } } } }, @@ -513,6 +699,12 @@ "state" : "translated", "value" : "Liens" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Liên kết" + } } } }, @@ -530,6 +722,12 @@ "state" : "translated", "value" : "Développeur principal" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhà phát triển chính" + } } } }, @@ -546,6 +744,12 @@ "state" : "translated", "value" : "Tendies maximales atteintes" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Số lượng tendies đã đạt tối đa" + } } } }, @@ -562,6 +766,12 @@ "state" : "translated", "value" : "Suivant" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kế tiếp" + } } } }, @@ -578,6 +788,12 @@ "state" : "translated", "value" : "Nugget GitHub" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } } } }, @@ -594,6 +810,12 @@ "state" : "translated", "value" : "OK" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } } } }, @@ -610,6 +832,12 @@ "state" : "translated", "value" : "Seuls les fichiers .tendies peuvent être téléchargés!" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chỉ có thể tải xuống các tập tin .tendies!" + } } } }, @@ -626,6 +854,12 @@ "state" : "translated", "value" : "Veuillez patienter" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vui lòng chờ" + } } } }, @@ -642,6 +876,12 @@ "state" : "translated", "value" : "Pocket Poster" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } } } }, @@ -658,6 +898,12 @@ "state" : "translated", "value" : "PosterBoard n'a pas pu s'ouvrir directement. Le raccourci de secours sera maintenant ouvert." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard không thể mở trực tiếp. Phím tắt dự phòng sẽ được mở ngay bây giờ." + } } } }, @@ -674,6 +920,12 @@ "state" : "translated", "value" : "Libération" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Phát hành" + } } } }, @@ -690,6 +942,12 @@ "state" : "translated", "value" : "Répéter le tutoriel" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Xem lại Hướng dẫn" + } } } }, @@ -706,6 +964,12 @@ "state" : "translated", "value" : "Réinitialiser les Collections" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đặt lại Bộ sưu tập" + } } } }, @@ -722,6 +986,12 @@ "state" : "translated", "value" : "Sélectionner Tendies" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chọn Tendies" + } } } }, @@ -738,6 +1008,12 @@ "state" : "translated", "value" : "Tendies sélectionnées" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đã chọn Tendies" + } } } }, @@ -754,6 +1030,12 @@ "state" : "translated", "value" : "Sauter" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bỏ qua" + } } } }, @@ -770,6 +1052,12 @@ "state" : "translated", "value" : "Sociales" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mạng Xã hội" + } } } }, @@ -786,6 +1074,12 @@ "state" : "translated", "value" : "Succès!" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hoàn thành!" + } } } }, @@ -802,6 +1096,12 @@ "state" : "translated", "value" : "Importation réussie %@" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhập thành công %@" + } } } }, @@ -818,6 +1118,12 @@ "state" : "translated", "value" : "Support sur Ko-Fi" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hỗ trợ trên Ko-Fi" + } } } }, @@ -834,6 +1140,12 @@ "state" : "translated", "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Thư mục được thiết lập không đúng cách. Nhấn vào \"Đặt lại Bộ sưu tập\" và thử lại." + } } } }, @@ -850,6 +1162,12 @@ "state" : "translated", "value" : "L'application PosterBoard est maintenant ouverte. Veuillez la fermer à partir du sélecteur d'applications." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ứng dụng PosterBoard bây giờ sẽ được mở. Hãy đóng nó trong đa nhiệm." + } } } }, @@ -872,6 +1190,12 @@ "state" : "translated", "value" : "Version %1$@ (%2$@)" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Phiên bản %1@ (%2$@)" + } } } }, @@ -888,6 +1212,12 @@ "state" : "translated", "value" : "Vidéos" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videos" + } } } }, @@ -904,6 +1234,12 @@ "state" : "translated", "value" : "Voir sur GitHub" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Xem trên Github" + } } } }, @@ -920,6 +1256,12 @@ "state" : "translated", "value" : "Concepteur de site web" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhà thiết kế Website" + } } } }, @@ -936,6 +1278,12 @@ "state" : "translated", "value" : "Voulez-vous télécharger le fichier %@?" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn có muốn tải xuống tệp %@ không?" + } } } }, @@ -952,6 +1300,12 @@ "state" : "translated", "value" : "Vous ne pouvez appliquer que des descripteurs %@." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn chỉ có thể áp dụng %@ mô tả." + } } } }, @@ -968,6 +1322,12 @@ "state" : "translated", "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mã định danh Ứng dụng chưa chính xác. Vui lòng đặt lại." + } } } }, @@ -984,6 +1344,12 @@ "state" : "translated", "value" : "Votre PosterBoard se rafraîchit automatiquement." } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard sẽ được tự động làm mới." + } } } } diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index 9f94cbf..6441782 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -22,6 +22,12 @@ "state" : "translated", "value" : "Pocket Poster" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } } } }, @@ -38,6 +44,12 @@ "state" : "translated", "value" : "Fond d'écran Nugget" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hình nền Nugget" + } } } } From d5526630346ddab06ca3378e1be8e92c4d3c1f74 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Thu, 19 Jun 2025 03:05:27 -0400 Subject: [PATCH 19/35] clean video folder --- Pocket Poster/Pocket_PosterApp.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Pocket Poster/Pocket_PosterApp.swift b/Pocket Poster/Pocket_PosterApp.swift index 4f27740..8e54693 100644 --- a/Pocket Poster/Pocket_PosterApp.swift +++ b/Pocket Poster/Pocket_PosterApp.swift @@ -82,4 +82,9 @@ struct Pocket_PosterApp: App { } } } + + init() { + // clear the videos cache + try? FileManager.default.removeItem(at: SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory)) + } } From 9d8aef4039db643d004be68f412f0e23426a030e Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Thu, 19 Jun 2025 03:14:49 -0400 Subject: [PATCH 20/35] prepare for carplay app hash --- Pocket Poster/Views/SettingsView.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Pocket Poster/Views/SettingsView.swift b/Pocket Poster/Views/SettingsView.swift index b70bfc7..3cde281 100644 --- a/Pocket Poster/Views/SettingsView.swift +++ b/Pocket Poster/Views/SettingsView.swift @@ -133,7 +133,10 @@ struct SettingsView: View { let contents = try String(contentsOf: filePath) try? FileManager.default.removeItem(at: filePath) await MainActor.run { - pbHash = contents + let items = contents.split(separator: "\n") + if let pb = items.first { + pbHash = String(pb) + } } } catch { print(error.localizedDescription) From 622d8f98cfb7252dd4b1e865a9839d1eac597877 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Thu, 19 Jun 2025 04:52:55 -0400 Subject: [PATCH 21/35] thai support --- .../xcschemes/xcschememanagement.plist | 2 +- Pocket Poster/Localizable.xcstrings | 382 +++++++++++++++++- .../Pocket-Poster-InfoPlist.xcstrings | 12 + 3 files changed, 387 insertions(+), 9 deletions(-) diff --git a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist index f3372ed..d7a896f 100644 --- a/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pocket Poster.xcodeproj/xcuserdata/lemin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Pocket Poster.xcscheme_^#shared#^_ orderHint - 0 + 1 diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index edfbefb..01b87a1 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -15,10 +15,16 @@ "value" : "Actions" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดำเนินการ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Hành Động" + "value" : "Hành động" } } } @@ -37,6 +43,12 @@ "value" : "Cache de l'application vidé avec succès!" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ล้างแคชแอปสำเร็จแล้ว!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -59,6 +71,12 @@ "value" : "Hash de l'application" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "แฮชแอป" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -81,6 +99,12 @@ "value" : "Appliquer" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ใช้งาน" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -103,6 +127,12 @@ "value" : "Application de fonds d'écran..." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังตั้งค่าวอลเปเปอร์…" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -125,6 +155,12 @@ "value" : "Annuler" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ยกเลิก" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -147,10 +183,16 @@ "value" : "Vider le cache de l'application" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ล้างแคชแอป" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Xoá Cache Ứng Dụng" + "value" : "Xoá cache Ứng dụng" } } } @@ -169,6 +211,12 @@ "value" : "Réinitialisation des collections réussie!" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "รีเซ็ตคอลเลกชันสำเร็จแล้ว!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -191,6 +239,12 @@ "value" : "Erro télécharge le fond d'écran!" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดาวน์โหลดวอลเปเปอร์ไม่สำเร็จ!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -213,6 +267,12 @@ "value" : "Créer une méthode de secours supplémentaire" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "สร้างวิธีสำรองเพิ่มเติม" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -236,6 +296,12 @@ "value" : "Création %@..." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังสร้าง %@..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -259,6 +325,12 @@ "value" : "Création de données CAML..." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังสร้างข้อมูล CAML" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -281,6 +353,12 @@ "value" : "Crédits" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เครดิต" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -303,6 +381,12 @@ "value" : "Détecter" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ตรวจจับ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -325,6 +409,12 @@ "value" : "Voulez-vous réinitialiser les collections?" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "คุณต้องการรีเซ็ตคอลเลคชั่นหรือไม่?" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -347,6 +437,12 @@ "value" : "Télécharger le raccourci de secours" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดาวน์โหลด Shortcut สำรอง" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -369,6 +465,12 @@ "value" : "Télécharger un fichier de Tendies" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดาวน์โหลดไฟล์ Tendies" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -391,6 +493,12 @@ "value" : "Téléchargement" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังดาวน์โหลด" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -413,6 +521,12 @@ "value" : "Saisir le App Hash" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ใส่แฮชแอป" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -435,6 +549,12 @@ "value" : "Entrez votre app hash de PosterBoard dans les Paramètres." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ใส่แฮชแอปโปสเตอร์บอร์ดของคุณในเมนูการตั้งค่า" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -457,6 +577,12 @@ "value" : "Erreur" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ของผิดพลาด" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -479,6 +605,12 @@ "value" : "Exploitation" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -502,6 +634,12 @@ "value" : "L'extraction des tendies..." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังดึงข้อมูล tendies…" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -524,6 +662,12 @@ "value" : "Échec" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ไม่สำเร็จ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -546,6 +690,12 @@ "value" : "N'a pas réussi à importer les tendies" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "นำเข้า tendies ไม่สำเร็จ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -568,10 +718,16 @@ "value" : "Créateur de raccourcis de secours" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ตัวสร้าง Shortcut สำรอง" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Bộ tạo phím tắt dự phòng" + "value" : "Bộ tạo Phím tắt dự phòng" } } } @@ -590,10 +746,16 @@ "value" : "Retomber dans le raccourci" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังย้อนกลับไปใช้ Shortcut" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Quay lại phím tắt" + "value" : "Quay lại Phím tắt" } } } @@ -612,6 +774,12 @@ "value" : "Finir" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เสร็จ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -634,6 +802,12 @@ "value" : "Générer des vidéos..." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กำลังสร้างวิดีโอ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -656,6 +830,12 @@ "value" : "Accueil" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "หน้าหลัก" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -678,6 +858,12 @@ "value" : "Rejoindre le Discord" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เข้ารวม Discord" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -700,6 +886,12 @@ "value" : "Liens" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ลิงก์" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -723,6 +915,12 @@ "value" : "Développeur principal" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ผู้พัฒนาหลัก" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -745,6 +943,12 @@ "value" : "Tendies maximales atteintes" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ถึงจำนวนสูงสุดของ Tendies แล้ว" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -767,10 +971,16 @@ "value" : "Suivant" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ถัดไป" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Kế tiếp" + "value" : "Tiếp theo" } } } @@ -789,6 +999,12 @@ "value" : "Nugget GitHub" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Github" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -811,6 +1027,12 @@ "value" : "OK" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "โอเค" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -833,6 +1055,12 @@ "value" : "Seuls les fichiers .tendies peuvent être téléchargés!" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "สามารถดาวน์โหลดไฟล์ .tendies ได้เท่านั้น!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -855,6 +1083,12 @@ "value" : "Veuillez patienter" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "กรุณารอ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -877,6 +1111,12 @@ "value" : "Pocket Poster" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "พ็อกเก็ตโปสเตอร์" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -899,10 +1139,16 @@ "value" : "PosterBoard n'a pas pu s'ouvrir directement. Le raccourci de secours sera maintenant ouvert." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ไม่สามารถเปิดโปสเตอร์บอร์ดโดยตรง กำลังจะใช้ Shortcut สำรอง" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "PosterBoard không thể mở trực tiếp. Phím tắt dự phòng sẽ được mở ngay bây giờ." + "value" : "PosterBoard không thể mở trực tiếp. Phím tắt dự phòng bây giờ sẽ được mở." } } } @@ -921,6 +1167,12 @@ "value" : "Libération" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "รีลีส" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -943,6 +1195,12 @@ "value" : "Répéter le tutoriel" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดูบทแนะนำซ้ำ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -965,6 +1223,12 @@ "value" : "Réinitialiser les Collections" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "รีเซ็ตคอลเลคชั่น" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -987,6 +1251,12 @@ "value" : "Sélectionner Tendies" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เลือก Tendies" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1009,6 +1279,12 @@ "value" : "Tendies sélectionnées" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies ที่ถูกเลือก" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1031,6 +1307,12 @@ "value" : "Sauter" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ข้าม" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1053,6 +1335,12 @@ "value" : "Sociales" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "โซเชียล" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1075,10 +1363,16 @@ "value" : "Succès!" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "สำเร็จ!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Hoàn thành!" + "value" : "Thành công!" } } } @@ -1097,6 +1391,12 @@ "value" : "Importation réussie %@" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "นำเข้า %@ สำเร็จ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1119,6 +1419,12 @@ "value" : "Support sur Ko-Fi" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "สนับสนุนบน Ko-Fi" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1141,6 +1447,12 @@ "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "โฟลเดอร์ถูกตั้งค่าไม่ถูกต้อง กรุณาแตะ \"รีเซ็ตคอลเลคชั่น\" แล้วลองอีกครั้ง" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1163,10 +1475,16 @@ "value" : "L'application PosterBoard est maintenant ouverte. Veuillez la fermer à partir du sélecteur d'applications." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "แอปโปสเตอร์บอร์ดจะถึกเปิด ให้คุณปิดมันในหน้าปัดขึ้น" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Ứng dụng PosterBoard bây giờ sẽ được mở. Hãy đóng nó trong đa nhiệm." + "value" : "Ứng dụng PosterBoard đã được mở. Hãy đóng nó trong đa nhiệm." } } } @@ -1191,6 +1509,12 @@ "value" : "Version %1$@ (%2$@)" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เวอร์ชั่น %1$@ (%2$@)" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1213,6 +1537,12 @@ "value" : "Vidéos" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "วิดีโอ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1235,6 +1565,12 @@ "value" : "Voir sur GitHub" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดูบน GitHub" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1257,6 +1593,12 @@ "value" : "Concepteur de site web" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ผู้ออกแบบเว็บไซต์" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1279,6 +1621,12 @@ "value" : "Voulez-vous télécharger le fichier %@?" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "คุณต้องการดาวน์โหลดไฟล์ %@ หรือไม่?" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1301,6 +1649,12 @@ "value" : "Vous ne pouvez appliquer que des descripteurs %@." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "คุณสามารถใช้ descriptors %@ ได้เท่านั้น" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1323,6 +1677,12 @@ "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "แฮชแอปของคุณไม่ถูกต้อง กรุณาตั้งค่าใหม่อีกครั้ง" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1345,6 +1705,12 @@ "value" : "Votre PosterBoard se rafraîchit automatiquement." } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "โปสเตอร์บอร์ดของคุณจะรีเฟรชโดยอัตโนมัติ" + } + }, "vi" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index 6441782..90f2088 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -23,6 +23,12 @@ "value" : "Pocket Poster" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -45,6 +51,12 @@ "value" : "Fond d'écran Nugget" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "วอลเปเปอร์ Nugget" + } + }, "vi" : { "stringUnit" : { "state" : "translated", From 38c6d06a0ee7440882b115cfd2aa84cdb900dfa1 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Fri, 20 Jun 2025 11:41:24 -0400 Subject: [PATCH 22/35] add tutorial strings --- Pocket Poster/Localizable.xcstrings | 33 +++++++++++++++++++ .../Views/OnBoarding/OnBoardingPage.swift | 22 ++++++------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 01b87a1..6d84001 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -506,6 +506,9 @@ } } } + }, + "Enjoy!" : { + }, "Enter App Hash" : { "localizations" : { @@ -759,6 +762,9 @@ } } } + }, + "Find Wallpapers" : { + }, "Finish" : { "localizations" : { @@ -815,6 +821,12 @@ } } } + }, + "Get Shortcut" : { + + }, + "Here is a tutorial to help you get started with the app." : { + }, "Home" : { "localizations" : { @@ -843,6 +855,12 @@ } } } + }, + "Install Nugget" : { + + }, + "Install the Fallback Shortcut (Optional)" : { + }, "Join the Discord" : { "localizations" : { @@ -1068,6 +1086,9 @@ } } } + }, + "Open GitHub" : { + }, "Please wait" : { "localizations" : { @@ -1488,6 +1509,12 @@ } } } + }, + "To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails." : { + + }, + "To get the app bundle id, Nugget is required.\n\nOn your computer, download Nugget from the GitHub." : { + }, "Version %@ (%@)" : { "localizations" : { @@ -1606,6 +1633,9 @@ } } } + }, + "Welcome to Pocket Poster!" : { + }, "Would you like to download the file %@?" : { "localizations" : { @@ -1634,6 +1664,9 @@ } } } + }, + "You can find wallpapers on the official Cowabun.ga website." : { + }, "You can only apply %@ descriptors." : { "localizations" : { diff --git a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift index c4ae929..399220b 100644 --- a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift +++ b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift @@ -29,30 +29,30 @@ struct OnBoardingPage: Identifiable { let onBoardingCards: [OnBoardingPage] = [ .init( - title: "Welcome to Pocket Poster!", - description: "Here is a tutorial to help you get started with the app.", + title: NSLocalizedString("Welcome to Pocket Poster!", comment: ""), + description: NSLocalizedString("Here is a tutorial to help you get started with the app.", comment: ""), image: "Logo" ), .init( - title: "Install the Fallback Shortcut (Optional)", - description: "To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails.", + title: NSLocalizedString("Install the Fallback Shortcut (Optional)", comment: ""), + description: NSLocalizedString("To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails.", comment: ""), image: "Shortcuts", link: URL(string: PosterBoardManager.ShortcutURL), - linkName: "Get Shortcut" + linkName: NSLocalizedString("Get Shortcut", comment: "") ), .init( - title: "Install Nugget", - description: "To get the app bundle id, Nugget is required.\n\nOn your computer, download Nugget from the GitHub.", + title: NSLocalizedString("Install Nugget", comment: ""), + description: NSLocalizedString("To get the app bundle id, Nugget is required.\n\nOn your computer, download Nugget from the GitHub.", comment: ""), image: "Nugget", link: URL(string: "https://github.com/leminlimez/Nugget/releases/latest"), - linkName: "Open GitHub" + linkName: NSLocalizedString("Open GitHub", comment: "") ), .init( - title: "Enjoy!", - description: "You can find wallpapers on the official Cowabun.ga website.", + title: NSLocalizedString("Enjoy!", comment: ""), + description: NSLocalizedString("You can find wallpapers on the official Cowabun.ga website.", comment: ""), image: "Cowabunga", link: URL(string: PosterBoardManager.WallpapersURL), - linkName: "Find Wallpapers" + linkName: NSLocalizedString("Find Wallpapers", comment: "") ) ] From 2148a348dac6fa49dfb9c207a6f5d52126ecd204 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 08:12:51 -0400 Subject: [PATCH 23/35] add video import duration limit --- .../Controllers/PosterBoardManager.swift | 38 -------------- Pocket Poster/Controllers/VideoHandler.swift | 49 +++++++++++++++++++ Pocket Poster/Localizable.xcstrings | 6 +++ .../Views/NavigatorViews/VideoView.swift | 8 ++- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/Pocket Poster/Controllers/PosterBoardManager.swift b/Pocket Poster/Controllers/PosterBoardManager.swift index 4260e12..df51564 100644 --- a/Pocket Poster/Controllers/PosterBoardManager.swift +++ b/Pocket Poster/Controllers/PosterBoardManager.swift @@ -8,44 +8,6 @@ import Foundation import ZIPFoundation import UIKit -import CoreTransferable - -struct Movie: Transferable { - let url: URL - - static var transferRepresentation: some TransferRepresentation { - FileRepresentation(contentType: .movie) { movie in - SentTransferredFile(movie.url) - } importing: { received in - let videoFolder = SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory) - if !FileManager.default.fileExists(atPath: videoFolder.path()) { - try? FileManager.default.createDirectory(at: videoFolder, withIntermediateDirectories: true) - } - let copy = videoFolder.appending(path: "\(UUID()).mp4") - - if FileManager.default.fileExists(atPath: copy.path()) { - try FileManager.default.removeItem(at: copy) - } - - try FileManager.default.copyItem(at: received.file, to: copy) - return Self.init(url: copy) - } - } -} - -enum LoadState { - case unknown, loading, loaded(Movie), failed -} - -struct LoadInfo: Identifiable, Equatable { - static func == (lhs: LoadInfo, rhs: LoadInfo) -> Bool { - lhs.id == rhs.id - } - - var id = UUID() - var autoReverses: Bool = false - var loadState: LoadState -} class PosterBoardManager: ObservableObject { static let ShortcutURL = "https://www.icloud.com/shortcuts/a28d2c02ca11453cb5b8f91c12cfa692" diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift index 709f09c..c911b19 100644 --- a/Pocket Poster/Controllers/VideoHandler.swift +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -8,6 +8,7 @@ import Foundation import AVFoundation import UIKit +import CoreTransferable extension CGImage { var png: Data? { @@ -23,7 +24,55 @@ extension CGImage { } } +struct Movie: Transferable { + let url: URL + + static var transferRepresentation: some TransferRepresentation { + FileRepresentation(contentType: .movie) { movie in + SentTransferredFile(movie.url) + } importing: { received in + let videoFolder = SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory) + if !FileManager.default.fileExists(atPath: videoFolder.path()) { + try? FileManager.default.createDirectory(at: videoFolder, withIntermediateDirectories: true) + } + let copy = videoFolder.appending(path: "\(UUID()).mp4") + + if FileManager.default.fileExists(atPath: copy.path()) { + try FileManager.default.removeItem(at: copy) + } + + try FileManager.default.copyItem(at: received.file, to: copy) + return Self.init(url: copy) + } + } +} + +enum LoadState { + case unknown, loading, loaded(Movie), failed +} + +struct LoadInfo: Identifiable, Equatable { + static func == (lhs: LoadInfo, rhs: LoadInfo) -> Bool { + lhs.id == rhs.id + } + + var id = UUID() + var autoReverses: Bool = false + var loadState: LoadState +} + class VideoHandler { + static let MaxDurationSecs = 12.0 + + static func isVideoTooLong(at url: URL) -> Bool { + let asset = AVAsset(url: url) + + let duration = asset.duration + let durationTime = CMTimeGetSeconds(duration) + + return durationTime > MaxDurationSecs + } + static func createCaml(from url: URL, autoReverses: Bool) throws -> URL { // copy the resources let descrURL = SymHandler.getDocumentsDirectory().appendingPathComponent(UUID().uuidString, conformingTo: .directory) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 6d84001..5394f48 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -706,6 +706,9 @@ } } } + }, + "Failed to Import Video" : { + }, "Fallback Shortcut Creator" : { "localizations" : { @@ -1509,6 +1512,9 @@ } } } + }, + "The video you imported is too long! Your video must be %@ seconds or less." : { + }, "To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails." : { diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index 9841c61..97267b8 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -11,6 +11,7 @@ import AVKit struct VideoView: View { @ObservedObject var pbManager = PosterBoardManager.shared + @AppStorage("ignoreDurationLimit") var ignoreDurationLimit: Bool = false @State var selectedVideo: PhotosPickerItem? @@ -103,7 +104,12 @@ struct VideoView: View { do { if let movie = try await selectedVideo?.loadTransferable(type: Movie.self) { await MainActor.run { - pbManager.videos[id].loadState = .loaded(movie) + if !ignoreDurationLimit && VideoHandler.isVideoTooLong(at: movie.url) { + pbManager.videos.remove(at: id) + UIApplication.shared.alert(title: NSLocalizedString("Failed to Import Video", comment: ""), body: String(format: NSLocalizedString("The video you imported is too long! Your video must be %@ seconds or less.", comment: ""), "\(Int(VideoHandler.MaxDurationSecs))")) + } else { + pbManager.videos[id].loadState = .loaded(movie) + } } } else { await MainActor.run { From ec1293e3e458774b89903b23575a21c521b20dc2 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 08:20:15 -0400 Subject: [PATCH 24/35] add community translators to credits --- .../Credits/POEditor.imageset/Contents.json | 21 ++++++++++++++++++ .../Credits/POEditor.imageset/POEditor@2x.png | Bin 0 -> 20334 bytes Pocket Poster/Localizable.xcstrings | 3 +++ Pocket Poster/Views/SettingsView.swift | 1 + 4 files changed, 25 insertions(+) create mode 100644 Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/Contents.json create mode 100644 Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/POEditor@2x.png diff --git a/Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/Contents.json b/Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/Contents.json new file mode 100644 index 0000000..480979c --- /dev/null +++ b/Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "POEditor@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/POEditor@2x.png b/Pocket Poster/Assets.xcassets/Credits/POEditor.imageset/POEditor@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cd629cdb5bb4a5907500de85d8b76b6ee5e79747 GIT binary patch literal 20334 zcmeFZ=R;Fn@GeRMNRuY*RgfyZDF}!d2-2kY-jrUXHwi6ZK|leKUL#0v(tD9!6hiMs z>4Z)~AP~6Q-?{gmKjC~iA9fOw*=wymYt}Qfo|#3Ij+P1~`8{$10s>0a7m9iW1R(Uk zi}V)o&G7U}H1G!U(NlR&P%*-?1N@=DQS%7r%S!rFp!qE zWmr3p0>aGjv^>kulEbFlzt_?ss%?AYXJJS3ZLmue^b|~l-uyhvr5#==Qo-`FsaQd1 zX5Z1&NY40sgIaDW?(X-{=u?f@C0ZvngjtrgkFeKP^qNNK#lUe3I849)2W7YkIStZw zuI#6Q%lXyNvXSnt(~K9%N4H{v3fK&%Ld0N}1&z~-PCd|4;B#WEsz768?rj}iW<*zI6NEfFbz5OEf1+D z|GQNj^jCpS$G+qvR0J%pr<4{wN7!FVvTZ{1v7G<}!MV-8q!bVk)Mul7kyQphzu5I| zKKOik9q?AKOrsv&(o^oIl@>I4j{Uk1-Ctt|#-boNUHlgI6i+jwX8qdqK-#5__1Al1 z5K;Oa9qiQ7ei|(irXYTnkr>cFy%~R`7?t(o4d1EMlw!*%K?fmH_V~iiXtTk@4zV{^ zyU*fm1BgBWYGj_EzhHV0PV`P zvg-a;VF_2oGMl430Vs#qMM%bPQav)nEo$^4{uwwMuu8}VTC(aDMIoh@>BwgRL;U<* zU=T#yF9!u7$@a<*k2G{v*VoMZCaDw3BOat&fOim{6IArAyK zsh8jm6XID(Q?n_<{^}&BRJZ7(IN9Owd#T0#LG>vkgx;ByUw{T#y~RIUJoEd68fp`W zrzUOUvx_4D2T_!jFD1;~B)wXjLYE4WrV2x;A>YsD9-&Nk{b&3zf=<9Zy)1yv_&TfI zFyph*dh-lOgE^qkn=a0HZP<7sHFdRULr=4n{j6lX#vl=hh@9!iB!LzYx(okA>>)^` zi9}gAm*j(2*1XEpQ74w5RR2dtb-lVO#a#$&;oJb^^Pv^os~ zsl7-h(>oYFxcY&W%e1OsP-SaJNFDk5Oz~8!zE%H+I8sHOm-=xH;`i@Li$n;gAUIET zGO0h8=e)G$D(;`UN&avd|4fw=4m|?9&9E3eRtK1?u0;b)D-CVCK#)hc}lE+6=0ref1YV*jK-4scDle>t#skVRfc4+u*85gm4JjWl0 z414b>iOQPy+Fxxh&2o_d%bV(j=Dyh9&&7E?{)HtWL+SHzZlvejoVR2Q2X?H zZ~D7_&DJ+G%%84eM>Z0G+PpH98}?G~3;Pwq&iBWa18fMvtYq8j8&BVa)hTFSc(=Ht zJ0ae`dD9StFhcv`?bU;52^Era=~0cK_V5ssBu`*a*}PEyk(2pJ1HX=7gY3v^8L%|P zcHysK8Fa!)Y+LouXIq4GV@x1IFbofK(}A3C2@j_kWvc#ub2eAvhY45>Isp_PSQ~f| zF%+8S>rz0z*>?KmlO^qd>Pusq8OX8iyx-`~fBxjkot<#2%D)FJ_g8zXa#HcHr=nrZ z7wI&>5Mn7IHeLNrAC%s{^3ozk2r|II$aZ-kt%gw!P`lO z?_eTBs!_9Xw2N5JC_ED|N1D%E{!Fgj7rcBRGm*8q+AH##VmqKyn}0!$dBATpv-frQ zM`H9+YQ;voL(?>yxQ*QL3A&`NMe2wn8E{n&>3-{7{9BDO%AsqjXAWhvi?#5Bô z)~H3}TMhf;=#keFYV0MTHmY1$(MbBHS=wbFq9Ru9m+T#6h7K&7XC) zQrawcH#_lCS|=k!={<^&R`S1vMVD(&i)s{&*^NLUj^f(^ONIog4p9*2X>^J7nA?4| zc6Go$)N@BXA_DK9kv&Vwk+)MWwXGG{6wR3QaOPJu; zWP&ia-8!b9t*oThK8#PGn%-jH76_y(CPJmzx?{&^J_bQomdIszQquUQ&JG<$E5^SL z|4@7Zhg%g^k#71uJWs8Gw~L0#W8d0m!d$Yrv%vs#$z*6-##$Ffbbr6opFMz(7?Ump zzFcrQ&mA;2lj*aM(?aQv>ky+uj!#>{R7bYG5%i`mW|YaZMCEYH#uYmFK0HYA1G`YCKqr^B)vR1 zO=I}8uD+LOF}X$)xQcj0bV}O5r9`dMnM9%gS4fmCVACG7sb+*By2FIjchjR5Ae3Mb zpa9(Cw$%k8US*gF^YmV2?*4xFJ)(4)ZAAT&rR>3{z`TB=+fFuek{1u+i{KR`u~im- z0*VYH>TlZGU_@dZ#RG`FX3PQtaQZ9RG4HM>- zgliN1vn0NFn#|c9fsMk$!yoMN49L7T%lT8CrlwJy0?Ca`Xs06xGrF&aIlx`n_8YSN z^)ZUll05^p75VLI(WZRm8!NoXP7+mbNRYXVjrS7$r9n%X&>~ESHmn| zAtDufc@Y;O(ocVwgNfRwn<}pk!@0;d$(&qEoEqU9v4)4`qQY`J=&BDXkM(+E?4fLp zwbdpT=Gu*2A*V00Vz23qRzy2;Xa0C^w7(6EUShM+Q$o;$SL`05eep1J4icYV%iyZp z+x80+QY|)=%Pq}is_Af6%)W8R2m37{ZL_6fQLruzva%s5$9G!4|Gu$2N!fc!#um8j zKi4*?;F;2ZeBW)$j$jL&NSTduo`Kw|`$kUMW76rTT_Nnf8TYK%M(303PSBJM19CXU zsGeaVM6vj|z3H$pcJA&rhs7bvdc!TkyLcsV(zUJ-K8lg=f!Yk8}OR z493CR)_4#(b~h`bTuP&_Mj{BnU+(bvS)#^HzK+-#jDpjJB|#zQxy9Xvcv0a_xPr|C zgi3J6Y(QhJ_M>;cpVE^`9%yzZl@9l38A{aVMqt%Xoi0s?eDMY?+!ijQc}uoUrL291 zasSn?#FE*5>&l9SDrKo=N&q1v949#PUd`w(G}%k!`{g!*Fc+L|X-rTh<{DEK{D zV#$|{?0b;2Px=%x&#qOJBoU600diJaf!e&La}@Q9;z;~ZbwLp?P20eR+LeJH|b-6c)i1t8~M+mFt5Cz z2fhjq07%MDvUe%-XMLx>s#>Z7pQtQ2ejEg5&Jo}`dJk0_EhxT)c$Io6s_`HJ1hLGR z{+Stmg?emvM|M~Gmj~+7(D|!?+H=2RE->k1-qoS3jkS@h)JLlUP$dxrwWYzFx&^j+ zb3SeV_zn_sVs0>MLE`t17DB{AjU{ef`LvdbjG?|Usj7`;4O?TLI{GZi?HZ4VR^5z^ zcO=G$d3m_*Mnc2Ekja)^@%~J`vC_^pTQ8IEux%L4UB8v}E|UTMs7&IDZNJ9tSC+u? zB?#{$LK8gJ>QhDQRDB`ecA-gQHnbJ1ceHi%y*-mN-xL>I?z8gW^sgI%wlM|fF5LOki zEur5OLinwPlU)>r-E~**$=ONL-zQpmBuVs4!}9pcAzc*~k?zR*Tp`rkOWW<(I3l6C_gleJ^Kk~% zUvaBc?o+D}%juB%_9#fk@?^Oy(_M++qEC>}$3NR>OMYiG4Dd71-J2V7p(CCw{jKfq z>YAksM2xtIK@(2ee@pjl;I(#JVfwpA3v`}VjHdOAUaO>IgabeJgpVri1=ky>Z{!(8 z16>b43tNak$IOam9#PJ9VB3W?_^l%8ka=_20-c)a5+OqYxu&=)_4`pl+jR>Qup@$q z!0UbHK`xP{EuDx!Lg5ClHJ*#9`yF4@!#wLme_A+RoV0cfE2ZFHu%0jFRhJhOgzNnv z58oy&Ds4{TaXz}cMu_t|6_hdgYjrP6|6@YEB2?~os1cJgy4<7DZl_~C;?N>3q_g~5 zva(}ldV0tjXfEQ*w+~Y4Vw4rg14!|5^jQm)$$es+>qL3 z*zGaRW`B`kS@uHFl+iHTD&8BiA8zKMM@t^V{A&p^3=&vmK$i2D>$Z8Vx&GF3gQ?vY zGr3V+%=r2F^y}g(qEj9-QRR%0gZZ47R+SL8iw@rO+nf9Ibx9r}r>~_eg5PbAQVQcB zzIZlph({|@sRJBvxr9}9b{3R2+USjdDiXt_(|)ZnFfjC&@UGZiz(3BVEDHZw4ph9^ zSl8csYaWmg17k@T<)~W07VnG>v$2-C)Mh{ZalP{=Xajw7Z^r523<=w0W#yvhew_W^ z-*PF{TKAbXMN=pnG_EwyAXtktdp4q9^gljSF0C)RILw(@3D^?ijxLgLVwbbY#$V_) z7?G7lmNhFho063iF9eO+1p_qyMa>YoP<+|M`h2NKilm#_VbixL4;2>K7d%UWF}}Jf z>lBvgZf~h2SPE~-F@-Q;KgVi#=LUctPZr+#ep2t6g}diZz<&9E2$VQTJg$c_p`Vyg z>G)*U?9m|QPn(%N81OCM>}QSJg;Fd$trRlSEelEFn=WuSj1WDGZ^JmsoZ-(6%ck3Z zSR&yZ;OV#hv85lE?B%%#n?wK8>Y37RsOd3z33XPvP@Z{fW6^z8DtR%gJsjyO>wW}X z;_ASWthjlaR|sBWAkg*;jJVHI+fO_iE-CKVvA8N}#7RRNUVqoCAUVbO@zs&4qJVBk zs`4##+^z3gM#THN9Y2EO;^3hrcmcm+%NvI|4g^VTV3~_q9*ecyX)VuTiWKZ+8>M5m zzjw@GA<7&)HD!*<|7A?X$^8(jmPNv4_}78l)eah9J*=PsBdO*W$?fV}~vqn@P64wJuTU=F;;|PNnj-KZwV?;#I-Pep_BQhO{wNTAwJkmGb%T|5Dd<@fiAB-kA@fPSRW0=AdaU_oOO@ zobLTnW_vdgiG{qpVbL25Ng;$Crd*DE-YdSLJK1%m_y<%(oLtCn^^&I~n9ydJzu`@|8zCYPE06Ds#fF7-R1(nlf&*{2jX(BN}KbH2$3Z z0myZdH{(8p%;Y;$9{7Kpn9cD);P=rY9`Z^ycuVWdD$m)AO&$m+npLW;m^)9|_0)ST zuOqNZNT++)dv1wBb)3|^(`#e%3$NjA@)j21!IdJol|e?^qSd*2weXi!lNDkuVN~~9 zPf9*fv+COLx}XZPiGkABK?g~f4b*Zj=TnV~`m8HbaZC@S7IrG&v>`fbX2M%6Bn5@+Sng>&Ajy2hgD6d& z%eekgx_ zy7Q@vN0XGcD--TMc+BxMzD^qqqe+{1ipB6_ws|vLAFdcq$b_CkV_-8Kdin@hNK`9K zP@(g{g)OxIMQ7c?v*VuVu0r11;awl$?LH+26@wo-VsmRu3EA`jL5tIeFEVDQ3q@1g6nRSst#>&s-oJ7^)Ha zbgu5oFlXV8EmQriTIA@(ESXhQbT0&mU*0y6t(_lrs zWBt;2@Y9y#l;!^1Rxg>*;o>t0W}gflKp@xB$`vPUk^yUD3!ndPkS zY$fXonCpE z9~s?+YpH~PC3n-3Dt8VomWbVB)Nl|U?)?OJSGBt)nG`!%XDQElEtj?&SVLLisEZnJ z(vZFIwXC_6tbI$h=(E|LfOmEZqCxpy0CasNT*4Qv>X<2xN-K^_v+75RHl>IbO=3ra zQmK?KPUz0lVKfyzu~!x(7lzH9Z9)5V`x7guC|h#7^@l{kbe@(d9N#B)CKz;dmLIm& zp7r6+gEGR4yOy{QUjvDJ_GcQjiPZ5*UoevuLZm$wh?V)zBS{4_kI?V~@1`ZR&x6C0 z9rb-&f{eO5SS9eGRG_=`Ma|5gx3_R#9~N`IjE6@X%1PoS>XC%a+>8+4w_0YR(RyPW zP|*ZcjeCUDtn4@|7=4PnWy?V5rt7BOPG+;%KF2!#9f%#C~bFa)M7r0i;C?59>=;`Oc=#M0}78B)-HK? zGL`5F+(wJ!@;uu#Q^Y@H>2BRDsoM(0vEmv=*!DWD3`tc~q0a z>H=jNe%iz2euq+NHL)76FeoLGwrhp!d`lgz=;wQQRm4RVr)bLm0Bl8Jl5F8(BMPa7 z%X&K7Kceml3`u{V!b;s8Xd5<2OxLP9&~GrlQ+st3lyaU*sLJ)S75=3SjReECG^#?I zv%d9wlJoEpTuqI=+^pvclHh;nw3@P>=;bi_Ao$Naj~A0F4X)L+vmc>U;F6TkD(A!e zNJeDupl1^#@+%K{%Ql(Gkj%YH9u<00EZ>@aO0fFbq1$FyJX-OgwH&GzGBgY%bp(+9 zr5hGbdP@ov+p#FIn)#|GRHC*ytSVb@ zB&_+$Vx&FL&V=E~{|@^soT-En=E=Qqu}4pG{1_S+4?+}n)#p2KIj&07Pi?z$Ro+c( zI8X50Tr6nv$=O3YsX-Vk*kN6UnB&D4e-7sljL500Ei{tC`4K>X(N*2vTJo_rQ^I~c zyqcoan=Z~1-PuYnYQMV4i0XKJ5G`M^;V4HG%-FcNh4#^st%bWcbYcSb5PecO2ApnYFCB9ISfcaIVzVT~JPQ2tbWM-4htSyueW z>obcp?>*jl>3o*?YzK6U1ng`(d7mREaDFh0oQT^$sz57y2!*`}s9HVNXD@ObIL64|aiRV7T9yF00T-5!_ z#8*EvlGZe8zifA$L)G$T>T}?x9s~Qe0ZXX%d_r}m&m?WYMra~7=))c46sgy@8|}WJ zq4oSHiIIPvyP|D}RX$z^2KB04ERPs@*5ivgqoK1FHcddmw8?Q0NIjZ+d{F^6iyJGiS=~%Bxt{{RW zLAut@)K`$EI{_8YtNrwNc2E0usY(*fL+ehz5##r*oMjOoPINNu=M*D;m@Vc7lhpIm zLDmI>g0a=_~wWyW1Ks4*5vw%xKIm(E7zIw74-TsR3xz{9|na?7b?2l#Oq zhLj)SL)~U2qj-QqNLq3lJCJ`O0F#~re1U}A!r`-f>N)V`)Y~X#24r^|6(425lW}E= z{#(FanB5{=Khnq`@q_NWcyKebnteAxtZnwcNbetGLdyOl1?pV-Ic*JV#@rbVNZg-S zAOxlM$x?_k^tVS9vjaIoXeZfDb&ro9B{ZXxWdG?RZTF(mvp;{uWHmiJfubJ`J(%6S#~%9 zSd*;rAeCL^GZ#W?>c7_u3W!N9^?v``Ck-Uz*8jr?5UZ(64#oFL1+~0~ACx7z^+ zpH5@)fOI7sz6GwQn?<=2`Hq^4wv(M)2L>-BrvrUzgDYf)3KOwv$?$e2GQoRv+gj9Z zkM2!#0X=>uHF-Pr@JD#-p*qy#JDEvaLuWhpCz^%^a@T(y@(`=Z;Vo`SHASj0lWnug z^KhhzC_SS|dFNjcOUk}l4*%-?0hVFYT}+E)_J8F@2)?h+O<88o@XzF+`rryd6{)(V zQa2*s$_I4uTK&H44dHj#RT*fZ?5bdwGYK#(;odWHKR0b?+;eeVWg?n~+K82pUJRCa z5x{?TythpZZJ~#t|C8V~1o$li;&H7$tkqKxr1REiZ=-#~hoaR_EOQq>B;E%Rb`8ka(HXz%6Rr{LgROnj(>rbP+0U&=G4Rfuam~xLH<{z^wr*d3p6N-?T8UiFyM9lpQ@%BO_}Hx1&t2uBbD#h4 z>E)1`V_4cDi^!qO<>Tg#9p-ThZ>hE@J~lAveLLp?KniB&ZL45rUP5JIi6_#S&Lx+ z;n~PS3=t(~c7ctXC_Ulwdy6SafUOXK#~6MHrLZdLPO-Q7-Fu?9nQB2zY1gr<5uCG%B|IAJxKgTry}YL~9;M-97ud8{qwUKkplO$< zyVFK&u~TksSz1yuwAWU(;d*C5VTQUC-)fiZTQ^;2G1g6w4mo31cTXy=TU(cs*c$eK zlo!R~1u3(?`r5poY&{ruO?SnR(>Nr1KG02sZj^Md-c2%VF-1QRcD*X{_hqd)`*GIH zd(}~1Auf_SQ=Z%2alK$<%xu}$ys;tvKMUX#?BCZBFh<9O?6AK25!`Sdu>1Z|VcvkGHaq5W51c0xa3l4cdins9mmWT&3Ot&M{VGm}D}I6?yqpMY1GLFmh(`y_+ZPRan5O2#n;PUn zaaeXSS#J7z_&=yL>#VP#?!D0am!p7)ExgO+Z(k+ODhlPamIJZ%J$U#OAtR#QOtQ4O z4peL$-_Z$E8onygEhB7ZJ>Ku{?Z6C+B>H03AL61FkTF!7=<&BkymA1SoCOCW$Wu21 zJk6r$WY8uoxwcVwg%79h-<66$DM6{tGOqx45(=gQK~|K@b+l_x%dah%AYGQluPJL` zDA%SqR=y``9B}9!(c~xBXB*ktrMp4Dnds%RM>)PM7_Vrh>O7W4dRJC1F*=3Xefakz zI*4*>zvvB!Z%CZ<_HwB;<)lILTFkWo4uU}>`_=ulq9rY{T7UabRG!@*WQn!F{IXXy zK~EgOnr9HnaV{lqhoXc3;i3t-NmtOev{YI9?fdUvS^8Ayh|6SWX7j_Ir?4l-)%PEQ zy4e>80Pvw9ea>zK@rC5hlacLY9X^%z6~%u-i?_7naF=WMz|EDN4`K2SrFeO$%r#Wzt1R#c=7`)}&J7hxTRNnlPRwc0)^CaHRP;*vLhsjo zwqW{Sc$hZ1I_E#@2?ytd@U*u!GiJa;?OdY5e=}NqiLHHGd@~eAf=##Zgsr~=bV9_7 zEdF|aGNkhwj7!fyA9l+{o?uVC@2v~nu`lJbEOEqK6 znno9Ye+zDmyFS?UlTFID`yVqmv?uR?KUvyBjCFo z0x4&Le+tI&o(eeyl3Q*2tDI9Z9$DB|RWb;ledXi%dfD;%IJra&s^LX{EPSTnj||Xv z{M*g~mNR~*6caS^vH*XW#`vB2NM2rAC@j(n)~TuP4-AhDWX<|<;u(-iu|IP>cHU*2 ze83kO)>_w0oWHI^l*@}O&~%kPt^Jy3?5XxT6Mm0>B!%R!uaYe-(%k&EY6){q-ThD9 za>;j)byDipL?SKg=HBbHk;LMw3e`?@hUOA_i?=!iSYqJITA%-naNbGmHow79FOojc zTRqFD2vRe=s!%k_RttKtiep471oDk=B`pnp7jncp%ASiJUG$ZojFi-Qzs#w)c4Qo5 zxfQ<~cG}qp0p-Rkcv(>ZtL}K|9A=>7r5GFHl6PK!^T;7`S4#z3q}Y2A=I@>-CL8 zjQ6|9c80nvJ3?yAhFbQ-lg@mO-VYQ3n>2seda_Uv20@!Bb_t7A>g-JT=+ke z`1i?fpe7^H9iboMMJr!lf=jXs;V`~f_;TW0P~D|Oo%ExHN#9>|~EH29Ij*qwQ zm@=_}&Q13G3mp%GkCZ{=jYMdO{Mi+w9s7c~V@*3To-HG=vfY-EAYUFJ#UfxYj&y%b z`-cP_N-?G^$_@F_9puH74YAN{??4Wx7{WJI97t1zpgK}be!uw5hcqwG2=s)&&F&@d zB_h)%Y&eo0I1xf@GTYJrVow<&(%nq5-(+?r@8QcV$hJMESp-x=L)uCWwpIA-kOxr|CywfF)| z9SKuFFcnIc1%@T`ZglXjzm#FXw}+bo*H-kRSE) zS!vnn+HQccN+7Ab-{YZ(_B~k?xAo}6GsRg3kT{?ihkEt+e6_iqhO1wq{-BVvdfM=g z_6g)@S&u-$NCmeJ{xxn-4vMCHL|`5Ynn_Lf`!_=lQ7G3#iOb><-1ME$D5Pl&Kt`Esgn*cQ@$*`3kB zFR$GfIa1g@?Z~qd9G+v zM&s2+u@Vnsj2OquGGK~l3y!N_rcL@E+W zbIYU^li$xS?D`T`wzwsF6xf7(B9L#pi}>hal(LZ0cJzGeR!1rACA=b134hky@`);< zN%Dk}Ih1qM?S2;O;M=~jv|p%G;MYfBT?Y0dmAZ{|(FXfL!QY2dClDJpq{P_M!mpVf z2UcU)sl4XJnjIUmAjL+D{p_?VMOn)R>6xWDY7mh>pg~)hz!MSB(r^KueL}r24A=7F zY|`WUO0CH?FOd4D#I!6<6tbnafA||=% z0Sx2Y6CN=b{V`ph)jIw6owo)%Q0J2}0l-hPxZH)p*)>e(GzMjLexJERkV`JqEVS)7 zsEQ@%`t-B;#_`~@<95`uH7W3WU~VXqC=Q>fuU{Yza!_Uk-K8aI(x{geZ0V?MoQal` zg!+)WRdQu=s{p^(GyWf;vzpj0Ol@J^8UMXITyAV?0;66Rmaafc~k1!%%Xc$;9Do> zwqEqXShP%9jiTHVx?M6PIC*x~r2M-|+L3hcma!yb-Ut?MP$ z=bUk7Sxo2{6Gd3#eg`Vx`?;Id1zj`H>XnIa$A|N0OMV-DudB0VRx(+n-oi?o85h3;!&YroDeh` zQ_shepg~*d>}8RET{O^z8rS5%f-v{T)z1XfLxF4C>H-z`ccMFzUz|)pZOu_) zRs4P6=9G#c)c=x^Ut(5?(>GnHvwSFCHYFVJKeWM;(F^1j0BAgM#>e-}BhoWVZm~mk zs0pOwgeJS4zrGE&bTc07BHu6$lR@O7xnVCIkyuA2skOJeR0sIc+;jXgycwV=k+gGX$YK#BrJ+Dwf zO!8OSWj(-yjoKL`0|6HTkc94is7a^o+wiwc)B!ic;(Qdksme4HIu)nXXB4`tfmpBs z{Isa_vhi!HX40fL?GK@?xTd|We%WtCzFzj_Y)Kryoyf|pJCs60wra)%9_K5ubAoFM zv@fXSAxC{?bkjh~6F|$ZO|D=^9tAF9w0%Ix#lL0T%EVq2$v**+?pwPZ zvsY7Re_Eqq2^o?eUtKG6coypSQypb@G2gC8Q~7`%nhp0_TD7X;(Evv!L!lh!onKyJrh>BR^QS|IM47j*I4a836$Hk&zBv zRqIN=gVzM(XlCREw&V6BqYO;&)ZnzrL)`JiF~#2&5_oTtU-GWt<{M{c>#r6WJF39h>P~@lllF z*C+7xOpe)HMJi1U5dKU2uA#)*<^wVbgt-kZ5+dD@@O7Z4CFg6?X)#dD349rB^Re6l?$PpPwLU}b#dtO2?qhPUURSqX#8KN=sFygj!zB_C?xBK#hR+!u zvWe9NRG|KYL5&H2{lbuE_$F{8-r|ysjia;Gvxviw0GIY>jwJn*N6>zS-YGWFfe{9+ z)H3cU8nVc8Y?`|tUIz8^`+TKC><8P;r1=B*oo)>E1FX5mL6&Pck`PDI{bA>&mMA3t z^ig)&_P1A+jk{i~i7}3+%0)&*7*YwNb|p*UDF=-&^9DZ^r~%_H4B8PQr58eoc36k( z)2B&a<`5VD3@5F%fFqW@6$te`ms}l3E9UK94xaHP(1Mm!rQ`N>1=`tl;P6l!o=FM< zl)gkegUMIdXhwm-XX~baLFQKM>xDheFE%5??19*WQv)6PLnhD0~gbuQ1FZqY$am*-5t zK;+q3fTi^0fOXTwRJ-Fzh?$)`88aQSY46~V>I*&7aK~&*PPxWivWws~BSjigRbY1S zv@*@Ps}+_VzWJh~a`ePhsqWfZH1~tVlN1=F=k7>PQ6i3781uxkxeMr`zCv))Ns&wFAuq!^+J| z37<+q6rSGwn_1qzca3MmtFq?&3Wj>QJJz6-b);HC{8L11WzM*D18Lj?il<0`ih`EB zIIFw@gOF->(8cRyc!uO|;vj{J94HL?ooVX7BYnlVhy4-25ep*B>hIHG-QNZNH!-6| zN+)60n|Qza^>0__b22Z&`K-Jv5A(M4@K3?c0K;e07oEbCJCV;k7K6X>p~2_ zkwk`MdVxYN(l^BEhf03D8t8ZhYIp*}BAH8~+ABi`u{V6$n%0X*hiQ)0{{`L=2@NdR z1inwCGbS5AL55gpu=4Lt$>J(-jjRQz@Bu5xQgHW=jmI?xy|=iFn(-iGN?xP`FjT5| zY%2duwI)03-p)=dP%~fhK4zj9SKV^FwwdlLcFT~l&`njxlsI`bv&mz)iAk0Zs6FHT z@obPZ{64VhQ5bn=uiHM^K8zfIxBJd^`q>QPTgV4Je26mZdpGI(x)ZipadBa0N%tj_ zNj9Io<1S_atWTQ#qA4b{B;+s_%(BeG?Q z{vl*?ZnZQOtPE7{Ml_Fhe&(qZsav6$Dx60d56!}_&#K-Umv$-Je8|8Rd0ij)Ix%eR z+M~|?q+{j+rf;^A3;&apJS%t8BMupTS3P3Ynt0fm)SLStN*hsaOzj#>p}b@KVg4SeF+H<6hk%N|N`WTO$#hd{wI|LZn9=`M4b#_l2?75l_&lanvh`q9Zi!@tnEfWomYqni6G+zKaR3F*qruG5SY z!vcP9-|V*sQ7}EQqCU3BIM4WXNLiaVLgYWgc4!-ZD9{s9g&HFk(P(m|_cV-OGnvp!KyZ(OPy`+!C_qXlL zyqs}INq0Uc))HI?SvbU{4y*vacQ}^p<~Ic^J)R0EYG$~?%J!9)Ql zaM5#V=|?fLbwpH;-KDYGytPpl8HYd2(M}>`f;<@g9W1!;R;uU?J-6h)eR8@UaNlo$0@U>>lE#w^V0)5 zJZlT9UNSMr1BgL{F$RYjH=bvoN}7Z<``6dF01(LQZ@M#l$;y+%{yC|p2<1lb{Yf&%`avU(0vS~_lqyo!u~@{wYyDe+~I_T=a7tihx2bdGCX{{uiUH z_d|x>+u`YFTLWV<^&b5k6*|#a2vI80=k0lQbzC4I>#~@JEoS%g(!YFMOp?yZ+mZpY6zPpIg1XT>5I91I*Wcng-Rdpc=v(?-99>c_>yS>Hy(6oAuuev zOi^og@~t+fBm>^74qB+Un>EG_&aROR8MiMQtEtDdX=K-)&_9$zpvY+_r+ka(HlK-0 zR86?6JVl`N&pV|l`ikz(IqZ%K{iHCdySr1C?cY$^K#~&};r$F9Z{^+d=W=khJ81Y% z36nOQy8bwi7Fnn2{kEChA*HBk`g5uyWVYrsW|5N(>1Sx5)1gm{8SW@z%!#0Px?B`< z#t*f~JEWbrqVq4hN%qy@)Y}>#wV*TXgA}_Jg2uno9x27~q;GRGfFzSC3~7F2Q1Yf04Gwn=J+MxBJJ%&Qlo zu;0+!6f$?v*4a04D{7d~bh$f$6D)k^#|L$12UuXB(gGuQ_fKVt9ub7=J_A>r1?r=? zR>rA0+bBNEI!Ccn8Dyy5b5ruF*U$sB*uq$8WK+G_F;BYSDD{ z_-vQ!EUEl043;S{2qb2P|AC#N6l!Pq z?m(&tcm&qD0@s4oDyr?~1HqxV%p*sL1Bg5UO-EMX> zDlmz}{GEpScB#%y41B$KvX>8}LfRXH}Z} z{gQ{od%_aqf2yRuJ4uMLzNu7?4y91MfuJ|vz0q!y{>JxOTZ7tC>O-hXh%2lVc-5l6 z$E#)UYsNH;JM9o!xaAw8Uspr{uA=c2=J$`b?|&FxRirB>_ystclyUy{RdY>lqx%EF&^M(pB?&mn#>YaC>T)7$`jot{Zc=1`_XWi2L_YZAoi>VS%b%g_Ah8L3n zd1fM0Xc3}T&a58*$$3lrBCJ(+UfYxtCq)4+py)YGXt|8G%@+yWNh{$lxYTc7B)Y?l zl+ZrQ#_=wcO!n*htl5Z)5|@4AD&J}at~NoOIB+9*j}XE`C+xiPU!gp{0H$BjMReyr zQetidaZQ3b-s>WjF3ATMQ<~R=xA}g#7rJ7|1Tv+0sKL$yg5+KMLDoNp><>?rPTy13 z@Onn`0yt4}&&a3%=XV&8gA4vfQt&_*0o|SWJ?=0~?p)`q8P4zdANZP7Q4V1~p=V<$ z;{#(jWxn)@{_l$bs7*^8opIVXwTt@gXLS6CC>%YnsfU}t9N+zY^U<(d=ZfPo$aI?S zqYE@Z7%SnWXZ$No7o*lDa4hiwI2sB2JRdgF6d(m;N*oAvs( z`Kehw!6c6t8gGm6D9uAsN-%H7B!P}Ixh=hRJ3V&p)^kZcjLD7u=F-YRjwtB_T59r*W|=jbOUr7i!b+^fhwDC_C4Z!z!%=F zw`6t4EW7S<8uH5*(;-@}UGesi;otnu2J=Q&wQ`*hr*aP&`q_12;Kx7KwqR4EHui#F z)9A$p(9~-a$Fo(dj=%k>!V{jOOweiZew5D49YH?2@Va4-hzEe8LC67^c*!YKiO*#y zam`2`jY>VO{Vop~*ejDxnYg!9#e(->+VwNF**3m4C{i=$dJ>Wj1^TGH=7>QxKX}01 zkBy6We7hTloT~eme%duboQDi=8wu=Ou3``{v`Q=^=3}ASdv>1|Z^$Vir~_il{>$B> z^ws*n%D6m7nv@e|(ph!{?6n`hJ{Q^5E3-^2n?F~YfJ!3H9jpSZ+EXBfw<+R3Wyc*; zM$RgsFVQ*K{f#9*d)6tb0d(JcZjl>pTYE)gOB(t}ICo55gy)h!i_)1F`IR4NtgF@z zKrva_!QRR1WD;$veB!l;+`_Lfl4#3Hp-F)>xxJdj-ga1R{*qmaEYN6v$#Z=>?QOQa z?Km;!&}s}zhQh+s1eKdi+wGfs35zKF3!Y&ln^-`T3xkXQ@_Y8Y`A~H<>0n{5)uLJU zIbss*Z&1D1*^cbzQ@&&(fySI;Gh<8he*y4>y{BW5i# z;;ACq>B!jp#ss7Yx_MWY zAG!eF#j&v)UfU{?QGZFZ-W_<2xqMx&@DnKvvLtLSN(>0wM4wJR`|q zvF=h?@jE`IZaFjLf}#YX;{kvsnB&o_X`tq$-QotF0B3Ma-$>pX9XX?0PL0M|+I!gJ zIMGeX)Q&ia2SnYO+U%F-qT3R#NVf(_B%EJ$STPKZ-gJ;>p|lkT_bYh1q@d6J04UKp z(8S}z%KfWj%07Tnf-+zL1$!}@Ld;AJsd4HeyKo?rNPmHPi#H$;M+F~EP3Hy`ag)DD z1Z}rPG3RNFq%Jno^(_h32WP~wU6KBRz|=gdAgf~=3XO>0HC*(OrPW5hEP&JFtx{Hkt-gCQiTFo0302umR^{5^ z(cZu{2;reUT1>TM!$k)PYyZXfJ?h@ zC*Wi0;EW@?S>1fk5Gf^ba3mmv!QP3VX*q5Xme_QqhtgRp0azJl5Fb7^9ITe{MCnS) zlX=A17)=sZ(M}LZobrK%jXv{LCD@j`)7H-HsUg&ov9aaDvML@C+1lRn$9*g=tF!5^ z3V$M`0sxES!qyErbq+A{3^SJo{WUFx|DeJdnuh|E0f~#oln5CFg59lgsr-Ul zYh&1254wlgzvVUdgwT3!2osp>tTIaF_XGPf(8<~;*R?nn(A;ZXLx*F3=GY#{Pw!tS+ z%)C@r9^P&0)uB;$9S z;1S|80(LQXSjbTEv7sMWou62IxGra$Im2>Pdb)Y}0dpWxIZl$*L82t;}nWgQeoo~V3)_7W@9Do`AJM2F0w zJNM>825dyMCnTeNd%-aA!BJSd+W)Ym02bsFvGslU?t}05;QtZ^h Date: Sat, 21 Jun 2025 08:59:47 -0400 Subject: [PATCH 25/35] add/update languages + fix localization \n problem ar, ar-ae, ar-sa, cs, nl, fr, fr-ch, de, hu, ja, pl, ru, es, es-mx, th, tr, vi --- Pocket Poster/Localizable.xcstrings | 5296 ++++++++++++++++- .../Pocket-Poster-InfoPlist.xcstrings | 126 + .../Views/OnBoarding/OnBoardingPage.swift | 4 +- 3 files changed, 5406 insertions(+), 20 deletions(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 8ac5609..746fa6d 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -3,52 +3,208 @@ "strings" : { "Actions" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "العمليات" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إجراءات" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إجراءات" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Akce" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aktionen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Acciones" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acciones" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Actions" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actions" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Műveletek" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アクション" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acties" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Opcje" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Действия" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดำเนินการ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eylemler" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Hành động" + "value" : "Tác vụ" } } } }, "App Cache Successfully Cleared!" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم مسح ذاكرة التخزين المؤقت للتطبيق بنجاح!" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم مسح ذاكرة التخزين المؤقت بنجاح!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم مسح ذاكرة التخزين المؤقت للتطبيق بنجاح!" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplikační Cache Úspěšně Vyčištěna!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "App-Cache erfolgreich geleert!" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "El cache de la aplicación fue limpiado con exito!" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Caché de la app eliminada satisfactoriamente!" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Cache de l'application vidé avec succès!" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache de l'app vidé avec succès !" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Az app gyorsítótára sikeresen tisztítva!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリのキャッシュがクリアされました" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Cache Succesvol Schoongemaakt!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hash aplikacji wyczyszczony!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Кэш успешно очищен!" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ล้างแคชแอปสำเร็จแล้ว!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulama Önbelleği Başarıyla Temizlendi!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -59,24 +215,96 @@ }, "App Hash" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "معرّف هاش التطبيق" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "مفتاح الهاش للتطبيق" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hash Aplikace" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "App Hash" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hash de la app" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Hash de l'application" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hashje" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリハッシュ" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hash aplikacji" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "แฮชแอป" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulama Hash'i" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -87,24 +315,102 @@ }, "Apply" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplikovat" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anwenden" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Aplicar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplicar" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Appliquer" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appliquer" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alkalmazás" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "適用" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Toepassen" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zastosuj" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подтвердить" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ใช้งาน" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygula" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -115,24 +421,102 @@ }, "Applying Wallpapers..." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري تعيين الخلفيات…" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق الخلفيات..." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ تطبيق الخلفيات..." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplikuji Tapety..." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hintergrundbilder werden angewandt..." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Aplicando Fondos de Pantalla" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplicando fondos de pantalla…" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Application de fonds d'écran..." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Application des fonds d'écrans..." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Háttérképek alkalmazása..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "壁紙を適用中" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Achtergrond Toepassen…" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zastosowanie tapet..." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сохранение обоев..." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังตั้งค่าวอลเปเปอร์…" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Duvar Kağıtları Uygulanıyor..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -143,24 +527,102 @@ }, "Cancel" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إلغاء" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الغاء" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إلغاء" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zrušit" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abbrechen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Cancelar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancelar" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Annuler" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mégsem" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャンセル" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuleren" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anuluj" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Отмена" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ยกเลิก" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "İptal Et" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -171,24 +633,102 @@ }, "Clear App Cache" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "حذف بيانات التخزين المؤقت للتطبيق" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "مسح ذاكرة التخزين المؤقت للتطبيق" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "مسح ذاكرة التخزين المؤقت" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vyčistit Aplikační Cache" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "App-Cache löschen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Limpiar cache de aplicación" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Limpiar Caché de la App" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Vider le cache de l'application" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache de l'app" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "App gyorsítótárának tisztítása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャッシュをクリア" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Cache Verschonen" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wyczyść Cache aplikacji" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Очистить кэш" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ล้างแคชแอป" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulama Önbelleğini Temizle" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -199,24 +739,96 @@ }, "Collections Successfully Reset!" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم اعادة تعيين المجموعات بنجاح!" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم إعادة تعيين المجموعات بنجاح!" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kolekce Úspěšně Resetovány!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sammlungen erfolgreich zurückgesetzt!" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "¡Colecciones reiniciadas exitosamente!" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Colecciones reiniciadas satisfactoriamente!" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Réinitialisation des collections réussie!" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collections réinitialisées avec succès!" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gyűjtemények sikeresen visszaállítva!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コレクションが正常にリセットされました" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collecties Succesvol Hersteld!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kolekcje zresetowane!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Коллекции успешно сброшены!" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "รีเซ็ตคอลเลกชันสำเร็จแล้ว!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Koleksiyonlar Başarıyla Sıfırlandı!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -226,28 +838,113 @@ } }, "Community Translators" : { - + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сообщество переводчиков" + } + } + } }, "Could not download wallpaper!" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "حدث فشل في تحميل الخلفية!" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تعذر تحميل الخلفية!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "لم يمكن تحميل الخلفية!" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nepodařilo se stáhnout tapetu!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hintergrundbild konnte nicht heruntergeladen werden!" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "¡No se pudo descargar el fondo de pantalla!" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡No se pudo descargar el fondo de pantalla!" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Erro télécharge le fond d'écran!" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fond d'écran n'a pas pu être téléchargé!" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nem sikerült letölteni a háttérképet!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "壁紙がダウンロードできませんでした" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Achtergrond downloaden mislukt!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nie udało sie pobrać tapety!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка загрузки обоев!" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดาวน์โหลดวอลเปเปอร์ไม่สำเร็จ!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Duvar Kağıdı İndirilemedi!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -258,24 +955,96 @@ }, "Create Additional Fallback Method" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "انشئ طريقة بديلة اضافية لإستخدامها" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنشاء طريقة بديلة إضافية" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vytvořit Dodatečnou Záložní Metodu" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zusätzliche Fallback-Methode erstellen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Crear un método de respaldo adicional" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crear Método de respaldo adicional" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Créer une méthode de secours supplémentaire" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créer une méthode additionnelle de Fallback" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "További tartalék módszer létrehozása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "追加のフォールバックメソッドの作成" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maak een extra Terugval Methode" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stworz opcjonalna metodę Fallbacku" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Создать свою Fallback Shortcut" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "สร้างวิธีสำรองเพิ่มเติม" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ek Fallback yöntemi ekle" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -287,24 +1056,102 @@ "Creating %@..." : { "comment" : "the message for the current image that is being generated", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري التصميم %@..." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنشاء %@العنصر..." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ إنشاء %@..." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vytvářím %@..." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erstelle %@..." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Creando %@..." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creando %@..." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Création %@..." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création de %@" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ készítése..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ を作成中…" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creëren %@…" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tworzenie %@" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Создание %@..." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังสร้าง %@..." } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Oluşturuluyor %@..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -316,24 +1163,96 @@ "Creating CAML data..." : { "comment" : "translate this however you see fits", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري إنشاء ملف معلومات الخلفية…" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنشاء معلومات CAML..." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vytvářím CAML data..." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erstelle CAML-Daten..." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Creando datos CAML..." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creando datos CAML..." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Création de données CAML..." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création des données CAML..." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "CAML adat készítése..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "CAMLデータの作成中…" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "CAML data creëren…" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tworzenie danych CAML..." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сбор данных..." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังสร้างข้อมูล CAML" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "CAML verisi oluşturuluyor..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -344,24 +1263,96 @@ }, "Credits" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "مساهمين" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الاعتمادات" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kdo se podílel" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Credits" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Creditos" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créditos" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Crédits" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crédits" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Közreműködők" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "クレジット" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Met dank aan" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Twórcy" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Авторы" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "เครดิต" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Külçe" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -372,24 +1363,102 @@ }, "Detect" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم الكشف" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم التحقق" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "كشف" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detekovat" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erkennen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Detectar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detectar" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Détecter" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Détecter" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Érzékelés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "検出" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detecteren" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wykryj" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Найдено" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ตรวจจับ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tespit et" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -400,24 +1469,96 @@ }, "Do you want to reset collections?" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل ترغب بإعادة تعيين المجموعات ؟" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل ترغب في إعادة ضبط المجموعات؟" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přejete si resetovat kolekce?" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Möchten Sie die Sammlungen zurücksetzen?" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "¿Quieres reiniciar las colecciones?" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Quieres reiniciar las colecciones?" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Voulez-vous réinitialiser les collections?" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez-vous réinitialiser les collections?" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Visszaszeretnéd állítani a gyűjteményeket?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コレクションをリセットしますか?" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wil je de collecties resetten?" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Czy chcesz zresetować kolekcje?" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сбросить коллекции?" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "คุณต้องการรีเซ็ตคอลเลคชั่นหรือไม่?" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Koleksiyonları sıfırlamak istiyor musunuz?" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -428,52 +1569,202 @@ }, "Download Fallback Shortcut" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل الإختصار البديل" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل اختصار البديل" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stáhnout Záložní Zkratku" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback Shortcut herunterladen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Descargar acceso directo de respaldo" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargar atajo de respaldo" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Télécharger le raccourci de secours" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Téléchargement du raccourcis Fallback " + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tartalék parancs letöltése" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "フォールバックショートカットをダウンロード" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Download Terugval Snelkoppeling" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pobierz skrót fallback" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скачать Fallback Shortcut" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดาวน์โหลด Shortcut สำรอง" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback kestirmesini indir" + } + }, "vi" : { "stringUnit" : { "state" : "translated", - "value" : "Tải xuống phím tắt dự phòng" + "value" : "Tải xuống Phím tắt dự phòng" } } } }, "Download Tendies File" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل ملف ال Tendies" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل ملف Tendies" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل ملف Tendies" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stáhnout Tendies Soubor" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies-Datei herunterladen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Descargar archivo Tendies" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargar archivo Tendies" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Télécharger un fichier de Tendies" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger le fichier Tendies" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies fájl letöltése" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendiesファイルをダウンロード" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Download Tendies Bestand" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pobierz pliki tendies" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скачать файл Tendies" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดาวน์โหลดไฟล์ Tendies" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies dosyası indir" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -484,24 +1775,102 @@ }, "Downloading" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري التحميل" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "يتم التحميل" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "يتم التحميل" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stahuji" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Herunterladen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Descargando" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Descargando" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Téléchargement" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Téléchargement" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Letöltés folyamatban" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ダウンロード中" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Downloaden" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pobieranie" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Загрузка" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังดาวน์โหลด" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "İndiriliyor" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -511,28 +1880,161 @@ } }, "Enjoy!" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "استمتع!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "استمتع!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Viel spaß!" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disfruta!" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disfruta!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jouir!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ciesz się tapetami!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вперёд!" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เอ็นจอย!" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hãy thưởng thức!" + } + } + } }, "Enter App Hash" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادخل هاش التطبيق" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "أدخل الهاش" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zadejte Hash Aplikace" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "App-Hash eingeben" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Ingresar el hash de la aplicación" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresar el hash de la app" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Saisir le App Hash" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Insérer le Hash de l'app" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Írd be az App hashjét" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリハッシュを入力" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voer de App Hash in" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Podaj Hash Aplikacji" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Введите App Hash" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ใส่แฮชแอป" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulama Hash'i gir" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -543,24 +2045,96 @@ }, "Enter your PosterBoard app hash in Settings." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادخل هاش تطبيق PosterBoard خاصتك بالإعدادات." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "أدخل الهاش لتطبيق PosterBoard في الإعدادات." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zadejte váš hash PosterBoard aplikace v Nastavení." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geben Sie Ihren PosterBoard App-Hash in den Einstellungen ein." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Ingrese el hash de su aplicación PosterBoard en Configuración." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el hash de tu app PosterBoard en configuración." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Entrez votre app hash de PosterBoard dans les Paramètres." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Insérer votre PosterBoard hash de l'app dans les paramètres." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Írd be a PosterBoard app hashedet a Beállításokban." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定でPosterBoardアプリのハッシュを入力してください。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voer je PosterBoard app hash in instellingen toe" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Podaj hash aplikacji PosterBoard w ustawieniach." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Введите свой App Hash в настройках" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ใส่แฮชแอปโปสเตอร์บอร์ดของคุณในเมนูการตั้งค่า" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ayarlarda PosterBoard uygulama Hash'i girin." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -571,24 +2145,102 @@ }, "Error" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "خطأ" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "خطاء" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "خطأ" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chyba" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fehler" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Error" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Erreur" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hiba" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "エラー" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fout" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Błąd" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ของผิดพลาด" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hata" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -599,24 +2251,102 @@ }, "Exploit" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "استغلال الثغرة" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "استغلال" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "مؤسس الثغرة" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ausnutzen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Exploit" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Exploitation" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kwetsbaarheid" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Эксплойт" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "Exploit" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Açığı Kullan" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -628,24 +2358,102 @@ "Extracting tendies..." : { "comment" : "happens when unzipping the files", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري استخراج ملفات ال ... tendies" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "استخراج tendies..." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ استخراج tendies..." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extrahuji tendies..." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies werden extrahiert..." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Extrayendo tendies..." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extrayendo tendies..." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "L'extraction des tendies..." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Excraction des tendies..." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies kicsomagolása..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendiesを解凍中…" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uitpakken tendies…" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wyciąganie tendies..." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Извлечение .tendies..." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังดึงข้อมูล tendies…" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies dışa aktarılıyor..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -656,24 +2464,102 @@ }, "Failed" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selhalo" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gescheitert" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Fallido" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallido" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Échec" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échué" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sikertelen" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "失敗" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mislukt" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nie udało się" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ไม่สำเร็จ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Başarısız" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -684,24 +2570,102 @@ }, "Failed to import tendies" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل في استيراد ال tendies" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "\"فشل في استيراد tendies\"" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل في استيراد ملفات tendies" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Selhal import tendies" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Die Einfuhr von Tendies ist fehlgeschlagen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "No se pudieron importar tendies" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se pudieron importar los tendies" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "N'a pas réussi à importer les tendies" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de l'importation des tendies" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "A tendies importálása sikertelen" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendiesのインポートに失敗しました" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Toevoegen van tendies mislukt" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nie udało sie zaimportować tendies" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка при импорте .tendies" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "นำเข้า tendies ไม่สำเร็จ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies dosyaları içe aktarılırken hata oluştu" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -711,28 +2675,113 @@ } }, "Failed to Import Video" : { - + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка при импорте видео" + } + } + } }, "Fallback Shortcut Creator" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "مصمم الإختصار البديل" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنشاء اختصار البدائل" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "صانع اختصار Fallback" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tvorba Záložní Zkratky" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback Shortcut Creator" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Creador de atajos de respaldo" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Creador del atajo de respaldo" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Créateur de raccourcis de secours" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créateur de raccourcis Fallback" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tartalék parancs készítő" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "フォールバックショートカット作成者" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Terugval Snelkoppeling Maker" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tworzenie skrótu fallback" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Создатель Fallback Shortcut" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ตัวสร้าง Shortcut สำรอง" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback Kestirme Oluşturucusu" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -743,24 +2792,96 @@ }, "Falling Back to Shortcut" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري استخدام طريقة الاختصارات البديلة" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الرجوع إلى الاختصار" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přechod na Náhradní Zkratku" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rückgriff auf Kurzbefehle" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Regresar al atajo" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recurriendo al atajo" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Retomber dans le raccourci" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Revenir au raccourcis" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Visszatérés a parancshoz" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ショートカットに戻る" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Terugvallen op Snelkoppeling" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Powracanie do skroru fallback" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Возвращение к Fallback" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังย้อนกลับไปใช้ Shortcut" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kestirmeye geri düşülüyor" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -770,28 +2891,167 @@ } }, "Find Wallpapers" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "العثور على خلفيات للجهاز" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ابحث عن الخلفيات" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finde Hintergrundbilder" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Encontrar fondos de pantalla" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Buscar fondos de pantalla" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trouver des fonds d'écran" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Poszukaj tapet" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Галерея обоев" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ค้นหาวอลเปเปอร์" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tìm kiếm Hình nền" + } + } + } }, "Finish" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنهاء" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنهاء" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "أنهاء" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dokončit" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abschließen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Finalizar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Terminar" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Finir" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Terminer" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Befejezés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "終了" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Einde" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Koniec" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Готово" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "เสร็จ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tamamla" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -802,24 +3062,102 @@ }, "Generating Video..." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "جاري إنشاء الفيديو…" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ إنشاء الفيديو..." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ إنشاء الفيديو..." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generuji Video..." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video wird generiert..." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Generando vídeo..." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generando video…" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Générer des vidéos..." } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Géneration de la vidéo..." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videó generálása..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "動画を生成中…" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video Genereren" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generawonie filmu.." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Генерация видео..." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กำลังสร้างวิดีโอ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video oluşturuluyor..." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -829,31 +3167,225 @@ } }, "Get Shortcut" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الحصول على الاختصار" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "احصل على الأختصار" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kurzbefehl holen" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Obtener el atajo" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Conseguir el atajo" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Obtenir un raccourci" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zdobądź skrót" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Получить Fallback" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "รับ Shortcut" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tải xuống Phím tắt" + } + } + } }, "Here is a tutorial to help you get started with the app." : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "هذا دليل تعليمي لمساعدتك على البدء بإستخدام التطبيق." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إليك دليل تعليمي لمساعدتك على البدء باستخدام التطبيق." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aqui esta un tutorial para ayudarte a empezara a usar la aplicación" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aquí hay un tutorial para ayudarte a empezar a utilizar la aplicación." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voici un tutoriel pour vous aider à démarrer avec l'application." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Poradnik jak korzystać z aplikacji." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Эта инструкция поможет вам начать пользоваться данным приложением." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "นี่คือบทแนะนำเพื่อให้คุณเริ่มต้นใช้งานแอปได้" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đây là hướng dẫn trước khi bạn bắt đầu sử dụng ứng dụng này." + } + } + } }, "Home" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الرئيسية" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الصفحة الرئيسية" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "الصفحة الرئيسية" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Domů" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Startseite" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Inicio" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inicio" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Accueil" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Acceuil" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Főképernyő" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ホーム" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Thuis" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dom" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Домой" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "หน้าหลัก" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ana sayfa" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -863,31 +3395,231 @@ } }, "Install Nugget" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل Nugget" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "نزل Nuggrt" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget installieren" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Instala Nugget" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Instalar Nugget" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer Nugget" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zainstaluj Nugget" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Установить Nugget" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ติดตั้ง Nugget" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tải xuống Nugget" + } + } + } }, "Install the Fallback Shortcut (Optional)" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تحميل الاختصار البديل ( اختياري )" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تثبيت اختصار fallback (اختياري)" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kurzbefehl als Fallback installieren (Optional)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Instala el atajo de respaldo (opcional)" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Instalar el atajo de respaldo (opcional)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer le raccourci de repli (optionnel)" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zainstaluj skrót fallback (opcjonalne)" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Установите Fallback Shortcut (По желанию)" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ติดตั้ง Shortcut สำรอง (ไม่บังคับลง)" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cài đặt Phím tắt Dự phòng (Thích thì tải)" + } + } + } }, "Join the Discord" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أنضم الى الديسكورد" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "انضم إلى Discord" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "انضم الى الدسكورد" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přidej se na Discord Server" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Discord beitreten" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Unete a nuestro Discord" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Únete al Discord" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Rejoindre le Discord" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rejoigner le Discord" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Csatlakozz a Discordhoz" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Discordサーバに参加" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Meedoen aan Discord" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dołącz do naszego Discorda" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Присоединиться к Discord серверу" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "เข้ารวม Discord" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Discord sunucusuna katıl" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -898,24 +3630,102 @@ }, "Links" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "روابط" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "روابط" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "روابط" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Odkazy" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Links" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Enlaces" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enlaces" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Liens" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Liens" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Linkek" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リンク" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Links" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Linki" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ссылки" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ลิงก์" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Linkler" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -927,24 +3737,102 @@ "Main Developer" : { "comment" : "leminlimez's contribution", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "المطور الرئيسي" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "المطور الرئيسي" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "المطور الرئيسي" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hlavní Vývojář" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hauptentwickler" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Desarrollador Principal" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desarrollador principal" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Développeur principal" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Développeur principal" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Főfejlesztő" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "メイン開発者" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hoofd Developer" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Główny developer" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Главный разработчик" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ผู้พัฒนาหลัก" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ana geliştirici" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -955,24 +3843,102 @@ }, "Max Tendies Reached" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم بلوغ الحد الأقصى من ال Tendies" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم الوصول إلى الحد الأقصى من tendies" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "الحد الاقصى لـtendies وصل" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maximální Počet Tendies Dosažen" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maximale Tendies erreicht" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Cantidad Maxima de Tendies alcanzada" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Máximo de Tendies alcanzado" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Tendies maximales atteintes" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies maximum atteint" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maximum Tendies elérve" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "tendiesの上限到達" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maximale tendies Bereikt" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Limit tendies" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Достигнуто максимальное количество обоев" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ถึงจำนวนสูงสุดของ Tendies แล้ว" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maksimum tendies dosyası sınırına ulaşıldı" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -983,24 +3949,102 @@ }, "Next" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "التالي" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "التالي" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "التالي" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Další" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Weiter" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Siguiente" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siguiente" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Suivant" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suivant" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Következő" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "次" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Volgende" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Następny" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Далее" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ถัดไป" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sonraki" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1011,24 +4055,102 @@ }, "Nugget GitHub" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "صفحة Nugget على GitHub" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Github" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugger GitHub" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Nugget Github" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub de Nugget" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Nugget GitHub" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Github" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Github" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "Nugget Github" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1039,24 +4161,96 @@ }, "OK" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "حسناً" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "حسنا" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "OK" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "OK" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ок" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "โอเค" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tamam" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1065,26 +4259,168 @@ } } }, + "On your computer, download Nugget from the GitHub." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "على حاسوبك، قم بتحميل Nugget من GitHub." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "قم بتنزيل Nugget على جهاز الكمبيوتر الخاص بك من GitHub." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auf Ihrem Computer installieren sie Nugget über GitHub." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "En tu computadora, descargarlo desde GitHub" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "En tu computadora, descarga Nugget desde el GitHub." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sur votre ordinateur, téléchargez Nugget depuis GitHub." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Na swoim komputerze pobierz Nugget z GitHuba." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Установите Nugget из официального GitHub на ваш компьютер." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ดาวน์โหลด Nugget จาก GitHub บนคอมพิวเตอร์ของคุณ" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tải về Nugget trên máy tính từ Github." + } + } + } + }, "Only .tendies files can be downloaded!" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فقط ملفات .tendies يمكن تحميلها!" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "فقط ملفات .tendies يمكن تحميلها!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فقط ملفات .tendies يمكن تحميلها!" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Staženy mohou být pouze .tendies soubory!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Es können nur .tendies-Dateien heruntergeladen werden!" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Solo archivos .tendies pueden ser descargados" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Solo archivos .tendies pueden ser descargados!" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Seuls les fichiers .tendies peuvent être téléchargés!" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seulement les fichiers .tendies peuvent être téléchargés!" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Csak .tendies fájlt lehet letölteni!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "tendiesファイルのみダウンロードできます" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alleen .tendies bestanden kunnen worden gedownload!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tylko pliki .tendies mogą być pobrane!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Только файлы .tendies могут быть загружены!" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "สามารถดาวน์โหลดไฟล์ .tendies ได้เท่านั้น!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sadece .tendies dosyaları indirilebilir!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1094,28 +4430,167 @@ } }, "Open GitHub" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فتح GitHub" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "افتح على GitHub" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub öffnen" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abre GitHub" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Abrir GitHub" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ouvrir GitHub" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otwórz githuba" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Открыть GitHub" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "เปิด GitHub" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mở Github" + } + } + } }, "Please wait" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الرجاء الإنتظار" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الرجاء الانتظار" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please wait" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prosím počkejte" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bitte warten" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Por favor espere" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Por favor espere" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Veuillez patienter" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attendez s'il vous plait" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kérlek várj" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "お待ちください" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Even geduld" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Proszę czekać" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пожалуйста, подождите" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "กรุณารอ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lütfen bekleyin" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1126,24 +4601,102 @@ }, "Pocket Poster" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "بوكيت بوستر Pocket Poster" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster Ar" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Pocket Poster" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Pocket Poster" } }, + "fr-CH" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "พ็อกเก็ตโปสเตอร์" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1154,24 +4707,90 @@ }, "PosterBoard failed to open directly. The fallback shortcut will now be opened." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل فتح تطبيق PosterBoard بشكل مباشر. سيتم فتح الاختصار البديل." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل PosterBoard في الفتح بشكل مباشر. سيتم فتح الاختصار البديل الآن." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard se nemohl otevřít přímo. Otevře se záložní zkratka." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard konnte nicht direkt geöffnet werden. Der Ersatz-Kurzebefehl wird nun geöffnet." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "PosterBoard no se pudo abrir directamente. Ahora se abrirá el acceso directo alternativo." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard no se pudo abrir directamente. Se utilizará el atajo de respaldo." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "PosterBoard n'a pas pu s'ouvrir directement. Le raccourci de secours sera maintenant ouvert." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "A PosterBoard közvetlen megnyitása sikertelen. A tartalék parancs most elindul." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoardが直接開くことができませんでした。フォールバックショートカットが開きます。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard gefaald om het direct te openen. De terugval snelkoppeling wordt nu geopend." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nie udało sie otworzyć PosterBoard. Skrot fallback zostanie otwarty." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard не был открыт напрямую. Открывается Fallback Shortcut" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ไม่สามารถเปิดโปสเตอร์บอร์ดโดยตรง กำลังจะใช้ Shortcut สำรอง" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard doğrudan açılamadı. Fallback kestirmesi şimdi kullanılacak." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1182,24 +4801,96 @@ }, "Release" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الاصدار" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الاصدار" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "الإصدار" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vydání" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Release" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Lanzar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lanzamiento" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Libération" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kiadás" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リリース" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uitbrengen" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wydanie" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Релиз" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "รีลีส" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sürüm" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1210,24 +4901,96 @@ }, "Replay Tutorial" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "اعادة تشغيل الدليل التعليمي" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إعادة تشغيل الدليل" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إعادة تشغيل الدليل التعليمي" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přehrát návod" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tutorial erneut starten" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Reproducir de nuevo Tutorial" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Repetir el tutorial" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Répéter le tutoriel" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tutorial újrajátszása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "チュートリアルを再生" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tutorial opnieuw afspelen" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Powtórz poradnik" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Воспроизвести иструкцию заново" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดูบทแนะนำซ้ำ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tekrar Oynatma Öğreticisi" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1238,24 +5001,90 @@ }, "Reset Collections" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "اعادة تعيين المجموعات" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "إعادة تعيين المجموعات" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Resetovat Kolekce" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sammlungen zurücksetzen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Reiniciar colecciones" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reiniciar colecciones" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Réinitialiser les Collections" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gyűjetmények visszaállítása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コレクションをリセット" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collecties Terugzetten" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zresetuj kolekcje" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сбросить коллекции" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "รีเซ็ตคอลเลคชั่น" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Koleksiyonları sıfırla" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1266,24 +5095,96 @@ }, "Select Tendies" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "اختيار ال Tendies" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "حدد Tendies" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "اختار ملفات Tendies" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vybrat Tendies" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies auswählen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Seleccionar Tendies" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seleccionar Tendies" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Sélectionner Tendies" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies kiválasztása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendiesを選択" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kies Tendies" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wybierz tendies" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Выбрать Tendies" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "เลือก Tendies" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies dosyasını Seç" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1294,24 +5195,96 @@ }, "Selected Tendies" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ال Tendies المختارة" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم تحديد Tendies" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ملفات Tendies المختارة" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vybrané Tendies" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ausgewählte Tendies" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Tendies seleccionado" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies seleccionado" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Tendies sélectionnées" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kiválasztott Tendies" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "選択されたTendies" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geselecteerden Tendies" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wybrane tendies" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Выбранные Tendies" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "Tendies ที่ถูกเลือก" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seçilmiş Tendies dosyası" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1322,24 +5295,96 @@ }, "Skip" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تخطي" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تخطي" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تخطي" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přeskočit" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Überspringen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Saltar" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saltar" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Sauter" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kihagyás" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スキップ" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Overslaan" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pomiń" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Пропустить" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ข้าม" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geç" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1350,24 +5395,96 @@ }, "Socials" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "وسائل التواصل" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "روابط التواصل الاجتماعي" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "روابط" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociální Sítě" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Soziale Netzwerke" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Sociales" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociales" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Sociales" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Közösségi profilok" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ソーシャル" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociale media" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociale" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Социальные сети" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "โซเชียล" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sosyal Medya" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1378,24 +5495,96 @@ }, "Success!" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم بنجاح!" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "نجاح!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "نجاح!" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Úspěch!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erfolg!" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Logrado!" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Éxito!" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Succès!" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siker!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "成功" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gelukt!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sukces!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Готово!" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "สำเร็จ!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Başarılı!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1406,24 +5595,96 @@ }, "Successfully imported %@" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم الاستيراد بنجاح %@" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم استيراد %@ بنجاح" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم استيراد %@" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Úspěšně jsem importoval %@" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ wurde erfolgreich importiert" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Importado correctamente!" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ importado satisfactoriamente" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Importation réussie %@" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sikeresen importáltuk a %@" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ のインポートに成功" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succesvol toegevoegd %@" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zaimportowano %@" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Успешный импорт %@" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "นำเข้า %@ สำเร็จ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Başarıyla içe aktarıldı %@" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1434,24 +5695,96 @@ }, "Support on Ko-Fi" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادعمني على Ko-Fi" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الدعم عبر Ko-Fi" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادعمني في Ko-Fi" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Podpořte nás na Ko-Fi" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unterstütze bei Ko-Fi" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Apoyanos en Ko-Fi" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apóyanos en Ko-Fi" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Support sur Ko-Fi" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Támogass minket Ko-Fi-n" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ko-Fiでサポート" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Steun mij op Ko-Fi" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wesprzyj na Ko-Fi" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Поддержать на Ko-Fi" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "สนับสนุนบน Ko-Fi" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ko-Fi üzerinden destekleyin" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1462,24 +5795,84 @@ }, "The folder is improperly set up. Please tap \"Reset Collections\" and try again." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الملف لم يتم اعداده بشكل صحيح. الرجاء الضغط على \"اعادة تعيين المجموعات\" و المحاولة مجدداً." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "المجلد غير مهيأ بشكل صحيح. يرجى الضغط على \"إعادة تعيين المجموعات\" واعادة المحاولة." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Složka je nesprávně nastavena. Prosím klikněte na \"Resetovat Kolekce\" a zkuste to znovu." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der Ordner ist nicht ordnungsgemäß eingerichtet. Bitte tippen Sie auf \"Sammlungen zurücksetzen\" und versuchen Sie es erneut." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "La carpeta no está configurada correctamente. Pulsa \"Restablecer colecciones\" y vuelve a intentarlo." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "El folder no está configurado correctamente. Favor de presionar \"Reiniciar Colecciones\" e intente de nuevo." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "フォルダが正しく設定されていません。「コレクションをリセット」をタップして、もう一度やり直してください。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "De folder is incorrect ingesteld. Druk alsjeblieft op “herstel Collecties” en probeer het opnieuw." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Folder jest nieprawidłowo skonfigurowany. Kliknij „Resetuj kolekcje” i spróbuj ponownie." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ошибка. Нажмите \"Сбросить коллекции\" и попробуйте снова." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "โฟลเดอร์ถูกตั้งค่าไม่ถูกต้อง กรุณาแตะ \"รีเซ็ตคอลเลคชั่น\" แล้วลองอีกครั้ง" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Klasör uygunsuz kurulmuş. Lütfen \"Koleksiyonları Sıfırla\" tuşuna basıp tekrar deneyin." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1490,24 +5883,96 @@ }, "The PosterBoard app will now open. Please close it from the app switcher." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق PosterBoard سيفتح الآن. الرجاء اغلاقه من واجهة التبديل بين التطبيقات." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "سيتم فتح تطبيق PosterBoard الآن. يرجى إغلاقه من قائمة التطبيقات." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق PosterBoard بيفتح الان. قفله من السويتشر." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard aplikace se teď otevře. Prosím zavřete ji z Nedávných aplikací." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Die PosterBoard App wird nun geöffnet. Bitte schließen Sie sie über den App-Switcher." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Se abrirá la aplicación PosterBoard. Ciérrela desde el selector de aplicaciones." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "La app PosterBoard se abrirá. Por favor ciérrala del multitareas." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "L'application PosterBoard est maintenant ouverte. Veuillez la fermer à partir du sélecteur d'applications." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Megnyílik a PosterBoard alkalmazás. Kérjük, zárja be az alkalmazásváltóból." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoardアプリが開きます。アプリスイッチャーから閉じてください。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "De PosterBoard app opent nu. Sluit het af van de app switcher." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplikacja Posterboard zostanie otwarta. Proszę zamknąć ją w przełączniku aplikacji." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard сейчас будет открыт. Закройте его принудительно" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "แอปโปสเตอร์บอร์ดจะถึกเปิด ให้คุณปิดมันในหน้าปัดขึ้น" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard uygulaması şimdi açılacak. Lütfen uygulama değiştiriciden kapatın." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1517,16 +5982,169 @@ } }, "The video you imported is too long! Your video must be %@ seconds or less." : { - + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ваше видео слишком длинное! Оно должно быть не больше %@ секунд" + } + } + } }, - "To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails." : { - + "To apply, PosterBoard will need to open." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "لتطبيق التغييرات، سنحتاج لفتح تطبيق PosterBoard." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Um anzuwenden, Pocket Poster wird Posterboard öffnen." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para aplicar, PosterBoard necesitara abrirse." + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para aplicar, PosterBoard se abrirá." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour l'appliquer, PosterBoard doit être ouvert." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aby zastosować PosterBoard musi zostać otwarty." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Чтобы обои установились, Pocket Poster потребуется открыть PosterBoard." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ในการใช้งาน ตัวแอป PosterBoard จะจำเป็นต้องเปิดขึ้นมา" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Để áp dụng, PosterBoard sẽ cần phải được mở." + } + } + } }, - "To get the app bundle id, Nugget is required.\n\nOn your computer, download Nugget from the GitHub." : { - + "To get the app bundle id, Nugget is required." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "للحصول على معرّف bundle id الخاص بالتطبيق، تطبيق Nugget ضروري." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "للحصول على معرف حزمة التطبيق، يلزم استخدام Nugget." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Um die App-Bundle-ID zu bekommen, wird Nugget benötigt." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para obteenr el bundle id de la aplicacion, se necesitará Nugget." + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para obtener el Bundle ID de la app, se necesita Nugget." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour obtenir l'identifiant du bundle d'application, Nugget est nécessaire." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aby uzyskać identyfikator pakietu aplikacji, wymagany jest Nugget." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Чтобы получить ID приложения, потребуется Nugget." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ในการหา Bundle ID ของแอปจะต้องใช้ Nugget" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Để lấy ID gói của ứng dụng, bạn cần phải sử dụng Nugget." + } + } + } }, "Version %@ (%@)" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الاصدار %1$@ (%2$@)" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الإصدار %1$@ (%2$@)" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "الإصدار %1$@ (%2$@)" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verze %1$@ (%2$@)" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version %1$@ (%2$@)" + } + }, "en" : { "stringUnit" : { "state" : "new", @@ -1539,18 +6157,54 @@ "value" : "Version %1$@ (%2$@)" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versión %1$@ (%2$@)" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Version %1$@ (%2$@)" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "バージョン %1$@ (%2$@)" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versie %1$@ (%2$@)" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wersja %1@ (%2$@)" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Версия %1$@ (%2$@)" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "เวอร์ชั่น %1$@ (%2$@)" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sürüm %1$@ (%2$@)" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1561,24 +6215,84 @@ }, "Videos" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الفيديوهات" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الفديوهات" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videa" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videos" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Videos" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videos" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Vidéos" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "動画" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videos" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wideo" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Видео" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "วิดีโอ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videolar" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1589,24 +6303,84 @@ }, "View on GitHub" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "المشاهدة على GitHub" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "عرض على GitHub" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zobrazit na GitHubu" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auf GitHub ansehen" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Ver en GitHub" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ver en GitHub" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Voir sur GitHub" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHubで見る" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bekijk op GitHub" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zobacz na GitHubie" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ดูบน GitHub" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Github üzerinde görüntüle" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1617,24 +6391,90 @@ }, "Website Designer" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "مصمم الموقع" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "مصمم الموقع الإلكتروني" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ديزانير الموقع" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Designer Webovky" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Website-Designer" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Diseñador de la pagina" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diseñador del sitio web" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Concepteur de site web" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ウェブサイトデザイナー" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Website Designer" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Designer Strony" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дизайнер Веб-сайта" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "ผู้ออกแบบเว็บไซต์" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "İnteret sayfası tasarımcısı" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1644,28 +6484,149 @@ } }, "Welcome to Pocket Poster!" : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "مرحباً ب Pocket Poster!" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "مرحبا الى Pocket Poster!" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Willkommen zum Pocket Poster!" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bienvenido a Pocket Poster!" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Bienvenid@ a Pocket Poster!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bienvenue à Pocket Poster!" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Witaj w Pocket Poster!" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Добро пожаловать в Pocket Poster!" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ยินดีสู่ Pocket Poster!" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chào mừng đến với Pocket Poster!" + } + } + } }, "Would you like to download the file %@?" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل ترغب بتحميل الملف %@?" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل تريد تحميل الملف %@؟" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Přejete si stahnout soubor %@?" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Möchten Sie die Datei %@ herunterladen?" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "¿Quieres descargar el archivo %@?" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deseas descargar el archivo %@?" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Voulez-vous télécharger le fichier %@?" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ファイルをダウンロードしますか?" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wil je dit bestand downloaden %@?" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Czy chcesz pobrać plik %@?" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вы хотите скачать файл %@?" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "คุณต้องการดาวน์โหลดไฟล์ %@ หรือไม่?" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dosyayı indirmek ister misiniz %@?" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1675,28 +6636,207 @@ } }, "You can find wallpapers on the official Cowabun.ga website." : { - + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك العثور على موقع Cowabun.ga الرسمي." + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك العثور على الخلفيات على الموقع الرسمي Cowabun.ga." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sie können Hintergrundbilder auf der offiziellen Cowabun.ga Webseite finden." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Puedes encontrar fondos de pantalla en el sitio oficial Cowabun.ga" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Puedes encontrar fondos de pantalla en el sitio web oficial Cowabun.ga." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez trouver des fonds d'écran sur le site officiel de Cowabun.ga." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mozesz znaleźć tapety na oficjalnej stronie Cowabun.ga" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вы можете найти обои на официальном сайте Cowabun.ga." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "คุณสามารถหาวอลเปเปอร์ได้ที่เว็บไซต์ Cowabun.ga" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn có thể tìm kiếm các hình nền trên trang web Cowabun.ga." + } + } + } + }, + "You can install an optional shortcut if the original method fails." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك تحميل اختصار اختياري اذا فشلت الطريقة الاساسية." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sie können den optionalen Kurzbefehl installieren, wenn die originale Methode fehlgeschlagen hat." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Puedes instalar un atajo opcional si el metodo original falla." + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Puedes instalar un atajo opcional si el método original falla." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez installer un raccourci facultatif si la méthode originale échoue." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Możesz zainstalować opcjonalny skrót jeżeli oryginalna metoda nie zadziała." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вы можете установить Fallback Shortcut если встроенный метод не работает." + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "คุณสามารถติดตั้ง Shortcut เพิ่มได้ถ้าวิธีเดิมใช้ไม่ได้" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn có thể tải xuống Phím tắt Dự phòng nếu cách làm bình thường bị lỗi." + } + } + } }, "You can only apply %@ descriptors." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك فقط تطبيق %@ descriptors." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك تطبيق %@ وصف فقط." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Můžete aplikovat pouze %@ descriptory." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sie können nur %@-Deskriptoren anwenden." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Sólo puedes aplicar descriptores %@." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Solo puedes aplicar descriptores %@." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Vous ne pouvez appliquer que des descripteurs %@." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 記述子のみ適用できます。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Je kan alleen kenmerken %@ aanpassen." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Można stosować tylko deskryptory %@" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Вы можете установить только %@ дескрипторов." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "คุณสามารถใช้ descriptors %@ ได้เท่านั้น" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sadece %@ descriptors uygulanabilir." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1707,24 +6847,84 @@ }, "Your app hash is incorrect. Please set it again." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "هاش تطبيقك خاطئ. رجاءً عيينه مرة اخرى." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الهاش الخاص بالتطبيق غير صحيح. يرجى إعادة الإعداد." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Váš hash aplikace je nesprávný. Prosím nastavte ho znovu." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ihr App-Hash ist falsch. Bitte stellen Sie ihn erneut ein." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "El hash de tu aplicación es incorrecto. Por favor, configúralo de nuevo." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "El Hash de tu app es incorrecto. Por favor configúralo de nuevo." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリのハッシュが正しくありません。もう一度設定してください。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jou app hash is incorrect. Stel hem opnieuw in." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Twoj hash jest nieprawidłowy. Ustaw go jeszcze raz." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ваш App hash неправильный. Впишите его заново." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "แฮชแอปของคุณไม่ถูกต้อง กรุณาตั้งค่าใหม่อีกครั้ง" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulama Hash'iniz geçersiz . Lütfen tekrar giriniz." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1735,24 +6935,84 @@ }, "Your PosterBoard will refresh automatically." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تطبيق PosterBoard خاصتك سيتم تحديثه تلقائياً." + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "سيتم تحديث PosterBoard الخاص بك تلقائيًا." + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Váš PosterBoard se automaticky znovu načte." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ihr PosterBoard wird automatisch aktualisiert." + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Su PosterBoard se actualizará automáticamente." } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Su PosterBoard se actualizará automáticamente." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Votre PosterBoard se rafraîchit automatiquement." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoardは自動的に更新されます。" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jou PosterBoard ververst automatisch." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Twój posterboard odświeży się automatycznie." + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ваш PosterBoard будет перезагружен автоматически." + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "โปสเตอร์บอร์ดของคุณจะรีเฟรชโดยอัตโนมัติ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard'ınız otomatik olarak yenilenecektir." + } + }, "vi" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index 90f2088..e952db8 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -5,6 +5,36 @@ "comment" : "Bundle name", "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster Ar" + } + }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "en" : { "stringUnit" : { "state" : "new", @@ -17,18 +47,54 @@ "value" : "Pocket Poster" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Pocket Poster" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "Pocket Poster" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -39,24 +105,84 @@ }, "Nugget Wallpaper" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "خلفيات Nugget" + } + }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "خلفيات Nugget" + } + }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Tapeta" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Hintergrundbilder" + } + }, "es" : { "stringUnit" : { "state" : "translated", "value" : "Nugget Wallpaper" } }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Wallpaper" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Fond d'écran Nugget" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Wallpaper" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Achtergrond" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tapeta Nugget" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Обои Nugget" + } + }, "th" : { "stringUnit" : { "state" : "translated", "value" : "วอลเปเปอร์ Nugget" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Duvar Kağıdı" + } + }, "vi" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift index 399220b..21e9e94 100644 --- a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift +++ b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift @@ -35,14 +35,14 @@ let onBoardingCards: [OnBoardingPage] = [ ), .init( title: NSLocalizedString("Install the Fallback Shortcut (Optional)", comment: ""), - description: NSLocalizedString("To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails.", comment: ""), + description: NSLocalizedString("To apply, PosterBoard will need to open.", comment: "") + "\n\n" + NSLocalizedString("You can install an optional shortcut if the original method fails.", comment: ""), image: "Shortcuts", link: URL(string: PosterBoardManager.ShortcutURL), linkName: NSLocalizedString("Get Shortcut", comment: "") ), .init( title: NSLocalizedString("Install Nugget", comment: ""), - description: NSLocalizedString("To get the app bundle id, Nugget is required.\n\nOn your computer, download Nugget from the GitHub.", comment: ""), + description: NSLocalizedString("To get the app bundle id, Nugget is required.", comment: "") + "\n\n" + NSLocalizedString("On your computer, download Nugget from the GitHub.", comment: ""), image: "Nugget", link: URL(string: "https://github.com/leminlimez/Nugget/releases/latest"), linkName: NSLocalizedString("Open GitHub", comment: "") From 80be3c8941b4b21276d3e7320482122c51221c5c Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 09:07:52 -0400 Subject: [PATCH 26/35] update vietnamese --- Pocket Poster/Localizable.xcstrings | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 746fa6d..8c31d75 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -844,6 +844,12 @@ "state" : "translated", "value" : "Сообщество переводчиков" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cộng đồng các Phiên dịch viên" + } } } }, @@ -2681,6 +2687,12 @@ "state" : "translated", "value" : "Ошибка при импорте видео" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nhập Video bị lỗi" + } } } }, @@ -5988,6 +6000,12 @@ "state" : "translated", "value" : "Ваше видео слишком длинное! Оно должно быть не больше %@ секунд" } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bạn nhập video dài quá! Video của bạn cần phải ít hơn hoặc vừa đủ %@ giây." + } } } }, From 6aa0598da4b0ad1a6312baeb6766ed5a6dbddcf5 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 09:15:22 -0400 Subject: [PATCH 27/35] save carplay hash to make transition easier --- Pocket Poster/Views/SettingsView.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Pocket Poster/Views/SettingsView.swift b/Pocket Poster/Views/SettingsView.swift index d00e3f1..baceedd 100644 --- a/Pocket Poster/Views/SettingsView.swift +++ b/Pocket Poster/Views/SettingsView.swift @@ -9,7 +9,8 @@ import SwiftUI struct SettingsView: View { // Prefs - @AppStorage("pbHash") var pbHash: String = "" + @AppStorage("pbHash") var pbHash: String = "" // PosterBoard hash + @AppStorage("cpHash") var cpHash: String = "" // CarPlay hash @State var checkingForHash: Bool = false @State var hashCheckTask: Task? = nil @@ -138,6 +139,9 @@ struct SettingsView: View { if let pb = items.first { pbHash = String(pb) } + if items.count >= 2 { + cpHash = String(items[1]) + } } } catch { print(error.localizedDescription) From eccf8926fdf1bf50eaf9e215f5d796e6cfe10a7f Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 09:50:17 -0400 Subject: [PATCH 28/35] update russian and turkish --- Pocket Poster/Localizable.xcstrings | 120 +++++++++++++++++- .../Views/OnBoarding/OnBoardingPage.swift | 20 +-- 2 files changed, 124 insertions(+), 16 deletions(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 8c31d75..86e3626 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -845,6 +845,12 @@ "value" : "Сообщество переводчиков" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Toplum Çevirmenleri" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -1356,7 +1362,7 @@ "tr" : { "stringUnit" : { "state" : "translated", - "value" : "Külçe" + "value" : "İtibarlar" } }, "vi" : { @@ -1450,7 +1456,7 @@ "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Найдено" + "value" : "Верно" } }, "th" : { @@ -1932,7 +1938,7 @@ "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Вперёд!" + "value" : "Наслаждайтесь!" } }, "th" : { @@ -1941,6 +1947,12 @@ "value" : "เอ็นจอย!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tadına Var!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -2688,6 +2700,12 @@ "value" : "Ошибка при импорте видео" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video içe aktarılamadı" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -2958,6 +2976,12 @@ "value" : "ค้นหาวอลเปเปอร์" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Duvar Kağıtları Bul" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -3234,6 +3258,12 @@ "value" : "รับ Shortcut" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kestirme Al" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -3292,6 +3322,12 @@ "value" : "นี่คือบทแนะนำเพื่อให้คุณเริ่มต้นใช้งานแอปได้" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulamayı kullanmaya başlamak için bir eğitim videosu." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -3383,7 +3419,7 @@ "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Домой" + "value" : "Главная" } }, "th" : { @@ -3405,6 +3441,9 @@ } } } + }, + "How to Reset Collections" : { + }, "Install Nugget" : { "localizations" : { @@ -3453,7 +3492,7 @@ "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Установить Nugget" + "value" : "Установите Nugget" } }, "th" : { @@ -3462,6 +3501,12 @@ "value" : "ติดตั้ง Nugget" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget'i indir" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -3526,6 +3571,12 @@ "value" : "ติดตั้ง Shortcut สำรอง (ไม่บังคับลง)" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback Kestirmesini indir (Opsiyonel)" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -4327,6 +4378,12 @@ "value" : "ดาวน์โหลด Nugget จาก GitHub บนคอมพิวเตอร์ของคุณ" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bilgisayarınızda Nugget'i GitHub'dan indirin." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -4497,6 +4554,12 @@ "value" : "เปิด GitHub" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Github'ı Aç" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -4504,6 +4567,9 @@ } } } + }, + "Open the Language Settings" : { + }, "Please wait" : { "localizations" : { @@ -5304,6 +5370,9 @@ } } } + }, + "Set the Primary Language" : { + }, "Skip" : { "localizations" : { @@ -6001,6 +6070,12 @@ "value" : "Ваше видео слишком длинное! Оно должно быть не больше %@ секунд" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "İçe aktardığın video çok uzun! Video en fazla %@ veya daha az olmalı." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -6059,6 +6134,12 @@ "value" : "ในการใช้งาน ตัวแอป PosterBoard จะจำเป็นต้องเปิดขึ้นมา" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Uygulamak için PosterBoard Açılacak." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -6114,7 +6195,7 @@ "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Чтобы получить ID приложения, потребуется Nugget." + "value" : "Чтобы получить App Hash, потребуется Nugget." } }, "th" : { @@ -6123,6 +6204,12 @@ "value" : "ในการหา Bundle ID ของแอปจะต้องใช้ Nugget" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paket kimliğini almak için Nugget gereklidir." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -6130,6 +6217,9 @@ } } } + }, + "Verify That It Worked" : { + }, "Version %@ (%@)" : { "localizations" : { @@ -6557,6 +6647,12 @@ "value" : "ยินดีสู่ Pocket Poster!" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster'a Hoşgeldiniz!" + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -6709,6 +6805,12 @@ "value" : "คุณสามารถหาวอลเปเปอร์ได้ที่เว็บไซต์ Cowabun.ga" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cowabun.ga websitesinde duvar kağıtları bulabilirsiniz." + } + }, "vi" : { "stringUnit" : { "state" : "translated", @@ -6767,6 +6869,12 @@ "value" : "คุณสามารถติดตั้ง Shortcut เพิ่มได้ถ้าวิธีเดิมใช้ไม่ได้" } }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Orijinal yöntem başarısız olursa opsiyonel bir kestirme indirebilirsiniz." + } + }, "vi" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift index 21e9e94..4e99f56 100644 --- a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift +++ b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift @@ -9,14 +9,14 @@ import SwiftUICore struct OnBoardingPage: Identifiable { var id = UUID() - var title: String + var title: LocalizedStringKey var description: String var image: String var link: URL? - var linkName: String? + var linkName: LocalizedStringKey? var gradientColors: [Color] - init(title: String, description: String, image: String, link: URL? = nil, linkName: String? = nil, gradientColors: [Color] = [Color("WelcomeLight"), Color("WelcomeDark")]) { + init(title: LocalizedStringKey, description: String, image: String, link: URL? = nil, linkName: LocalizedStringKey? = nil, gradientColors: [Color] = [Color("WelcomeLight"), Color("WelcomeDark")]) { self.id = UUID() self.title = title self.description = description @@ -29,30 +29,30 @@ struct OnBoardingPage: Identifiable { let onBoardingCards: [OnBoardingPage] = [ .init( - title: NSLocalizedString("Welcome to Pocket Poster!", comment: ""), + title: "Welcome to Pocket Poster!", description: NSLocalizedString("Here is a tutorial to help you get started with the app.", comment: ""), image: "Logo" ), .init( - title: NSLocalizedString("Install the Fallback Shortcut (Optional)", comment: ""), + title: "Install the Fallback Shortcut (Optional)", description: NSLocalizedString("To apply, PosterBoard will need to open.", comment: "") + "\n\n" + NSLocalizedString("You can install an optional shortcut if the original method fails.", comment: ""), image: "Shortcuts", link: URL(string: PosterBoardManager.ShortcutURL), - linkName: NSLocalizedString("Get Shortcut", comment: "") + linkName: "Get Shortcut" ), .init( - title: NSLocalizedString("Install Nugget", comment: ""), + title: "Install Nugget", description: NSLocalizedString("To get the app bundle id, Nugget is required.", comment: "") + "\n\n" + NSLocalizedString("On your computer, download Nugget from the GitHub.", comment: ""), image: "Nugget", link: URL(string: "https://github.com/leminlimez/Nugget/releases/latest"), - linkName: NSLocalizedString("Open GitHub", comment: "") + linkName: "Open GitHub" ), .init( - title: NSLocalizedString("Enjoy!", comment: ""), + title: "Enjoy!", description: NSLocalizedString("You can find wallpapers on the official Cowabun.ga website.", comment: ""), image: "Cowabunga", link: URL(string: PosterBoardManager.WallpapersURL), - linkName: NSLocalizedString("Find Wallpapers", comment: "") + linkName: "Find Wallpapers" ) ] From 71d37a38bb20acf83f0aca9bf675f3c172bb2fde Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 10:47:42 -0400 Subject: [PATCH 29/35] add time preview to video --- Pocket Poster/Localizable.xcstrings | 162 ++++++++++++++++-- .../Pocket-Poster-InfoPlist.xcstrings | 12 ++ .../Views/NavigatorViews/VideoView.swift | 61 +++++-- .../Views/OnBoarding/OnBoardingPage.swift | 20 +-- 4 files changed, 223 insertions(+), 32 deletions(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 86e3626..026fb97 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -839,6 +839,12 @@ }, "Community Translators" : { "localizations" : { + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fordítók" + } + }, "ru" : { "stringUnit" : { "state" : "translated", @@ -1929,6 +1935,12 @@ "value" : "Jouir!" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Élvezd!" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -2694,6 +2706,12 @@ }, "Failed to Import Video" : { "localizations" : { + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videó importálása sikertelen" + } + }, "ru" : { "stringUnit" : { "state" : "translated", @@ -2958,6 +2976,12 @@ "value" : "Trouver des fonds d'écran" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Háttérképek találása" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3240,6 +3264,12 @@ "value" : "Obtenir un raccourci" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Shortcut letöltése" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3304,6 +3334,12 @@ "value" : "Voici un tutoriel pour vous aider à démarrer avec l'application." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Íme egy oktatóanyag, amely segít az alkalmazás használatának megkezdésében." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3441,9 +3477,6 @@ } } } - }, - "How to Reset Collections" : { - }, "Install Nugget" : { "localizations" : { @@ -3483,6 +3516,12 @@ "value" : "Installer Nugget" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget telepítése" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3553,6 +3592,12 @@ "value" : "Installer le raccourci de repli (optionnel)" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tartalék parancs telepítése" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -4360,6 +4405,12 @@ "value" : "Sur votre ordinateur, téléchargez Nugget depuis GitHub." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "A számítógépeden, töltsd le a Nuggetet a GitHubról." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -4536,6 +4587,12 @@ "value" : "Ouvrir GitHub" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub megnyitésa" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -4567,9 +4624,6 @@ } } } - }, - "Open the Language Settings" : { - }, "Please wait" : { "localizations" : { @@ -5370,9 +5424,6 @@ } } } - }, - "Set the Primary Language" : { - }, "Skip" : { "localizations" : { @@ -5918,6 +5969,12 @@ "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "A mappa nincs megfelelően beállítva. Koppintson a \"Gyűjtemények visszaállítása\" gombra, és próbálja újra." + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6064,6 +6121,12 @@ }, "The video you imported is too long! Your video must be %@ seconds or less." : { "localizations" : { + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Az importált videó túl hosszú! A videó hossza legfeljebb %@ másodperc lehet." + } + }, "ru" : { "stringUnit" : { "state" : "translated", @@ -6116,6 +6179,12 @@ "value" : "Pour l'appliquer, PosterBoard doit être ouvert." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Az alkalmazáshoz a PosterBoardnak meg kell nyílnia." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6186,6 +6255,12 @@ "value" : "Pour obtenir l'identifiant du bundle d'application, Nugget est nécessaire." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nuggetre van szükség az App Bundle id megszerzéséhez." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6217,9 +6292,6 @@ } } } - }, - "Verify That It Worked" : { - }, "Version %@ (%@)" : { "localizations" : { @@ -6277,6 +6349,12 @@ "value" : "Version %1$@ (%2$@)" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verzió %1$@ (%2$@)" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6365,6 +6443,12 @@ "value" : "Vidéos" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videók" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6453,6 +6537,12 @@ "value" : "Voir sur GitHub" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Megtekintés a GitHubon" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6547,6 +6637,12 @@ "value" : "Concepteur de site web" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Weboldal Designere" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6629,6 +6725,12 @@ "value" : "Bienvenue à Pocket Poster!" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Üdvözlünk a Pocket Poster-be!" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6705,6 +6807,12 @@ "value" : "Voulez-vous télécharger le fichier %@?" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Szeretnéd letölteni a(z) %@ fájlt?" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -6787,6 +6895,12 @@ "value" : "Vous pouvez trouver des fonds d'écran sur le site officiel de Cowabun.ga." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Háttérképeket a hivatalos Cowabun.ga weboldalon találhatsz." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6851,6 +6965,12 @@ "value" : "Vous pouvez installer un raccourci facultatif si la méthode originale échoue." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Telepíthetsz egy opcionális parancsot, ha az eredeti módszer nem működik." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6927,6 +7047,12 @@ "value" : "Vous ne pouvez appliquer que des descripteurs %@." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Csak %@ descriptort alkalmazhatsz." + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -7015,6 +7141,12 @@ "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Az App hashed helytelen. Kérlek állítsd be újra" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -7103,6 +7235,12 @@ "value" : "Votre PosterBoard se rafraîchit automatiquement." } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "A PosterBoardod automatikusan újra fog tölteni." + } + }, "ja" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index e952db8..16409c1 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -59,6 +59,12 @@ "value" : "Pocket Poster" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "ja" : { "stringUnit" : { "state" : "translated", @@ -147,6 +153,12 @@ "value" : "Fond d'écran Nugget" } }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget Háttérkép" + } + }, "ja" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Views/NavigatorViews/VideoView.swift b/Pocket Poster/Views/NavigatorViews/VideoView.swift index 97267b8..ed56f69 100644 --- a/Pocket Poster/Views/NavigatorViews/VideoView.swift +++ b/Pocket Poster/Views/NavigatorViews/VideoView.swift @@ -14,12 +14,30 @@ struct VideoView: View { @AppStorage("ignoreDurationLimit") var ignoreDurationLimit: Bool = false @State var selectedVideo: PhotosPickerItem? + @State private var currentPage: Int = 0 + + @State private var currentDate = Date() + private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() // update every second + private var dateFormatter: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "EEEE, MMMM d" + return formatter + } + private var timeFormatter: DateFormatter { + let formatter = DateFormatter() + if Locale.current.hourCycle == .zeroToEleven || Locale.current.hourCycle == .oneToTwelve { + formatter.dateFormat = "h:mm" + } else { + formatter.dateFormat = "HH:mm" + } + return formatter + } var body: some View { VStack { GeometryReader { geom in - TabView { - ForEach(pbManager.videos) { vid in + TabView(selection: $currentPage) { + ForEach(Array(pbManager.videos.enumerated()), id: \.offset) { idx, vid in ZStack { switch vid.loadState { case .unknown: @@ -31,6 +49,17 @@ struct VideoView: View { .scaledToFill() .frame(width: geom.size.width * 0.7, height: geom.size.height * 0.8) .clipped() + VStack { + Text(dateFormatter.string(from: currentDate)) + .shadow(radius: 10) + + Text(timeFormatter.string(from: currentDate)) + .font(.system(size: 75, weight: .semibold, design: .rounded)) + .shadow(radius: 10) + Spacer() + } + .padding(.top, 45) + .foregroundStyle(.white) case .failed: Text("Failed") } @@ -39,6 +68,7 @@ struct VideoView: View { .shadow(radius: 5) .background(Color.black.opacity(0.6)) .cornerRadius(24) + .tag(idx) .overlay { RoundedRectangle(cornerRadius: 24) .stroke(.gray, lineWidth: 4) @@ -51,22 +81,30 @@ struct VideoView: View { .overlay( // Loops Button Button(action: { - if let index = pbManager.videos.firstIndex(of: vid) { - pbManager.videos[index].autoReverses = !vid.autoReverses - } + pbManager.videos[idx].autoReverses = !vid.autoReverses }) { Image(systemName: "arrow.left.arrow.right.circle") .font(.title) - .foregroundStyle(.black) + .foregroundStyle(Color(uiColor: .label)) .background { - Circle() - .foregroundStyle(vid.autoReverses ? .blue : .white) + if vid.autoReverses { + Circle() + .foregroundStyle(.blue.opacity(0.8)) + .shadow(radius: 5) + } else { + Circle() + .foregroundStyle(.regularMaterial) + .shadow(radius: 5) + } } }.offset(x: 8, y: -8), alignment: .topTrailing ) } .onDelete(perform: removeVideo) + .onReceive(timer) { input in + currentDate = input + } // MARK: Select Photo Option if selectedVideo == nil && pbManager.videos.count < 5 { @@ -90,6 +128,7 @@ struct VideoView: View { .shadow(radius: 5) .background(Color.black.opacity(0.6)) .cornerRadius(24) + .tag(pbManager.videos.count) .overlay { RoundedRectangle(cornerRadius: 24) .stroke(.gray, lineWidth: 4) @@ -109,6 +148,7 @@ struct VideoView: View { UIApplication.shared.alert(title: NSLocalizedString("Failed to Import Video", comment: ""), body: String(format: NSLocalizedString("The video you imported is too long! Your video must be %@ seconds or less.", comment: ""), "\(Int(VideoHandler.MaxDurationSecs))")) } else { pbManager.videos[id].loadState = .loaded(movie) + currentPage = id } } } else { @@ -124,7 +164,7 @@ struct VideoView: View { selectedVideo = nil } } - .tabViewStyle(.page) + .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always)) } } } @@ -155,7 +195,8 @@ struct DeleteButton: View { .font(.title) .background { Circle() - .foregroundStyle(.white) + .foregroundStyle(.regularMaterial) + .shadow(radius: 5) } } .offset(x: -8, y: -8) diff --git a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift index 4e99f56..21e9e94 100644 --- a/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift +++ b/Pocket Poster/Views/OnBoarding/OnBoardingPage.swift @@ -9,14 +9,14 @@ import SwiftUICore struct OnBoardingPage: Identifiable { var id = UUID() - var title: LocalizedStringKey + var title: String var description: String var image: String var link: URL? - var linkName: LocalizedStringKey? + var linkName: String? var gradientColors: [Color] - init(title: LocalizedStringKey, description: String, image: String, link: URL? = nil, linkName: LocalizedStringKey? = nil, gradientColors: [Color] = [Color("WelcomeLight"), Color("WelcomeDark")]) { + init(title: String, description: String, image: String, link: URL? = nil, linkName: String? = nil, gradientColors: [Color] = [Color("WelcomeLight"), Color("WelcomeDark")]) { self.id = UUID() self.title = title self.description = description @@ -29,30 +29,30 @@ struct OnBoardingPage: Identifiable { let onBoardingCards: [OnBoardingPage] = [ .init( - title: "Welcome to Pocket Poster!", + title: NSLocalizedString("Welcome to Pocket Poster!", comment: ""), description: NSLocalizedString("Here is a tutorial to help you get started with the app.", comment: ""), image: "Logo" ), .init( - title: "Install the Fallback Shortcut (Optional)", + title: NSLocalizedString("Install the Fallback Shortcut (Optional)", comment: ""), description: NSLocalizedString("To apply, PosterBoard will need to open.", comment: "") + "\n\n" + NSLocalizedString("You can install an optional shortcut if the original method fails.", comment: ""), image: "Shortcuts", link: URL(string: PosterBoardManager.ShortcutURL), - linkName: "Get Shortcut" + linkName: NSLocalizedString("Get Shortcut", comment: "") ), .init( - title: "Install Nugget", + title: NSLocalizedString("Install Nugget", comment: ""), description: NSLocalizedString("To get the app bundle id, Nugget is required.", comment: "") + "\n\n" + NSLocalizedString("On your computer, download Nugget from the GitHub.", comment: ""), image: "Nugget", link: URL(string: "https://github.com/leminlimez/Nugget/releases/latest"), - linkName: "Open GitHub" + linkName: NSLocalizedString("Open GitHub", comment: "") ), .init( - title: "Enjoy!", + title: NSLocalizedString("Enjoy!", comment: ""), description: NSLocalizedString("You can find wallpapers on the official Cowabun.ga website.", comment: ""), image: "Cowabunga", link: URL(string: PosterBoardManager.WallpapersURL), - linkName: "Find Wallpapers" + linkName: NSLocalizedString("Find Wallpapers", comment: "") ) ] From 7bf227a6de3d55010acddefcb311295dee574717 Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 11:22:10 -0400 Subject: [PATCH 30/35] option to ignore video duration limit --- Pocket Poster.xcodeproj/project.pbxproj | 4 ++-- Pocket Poster/Localizable.xcstrings | 6 ++++++ Pocket Poster/Views/SettingsView.swift | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 07e4182..5b0f8ad 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 026fb97..2219868 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -1484,6 +1484,9 @@ } } } + }, + "Disable Video Duration Limit" : { + }, "Do you want to reset collections?" : { "localizations" : { @@ -4930,6 +4933,9 @@ } } } + }, + "Preferences" : { + }, "Release" : { "localizations" : { diff --git a/Pocket Poster/Views/SettingsView.swift b/Pocket Poster/Views/SettingsView.swift index baceedd..58bf135 100644 --- a/Pocket Poster/Views/SettingsView.swift +++ b/Pocket Poster/Views/SettingsView.swift @@ -11,6 +11,7 @@ struct SettingsView: View { // Prefs @AppStorage("pbHash") var pbHash: String = "" // PosterBoard hash @AppStorage("cpHash") var cpHash: String = "" // CarPlay hash + @AppStorage("ignoreDurationLimit") var ignoreDurationLimit: Bool = false @State var checkingForHash: Bool = false @State var hashCheckTask: Task? = nil @@ -46,6 +47,14 @@ struct SettingsView: View { Label("App Hash", systemImage: "lock.app.dashed") } + Section { + Toggle(isOn: $ignoreDurationLimit, label: { + Label("Disable Video Duration Limit", systemImage: "ruler") + }) + } header: { + Label("Preferences", systemImage: "gear") + } + Section { Button(action: { UIImpactFeedbackGenerator(style: .soft).impactOccurred() From bfaf9d1678281b071194c3261109605dea368f2d Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sat, 21 Jun 2025 14:15:00 -0400 Subject: [PATCH 31/35] release pooled memory while extracting frames --- Pocket Poster/Controllers/VideoHandler.swift | 24 +++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Pocket Poster/Controllers/VideoHandler.swift b/Pocket Poster/Controllers/VideoHandler.swift index c911b19..1484f76 100644 --- a/Pocket Poster/Controllers/VideoHandler.swift +++ b/Pocket Poster/Controllers/VideoHandler.swift @@ -140,17 +140,19 @@ class VideoHandler { while let sampleBuffer = readerOutput.copyNextSampleBuffer(), let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) { - let name = "\(frameCount).jpg" - let filePathName = "assets/\(name)" - UIApplication.shared.change(title: NSLocalizedString("Generating Video...", comment: ""), body: String(format: NSLocalizedString("Creating %@...", comment: "the message for the current image that is being generated"), filePathName)) - - let ciImage = CIImage(cvPixelBuffer: imageBuffer) - let context = CIContext() - if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) { - if let img = cgImage.jpg { - try img.write(to: assetsFolder.appendingPathComponent(name)) - camlData += "\t\t\t\n" - frameCount += 1 + try? autoreleasepool { + let name = "\(frameCount).jpg" + let filePathName = "assets/\(name)" + UIApplication.shared.change(title: NSLocalizedString("Generating Video...", comment: ""), body: String(format: NSLocalizedString("Creating %@...", comment: "the message for the current image that is being generated"), filePathName)) + + let ciImage = CIImage(cvPixelBuffer: imageBuffer) + let context = CIContext() + if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) { + if let img = cgImage.jpg { + try img.write(to: assetsFolder.appendingPathComponent(name)) + camlData += "\t\t\t\n" + frameCount += 1 + } } } } From 2536f5df86b4eccb748add87291b3f12d9e61e9f Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sun, 22 Jun 2025 11:35:53 -0400 Subject: [PATCH 32/35] update/add finished languages ae-AE, es, es-MX, fr, fr-BE, fr-CA, ko, zh-Hant, th, pl, nl, ja, de, hu, ru, tr --- Pocket Poster/Localizable.xcstrings | 2464 ++++++++++++++++- .../Pocket-Poster-InfoPlist.xcstrings | 48 + 2 files changed, 2508 insertions(+), 4 deletions(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 2219868..fec8c30 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -51,6 +51,18 @@ "value" : "Actions" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actions" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actions" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -69,6 +81,12 @@ "value" : "アクション" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "활동" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -104,6 +122,12 @@ "state" : "translated", "value" : "Tác vụ" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "動作" + } } } }, @@ -157,6 +181,18 @@ "value" : "Cache de l'application vidé avec succès!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le cache de l'application a été effacé avec succès !" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache de l'application effacée!" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -175,6 +211,12 @@ "value" : "アプリのキャッシュがクリアされました" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 캐시가 성공적으로 삭제되었습니다!" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -210,6 +252,12 @@ "state" : "translated", "value" : "Bộ nhớ cache đã được xóa!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "App 快取已成功清除!" + } } } }, @@ -257,6 +305,18 @@ "value" : "Hash de l'application" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "App hash" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hachage d'application" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -275,6 +335,12 @@ "value" : "アプリハッシュ" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 해시" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -310,6 +376,12 @@ "state" : "translated", "value" : "Mã định danh Ứng dụng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "App 哈希值" + } } } }, @@ -363,6 +435,18 @@ "value" : "Appliquer" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appliquer" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appliquer" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -381,6 +465,12 @@ "value" : "適用" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "적용" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -416,6 +506,12 @@ "state" : "translated", "value" : "Áp dụng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "加載" + } } } }, @@ -469,6 +565,18 @@ "value" : "Application de fonds d'écran..." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Application de fond d’écran" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Application des fonds d'écran..." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -487,6 +595,12 @@ "value" : "壁紙を適用中" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "배경화면을 적용하는중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -522,6 +636,12 @@ "state" : "translated", "value" : "Đang áp dụng Hình nền..." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在加載桌布…" + } } } }, @@ -575,6 +695,18 @@ "value" : "Annuler" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Passer" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -593,6 +725,12 @@ "value" : "キャンセル" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "취소" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -628,6 +766,12 @@ "state" : "translated", "value" : "Huỷ" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "取消" + } } } }, @@ -681,6 +825,18 @@ "value" : "Vider le cache de l'application" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache d’application" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer le cache d'application" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -699,6 +855,12 @@ "value" : "キャッシュをクリア" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 캐시 삭제하기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -734,6 +896,12 @@ "state" : "translated", "value" : "Xoá cache Ứng dụng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除App 快取" + } } } }, @@ -781,6 +949,18 @@ "value" : "Réinitialisation des collections réussie!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les collections se réinitialisent avec succès !" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Collections réinitialisées!" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -799,6 +979,12 @@ "value" : "コレクションが正常にリセットされました" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "컬렉션이 성공적으로 초기화되었습니다!" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -834,23 +1020,101 @@ "state" : "translated", "value" : "Đặt lại thành công Bộ sưu tập!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選集資料夾已成功重置!" + } } } }, "Community Translators" : { "localizations" : { + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "مترجمو المجتمع" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Community-Übersetzern" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comunidad de traductores" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traductores de la comunidad" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traducteurs communautaires" + } + }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traduction communautaire" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Traducteurs de communauté" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Fordítók" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コミュニティ翻訳者" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "커뮤니티 번역자" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gemeenschapsvertalers" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tłumacze" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Сообщество переводчиков" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ผู้แปลภาษา" + } + }, "tr" : { "stringUnit" : { "state" : "translated", @@ -862,6 +1126,12 @@ "state" : "translated", "value" : "Cộng đồng các Phiên dịch viên" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "社群翻譯者" + } } } }, @@ -915,6 +1185,18 @@ "value" : "Erro télécharge le fond d'écran!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossible d’installer les fond écran!" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "impossible de télécharger le fond d'écran!" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -933,6 +1215,12 @@ "value" : "壁紙がダウンロードできませんでした" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "배경화면을 다운로드 할 수 없습니다!" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -968,6 +1256,12 @@ "state" : "translated", "value" : "Không thể tải xuống hình nền!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "無法下載桌布!" + } } } }, @@ -1015,6 +1309,18 @@ "value" : "Créer une méthode de secours supplémentaire" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créer une méthode de repli supplémentaire" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créer une méthode de secours additionnelle" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1033,6 +1339,12 @@ "value" : "追加のフォールバックメソッドの作成" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "추가적인 Fallback Method 생성하기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1068,6 +1380,12 @@ "state" : "translated", "value" : "Tạo phương thức dự phòng bổ sung" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "新增替代方案" + } } } }, @@ -1122,6 +1440,18 @@ "value" : "Création %@..." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création%@" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création de %@..." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1140,6 +1470,12 @@ "value" : "%@ を作成中…" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 생성중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1175,6 +1511,12 @@ "state" : "translated", "value" : "Đang tạo %@..." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在創建%@…" + } } } }, @@ -1223,6 +1565,18 @@ "value" : "Création de données CAML..." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création CAML data" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création des données CAML..." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1241,6 +1595,12 @@ "value" : "CAMLデータの作成中…" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "CAML 데이터 생성중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1276,6 +1636,12 @@ "state" : "translated", "value" : "Đang tạo dữ liệu CAML..." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在建立 CAML 資料…" + } } } }, @@ -1323,6 +1689,18 @@ "value" : "Crédits" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crédits" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crédits " + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1341,6 +1719,12 @@ "value" : "クレジット" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "출처" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1376,6 +1760,12 @@ "state" : "translated", "value" : "Đóng góp" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "鸣谢" + } } } }, @@ -1429,6 +1819,18 @@ "value" : "Détecter" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Détecter" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Detecter" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1447,6 +1849,12 @@ "value" : "検出" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "감지" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1482,11 +1890,120 @@ "state" : "translated", "value" : "Phát hiện" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "偵測" + } } } }, "Disable Video Duration Limit" : { - + "localizations" : { + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "تعطيل حد مدة الفيديو" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videolänge limit ausschalten" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desactivar el limite de la duración de los videos" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desactivar límite de duración del video" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactiver la limite de durée de la vidéo" + } + }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactiver la limite de durée pour les vidéo" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactiver la limite de longueur de vidéo." + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videó hosszúsági limit letiltása" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "動画の長さ制限を無効にする" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "비디오 길이 제한 해제" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Beperk video­duur uitschakelen" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wyłącz limit czasu trwania wideo" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Отключить ограничение длительности видео" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "ปิดการจำกัดความยาววิดีโอ" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video süre limitini devre dışı bırak" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tắt Giới hạn Thời gian của Video" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "停用影片長度限制" + } + } + } }, "Do you want to reset collections?" : { "localizations" : { @@ -1532,6 +2049,18 @@ "value" : "Voulez-vous réinitialiser les collections?" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez vous réinstaller la collection?" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez-vous réinitialiser les collections?" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1550,6 +2079,12 @@ "value" : "コレクションをリセットしますか?" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "컬렉션을 초기화하고 싶으신가요?" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1585,6 +2120,12 @@ "state" : "translated", "value" : "Bạn có muốn thiết lập lại các bộ sưu tập?" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您要重設收藏嗎?" + } } } }, @@ -1632,6 +2173,18 @@ "value" : "Télécharger le raccourci de secours" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger les avis du raccourci" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger raccourci de secours" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1650,6 +2203,12 @@ "value" : "フォールバックショートカットをダウンロード" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fallback 단축어 다운로드" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1685,6 +2244,12 @@ "state" : "translated", "value" : "Tải xuống Phím tắt dự phòng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "下載備用捷徑" + } } } }, @@ -1738,6 +2303,18 @@ "value" : "Télécharger un fichier de Tendies" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger fichier tendies" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Télécharger le fichier Tendies " + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1756,6 +2333,12 @@ "value" : "Tendiesファイルをダウンロード" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies 파일 다운로드" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1791,6 +2374,12 @@ "state" : "translated", "value" : "Tải xuống tệp tendies" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "下載 Tendies 檔案" + } } } }, @@ -1844,6 +2433,18 @@ "value" : "Téléchargement" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Téléchargement" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Téléchargement" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -1862,6 +2463,12 @@ "value" : "ダウンロード中" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "다운로드 중" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -1897,6 +2504,12 @@ "state" : "translated", "value" : "Đang Tải xuống" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在下載" + } } } }, @@ -1908,6 +2521,12 @@ "value" : "استمتع!" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "استمتع!" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -1938,12 +2557,42 @@ "value" : "Jouir!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apprécier!" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Profitez!" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Élvezd!" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "お楽しみください!" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "즐기세요!" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geniet!" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -1973,6 +2622,12 @@ "state" : "translated", "value" : "Hãy thưởng thức!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "請享用!" + } } } }, @@ -2020,6 +2675,18 @@ "value" : "Saisir le App Hash" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entrer app hash" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entrer le hach d'application " + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2038,6 +2705,12 @@ "value" : "アプリハッシュを入力" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Hash 입력" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2073,6 +2746,12 @@ "state" : "translated", "value" : "Nhập mã định danh Ứng dụng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "輸入應用程式雜湊值" + } } } }, @@ -2120,6 +2799,18 @@ "value" : "Entrez votre app hash de PosterBoard dans les Paramètres." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saisissez le hachage de votre application PosterBoard dans Paramètres." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Entrer votre hach de l'application PosterBoard dans les paramètres." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2138,6 +2829,12 @@ "value" : "設定でPosterBoardアプリのハッシュを入力してください。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard App Hash를 설정에서 입력하세요." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2173,6 +2870,12 @@ "state" : "translated", "value" : "Nhập mã định danh của PosterBoard trong Cài đặt." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "在設定中輸入您的 PosterBoard 應用程式雜湊值。" + } } } }, @@ -2226,6 +2929,18 @@ "value" : "Erreur" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreurs" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2244,6 +2959,12 @@ "value" : "エラー" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "오류" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2279,6 +3000,12 @@ "state" : "translated", "value" : "Lỗi" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "錯誤" + } } } }, @@ -2332,6 +3059,18 @@ "value" : "Exploitation" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploit" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Exploiter" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2350,6 +3089,12 @@ "value" : "Exploit" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "취약점 이용" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2385,6 +3130,12 @@ "state" : "translated", "value" : "Khai thác" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "利用程式漏洞" + } } } }, @@ -2439,6 +3190,18 @@ "value" : "L'extraction des tendies..." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extractions tendies" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extraction des tendies..." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2457,6 +3220,12 @@ "value" : "Tendiesを解凍中…" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "tendies 추출 중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2492,6 +3261,12 @@ "state" : "translated", "value" : "Đang giải nén tendies..." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在解壓 tendies…" + } } } }, @@ -2545,6 +3320,18 @@ "value" : "Échec" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2563,6 +3350,12 @@ "value" : "失敗" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "실패함" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2598,6 +3391,12 @@ "state" : "translated", "value" : "Thất bại" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "失敗" + } } } }, @@ -2651,6 +3450,18 @@ "value" : "N'a pas réussi à importer les tendies" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de l'importation de tendies" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Importation des tendies échouée." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2669,6 +3480,12 @@ "value" : "Tendiesのインポートに失敗しました" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "tendies 가져오기에 실패했습니다" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2704,23 +3521,101 @@ "state" : "translated", "value" : "Nhập tendies thất bại" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "匯入 tendies 失敗" + } } } }, "Failed to Import Video" : { "localizations" : { + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل في استيراد الفيديو" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Videoimport fehlgeschlagen" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error al importar video" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se pudo importar el video" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de l'importation de la vidéo" + } + }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossible d importer la vidéo" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec lors de l'importation de la vidéo." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Videó importálása sikertelen" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "動画のインポートに失敗しました" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "비디오 가져오기에 실패했습니다" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video importeren mislukt" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nie udało sie zaimportować filmu" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Ошибка при импорте видео" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "นำเข้าวิดีโอไม่สำเร็จ" + } + }, "tr" : { "stringUnit" : { "state" : "translated", @@ -2732,6 +3627,12 @@ "state" : "translated", "value" : "Nhập Video bị lỗi" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "匯入影片失敗" + } } } }, @@ -2785,6 +3686,18 @@ "value" : "Créateur de raccourcis de secours" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avis Creteur du raccourcis" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Création de raccourci de secours" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2803,6 +3716,12 @@ "value" : "フォールバックショートカット作成者" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "예비 단축어 생성기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2838,6 +3757,12 @@ "state" : "translated", "value" : "Bộ tạo Phím tắt dự phòng" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "備用捷徑建立器" + } } } }, @@ -2885,6 +3810,18 @@ "value" : "Retomber dans le raccourci" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Revenir au raccourci" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Revenir au raccourci" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -2903,6 +3840,12 @@ "value" : "ショートカットに戻る" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "예비 단축어로 전환 중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -2938,6 +3881,12 @@ "state" : "translated", "value" : "Quay lại Phím tắt" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在切換至備用捷徑" + } } } }, @@ -2949,6 +3898,12 @@ "value" : "العثور على خلفيات للجهاز" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "ابحث عن الخلفيات" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -2979,12 +3934,42 @@ "value" : "Trouver des fonds d'écran" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trouver des fond d’écran" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Trouver des fonds d'écran " + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Háttérképek találása" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "壁紙を探す" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "배경화면 찾기" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Achtergronden zoeken" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3014,6 +3999,12 @@ "state" : "translated", "value" : "Tìm kiếm Hình nền" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "尋找壁紙" + } } } }, @@ -3067,6 +4058,18 @@ "value" : "Finir" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finit" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Finir" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3085,6 +4088,12 @@ "value" : "終了" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3120,6 +4129,12 @@ "state" : "translated", "value" : "Hoàn thành" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成" + } } } }, @@ -3173,6 +4188,18 @@ "value" : "Générer des vidéos..." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generation de video" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Génération de la vidéo..." + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3191,6 +4218,12 @@ "value" : "動画を生成中…" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "비디오 생성 중..." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3226,6 +4259,12 @@ "state" : "translated", "value" : "Đang tạo video..." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在產生影片…" + } } } }, @@ -3237,6 +4276,12 @@ "value" : "الحصول على الاختصار" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "احصل على الاختصار" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -3267,12 +4312,42 @@ "value" : "Obtenir un raccourci" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Obtenez le raccourci" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Obtenir raccourci" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Shortcut letöltése" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ショートカットを取得" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "단축어 받기" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Snelkoppeling ophalen" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3302,6 +4377,12 @@ "state" : "translated", "value" : "Tải xuống Phím tắt" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "取得捷徑" + } } } }, @@ -3313,12 +4394,24 @@ "value" : "هذا دليل تعليمي لمساعدتك على البدء بإستخدام التطبيق." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "هذا دليل لمساعدتك على بدء استخدام التطبيق." + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", "value" : "إليك دليل تعليمي لمساعدتك على البدء باستخدام التطبيق." } }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hier ist ein Tutorial, um Ihnen mit der App zu helfen." + } + }, "es" : { "stringUnit" : { "state" : "translated", @@ -3337,12 +4430,42 @@ "value" : "Voici un tutoriel pour vous aider à démarrer avec l'application." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voici un tutoriel pour vous aider à démarrer avec l'application." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voici un tutoriel qui vous aidera à utiliser cette application" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Íme egy oktatóanyag, amely segít az alkalmazás használatának megkezdésében." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリの使い方を説明するチュートリアルはこちらです。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 사용을 시작하는 데 도움이 되는 튜토리얼입니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hier is een handleiding om je op weg te helpen met de app." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3372,6 +4495,12 @@ "state" : "translated", "value" : "Đây là hướng dẫn trước khi bạn bắt đầu sử dụng ứng dụng này." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "以下是幫助您開始使用本應用程式的教學。" + } } } }, @@ -3425,6 +4554,18 @@ "value" : "Accueil" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Maison" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Accueil" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3443,6 +4584,12 @@ "value" : "ホーム" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "홈" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3478,6 +4625,12 @@ "state" : "translated", "value" : "Trang chủ" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "首頁" + } } } }, @@ -3489,6 +4642,12 @@ "value" : "تحميل Nugget" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "ثبّت Nugget" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -3519,12 +4678,42 @@ "value" : "Installer Nugget" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer nugget" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer Nugget" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Nugget telepítése" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget をインストール" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget 설치" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget installeren" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -3554,6 +4743,12 @@ "state" : "translated", "value" : "Tải xuống Nugget" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "安裝 Nugget" + } } } }, @@ -3565,6 +4760,12 @@ "value" : "تحميل الاختصار البديل ( اختياري )" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "ثبّت الاختصار الاحتياطي (اختياري)" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -3595,10 +4796,40 @@ "value" : "Installer le raccourci de repli (optionnel)" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer le raccourci de secours (facultatif)" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer le raccourci de secours (optionnel)" + } + }, "hu" : { "stringUnit" : { "state" : "translated", - "value" : "Tartalék parancs telepítése" + "value" : "Tartalék parancs telepítése (Opcionális)" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "代替ショートカットをインストール(任意)" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "예비 단축어 설치 (선택 사항)" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reserve-snelkoppeling installeren (optioneel)" } }, "pl" : { @@ -3630,6 +4861,12 @@ "state" : "translated", "value" : "Cài đặt Phím tắt Dự phòng (Thích thì tải)" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "安裝備用捷徑(選用)" + } } } }, @@ -3683,6 +4920,18 @@ "value" : "Rejoindre le Discord" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rejoignez le discord" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rejoindre le Discord" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3701,6 +4950,12 @@ "value" : "Discordサーバに参加" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "디스코드 참여하기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3736,6 +4991,12 @@ "state" : "translated", "value" : "Tham gia Discord" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "加入 Discord 群組" + } } } }, @@ -3789,6 +5050,18 @@ "value" : "Liens" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Liens" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Liens" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3807,6 +5080,12 @@ "value" : "リンク" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "링크" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3842,6 +5121,12 @@ "state" : "translated", "value" : "Liên kết" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "連結" + } } } }, @@ -3896,6 +5181,18 @@ "value" : "Développeur principal" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Développeur principale" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Développeur principal " + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -3914,6 +5211,12 @@ "value" : "メイン開発者" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "주 개발자" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -3949,6 +5252,12 @@ "state" : "translated", "value" : "Nhà phát triển chính" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要開發者" + } } } }, @@ -4002,6 +5311,18 @@ "value" : "Tendies maximales atteintes" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre max de tendies atteint" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre maximal de Tendies atteint" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4020,6 +5341,12 @@ "value" : "tendiesの上限到達" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최대 Tendies에 도달함" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4055,6 +5382,12 @@ "state" : "translated", "value" : "Số lượng tendies đã đạt tối đa" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "已達到 Tendies 上限" + } } } }, @@ -4108,6 +5441,18 @@ "value" : "Suivant" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prochain" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prochain" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4126,6 +5471,12 @@ "value" : "次" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "다음" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4161,6 +5512,12 @@ "state" : "translated", "value" : "Tiếp theo" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "下一步" + } } } }, @@ -4214,6 +5571,18 @@ "value" : "Nugget GitHub" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub Nugget" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4232,6 +5601,12 @@ "value" : "Nugget GitHub" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget GitHub" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4267,6 +5642,12 @@ "state" : "translated", "value" : "Nugget GitHub" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget 的 GitHub" + } } } }, @@ -4314,6 +5695,18 @@ "value" : "OK" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ok" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4332,6 +5725,12 @@ "value" : "OK" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "확인" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4367,6 +5766,12 @@ "state" : "translated", "value" : "OK" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "確定" + } } } }, @@ -4378,6 +5783,12 @@ "value" : "على حاسوبك، قم بتحميل Nugget من GitHub." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "على جهاز الكمبيوتر، قم بتنزيل Nugget من GitHub." + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -4408,12 +5819,42 @@ "value" : "Sur votre ordinateur, téléchargez Nugget depuis GitHub." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sur votre ordinateur, télécharger nugget depuis le GitHub" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sur votre ordinateur, téléchargez Nugget à partir du GitHub" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "A számítógépeden, töltsd le a Nuggetet a GitHubról." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パソコンで GitHub から Nugget をダウンロードしてください。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "컴퓨터에서 GitHub에서 Nugget을 다운로드하세요." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Download Nugget op je computer vanaf GitHub." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -4443,6 +5884,12 @@ "state" : "translated", "value" : "Tải về Nugget trên máy tính từ Github." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "請在您的電腦上從 GitHub 下載 Nugget。" + } } } }, @@ -4496,6 +5943,18 @@ "value" : "Seuls les fichiers .tendies peuvent être téléchargés!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seulement les fichiers .tendies ne peut être télécharger!" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seulement des fichiers .tendies peuvent être téléchargés!" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4514,6 +5973,12 @@ "value" : "tendiesファイルのみダウンロードできます" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : ".tendies 파일만 다운로드할 수 있습니다!" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4549,6 +6014,12 @@ "state" : "translated", "value" : "Chỉ có thể tải xuống các tập tin .tendies!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "只能下載 .tendies 檔案!" + } } } }, @@ -4560,6 +6031,12 @@ "value" : "فتح GitHub" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "افتح GitHub" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -4590,12 +6067,42 @@ "value" : "Ouvrir GitHub" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ouvrir GitHub" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ouvrir GitHub" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "GitHub megnyitésa" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub を開く" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub 열기" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub openen" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -4625,6 +6132,12 @@ "state" : "translated", "value" : "Mở Github" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開啟 GitHub" + } } } }, @@ -4678,6 +6191,18 @@ "value" : "Veuillez patienter" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Attendez s’il vous plaît" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Veuillez patienter" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4696,6 +6221,12 @@ "value" : "お待ちください" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "잠시만 기다려주세요" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4731,6 +6262,12 @@ "state" : "translated", "value" : "Vui lòng chờ" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "請稍候" + } } } }, @@ -4784,6 +6321,18 @@ "value" : "Pocket Poster" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket poster" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "fr-CH" : { "stringUnit" : { "state" : "translated", @@ -4802,6 +6351,12 @@ "value" : "Pocket Poster" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4837,6 +6392,12 @@ "state" : "translated", "value" : "Pocket Poster" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } } } }, @@ -4884,6 +6445,18 @@ "value" : "PosterBoard n'a pas pu s'ouvrir directement. Le raccourci de secours sera maintenant ouvert." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard ne s'est pas ouvert directement. Le raccourci de secours sera maintenant ouvert." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard a échoué d'ouvrir directement. Le raccourci de secours sera lancé." + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -4896,6 +6469,12 @@ "value" : "PosterBoardが直接開くことができませんでした。フォールバックショートカットが開きます。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard를 직접 열 수 없습니다. 예비 단축어가 대신 열립니다." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -4931,11 +6510,120 @@ "state" : "translated", "value" : "PosterBoard không thể mở trực tiếp. Phím tắt dự phòng bây giờ sẽ được mở." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "無法直接開啟 PosterBoard。將改為開啟備用捷徑。" + } } } }, "Preferences" : { - + "localizations" : { + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "التفضيلات" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Präferenzen" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferencias" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferencias" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Préférences" + } + }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Préférence" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Préférences" + } + }, + "hu" : { + "stringUnit" : { + "state" : "translated", + "value" : "Beállítások" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "환경설정" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voorkeuren" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferencje" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Настройки" + } + }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "การตั้งค่า" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tercihler" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tùy chọn" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏好設定" + } + } + } }, "Release" : { "localizations" : { @@ -4987,6 +6675,18 @@ "value" : "Libération" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sortie" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -4999,6 +6699,12 @@ "value" : "リリース" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "릴리스" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5034,6 +6740,12 @@ "state" : "translated", "value" : "Phát hành" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "釋出" + } } } }, @@ -5087,6 +6799,18 @@ "value" : "Répéter le tutoriel" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rejouer le tutoriel" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Revoir le tutoriel" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5099,6 +6823,12 @@ "value" : "チュートリアルを再生" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "튜토리얼 다시 보기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5134,6 +6864,12 @@ "state" : "translated", "value" : "Xem lại Hướng dẫn" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "重播教學" + } } } }, @@ -5181,6 +6917,18 @@ "value" : "Réinitialiser les Collections" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialiser la collections" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialiser collections" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5193,6 +6941,12 @@ "value" : "コレクションをリセット" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "컬렉션 초기화" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5228,6 +6982,12 @@ "state" : "translated", "value" : "Đặt lại Bộ sưu tập" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "重設收藏" + } } } }, @@ -5281,6 +7041,18 @@ "value" : "Sélectionner Tendies" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sélectionner Tendis" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sélectionner Tendies" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5293,6 +7065,12 @@ "value" : "Tendiesを選択" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies 선택" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5328,6 +7106,12 @@ "state" : "translated", "value" : "Chọn Tendies" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇 Tendies" + } } } }, @@ -5381,6 +7165,18 @@ "value" : "Tendies sélectionnées" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sélectionner Tendies" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tendies sélectionnés" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5393,6 +7189,12 @@ "value" : "選択されたTendies" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "선택된 Tendies" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5428,6 +7230,12 @@ "state" : "translated", "value" : "Đã chọn Tendies" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "已選擇的 Tendies" + } } } }, @@ -5481,6 +7289,18 @@ "value" : "Sauter" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Passer" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Passer" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5493,6 +7313,12 @@ "value" : "スキップ" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "건너뛰기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5528,6 +7354,12 @@ "state" : "translated", "value" : "Bỏ qua" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳過" + } } } }, @@ -5581,6 +7413,18 @@ "value" : "Sociales" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sociales" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Médias sociaux" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5593,6 +7437,12 @@ "value" : "ソーシャル" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "소셜 미디어" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5628,6 +7478,12 @@ "state" : "translated", "value" : "Mạng Xã hội" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "社群媒體" + } } } }, @@ -5681,6 +7537,18 @@ "value" : "Succès!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succès!" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succès!" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5693,6 +7561,12 @@ "value" : "成功" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "성공!" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5728,6 +7602,12 @@ "state" : "translated", "value" : "Thành công!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "成功!" + } } } }, @@ -5781,6 +7661,18 @@ "value" : "Importation réussie %@" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Importé avec succès" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Importation de %@ succédée" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5793,6 +7685,12 @@ "value" : "%@ のインポートに成功" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 가져오기에 성공했습니다" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5828,6 +7726,12 @@ "state" : "translated", "value" : "Nhập thành công %@" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "成功匯入 %@" + } } } }, @@ -5881,6 +7785,18 @@ "value" : "Support sur Ko-Fi" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Support sur Ko-Fi" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Supporter sur Ko-Fi" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5893,6 +7809,12 @@ "value" : "Ko-Fiでサポート" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ko-Fi에서 후원하기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -5928,6 +7850,12 @@ "state" : "translated", "value" : "Hỗ trợ trên Ko-Fi" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "在 Ko-Fi 上支持我們" + } } } }, @@ -5975,6 +7903,18 @@ "value" : "Le dossier est mal configuré. Appuyez sur \"Réinitialiser les Collections\" et réessayez." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le dossier est mal configuré. Veuillez appuyer sur \"Réinitialiser les collections\" et réessayer." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le dossier est mal installé. Veuillez cliquer sur \"réinitialiser collections\" et réessayer." + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -5987,6 +7927,12 @@ "value" : "フォルダが正しく設定されていません。「コレクションをリセット」をタップして、もう一度やり直してください。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "폴더 설정이 올바르지 않습니다. \"컬렉션 초기화\"를 누른 후 다시 시도해주세요." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6022,6 +7968,12 @@ "state" : "translated", "value" : "Thư mục được thiết lập không đúng cách. Nhấn vào \"Đặt lại Bộ sưu tập\" và thử lại." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "資料夾設置不正確。請點選「重設收藏」後再試一次。" + } } } }, @@ -6075,6 +8027,18 @@ "value" : "L'application PosterBoard est maintenant ouverte. Veuillez la fermer à partir du sélecteur d'applications." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'application PosterBoard s'ouvrira maintenant. Veuillez le fermer à partir du commutateur d'application." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'appli PosterBoard sera maintenant lancé. Veuillez le fermer a partir du sélecteur d'applications." + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6087,6 +8051,12 @@ "value" : "PosterBoardアプリが開きます。アプリスイッチャーから閉じてください。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard 앱이 열립니다. 앱 전환기에서 닫아주세요." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6122,23 +8092,101 @@ "state" : "translated", "value" : "Ứng dụng PosterBoard đã được mở. Hãy đóng nó trong đa nhiệm." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard 應用程式將立即開啟。請從應用程式切換器中將其關閉。" + } } } }, "The video you imported is too long! Your video must be %@ seconds or less." : { "localizations" : { + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "الفيديو الذي قمت باستيراده طويل جدًا! يجب أن يكون الفيديو %@ ثانية أو أقل." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Video, das sie importiert haben, ist zu lang! Ihr Video muss %@ Sekunden oder kürzer sein." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "El video que importaste es demasiado largo! Tu video debe tener %@ segundos o menos" + } + }, + "es-MX" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡El video importado es muy largo! Tu video debe durar %@ segundos o menos." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La vidéo que vous avez importée est trop longue! Votre vidéo doit être de %@ secondes ou moins." + } + }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "La vidéo que vous avez importer es trop longue! Votre vidéo doit être de de 10 secondes ou moins." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "La vidéo que vous avez sélectionné est trop long! Votre vidéo doit être de %@ secondes ou moins." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Az importált videó túl hosszú! A videó hossza legfeljebb %@ másodperc lehet." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "インポートした動画が長すぎます!動画は%@秒以内である必要があります。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "가져온 비디오가 너무 깁니다! %@초 이하의 비디오만 허용됩니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "De geïmporteerde video is te lang! De video mag maximaal %@ seconden duren." + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Film który zaimportowałeś jest za długi! Film musi mieć %@ sekund lub mniej." + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Ваше видео слишком длинное! Оно должно быть не больше %@ секунд" } }, + "th" : { + "stringUnit" : { + "state" : "translated", + "value" : "วิดีโอที่จะนำเข้ายาวเกิน! วิดีโอต้องสั้นกว่า %@ วินาที" + } + }, "tr" : { "stringUnit" : { "state" : "translated", @@ -6150,6 +8198,12 @@ "state" : "translated", "value" : "Bạn nhập video dài quá! Video của bạn cần phải ít hơn hoặc vừa đủ %@ giây." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您匯入的影片太長!影片長度必須在 %@ 秒以內。" + } } } }, @@ -6161,6 +8215,12 @@ "value" : "لتطبيق التغييرات، سنحتاج لفتح تطبيق PosterBoard." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "لتطبيق ذلك، يجب فتح PosterBoard." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -6185,12 +8245,42 @@ "value" : "Pour l'appliquer, PosterBoard doit être ouvert." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour appliquer, PosterBoard doit être ouvert" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour appliquer, PosterBoard devra ouvrir." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Az alkalmazáshoz a PosterBoardnak meg kell nyílnia." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "適用するには PosterBoard を開く必要があります。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "적용하려면 PosterBoard가 열려야 합니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Om toe te passen, moet PosterBoard worden geopend." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6220,6 +8310,12 @@ "state" : "translated", "value" : "Để áp dụng, PosterBoard sẽ cần phải được mở." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "若要套用,必須開啟 PosterBoard。" + } } } }, @@ -6231,6 +8327,12 @@ "value" : "للحصول على معرّف bundle id الخاص بالتطبيق، تطبيق Nugget ضروري." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "للحصول على مُعرّف حزمة التطبيق، يجب تثبيت Nugget." + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -6261,12 +8363,42 @@ "value" : "Pour obtenir l'identifiant du bundle d'application, Nugget est nécessaire." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour obtenir l'identifiant du bundle de l'application, Nugget est nécessaire." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour récupérer le Bundle ID de l'application, Nugget est requis." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Nuggetre van szükség az App Bundle id megszerzéséhez." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリのバンドルIDを取得するには Nugget が必要です。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 번들 ID를 가져오려면 Nugget이 필요합니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Om de bundle-id van de app te verkrijgen, is Nugget vereist." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6296,6 +8428,12 @@ "state" : "translated", "value" : "Để lấy ID gói của ứng dụng, bạn cần phải sử dụng Nugget." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "若要取得應用程式的 bundle ID,需安裝 Nugget。" + } } } }, @@ -6355,6 +8493,18 @@ "value" : "Version %1$@ (%2$@)" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version 1" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version %1$@ (%2$@)" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6367,6 +8517,12 @@ "value" : "バージョン %1$@ (%2$@)" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "버전 %1$@ (%2$@)" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6402,6 +8558,12 @@ "state" : "translated", "value" : "Phiên bản %1@ (%2$@)" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "版本 %1$@(%2$@)" + } } } }, @@ -6449,6 +8611,18 @@ "value" : "Vidéos" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vidéos" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vidéos" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6461,6 +8635,12 @@ "value" : "動画" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "비디오" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6496,6 +8676,12 @@ "state" : "translated", "value" : "Videos" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "影片" + } } } }, @@ -6543,6 +8729,18 @@ "value" : "Voir sur GitHub" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Regarder sur GitHub" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voir sur GitHub" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6555,6 +8753,12 @@ "value" : "GitHubで見る" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "GitHub에서 보기" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6590,6 +8794,12 @@ "state" : "translated", "value" : "Xem trên Github" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "在 GitHub 上查看" + } } } }, @@ -6643,6 +8853,18 @@ "value" : "Concepteur de site web" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Designer du site" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Designer de site" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6655,6 +8877,12 @@ "value" : "ウェブサイトデザイナー" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "웹사이트 디자이너" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6690,6 +8918,12 @@ "state" : "translated", "value" : "Nhà thiết kế Website" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "網站設計師" + } } } }, @@ -6701,6 +8935,12 @@ "value" : "مرحباً ب Pocket Poster!" } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "مرحبًا بك في Pocket Poster!" + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -6731,12 +8971,42 @@ "value" : "Bienvenue à Pocket Poster!" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bienvenu sur pocket poster!" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bienvenue à Pocket Poster" + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Üdvözlünk a Pocket Poster-be!" } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster へようこそ!" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster에 오신 것을 환영합니다!" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Welkom bij Pocket Poster!" + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6766,6 +9036,12 @@ "state" : "translated", "value" : "Chào mừng đến với Pocket Poster!" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "歡迎使用 Pocket Poster!" + } } } }, @@ -6813,6 +9089,18 @@ "value" : "Voulez-vous télécharger le fichier %@?" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez vous télécharger le fichier" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voulez-vous télécharger le fichier %@?" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -6825,6 +9113,12 @@ "value" : "%@ファイルをダウンロードしますか?" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ 파일을 다운로드하시겠습니까?" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -6860,6 +9154,12 @@ "state" : "translated", "value" : "Bạn có muốn tải xuống tệp %@ không?" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您要下載檔案 %@ 嗎?" + } } } }, @@ -6871,6 +9171,12 @@ "value" : "يمكنك العثور على موقع Cowabun.ga الرسمي." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك العثور على الخلفيات في موقع Cowabun.ga الرسمي." + } + }, "ar-SA" : { "stringUnit" : { "state" : "translated", @@ -6901,12 +9207,42 @@ "value" : "Vous pouvez trouver des fonds d'écran sur le site officiel de Cowabun.ga." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez trouver des fond écran sur le site officiel Cowabung.ga" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez trouver des fonds d'écran sur le site officiel Cowabun.ga." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Háttérképeket a hivatalos Cowabun.ga weboldalon találhatsz." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "公式の Cowabun.ga サイトで壁紙を見つけることができます。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "공식 Cowabun.ga 웹사이트에서 배경화면을 찾을 수 있습니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Je kunt achtergronden vinden op de officiële Cowabun.ga website." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -6936,6 +9272,12 @@ "state" : "translated", "value" : "Bạn có thể tìm kiếm các hình nền trên trang web Cowabun.ga." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您可以在 Cowabun.ga 官方網站上找到壁紙。" + } } } }, @@ -6947,6 +9289,12 @@ "value" : "يمكنك تحميل اختصار اختياري اذا فشلت الطريقة الاساسية." } }, + "ar-AE" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك تثبيت اختصار اختياري إذا فشلت الطريقة الأصلية." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -6971,12 +9319,42 @@ "value" : "Vous pouvez installer un raccourci facultatif si la méthode originale échoue." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez installer un raccourci optionnel si la méthode original ne fonctionne pas." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez installer un raccourci optionnel si la méthode originelle échoue." + } + }, "hu" : { "stringUnit" : { "state" : "translated", "value" : "Telepíthetsz egy opcionális parancsot, ha az eredeti módszer nem működik." } }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : " 元の方法がうまくいかない場合は、オプションのショートカットをインストールできます。" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "원래 방법이 실패하면 선택적 단축어를 설치할 수 있습니다." + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Je kunt een optionele snelkoppeling installeren als de oorspronkelijke methode faalt." + } + }, "pl" : { "stringUnit" : { "state" : "translated", @@ -7006,6 +9384,12 @@ "state" : "translated", "value" : "Bạn có thể tải xuống Phím tắt Dự phòng nếu cách làm bình thường bị lỗi." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "如果原始方法失敗,您可以安裝選用的捷徑。" + } } } }, @@ -7053,6 +9437,18 @@ "value" : "Vous ne pouvez appliquer que des descripteurs %@." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "You pouvez seulement appliquer 10 descriptions." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez que appliquer des descripteurs %@." + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -7065,6 +9461,12 @@ "value" : "%@ 記述子のみ適用できます。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@개의 설명자만 적용할 수 있습니다." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -7100,6 +9502,12 @@ "state" : "translated", "value" : "Bạn chỉ có thể áp dụng %@ mô tả." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您只能套用 %@ 個描述項。" + } } } }, @@ -7147,10 +9555,22 @@ "value" : "Votre App Hash est incorrect. Veuillez le redéfinir." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le hachage de votre application est incorrect. Veuillez le régler à nouveau." + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre hach d'application est incorrect. Veuillez le régler de nouveau." + } + }, "hu" : { "stringUnit" : { "state" : "translated", - "value" : "Az App hashed helytelen. Kérlek állítsd be újra" + "value" : "Az App hashed helytelen. Kérlek állítsd be újra." } }, "ja" : { @@ -7159,6 +9579,12 @@ "value" : "アプリのハッシュが正しくありません。もう一度設定してください。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 해시가 올바르지 않습니다. 다시 설정해주세요." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -7194,6 +9620,12 @@ "state" : "translated", "value" : "Mã định danh Ứng dụng chưa chính xác. Vui lòng đặt lại." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的應用程式雜湊值不正確。請重新設定。" + } } } }, @@ -7241,6 +9673,18 @@ "value" : "Votre PosterBoard se rafraîchit automatiquement." } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre PosterBoard mettra jour automatiquement" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre PosterBoard sera rafraîchi automatiquement." + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -7253,6 +9697,12 @@ "value" : "PosterBoardは自動的に更新されます。" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "PosterBoard가 자동으로 새로고침됩니다." + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -7288,6 +9738,12 @@ "state" : "translated", "value" : "PosterBoard sẽ được tự động làm mới." } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "您的 PosterBoard 將會自動重新整理。" + } } } } diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index 16409c1..cc70cc5 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -59,6 +59,18 @@ "value" : "Pocket Poster" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -71,6 +83,12 @@ "value" : "Pocket Poster" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -106,6 +124,12 @@ "state" : "translated", "value" : "Pocket Poster" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pocket Poster" + } } } }, @@ -153,6 +177,18 @@ "value" : "Fond d'écran Nugget" } }, + "fr-BE" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fond écran nugget" + } + }, + "fr-CA" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fond d'écran Nugget" + } + }, "hu" : { "stringUnit" : { "state" : "translated", @@ -165,6 +201,12 @@ "value" : "Nugget Wallpaper" } }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget 배경화면" + } + }, "nl" : { "stringUnit" : { "state" : "translated", @@ -200,6 +242,12 @@ "state" : "translated", "value" : "Hình nền Nugget" } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nugget 壁紙" + } } } } From fe1911a5cd530600dad93bd56fd684c02e6b7c8b Mon Sep 17 00:00:00 2001 From: leminlimez <59540996+leminlimez@users.noreply.github.com> Date: Sun, 22 Jun 2025 17:03:21 -0400 Subject: [PATCH 33/35] update languages ar, ar-SA, cs, fr-CA --- Pocket Poster/Localizable.xcstrings | 218 +++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index fec8c30..44cbd6e 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -275,6 +275,12 @@ "value" : "مفتاح الهاش للتطبيق" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "هاش البرنامج" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -919,6 +925,12 @@ "value" : "تم إعادة تعيين المجموعات بنجاح!" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تمت إعادة تعيين المجموعات بنجاح!" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -1037,6 +1049,12 @@ "value" : "مترجمو المجتمع" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Komunitní Překladatelé" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1279,6 +1297,12 @@ "value" : "إنشاء طريقة بديلة إضافية" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إنشاء طريقة Fallback إضافية" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -1535,6 +1559,12 @@ "value" : "إنشاء معلومات CAML..." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "جارٍ إنشاء بيانات CAML..." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -1659,6 +1689,12 @@ "value" : "الاعتمادات" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "المساهمون" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -1907,6 +1943,12 @@ "value" : "تعطيل حد مدة الفيديو" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vypnout Omezení Délky Videa" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -2019,6 +2061,12 @@ "value" : "هل ترغب في إعادة ضبط المجموعات؟" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل ترغب في إعادة تعيين المجموعات؟" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -2143,6 +2191,12 @@ "value" : "تحميل اختصار البديل" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "حمل اختصار Fallback" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -2533,6 +2587,12 @@ "value" : "استمتع!" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Užívejte!" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -2645,6 +2705,12 @@ "value" : "أدخل الهاش" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادخل هاش البرنامج" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -2769,6 +2835,12 @@ "value" : "أدخل الهاش لتطبيق PosterBoard في الإعدادات." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "ادخل هاش البرنامج من الاعدادات" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -3538,6 +3610,12 @@ "value" : "فشل في استيراد الفيديو" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Import Videa Selhal" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -3780,6 +3858,12 @@ "value" : "الرجوع إلى الاختصار" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "يتم استخدام الاختصار" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -3910,6 +3994,12 @@ "value" : "ابحث عن الخلفيات" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Najít Tapety" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -4288,6 +4378,12 @@ "value" : "احصل على الأختصار" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Získat Zkratku" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -4406,6 +4502,12 @@ "value" : "إليك دليل تعليمي لمساعدتك على البدء باستخدام التطبيق." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zde je návod, který vám pomůže s aplikací začít." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -4654,6 +4756,12 @@ "value" : "نزل Nuggrt" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nainstalovat Nugget" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -4772,6 +4880,12 @@ "value" : "تثبيت اختصار fallback (اختياري)" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nainstalovat Záložní Zkratku (Volitelné)" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -5190,7 +5304,7 @@ "fr-CA" : { "stringUnit" : { "state" : "translated", - "value" : "Développeur principal " + "value" : "Développeur principal" } }, "fr-CH" : { @@ -5665,6 +5779,12 @@ "value" : "حسنا" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "أوك" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -5795,6 +5915,12 @@ "value" : "قم بتنزيل Nugget على جهاز الكمبيوتر الخاص بك من GitHub." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Na počítači si z GitHubu stáhněte Nugget." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -6043,6 +6169,12 @@ "value" : "افتح على GitHub" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Otevřít GitHub" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -6415,6 +6547,12 @@ "value" : "فشل PosterBoard في الفتح بشكل مباشر. سيتم فتح الاختصار البديل الآن." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل فتح PosterBoard مباشرةً. سيتم الآن فتح الاختصار fallback." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -6527,6 +6665,12 @@ "value" : "التفضيلات" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Předvolby" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -6887,6 +7031,12 @@ "value" : "إعادة تعيين المجموعات" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "إعادة تعيين المجموعات" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -7873,6 +8023,12 @@ "value" : "المجلد غير مهيأ بشكل صحيح. يرجى الضغط على \"إعادة تعيين المجموعات\" واعادة المحاولة." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "المجلد مُعد بشكل غير صحيح. يرجى الضغط على \"إعادة تعيين المجموعات\" وحاول مرة أخرى." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -8109,6 +8265,12 @@ "value" : "الفيديو الذي قمت باستيراده طويل جدًا! يجب أن يكون الفيديو %@ ثانية أو أقل." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Video které jste importovali je příliš dlouhé! Musí mít %@ sekund nebo méně." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -8221,6 +8383,12 @@ "value" : "لتطبيق ذلك، يجب فتح PosterBoard." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pro aplikování se bude muset otevřít PosterBoard" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -8339,6 +8507,12 @@ "value" : "للحصول على معرف حزمة التطبيق، يلزم استخدام Nugget." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pro získání ID balíčku aplikace je potřeba Nugget." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -8581,6 +8755,12 @@ "value" : "الفديوهات" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فيديو" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -8699,6 +8879,12 @@ "value" : "عرض على GitHub" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "انظر على Github" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -8947,6 +9133,12 @@ "value" : "مرحبا الى Pocket Poster!" } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vítejte v Pocket Posteru!" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -9059,6 +9251,12 @@ "value" : "هل تريد تحميل الملف %@؟" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "هل ترغب في تنزيل الملف %@؟" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -9183,6 +9381,12 @@ "value" : "يمكنك العثور على الخلفيات على الموقع الرسمي Cowabun.ga." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tapety můžete najít na oficiálních stránkách Cowagun.ga." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -9295,6 +9499,12 @@ "value" : "يمكنك تثبيت اختصار اختياري إذا فشلت الطريقة الأصلية." } }, + "cs" : { + "stringUnit" : { + "state" : "translated", + "value" : "Můžete nainstalovat volitelnou zkratku když původní metoda selže." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -9525,6 +9735,12 @@ "value" : "الهاش الخاص بالتطبيق غير صحيح. يرجى إعادة الإعداد." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "هاش البرنامج غير صحيح. يرجى إعادة تعيينه." + } + }, "cs" : { "stringUnit" : { "state" : "translated", From 013743cd5ca6fe55f31d1299a83e91b81419c7f6 Mon Sep 17 00:00:00 2001 From: leminlimez Date: Mon, 23 Jun 2025 13:19:59 -0400 Subject: [PATCH 34/35] update ar, ar-SA --- Pocket Poster.xcodeproj/project.pbxproj | 4 +- Pocket Poster/Localizable.xcstrings | 88 ++++++++++++++++++- .../Pocket-Poster-InfoPlist.xcstrings | 6 ++ 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/Pocket Poster.xcodeproj/project.pbxproj b/Pocket Poster.xcodeproj/project.pbxproj index 5b0f8ad..d76fbe4 100644 --- a/Pocket Poster.xcodeproj/project.pbxproj +++ b/Pocket Poster.xcodeproj/project.pbxproj @@ -264,7 +264,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 0; DEVELOPMENT_ASSET_PATHS = "\"Pocket Poster/Preview Content\""; DEVELOPMENT_TEAM = 2P4CP47H76; ENABLE_PREVIEWS = YES; diff --git a/Pocket Poster/Localizable.xcstrings b/Pocket Poster/Localizable.xcstrings index 44cbd6e..cd0b104 100644 --- a/Pocket Poster/Localizable.xcstrings +++ b/Pocket Poster/Localizable.xcstrings @@ -1043,12 +1043,24 @@ }, "Community Translators" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "مترجمو المجتمع" + } + }, "ar-AE" : { "stringUnit" : { "state" : "translated", "value" : "مترجمو المجتمع" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "مجتمع المترجمين" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -1937,12 +1949,24 @@ }, "Disable Video Duration Limit" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تعطيل حد مدة الفيديو" + } + }, "ar-AE" : { "stringUnit" : { "state" : "translated", "value" : "تعطيل حد مدة الفيديو" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "تعطيل حد مدة الفيديو" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -2956,7 +2980,7 @@ "ar" : { "stringUnit" : { "state" : "translated", - "value" : "خطأ" + "value" : " خطأ" } }, "ar-AE" : { @@ -3604,12 +3628,24 @@ }, "Failed to Import Video" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل في استيراد الفيديو" + } + }, "ar-AE" : { "stringUnit" : { "state" : "translated", "value" : "فشل في استيراد الفيديو" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "فشل استيراد الفيديو" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -6290,7 +6326,7 @@ "ar-SA" : { "stringUnit" : { "state" : "translated", - "value" : "Please wait" + "value" : "يرجى الانتظار" } }, "cs" : { @@ -6659,12 +6695,24 @@ }, "Preferences" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "التفضيلات" + } + }, "ar-AE" : { "stringUnit" : { "state" : "translated", "value" : "التفضيلات" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "التفضيلات" + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -8259,12 +8307,24 @@ }, "The video you imported is too long! Your video must be %@ seconds or less." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الفيديو الذي قمتَ باستيراده طويل جداً! يجب أن يكون الفيديو %@ ثانية أو أقل." + } + }, "ar-AE" : { "stringUnit" : { "state" : "translated", "value" : "الفيديو الذي قمت باستيراده طويل جدًا! يجب أن يكون الفيديو %@ ثانية أو أقل." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "الفيديو الذي استوردته طويل جدًا! يجب أن يكون طول الفيديو %@ ثانية أو أقل." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -8383,6 +8443,12 @@ "value" : "لتطبيق ذلك، يجب فتح PosterBoard." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "لتطبيق ذلك، سيحتاج PosterBoard إلى الفتح." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -9499,6 +9565,12 @@ "value" : "يمكنك تثبيت اختصار اختياري إذا فشلت الطريقة الأصلية." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك تثبيت اختصار اختياري إذا فشلت الطريقة الأصلية." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -9617,6 +9689,12 @@ "value" : "يمكنك تطبيق %@ وصف فقط." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكنك تطبيق أوصاف %@ فقط." + } + }, "cs" : { "stringUnit" : { "state" : "translated", @@ -9859,6 +9937,12 @@ "value" : "سيتم تحديث PosterBoard الخاص بك تلقائيًا." } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "سيتم تحديث PosterBoard تلقائيًا." + } + }, "cs" : { "stringUnit" : { "state" : "translated", diff --git a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings index cc70cc5..57245f9 100644 --- a/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings +++ b/Pocket Poster/Pocket-Poster-InfoPlist.xcstrings @@ -147,6 +147,12 @@ "value" : "خلفيات Nugget" } }, + "ar-SA" : { + "stringUnit" : { + "state" : "translated", + "value" : "خلفيات Nugget" + } + }, "cs" : { "stringUnit" : { "state" : "translated", From 3801241850690aaa5193d755b85693accb73cb39 Mon Sep 17 00:00:00 2001 From: leminlimez Date: Mon, 23 Jun 2025 13:22:48 -0400 Subject: [PATCH 35/35] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1c46322..1325f8d 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,11 @@ Since there is no way to read files currently, you will need a computer to get t Download [Nugget](https://github.com/leminlimez/Nugget) on your computer and plug in your phone. Then, navigate to the `Settings` page and click the `Pocket Poster Helper` button. Inside Pocket Poster, click the `Detect` button inside of settings. ## Credits +- Translations crowdsourced using [POEditor][POEditorJoin]. Thank you everyone who assisted in the translation effort! - [PosterRestore][PosterRestoreDiscord] for their help with PosterBoard - [dootskyre][dootskyreX] for the fallback shortcut - [Nathan](https://github.com/verygenericname) and [DuyKhanhTran](https://github.com/khanhduytran0) for the exploit +[POEditorJoin]: https://poeditor.com/join/project/MPZOsunwVj [PosterRestoreDiscord]: https://discord.gg/gWtzTVhMvh [dootskyreX]: https://x.com/dootskyre