2020-06-09 22:37:34 +03:00
/ * *
* Module for media library editor .
* @ module components / mediaLibraryEditor / mediaLibraryEditor
* /
2022-01-30 00:27:26 +03:00
import escapeHtml from 'escape-html' ;
2020-08-14 08:46:34 +02:00
import 'jquery' ;
import loading from '../loading/loading' ;
import dialogHelper from '../dialogHelper/dialogHelper' ;
import dom from '../../scripts/dom' ;
import libraryoptionseditor from '../libraryoptionseditor/libraryoptionseditor' ;
import globalize from '../../scripts/globalize' ;
import '../../elements/emby-button/emby-button' ;
2021-01-26 16:25:38 -05:00
import '../listview/listview.scss' ;
2020-08-14 08:46:34 +02:00
import '../../elements/emby-button/paper-icon-button-light' ;
2021-01-26 16:25:38 -05:00
import '../formdialog.scss' ;
2020-08-14 08:46:34 +02:00
import '../../elements/emby-toggle/emby-toggle' ;
2023-02-26 01:01:31 +02:00
import '../../styles/flexstyles.scss' ;
2022-07-14 17:59:23 -04:00
import './style.scss' ;
2020-10-18 14:19:41 +01:00
import toast from '../toast/toast' ;
2020-10-18 15:18:15 +01:00
import confirm from '../confirm/confirm' ;
2020-11-25 00:17:24 -05:00
import template from './mediaLibraryEditor.template.html' ;
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function onEditLibrary ( ) {
if ( isCreating ) {
2019-05-07 13:17:40 -07:00
return false ;
}
2023-04-19 01:56:05 -04:00
isCreating = true ;
loading . show ( ) ;
const dlg = dom . parentWithClass ( this , 'dlg-libraryeditor' ) ;
let libraryOptions = libraryoptionseditor . getLibraryOptions ( dlg . querySelector ( '.libraryOptions' ) ) ;
2024-08-08 14:12:25 +09:00
// when the library has moved or symlinked, the ItemId is not correct anymore
// this can lead to a forever spinning value on edit the library parameters
if ( currentOptions . library . ItemId == undefined ) {
toast ( 'The library setting is in an invalid state, cannot edit. You are most likely suffering from a bug where the path in the database is not the absolute path in the filesystem' ) ;
loading . hide ( ) ;
dialogHelper . close ( dlg ) ;
return false ;
}
2023-04-19 01:56:05 -04:00
libraryOptions = Object . assign ( currentOptions . library . LibraryOptions || { } , libraryOptions ) ;
ApiClient . updateVirtualFolderOptions ( currentOptions . library . ItemId , libraryOptions ) . then ( ( ) => {
hasChanges = true ;
isCreating = false ;
loading . hide ( ) ;
dialogHelper . close ( dlg ) ;
} , ( ) => {
isCreating = false ;
loading . hide ( ) ;
} ) ;
return false ;
}
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function addMediaLocation ( page , path , networkSharePath ) {
const virtualFolder = currentOptions . library ;
const refreshAfterChange = currentOptions . refresh ;
ApiClient . addMediaPath ( virtualFolder . Name , path , networkSharePath , refreshAfterChange ) . then ( ( ) => {
hasChanges = true ;
refreshLibraryFromServer ( page ) ;
} , ( ) => {
toast ( globalize . translate ( 'ErrorAddingMediaPathToVirtualFolder' ) ) ;
} ) ;
}
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function updateMediaLocation ( page , path , networkSharePath ) {
const virtualFolder = currentOptions . library ;
ApiClient . updateMediaPath ( virtualFolder . Name , {
Path : path ,
NetworkPath : networkSharePath
} ) . then ( ( ) => {
hasChanges = true ;
refreshLibraryFromServer ( page ) ;
} , ( ) => {
toast ( globalize . translate ( 'ErrorAddingMediaPathToVirtualFolder' ) ) ;
} ) ;
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
function onRemoveClick ( btnRemovePath , location ) {
const button = btnRemovePath ;
const virtualFolder = currentOptions . library ;
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
confirm ( {
title : globalize . translate ( 'HeaderRemoveMediaLocation' ) ,
text : globalize . translate ( 'MessageConfirmRemoveMediaLocation' ) ,
confirmText : globalize . translate ( 'Delete' ) ,
primary : 'delete'
} ) . then ( ( ) => {
const refreshAfterChange = currentOptions . refresh ;
ApiClient . removeMediaPath ( virtualFolder . Name , location , refreshAfterChange ) . then ( ( ) => {
hasChanges = true ;
refreshLibraryFromServer ( dom . parentWithClass ( button , 'dlg-libraryeditor' ) ) ;
} , ( ) => {
toast ( globalize . translate ( 'ErrorDefault' ) ) ;
} ) ;
} ) ;
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
function onListItemClick ( e ) {
const listItem = dom . parentWithClass ( e . target , 'listItem' ) ;
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
if ( listItem ) {
const index = parseInt ( listItem . getAttribute ( 'data-index' ) , 10 ) ;
2023-07-06 13:39:48 -04:00
const pathInfos = currentOptions . library . LibraryOptions ? . PathInfos || [ ] ;
2023-04-19 01:56:05 -04:00
const pathInfo = index == null ? { } : pathInfos [ index ] || { } ;
const originalPath = pathInfo . Path || ( index == null ? null : currentOptions . library . Locations [ index ] ) ;
const btnRemovePath = dom . parentWithClass ( e . target , 'btnRemovePath' ) ;
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
if ( btnRemovePath ) {
onRemoveClick ( btnRemovePath , originalPath ) ;
return ;
2019-05-06 17:26:18 -07:00
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
showDirectoryBrowser ( dom . parentWithClass ( listItem , 'dlg-libraryeditor' ) , originalPath , pathInfo . NetworkPath ) ;
2018-10-23 01:05:09 +03:00
}
2023-04-19 01:56:05 -04:00
}
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function getFolderHtml ( pathInfo , index ) {
let html = '' ;
html += ` <div class="listItem listItem-border lnkPath" data-index=" ${ index } "> ` ;
html += ` <div class=" ${ pathInfo . NetworkPath ? 'listItemBody two-line' : 'listItemBody' } "> ` ;
html += '<h3 class="listItemBodyText">' ;
html += escapeHtml ( pathInfo . Path ) ;
html += '</h3>' ;
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
if ( pathInfo . NetworkPath ) {
html += ` <div class="listItemBodyText secondary"> ${ escapeHtml ( pathInfo . NetworkPath ) } </div> ` ;
2018-10-23 01:05:09 +03:00
}
2023-04-19 01:56:05 -04:00
html += '</div>' ;
html += ` <button type="button" is="paper-icon-button-light" class="listItemButton btnRemovePath" data-index=" ${ index } "><span class="material-icons remove_circle" aria-hidden="true"></span></button> ` ;
html += '</div>' ;
return html ;
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
function refreshLibraryFromServer ( page ) {
ApiClient . getVirtualFolders ( ) . then ( result => {
const library = result . filter ( f => {
return f . Name === currentOptions . library . Name ;
} ) [ 0 ] ;
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
if ( library ) {
currentOptions . library = library ;
renderLibrary ( page , currentOptions ) ;
2019-05-06 17:26:18 -07:00
}
2023-04-19 01:56:05 -04:00
} ) ;
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
function renderLibrary ( page , options ) {
2023-07-06 13:39:48 -04:00
let pathInfos = options . library . LibraryOptions ? . PathInfos || [ ] ;
2023-04-19 01:56:05 -04:00
if ( ! pathInfos . length ) {
pathInfos = options . library . Locations . map ( p => {
return {
Path : p
} ;
} ) ;
2018-10-23 01:05:09 +03:00
}
2023-04-19 01:56:05 -04:00
if ( options . library . CollectionType === 'boxsets' ) {
page . querySelector ( '.folders' ) . classList . add ( 'hide' ) ;
} else {
page . querySelector ( '.folders' ) . classList . remove ( 'hide' ) ;
2018-10-23 01:05:09 +03:00
}
2023-04-19 01:56:05 -04:00
page . querySelector ( '.folderList' ) . innerHTML = pathInfos . map ( getFolderHtml ) . join ( '' ) ;
}
function onAddButtonClick ( ) {
showDirectoryBrowser ( dom . parentWithClass ( this , 'dlg-libraryeditor' ) ) ;
}
2020-01-26 19:02:37 +03:00
2023-04-19 01:56:05 -04:00
function showDirectoryBrowser ( context , originalPath , networkPath ) {
import ( '../directorybrowser/directorybrowser' ) . then ( ( { default : DirectoryBrowser } ) => {
const picker = new DirectoryBrowser ( ) ;
picker . show ( {
pathReadOnly : originalPath != null ,
path : originalPath ,
networkSharePath : networkPath ,
callback : function ( path , networkSharePath ) {
if ( path ) {
if ( originalPath ) {
updateMediaLocation ( context , originalPath , networkSharePath ) ;
} else {
addMediaLocation ( context , path , networkSharePath ) ;
}
2018-10-23 01:05:09 +03:00
}
2023-04-19 01:56:05 -04:00
picker . close ( ) ;
}
2020-01-26 19:02:37 +03:00
} ) ;
2023-04-19 01:56:05 -04:00
} ) ;
}
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function initEditor ( dlg , options ) {
renderLibrary ( dlg , options ) ;
dlg . querySelector ( '.btnAddFolder' ) . addEventListener ( 'click' , onAddButtonClick ) ;
dlg . querySelector ( '.folderList' ) . addEventListener ( 'click' , onListItemClick ) ;
dlg . querySelector ( '.btnSubmit' ) . addEventListener ( 'click' , onEditLibrary ) ;
libraryoptionseditor . embed ( dlg . querySelector ( '.libraryOptions' ) , options . library . CollectionType , options . library . LibraryOptions ) ;
}
2018-10-23 01:05:09 +03:00
2023-04-19 01:56:05 -04:00
function onDialogClosed ( ) {
currentDeferred . resolveWith ( null , [ hasChanges ] ) ;
}
2018-10-23 01:05:09 +03:00
2023-07-06 11:49:55 -04:00
export class MediaLibraryEditor {
2020-06-26 19:30:44 +03:00
constructor ( options ) {
const deferred = jQuery . Deferred ( ) ;
currentOptions = options ;
currentDeferred = deferred ;
hasChanges = false ;
2020-11-25 00:17:24 -05:00
const dlg = dialogHelper . createDialog ( {
size : 'small' ,
modal : false ,
removeOnClose : true ,
scrollY : false
} ) ;
dlg . classList . add ( 'dlg-libraryeditor' ) ;
dlg . classList . add ( 'ui-body-a' ) ;
dlg . classList . add ( 'background-theme-a' ) ;
dlg . classList . add ( 'formDialog' ) ;
dlg . innerHTML = globalize . translateHtml ( template ) ;
2022-01-30 00:27:26 +03:00
dlg . querySelector ( '.formDialogHeaderTitle' ) . innerText = options . library . Name ;
2020-11-25 00:17:24 -05:00
initEditor ( dlg , options ) ;
dlg . addEventListener ( 'close' , onDialogClosed ) ;
dialogHelper . open ( dlg ) ;
dlg . querySelector ( '.btnCancel' ) . addEventListener ( 'click' , ( ) => {
dialogHelper . close ( dlg ) ;
2020-06-26 19:30:44 +03:00
} ) ;
2020-11-25 00:17:24 -05:00
refreshLibraryFromServer ( dlg ) ;
2020-06-26 19:30:44 +03:00
return deferred . promise ( ) ;
2018-10-23 01:05:09 +03:00
}
2020-06-09 22:37:34 +03:00
}
2023-04-19 01:56:05 -04:00
let currentDeferred ;
let currentOptions ;
let hasChanges = false ;
let isCreating = false ;
2019-05-06 17:26:18 -07:00
2023-07-06 11:49:55 -04:00
export default MediaLibraryEditor ;