391 lines
13 KiB
PHTML
391 lines
13 KiB
PHTML
$(function() {
|
|
var CSRF = '<?=$csrf ?>';
|
|
var MAX_UPLOAD_SIZE = <?=$max_upload_size ?>;
|
|
|
|
var $current_dir = '';
|
|
|
|
var appToolbar = new Vue({
|
|
el: '#app-toolbar',
|
|
data: {
|
|
playlists: <?=json_encode($playlists) ?>
|
|
},
|
|
methods: {
|
|
doBatch: function (e) {
|
|
e.preventDefault();
|
|
|
|
var $files = getSelectedFiles();
|
|
$files.length && $.post('<?=$router->fromHere('stations:files:batch') ?>',{
|
|
'do': $(e.target).data('action'),
|
|
'files': $files.join('|'),
|
|
'csrf': CSRF,
|
|
'file': getUrlHash()
|
|
},function(data){
|
|
list();
|
|
},'json');
|
|
|
|
$(this).closest('.btn-group').removeClass('open');
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
|
|
var appMoveFilesModal = new Vue({
|
|
el: '#mdl-move-file',
|
|
data: {
|
|
selected_files: 0,
|
|
move_dir: '',
|
|
dir_history: [],
|
|
directory_grid: null
|
|
},
|
|
methods: {
|
|
pageBack: function(e) {
|
|
e.preventDefault();
|
|
|
|
this.dir_history.pop();
|
|
this.move_dir = this.dir_history.join("/");
|
|
this.directory_grid.bootgrid("reload");
|
|
}
|
|
}
|
|
});
|
|
|
|
var grid = $("#file-table").bootgrid({
|
|
ajax: true,
|
|
selection: true,
|
|
multiSelect: true,
|
|
rowSelect: false,
|
|
caseSensitive: false,
|
|
url: "<?=$router->fromHere('stations:files:list') ?>",
|
|
post: function() {
|
|
return {
|
|
'file': $current_dir,
|
|
'csrf': CSRF
|
|
};
|
|
},
|
|
formatters: {
|
|
"playable": function(column, row) {
|
|
var $url = row.is_dir ? '#' + row.path : row.media_play_url;
|
|
var $icon = '';
|
|
|
|
if (row.media_is_playable)
|
|
$icon = '<a class="file-icon btn-audio" href="#" data-url="'+$url+'"><i class="material-icons" aria-hidden="true">play_circle_filled</i></a>';
|
|
else
|
|
$icon = '<span class="file-icon"><i class="material-icons" aria-hidden="true">'+(row.is_dir ? 'folder' : 'note')+'</i></span>';
|
|
|
|
var $link = '<a class="name" href="'+$url+'" title="'+row.name+'">'+(row.is_dir ? row.text : row.media_name)+'</a>';
|
|
|
|
var art_src = (row.media_art) ? row.media_art : '/static/img/generic_song.jpg';
|
|
var $art = (row.is_dir) ? '' : '<a href="'+art_src+'" class="album-art float-right pl-3" target="_blank"><img style="width: 40px; height: auto; border-radius: 5px;" alt="<?=__('Album Artwork') ?>" src="'+art_src+'"></a>';
|
|
|
|
return '<div class="'+(row.is_dir ? 'is_dir' : 'is_file')+'">'+$art+$icon + $link + '<br><small>'+(row.is_dir ? 'Directory' : row.text)+'</small></div>';
|
|
},
|
|
"commands": function(column, row) {
|
|
if (row.media_edit_url)
|
|
return '<a class="btn btn-sm btn-primary" href="'+row.media_edit_url+'"><?=__('Edit') ?></a>';
|
|
else
|
|
return '<a class="btn btn-sm btn-primary" href="'+row.rename_url+'"><?=__('Rename') ?></a>';
|
|
},
|
|
"file_length": function(column, row) {
|
|
if (!row.media_length_text) {
|
|
return '';
|
|
}
|
|
|
|
return row.media_length_text;
|
|
},
|
|
"file_size": function(column, row) {
|
|
if (!row.size) {
|
|
return '';
|
|
}
|
|
|
|
return formatFileSize(row.size);
|
|
},
|
|
"file_mtime": function(column, row) {
|
|
if (!row.mtime) {
|
|
return '';
|
|
}
|
|
|
|
return formatTimestamp(row.mtime);
|
|
},
|
|
"playlists": function(column, row) {
|
|
if (row.media_playlists.length > 0) {
|
|
var playlists = [];
|
|
var playlist;
|
|
|
|
for (var i = 0; i < row.media_playlists.length; i++) {
|
|
playlist = row.media_playlists[i];
|
|
playlists.push('<a class="btn-search" href="#" data-term="playlist:'+playlist+'">'+playlist+'</a>');
|
|
}
|
|
|
|
return playlists.join(', ');
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
}
|
|
}).on("loaded.rs.jquery.bootgrid", function() {
|
|
/* Executes after data is loaded and rendered */
|
|
grid.find(".btn-audio").on("click", function(e) {
|
|
e.preventDefault();
|
|
handlePlayClick($(this).data('url'));
|
|
return false;
|
|
});
|
|
|
|
/* Handle playlist search function */
|
|
grid.find(".btn-search").on("click", function(e) {
|
|
e.preventDefault();
|
|
grid.bootgrid("clear").bootgrid("search", $(this).data('term'));
|
|
return false;
|
|
});
|
|
|
|
/* Handle album art clicking. */
|
|
grid.find('.album-art').fancybox({});
|
|
|
|
appMoveFilesModal.selected_files = getSelectedFiles().length;
|
|
}).on("selected.rs.jquery.bootgrid", function(e, columns, row) {
|
|
appMoveFilesModal.selected_files = getSelectedFiles().length;
|
|
}).on("deselected.rs.jquery.bootgrid", function(e, columns, row) {
|
|
appMoveFilesModal.selected_files = getSelectedFiles().length;
|
|
});
|
|
|
|
appMoveFilesModal.directory_grid = $("#directory-table").bootgrid({
|
|
ajax: true,
|
|
navigation: 0,
|
|
selection: false,
|
|
rowSelect: false,
|
|
caseSensitive: false,
|
|
url: "<?=$router->fromHere('stations:files:directories') ?>",
|
|
post: function() {
|
|
return {
|
|
'csrf': CSRF,
|
|
'file': appMoveFilesModal.move_dir
|
|
};
|
|
},
|
|
formatters: {
|
|
"directory": function(column, row) {
|
|
$icon = '<span class="file-icon"><i class="material-icons" aria-hidden="true">folder</i></span> ';
|
|
|
|
return '<div class="is_dir">'+$icon + row.name +'</div>';
|
|
},
|
|
"commands": function(column, row) {
|
|
return '<a class="btn btn-sm btn-primary btn-select" href="#" data-path="'+window.btoa(appMoveFilesModal.move_dir.length ? appMoveFilesModal.move_dir + '/' + row.path : row.path)+'"><?=__('Select') ?></a>';
|
|
}
|
|
}
|
|
}).on("loaded.rs.jquery.bootgrid", function() {
|
|
/* Handle directory selection */
|
|
appMoveFilesModal.directory_grid.find(".btn-select").on("click", function(e) {
|
|
e.preventDefault();
|
|
|
|
var $files = getSelectedFiles();
|
|
$files.length && $.post('<?=$router->fromHere('stations:files:batch') ?>',{
|
|
'do': 'move',
|
|
'files': $files.join('|'),
|
|
'csrf': CSRF,
|
|
'directory': window.atob($(this).data('path'))
|
|
},function(data){
|
|
list();
|
|
$('#mdl-move-file').modal('hide');
|
|
},'json');
|
|
|
|
return false;
|
|
});
|
|
}).on("click.rs.jquery.bootgrid", function(e, columns, row) {
|
|
appMoveFilesModal.dir_history.push(row.path);
|
|
appMoveFilesModal.move_dir = appMoveFilesModal.dir_history.join("/");
|
|
appMoveFilesModal.directory_grid.bootgrid("reload");
|
|
});
|
|
|
|
$('#mdl-move-file').on('show.bs.modal', function (e) {
|
|
appMoveFilesModal.dir_history = [];
|
|
appMoveFilesModal.move_dir = '';
|
|
appMoveFilesModal.directory_grid.bootgrid("reload");
|
|
});
|
|
|
|
// Check if initial URL has a hash.
|
|
var hashval = getUrlHash();
|
|
|
|
if (hashval.length > 0)
|
|
list();
|
|
else
|
|
$('#breadcrumb').empty().html(renderBreadcrumbs(hashval));
|
|
|
|
$(window).bind('hashchange',list);
|
|
|
|
// Create new directory
|
|
$('form#mkdir').submit(function(e) {
|
|
e.preventDefault();
|
|
|
|
var hashval = getUrlHash();
|
|
var $dir = $(this).find('[name=name]');
|
|
|
|
$dir.val().length && $.post('<?=$router->fromHere('stations:files:mkdir') ?>',{
|
|
name: $dir.val(),
|
|
csrf: CSRF,
|
|
file: hashval
|
|
},function(data){
|
|
list();
|
|
},'json');
|
|
|
|
$dir.val('');
|
|
return false;
|
|
});
|
|
|
|
$('.btn-new-playlist').on('click', function(e) {
|
|
$(this).closest('.btn-group').removeClass('open');
|
|
});
|
|
|
|
$('#frm-create-playlist').submit(function(e) {
|
|
e.preventDefault();
|
|
|
|
var $files = getSelectedFiles();
|
|
$files.length && $.post('<?=$router->fromHere('stations:files:batch') ?>',{
|
|
'do': 'playlist_new',
|
|
'name': $('#fld-playlist-name').val(),
|
|
'files': $files.join('|'),
|
|
'csrf': CSRF,
|
|
'file': getUrlHash()
|
|
},function(data){
|
|
if (data.success) {
|
|
appToolbar.playlists.push(data.record);
|
|
}
|
|
list();
|
|
},'json');
|
|
|
|
$('#fld-playlist-name').val('');
|
|
$('#mdl-create-playlist').modal('hide');
|
|
|
|
return false;
|
|
});
|
|
|
|
$('#frm-create-directory').submit(function(e) {
|
|
e.preventDefault();
|
|
|
|
var $dir = $('#fld-directory-name');
|
|
|
|
$dir.val().length && $.post('<?=$router->fromHere('stations:files:mkdir') ?>',{
|
|
name: $dir.val(),
|
|
csrf: CSRF,
|
|
file: getUrlHash()
|
|
},function(data){
|
|
list();
|
|
},'json');
|
|
|
|
$dir.val('');
|
|
$('#mdl-create-directory').modal('hide');
|
|
return false;
|
|
});
|
|
|
|
// File upload stuff
|
|
var flow = new Flow({
|
|
target: '<?=$router->fromHere('stations:files:upload') ?>',
|
|
query: function() {
|
|
return {
|
|
csrf: CSRF,
|
|
file: getUrlHash(),
|
|
searchPhrase: $('input.search-field').val()
|
|
};
|
|
},
|
|
withCredentials: true,
|
|
allowDuplicateUploads: true,
|
|
fileParameterName: 'file_data'
|
|
});
|
|
|
|
flow.assignBrowse(document.getElementById('file_browse_target'));
|
|
flow.assignDrop(document.getElementById('file_drop_target'));
|
|
|
|
flow.on('fileAdded', function(file, event) {
|
|
$('#upload_progress').append(renderFileUploadRow(file));
|
|
return true;
|
|
});
|
|
flow.on('filesSubmitted', function(array, event) {
|
|
flow.upload();
|
|
});
|
|
flow.on('fileProgress', function(file) {
|
|
var $row = $('#file_upload_'+file.uniqueIdentifier);
|
|
$row.find('.progress-bar').css('width',(file.progress() * 100)+'%' );
|
|
});
|
|
flow.on('fileSuccess', function(file, message){
|
|
var $row = $('#file_upload_'+file.uniqueIdentifier);
|
|
$row.fadeOut();
|
|
list();
|
|
});
|
|
flow.on('fileError', function(file, message){
|
|
var $row = $('#file_upload_'+file.uniqueIdentifier);
|
|
$row.remove();
|
|
|
|
var $error_row = renderFileSizeErrorRow(file, message);
|
|
$('#upload_progress').append($error_row);
|
|
window.setTimeout(function(){ $error_row.fadeOut(); },5000);
|
|
});
|
|
flow.on('error', function(message, file, chunk) {
|
|
console.log(message, file, chunk);
|
|
});
|
|
|
|
function renderFileUploadRow(file) {
|
|
return $row = $('<div id="file_upload_'+file.uniqueIdentifier+'"/>')
|
|
.append( $('<span class="fileuploadname" />').text(file.name) )
|
|
.append( $('<div class="progress"><div class="progress-bar"></div></div>') )
|
|
.append( $('<span class="size" />').text(formatFileSize(file.size)) );
|
|
}
|
|
|
|
function renderFileSizeErrorRow(file, message) {
|
|
return $row = $('<div id="file_upload_error_'+file.uniqueIdentifier+'" class="error" />')
|
|
.append( $('<span class="fileuploadname" />').text('Error: ' + file.name))
|
|
.append( $('<span/>').text(message) );
|
|
}
|
|
|
|
function list() {
|
|
var hashval = getUrlHash();
|
|
$('#breadcrumb').empty().html(renderBreadcrumbs(hashval));
|
|
|
|
console.log('Relisting for directory: #'+hashval);
|
|
|
|
$current_dir = hashval;
|
|
$('#file-table').bootgrid("reload");
|
|
}
|
|
|
|
function getUrlHash() {
|
|
var url_hash = decodeURIComponent(window.location.hash.substr(1).replace(/\+/g, "%20"));
|
|
|
|
if (url_hash.substr(0, 9) === 'playlist:') {
|
|
window.location.hash = '';
|
|
grid.bootgrid("clear").bootgrid("search", url_hash);
|
|
return '';
|
|
}
|
|
|
|
return url_hash;
|
|
}
|
|
|
|
function getSelectedFiles() {
|
|
$files = [];
|
|
$('#file-table').find('tr.active').each(function() {
|
|
$files.push($(this).data('row-id'));
|
|
});
|
|
|
|
return $files;
|
|
}
|
|
|
|
function renderBreadcrumbs(path) {
|
|
// noinspection JSAnnotator
|
|
var base = "",
|
|
$html = $('<div/>').append( $('<a href=#>'+<?=$this->escapeJs(__('Home')) ?>+'</a></div>') );
|
|
$.each(path.split('/'),function(k,v){
|
|
if(v) {
|
|
$html.append( $('<span/>').text(' ▸ ') )
|
|
.append( $('<a/>').attr('href','#'+base+v).text(v) );
|
|
base += v + '/';
|
|
}
|
|
});
|
|
return $html;
|
|
}
|
|
|
|
function formatTimestamp(unix_timestamp) {
|
|
return moment.unix(unix_timestamp).format('lll');
|
|
}
|
|
|
|
function formatFileSize(bytes) {
|
|
var s = ['bytes', 'KB','MB','GB','TB','PB','EB'];
|
|
for(var pos = 0;bytes >= 1000; pos++,bytes /= 1024);
|
|
var d = Math.round(bytes*10);
|
|
return pos ? [parseInt(d/10),".",d%10," ",s[pos]].join('') : bytes + ' bytes';
|
|
}
|
|
});
|