
class FolderPicker{
constructor(path,callback){
this.callback=callback;
this.path=path?path.replace(/\/$/,''):'/Volumes';
this.shortcuts=[];
this.container=AddElement(document.body,'div');
this.container.className='panelContainer';
this.mainContent=AddElement(this.container,'div');
this.mainContent.className='panelContent';
this.mainContent.id='folderPicker';
let titleDiv=AddElement(this.mainContent,'div');
titleDiv.className='panelTitle';
titleDiv.textContent=Loc('Choose a Folder');
let bodyDiv=AddElement(this.mainContent,'div');
bodyDiv.className='panelBody';
this.pathSel=AddElement(bodyDiv,'select');
let arr=this.path.split('/');
for(let i=arr.length-1;i>0;i--)AddElement(this.pathSel,'option').textContent=arr[i];
this.pathSel.onchange=()=>this.pathChanged();
this.listSel=AddElement(bodyDiv,'select');
this.listSel.size=10;
this.listSel.ondblclick=()=>this.doubleClick();
this.listSel.id='listSel';
let button=AddElement(bodyDiv,'button');
button.type='button';
button.className='shortButton';
button.innerHTML=Loc('Create Folder…');
button.onclick=()=>this.createFolder();
this.shortcutButton=AddElement(bodyDiv,'button','margin-left:8px;');
this.shortcutButton.type='button';
this.shortcutButton.className='shortButton';
this.shortcutButton.innerHTML=Loc('Shortcuts')+' &#9662;';
this.shortcutButton.disabled=true;
this.shortcutButton.onclick=(event)=>this.chooseShortcut(event);
let footerDiv=AddElement(this.mainContent,'div');
footerDiv.className='panelFooter';
button=AddElement(footerDiv,'button');
button.type='button';
button.className='regButton';
button.textContent=Loc('Cancel');
button.onclick=()=>this.buttonClick(0);
button=AddElement(footerDiv,'button');
button.type='button';
button.className='regButton';
button.textContent=Loc('OK');
button.onclick=()=>this.buttonClick(1);
this.feedback=AddElement(footerDiv,'span','max-width:310px;');
this.feedback.className='feedback';
this.fetchDirList();
this.container.style.display='flex';
this.fetchShortcutList();
}
pathChanged(){
this.path='';
let numToRemove=this.pathSel.selectedIndex;
for(let i=0;i<numToRemove;i++)this.pathSel.options[0].remove();
this.pathSel.selectedIndex=0;
for(let i=this.pathSel.options.length-1;i>=0;i--)this.path+='/'+this.pathSel.options[i].textContent;
this.fetchDirList();
}
doubleClick(){
if(this.listSel.selectedIndex>-1)this.navigateIntoFolder(this.listSel.options[this.listSel.selectedIndex].textContent);
}
navigateIntoFolder(name){
let opt=document.createElement('option');
opt.textContent=name;
this.pathSel.add(opt,0);
this.pathSel.selectedIndex=0;
this.path+='/'+name;
this.fetchDirList();
}
goToPath(path){
this.path=path;
this.pathSel.innerHTML='';
let arr=path.split('/');
for(let i=arr.length-1;i>0;i--)AddElement(this.pathSel,'option').textContent=arr[i];
this.fetchDirList();
}
buttonClick(ok){
if(ok){
this.checkDirValidity((this.path+((this.listSel.selectedIndex>-1)?'/'+this.listSel.options[this.listSel.selectedIndex].textContent:'')));
}else{
this.callback(null);
this.container.remove();
}
}
createFolder(){
let content=AddElement(this.mainContent,'div','position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;backdrop-filter:blur(10px);border-radius:10px;');
content.className='panelPanel';
let ttl=AddElement(content,'span','display:block;margin:32px 16px 16px 16px;');
ttl.textContent=Loc('Create a Folder');
let txt=AddElement(content,'input','display:block;margin:16px;width:90%;');
txt.type='text';
let btn=AddElement(content,'button');
btn.type='button';
btn.innerHTML=Loc('Cancel');
btn.className='regButton';
btn.onclick=()=>{
content.remove();
};
btn=AddElement(content,'button');
btn.type='button';
btn.innerHTML=Loc('Create');
btn.className='regButton';
btn.onclick=()=>{
let name=txt.value.trim();
name=name.replace(/[\/:]/g,'');
if(name)this.navigateIntoFolder(name);
content.remove();
};
txt.focus();
}
chooseShortcut(event){
let menu=new PopMenu(event);
for(let shortcut of this.shortcuts){
menu.addItem(shortcut.name,false,()=>{this.goToPath(shortcut.path)});
}
}
async fetchShortcutList(){
let response=await fetch('dirShortcuts',{credentials:'same-origin'});
if(response.ok){
this.shortcuts=await response.json();
if(this.shortcuts.length){
this.shortcutButton.disabled=false;
}
}
}
async fetchDirList(){
this.listSel.innerHTML='<option disabled>'+Loc('Loading…')+'</option>';
try{
let response=await fetch('dirList?path='+encodeURIComponent(this.path),{credentials:'same-origin'});
if(!response.ok)throw new Error('HTTP error '+response.status);
let txt=await response.text();
let arr=txt.split('/');
arr.sort();
this.listSel.innerHTML='';
for(let name of arr)if(name)AddElement(this.listSel,'option').textContent=name;
}catch(error){
this.listSel.innerHTML='<option disabled>'+error+'</option>';
}
}
async checkDirValidity(path){
let response=await fetch('dirValidity?path='+encodeURIComponent(path),{credentials:'same-origin'});
if(response.ok){
let txt=await response.text();
if(txt=='OK'){
this.callback(path);
this.container.remove();
}else{
this.feedback.textContent=Loc('ReadOnlyDir');
}
}
}
}
