Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Shared/Coordinators/AdminDashboardCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ final class AdminDashboardCoordinator: NavigationCoordinatable {
@Route(.modal)
var userPermissions = makeUserPermissions
@Route(.modal)
var userParentalRatings = makeUserParentalRatings
@Route(.modal)
var resetUserPassword = makeResetUserPassword
@Route(.modal)
var addServerUser = makeAddServerUser
Expand Down Expand Up @@ -160,6 +162,12 @@ final class AdminDashboardCoordinator: NavigationCoordinatable {
}
}

func makeUserParentalRatings(viewModel: ServerUserAdminViewModel) -> NavigationViewCoordinator<BasicNavigationViewCoordinator> {
NavigationViewCoordinator {
ServerUserParentalRatingView(viewModel: viewModel)
}
}

func makeResetUserPassword(userID: String) -> NavigationViewCoordinator<BasicNavigationViewCoordinator> {
NavigationViewCoordinator {
ResetUserPasswordView(userID: userID, requiresCurrentPassword: false)
Expand Down
36 changes: 36 additions & 0 deletions Shared/Extensions/JellyfinAPI/ParentalRating.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// 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
import JellyfinAPI

extension UnratedItem: Displayable {

var displayTitle: String {
switch self {
case .movie:
L10n.movies
case .trailer:
L10n.trailers
case .series:
L10n.tvShows
case .music:
L10n.music
case .book:
L10n.books
case .liveTvChannel:
L10n.liveTVChannels
case .liveTvProgram:
L10n.liveTVPrograms
case .channelContent:
L10n.channels
case .other:
L10n.other
}
}
}
32 changes: 32 additions & 0 deletions Shared/Strings/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ internal enum L10n {
internal static let access = L10n.tr("Localizable", "access", fallback: "Access")
/// Accessibility
internal static let accessibility = L10n.tr("Localizable", "accessibility", fallback: "Accessibility")
/// Access schedule
internal static let accessSchedule = L10n.tr("Localizable", "accessSchedule", fallback: "Access schedule")
/// Create an access schedule to limit access to certain hours.
internal static let accessScheduleDescription = L10n.tr("Localizable", "accessScheduleDescription", fallback: "Create an access schedule to limit access to certain hours.")
/// Active
internal static let active = L10n.tr("Localizable", "active", fallback: "Active")
/// Active Devices
Expand Down Expand Up @@ -66,6 +70,10 @@ internal enum L10n {
internal static let allMedia = L10n.tr("Localizable", "allMedia", fallback: "All Media")
/// Allow collection management
internal static let allowCollectionManagement = L10n.tr("Localizable", "allowCollectionManagement", fallback: "Allow collection management")
/// Allowed tags
internal static let allowedTags = L10n.tr("Localizable", "allowedTags", fallback: "Allowed tags")
/// Only show media to this user with at least one of the specified tags.
internal static let allowedTagsDescription = L10n.tr("Localizable", "allowedTagsDescription", fallback: "Only show media to this user with at least one of the specified tags.")
/// Allow media item deletion
internal static let allowItemDeletion = L10n.tr("Localizable", "allowItemDeletion", fallback: "Allow media item deletion")
/// Allow media item editing
Expand Down Expand Up @@ -196,8 +204,18 @@ internal enum L10n {
internal static let bitrateTestDisclaimer = L10n.tr("Localizable", "bitrateTestDisclaimer", fallback: "Longer tests are more accurate but may result in a delayed playback.")
/// bps
internal static let bitsPerSecond = L10n.tr("Localizable", "bitsPerSecond", fallback: "bps")
/// Blocked tags
internal static let blockedTags = L10n.tr("Localizable", "blockedTags", fallback: "Blocked tags")
/// Hide media with at least one of the specified tags.
internal static let blockedTagsDescription = L10n.tr("Localizable", "blockedTagsDescription", fallback: "Hide media with at least one of the specified tags.")
/// Block unrated items
internal static let blockUnratedItems = L10n.tr("Localizable", "blockUnratedItems", fallback: "Block unrated items")
/// Block items from this user with no or unrecognized rating information.
internal static let blockUnratedItemsDescription = L10n.tr("Localizable", "blockUnratedItemsDescription", fallback: "Block items from this user with no or unrecognized rating information.")
/// Blue
internal static let blue = L10n.tr("Localizable", "blue", fallback: "Blue")
/// Books
internal static let books = L10n.tr("Localizable", "books", fallback: "Books")
/// Bugs and Features
internal static let bugsAndFeatures = L10n.tr("Localizable", "bugsAndFeatures", fallback: "Bugs and Features")
/// Buttons
Expand Down Expand Up @@ -700,6 +718,10 @@ internal enum L10n {
internal static let liveTV = L10n.tr("Localizable", "liveTV", fallback: "Live TV")
/// Live TV access
internal static let liveTvAccess = L10n.tr("Localizable", "liveTvAccess", fallback: "Live TV access")
/// Live TV Channels
internal static let liveTVChannels = L10n.tr("Localizable", "liveTVChannels", fallback: "Live TV Channels")
/// Live TV Programs
internal static let liveTVPrograms = L10n.tr("Localizable", "liveTVPrograms", fallback: "Live TV Programs")
/// Live TV recording management
internal static let liveTvRecordingManagement = L10n.tr("Localizable", "liveTvRecordingManagement", fallback: "Live TV recording management")
/// Loading
Expand Down Expand Up @@ -744,6 +766,10 @@ internal enum L10n {
internal static let maximumSessions = L10n.tr("Localizable", "maximumSessions", fallback: "Maximum sessions")
/// Maximum sessions policy
internal static let maximumSessionsPolicy = L10n.tr("Localizable", "maximumSessionsPolicy", fallback: "Maximum sessions policy")
/// Maximum parental rating
internal static let maxParentalRating = L10n.tr("Localizable", "maxParentalRating", fallback: "Maximum parental rating")
/// Content with a higher rating will be hidden from this user.
internal static let maxParentalRatingDescription = L10n.tr("Localizable", "maxParentalRatingDescription", fallback: "Content with a higher rating will be hidden from this user.")
/// This setting may result in media failing to start playback.
internal static let mayResultInPlaybackFailure = L10n.tr("Localizable", "mayResultInPlaybackFailure", fallback: "This setting may result in media failing to start playback.")
/// Media
Expand Down Expand Up @@ -780,6 +806,8 @@ internal enum L10n {
internal static func multipleUsers(_ p1: Int) -> String {
return L10n.tr("Localizable", "multipleUsers", p1, fallback: "%d users")
}
/// Music
internal static let music = L10n.tr("Localizable", "music", fallback: "Music")
/// MVC
internal static let mvc = L10n.tr("Localizable", "mvc", fallback: "MVC")
/// Name
Expand Down Expand Up @@ -888,6 +916,8 @@ internal enum L10n {
internal static func pageOfWithNumbers(_ p1: Any, _ p2: Any) -> String {
return L10n.tr("Localizable", "pageOfWithNumbers", String(describing: p1), String(describing: p2), fallback: "Page %1$@ of %2$@")
}
/// Parental controls
internal static let parentalControls = L10n.tr("Localizable", "parentalControls", fallback: "Parental controls")
/// Parental Rating
internal static let parentalRating = L10n.tr("Localizable", "parentalRating", fallback: "Parental Rating")
/// Password
Expand Down Expand Up @@ -1328,6 +1358,8 @@ internal enum L10n {
internal static let title = L10n.tr("Localizable", "title", fallback: "Title")
/// Too Many Redirects
internal static let tooManyRedirects = L10n.tr("Localizable", "tooManyRedirects", fallback: "Too Many Redirects")
/// Trailers
internal static let trailers = L10n.tr("Localizable", "trailers", fallback: "Trailers")
/// Trailing Value
internal static let trailingValue = L10n.tr("Localizable", "trailingValue", fallback: "Trailing Value")
/// Transcode
Expand Down
26 changes: 22 additions & 4 deletions Swiftfin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
4E204E592C574FD9004D22A2 /* CustomizeSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E204E582C574FD9004D22A2 /* CustomizeSettingsCoordinator.swift */; };
4E2182E52CAF67F50094806B /* PlayMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2182E42CAF67EF0094806B /* PlayMethod.swift */; };
4E2182E62CAF67F50094806B /* PlayMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2182E42CAF67EF0094806B /* PlayMethod.swift */; };
4E2470082D078DD7009139D8 /* ServerUserParentalRatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2470062D078DD7009139D8 /* ServerUserParentalRatingView.swift */; };
4E24ECFB2D076F6200A473A9 /* ListRowCheckbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E24ECFA2D076F2B00A473A9 /* ListRowCheckbox.swift */; };
4E24ECFC2D076F6200A473A9 /* ListRowCheckbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E24ECFA2D076F2B00A473A9 /* ListRowCheckbox.swift */; };
4E2AC4BE2C6C48D200DD600D /* CustomDeviceProfileAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2AC4BD2C6C48D200DD600D /* CustomDeviceProfileAction.swift */; };
Expand Down Expand Up @@ -100,6 +101,8 @@
4E5E48E52AB59806003F1B48 /* CustomizeViewsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E5E48E42AB59806003F1B48 /* CustomizeViewsSettings.swift */; };
4E63B9FA2C8A5BEF00C25378 /* AdminDashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E63B9F42C8A5BEF00C25378 /* AdminDashboardView.swift */; };
4E63B9FC2C8A5C3E00C25378 /* ActiveSessionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E63B9FB2C8A5C3E00C25378 /* ActiveSessionsViewModel.swift */; };
4E656C302D0798AA00F993F3 /* ParentalRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E656C2F2D0798A900F993F3 /* ParentalRating.swift */; };
4E656C312D0798AA00F993F3 /* ParentalRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E656C2F2D0798A900F993F3 /* ParentalRating.swift */; };
4E6619FC2CEFE2BE00025C99 /* ItemEditorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6619FB2CEFE2B500025C99 /* ItemEditorViewModel.swift */; };
4E6619FD2CEFE2BE00025C99 /* ItemEditorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6619FB2CEFE2B500025C99 /* ItemEditorViewModel.swift */; };
4E661A012CEFE39D00025C99 /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E661A002CEFE39900025C99 /* EditMetadataView.swift */; };
Expand Down Expand Up @@ -1177,6 +1180,7 @@
4E182C9E2C94A1E000FBEFD5 /* ServerTaskRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerTaskRow.swift; sourceTree = "<group>"; };
4E204E582C574FD9004D22A2 /* CustomizeSettingsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomizeSettingsCoordinator.swift; sourceTree = "<group>"; };
4E2182E42CAF67EF0094806B /* PlayMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayMethod.swift; sourceTree = "<group>"; };
4E2470062D078DD7009139D8 /* ServerUserParentalRatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerUserParentalRatingView.swift; sourceTree = "<group>"; };
4E24ECFA2D076F2B00A473A9 /* ListRowCheckbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRowCheckbox.swift; sourceTree = "<group>"; };
4E2AC4BD2C6C48D200DD600D /* CustomDeviceProfileAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDeviceProfileAction.swift; sourceTree = "<group>"; };
4E2AC4C12C6C491200DD600D /* AudoCodec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudoCodec.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1224,6 +1228,7 @@
4E5E48E42AB59806003F1B48 /* CustomizeViewsSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomizeViewsSettings.swift; sourceTree = "<group>"; };
4E63B9F42C8A5BEF00C25378 /* AdminDashboardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdminDashboardView.swift; sourceTree = "<group>"; };
4E63B9FB2C8A5C3E00C25378 /* ActiveSessionsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActiveSessionsViewModel.swift; sourceTree = "<group>"; };
4E656C2F2D0798A900F993F3 /* ParentalRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentalRating.swift; sourceTree = "<group>"; };
4E6619FB2CEFE2B500025C99 /* ItemEditorViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemEditorViewModel.swift; sourceTree = "<group>"; };
4E661A002CEFE39900025C99 /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; };
4E661A042CEFE46300025C99 /* DateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSection.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2135,6 +2140,14 @@
path = Components;
sourceTree = "<group>";
};
4E2470072D078DD7009139D8 /* ServerUserParentalRatingView */ = {
isa = PBXGroup;
children = (
4E2470062D078DD7009139D8 /* ServerUserParentalRatingView.swift */,
);
path = ServerUserParentalRatingView;
sourceTree = "<group>";
};
4E2AC4C02C6C48EB00DD600D /* MediaComponents */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2291,6 +2304,7 @@
4E35CE622CBED3FF00DBD886 /* ServerLogsView */,
4E182C9A2C94991800FBEFD5 /* ServerTasksView */,
4EC2B1A72CC9725400D866BE /* ServerUserDetailsView */,
4E2470072D078DD7009139D8 /* ServerUserParentalRatingView */,
4E537A822D03D0FA00659A1A /* ServerUserDeviceAccessView */,
4E537A8C2D04410E00659A1A /* ServerUserLiveTVAccessView */,
4EF3D80A2CF7D6670081AD20 /* ServerUserAccessView */,
Expand Down Expand Up @@ -4224,6 +4238,7 @@
E122A9122788EAAD0060FA63 /* MediaStream.swift */,
4E661A2D2CEFE77700025C99 /* MetadataField.swift */,
E1AD105E26D9ADDD003E4A08 /* NameGuidPair.swift */,
4E656C2F2D0798A900F993F3 /* ParentalRating.swift */,
4EFE0C7C2D0156A500D4834D /* PersonKind.swift */,
E1ED7FDA2CAA4B6D00ACB6E3 /* PlayerStateInfo.swift */,
4E2182E42CAF67EF0094806B /* PlayMethod.swift */,
Expand Down Expand Up @@ -5151,6 +5166,7 @@
E1356E0429A731EB00382563 /* SeparatorHStack.swift in Sources */,
E1575E69293E77B5001665B1 /* ItemSortBy.swift in Sources */,
E1B490482967E2E500D3EDCE /* CoreStore.swift in Sources */,
4E656C312D0798AA00F993F3 /* ParentalRating.swift in Sources */,
E1DC9845296DECB600982F06 /* ProgressIndicator.swift in Sources */,
E1C925F928875647002A7A66 /* LatestInLibraryView.swift in Sources */,
E11B1B6D2718CD68006DA3E8 /* JellyfinAPIError.swift in Sources */,
Expand Down Expand Up @@ -5371,6 +5387,7 @@
6220D0B426D5ED8000B8E046 /* LibraryCoordinator.swift in Sources */,
E17AC96D2954E9CA003D2BC2 /* DownloadListView.swift in Sources */,
4E8B34EA2AB91B6E0018F305 /* ItemFilter.swift in Sources */,
4E2470082D078DD7009139D8 /* ServerUserParentalRatingView.swift in Sources */,
E1A1528828FD229500600579 /* ChevronButton.swift in Sources */,
E1CB75732C80E71800217C76 /* DirectPlayProfile.swift in Sources */,
E1B490472967E2E500D3EDCE /* CoreStore.swift in Sources */,
Expand Down Expand Up @@ -5533,6 +5550,7 @@
4E2AC4C52C6C492700DD600D /* MediaContainer.swift in Sources */,
4E2AC4CB2C6C494E00DD600D /* VideoCodec.swift in Sources */,
E1EA09692BED78BB004CDE76 /* UserAccessPolicy.swift in Sources */,
4E656C302D0798AA00F993F3 /* ParentalRating.swift in Sources */,
E18E0204288749200022598C /* RowDivider.swift in Sources */,
E18E01DA288747230022598C /* iPadOSEpisodeContentView.swift in Sources */,
E1CB75752C80EAFA00217C76 /* ArrayBuilder.swift in Sources */,
Expand Down Expand Up @@ -6270,7 +6288,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 78;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = TY84JMYEFE;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand All @@ -6286,7 +6304,7 @@
);
MARKETING_VERSION = 1.0.0;
OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = pip.jellyfin.swiftfin;
PRODUCT_BUNDLE_IDENTIFIER = org.jellyfin.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTS_MACCATALYST = NO;
Expand All @@ -6310,7 +6328,7 @@
CURRENT_PROJECT_VERSION = 78;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = TY84JMYEFE;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand All @@ -6326,7 +6344,7 @@
);
MARKETING_VERSION = 1.0.0;
OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = pip.jellyfin.swiftfin;
PRODUCT_BUNDLE_IDENTIFIER = org.jellyfin.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTS_MACCATALYST = NO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import JellyfinAPI
import SwiftUI

struct ServerUserDetailsView: View {

@EnvironmentObject
private var router: AdminDashboardCoordinator.Router

Expand Down Expand Up @@ -68,31 +67,27 @@ struct ServerUserDetailsView: View {
}
}

/* Section("Parental controls") {
// TODO: Allow items SDK 10.10 - allowedTags
ChevronButton("Allow items")
.onSelect {
router.route(to: \.userAllowedTags, viewModel)
}

// TODO: Block items - blockedTags
ChevronButton("Block items")
.onSelect {
router.route(to: \.userBlockedTags, viewModel)
}

// TODO: Access Schedules - accessSchedules
ChevronButton("Access schedule")
Section(L10n.parentalControls) {
// TODO: Access Schedules - accessSchedules
/* ChevronButton("Access schedule")
.onSelect {
router.route(to: \.userAccessSchedules, viewModel)
}

// TODO: Parental Rating - maxParentalRating, blockUnratedItems
ChevronButton("Parental rating")
.onSelect {
router.route(to: \.userParentalRating, viewModel)
}
} */
// TODO: Allow items SDK 10.10 - allowedTags
ChevronButton("Allow items")
.onSelect {
router.route(to: \.userAllowedTags, viewModel)
}
// TODO: Block items - blockedTags
ChevronButton("Block items")
.onSelect {
router.route(to: \.userBlockedTags, viewModel)
}*/
ChevronButton(L10n.ratings)
.onSelect {
router.route(to: \.userParentalRatings, viewModel)
}
}
}
.navigationTitle(L10n.user)
.onAppear {
Expand Down
Loading