From c0b875ed2a0ab4bdd20633a25e2b280c81732270 Mon Sep 17 00:00:00 2001 From: Joe Kribs Date: Sun, 6 Apr 2025 16:05:33 -0600 Subject: [PATCH] [tvOS] Various Setting Cleanup (#1473) * Various setting cleanup * Remove Double headers * My gradient did nothing... So resetting back to less. * Reduce unnecessary formatting changes. * Revisions https://github.com/jellyfin/Swiftfin/pull/1473#pullrequestreview-2745279339 * Subtitles was missing brightness. Subtitle shouldn't mirror title but image. * Remove TODO. --- Shared/Strings/Strings.swift | 24 +++++++++++ Swiftfin tvOS/Components/ListRowMenu.swift | 42 +++++++++---------- .../OrderedSectionSelectorView.swift | 1 - .../Components/SplitFormWindowView.swift | 12 +----- Swiftfin tvOS/Views/FontPickerView.swift | 1 - Swiftfin tvOS/Views/ServerDetailView.swift | 1 - .../EditCustomDeviceProfileView.swift | 4 +- .../CustomDeviceProfileSettingsView.swift | 4 +- .../CustomizeViewsSettings.swift | 1 - .../SettingsView/IndicatorSettingsView.swift | 1 - .../UserProfileSettingsView.swift | 1 - .../VideoPlayerSettingsView.swift | 2 +- .../Views/UserSignInView/UserSignInView.swift | 5 ++- .../EditCustomDeviceProfileView.swift | 4 +- .../CustomDeviceProfileSettingsView.swift | 4 +- .../SettingsView/GestureSettingsView.swift | 16 +++---- Translations/en.lproj/Localizable.strings | 36 ++++++++++++++++ 17 files changed, 102 insertions(+), 57 deletions(-) diff --git a/Shared/Strings/Strings.swift b/Shared/Strings/Strings.swift index 43644754..ce44c590 100644 --- a/Shared/Strings/Strings.swift +++ b/Shared/Strings/Strings.swift @@ -512,6 +512,8 @@ internal enum L10n { internal static let displayOrder = L10n.tr("Localizable", "displayOrder", fallback: "Display Order") /// Done internal static let done = L10n.tr("Localizable", "done", fallback: "Done") + /// Double touch + internal static let doubleTouch = L10n.tr("Localizable", "doubleTouch", fallback: "Double touch") /// Downloads internal static let downloads = L10n.tr("Localizable", "downloads", fallback: "Downloads") /// Duplicate User @@ -646,6 +648,10 @@ internal enum L10n { internal static let hint = L10n.tr("Localizable", "hint", fallback: "Hint") /// Home internal static let home = L10n.tr("Localizable", "home", fallback: "Home") + /// Horizontal pan + internal static let horizontalPan = L10n.tr("Localizable", "horizontalPan", fallback: "Horizontal pan") + /// Horizontal swipe + internal static let horizontalSwipe = L10n.tr("Localizable", "horizontalSwipe", fallback: "Horizontal swipe") /// Hours internal static let hours = L10n.tr("Localizable", "hours", fallback: "Hours") /// ID @@ -724,6 +730,8 @@ internal enum L10n { internal static let learnMoreEllipsis = L10n.tr("Localizable", "learnMoreEllipsis", fallback: "Learn more...") /// Left internal static let `left` = L10n.tr("Localizable", "left", fallback: "Left") + /// Left vertical pan + internal static let leftVerticalPan = L10n.tr("Localizable", "leftVerticalPan", fallback: "Left vertical pan") /// Letter internal static let letter = L10n.tr("Localizable", "letter", fallback: "Letter") /// Letterer @@ -768,6 +776,8 @@ internal enum L10n { internal static let logs = L10n.tr("Localizable", "logs", fallback: "Logs") /// Access the Jellyfin server logs for troubleshooting and monitoring purposes. internal static let logsDescription = L10n.tr("Localizable", "logsDescription", fallback: "Access the Jellyfin server logs for troubleshooting and monitoring purposes.") + /// Long press + internal static let longPress = L10n.tr("Localizable", "longPress", fallback: "Long press") /// Lyricist internal static let lyricist = L10n.tr("Localizable", "lyricist", fallback: "Lyricist") /// Lyrics @@ -820,12 +830,16 @@ internal enum L10n { internal static let minutes = L10n.tr("Localizable", "minutes", fallback: "Minutes") /// Missing internal static let missing = L10n.tr("Localizable", "missing", fallback: "Missing") + /// Missing codec values + internal static let missingCodecValues = L10n.tr("Localizable", "missingCodecValues", fallback: "Missing codec values") /// Missing Items internal static let missingItems = L10n.tr("Localizable", "missingItems", fallback: "Missing Items") /// Mixer internal static let mixer = L10n.tr("Localizable", "mixer", fallback: "Mixer") /// Movies internal static let movies = L10n.tr("Localizable", "movies", fallback: "Movies") + /// Multi tap + internal static let multiTap = L10n.tr("Localizable", "multiTap", fallback: "Multi tap") /// Music internal static let music = L10n.tr("Localizable", "music", fallback: "Music") /// MVC @@ -860,6 +874,8 @@ internal enum L10n { internal static let nextUpRewatch = L10n.tr("Localizable", "nextUpRewatch", fallback: "Rewatching in Next Up") /// No internal static let no = L10n.tr("Localizable", "no", fallback: "No") + /// No profiles defined. Playback issues may occur. + internal static let noDeviceProfileWarning = L10n.tr("Localizable", "noDeviceProfileWarning", fallback: "No profiles defined. Playback issues may occur.") /// No episodes available internal static let noEpisodesAvailable = L10n.tr("Localizable", "noEpisodesAvailable", fallback: "No episodes available") /// No local servers found @@ -936,6 +952,8 @@ internal enum L10n { internal static let permissions = L10n.tr("Localizable", "permissions", fallback: "Permissions") /// Pin internal static let pin = L10n.tr("Localizable", "pin", fallback: "Pin") + /// Pinch + internal static let pinch = L10n.tr("Localizable", "pinch", fallback: "Pinch") /// Play internal static let play = L10n.tr("Localizable", "play", fallback: "Play") /// Play / Pause @@ -980,6 +998,8 @@ internal enum L10n { internal static let profile = L10n.tr("Localizable", "profile", fallback: "Profile") /// Profile Image internal static let profileImage = L10n.tr("Localizable", "profileImage", fallback: "Profile Image") + /// Profile not saved + internal static let profileNotSaved = L10n.tr("Localizable", "profileNotSaved", fallback: "Profile not saved") /// Profiles internal static let profiles = L10n.tr("Localizable", "profiles", fallback: "Profiles") /// Programs @@ -1058,6 +1078,8 @@ internal enum L10n { internal static let replaceAll = L10n.tr("Localizable", "replaceAll", fallback: "Replace All") /// Replace all unlocked metadata and images with new information. internal static let replaceAllDescription = L10n.tr("Localizable", "replaceAllDescription", fallback: "Replace all unlocked metadata and images with new information.") + /// Current profile values may cause playback issues + internal static let replaceDeviceProfileWarning = L10n.tr("Localizable", "replaceDeviceProfileWarning", fallback: "Current profile values may cause playback issues") /// Replace Images internal static let replaceImages = L10n.tr("Localizable", "replaceImages", fallback: "Replace Images") /// Replace all images with new images. @@ -1110,6 +1132,8 @@ internal enum L10n { internal static let reviews = L10n.tr("Localizable", "reviews", fallback: "Reviews") /// Right internal static let `right` = L10n.tr("Localizable", "right", fallback: "Right") + /// Right vertical pan + internal static let rightVerticalPan = L10n.tr("Localizable", "rightVerticalPan", fallback: "Right vertical pan") /// Role internal static let role = L10n.tr("Localizable", "role", fallback: "Role") /// Rotate diff --git a/Swiftfin tvOS/Components/ListRowMenu.swift b/Swiftfin tvOS/Components/ListRowMenu.swift index 660c6744..b6800ce1 100644 --- a/Swiftfin tvOS/Components/ListRowMenu.swift +++ b/Swiftfin tvOS/Components/ListRowMenu.swift @@ -25,32 +25,32 @@ struct ListRowMenu: View { var body: some View { Menu(content: content) { - ZStack { - RoundedRectangle(cornerRadius: 10) - .fill(isFocused ? Color.white : Color.clear) + HStack { + title + .foregroundStyle(isFocused ? .black : .white) + .padding(.leading, 4) - HStack { - title - .foregroundStyle(isFocused ? Color.black : Color.white) - .padding(.leading, 4) + Spacer() - Spacer() - - if let subtitle { - subtitle - .foregroundStyle(isFocused ? Color.black : Color.secondary) - .brightness(isFocused ? 0.4 : 0) - } - - Image(systemName: "chevron.up.chevron.down") - .font(.body.weight(.regular)) - .foregroundStyle(isFocused ? Color.black : Color.secondary) + if let subtitle { + subtitle + .foregroundStyle(isFocused ? .black : .secondary) .brightness(isFocused ? 0.4 : 0) } - .padding(.horizontal) + + Image(systemName: "chevron.up.chevron.down") + .font(.body.weight(.regular)) + .foregroundStyle(isFocused ? .black : .secondary) + .brightness(isFocused ? 0.4 : 0) } - .scaleEffect(isFocused ? 1.05 : 1.0) - .animation(.spring(response: 0.15, dampingFraction: 0.75), value: isFocused) + .padding(.horizontal) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) + .background( + RoundedRectangle(cornerRadius: 10) + .fill(isFocused ? Color.white : Color.clear) + ) + .scaleEffect(isFocused ? 1.04 : 1.0) + .animation(.easeInOut(duration: 0.125), value: isFocused) } .menuStyle(.borderlessButton) .listRowInsets(.zero) diff --git a/Swiftfin tvOS/Components/OrderedSectionSelectorView.swift b/Swiftfin tvOS/Components/OrderedSectionSelectorView.swift index 9b958c64..8319c0f3 100644 --- a/Swiftfin tvOS/Components/OrderedSectionSelectorView.swift +++ b/Swiftfin tvOS/Components/OrderedSectionSelectorView.swift @@ -90,7 +90,6 @@ struct OrderedSectionSelectorView: View { } .environment(\.editMode, editMode) } - .withDescriptionTopPadding() .animation(.linear(duration: 0.2), value: selection.value) } } diff --git a/Swiftfin tvOS/Components/SplitFormWindowView.swift b/Swiftfin tvOS/Components/SplitFormWindowView.swift index 3d44c38c..e434030d 100644 --- a/Swiftfin tvOS/Components/SplitFormWindowView.swift +++ b/Swiftfin tvOS/Components/SplitFormWindowView.swift @@ -8,12 +8,8 @@ import SwiftUI -// TODO: See if `descriptionTopPadding` is really necessary to fix the navigation bar padding, or just add all the time - struct SplitFormWindowView: View { - private var descriptionTopPadding: Bool = false - private var contentView: () -> any View private var descriptionView: () -> any View @@ -28,9 +24,7 @@ struct SplitFormWindowView: View { contentView() .eraseToAnyView() } - .if(descriptionTopPadding) { view in - view.padding(.top) - } + .padding(.top) .scrollClipDisabled() } } @@ -52,8 +46,4 @@ extension SplitFormWindowView { func descriptionView(@ViewBuilder _ content: @escaping () -> any View) -> Self { copy(modifying: \.descriptionView, with: content) } - - func withDescriptionTopPadding() -> Self { - copy(modifying: \.descriptionTopPadding, with: true) - } } diff --git a/Swiftfin tvOS/Views/FontPickerView.swift b/Swiftfin tvOS/Views/FontPickerView.swift index c82ed374..2e9d4889 100644 --- a/Swiftfin tvOS/Views/FontPickerView.swift +++ b/Swiftfin tvOS/Views/FontPickerView.swift @@ -49,6 +49,5 @@ struct FontPickerView: View { } } } - .withDescriptionTopPadding() } } diff --git a/Swiftfin tvOS/Views/ServerDetailView.swift b/Swiftfin tvOS/Views/ServerDetailView.swift index f7d90d6e..ba0ebbad 100644 --- a/Swiftfin tvOS/Views/ServerDetailView.swift +++ b/Swiftfin tvOS/Views/ServerDetailView.swift @@ -78,7 +78,6 @@ struct EditServerView: View { } } } - .withDescriptionTopPadding() .navigationTitle(L10n.server) .alert(L10n.deleteServer, isPresented: $isPresentingConfirmDeletion) { Button(L10n.delete, role: .destructive) { diff --git a/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift b/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift index 96d67b7d..0d6dac54 100644 --- a/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift +++ b/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift @@ -130,11 +130,11 @@ extension CustomDeviceProfileSettingsView { .padding(.vertical) if !isValid { - Label("Current profile values may cause playback issues", systemImage: "exclamationmark.circle.fill") + Label(L10n.replaceDeviceProfileWarning, systemImage: "exclamationmark.circle.fill") } } .navigationTitle(L10n.customProfile) - .alert("Profile not saved", isPresented: $isPresentingNotSaved) { + .alert(L10n.profileNotSaved, isPresented: $isPresentingNotSaved) { Button(L10n.close, role: .destructive) { router.dismissCoordinator() } diff --git a/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift b/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift index d6b7b534..3ffa88bf 100644 --- a/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift +++ b/Swiftfin tvOS/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift @@ -58,14 +58,14 @@ struct CustomDeviceProfileSettingsView: View { } if !isValid { - Label("No profiles defined. Playback issues may occur.", systemImage: "exclamationmark.circle.fill") + Label(L10n.noDeviceProfileWarning, systemImage: "exclamationmark.circle.fill") } } } Section { if customProfiles.isEmpty { - Button("Add profile") { + Button(L10n.add) { router.route(to: \.createCustomDeviceProfile) } } diff --git a/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift b/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift index 2b26db73..ddde6926 100644 --- a/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift +++ b/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings/CustomizeViewsSettings.swift @@ -77,7 +77,6 @@ struct CustomizeViewsSettings: View { HomeSection() } - .withDescriptionTopPadding() .navigationTitle(L10n.customize) } } diff --git a/Swiftfin tvOS/Views/SettingsView/IndicatorSettingsView.swift b/Swiftfin tvOS/Views/SettingsView/IndicatorSettingsView.swift index 565301c8..cd456456 100644 --- a/Swiftfin tvOS/Views/SettingsView/IndicatorSettingsView.swift +++ b/Swiftfin tvOS/Views/SettingsView/IndicatorSettingsView.swift @@ -43,7 +43,6 @@ struct IndicatorSettingsView: View { Toggle(L10n.showWatched, isOn: $showWatched) } } - .withDescriptionTopPadding() .navigationTitle(L10n.indicators) } } diff --git a/Swiftfin tvOS/Views/SettingsView/UserProfileSettingsView/UserProfileSettingsView.swift b/Swiftfin tvOS/Views/SettingsView/UserProfileSettingsView/UserProfileSettingsView.swift index 043b3509..9d0c1116 100644 --- a/Swiftfin tvOS/Views/SettingsView/UserProfileSettingsView/UserProfileSettingsView.swift +++ b/Swiftfin tvOS/Views/SettingsView/UserProfileSettingsView/UserProfileSettingsView.swift @@ -71,7 +71,6 @@ struct UserProfileSettingsView: View { // Text(L10n.resetSettingsDescription) // } } - .withDescriptionTopPadding() .navigationTitle(L10n.user) .confirmationDialog( L10n.resetSettings, diff --git a/Swiftfin tvOS/Views/SettingsView/VideoPlayerSettingsView.swift b/Swiftfin tvOS/Views/SettingsView/VideoPlayerSettingsView.swift index 139bbacb..d144d2d0 100644 --- a/Swiftfin tvOS/Views/SettingsView/VideoPlayerSettingsView.swift +++ b/Swiftfin tvOS/Views/SettingsView/VideoPlayerSettingsView.swift @@ -73,7 +73,6 @@ struct VideoPlayerSettingsView: View { Toggle(L10n.pauseOnBackground, isOn: $pauseOnBackground) Toggle(L10n.playOnActive, isOn: $playOnActive) } - .navigationTitle(L10n.videoPlayer.text) .blurredFullScreenCover(isPresented: $isPresentingResumeOffsetStepper) { StepperView( title: L10n.resumeOffsetTitle, @@ -90,5 +89,6 @@ struct VideoPlayerSettingsView: View { } } } + .navigationTitle(L10n.videoPlayer) } } diff --git a/Swiftfin tvOS/Views/UserSignInView/UserSignInView.swift b/Swiftfin tvOS/Views/UserSignInView/UserSignInView.swift index 6bfc5b77..2c683029 100644 --- a/Swiftfin tvOS/Views/UserSignInView/UserSignInView.swift +++ b/Swiftfin tvOS/Views/UserSignInView/UserSignInView.swift @@ -102,12 +102,13 @@ struct UserSignInView: View { } viewModel.send(.signIn(username: username, password: password, policy: .none)) } + .padding(.bottom) if case .signingIn = viewModel.state { ListRowButton(L10n.cancel, role: .cancel) { viewModel.send(.cancel) } - .padding(.vertical) + .padding(.bottom) } else { ListRowButton(L10n.signIn) { viewModel.send(.signIn(username: username, password: password, policy: .none)) @@ -118,7 +119,7 @@ struct UserSignInView: View { username.isEmpty ? Color.white.opacity(0.5) : accentColor ) .opacity(username.isEmpty ? 0.5 : 1) - .padding(.vertical) + .padding(.bottom) } if viewModel.isQuickConnectEnabled { diff --git a/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift b/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift index b66cf2bf..e19de04b 100644 --- a/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift +++ b/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/Components/EditCustomDeviceProfileView.swift @@ -110,7 +110,7 @@ extension CustomDeviceProfileSettingsView { } } footer: { if !isValid { - Label("Missing codec values", systemImage: "exclamationmark.circle.fill") + Label(L10n.missingCodecValues, systemImage: "exclamationmark.circle.fill") .labelStyle(.sectionFooterWithImage(imageStyle: .orange)) } } @@ -136,7 +136,7 @@ extension CustomDeviceProfileSettingsView { .buttonStyle(.toolbarPill) .disabled(!isValid) } - .alert("Profile not saved", isPresented: $isPresentingNotSaved) { + .alert(L10n.profileNotSaved, isPresented: $isPresentingNotSaved) { Button(L10n.close, role: .destructive) { router.dismissCoordinator() } diff --git a/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift b/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift index b7490a77..861c2cf2 100644 --- a/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift +++ b/Swiftfin/Views/SettingsView/CustomDeviceProfileSettingsView/CustomDeviceProfileSettingsView.swift @@ -47,7 +47,7 @@ struct CustomDeviceProfileSettingsView: View { } if !isValid { - Label("No profiles defined. Playback issues may occur.", systemImage: "exclamationmark.circle.fill") + Label(L10n.noDeviceProfileWarning, systemImage: "exclamationmark.circle.fill") .labelStyle(.sectionFooterWithImage(imageStyle: .orange)) } } @@ -56,7 +56,7 @@ struct CustomDeviceProfileSettingsView: View { Section(L10n.profiles) { if customProfiles.isEmpty { - Button("Add profile") { + Button(L10n.add) { router.route(to: \.createCustomDeviceProfile) } } diff --git a/Swiftfin/Views/SettingsView/GestureSettingsView.swift b/Swiftfin/Views/SettingsView/GestureSettingsView.swift index a84e816a..92954185 100644 --- a/Swiftfin/Views/SettingsView/GestureSettingsView.swift +++ b/Swiftfin/Views/SettingsView/GestureSettingsView.swift @@ -38,23 +38,23 @@ struct GestureSettingsView: View { Section { - CaseIterablePicker("Horizontal Pan", selection: $horizontalPanGesture) + CaseIterablePicker(L10n.horizontalPan, selection: $horizontalPanGesture) .disabled(horizontalSwipeGesture != .none && horizontalPanGesture == .none) - CaseIterablePicker("Horizontal Swipe", selection: $horizontalSwipeGesture) + CaseIterablePicker(L10n.horizontalSwipe, selection: $horizontalSwipeGesture) .disabled(horizontalPanGesture != .none && horizontalSwipeGesture == .none) - CaseIterablePicker("Long Press", selection: $longPressGesture) + CaseIterablePicker(L10n.longPress, selection: $longPressGesture) - CaseIterablePicker("Multi Tap", selection: $multiTapGesture) + CaseIterablePicker(L10n.multiTap, selection: $multiTapGesture) - CaseIterablePicker("Double Touch", selection: $doubleTouchGesture) + CaseIterablePicker(L10n.doubleTouch, selection: $doubleTouchGesture) - CaseIterablePicker("Pinch", selection: $pinchGesture) + CaseIterablePicker(L10n.pinch, selection: $pinchGesture) - CaseIterablePicker("Left Vertical Pan", selection: $verticalPanGestureLeft) + CaseIterablePicker(L10n.leftVerticalPan, selection: $verticalPanGestureLeft) - CaseIterablePicker("Right Vertical Pan", selection: $verticalPanGestureRight) + CaseIterablePicker(L10n.rightVerticalPan, selection: $verticalPanGestureRight) } } .navigationTitle(L10n.gestures) diff --git a/Translations/en.lproj/Localizable.strings b/Translations/en.lproj/Localizable.strings index 662fd507..a935b5ed 100644 --- a/Translations/en.lproj/Localizable.strings +++ b/Translations/en.lproj/Localizable.strings @@ -724,6 +724,9 @@ /// Done "done" = "Done"; +/// Double touch +"doubleTouch" = "Double touch"; + /// Downloads "downloads" = "Downloads"; @@ -913,6 +916,12 @@ /// Home "home" = "Home"; +/// Horizontal pan +"horizontalPan" = "Horizontal pan"; + +/// Horizontal swipe +"horizontalSwipe" = "Horizontal swipe"; + /// Hours "hours" = "Hours"; @@ -1021,6 +1030,9 @@ /// Left "left" = "Left"; +/// Left vertical pan +"leftVerticalPan" = "Left vertical pan"; + /// Letter "letter" = "Letter"; @@ -1087,6 +1099,9 @@ /// Access the Jellyfin server logs for troubleshooting and monitoring purposes. "logsDescription" = "Access the Jellyfin server logs for troubleshooting and monitoring purposes."; +/// Long press +"longPress" = "Long press"; + /// Lyricist "lyricist" = "Lyricist"; @@ -1165,6 +1180,9 @@ /// Missing "missing" = "Missing"; +/// Missing codec values +"missingCodecValues" = "Missing codec values"; + /// Missing Items "missingItems" = "Missing Items"; @@ -1174,6 +1192,9 @@ /// Movies "movies" = "Movies"; +/// Multi tap +"multiTap" = "Multi tap"; + /// Music "music" = "Music"; @@ -1225,6 +1246,9 @@ /// No "no" = "No"; +/// No profiles defined. Playback issues may occur. +"noDeviceProfileWarning" = "No profiles defined. Playback issues may occur."; + /// No episodes available "noEpisodesAvailable" = "No episodes available"; @@ -1336,6 +1360,9 @@ /// Pin "pin" = "Pin"; +/// Pinch +"pinch" = "Pinch"; + /// Play "play" = "Play"; @@ -1402,6 +1429,9 @@ /// Profile Image "profileImage" = "Profile Image"; +/// Profile not saved +"profileNotSaved" = "Profile not saved"; + /// Profiles "profiles" = "Profiles"; @@ -1516,6 +1546,9 @@ /// Replace all unlocked metadata and images with new information. "replaceAllDescription" = "Replace all unlocked metadata and images with new information."; +/// Current profile values may cause playback issues +"replaceDeviceProfileWarning" = "Current profile values may cause playback issues"; + /// Replace Images "replaceImages" = "Replace Images"; @@ -1591,6 +1624,9 @@ /// Right "right" = "Right"; +/// Right vertical pan +"rightVerticalPan" = "Right vertical pan"; + /// Role "role" = "Role";