319 lines
13 KiB
JavaScript
319 lines
13 KiB
JavaScript
// grab all selected thumbnails and return a <div> containing the thumbnails
|
|
// with extra yr and date attached as attributes so we can set the default
|
|
// dir name for a move directory - not used in del, but no harm to include them
|
|
function GetSelnAsDiv()
|
|
{
|
|
seln=''
|
|
$('.highlight').each(function( index ) {
|
|
seln+='<div fname="' + $(this).attr('fname') + '" yr="' + $(this).attr('yr') +
|
|
'" date="' + $(this).attr('date') +
|
|
'" class="px-1 col col-auto">' + $(this).children().parent().html() + '</div>'
|
|
seln+='<input type="hidden" name="eid-'+index+'" value="'+$(this).attr('id')+'">'
|
|
} )
|
|
return '<div class="row col-12">'+seln+'</div>'
|
|
}
|
|
|
|
// return a list of eid=<id> for each selected thumbnail
|
|
function GetSelnAsData()
|
|
{
|
|
to_del=''
|
|
$('.highlight').each(function( index ) { to_del+='&eid-'+index+'='+$(this).attr('id') } )
|
|
return to_del
|
|
}
|
|
|
|
// use an ajax POST to force an AI scan on the selected image(s)
|
|
function RunAIOnSeln(person)
|
|
{
|
|
post_data = GetSelnAsData()
|
|
post_data += '&person='+person.replace('ai-','')
|
|
$.ajax({ type: 'POST', data: post_data, url: '/run_ai_on', success: function(data){ CheckForJobs() } })
|
|
}
|
|
|
|
// code to change the associated image/icon when the move to selection box (import or storage paths) is changed
|
|
function change_rp_sel()
|
|
{
|
|
icon_url = $('option:selected', '#rp_sel').attr('icon_url')
|
|
$('#move_path_icon').html( '<svg id="move_path_icon" width="20" height="20" fill="currentColor"><use xlink:href="'
|
|
+ icon_url + '"></svg>' )
|
|
seld_ptype=$('option:selected', '#rp_sel').attr('path_type')
|
|
$('#move_path_type').val( seld_ptype )
|
|
// clear all 'existing' buttons
|
|
$('.move_Import').addClass('d-none')
|
|
$('.move_Storage').addClass('d-none')
|
|
// show just selected path's (relevant) buttons
|
|
$('.move_'+seld_ptype).removeClass('d-none')
|
|
}
|
|
|
|
// POST to see if there are any other existing directories named around this date
|
|
// (if so display them as options for a move)
|
|
function GetExistingDirsAsDiv( dt, divname, ptype )
|
|
{
|
|
$.ajax({
|
|
type: 'POST', data: null, url: '/get_existing_paths/'+dt,
|
|
success: function(data) {
|
|
$('#'+divname).html(data)
|
|
dirs = JSON.parse(data)
|
|
s=''
|
|
dirs.forEach( function(item, index) {
|
|
if( item.ptype != ptype )
|
|
vis = 'd-none '
|
|
else
|
|
vis = ''
|
|
s+= '<button class="btn btn-outline-primary move_'+item.ptype+ ' ' + vis + '" '
|
|
s+= 'onClick="$(\'#prefix\').val(\''+item.prefix.replace("\'","\\\'")+'\'); '
|
|
s+='$(\'#suffix\').val(\''+item.suffix.replace("\'","\\\'")+'\');return false;">'
|
|
s+=item.prefix+item.suffix
|
|
s+='</button>'
|
|
} )
|
|
if( s == '' )
|
|
$('#existing').html('')
|
|
else
|
|
$('#move_'+ptype).removeClass('invisible')
|
|
$('#'+divname).html(s)
|
|
}
|
|
} )
|
|
}
|
|
|
|
// wrapper to do some clean up before POST to /move_files or /delete_files
|
|
// used to remove the highlighted item(s) && reset the numbering so highlighting continues to work
|
|
function MoveOrDelCleanUpUI()
|
|
{
|
|
// remove the images being moved (so UI immediately 'sees' the move)
|
|
$("[name^=eid-]").each( function() { $('#'+$(this).attr('value')).remove() } )
|
|
// reorder the images via ecnt again, so future highlighting can work
|
|
document.mf_id=0; $('.figure').each( function() { $(this).attr('ecnt', document.mf_id ); document.mf_id++ } )
|
|
$('#dbox').modal('hide')
|
|
}
|
|
|
|
|
|
// show the DBox for a move file, includes all thumbnails of selected files to move
|
|
// and a pre-populated folder to move them into, with text field to add a suffix
|
|
function MoveDBox(path_details, db_url)
|
|
{
|
|
$('#dbox-title').html('Move Selected File(s) to new directory in Storage Path')
|
|
div =`
|
|
<div class="form-row col-12">
|
|
<p class="col">Moving the following files?</p>
|
|
</div>
|
|
<form id="mv_fm" class="form form-control-inline col-12">
|
|
<input id="move_path_type" name="move_path_type" type="hidden"
|
|
`
|
|
div += ' value="' + path_details[0].type + '"></input>'
|
|
div+=GetSelnAsDiv()
|
|
yr=$('.highlight').first().attr('yr')
|
|
dt=$('.highlight').first().attr('date')
|
|
div+='<div class="row">Use Existing Directory (in the chosen path):</div><div id="existing"></div>'
|
|
GetExistingDirsAsDiv( dt, "existing", path_details[0].type )
|
|
div+=`
|
|
<div class="input-group my-3">
|
|
<alert class="alert alert-primary my-auto py-1">
|
|
`
|
|
// NB: alert-primary here is a hack to get the bg the same color as the alert primary by
|
|
div+= '<svg id="move_path_icon" width="20" height="20" fill="currentColor"><use xlink:href="' + path_details[0].icon_url + '"></svg>'
|
|
div+= '<select id="rp_sel" name="rel_path" class="text-primary alert-primary py-1 border border-primary rounded" onChange="change_rp_sel()">'
|
|
for(p of path_details) {
|
|
div+= '<option path_type="'+p.type+'" icon_url="'+p.icon_url+'">'+p.path+'</option>'
|
|
}
|
|
div+= '</select>'
|
|
div+=`
|
|
</alert>
|
|
<input id="prefix" type="text" name="prefix" class="text-primary text-right form-control"
|
|
`
|
|
div+="value="+yr+'/'+dt+"-"
|
|
div+=`
|
|
"></input>
|
|
<input id="suffix" type="text" name="suffix" class="form-control" placeholder="name"> </input>
|
|
</div>
|
|
<div class="form-row col-12 mt-2">
|
|
<button onClick="$('#dbox').modal('hide'); return false;" class="btn btn-outline-secondary offset-1 col-2">Cancel</button>
|
|
<button id="move_submit" onClick="MoveOrDelCleanUpUI(); $.ajax({ type: 'POST', data: $('#mv_fm').serialize(), url: '/move_files', success: function(data) {
|
|
if( $(location).attr('pathname').match('search') !== null ) { window.location='/' }; CheckForJobs() } }); return false" class="btn btn-outline-primary col-2">Ok</button>
|
|
</div>
|
|
</form>
|
|
`
|
|
|
|
$('#dbox-content').html(div)
|
|
$('#dbox').modal('show')
|
|
$("#prefix").keypress(function (e) { if (e.which == 13) { $("#move_submit").click(); return false; } } )
|
|
$("#suffix").keypress(function (e) { if (e.which == 13) { $("#move_submit").click(); return false; } } )
|
|
}
|
|
|
|
// show the DBox for a delete/restore file, includes all thumbnails of selected files
|
|
// with appropriate coloured button to Delete or Restore files`
|
|
function DelDBox(del_or_undel)
|
|
{
|
|
to_del = GetSelnAsData()
|
|
$('#dbox-title').html(del_or_undel+' Selected File(s)')
|
|
div ='<div class="row col-12"><p class="col">' + del_or_undel + ' the following files?</p></div>'
|
|
div+=GetSelnAsDiv()
|
|
div+=`<div class="row col-12 mt-3">
|
|
<button onClick="$('#dbox').modal('hide')" class="btn btn-outline-secondary col-2">Cancel</button>
|
|
`
|
|
div+=`
|
|
<button onClick="MoveOrDelCleanUpUI(); $.ajax({ type: 'POST', data: to_del, url:
|
|
`
|
|
if( del_or_undel == "Delete" )
|
|
div+=`
|
|
'/delete_files',
|
|
success: function(data){
|
|
if( $(location).attr('pathname').match('search') !== null ) { window.location='/' }; CheckForJobs() } }); return false" class="btn btn-outline-danger col-2">Ok</button>
|
|
</div>
|
|
`
|
|
else
|
|
// just force page reload to / for now if restoring files from a search path -- a search (by name)
|
|
// would match the deleted/restored file, so it would be complex to clean up the UI (and can't reload, as DB won't be changed yet)
|
|
div+=`
|
|
'/restore_files',
|
|
success: function(data){
|
|
if( $(location).attr('pathname').match('search') !== null ) { window.location='/' }; CheckForJobs() } }); return false" class="btn btn-outline-success col-2">Ok</button>
|
|
</div>
|
|
`
|
|
$('#dbox-content').html(div)
|
|
$('#dbox').modal('show')
|
|
}
|
|
|
|
// show the DBox for a lame quick version of file details
|
|
function DetailsDBox()
|
|
{
|
|
$('#dbox-title').html('Details of Selected File(s)')
|
|
var div ='<div class="row col-12">'
|
|
$('.highlight').each(function( index ) {
|
|
div += "<div class='col-3' style='background-color:lightgray'>Name:</div><div class='col-9' style='background-color:lightgray'>" + $(this).attr('fname') + "</div>"
|
|
div += "<div class='col-3'>Date:</div><div class='col-9'>" + $(this).attr('pretty_date') + "</div>"
|
|
dir = $(this).attr('in_dir')
|
|
if( dir.slice(-1) != "/" )
|
|
dir=dir.concat('/')
|
|
div += "<div class='col-3'>Dir:</div><div class='col-9'>" + dir + "</div>"
|
|
div += "<div class='col-3'>Size:</div><div class='col-9'>" + $(this).attr('size') + " MB</div>"
|
|
div += "<div class='col-3'>Hash:</div><div class='col-9'>" + $(this).attr('hash') + "</div>"
|
|
div += "<div class='col-3'>Path Type:</div><div class='col-9'>" + $(this).attr('path_type') + "</div>"
|
|
} )
|
|
div += `
|
|
</div>
|
|
<br>
|
|
<div class="form-row col-12">
|
|
<button onClick="$('#dbox').modal('hide'); return false;" class="btn btn-outline-secondary offset-1 col-2">Cancel</button>
|
|
</div>
|
|
`
|
|
$('#dbox-content').html(div)
|
|
$('#dbox').modal('show')
|
|
}
|
|
|
|
|
|
// function to change the size of thumbnails (and resets button bar to newly
|
|
// selected size)
|
|
function ChangeSize(clicked_button,sz)
|
|
{
|
|
$('.sz-but.btn-info').removeClass('btn-info text-white').addClass('btn-outline-info')
|
|
$(clicked_button).addClass('btn-info text-white').removeClass('btn-outline-info')
|
|
$('.thumb').attr( {height: sz, style: 'font-size:'+sz+'px' } )
|
|
$('#size').val(sz)
|
|
sz=sz-22
|
|
$('.svg').height(sz);
|
|
$('.svg').width(sz);
|
|
$('.svg_cap').width(sz);
|
|
}
|
|
|
|
// DoSel is called when a click event occurs, and sets the selection via adding
|
|
// 'highlight' to the class of the appropriate thumbnails
|
|
// e == event (can see if shift/ctrl held down while left-clicking
|
|
// el == element the click is on
|
|
// this allows single-click to select, ctrl-click to (de)select 1 item, and
|
|
// shift-click to add all elements between highlighted area and clicked area,
|
|
// whether you click after highlight or before
|
|
function DoSel(e, el)
|
|
{
|
|
if( e.ctrlKey || document.fake_ctrl === 1 )
|
|
{
|
|
$(el).toggleClass('highlight')
|
|
if( document.fake_ctrl === 1 )
|
|
document.fake_ctrl=0
|
|
return
|
|
}
|
|
if( e.shiftKey || document.fake_shift === 1 )
|
|
{
|
|
st=Number($('.highlight').first().attr('ecnt'))
|
|
end=Number($('.highlight').last().attr('ecnt'))
|
|
clicked=Number($(el).attr('ecnt'))
|
|
// if we shift-click first element, then st/end are NaN, so just highlightthe one clicked
|
|
if( isNaN(st) )
|
|
{
|
|
$('.entry').slice( clicked, clicked+1 ).addClass('highlight')
|
|
return
|
|
}
|
|
if( clicked > end )
|
|
$('.entry').slice( end, clicked+1 ).addClass('highlight')
|
|
else
|
|
$('.entry').slice( clicked, st ).addClass('highlight')
|
|
|
|
if( document.fake_shift === 1 )
|
|
document.fake_shift=0
|
|
return
|
|
}
|
|
$('.highlight').removeClass('highlight')
|
|
$(el).addClass('highlight')
|
|
}
|
|
|
|
// if a selection exists, enable move & del/restore buttons otherwise disable them
|
|
function SetButtonState() {
|
|
var sel=false
|
|
$('.highlight').each(function( index ) { sel=true } )
|
|
if( sel ) {
|
|
$('#move').attr('disabled', false )
|
|
$('#del').attr('disabled', false )
|
|
} else {
|
|
$('#move').attr('disabled', true )
|
|
$('#del').attr('disabled', true )
|
|
}
|
|
}
|
|
|
|
// Check if the set of highlights are either only figures, dirs or both
|
|
// used to work out what options are shown in the file context menu
|
|
function FiguresOrDirsOrBoth() {
|
|
var figure=false
|
|
var dir=false
|
|
$('.highlight').each(function( index ) {
|
|
if( $(this).hasClass('figure') ) {
|
|
figure=true
|
|
}
|
|
if( $(this).hasClass('dir') ) {
|
|
dir=true
|
|
}
|
|
} )
|
|
if( figure & ! dir )
|
|
return "figure"
|
|
if( ! figure & dir )
|
|
return "dir"
|
|
return "both"
|
|
}
|
|
|
|
// Check if the set of highlights contain Bin and Not Bin...
|
|
// if its both, then no del/restore is possible in context menu
|
|
// otherwise can either set del or restore appropriately
|
|
function SelContainsBinAndNotBin() {
|
|
var bin=false
|
|
var not_bin=false
|
|
$('.highlight').each(function( index ) {
|
|
if( $(this).attr('path_type') == "Bin" ) {
|
|
bin=true
|
|
} else {
|
|
not_bin=true
|
|
}
|
|
} )
|
|
if( bin && not_bin )
|
|
return true
|
|
else
|
|
return false
|
|
}
|
|
|
|
// checks to see if there is no selection active
|
|
function NoSel() {
|
|
var sel=false
|
|
$('.highlight').each(function( index ) { sel=true } )
|
|
// func looks for No Selection, so if sel is true and we have a sel, return false (i.e. NOT No Sel -> Sel )
|
|
if( sel )
|
|
return false
|
|
else
|
|
return true
|
|
}
|