[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.
This commit is contained in:
parent
df89832647
commit
c0b875ed2a
|
@ -512,6 +512,8 @@ internal enum L10n {
|
||||||
internal static let displayOrder = L10n.tr("Localizable", "displayOrder", fallback: "Display Order")
|
internal static let displayOrder = L10n.tr("Localizable", "displayOrder", fallback: "Display Order")
|
||||||
/// Done
|
/// Done
|
||||||
internal static let done = L10n.tr("Localizable", "done", fallback: "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
|
/// Downloads
|
||||||
internal static let downloads = L10n.tr("Localizable", "downloads", fallback: "Downloads")
|
internal static let downloads = L10n.tr("Localizable", "downloads", fallback: "Downloads")
|
||||||
/// Duplicate User
|
/// Duplicate User
|
||||||
|
@ -646,6 +648,10 @@ internal enum L10n {
|
||||||
internal static let hint = L10n.tr("Localizable", "hint", fallback: "Hint")
|
internal static let hint = L10n.tr("Localizable", "hint", fallback: "Hint")
|
||||||
/// Home
|
/// Home
|
||||||
internal static let home = L10n.tr("Localizable", "home", fallback: "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
|
/// Hours
|
||||||
internal static let hours = L10n.tr("Localizable", "hours", fallback: "Hours")
|
internal static let hours = L10n.tr("Localizable", "hours", fallback: "Hours")
|
||||||
/// ID
|
/// ID
|
||||||
|
@ -724,6 +730,8 @@ internal enum L10n {
|
||||||
internal static let learnMoreEllipsis = L10n.tr("Localizable", "learnMoreEllipsis", fallback: "Learn more...")
|
internal static let learnMoreEllipsis = L10n.tr("Localizable", "learnMoreEllipsis", fallback: "Learn more...")
|
||||||
/// Left
|
/// Left
|
||||||
internal static let `left` = L10n.tr("Localizable", "left", fallback: "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
|
/// Letter
|
||||||
internal static let letter = L10n.tr("Localizable", "letter", fallback: "Letter")
|
internal static let letter = L10n.tr("Localizable", "letter", fallback: "Letter")
|
||||||
/// Letterer
|
/// Letterer
|
||||||
|
@ -768,6 +776,8 @@ internal enum L10n {
|
||||||
internal static let logs = L10n.tr("Localizable", "logs", fallback: "Logs")
|
internal static let logs = L10n.tr("Localizable", "logs", fallback: "Logs")
|
||||||
/// Access the Jellyfin server logs for troubleshooting and monitoring purposes.
|
/// 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.")
|
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
|
/// Lyricist
|
||||||
internal static let lyricist = L10n.tr("Localizable", "lyricist", fallback: "Lyricist")
|
internal static let lyricist = L10n.tr("Localizable", "lyricist", fallback: "Lyricist")
|
||||||
/// Lyrics
|
/// Lyrics
|
||||||
|
@ -820,12 +830,16 @@ internal enum L10n {
|
||||||
internal static let minutes = L10n.tr("Localizable", "minutes", fallback: "Minutes")
|
internal static let minutes = L10n.tr("Localizable", "minutes", fallback: "Minutes")
|
||||||
/// Missing
|
/// Missing
|
||||||
internal static let missing = L10n.tr("Localizable", "missing", fallback: "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
|
/// Missing Items
|
||||||
internal static let missingItems = L10n.tr("Localizable", "missingItems", fallback: "Missing Items")
|
internal static let missingItems = L10n.tr("Localizable", "missingItems", fallback: "Missing Items")
|
||||||
/// Mixer
|
/// Mixer
|
||||||
internal static let mixer = L10n.tr("Localizable", "mixer", fallback: "Mixer")
|
internal static let mixer = L10n.tr("Localizable", "mixer", fallback: "Mixer")
|
||||||
/// Movies
|
/// Movies
|
||||||
internal static let movies = L10n.tr("Localizable", "movies", fallback: "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
|
/// Music
|
||||||
internal static let music = L10n.tr("Localizable", "music", fallback: "Music")
|
internal static let music = L10n.tr("Localizable", "music", fallback: "Music")
|
||||||
/// MVC
|
/// MVC
|
||||||
|
@ -860,6 +874,8 @@ internal enum L10n {
|
||||||
internal static let nextUpRewatch = L10n.tr("Localizable", "nextUpRewatch", fallback: "Rewatching in Next Up")
|
internal static let nextUpRewatch = L10n.tr("Localizable", "nextUpRewatch", fallback: "Rewatching in Next Up")
|
||||||
/// No
|
/// No
|
||||||
internal static let no = L10n.tr("Localizable", "no", fallback: "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
|
/// No episodes available
|
||||||
internal static let noEpisodesAvailable = L10n.tr("Localizable", "noEpisodesAvailable", fallback: "No episodes available")
|
internal static let noEpisodesAvailable = L10n.tr("Localizable", "noEpisodesAvailable", fallback: "No episodes available")
|
||||||
/// No local servers found
|
/// No local servers found
|
||||||
|
@ -936,6 +952,8 @@ internal enum L10n {
|
||||||
internal static let permissions = L10n.tr("Localizable", "permissions", fallback: "Permissions")
|
internal static let permissions = L10n.tr("Localizable", "permissions", fallback: "Permissions")
|
||||||
/// Pin
|
/// Pin
|
||||||
internal static let pin = L10n.tr("Localizable", "pin", fallback: "Pin")
|
internal static let pin = L10n.tr("Localizable", "pin", fallback: "Pin")
|
||||||
|
/// Pinch
|
||||||
|
internal static let pinch = L10n.tr("Localizable", "pinch", fallback: "Pinch")
|
||||||
/// Play
|
/// Play
|
||||||
internal static let play = L10n.tr("Localizable", "play", fallback: "Play")
|
internal static let play = L10n.tr("Localizable", "play", fallback: "Play")
|
||||||
/// Play / Pause
|
/// Play / Pause
|
||||||
|
@ -980,6 +998,8 @@ internal enum L10n {
|
||||||
internal static let profile = L10n.tr("Localizable", "profile", fallback: "Profile")
|
internal static let profile = L10n.tr("Localizable", "profile", fallback: "Profile")
|
||||||
/// Profile Image
|
/// Profile Image
|
||||||
internal static let profileImage = L10n.tr("Localizable", "profileImage", fallback: "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
|
/// Profiles
|
||||||
internal static let profiles = L10n.tr("Localizable", "profiles", fallback: "Profiles")
|
internal static let profiles = L10n.tr("Localizable", "profiles", fallback: "Profiles")
|
||||||
/// Programs
|
/// Programs
|
||||||
|
@ -1058,6 +1078,8 @@ internal enum L10n {
|
||||||
internal static let replaceAll = L10n.tr("Localizable", "replaceAll", fallback: "Replace All")
|
internal static let replaceAll = L10n.tr("Localizable", "replaceAll", fallback: "Replace All")
|
||||||
/// Replace all unlocked metadata and images with new information.
|
/// 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.")
|
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
|
/// Replace Images
|
||||||
internal static let replaceImages = L10n.tr("Localizable", "replaceImages", fallback: "Replace Images")
|
internal static let replaceImages = L10n.tr("Localizable", "replaceImages", fallback: "Replace Images")
|
||||||
/// Replace all images with new images.
|
/// Replace all images with new images.
|
||||||
|
@ -1110,6 +1132,8 @@ internal enum L10n {
|
||||||
internal static let reviews = L10n.tr("Localizable", "reviews", fallback: "Reviews")
|
internal static let reviews = L10n.tr("Localizable", "reviews", fallback: "Reviews")
|
||||||
/// Right
|
/// Right
|
||||||
internal static let `right` = L10n.tr("Localizable", "right", fallback: "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
|
/// Role
|
||||||
internal static let role = L10n.tr("Localizable", "role", fallback: "Role")
|
internal static let role = L10n.tr("Localizable", "role", fallback: "Role")
|
||||||
/// Rotate
|
/// Rotate
|
||||||
|
|
|
@ -25,32 +25,32 @@ struct ListRowMenu<Content: View, Subtitle: View>: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Menu(content: content) {
|
Menu(content: content) {
|
||||||
ZStack {
|
HStack {
|
||||||
RoundedRectangle(cornerRadius: 10)
|
title
|
||||||
.fill(isFocused ? Color.white : Color.clear)
|
.foregroundStyle(isFocused ? .black : .white)
|
||||||
|
.padding(.leading, 4)
|
||||||
|
|
||||||
HStack {
|
Spacer()
|
||||||
title
|
|
||||||
.foregroundStyle(isFocused ? Color.black : Color.white)
|
|
||||||
.padding(.leading, 4)
|
|
||||||
|
|
||||||
Spacer()
|
if let subtitle {
|
||||||
|
subtitle
|
||||||
if let subtitle {
|
.foregroundStyle(isFocused ? .black : .secondary)
|
||||||
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)
|
|
||||||
.brightness(isFocused ? 0.4 : 0)
|
.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)
|
.padding(.horizontal)
|
||||||
.animation(.spring(response: 0.15, dampingFraction: 0.75), value: isFocused)
|
.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)
|
.menuStyle(.borderlessButton)
|
||||||
.listRowInsets(.zero)
|
.listRowInsets(.zero)
|
||||||
|
|
|
@ -90,7 +90,6 @@ struct OrderedSectionSelectorView<Element: Displayable & Hashable>: View {
|
||||||
}
|
}
|
||||||
.environment(\.editMode, editMode)
|
.environment(\.editMode, editMode)
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
.animation(.linear(duration: 0.2), value: selection.value)
|
.animation(.linear(duration: 0.2), value: selection.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,8 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
// TODO: See if `descriptionTopPadding` is really necessary to fix the navigation bar padding, or just add all the time
|
|
||||||
|
|
||||||
struct SplitFormWindowView: View {
|
struct SplitFormWindowView: View {
|
||||||
|
|
||||||
private var descriptionTopPadding: Bool = false
|
|
||||||
|
|
||||||
private var contentView: () -> any View
|
private var contentView: () -> any View
|
||||||
private var descriptionView: () -> any View
|
private var descriptionView: () -> any View
|
||||||
|
|
||||||
|
@ -28,9 +24,7 @@ struct SplitFormWindowView: View {
|
||||||
contentView()
|
contentView()
|
||||||
.eraseToAnyView()
|
.eraseToAnyView()
|
||||||
}
|
}
|
||||||
.if(descriptionTopPadding) { view in
|
.padding(.top)
|
||||||
view.padding(.top)
|
|
||||||
}
|
|
||||||
.scrollClipDisabled()
|
.scrollClipDisabled()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,8 +46,4 @@ extension SplitFormWindowView {
|
||||||
func descriptionView(@ViewBuilder _ content: @escaping () -> any View) -> Self {
|
func descriptionView(@ViewBuilder _ content: @escaping () -> any View) -> Self {
|
||||||
copy(modifying: \.descriptionView, with: content)
|
copy(modifying: \.descriptionView, with: content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withDescriptionTopPadding() -> Self {
|
|
||||||
copy(modifying: \.descriptionTopPadding, with: true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,5 @@ struct FontPickerView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ struct EditServerView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
.navigationTitle(L10n.server)
|
.navigationTitle(L10n.server)
|
||||||
.alert(L10n.deleteServer, isPresented: $isPresentingConfirmDeletion) {
|
.alert(L10n.deleteServer, isPresented: $isPresentingConfirmDeletion) {
|
||||||
Button(L10n.delete, role: .destructive) {
|
Button(L10n.delete, role: .destructive) {
|
||||||
|
|
|
@ -130,11 +130,11 @@ extension CustomDeviceProfileSettingsView {
|
||||||
.padding(.vertical)
|
.padding(.vertical)
|
||||||
|
|
||||||
if !isValid {
|
if !isValid {
|
||||||
Label("Current profile values may cause playback issues", systemImage: "exclamationmark.circle.fill")
|
Label(L10n.replaceDeviceProfileWarning, systemImage: "exclamationmark.circle.fill")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle(L10n.customProfile)
|
.navigationTitle(L10n.customProfile)
|
||||||
.alert("Profile not saved", isPresented: $isPresentingNotSaved) {
|
.alert(L10n.profileNotSaved, isPresented: $isPresentingNotSaved) {
|
||||||
Button(L10n.close, role: .destructive) {
|
Button(L10n.close, role: .destructive) {
|
||||||
router.dismissCoordinator()
|
router.dismissCoordinator()
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,14 +58,14 @@ struct CustomDeviceProfileSettingsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValid {
|
if !isValid {
|
||||||
Label("No profiles defined. Playback issues may occur.", systemImage: "exclamationmark.circle.fill")
|
Label(L10n.noDeviceProfileWarning, systemImage: "exclamationmark.circle.fill")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
if customProfiles.isEmpty {
|
if customProfiles.isEmpty {
|
||||||
Button("Add profile") {
|
Button(L10n.add) {
|
||||||
router.route(to: \.createCustomDeviceProfile)
|
router.route(to: \.createCustomDeviceProfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,6 @@ struct CustomizeViewsSettings: View {
|
||||||
|
|
||||||
HomeSection()
|
HomeSection()
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
.navigationTitle(L10n.customize)
|
.navigationTitle(L10n.customize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ struct IndicatorSettingsView: View {
|
||||||
Toggle(L10n.showWatched, isOn: $showWatched)
|
Toggle(L10n.showWatched, isOn: $showWatched)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
.navigationTitle(L10n.indicators)
|
.navigationTitle(L10n.indicators)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ struct UserProfileSettingsView: View {
|
||||||
// Text(L10n.resetSettingsDescription)
|
// Text(L10n.resetSettingsDescription)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
.withDescriptionTopPadding()
|
|
||||||
.navigationTitle(L10n.user)
|
.navigationTitle(L10n.user)
|
||||||
.confirmationDialog(
|
.confirmationDialog(
|
||||||
L10n.resetSettings,
|
L10n.resetSettings,
|
||||||
|
|
|
@ -73,7 +73,6 @@ struct VideoPlayerSettingsView: View {
|
||||||
Toggle(L10n.pauseOnBackground, isOn: $pauseOnBackground)
|
Toggle(L10n.pauseOnBackground, isOn: $pauseOnBackground)
|
||||||
Toggle(L10n.playOnActive, isOn: $playOnActive)
|
Toggle(L10n.playOnActive, isOn: $playOnActive)
|
||||||
}
|
}
|
||||||
.navigationTitle(L10n.videoPlayer.text)
|
|
||||||
.blurredFullScreenCover(isPresented: $isPresentingResumeOffsetStepper) {
|
.blurredFullScreenCover(isPresented: $isPresentingResumeOffsetStepper) {
|
||||||
StepperView(
|
StepperView(
|
||||||
title: L10n.resumeOffsetTitle,
|
title: L10n.resumeOffsetTitle,
|
||||||
|
@ -90,5 +89,6 @@ struct VideoPlayerSettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationTitle(L10n.videoPlayer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,12 +102,13 @@ struct UserSignInView: View {
|
||||||
}
|
}
|
||||||
viewModel.send(.signIn(username: username, password: password, policy: .none))
|
viewModel.send(.signIn(username: username, password: password, policy: .none))
|
||||||
}
|
}
|
||||||
|
.padding(.bottom)
|
||||||
|
|
||||||
if case .signingIn = viewModel.state {
|
if case .signingIn = viewModel.state {
|
||||||
ListRowButton(L10n.cancel, role: .cancel) {
|
ListRowButton(L10n.cancel, role: .cancel) {
|
||||||
viewModel.send(.cancel)
|
viewModel.send(.cancel)
|
||||||
}
|
}
|
||||||
.padding(.vertical)
|
.padding(.bottom)
|
||||||
} else {
|
} else {
|
||||||
ListRowButton(L10n.signIn) {
|
ListRowButton(L10n.signIn) {
|
||||||
viewModel.send(.signIn(username: username, password: password, policy: .none))
|
viewModel.send(.signIn(username: username, password: password, policy: .none))
|
||||||
|
@ -118,7 +119,7 @@ struct UserSignInView: View {
|
||||||
username.isEmpty ? Color.white.opacity(0.5) : accentColor
|
username.isEmpty ? Color.white.opacity(0.5) : accentColor
|
||||||
)
|
)
|
||||||
.opacity(username.isEmpty ? 0.5 : 1)
|
.opacity(username.isEmpty ? 0.5 : 1)
|
||||||
.padding(.vertical)
|
.padding(.bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.isQuickConnectEnabled {
|
if viewModel.isQuickConnectEnabled {
|
||||||
|
|
|
@ -110,7 +110,7 @@ extension CustomDeviceProfileSettingsView {
|
||||||
}
|
}
|
||||||
} footer: {
|
} footer: {
|
||||||
if !isValid {
|
if !isValid {
|
||||||
Label("Missing codec values", systemImage: "exclamationmark.circle.fill")
|
Label(L10n.missingCodecValues, systemImage: "exclamationmark.circle.fill")
|
||||||
.labelStyle(.sectionFooterWithImage(imageStyle: .orange))
|
.labelStyle(.sectionFooterWithImage(imageStyle: .orange))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ extension CustomDeviceProfileSettingsView {
|
||||||
.buttonStyle(.toolbarPill)
|
.buttonStyle(.toolbarPill)
|
||||||
.disabled(!isValid)
|
.disabled(!isValid)
|
||||||
}
|
}
|
||||||
.alert("Profile not saved", isPresented: $isPresentingNotSaved) {
|
.alert(L10n.profileNotSaved, isPresented: $isPresentingNotSaved) {
|
||||||
Button(L10n.close, role: .destructive) {
|
Button(L10n.close, role: .destructive) {
|
||||||
router.dismissCoordinator()
|
router.dismissCoordinator()
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct CustomDeviceProfileSettingsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValid {
|
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))
|
.labelStyle(.sectionFooterWithImage(imageStyle: .orange))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ struct CustomDeviceProfileSettingsView: View {
|
||||||
Section(L10n.profiles) {
|
Section(L10n.profiles) {
|
||||||
|
|
||||||
if customProfiles.isEmpty {
|
if customProfiles.isEmpty {
|
||||||
Button("Add profile") {
|
Button(L10n.add) {
|
||||||
router.route(to: \.createCustomDeviceProfile)
|
router.route(to: \.createCustomDeviceProfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,23 +38,23 @@ struct GestureSettingsView: View {
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
|
|
||||||
CaseIterablePicker("Horizontal Pan", selection: $horizontalPanGesture)
|
CaseIterablePicker(L10n.horizontalPan, selection: $horizontalPanGesture)
|
||||||
.disabled(horizontalSwipeGesture != .none && horizontalPanGesture == .none)
|
.disabled(horizontalSwipeGesture != .none && horizontalPanGesture == .none)
|
||||||
|
|
||||||
CaseIterablePicker("Horizontal Swipe", selection: $horizontalSwipeGesture)
|
CaseIterablePicker(L10n.horizontalSwipe, selection: $horizontalSwipeGesture)
|
||||||
.disabled(horizontalPanGesture != .none && horizontalSwipeGesture == .none)
|
.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)
|
.navigationTitle(L10n.gestures)
|
||||||
|
|
|
@ -724,6 +724,9 @@
|
||||||
/// Done
|
/// Done
|
||||||
"done" = "Done";
|
"done" = "Done";
|
||||||
|
|
||||||
|
/// Double touch
|
||||||
|
"doubleTouch" = "Double touch";
|
||||||
|
|
||||||
/// Downloads
|
/// Downloads
|
||||||
"downloads" = "Downloads";
|
"downloads" = "Downloads";
|
||||||
|
|
||||||
|
@ -913,6 +916,12 @@
|
||||||
/// Home
|
/// Home
|
||||||
"home" = "Home";
|
"home" = "Home";
|
||||||
|
|
||||||
|
/// Horizontal pan
|
||||||
|
"horizontalPan" = "Horizontal pan";
|
||||||
|
|
||||||
|
/// Horizontal swipe
|
||||||
|
"horizontalSwipe" = "Horizontal swipe";
|
||||||
|
|
||||||
/// Hours
|
/// Hours
|
||||||
"hours" = "Hours";
|
"hours" = "Hours";
|
||||||
|
|
||||||
|
@ -1021,6 +1030,9 @@
|
||||||
/// Left
|
/// Left
|
||||||
"left" = "Left";
|
"left" = "Left";
|
||||||
|
|
||||||
|
/// Left vertical pan
|
||||||
|
"leftVerticalPan" = "Left vertical pan";
|
||||||
|
|
||||||
/// Letter
|
/// Letter
|
||||||
"letter" = "Letter";
|
"letter" = "Letter";
|
||||||
|
|
||||||
|
@ -1087,6 +1099,9 @@
|
||||||
/// Access the Jellyfin server logs for troubleshooting and monitoring purposes.
|
/// Access the Jellyfin server logs for troubleshooting and monitoring purposes.
|
||||||
"logsDescription" = "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" = "Lyricist";
|
"lyricist" = "Lyricist";
|
||||||
|
|
||||||
|
@ -1165,6 +1180,9 @@
|
||||||
/// Missing
|
/// Missing
|
||||||
"missing" = "Missing";
|
"missing" = "Missing";
|
||||||
|
|
||||||
|
/// Missing codec values
|
||||||
|
"missingCodecValues" = "Missing codec values";
|
||||||
|
|
||||||
/// Missing Items
|
/// Missing Items
|
||||||
"missingItems" = "Missing Items";
|
"missingItems" = "Missing Items";
|
||||||
|
|
||||||
|
@ -1174,6 +1192,9 @@
|
||||||
/// Movies
|
/// Movies
|
||||||
"movies" = "Movies";
|
"movies" = "Movies";
|
||||||
|
|
||||||
|
/// Multi tap
|
||||||
|
"multiTap" = "Multi tap";
|
||||||
|
|
||||||
/// Music
|
/// Music
|
||||||
"music" = "Music";
|
"music" = "Music";
|
||||||
|
|
||||||
|
@ -1225,6 +1246,9 @@
|
||||||
/// No
|
/// No
|
||||||
"no" = "No";
|
"no" = "No";
|
||||||
|
|
||||||
|
/// No profiles defined. Playback issues may occur.
|
||||||
|
"noDeviceProfileWarning" = "No profiles defined. Playback issues may occur.";
|
||||||
|
|
||||||
/// No episodes available
|
/// No episodes available
|
||||||
"noEpisodesAvailable" = "No episodes available";
|
"noEpisodesAvailable" = "No episodes available";
|
||||||
|
|
||||||
|
@ -1336,6 +1360,9 @@
|
||||||
/// Pin
|
/// Pin
|
||||||
"pin" = "Pin";
|
"pin" = "Pin";
|
||||||
|
|
||||||
|
/// Pinch
|
||||||
|
"pinch" = "Pinch";
|
||||||
|
|
||||||
/// Play
|
/// Play
|
||||||
"play" = "Play";
|
"play" = "Play";
|
||||||
|
|
||||||
|
@ -1402,6 +1429,9 @@
|
||||||
/// Profile Image
|
/// Profile Image
|
||||||
"profileImage" = "Profile Image";
|
"profileImage" = "Profile Image";
|
||||||
|
|
||||||
|
/// Profile not saved
|
||||||
|
"profileNotSaved" = "Profile not saved";
|
||||||
|
|
||||||
/// Profiles
|
/// Profiles
|
||||||
"profiles" = "Profiles";
|
"profiles" = "Profiles";
|
||||||
|
|
||||||
|
@ -1516,6 +1546,9 @@
|
||||||
/// Replace all unlocked metadata and images with new information.
|
/// Replace all unlocked metadata and images with new information.
|
||||||
"replaceAllDescription" = "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
|
/// Replace Images
|
||||||
"replaceImages" = "Replace Images";
|
"replaceImages" = "Replace Images";
|
||||||
|
|
||||||
|
@ -1591,6 +1624,9 @@
|
||||||
/// Right
|
/// Right
|
||||||
"right" = "Right";
|
"right" = "Right";
|
||||||
|
|
||||||
|
/// Right vertical pan
|
||||||
|
"rightVerticalPan" = "Right vertical pan";
|
||||||
|
|
||||||
/// Role
|
/// Role
|
||||||
"role" = "Role";
|
"role" = "Role";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue