From 394a5482635e2354fc66c1f40f9147bcd1e88fd1 Mon Sep 17 00:00:00 2001 From: chinkara Date: Sun, 15 Oct 2023 22:01:52 +0200 Subject: [PATCH 1/3] No admin user can be allowed to "edit subtitles" Front end support to new feature. A user without admin rights can be allowed to "edit subtitles" --- src/apps/dashboard/routes/users/profile.tsx | 7 +++++++ src/components/itemContextMenu.js | 2 +- src/strings/en-us.json | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/apps/dashboard/routes/users/profile.tsx b/src/apps/dashboard/routes/users/profile.tsx index 11cda31fcd..7ef62f8261 100644 --- a/src/apps/dashboard/routes/users/profile.tsx +++ b/src/apps/dashboard/routes/users/profile.tsx @@ -182,6 +182,7 @@ const UserEdit: FunctionComponent = () => { (page.querySelector('.chkDisabled') as HTMLInputElement).checked = user.Policy.IsDisabled; (page.querySelector('.chkIsHidden') as HTMLInputElement).checked = user.Policy.IsHidden; (page.querySelector('.chkEnableCollectionManagement') as HTMLInputElement).checked = user.Policy.EnableCollectionManagement; + (page.querySelector('.chkEnableSubtitleManagement') as HTMLInputElement).checked = user.Policy.EnableSubtitleManagement; (page.querySelector('.chkRemoteControlSharedDevices') as HTMLInputElement).checked = user.Policy.EnableSharedDeviceControl; (page.querySelector('.chkEnableRemoteControlOtherUsers') as HTMLInputElement).checked = user.Policy.EnableRemoteControlOfOtherUsers; (page.querySelector('.chkEnableDownloading') as HTMLInputElement).checked = user.Policy.EnableContentDownloading; @@ -240,6 +241,7 @@ const UserEdit: FunctionComponent = () => { user.Policy.EnableVideoPlaybackTranscoding = (page.querySelector('.chkEnableVideoPlaybackTranscoding') as HTMLInputElement).checked; user.Policy.EnablePlaybackRemuxing = (page.querySelector('.chkEnableVideoPlaybackRemuxing') as HTMLInputElement).checked; user.Policy.EnableCollectionManagement = (page.querySelector('.chkEnableCollectionManagement') as HTMLInputElement).checked; + user.Policy.EnableSubtitleManagement = (page.querySelector('.chkEnableSubtitleManagement') as HTMLInputElement).checked; user.Policy.ForceRemoteSourceTranscoding = (page.querySelector('.chkForceRemoteSourceTranscoding') as HTMLInputElement).checked; user.Policy.EnableContentDownloading = (page.querySelector('.chkEnableDownloading') as HTMLInputElement).checked; user.Policy.EnableRemoteAccess = (page.querySelector('.chkRemoteAccess') as HTMLInputElement).checked; @@ -392,6 +394,11 @@ const UserEdit: FunctionComponent = () => { className='chkEnableCollectionManagement' title='AllowCollectionManagement' /> +

{globalize.translate('HeaderFeatureAccess')} diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 6d1c3c24f5..809767be5b 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -214,7 +214,7 @@ export function getCommands(options) { }); } - if (canEdit && item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program' + if ((canEdit || user.Policy.EnableSubtitleManagement) && item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program' && item.LocationType !== 'Virtual' && !(item.Type === 'Recording' && item.Status !== 'Completed') && options.editSubtitles !== false diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 7bc81572d4..f140cb2ad4 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -23,6 +23,7 @@ "AllLibraries": "All libraries", "AllowedRemoteAddressesHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. If left blank, all remote addresses will be allowed.", "AllowCollectionManagement": "Allow this user to manage collections", + "AllowSubtitleManagement": "Allow this user to edit subtitles", "AllowFfmpegThrottling": "Throttle Transcodes", "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume less resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", "AllowSegmentDeletion": "Delete segments", From fd50b3af5507182fde7ba72f0409e7418e75941c Mon Sep 17 00:00:00 2001 From: chinkara Date: Tue, 6 Feb 2024 09:52:14 +0100 Subject: [PATCH 2/3] improve itemContextMenu.js by adding a helper function to itemHelper.js --- src/components/itemContextMenu.js | 6 +----- src/components/itemHelper.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 809767be5b..ad2052a3e1 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -214,11 +214,7 @@ export function getCommands(options) { }); } - if ((canEdit || user.Policy.EnableSubtitleManagement) && item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program' - && item.LocationType !== 'Virtual' - && !(item.Type === 'Recording' && item.Status !== 'Completed') - && options.editSubtitles !== false - ) { + if (itemHelper.canEditSubtitles(user, item) && options.editSubtitles !== false) { commands.push({ name: globalize.translate('EditSubtitles'), id: 'editsubtitles', diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index d763003fb9..18c97c7fd4 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -155,6 +155,33 @@ export function canEditImages (user, item) { return itemType !== 'Timer' && itemType !== 'SeriesTimer' && canEdit(user, item) && !isLocalItem(item); } +export function canEditSubtitles (user, item) { + if (item.MediaType !== 'Video') { + return false; + } + const itemType = item.Type; + if (itemType === 'Recording' && item.Status !== 'Completed') { + return false; + } + if (itemType === 'TvChannel' + || itemType === 'Program' + || itemType === 'Timer' + || itemType === 'SeriesTimer' + || itemType === 'UserRootFolder' + || itemType === 'UserView' + ) { + return false; + } + if (isLocalItem(item)) { + return false; + } + if (item.LocationType === 'Virtual') { + return false; + } + return user.Policy.EnableSubtitleManagement + || user.Policy.IsAdministrator; +} + export function canShare (item, user) { if (item.Type === 'Program') { return false; @@ -300,6 +327,7 @@ export default { canIdentify: canIdentify, canEdit: canEdit, canEditImages: canEditImages, + canEditSubtitles: canEditSubtitles, canShare: canShare, enableDateAddedDisplay: enableDateAddedDisplay, canMarkPlayed: canMarkPlayed, From 5c60f99077ce1dada3a4af10251766b677dc8e08 Mon Sep 17 00:00:00 2001 From: chinkara Date: Thu, 7 Mar 2024 10:12:27 +0100 Subject: [PATCH 3/3] Fix itemHelper by adding Enums and update function declation --- src/components/itemHelper.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index 18c97c7fd4..498a8bab80 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -1,6 +1,10 @@ import { appHost } from './apphost'; import globalize from '../scripts/globalize'; import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; +import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; +import { LocationType } from '@jellyfin/sdk/lib/generated-client/models/location-type'; +import { RecordingStatus } from '@jellyfin/sdk/lib/generated-client/models/recording-status'; +import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'; export function getDisplayName(item, options = {}) { if (!item) { @@ -156,26 +160,26 @@ export function canEditImages (user, item) { } export function canEditSubtitles (user, item) { - if (item.MediaType !== 'Video') { + if (item.MediaType !== MediaType.Video) { return false; } const itemType = item.Type; - if (itemType === 'Recording' && item.Status !== 'Completed') { + if (itemType === BaseItemKind.Recording && item.Status !== RecordingStatus.Completed) { return false; } - if (itemType === 'TvChannel' - || itemType === 'Program' + if (itemType === BaseItemKind.TvChannel + || itemType === BaseItemKind.Program || itemType === 'Timer' || itemType === 'SeriesTimer' - || itemType === 'UserRootFolder' - || itemType === 'UserView' + || itemType === BaseItemKind.UserRootFolder + || itemType === BaseItemKind.UserView ) { return false; } if (isLocalItem(item)) { return false; } - if (item.LocationType === 'Virtual') { + if (item.LocationType === LocationType.Virtual) { return false; } return user.Policy.EnableSubtitleManagement @@ -327,7 +331,7 @@ export default { canIdentify: canIdentify, canEdit: canEdit, canEditImages: canEditImages, - canEditSubtitles: canEditSubtitles, + canEditSubtitles, canShare: canShare, enableDateAddedDisplay: enableDateAddedDisplay, canMarkPlayed: canMarkPlayed,