diff --git a/Shared/Components/TruncatedText.swift b/Shared/Components/TruncatedText.swift index d042a923..3c224b0a 100644 --- a/Shared/Components/TruncatedText.swift +++ b/Shared/Components/TruncatedText.swift @@ -31,7 +31,7 @@ struct TruncatedText: View { private var isTruncatedBinding: Binding private var onSeeMore: () -> Void - private let seeMoreText = "\u{2026} See More" + private let seeMoreText = "\u{2026}" + L10n.seeMore private var seeMoreType: SeeMoreType private let text: String diff --git a/Shared/Extensions/JellyfinAPI/SortOrder+ItemSortOrder.swift b/Shared/Extensions/JellyfinAPI/SortOrder+ItemSortOrder.swift index 32b3d770..c5b6f6e7 100644 --- a/Shared/Extensions/JellyfinAPI/SortOrder+ItemSortOrder.swift +++ b/Shared/Extensions/JellyfinAPI/SortOrder+ItemSortOrder.swift @@ -17,9 +17,9 @@ extension ItemSortOrder: Displayable { var displayTitle: String { switch self { case .ascending: - return "Ascending" + return L10n.ascending case .descending: - return "Descending" + return L10n.descending } } } diff --git a/Shared/Objects/CustomDeviceProfileAction.swift b/Shared/Objects/CustomDeviceProfileAction.swift index b9f6dcfe..fa66c6d5 100644 --- a/Shared/Objects/CustomDeviceProfileAction.swift +++ b/Shared/Objects/CustomDeviceProfileAction.swift @@ -19,7 +19,7 @@ enum CustomDeviceProfileAction: String, CaseIterable, Displayable, Storable { case .add: return L10n.add case .replace: - return "Replace" + return L10n.replace } } } diff --git a/Shared/Objects/GestureAction.swift b/Shared/Objects/GestureAction.swift index 59403a62..8294c12f 100644 --- a/Shared/Objects/GestureAction.swift +++ b/Shared/Objects/GestureAction.swift @@ -26,7 +26,7 @@ enum LongPressAction: String, GestureAction { case .none: return L10n.none case .gestureLock: - return "Gesture Lock" + return L10n.gestureLock } } } @@ -60,7 +60,7 @@ enum DoubleTouchAction: String, GestureAction { case .aspectFill: return L10n.aspectFill case .gestureLock: - return "Gesture Lock" + return L10n.gestureLock case .pausePlay: return L10n.playAndPause } @@ -85,17 +85,17 @@ enum PanAction: String, GestureAction { case .audioffset: return L10n.audioOffset case .brightness: - return "Brightness" + return L10n.brightness case .playbackSpeed: return L10n.playbackSpeed case .scrub: - return "Scrub" + return L10n.scrub case .slowScrub: - return "Slow Scrub" + return L10n.slowScrub case .subtitleOffset: return L10n.subtitleOffset case .volume: - return "Volume" + return L10n.volume } } } diff --git a/Shared/Objects/OverlayType.swift b/Shared/Objects/OverlayType.swift index 53b726c1..c85c3cb2 100644 --- a/Shared/Objects/OverlayType.swift +++ b/Shared/Objects/OverlayType.swift @@ -32,7 +32,7 @@ enum PlaybackButtonType: String, CaseIterable, Displayable, Defaults.Serializabl var displayTitle: String { switch self { case .large: - return "Large" + return L10n.large case .compact: return L10n.compact } diff --git a/Shared/Objects/PosterDisplayType.swift b/Shared/Objects/PosterDisplayType.swift index 18e88525..3b27d3a7 100644 --- a/Shared/Objects/PosterDisplayType.swift +++ b/Shared/Objects/PosterDisplayType.swift @@ -15,13 +15,12 @@ enum PosterDisplayType: String, CaseIterable, Displayable, Storable, SystemImage case landscape case portrait - // TODO: localize var displayTitle: String { switch self { case .landscape: - "Landscape" + L10n.landscape case .portrait: - "Portrait" + L10n.portrait } } diff --git a/Shared/Objects/SliderType.swift b/Shared/Objects/SliderType.swift index fcf5bab0..22d7db62 100644 --- a/Shared/Objects/SliderType.swift +++ b/Shared/Objects/SliderType.swift @@ -17,9 +17,9 @@ enum SliderType: String, CaseIterable, Displayable, Defaults.Serializable { var displayTitle: String { switch self { case .thumb: - return "Thumb" + return L10n.thumbSlider case .capsule: - return "Capsule" + return L10n.capsule } } } diff --git a/Shared/Objects/TimeStampType.swift b/Shared/Objects/TimeStampType.swift index 51847bac..35a90d2c 100644 --- a/Shared/Objects/TimeStampType.swift +++ b/Shared/Objects/TimeStampType.swift @@ -17,7 +17,7 @@ enum TimestampType: String, CaseIterable, Defaults.Serializable, Displayable { var displayTitle: String { switch self { case .split: - return "Split" + return L10n.split case .compact: return L10n.compact } diff --git a/Shared/Objects/TrailingTimestampType.swift b/Shared/Objects/TrailingTimestampType.swift index 916fb494..acedb24b 100644 --- a/Shared/Objects/TrailingTimestampType.swift +++ b/Shared/Objects/TrailingTimestampType.swift @@ -17,9 +17,9 @@ enum TrailingTimestampType: String, CaseIterable, Displayable, Defaults.Serializ var displayTitle: String { switch self { case .timeLeft: - return "Time left" + return L10n.timeLeft case .totalTime: - return "Total time" + return L10n.totalTime } } } diff --git a/Shared/Objects/UserAccessPolicy.swift b/Shared/Objects/UserAccessPolicy.swift index d9fa1371..029d6dd9 100644 --- a/Shared/Objects/UserAccessPolicy.swift +++ b/Shared/Objects/UserAccessPolicy.swift @@ -23,7 +23,7 @@ enum UserAccessPolicy: String, CaseIterable, Codable, Displayable { case .none: L10n.none case .requireDeviceAuthentication: - "Device Authentication" + L10n.deviceAuth case .requirePin: L10n.pin } diff --git a/Shared/Objects/VideoPlayerType/VideoPlayerType.swift b/Shared/Objects/VideoPlayerType/VideoPlayerType.swift index f3d23c94..fe20f8a3 100644 --- a/Shared/Objects/VideoPlayerType/VideoPlayerType.swift +++ b/Shared/Objects/VideoPlayerType/VideoPlayerType.swift @@ -19,7 +19,7 @@ enum VideoPlayerType: String, CaseIterable, Defaults.Serializable, Displayable { var displayTitle: String { switch self { case .native: - "Native" + L10n.native case .swiftfin: "Swiftfin" } diff --git a/Shared/Strings/Strings.swift b/Shared/Strings/Strings.swift index 452ebc8c..5f902658 100644 --- a/Shared/Strings/Strings.swift +++ b/Shared/Strings/Strings.swift @@ -128,6 +128,8 @@ internal enum L10n { internal static let art = L10n.tr("Localizable", "art", fallback: "Art") /// Artist internal static let artist = L10n.tr("Localizable", "artist", fallback: "Artist") + /// Ascending + internal static let ascending = L10n.tr("Localizable", "ascending", fallback: "Ascending") /// Aspect Fill internal static let aspectFill = L10n.tr("Localizable", "aspectFill", fallback: "Aspect Fill") /// Audio @@ -238,6 +240,8 @@ internal enum L10n { internal static let box = L10n.tr("Localizable", "box", fallback: "Box") /// BoxRear internal static let boxRear = L10n.tr("Localizable", "boxRear", fallback: "BoxRear") + /// Brightness + internal static let brightness = L10n.tr("Localizable", "brightness", fallback: "Brightness") /// Bugs and Features internal static let bugsAndFeatures = L10n.tr("Localizable", "bugsAndFeatures", fallback: "Bugs and Features") /// Buttons @@ -250,12 +254,16 @@ internal enum L10n { internal static let cannotConnectToHost = L10n.tr("Localizable", "cannotConnectToHost", fallback: "Cannot connect to host") /// Capabilities internal static let capabilities = L10n.tr("Localizable", "capabilities", fallback: "Capabilities") + /// Capsule + internal static let capsule = L10n.tr("Localizable", "capsule", fallback: "Capsule") /// Cast & Crew internal static let castAndCrew = L10n.tr("Localizable", "castAndCrew", fallback: "Cast & Crew") /// Category internal static let category = L10n.tr("Localizable", "category", fallback: "Category") /// Change Pin internal static let changePin = L10n.tr("Localizable", "changePin", fallback: "Change Pin") + /// Channel display + internal static let channelDisplay = L10n.tr("Localizable", "channelDisplay", fallback: "Channel display") /// Channels internal static let channels = L10n.tr("Localizable", "channels", fallback: "Channels") /// Chapter @@ -282,6 +290,10 @@ internal enum L10n { internal static let colorist = L10n.tr("Localizable", "colorist", fallback: "Colorist") /// Columns internal static let columns = L10n.tr("Localizable", "columns", fallback: "Columns") + /// Columns: %@ + internal static func columnsWithCount(_ p1: Any) -> String { + return L10n.tr("Localizable", "columnsWithCount", String(describing: p1), fallback: "Columns: %@") + } /// Community internal static let community = L10n.tr("Localizable", "community", fallback: "Community") /// Community rating @@ -304,6 +316,10 @@ internal enum L10n { internal static let conductor = L10n.tr("Localizable", "conductor", fallback: "Conductor") /// Confirm internal static let confirm = L10n.tr("Localizable", "confirm", fallback: "Confirm") + /// Are you sure you want to delete %@ and all of its connected users? + internal static func confirmDeleteServerAndUsers(_ p1: Any) -> String { + return L10n.tr("Localizable", "confirmDeleteServerAndUsers", String(describing: p1), fallback: "Are you sure you want to delete %@ and all of its connected users?") + } /// Confirm New Password internal static let confirmNewPassword = L10n.tr("Localizable", "confirmNewPassword", fallback: "Confirm New Password") /// Confirm Password @@ -408,6 +424,8 @@ internal enum L10n { internal static let dayOfWeek = L10n.tr("Localizable", "dayOfWeek", fallback: "Day of Week") /// Days internal static let days = L10n.tr("Localizable", "days", fallback: "Days") + /// Decrease playback speed + internal static let decreasePlaybackSpeed = L10n.tr("Localizable", "decreasePlaybackSpeed", fallback: "Decrease playback speed") /// Default internal static let `default` = L10n.tr("Localizable", "default", fallback: "Default") /// Admins are locked out after 5 failed attempts. Non-admins are locked out after 3 attempts. @@ -482,12 +500,18 @@ internal enum L10n { internal static let deletion = L10n.tr("Localizable", "deletion", fallback: "Deletion") /// Delivery internal static let delivery = L10n.tr("Localizable", "delivery", fallback: "Delivery") + /// Descending + internal static let descending = L10n.tr("Localizable", "descending", fallback: "Descending") + /// Detailed + internal static let detailed = L10n.tr("Localizable", "detailed", fallback: "Detailed") /// Details internal static let details = L10n.tr("Localizable", "details", fallback: "Details") /// Device internal static let device = L10n.tr("Localizable", "device", fallback: "Device") /// Device Access internal static let deviceAccess = L10n.tr("Localizable", "deviceAccess", fallback: "Device Access") + /// Device authentication + internal static let deviceAuth = L10n.tr("Localizable", "deviceAuth", fallback: "Device authentication") /// Device authentication failed internal static let deviceAuthFailed = L10n.tr("Localizable", "deviceAuthFailed", fallback: "Device authentication failed") /// Device Profile @@ -540,8 +564,8 @@ internal enum L10n { internal static let dvd = L10n.tr("Localizable", "dvd", fallback: "DVD") /// Edit internal static let edit = L10n.tr("Localizable", "edit", fallback: "Edit") - /// Edit collections - internal static let editCollections = L10n.tr("Localizable", "editCollections", fallback: "Edit collections") + /// Edit Collections + internal static let editCollections = L10n.tr("Localizable", "editCollections", fallback: "Edit Collections") /// Edit media internal static let editMedia = L10n.tr("Localizable", "editMedia", fallback: "Edit media") /// Editor @@ -648,8 +672,14 @@ internal enum L10n { internal static let genres = L10n.tr("Localizable", "genres", fallback: "Genres") /// Categories that describe the themes or styles of media. internal static let genresDescription = L10n.tr("Localizable", "genresDescription", fallback: "Categories that describe the themes or styles of media.") + /// Gesture lock + internal static let gestureLock = L10n.tr("Localizable", "gestureLock", fallback: "Gesture lock") /// Gestures internal static let gestures = L10n.tr("Localizable", "gestures", fallback: "Gestures") + /// Gestures locked + internal static let gesturesLocked = L10n.tr("Localizable", "gesturesLocked", fallback: "Gestures locked") + /// Gestures unlocked + internal static let gesturesUnlocked = L10n.tr("Localizable", "gesturesUnlocked", fallback: "Gestures unlocked") /// Gbps internal static let gigabitsPerSecond = L10n.tr("Localizable", "gigabitsPerSecond", fallback: "Gbps") /// Green @@ -690,6 +720,12 @@ internal enum L10n { internal static let images = L10n.tr("Localizable", "images", fallback: "Images") /// Image source internal static let imageSource = L10n.tr("Localizable", "imageSource", fallback: "Image source") + /// Incorrect pin for %@ + internal static func incorrectPinForUser(_ p1: Any) -> String { + return L10n.tr("Localizable", "incorrectPinForUser", String(describing: p1), fallback: "Incorrect pin for %@") + } + /// Increase playback speed + internal static let increasePlaybackSpeed = L10n.tr("Localizable", "increasePlaybackSpeed", fallback: "Increase playback speed") /// Index internal static let index = L10n.tr("Localizable", "index", fallback: "Index") /// Index number @@ -732,8 +768,12 @@ internal enum L10n { internal static let kids = L10n.tr("Localizable", "kids", fallback: "Kids") /// kbps internal static let kilobitsPerSecond = L10n.tr("Localizable", "kilobitsPerSecond", fallback: "kbps") + /// Landscape + internal static let landscape = L10n.tr("Localizable", "landscape", fallback: "Landscape") /// Language internal static let language = L10n.tr("Localizable", "language", fallback: "Language") + /// Large + internal static let large = L10n.tr("Localizable", "large", fallback: "Large") /// Larger internal static let larger = L10n.tr("Localizable", "larger", fallback: "Larger") /// Largest @@ -752,8 +792,8 @@ internal enum L10n { } /// Layout internal static let layout = L10n.tr("Localizable", "layout", fallback: "Layout") - /// Learn more... - internal static let learnMoreEllipsis = L10n.tr("Localizable", "learnMoreEllipsis", fallback: "Learn more...") + /// Learn more + internal static let learnMore = L10n.tr("Localizable", "learnMore", fallback: "Learn more") /// Left internal static let `left` = L10n.tr("Localizable", "left", fallback: "Left") /// Left vertical pan @@ -766,6 +806,8 @@ internal enum L10n { internal static let letterPicker = L10n.tr("Localizable", "letterPicker", fallback: "Letter Picker") /// Level internal static let level = L10n.tr("Localizable", "level", fallback: "Level") + /// Libraries + internal static let libraries = L10n.tr("Localizable", "libraries", fallback: "Libraries") /// Library internal static let library = L10n.tr("Localizable", "library", fallback: "Library") /// Light @@ -874,6 +916,8 @@ internal enum L10n { internal static let mvc = L10n.tr("Localizable", "mvc", fallback: "MVC") /// Name internal static let name = L10n.tr("Localizable", "name", fallback: "Name") + /// Native + internal static let native = L10n.tr("Localizable", "native", fallback: "Native") /// Native Player internal static let nativePlayer = L10n.tr("Localizable", "nativePlayer", fallback: "Native Player") /// Network timed out @@ -970,6 +1014,8 @@ internal enum L10n { internal static let passwordChangeWarning = L10n.tr("Localizable", "passwordChangeWarning", fallback: "Changes the Jellyfin server user password. This does not change any Swiftfin settings.") /// New passwords do not match. internal static let passwordsDoNotMatch = L10n.tr("Localizable", "passwordsDoNotMatch", fallback: "New passwords do not match.") + /// Pause + internal static let pause = L10n.tr("Localizable", "pause", fallback: "Pause") /// Pause on background internal static let pauseOnBackground = L10n.tr("Localizable", "pauseOnBackground", fallback: "Pause on background") /// Penciller @@ -1008,6 +1054,8 @@ internal enum L10n { internal static let playOnActive = L10n.tr("Localizable", "playOnActive", fallback: "Play on active") /// Play Previous Item internal static let playPreviousItem = L10n.tr("Localizable", "playPreviousItem", fallback: "Play Previous Item") + /// Portrait + internal static let portrait = L10n.tr("Localizable", "portrait", fallback: "Portrait") /// Posters internal static let posters = L10n.tr("Localizable", "posters", fallback: "Posters") /// Premiere Date @@ -1108,6 +1156,8 @@ internal enum L10n { internal static let remux = L10n.tr("Localizable", "remux", fallback: "Remux") /// Reorder internal static let reorder = L10n.tr("Localizable", "reorder", fallback: "Reorder") + /// Replace + internal static let replace = L10n.tr("Localizable", "replace", fallback: "Replace") /// Replace All internal static let replaceAll = L10n.tr("Localizable", "replaceAll", fallback: "Replace All") /// Replace all unlocked metadata and images with new information. @@ -1140,6 +1190,8 @@ internal enum L10n { internal static let resetAllSettings = L10n.tr("Localizable", "resetAllSettings", fallback: "Reset all settings back to defaults.") /// Reset the filter values to none. internal static let resetFilterFooter = L10n.tr("Localizable", "resetFilterFooter", fallback: "Reset the filter values to none.") + /// Reset playback speed + internal static let resetPlaybackSpeed = L10n.tr("Localizable", "resetPlaybackSpeed", fallback: "Reset playback speed") /// Reset Settings internal static let resetSettings = L10n.tr("Localizable", "resetSettings", fallback: "Reset Settings") /// Reset Swiftfin user settings @@ -1194,6 +1246,8 @@ internal enum L10n { internal static let score = L10n.tr("Localizable", "score", fallback: "Score") /// Screenshot internal static let screenshot = L10n.tr("Localizable", "screenshot", fallback: "Screenshot") + /// Scrub + internal static let scrub = L10n.tr("Localizable", "scrub", fallback: "Scrub") /// Scrub Current Time internal static let scrubCurrentTime = L10n.tr("Localizable", "scrubCurrentTime", fallback: "Scrub Current Time") /// Search @@ -1304,6 +1358,8 @@ internal enum L10n { internal static let sliderColor = L10n.tr("Localizable", "sliderColor", fallback: "Slider Color") /// Slider Type internal static let sliderType = L10n.tr("Localizable", "sliderType", fallback: "Slider Type") + /// Slow scrub + internal static let slowScrub = L10n.tr("Localizable", "slowScrub", fallback: "Slow scrub") /// Smaller internal static let smaller = L10n.tr("Localizable", "smaller", fallback: "Smaller") /// Smallest @@ -1322,6 +1378,8 @@ internal enum L10n { internal static let splashscreen = L10n.tr("Localizable", "splashscreen", fallback: "Splashscreen") /// When All Servers is selected, use the splashscreen from a single server or a random server internal static let splashscreenFooter = L10n.tr("Localizable", "splashscreenFooter", fallback: "When All Servers is selected, use the splashscreen from a single server or a random server") + /// Split + internal static let split = L10n.tr("Localizable", "split", fallback: "Split") /// Sports internal static let sports = L10n.tr("Localizable", "sports", fallback: "Sports") /// Start date @@ -1408,8 +1466,12 @@ internal enum L10n { internal static let themeVideo = L10n.tr("Localizable", "themeVideo", fallback: "Theme Video") /// Thumb internal static let thumb = L10n.tr("Localizable", "thumb", fallback: "Thumb") + /// Thumb + internal static let thumbSlider = L10n.tr("Localizable", "thumbSlider", fallback: "Thumb") /// Time internal static let time = L10n.tr("Localizable", "time", fallback: "Time") + /// Time left + internal static let timeLeft = L10n.tr("Localizable", "timeLeft", fallback: "Time left") /// Time Limit internal static let timeLimit = L10n.tr("Localizable", "timeLimit", fallback: "Time Limit") /// Time limit: %1$@ @@ -1422,6 +1484,8 @@ internal enum L10n { internal static let timestampType = L10n.tr("Localizable", "timestampType", fallback: "Timestamp Type") /// Title internal static let title = L10n.tr("Localizable", "title", fallback: "Title") + /// Total time + internal static let totalTime = L10n.tr("Localizable", "totalTime", fallback: "Total time") /// Trailer internal static let trailer = L10n.tr("Localizable", "trailer", fallback: "Trailer") /// Trailers @@ -1456,6 +1520,8 @@ internal enum L10n { internal static let unableToPerformDeviceAuth = L10n.tr("Localizable", "unableToPerformDeviceAuth", fallback: "Unable to perform device authentication") /// Unable to perform device authentication. You may need to enable Face ID in the Settings app for Swiftfin. internal static let unableToPerformDeviceAuthFaceID = L10n.tr("Localizable", "unableToPerformDeviceAuthFaceID", fallback: "Unable to perform device authentication. You may need to enable Face ID in the Settings app for Swiftfin.") + /// Unable to update custom name + internal static let unableToUpdateCustomName = L10n.tr("Localizable", "unableToUpdateCustomName", fallback: "Unable to update custom name") /// Unaired internal static let unaired = L10n.tr("Localizable", "unaired", fallback: "Unaired") /// Unauthorized @@ -1546,6 +1612,8 @@ internal enum L10n { internal static let videoTranscoding = L10n.tr("Localizable", "videoTranscoding", fallback: "Video transcoding") /// Some views may need an app restart to update. internal static let viewsMayRequireRestart = L10n.tr("Localizable", "viewsMayRequireRestart", fallback: "Some views may need an app restart to update.") + /// Volume + internal static let volume = L10n.tr("Localizable", "volume", fallback: "Volume") /// Votes internal static let votes = L10n.tr("Localizable", "votes", fallback: "Votes") /// Weekday diff --git a/Shared/ViewModels/AdminDashboard/DeviceDetailViewModel.swift b/Shared/ViewModels/AdminDashboard/DeviceDetailViewModel.swift index 6fbce1cd..c5ab681c 100644 --- a/Shared/ViewModels/AdminDashboard/DeviceDetailViewModel.swift +++ b/Shared/ViewModels/AdminDashboard/DeviceDetailViewModel.swift @@ -68,7 +68,7 @@ final class DeviceDetailViewModel: ViewModel, Stateful, Eventful { } } catch { await MainActor.run { - self.eventSubject.send(.error(.init("Unable to update custom name"))) + self.eventSubject.send(.error(.init(L10n.unableToUpdateCustomName))) } } diff --git a/Shared/ViewModels/SelectUserViewModel.swift b/Shared/ViewModels/SelectUserViewModel.swift index a09037f7..e778fe68 100644 --- a/Shared/ViewModels/SelectUserViewModel.swift +++ b/Shared/ViewModels/SelectUserViewModel.swift @@ -77,8 +77,7 @@ final class SelectUserViewModel: ViewModel, Eventful, Stateful { if user.accessPolicy == .requirePin, let storedPin = keychain.get("\(user.id)-pin") { if pin != storedPin { - eventSubject.send(.error(.init("Incorrect pin for \(user.username)"))) - + eventSubject.send(.error(.init(L10n.incorrectPinForUser(user.username)))) return .content } } diff --git a/Shared/ViewModels/UserLocalSecurityViewModel.swift b/Shared/ViewModels/UserLocalSecurityViewModel.swift index 91248012..55342d14 100644 --- a/Shared/ViewModels/UserLocalSecurityViewModel.swift +++ b/Shared/ViewModels/UserLocalSecurityViewModel.swift @@ -61,7 +61,7 @@ final class UserLocalSecurityViewModel: ViewModel, Eventful { if let storedPin = keychain.get("\(userSession.user.id)-pin") { if oldPin != storedPin { - eventSubject.send(.error(.init("Incorrect pin for \(userSession.user.username)"))) + eventSubject.send(.error(.init(L10n.incorrectPinForUser(userSession.user.username)))) throw JellyfinAPIError("invalid pin") } } diff --git a/Swiftfin tvOS/Views/ServerDetailView.swift b/Swiftfin tvOS/Views/ServerDetailView.swift index ba0ebbad..24c95bc9 100644 --- a/Swiftfin tvOS/Views/ServerDetailView.swift +++ b/Swiftfin tvOS/Views/ServerDetailView.swift @@ -85,7 +85,7 @@ struct EditServerView: View { router.popLast() } } message: { - Text("Are you sure you want to delete \(viewModel.server.name) and all of its connected users?") + Text(L10n.confirmDeleteServerAndUsers(viewModel.server.name)) } } } diff --git a/Swiftfin/Components/LearnMoreButton.swift b/Swiftfin/Components/LearnMoreButton.swift index d4b9e4fe..0f6e4060 100644 --- a/Swiftfin/Components/LearnMoreButton.swift +++ b/Swiftfin/Components/LearnMoreButton.swift @@ -26,7 +26,7 @@ struct LearnMoreButton: View { // MARK: - Body var body: some View { - Button(L10n.learnMoreEllipsis) { + Button(L10n.learnMore + "\u{2026}") { isPresented = true } .foregroundStyle(Color.accentColor) diff --git a/Swiftfin/Components/ListTitleSection.swift b/Swiftfin/Components/ListTitleSection.swift index c9d22a46..8fae6c08 100644 --- a/Swiftfin/Components/ListTitleSection.swift +++ b/Swiftfin/Components/ListTitleSection.swift @@ -33,7 +33,7 @@ struct ListTitleSection: View { } if let onLearnMore { - Button("Learn More\u{2026}", action: onLearnMore) + Button(L10n.learnMore + "\u{2026}", action: onLearnMore) } } .font(.subheadline) @@ -99,7 +99,7 @@ struct InsetGroupedListHeader: View { } if onLearnMore != nil { - Text("Learn More\u{2026}") + Text(L10n.learnMore + "\u{2026}") .foregroundStyle(accentColor) } } diff --git a/Swiftfin/Views/ChannelLibraryView/ChannelLibraryView.swift b/Swiftfin/Views/ChannelLibraryView/ChannelLibraryView.swift index 2df99f3b..194f9335 100644 --- a/Swiftfin/Views/ChannelLibraryView/ChannelLibraryView.swift +++ b/Swiftfin/Views/ChannelLibraryView/ChannelLibraryView.swift @@ -163,12 +163,12 @@ struct ChannelLibraryView: View { Menu { // We repurposed `LibraryDisplayType` but want different labels - Picker("Channel Display", selection: $channelDisplayType) { + Picker(L10n.channelDisplay, selection: $channelDisplayType) { Label(L10n.compact, systemImage: LibraryDisplayType.grid.systemImage) .tag(LibraryDisplayType.grid) - Label("Detailed", systemImage: LibraryDisplayType.list.systemImage) + Label(L10n.detailed, systemImage: LibraryDisplayType.list.systemImage) .tag(LibraryDisplayType.list) } } label: { diff --git a/Swiftfin/Views/EditServerView.swift b/Swiftfin/Views/EditServerView.swift index 2957db3b..5bb82132 100644 --- a/Swiftfin/Views/EditServerView.swift +++ b/Swiftfin/Views/EditServerView.swift @@ -72,7 +72,7 @@ struct EditServerView: View { router.popLast() } } message: { - Text("Are you sure you want to delete \(viewModel.server.name) and all of its connected users?") + Text(L10n.confirmDeleteServerAndUsers(viewModel.server.name)) } } } diff --git a/Swiftfin/Views/PagingLibraryView/Components/LibraryViewTypeToggle.swift b/Swiftfin/Views/PagingLibraryView/Components/LibraryViewTypeToggle.swift index e0a5999b..002777ac 100644 --- a/Swiftfin/Views/PagingLibraryView/Components/LibraryViewTypeToggle.swift +++ b/Swiftfin/Views/PagingLibraryView/Components/LibraryViewTypeToggle.swift @@ -37,14 +37,14 @@ extension PagingLibraryView { var body: some View { Menu { - Section("Poster") { + Section(L10n.posters) { Button { posterType = .landscape } label: { if posterType == .landscape { - Label("Landscape", systemImage: "checkmark") + Label(L10n.landscape, systemImage: "checkmark") } else { - Label("Landscape", systemImage: "rectangle") + Label(L10n.landscape, systemImage: "rectangle") } } @@ -52,9 +52,9 @@ extension PagingLibraryView { posterType = .portrait } label: { if posterType == .portrait { - Label("Portrait", systemImage: "checkmark") + Label(L10n.portrait, systemImage: "checkmark") } else { - Label("Portrait", systemImage: "rectangle.portrait") + Label(L10n.portrait, systemImage: "rectangle.portrait") } } } @@ -82,7 +82,7 @@ extension PagingLibraryView { } if viewType == .list, UIDevice.isPad { - Stepper("Columns: \(listColumnCount)", value: $listColumnCount, in: 1 ... 3) + Stepper(L10n.columnsWithCount(listColumnCount), value: $listColumnCount, in: 1 ... 3) } } label: { switch viewType { diff --git a/Swiftfin/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift b/Swiftfin/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift index 7c79ef08..988382d1 100644 --- a/Swiftfin/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift +++ b/Swiftfin/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift @@ -140,7 +140,7 @@ struct CustomizeViewsSettings: View { CaseIterablePicker(L10n.search, selection: $searchPosterType) } - Section("Libraries") { + Section(L10n.libraries) { CaseIterablePicker(L10n.library, selection: $libraryDisplayType) CaseIterablePicker(L10n.posters, selection: $libraryPosterType) diff --git a/Swiftfin/Views/UserSignInView/Components/UserSignInSecurityView.swift b/Swiftfin/Views/UserSignInView/Components/UserSignInSecurityView.swift index a431ea77..8815f704 100644 --- a/Swiftfin/Views/UserSignInView/Components/UserSignInSecurityView.swift +++ b/Swiftfin/Views/UserSignInView/Components/UserSignInSecurityView.swift @@ -49,7 +49,7 @@ extension UserSignInView { VStack(alignment: .leading, spacing: 10) { Text( - "Additional security for users signed in to this device. This does not change any Jellyfin server user settings." + L10n.additionalSecurityAccessDescription ) // frame necessary with bug within BulletedList diff --git a/Swiftfin/Views/VideoPlayer/LiveVideoPlayer.swift b/Swiftfin/Views/VideoPlayer/LiveVideoPlayer.swift index 32a6be53..4030ef7e 100644 --- a/Swiftfin/Views/VideoPlayer/LiveVideoPlayer.swift +++ b/Swiftfin/Views/VideoPlayer/LiveVideoPlayer.swift @@ -188,9 +188,9 @@ struct LiveVideoPlayer: View { } .onChange(of: isGestureLocked) { newValue in if newValue { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) } else { - updateViewProxy.present(systemName: "lock.open.fill", title: "Gestures Unlocked") + updateViewProxy.present(systemName: "lock.open.fill", title: L10n.gesturesUnlocked) } } .onChange(of: isScrubbing) { newValue in @@ -305,7 +305,7 @@ extension LiveVideoPlayer { private func handleTapGesture(unitPoint: UnitPoint, taps: Int) { guard !isGestureLocked else { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) return } @@ -330,7 +330,7 @@ extension LiveVideoPlayer { private func handleDoubleTouchGesture(unitPoint: UnitPoint, taps: Int) { guard !isGestureLocked else { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) return } diff --git a/Swiftfin/Views/VideoPlayer/VideoPlayer+KeyCommands.swift b/Swiftfin/Views/VideoPlayer/VideoPlayer+KeyCommands.swift index 5d6a0d4c..304e491a 100644 --- a/Swiftfin/Views/VideoPlayer/VideoPlayer+KeyCommands.swift +++ b/Swiftfin/Views/VideoPlayer/VideoPlayer+KeyCommands.swift @@ -55,10 +55,10 @@ struct VideoPlayerKeyCommandsModifier: ViewModifier { ) { if videoPlayerManager.state == .playing { videoPlayerManager.proxy.pause() - updateViewProxy.present(systemName: "pause.fill", title: "Pause") + updateViewProxy.present(systemName: "pause.fill", title: L10n.pause) } else { videoPlayerManager.proxy.play() - updateViewProxy.present(systemName: "play.fill", title: "Play") + updateViewProxy.present(systemName: "play.fill", title: L10n.play) } } @@ -139,7 +139,7 @@ struct VideoPlayerKeyCommandsModifier: ViewModifier { // MARK: aspect fill KeyCommandAction( - title: "Aspect Fill", + title: L10n.aspectFill, input: "f", modifierFlags: .command ) { @@ -151,7 +151,7 @@ struct VideoPlayerKeyCommandsModifier: ViewModifier { // MARK: decrease playback speed KeyCommandAction( - title: "Decrease Playback Speed", + title: L10n.decreasePlaybackSpeed, input: "[", modifierFlags: .command ) { @@ -171,7 +171,7 @@ struct VideoPlayerKeyCommandsModifier: ViewModifier { // MARK: increase playback speed KeyCommandAction( - title: "Increase Playback Speed", + title: L10n.increasePlaybackSpeed, input: "]", modifierFlags: .command ) { @@ -191,7 +191,7 @@ struct VideoPlayerKeyCommandsModifier: ViewModifier { // MARK: reset playback speed KeyCommandAction( - title: "Reset Playback Speed", + title: L10n.resetPlaybackSpeed, input: "\\", modifierFlags: .command ) { diff --git a/Swiftfin/Views/VideoPlayer/VideoPlayer.swift b/Swiftfin/Views/VideoPlayer/VideoPlayer.swift index 800966ef..861c7d9d 100644 --- a/Swiftfin/Views/VideoPlayer/VideoPlayer.swift +++ b/Swiftfin/Views/VideoPlayer/VideoPlayer.swift @@ -225,9 +225,9 @@ struct VideoPlayer: View { } .onChange(of: isGestureLocked) { newValue in if newValue { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) } else { - updateViewProxy.present(systemName: "lock.open.fill", title: "Gestures Unlocked") + updateViewProxy.present(systemName: "lock.open.fill", title: L10n.gesturesUnlocked) } } .onChange(of: isScrubbing) { newValue in @@ -352,7 +352,7 @@ extension VideoPlayer { private func handleTapGesture(unitPoint: UnitPoint, taps: Int) { guard !isGestureLocked else { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) return } @@ -382,7 +382,7 @@ extension VideoPlayer { } guard !isGestureLocked else { - updateViewProxy.present(systemName: "lock.fill", title: "Gestures Locked") + updateViewProxy.present(systemName: "lock.fill", title: L10n.gesturesLocked) return } diff --git a/Translations/en.lproj/Localizable.strings b/Translations/en.lproj/Localizable.strings index ae61fb82..20a358eb 100644 Binary files a/Translations/en.lproj/Localizable.strings and b/Translations/en.lproj/Localizable.strings differ