[Meta] Automatic String Organization (#1372)
* Automate String Organization. * Comment the script so it's easier to maintain? Or messier? * Linting post comments * Rename ShellScript -> Alphabetize Strings for tvOS * use swift regex, add error messages, clean up separators * Only search for ./Translations/en.lproj/Localizable.strings * Purge Unused Strings Script * Organize Translation Scripts into a Folder. Update references at the project level. * clean up --------- Co-authored-by: Ethan Pippin <ethanpippin2343@gmail.com>
This commit is contained in:
parent
a6bd093960
commit
af602d3d98
|
@ -0,0 +1,54 @@
|
||||||
|
//
|
||||||
|
// Swiftfin is subject to the terms of the Mozilla Public
|
||||||
|
// License, v2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// Get the English localization file
|
||||||
|
let fileURL = URL(fileURLWithPath: "./Translations/en.lproj/Localizable.strings")
|
||||||
|
|
||||||
|
// This regular expression pattern matches lines of the format:
|
||||||
|
// "Key" = "Value";
|
||||||
|
let regex = #/^\"(?<key>[^\"]+)\"\s*=\s*\"(?<value>[^\"]+)\";/#
|
||||||
|
|
||||||
|
// Attempt to read the file content.
|
||||||
|
guard let content = try? String(contentsOf: fileURL, encoding: .utf8) else {
|
||||||
|
print("Unable to read file: \(fileURL.path)")
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split file content by newlines to process line by line.
|
||||||
|
let strings = content.components(separatedBy: .newlines)
|
||||||
|
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||||
|
.filter { !$0.isEmpty && !$0.hasPrefix("//") }
|
||||||
|
|
||||||
|
let entries = strings.reduce(into: [String: String]()) {
|
||||||
|
if let match = $1.firstMatch(of: regex) {
|
||||||
|
let key = String(match.output.key)
|
||||||
|
let value = String(match.output.value)
|
||||||
|
$0[key] = value
|
||||||
|
} else {
|
||||||
|
print("Error: Invalid line format in \(fileURL.path): \($1)")
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the keys alphabetically for consistent ordering.
|
||||||
|
let sortedKeys = entries.keys.sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
|
||||||
|
let newContent = sortedKeys.map { "/// \(entries[$0]!)\n\"\($0)\" = \"\(entries[$0]!)\";" }.joined(separator: "\n\n")
|
||||||
|
|
||||||
|
// Write the updated, sorted, and commented localizations back to the file.
|
||||||
|
do {
|
||||||
|
try newContent.write(to: fileURL, atomically: true, encoding: .utf8)
|
||||||
|
|
||||||
|
if let derivedFileDirectory = ProcessInfo.processInfo.environment["DERIVED_FILE_DIR"] {
|
||||||
|
try? "".write(toFile: derivedFileDirectory + "/alphabetizeStrings.txt", atomically: true, encoding: .utf8)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error: Failed to write to \(fileURL.path)")
|
||||||
|
exit(1)
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
//
|
||||||
|
// Swiftfin is subject to the terms of the Mozilla Public
|
||||||
|
// License, v2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// Path to the English localization file
|
||||||
|
let localizationFile = "./Translations/en.lproj/Localizable.strings"
|
||||||
|
|
||||||
|
// Directories to scan for Swift files
|
||||||
|
let directoriesToScan = ["./Shared", "./Swiftfin", "./Swiftfin tvOS"]
|
||||||
|
|
||||||
|
// File to exclude from scanning
|
||||||
|
let excludedFile = "./Shared/Strings/Strings.swift"
|
||||||
|
|
||||||
|
// Regular expressions to match localization entries and usage in Swift files
|
||||||
|
// Matches lines like "Key" = "Value";
|
||||||
|
let localizationRegex = #/^\"(?<key>[^\"]+)\"\s*=\s*\"(?<value>[^\"]+)\";$/#
|
||||||
|
|
||||||
|
// Matches usage like L10n.key in Swift files
|
||||||
|
let usageRegex = #/L10n\.(?<key>[a-zA-Z0-9_]+)/#
|
||||||
|
|
||||||
|
// Attempt to load the localization file's content
|
||||||
|
guard let localizationContent = try? String(contentsOfFile: localizationFile, encoding: .utf8) else {
|
||||||
|
print("Unable to read localization file at \(localizationFile)")
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the file into lines and initialize a dictionary for localization entries
|
||||||
|
let localizationLines = localizationContent.components(separatedBy: .newlines)
|
||||||
|
var localizationEntries = [String: String]()
|
||||||
|
|
||||||
|
// Parse each line to extract key-value pairs
|
||||||
|
for line in localizationLines {
|
||||||
|
let trimmed = line.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
// Skip empty lines or comments
|
||||||
|
if trimmed.isEmpty || trimmed.hasPrefix("//") { continue }
|
||||||
|
|
||||||
|
// Match valid localization entries and add them to the dictionary
|
||||||
|
if let match = line.firstMatch(of: localizationRegex) {
|
||||||
|
let key = String(match.output.key)
|
||||||
|
let value = String(match.output.value)
|
||||||
|
localizationEntries[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set to store all keys found in the codebase
|
||||||
|
var usedKeys = Set<String>()
|
||||||
|
|
||||||
|
// Function to scan a directory recursively for Swift files
|
||||||
|
func scanDirectory(_ path: String) {
|
||||||
|
let fileManager = FileManager.default
|
||||||
|
guard let enumerator = fileManager.enumerator(atPath: path) else { return }
|
||||||
|
|
||||||
|
for case let file as String in enumerator {
|
||||||
|
let filePath = "\(path)/\(file)"
|
||||||
|
|
||||||
|
// Skip the excluded file
|
||||||
|
if filePath == excludedFile { continue }
|
||||||
|
|
||||||
|
// Process only Swift files
|
||||||
|
if file.hasSuffix(".swift") {
|
||||||
|
if let fileContent = try? String(contentsOfFile: filePath, encoding: .utf8) {
|
||||||
|
for line in fileContent.components(separatedBy: .newlines) {
|
||||||
|
// Find all matches for L10n.key in each line
|
||||||
|
let matches = line.matches(of: usageRegex)
|
||||||
|
for match in matches {
|
||||||
|
let key = String(match.output.key)
|
||||||
|
usedKeys.insert(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan all specified directories
|
||||||
|
for directory in directoriesToScan {
|
||||||
|
scanDirectory(directory)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Remove Unused Keys
|
||||||
|
|
||||||
|
// Identify keys in the localization file that are not used in the codebase
|
||||||
|
let unusedKeys = localizationEntries.keys.filter { !usedKeys.contains($0) }
|
||||||
|
|
||||||
|
// Remove unused keys from the dictionary
|
||||||
|
unusedKeys.forEach { localizationEntries.removeValue(forKey: $0) }
|
||||||
|
|
||||||
|
// MARK: - Write Updated Localizable.strings
|
||||||
|
|
||||||
|
// Sort keys alphabetically for consistent formatting
|
||||||
|
let sortedKeys = localizationEntries.keys.sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
|
||||||
|
|
||||||
|
// Reconstruct the localization file with sorted and updated entries
|
||||||
|
let updatedContent = sortedKeys.map { "/// \(localizationEntries[$0]!)\n\"\($0)\" = \"\(localizationEntries[$0]!)\";" }
|
||||||
|
.joined(separator: "\n\n")
|
||||||
|
|
||||||
|
// Attempt to write the updated content back to the localization file
|
||||||
|
do {
|
||||||
|
try updatedContent.write(toFile: localizationFile, atomically: true, encoding: .utf8)
|
||||||
|
print("Localization file updated. Removed \(unusedKeys.count) unused keys.")
|
||||||
|
} catch {
|
||||||
|
print("Error: Failed to write updated localization file.")
|
||||||
|
exit(1)
|
||||||
|
}
|
|
@ -1346,8 +1346,6 @@ internal enum L10n {
|
||||||
internal static let weekly = L10n.tr("Localizable", "weekly", fallback: "Weekly")
|
internal static let weekly = L10n.tr("Localizable", "weekly", fallback: "Weekly")
|
||||||
/// This will be created as a new item on your Jellyfin Server.
|
/// This will be created as a new item on your Jellyfin Server.
|
||||||
internal static let willBeCreatedOnServer = L10n.tr("Localizable", "willBeCreatedOnServer", fallback: "This will be created as a new item on your Jellyfin Server.")
|
internal static let willBeCreatedOnServer = L10n.tr("Localizable", "willBeCreatedOnServer", fallback: "This will be created as a new item on your Jellyfin Server.")
|
||||||
/// WIP
|
|
||||||
internal static let wip = L10n.tr("Localizable", "wip", fallback: "WIP")
|
|
||||||
/// Writer
|
/// Writer
|
||||||
internal static let writer = L10n.tr("Localizable", "writer", fallback: "Writer")
|
internal static let writer = L10n.tr("Localizable", "writer", fallback: "Writer")
|
||||||
/// Year
|
/// Year
|
||||||
|
|
|
@ -762,7 +762,6 @@
|
||||||
E1763A292BF3046A004DF6AB /* AddUserButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A282BF3046A004DF6AB /* AddUserButton.swift */; };
|
E1763A292BF3046A004DF6AB /* AddUserButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A282BF3046A004DF6AB /* AddUserButton.swift */; };
|
||||||
E1763A2B2BF3046E004DF6AB /* UserGridButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A2A2BF3046E004DF6AB /* UserGridButton.swift */; };
|
E1763A2B2BF3046E004DF6AB /* UserGridButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A2A2BF3046E004DF6AB /* UserGridButton.swift */; };
|
||||||
E1763A642BF3C9AA004DF6AB /* ListRowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A632BF3C9AA004DF6AB /* ListRowButton.swift */; };
|
E1763A642BF3C9AA004DF6AB /* ListRowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A632BF3C9AA004DF6AB /* ListRowButton.swift */; };
|
||||||
E1763A662BF3CA83004DF6AB /* FullScreenMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A652BF3CA83004DF6AB /* FullScreenMenu.swift */; };
|
|
||||||
E1763A6A2BF3D177004DF6AB /* PublicUserButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A692BF3D177004DF6AB /* PublicUserButton.swift */; };
|
E1763A6A2BF3D177004DF6AB /* PublicUserButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A692BF3D177004DF6AB /* PublicUserButton.swift */; };
|
||||||
E1763A712BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */; };
|
E1763A712BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */; };
|
||||||
E1763A722BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */; };
|
E1763A722BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */; };
|
||||||
|
@ -1272,6 +1271,7 @@
|
||||||
4E6C27072C8BD0AD00FD2185 /* ActiveSessionDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSessionDetailView.swift; sourceTree = "<group>"; };
|
4E6C27072C8BD0AD00FD2185 /* ActiveSessionDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSessionDetailView.swift; sourceTree = "<group>"; };
|
||||||
4E71D6882C80910900A0174D /* EditCustomDeviceProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCustomDeviceProfileView.swift; sourceTree = "<group>"; };
|
4E71D6882C80910900A0174D /* EditCustomDeviceProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCustomDeviceProfileView.swift; sourceTree = "<group>"; };
|
||||||
4E73E2A52C41CFD3002D2A78 /* PlaybackBitrateTestSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackBitrateTestSize.swift; sourceTree = "<group>"; };
|
4E73E2A52C41CFD3002D2A78 /* PlaybackBitrateTestSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackBitrateTestSize.swift; sourceTree = "<group>"; };
|
||||||
|
4E75B34A2D164AC100D16531 /* PurgeUnusedStrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurgeUnusedStrings.swift; sourceTree = "<group>"; };
|
||||||
4E762AAD2C3A1A95004D1579 /* PlaybackBitrate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaybackBitrate.swift; sourceTree = "<group>"; };
|
4E762AAD2C3A1A95004D1579 /* PlaybackBitrate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaybackBitrate.swift; sourceTree = "<group>"; };
|
||||||
4E884C642CEBB2FF004CF6AD /* LearnMoreModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMoreModal.swift; sourceTree = "<group>"; };
|
4E884C642CEBB2FF004CF6AD /* LearnMoreModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMoreModal.swift; sourceTree = "<group>"; };
|
||||||
4E8B34E92AB91B6E0018F305 /* ItemFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemFilter.swift; sourceTree = "<group>"; };
|
4E8B34E92AB91B6E0018F305 /* ItemFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemFilter.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1324,6 +1324,7 @@
|
||||||
4EC2B1A82CC97C0400D866BE /* ServerUserDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerUserDetailsView.swift; sourceTree = "<group>"; };
|
4EC2B1A82CC97C0400D866BE /* ServerUserDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerUserDetailsView.swift; sourceTree = "<group>"; };
|
||||||
4EC50D602C934B3A00FC3D0E /* ServerTasksViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerTasksViewModel.swift; sourceTree = "<group>"; };
|
4EC50D602C934B3A00FC3D0E /* ServerTasksViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerTasksViewModel.swift; sourceTree = "<group>"; };
|
||||||
4EC6C16A2C92999800FC904B /* TranscodeSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscodeSection.swift; sourceTree = "<group>"; };
|
4EC6C16A2C92999800FC904B /* TranscodeSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscodeSection.swift; sourceTree = "<group>"; };
|
||||||
|
4EC71FBB2D161FE300D0B3A8 /* AlphabetizeStrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlphabetizeStrings.swift; sourceTree = "<group>"; };
|
||||||
4ECDAA9D2C920A8E0030F2F5 /* TranscodeReason.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscodeReason.swift; sourceTree = "<group>"; };
|
4ECDAA9D2C920A8E0030F2F5 /* TranscodeReason.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscodeReason.swift; sourceTree = "<group>"; };
|
||||||
4ECF5D812D0A3D0200F066B1 /* AddAccessScheduleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccessScheduleView.swift; sourceTree = "<group>"; };
|
4ECF5D812D0A3D0200F066B1 /* AddAccessScheduleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccessScheduleView.swift; sourceTree = "<group>"; };
|
||||||
4ECF5D892D0A57EF00F066B1 /* DynamicDayOfWeek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicDayOfWeek.swift; sourceTree = "<group>"; };
|
4ECF5D892D0A57EF00F066B1 /* DynamicDayOfWeek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicDayOfWeek.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1695,7 +1696,6 @@
|
||||||
E1763A282BF3046A004DF6AB /* AddUserButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddUserButton.swift; sourceTree = "<group>"; };
|
E1763A282BF3046A004DF6AB /* AddUserButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddUserButton.swift; sourceTree = "<group>"; };
|
||||||
E1763A2A2BF3046E004DF6AB /* UserGridButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserGridButton.swift; sourceTree = "<group>"; };
|
E1763A2A2BF3046E004DF6AB /* UserGridButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserGridButton.swift; sourceTree = "<group>"; };
|
||||||
E1763A632BF3C9AA004DF6AB /* ListRowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRowButton.swift; sourceTree = "<group>"; };
|
E1763A632BF3C9AA004DF6AB /* ListRowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRowButton.swift; sourceTree = "<group>"; };
|
||||||
E1763A652BF3CA83004DF6AB /* FullScreenMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullScreenMenu.swift; sourceTree = "<group>"; };
|
|
||||||
E1763A692BF3D177004DF6AB /* PublicUserButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicUserButton.swift; sourceTree = "<group>"; };
|
E1763A692BF3D177004DF6AB /* PublicUserButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicUserButton.swift; sourceTree = "<group>"; };
|
||||||
E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftfinStore+Mappings.swift"; sourceTree = "<group>"; };
|
E1763A702BF3F67C004DF6AB /* SwiftfinStore+Mappings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftfinStore+Mappings.swift"; sourceTree = "<group>"; };
|
||||||
E1763A732BF3FA4C004DF6AB /* AppLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLoadingView.swift; sourceTree = "<group>"; };
|
E1763A732BF3FA4C004DF6AB /* AppLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLoadingView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -2462,6 +2462,15 @@
|
||||||
path = ActiveSessionDetailView;
|
path = ActiveSessionDetailView;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4E75B34D2D16583900D16531 /* Translations */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4EC71FBB2D161FE300D0B3A8 /* AlphabetizeStrings.swift */,
|
||||||
|
4E75B34A2D164AC100D16531 /* PurgeUnusedStrings.swift */,
|
||||||
|
);
|
||||||
|
path = Translations;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4E8F74A32CE03D3100CC8969 /* ItemEditorView */ = {
|
4E8F74A32CE03D3100CC8969 /* ItemEditorView */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -2692,6 +2701,14 @@
|
||||||
path = ServerUserDetailsView;
|
path = ServerUserDetailsView;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4EC71FBA2D161FD800D0B3A8 /* Scripts */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4E75B34D2D16583900D16531 /* Translations */,
|
||||||
|
);
|
||||||
|
path = Scripts;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4ECF5D822D0A3D0200F066B1 /* AddAccessScheduleView */ = {
|
4ECF5D822D0A3D0200F066B1 /* AddAccessScheduleView */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -3004,6 +3021,7 @@
|
||||||
534D4FE126A7D7CC000A7A48 /* Translations */,
|
534D4FE126A7D7CC000A7A48 /* Translations */,
|
||||||
5377CBF2263B596A003A4E83 /* Products */,
|
5377CBF2263B596A003A4E83 /* Products */,
|
||||||
53D5E3DB264B47EE00BADDC8 /* Frameworks */,
|
53D5E3DB264B47EE00BADDC8 /* Frameworks */,
|
||||||
|
4EC71FBA2D161FD800D0B3A8 /* Scripts */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
@ -4753,6 +4771,7 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 535870712669D21700D05A09 /* Build configuration list for PBXNativeTarget "Swiftfin tvOS" */;
|
buildConfigurationList = 535870712669D21700D05A09 /* Build configuration list for PBXNativeTarget "Swiftfin tvOS" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
4EC71FBD2D1620AF00D0B3A8 /* Alphabetize Strings */,
|
||||||
6286F0A3271C0ABA00C40ED5 /* Run Swiftgen.swift */,
|
6286F0A3271C0ABA00C40ED5 /* Run Swiftgen.swift */,
|
||||||
BD83D7852B55EEB600652C24 /* Run SwiftFormat */,
|
BD83D7852B55EEB600652C24 /* Run SwiftFormat */,
|
||||||
5358705C2669D21600D05A09 /* Sources */,
|
5358705C2669D21600D05A09 /* Sources */,
|
||||||
|
@ -4800,6 +4819,7 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 5377CC1B263B596B003A4E83 /* Build configuration list for PBXNativeTarget "Swiftfin iOS" */;
|
buildConfigurationList = 5377CC1B263B596B003A4E83 /* Build configuration list for PBXNativeTarget "Swiftfin iOS" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
4EC71FBC2D16201C00D0B3A8 /* Alphabetize Strings */,
|
||||||
6286F09E271C093000C40ED5 /* Run Swiftgen.swift */,
|
6286F09E271C093000C40ED5 /* Run Swiftgen.swift */,
|
||||||
BD0BA2282AD64BB200306A8D /* Run SwiftFormat */,
|
BD0BA2282AD64BB200306A8D /* Run SwiftFormat */,
|
||||||
5377CBED263B596A003A4E83 /* Sources */,
|
5377CBED263B596A003A4E83 /* Sources */,
|
||||||
|
@ -4989,6 +5009,46 @@
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
4EC71FBC2D16201C00D0B3A8 /* Alphabetize Strings */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"$(SRCROOT)/Translations/en.lproj/Localizable.strings",
|
||||||
|
);
|
||||||
|
name = "Alphabetize Strings";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/alphabetizeStrings.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "xcrun --sdk macosx swift \"${SRCROOT}/Scripts/Translations/AlphabetizeStrings.swift\"\n";
|
||||||
|
};
|
||||||
|
4EC71FBD2D1620AF00D0B3A8 /* Alphabetize Strings */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"$(SRCROOT)/Translations/en.lproj/Localizable.strings",
|
||||||
|
);
|
||||||
|
name = "Alphabetize Strings";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/alphabetizeStrings.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "xcrun --sdk macosx swift \"${SRCROOT}/Scripts/Translations/AlphabetizeStrings.swift\"\n";
|
||||||
|
};
|
||||||
6286F09E271C093000C40ED5 /* Run Swiftgen.swift */ = {
|
6286F09E271C093000C40ED5 /* Run Swiftgen.swift */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
/// Access
|
/// Access
|
||||||
"access" = "Access";
|
"access" = "Access";
|
||||||
|
|
||||||
|
/// Accessibility
|
||||||
|
"accessibility" = "Accessibility";
|
||||||
|
|
||||||
/// The End Time must come after the Start Time.
|
/// The End Time must come after the Start Time.
|
||||||
"accessScheduleInvalidTime" = "The End Time must come after the Start Time.";
|
"accessScheduleInvalidTime" = "The End Time must come after the Start Time.";
|
||||||
|
|
||||||
|
@ -22,9 +25,6 @@
|
||||||
/// Define the allowed hours for usage and restrict access outside those times.
|
/// Define the allowed hours for usage and restrict access outside those times.
|
||||||
"accessSchedulesDescription" = "Define the allowed hours for usage and restrict access outside those times.";
|
"accessSchedulesDescription" = "Define the allowed hours for usage and restrict access outside those times.";
|
||||||
|
|
||||||
/// Accessibility
|
|
||||||
"accessibility" = "Accessibility";
|
|
||||||
|
|
||||||
/// Active
|
/// Active
|
||||||
"active" = "Active";
|
"active" = "Active";
|
||||||
|
|
||||||
|
@ -37,11 +37,14 @@
|
||||||
/// Add
|
/// Add
|
||||||
"add" = "Add";
|
"add" = "Add";
|
||||||
|
|
||||||
|
/// Add Access Schedule
|
||||||
|
"addAccessSchedule" = "Add Access Schedule";
|
||||||
|
|
||||||
/// Add API key
|
/// Add API key
|
||||||
"addAPIKey" = "Add API key";
|
"addAPIKey" = "Add API key";
|
||||||
|
|
||||||
/// Add Access Schedule
|
/// Additional security access for users signed in to this device. This does not change any Jellyfin server user settings.
|
||||||
"addAccessSchedule" = "Add Access Schedule";
|
"additionalSecurityAccessDescription" = "Additional security access for users signed in to this device. This does not change any Jellyfin server user settings.";
|
||||||
|
|
||||||
/// Add Server
|
/// Add Server
|
||||||
"addServer" = "Add Server";
|
"addServer" = "Add Server";
|
||||||
|
@ -55,9 +58,6 @@
|
||||||
/// Add User
|
/// Add User
|
||||||
"addUser" = "Add User";
|
"addUser" = "Add User";
|
||||||
|
|
||||||
/// Additional security access for users signed in to this device. This does not change any Jellyfin server user settings.
|
|
||||||
"additionalSecurityAccessDescription" = "Additional security access for users signed in to this device. This does not change any Jellyfin server user settings.";
|
|
||||||
|
|
||||||
/// Administrator
|
/// Administrator
|
||||||
"administrator" = "Administrator";
|
"administrator" = "Administrator";
|
||||||
|
|
||||||
|
@ -67,15 +67,15 @@
|
||||||
/// Age %@
|
/// Age %@
|
||||||
"agesGroup" = "Age %@";
|
"agesGroup" = "Age %@";
|
||||||
|
|
||||||
|
/// Aired
|
||||||
|
"aired" = "Aired";
|
||||||
|
|
||||||
/// Air Time
|
/// Air Time
|
||||||
"airTime" = "Air Time";
|
"airTime" = "Air Time";
|
||||||
|
|
||||||
/// Airs %s
|
/// Airs %s
|
||||||
"airWithDate" = "Airs %s";
|
"airWithDate" = "Airs %s";
|
||||||
|
|
||||||
/// Aired
|
|
||||||
"aired" = "Aired";
|
|
||||||
|
|
||||||
/// Album Artist
|
/// Album Artist
|
||||||
"albumArtist" = "Album Artist";
|
"albumArtist" = "Album Artist";
|
||||||
|
|
||||||
|
@ -88,12 +88,6 @@
|
||||||
/// All Media
|
/// All Media
|
||||||
"allMedia" = "All Media";
|
"allMedia" = "All Media";
|
||||||
|
|
||||||
/// All Servers
|
|
||||||
"allServers" = "All Servers";
|
|
||||||
|
|
||||||
/// View and manage all registered users on the server, including their permissions and activity status.
|
|
||||||
"allUsersDescription" = "View and manage all registered users on the server, including their permissions and activity status.";
|
|
||||||
|
|
||||||
/// Allow collection management
|
/// Allow collection management
|
||||||
"allowCollectionManagement" = "Allow collection management";
|
"allowCollectionManagement" = "Allow collection management";
|
||||||
|
|
||||||
|
@ -103,6 +97,12 @@
|
||||||
/// Allow media item editing
|
/// Allow media item editing
|
||||||
"allowItemEditing" = "Allow media item editing";
|
"allowItemEditing" = "Allow media item editing";
|
||||||
|
|
||||||
|
/// All Servers
|
||||||
|
"allServers" = "All Servers";
|
||||||
|
|
||||||
|
/// View and manage all registered users on the server, including their permissions and activity status.
|
||||||
|
"allUsersDescription" = "View and manage all registered users on the server, including their permissions and activity status.";
|
||||||
|
|
||||||
/// Alternate
|
/// Alternate
|
||||||
"alternate" = "Alternate";
|
"alternate" = "Alternate";
|
||||||
|
|
||||||
|
@ -127,12 +127,12 @@
|
||||||
/// API Keys
|
/// API Keys
|
||||||
"apiKeysTitle" = "API Keys";
|
"apiKeysTitle" = "API Keys";
|
||||||
|
|
||||||
/// App Icon
|
|
||||||
"appIcon" = "App Icon";
|
|
||||||
|
|
||||||
/// Appearance
|
/// Appearance
|
||||||
"appearance" = "Appearance";
|
"appearance" = "Appearance";
|
||||||
|
|
||||||
|
/// App Icon
|
||||||
|
"appIcon" = "App Icon";
|
||||||
|
|
||||||
/// Application Name
|
/// Application Name
|
||||||
"applicationName" = "Application Name";
|
"applicationName" = "Application Name";
|
||||||
|
|
||||||
|
@ -202,12 +202,12 @@
|
||||||
/// Tests your server connection to assess internet speed and adjust bandwidth automatically.
|
/// Tests your server connection to assess internet speed and adjust bandwidth automatically.
|
||||||
"birateAutoDescription" = "Tests your server connection to assess internet speed and adjust bandwidth automatically.";
|
"birateAutoDescription" = "Tests your server connection to assess internet speed and adjust bandwidth automatically.";
|
||||||
|
|
||||||
/// Birth year
|
|
||||||
"birthYear" = "Birth year";
|
|
||||||
|
|
||||||
/// Birthday
|
/// Birthday
|
||||||
"birthday" = "Birthday";
|
"birthday" = "Birthday";
|
||||||
|
|
||||||
|
/// Birth year
|
||||||
|
"birthYear" = "Birth year";
|
||||||
|
|
||||||
/// Auto
|
/// Auto
|
||||||
"bitrateAuto" = "Auto";
|
"bitrateAuto" = "Auto";
|
||||||
|
|
||||||
|
@ -316,12 +316,12 @@
|
||||||
/// Channels
|
/// Channels
|
||||||
"channels" = "Channels";
|
"channels" = "Channels";
|
||||||
|
|
||||||
/// Chapter Slider
|
|
||||||
"chapterSlider" = "Chapter Slider";
|
|
||||||
|
|
||||||
/// Chapters
|
/// Chapters
|
||||||
"chapters" = "Chapters";
|
"chapters" = "Chapters";
|
||||||
|
|
||||||
|
/// Chapter Slider
|
||||||
|
"chapterSlider" = "Chapter Slider";
|
||||||
|
|
||||||
/// Cinematic
|
/// Cinematic
|
||||||
"cinematic" = "Cinematic";
|
"cinematic" = "Cinematic";
|
||||||
|
|
||||||
|
@ -418,15 +418,15 @@
|
||||||
/// Cover Artist
|
/// Cover Artist
|
||||||
"coverArtist" = "Cover Artist";
|
"coverArtist" = "Cover Artist";
|
||||||
|
|
||||||
|
/// Create & Join Groups
|
||||||
|
"createAndJoinGroups" = "Create & Join Groups";
|
||||||
|
|
||||||
/// Create API Key
|
/// Create API Key
|
||||||
"createAPIKey" = "Create API Key";
|
"createAPIKey" = "Create API Key";
|
||||||
|
|
||||||
/// Enter the application name for the new API key.
|
/// Enter the application name for the new API key.
|
||||||
"createAPIKeyMessage" = "Enter the application name for the new API key.";
|
"createAPIKeyMessage" = "Enter the application name for the new API key.";
|
||||||
|
|
||||||
/// Create & Join Groups
|
|
||||||
"createAndJoinGroups" = "Create & Join Groups";
|
|
||||||
|
|
||||||
/// Create a pin to sign in to %@ on this device
|
/// Create a pin to sign in to %@ on this device
|
||||||
"createPinForUser" = "Create a pin to sign in to %@ on this device";
|
"createPinForUser" = "Create a pin to sign in to %@ on this device";
|
||||||
|
|
||||||
|
@ -472,6 +472,9 @@
|
||||||
/// Custom failed logins
|
/// Custom failed logins
|
||||||
"customFailedLogins" = "Custom failed logins";
|
"customFailedLogins" = "Custom failed logins";
|
||||||
|
|
||||||
|
/// Customize
|
||||||
|
"customize" = "Customize";
|
||||||
|
|
||||||
/// Custom Profile
|
/// Custom Profile
|
||||||
"customProfile" = "Custom Profile";
|
"customProfile" = "Custom Profile";
|
||||||
|
|
||||||
|
@ -481,9 +484,6 @@
|
||||||
/// Custom sessions
|
/// Custom sessions
|
||||||
"customSessions" = "Custom sessions";
|
"customSessions" = "Custom sessions";
|
||||||
|
|
||||||
/// Customize
|
|
||||||
"customize" = "Customize";
|
|
||||||
|
|
||||||
/// Daily
|
/// Daily
|
||||||
"daily" = "Daily";
|
"daily" = "Daily";
|
||||||
|
|
||||||
|
@ -637,6 +637,9 @@
|
||||||
/// Plays content in its original format. May cause playback issues on unsupported media types.
|
/// Plays content in its original format. May cause playback issues on unsupported media types.
|
||||||
"directDescription" = "Plays content in its original format. May cause playback issues on unsupported media types.";
|
"directDescription" = "Plays content in its original format. May cause playback issues on unsupported media types.";
|
||||||
|
|
||||||
|
/// Director
|
||||||
|
"director" = "Director";
|
||||||
|
|
||||||
/// Direct Play
|
/// Direct Play
|
||||||
"directPlay" = "Direct Play";
|
"directPlay" = "Direct Play";
|
||||||
|
|
||||||
|
@ -646,9 +649,6 @@
|
||||||
/// Direct Stream
|
/// Direct Stream
|
||||||
"directStream" = "Direct Stream";
|
"directStream" = "Direct Stream";
|
||||||
|
|
||||||
/// Director
|
|
||||||
"director" = "Director";
|
|
||||||
|
|
||||||
/// Disabled
|
/// Disabled
|
||||||
"disabled" = "Disabled";
|
"disabled" = "Disabled";
|
||||||
|
|
||||||
|
@ -679,15 +679,15 @@
|
||||||
/// Edit
|
/// Edit
|
||||||
"edit" = "Edit";
|
"edit" = "Edit";
|
||||||
|
|
||||||
|
/// Editor
|
||||||
|
"editor" = "Editor";
|
||||||
|
|
||||||
/// Edit Server
|
/// Edit Server
|
||||||
"editServer" = "Edit Server";
|
"editServer" = "Edit Server";
|
||||||
|
|
||||||
/// Edit Users
|
/// Edit Users
|
||||||
"editUsers" = "Edit Users";
|
"editUsers" = "Edit Users";
|
||||||
|
|
||||||
/// Editor
|
|
||||||
"editor" = "Editor";
|
|
||||||
|
|
||||||
/// Enable all devices
|
/// Enable all devices
|
||||||
"enableAllDevices" = "Enable all devices";
|
"enableAllDevices" = "Enable all devices";
|
||||||
|
|
||||||
|
@ -700,12 +700,12 @@
|
||||||
/// End Date
|
/// End Date
|
||||||
"endDate" = "End Date";
|
"endDate" = "End Date";
|
||||||
|
|
||||||
/// End Time
|
|
||||||
"endTime" = "End Time";
|
|
||||||
|
|
||||||
/// Ended
|
/// Ended
|
||||||
"ended" = "Ended";
|
"ended" = "Ended";
|
||||||
|
|
||||||
|
/// End Time
|
||||||
|
"endTime" = "End Time";
|
||||||
|
|
||||||
/// Engineer
|
/// Engineer
|
||||||
"engineer" = "Engineer";
|
"engineer" = "Engineer";
|
||||||
|
|
||||||
|
@ -754,12 +754,12 @@
|
||||||
/// Every
|
/// Every
|
||||||
"every" = "Every";
|
"every" = "Every";
|
||||||
|
|
||||||
/// Every %1$@
|
|
||||||
"everyInterval" = "Every %1$@";
|
|
||||||
|
|
||||||
/// Everyday
|
/// Everyday
|
||||||
"everyday" = "Everyday";
|
"everyday" = "Everyday";
|
||||||
|
|
||||||
|
/// Every %1$@
|
||||||
|
"everyInterval" = "Every %1$@";
|
||||||
|
|
||||||
/// Executed
|
/// Executed
|
||||||
"executed" = "Executed";
|
"executed" = "Executed";
|
||||||
|
|
||||||
|
@ -937,12 +937,12 @@
|
||||||
/// Letter
|
/// Letter
|
||||||
"letter" = "Letter";
|
"letter" = "Letter";
|
||||||
|
|
||||||
/// Letter Picker
|
|
||||||
"letterPicker" = "Letter Picker";
|
|
||||||
|
|
||||||
/// Letterer
|
/// Letterer
|
||||||
"letterer" = "Letterer";
|
"letterer" = "Letterer";
|
||||||
|
|
||||||
|
/// Letter Picker
|
||||||
|
"letterPicker" = "Letter Picker";
|
||||||
|
|
||||||
/// Library
|
/// Library
|
||||||
"library" = "Library";
|
"library" = "Library";
|
||||||
|
|
||||||
|
@ -958,15 +958,15 @@
|
||||||
/// Live TV
|
/// Live TV
|
||||||
"liveTV" = "Live TV";
|
"liveTV" = "Live TV";
|
||||||
|
|
||||||
|
/// Live TV access
|
||||||
|
"liveTvAccess" = "Live TV access";
|
||||||
|
|
||||||
/// Live TV Channels
|
/// Live TV Channels
|
||||||
"liveTVChannels" = "Live TV Channels";
|
"liveTVChannels" = "Live TV Channels";
|
||||||
|
|
||||||
/// Live TV Programs
|
/// Live TV Programs
|
||||||
"liveTVPrograms" = "Live TV Programs";
|
"liveTVPrograms" = "Live TV Programs";
|
||||||
|
|
||||||
/// Live TV access
|
|
||||||
"liveTvAccess" = "Live TV access";
|
|
||||||
|
|
||||||
/// Live TV recording management
|
/// Live TV recording management
|
||||||
"liveTvRecordingManagement" = "Live TV recording management";
|
"liveTvRecordingManagement" = "Live TV recording management";
|
||||||
|
|
||||||
|
@ -1000,12 +1000,6 @@
|
||||||
/// Management
|
/// Management
|
||||||
"management" = "Management";
|
"management" = "Management";
|
||||||
|
|
||||||
/// Maximum parental rating
|
|
||||||
"maxParentalRating" = "Maximum parental rating";
|
|
||||||
|
|
||||||
/// Content with a higher rating will be hidden from this user.
|
|
||||||
"maxParentalRatingDescription" = "Content with a higher rating will be hidden from this user.";
|
|
||||||
|
|
||||||
/// Maximum Bitrate
|
/// Maximum Bitrate
|
||||||
"maximumBitrate" = "Maximum Bitrate";
|
"maximumBitrate" = "Maximum Bitrate";
|
||||||
|
|
||||||
|
@ -1030,6 +1024,12 @@
|
||||||
/// Maximum sessions policy
|
/// Maximum sessions policy
|
||||||
"maximumSessionsPolicy" = "Maximum sessions policy";
|
"maximumSessionsPolicy" = "Maximum sessions policy";
|
||||||
|
|
||||||
|
/// Maximum parental rating
|
||||||
|
"maxParentalRating" = "Maximum parental rating";
|
||||||
|
|
||||||
|
/// Content with a higher rating will be hidden from this user.
|
||||||
|
"maxParentalRatingDescription" = "Content with a higher rating will be hidden from this user.";
|
||||||
|
|
||||||
/// Media
|
/// Media
|
||||||
"media" = "Media";
|
"media" = "Media";
|
||||||
|
|
||||||
|
@ -1096,12 +1096,12 @@
|
||||||
/// New Password
|
/// New Password
|
||||||
"newPassword" = "New Password";
|
"newPassword" = "New Password";
|
||||||
|
|
||||||
/// New User
|
|
||||||
"newUser" = "New User";
|
|
||||||
|
|
||||||
/// News
|
/// News
|
||||||
"news" = "News";
|
"news" = "News";
|
||||||
|
|
||||||
|
/// New User
|
||||||
|
"newUser" = "New User";
|
||||||
|
|
||||||
/// Next
|
/// Next
|
||||||
"next" = "Next";
|
"next" = "Next";
|
||||||
|
|
||||||
|
@ -1129,6 +1129,9 @@
|
||||||
/// No local servers found
|
/// No local servers found
|
||||||
"noLocalServersFound" = "No local servers found";
|
"noLocalServersFound" = "No local servers found";
|
||||||
|
|
||||||
|
/// None
|
||||||
|
"none" = "None";
|
||||||
|
|
||||||
/// No overview available
|
/// No overview available
|
||||||
"noOverviewAvailable" = "No overview available";
|
"noOverviewAvailable" = "No overview available";
|
||||||
|
|
||||||
|
@ -1138,24 +1141,21 @@
|
||||||
/// No results.
|
/// No results.
|
||||||
"noResults" = "No results.";
|
"noResults" = "No results.";
|
||||||
|
|
||||||
|
/// Normal
|
||||||
|
"normal" = "Normal";
|
||||||
|
|
||||||
/// No runtime limit
|
/// No runtime limit
|
||||||
"noRuntimeLimit" = "No runtime limit";
|
"noRuntimeLimit" = "No runtime limit";
|
||||||
|
|
||||||
/// No session
|
/// No session
|
||||||
"noSession" = "No session";
|
"noSession" = "No session";
|
||||||
|
|
||||||
/// No title
|
|
||||||
"noTitle" = "No title";
|
|
||||||
|
|
||||||
/// None
|
|
||||||
"none" = "None";
|
|
||||||
|
|
||||||
/// Normal
|
|
||||||
"normal" = "Normal";
|
|
||||||
|
|
||||||
/// Type: %@ not implemented yet :(
|
/// Type: %@ not implemented yet :(
|
||||||
"notImplementedYetWithType" = "Type: %@ not implemented yet :(";
|
"notImplementedYetWithType" = "Type: %@ not implemented yet :(";
|
||||||
|
|
||||||
|
/// No title
|
||||||
|
"noTitle" = "No title";
|
||||||
|
|
||||||
/// Official Rating
|
/// Official Rating
|
||||||
"officialRating" = "Official Rating";
|
"officialRating" = "Official Rating";
|
||||||
|
|
||||||
|
@ -1207,12 +1207,12 @@
|
||||||
/// Password
|
/// Password
|
||||||
"password" = "Password";
|
"password" = "Password";
|
||||||
|
|
||||||
/// Changes the Jellyfin server user password. This does not change any Swiftfin settings.
|
|
||||||
"passwordChangeWarning" = "Changes the Jellyfin server user password. This does not change any Swiftfin settings.";
|
|
||||||
|
|
||||||
/// User password has been changed.
|
/// User password has been changed.
|
||||||
"passwordChangedMessage" = "User password has been changed.";
|
"passwordChangedMessage" = "User password has been changed.";
|
||||||
|
|
||||||
|
/// Changes the Jellyfin server user password. This does not change any Swiftfin settings.
|
||||||
|
"passwordChangeWarning" = "Changes the Jellyfin server user password. This does not change any Swiftfin settings.";
|
||||||
|
|
||||||
/// New passwords do not match.
|
/// New passwords do not match.
|
||||||
"passwordsDoNotMatch" = "New passwords do not match.";
|
"passwordsDoNotMatch" = "New passwords do not match.";
|
||||||
|
|
||||||
|
@ -1240,18 +1240,6 @@
|
||||||
/// Play / Pause
|
/// Play / Pause
|
||||||
"playAndPause" = "Play / Pause";
|
"playAndPause" = "Play / Pause";
|
||||||
|
|
||||||
/// Play From Beginning
|
|
||||||
"playFromBeginning" = "Play From Beginning";
|
|
||||||
|
|
||||||
/// Play Next Item
|
|
||||||
"playNextItem" = "Play Next Item";
|
|
||||||
|
|
||||||
/// Play on active
|
|
||||||
"playOnActive" = "Play on active";
|
|
||||||
|
|
||||||
/// Play Previous Item
|
|
||||||
"playPreviousItem" = "Play Previous Item";
|
|
||||||
|
|
||||||
/// Playback
|
/// Playback
|
||||||
"playback" = "Playback";
|
"playback" = "Playback";
|
||||||
|
|
||||||
|
@ -1267,6 +1255,18 @@
|
||||||
/// Played
|
/// Played
|
||||||
"played" = "Played";
|
"played" = "Played";
|
||||||
|
|
||||||
|
/// Play From Beginning
|
||||||
|
"playFromBeginning" = "Play From Beginning";
|
||||||
|
|
||||||
|
/// Play Next Item
|
||||||
|
"playNextItem" = "Play Next Item";
|
||||||
|
|
||||||
|
/// Play on active
|
||||||
|
"playOnActive" = "Play on active";
|
||||||
|
|
||||||
|
/// Play Previous Item
|
||||||
|
"playPreviousItem" = "Play Previous Item";
|
||||||
|
|
||||||
/// Posters
|
/// Posters
|
||||||
"posters" = "Posters";
|
"posters" = "Posters";
|
||||||
|
|
||||||
|
@ -1402,6 +1402,9 @@
|
||||||
/// Replace unlocked metadata with new information.
|
/// Replace unlocked metadata with new information.
|
||||||
"replaceMetadataDescription" = "Replace unlocked metadata with new information.";
|
"replaceMetadataDescription" = "Replace unlocked metadata with new information.";
|
||||||
|
|
||||||
|
/// Required
|
||||||
|
"required" = "Required";
|
||||||
|
|
||||||
/// Require device authentication when signing in to the user.
|
/// Require device authentication when signing in to the user.
|
||||||
"requireDeviceAuthDescription" = "Require device authentication when signing in to the user.";
|
"requireDeviceAuthDescription" = "Require device authentication when signing in to the user.";
|
||||||
|
|
||||||
|
@ -1414,9 +1417,6 @@
|
||||||
/// Require a local pin when signing in to the user. This pin is unrecoverable.
|
/// Require a local pin when signing in to the user. This pin is unrecoverable.
|
||||||
"requirePinDescription" = "Require a local pin when signing in to the user. This pin is unrecoverable.";
|
"requirePinDescription" = "Require a local pin when signing in to the user. This pin is unrecoverable.";
|
||||||
|
|
||||||
/// Required
|
|
||||||
"required" = "Required";
|
|
||||||
|
|
||||||
/// Reset
|
/// Reset
|
||||||
"reset" = "Reset";
|
"reset" = "Reset";
|
||||||
|
|
||||||
|
@ -1525,12 +1525,12 @@
|
||||||
/// Server Logs
|
/// Server Logs
|
||||||
"serverLogs" = "Server Logs";
|
"serverLogs" = "Server Logs";
|
||||||
|
|
||||||
/// Server URL
|
|
||||||
"serverURL" = "Server URL";
|
|
||||||
|
|
||||||
/// Servers
|
/// Servers
|
||||||
"servers" = "Servers";
|
"servers" = "Servers";
|
||||||
|
|
||||||
|
/// Server URL
|
||||||
|
"serverURL" = "Server URL";
|
||||||
|
|
||||||
/// Session
|
/// Session
|
||||||
"session" = "Session";
|
"session" = "Session";
|
||||||
|
|
||||||
|
@ -1660,15 +1660,15 @@
|
||||||
/// Subtitle Offset
|
/// Subtitle Offset
|
||||||
"subtitleOffset" = "Subtitle Offset";
|
"subtitleOffset" = "Subtitle Offset";
|
||||||
|
|
||||||
/// Subtitle Size
|
|
||||||
"subtitleSize" = "Subtitle Size";
|
|
||||||
|
|
||||||
/// Subtitles
|
/// Subtitles
|
||||||
"subtitles" = "Subtitles";
|
"subtitles" = "Subtitles";
|
||||||
|
|
||||||
/// Settings only affect some subtitle types
|
/// Settings only affect some subtitle types
|
||||||
"subtitlesDisclaimer" = "Settings only affect some subtitle types";
|
"subtitlesDisclaimer" = "Settings only affect some subtitle types";
|
||||||
|
|
||||||
|
/// Subtitle Size
|
||||||
|
"subtitleSize" = "Subtitle Size";
|
||||||
|
|
||||||
/// Success
|
/// Success
|
||||||
"success" = "Success";
|
"success" = "Success";
|
||||||
|
|
||||||
|
@ -1720,18 +1720,18 @@
|
||||||
/// Failed
|
/// Failed
|
||||||
"taskFailed" = "Failed";
|
"taskFailed" = "Failed";
|
||||||
|
|
||||||
/// Sets the duration (in minutes) in between task triggers.
|
|
||||||
"taskTriggerInterval" = "Sets the duration (in minutes) in between task triggers.";
|
|
||||||
|
|
||||||
/// Sets the maximum runtime (in hours) for this task trigger.
|
|
||||||
"taskTriggerTimeLimit" = "Sets the maximum runtime (in hours) for this task trigger.";
|
|
||||||
|
|
||||||
/// Tasks
|
/// Tasks
|
||||||
"tasks" = "Tasks";
|
"tasks" = "Tasks";
|
||||||
|
|
||||||
/// Tasks are operations that are scheduled to run periodically or can be triggered manually.
|
/// Tasks are operations that are scheduled to run periodically or can be triggered manually.
|
||||||
"tasksDescription" = "Tasks are operations that are scheduled to run periodically or can be triggered manually.";
|
"tasksDescription" = "Tasks are operations that are scheduled to run periodically or can be triggered manually.";
|
||||||
|
|
||||||
|
/// Sets the duration (in minutes) in between task triggers.
|
||||||
|
"taskTriggerInterval" = "Sets the duration (in minutes) in between task triggers.";
|
||||||
|
|
||||||
|
/// Sets the maximum runtime (in hours) for this task trigger.
|
||||||
|
"taskTriggerTimeLimit" = "Sets the maximum runtime (in hours) for this task trigger.";
|
||||||
|
|
||||||
/// Tbps
|
/// Tbps
|
||||||
"terabitsPerSecond" = "Tbps";
|
"terabitsPerSecond" = "Tbps";
|
||||||
|
|
||||||
|
@ -1858,18 +1858,18 @@
|
||||||
/// This user will require device authentication.
|
/// This user will require device authentication.
|
||||||
"userDeviceAuthRequiredDescription" = "This user will require device authentication.";
|
"userDeviceAuthRequiredDescription" = "This user will require device authentication.";
|
||||||
|
|
||||||
/// This user will require a pin.
|
|
||||||
"userPinRequiredDescription" = "This user will require a pin.";
|
|
||||||
|
|
||||||
/// User %@ requires device authentication
|
|
||||||
"userRequiresDeviceAuthentication" = "User %@ requires device authentication";
|
|
||||||
|
|
||||||
/// Username
|
/// Username
|
||||||
"username" = "Username";
|
"username" = "Username";
|
||||||
|
|
||||||
/// A username is required
|
/// A username is required
|
||||||
"usernameRequired" = "A username is required";
|
"usernameRequired" = "A username is required";
|
||||||
|
|
||||||
|
/// This user will require a pin.
|
||||||
|
"userPinRequiredDescription" = "This user will require a pin.";
|
||||||
|
|
||||||
|
/// User %@ requires device authentication
|
||||||
|
"userRequiresDeviceAuthentication" = "User %@ requires device authentication";
|
||||||
|
|
||||||
/// Users
|
/// Users
|
||||||
"users" = "Users";
|
"users" = "Users";
|
||||||
|
|
||||||
|
@ -1927,9 +1927,6 @@
|
||||||
/// This will be created as a new item on your Jellyfin Server.
|
/// This will be created as a new item on your Jellyfin Server.
|
||||||
"willBeCreatedOnServer" = "This will be created as a new item on your Jellyfin Server.";
|
"willBeCreatedOnServer" = "This will be created as a new item on your Jellyfin Server.";
|
||||||
|
|
||||||
/// WIP
|
|
||||||
"wip" = "WIP";
|
|
||||||
|
|
||||||
/// Writer
|
/// Writer
|
||||||
"writer" = "Writer";
|
"writer" = "Writer";
|
||||||
|
|
||||||
|
@ -1943,5 +1940,4 @@
|
||||||
"yellow" = "Yellow";
|
"yellow" = "Yellow";
|
||||||
|
|
||||||
/// Yes
|
/// Yes
|
||||||
"yes" = "Yes";
|
"yes" = "Yes";
|
||||||
|
|
Loading…
Reference in New Issue