file_selector.html 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title locale="title">File Selector</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
  7. <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
  8. <link rel="stylesheet" href="../../script/ao.css">
  9. <script type="text/javascript" src="../../script/jquery.min.js"></script>
  10. <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
  11. <script type="text/javascript" src="../../script/ao_module.js"></script>
  12. <script type="text/javascript" src="../../script/applocale.js"></script>
  13. <style>
  14. body{
  15. background-color:#f5f5f5 !important;
  16. }
  17. .navi{
  18. padding:8px;
  19. background-color:#fcfcfc;
  20. border-bottom:2px solid #34b7eb;
  21. left:0px;
  22. top:0px;
  23. margin-top: -0.6em;
  24. width:100%;
  25. z-index:99;
  26. position: fixed;
  27. }
  28. .fileSelectorContainer{
  29. width: 100%;
  30. vertical-align:top;
  31. }
  32. #sidebar{
  33. padding-top: 1em;
  34. background-color:#f5f5f5 !important;
  35. display: inline-block;
  36. z-index:90 !important;
  37. width:200px;
  38. top: 0;
  39. }
  40. #fileListWrapper{
  41. display: inline-block;
  42. width: calc(100% - 220px);
  43. min-height:300px;
  44. vertical-align:top;
  45. padding: 1em;
  46. background-color: white;
  47. border-radius: 12px;
  48. margin-bottom: 20px;
  49. margin-top: 1em;
  50. }
  51. .navi .button{
  52. box-shadow: 0 1px 1px 0px rgb(190, 190, 190) !important;
  53. }
  54. .list .item{
  55. cursor:pointer;
  56. }
  57. .list .item:hover{
  58. color:#c7c7c7 !important;
  59. }
  60. .extrapadding{
  61. padding-left:6px !important;
  62. padding-right:6px !important;
  63. color:#676768 !important;
  64. }
  65. .fileObject{
  66. overflow-wrap: break-word !important;
  67. display: block !important;
  68. padding:12px !important;
  69. font-size:98%;
  70. }
  71. .fileObject .fileInfo{
  72. display:inline-block !important;
  73. word-break: break-all;
  74. text-overflow: ellipsis !important;
  75. overflow: hidden;
  76. color:black;
  77. user-select: none;
  78. }
  79. .fileObject.selected{
  80. background-color:#d2f2f7 !important;
  81. }
  82. .fileObject.item:hover{
  83. background-color:#f2f2f2;
  84. }
  85. .bordered{
  86. border: 1px solid #dedede;
  87. }
  88. #fileListWrapper{
  89. width: calc(100% - 220px);
  90. min-height: 90vh;
  91. }
  92. @media only screen and (max-width: 560px) {
  93. #sidebar{
  94. padding-top: 2em;
  95. background-color:#f5f5f5 !important;
  96. position: fixed;
  97. width:200px;
  98. height: 100%;
  99. top: 0;
  100. left: 0;
  101. -webkit-box-shadow: 9px 0px 23px -14px rgba(135,135,135,0.4);
  102. -moz-box-shadow: 9px 0px 23px -14px rgba(135,135,135,0.4);
  103. box-shadow: 9px 0px 23px -14px rgba(135,135,135,0.4);
  104. }
  105. .navi{
  106. margin-top: -1em;
  107. }
  108. #fileListWrapper{
  109. width: 100%;
  110. }
  111. }
  112. .flexContainer{
  113. display: flex;
  114. flex-wrap:wrap;
  115. align-items:flex-start;
  116. margin-top:5px;
  117. }
  118. .flexleft {
  119. padding-right: 1em;
  120. min-width: 200px;
  121. }
  122. .flexright{
  123. flex-grow:1;
  124. margin-bottom: 0.4em;
  125. min-width: 300px;
  126. }
  127. </style>
  128. </head>
  129. <body>
  130. <div class="navi">
  131. <div class="flexContainer">
  132. <div class="flexleft">
  133. <button id="sidebarToggleBtn" class="ui icon small button" onclick="$('#sidebar').toggle();"><i class="content icon"></i></button>
  134. <button title="Back" class="ui icon small button" onclick="backDir();"><i class="arrow left icon"></i></button>
  135. <button title="Parent" class="ui icon small button" onclick="parentDir();"><i class="arrow up icon"></i></button>
  136. <button title="Refresh" class="ui icon small button" onclick="refresh();"><i class="refresh icon"></i></button>
  137. <button title="New Folder" class="ui icon small button" onclick="newFolder();"><i class="folder icon"></i></button>
  138. </div>
  139. <div class="flexright">
  140. <div class="ui action fluid tiny input" style="height: 34px; margin-top: 0.4em;">
  141. <input id="addressbar" type="text" placeholder="" onchange="updatePath();">
  142. <button class="ui positive icon button" onclick="confirmSelection();"><i class="checkmark icon"></i></button>
  143. </div>
  144. <div id="newfilenameInput" style="height: 34px; margin-top: 0.4em;">
  145. <div class="ui fluid tiny input">
  146. <input id="filename" type="text" placeholder="New Filename">
  147. </div>
  148. </div>
  149. <div id="newFolderInput" style="height: 34px; margin-top: 0.6em; display:none;">
  150. <div class="ui fluid action tiny input">
  151. <input id="foldername" type="text" placeholder="New Folder" value="">
  152. <button class="ui icon button" onclick="createFolder()" title="Create Folder"><i class="add icon"></i></button>
  153. </div>
  154. </div>
  155. </div>
  156. </div>
  157. </div>
  158. <div class="fileSelectorContainer">
  159. <!-- Sidebar -->
  160. <div id="sidebar" style="padding-left: 0.6em;">
  161. <div class="contents">
  162. <div class="ui accordion">
  163. <div class="title active">
  164. <i class="dropdown icon"></i>
  165. <span locale="roots/user">User</span>
  166. </div>
  167. <div class="active content" style="padding-left: 1em; padding-bottom: 0.5em;">
  168. <div class="ui list" id="userlist"></div>
  169. </div>
  170. </div >
  171. <div class="ui accordion">
  172. <div class="title active">
  173. <i class="dropdown icon"></i>
  174. <span locale="roots/storage">Storage</span>
  175. </div>
  176. <div class="active content">
  177. <div id="storagelist" class="ui list" style="padding-left: 1em; padding-bottom: 0.5em;" >
  178. </div>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. <!-- Folder List -->
  184. <div id="fileListWrapper" class="fileListWrapper">
  185. <div id="folderList" class="ui relaxed divided fluid list bordered whiteTheme">
  186. <div class="fileObject">
  187. <span class="fileInfo"><i class="loading spinner icon" style="margin-right:12px;"></i> <span locale="message/loading">Loading</span></span>
  188. </div>
  189. </div>
  190. <div id="fileList" class="ui relaxed divided list bordered whiteTheme">
  191. </div>
  192. <div id="nofilesCheckmark" style="width: 100%; margin-top: calc(150px - 2em); text-align:center; opacity: 0.6; display:none; pointer-events: none; user-select: none;">
  193. <p><i class="grey folder open icon"></i> <span locale="message/nofile">No file</span></p>
  194. </div>
  195. </div>
  196. </div>
  197. <div id="waitloader" class="ui active dimmer" style="display:none; z-index:999;">
  198. <div id="waitloadertext" class="ui indeterminate text loader" locale="message/waitingResp">Waiting Response</div>
  199. </div>
  200. <script>
  201. var multiSelect = false;
  202. var type = "file";
  203. var currentDir = "user:/";
  204. var currentFileList = [];
  205. var pathHistory = [];
  206. var ctrlDown = false;
  207. var shiftDown = false;
  208. var lastClickedItemID = 0;
  209. var listenerUUID = "";
  210. var fileOptions = {};
  211. //$('.ui.accordion').accordion();
  212. if (applocale){
  213. //Applocale found. Do localization
  214. applocale.init("../locale/file_selector.json", function(){
  215. applocale.translate();
  216. initRoots();
  217. });
  218. }else{
  219. //Applocale not found. Is this a trim down version of ArozOS?
  220. applocale = {
  221. getString: function(key, original){
  222. return original;
  223. }
  224. }
  225. initRoots();
  226. }
  227. initSelectorObject();
  228. updateWindowResize();
  229. function initSelectorObject(){
  230. var initInfo = loadSelectorInfoFromHash();
  231. //Load the initiation directory
  232. listDir(initInfo.root);
  233. //init global var
  234. type = initInfo.type;
  235. multiSelect = initInfo.allowMultiple;
  236. listenerUUID = initInfo.listenerUUID;
  237. if (initInfo.options != undefined){
  238. fileOptions = JSON.parse(JSON.stringify(initInfo.options));
  239. }
  240. //Load options and parse the UI
  241. if (type == "new"){
  242. //Resize the top bar
  243. updateUIElements();
  244. if (typeof(fileOptions.defaultName) != "undefined"){
  245. $("#filename").val(fileOptions.defaultName);
  246. }else{
  247. $("#filename").val("newfile.txt");
  248. }
  249. }else{
  250. $("#newfilenameInput").hide();
  251. }
  252. }
  253. function cancelSelection(){
  254. localStorage.setItem(listenerUUID, JSON.stringify("&&selection_canceled&&"));
  255. }
  256. function confirmSelection(){
  257. var files = [];
  258. $(".selected.fileObject").each(function(){
  259. var filename = decodeURIComponent($(this).attr('filename'));
  260. var filepath = decodeURIComponent($(this).attr('filepath'));
  261. files.push({
  262. filename: filename,
  263. filepath: filepath
  264. });
  265. });
  266. //Check if currentdir end with "/". If not, append it
  267. if(currentDir.substr(currentDir.length - 1, 1) != "/"){
  268. currentDir = currentDir + "/";
  269. }
  270. //Check for special cases
  271. if (files.length == 0 && type == "folder"){
  272. //Select the current path as target instead
  273. var currentPathname = currentDir.split("/");
  274. currentPathname.pop();
  275. currentPathname = currentPathname.pop();
  276. if (currentPathname == ""){
  277. currentPathname = currentDir;
  278. }
  279. files.push({
  280. filename: currentPathname,
  281. filepath: currentDir
  282. });
  283. }else if (files.length == 0 && type == "new"){
  284. //Push this new file into the return structure
  285. var newFilename = $("#filename").val();
  286. files.push({
  287. filename: newFilename,
  288. filepath: currentDir + newFilename
  289. });
  290. }
  291. if (ao_module_virtualDesktop){
  292. if (!ao_module_parentCallback(files)){
  293. //Parent callback not exists
  294. alert("Selection Failed. Is parent window alive?")
  295. }else{
  296. parent.closeFwProcess(ao_module_windowID);
  297. }
  298. }else{
  299. if (listenerUUID == ""){
  300. alert("Invalid listener UUID. Please re-open your file selector.")
  301. return;
  302. }
  303. var selectedFilesInJSON = JSON.stringify(files);
  304. localStorage.setItem(listenerUUID, selectedFilesInJSON);
  305. $("#waitloader").show();
  306. setTimeout(function(){
  307. $("#waitloadertext").html("<i class='remove icon'></i> System is not responding. <br>Please close this window and retry.");
  308. },10000)
  309. }
  310. }
  311. //Handle on window close function, cancel current selection
  312. window.onbeforeunload = function(){
  313. cancelSelection();
  314. }
  315. //Overwrite the ao_module close function
  316. function ao_module_close(){
  317. if (!ao_module_virtualDesktop){
  318. return;
  319. }
  320. if (!ao_module_parentCallback(files)){
  321. alert("Selection Failed. Is parent window alive?")
  322. }else{
  323. parent.closeFwProcess(ao_module_windowID);
  324. }
  325. }
  326. function updatePath(){
  327. var newDir = $("#addressbar").val();
  328. listDir(newDir);
  329. }
  330. function refresh(){
  331. $("#fileList").html("");
  332. $("#folderList").html("");
  333. listDir(currentDir);
  334. }
  335. function newFolder(){
  336. var newFileOffset = 0;
  337. if ($("#newfilenameInput").is(":visible")){
  338. newFileOffset += 40;
  339. }
  340. $("#newFolderInput").toggle();
  341. updateUIElements();
  342. }
  343. function updateUIElements(){
  344. $("#sidebar").css("padding-top", $(".navi").height() + 8);
  345. $("#fileListWrapper").css("padding-top", $(".navi").height() + 8)
  346. }
  347. function hideFolderNameInput(){
  348. $("#newFolderInput").hide();
  349. updateUIElements();
  350. }
  351. function createFolder(){
  352. var folderName = $("#foldername").val();
  353. if (folderName == ""){
  354. folderName = "New Folder"
  355. $("#foldername").val("New Folder");
  356. }
  357. folderName = folderName.replace(/[<>:"/\\|?*]/g, "_");
  358. //Check if folder exists
  359. var nameAlreadyExists = false;
  360. currentFileList.forEach(fileObject => {
  361. if (fileObject.IsDir && fileObject.Filename == folderName){
  362. nameAlreadyExists = true;
  363. }
  364. });
  365. if (nameAlreadyExists){
  366. alert("Folder already exists")
  367. return
  368. }
  369. //Create the new folder request
  370. requestCSRFToken(function(token){
  371. $.ajax({
  372. url: "../../system/file_system/newItem",
  373. data: {type: "folder", src: currentDir, filename: folderName, csrft: token},
  374. success: function(data){
  375. if (data.error !== undefined){
  376. alert(data.error);
  377. }else{
  378. refresh()
  379. }
  380. hideFolderNameInput();
  381. }
  382. });
  383. });
  384. }
  385. function loadSelectorInfoFromHash(){
  386. if (window.location.hash.length == 0){
  387. return {
  388. root: "user:/",
  389. type: "file",
  390. allowMultiple: false
  391. }
  392. }else{
  393. try{
  394. var selectInfo = JSON.parse(decodeURIComponent(window.location.hash.substring(1)));
  395. return selectInfo;
  396. }catch{
  397. //Error parsing the input. Use default settings
  398. return {
  399. root: "user:/",
  400. type: "file",
  401. allowMultiple: false
  402. }
  403. }
  404. }
  405. }
  406. function listDir(dir){
  407. currentDir = dir;
  408. pathHistory.push(currentDir);
  409. $("#addressbar").val(currentDir);
  410. $("#nofilesCheckmark").hide();
  411. $("#folderList").html(`<div class="ui fluid" style="text-align: center; padding: 1.2em;"><i class="ui loading spinner icon"></i></div>`);
  412. $("#folderList").show();
  413. $("#fileList").hide();
  414. ao_module_setWindowTitle(`Open`);
  415. $.get("../../system/file_system/listDir?dir=" + encodeURIComponent(dir),function(data){
  416. $("#folderList").html("");
  417. $("#fileList").html("");
  418. if (data === null){
  419. $("#folderList").hide();
  420. $("#fileList").hide();
  421. $("#nofilesCheckmark").show();
  422. return;
  423. }else{
  424. $("#folderList").show();
  425. $("#fileList").show();
  426. }
  427. if (data.error !== undefined){
  428. //Load the index instead
  429. listDir("user:/");
  430. }else{
  431. currentFileList = data;
  432. var folders = [];
  433. var files = [];
  434. for (var i =0; i < data.length; i++){
  435. if (data[i].IsDir == true){
  436. folders.push(data[i]);
  437. }else{
  438. if (fileOptions.filter != undefined){
  439. var fileExt = data[i].Filename.split(".").pop();
  440. for (var j = 0; j < fileOptions.filter.length; j++){
  441. if (fileOptions.filter[j] == fileExt){
  442. files.push(data[i]);
  443. break;
  444. }
  445. }
  446. }else{
  447. files.push(data[i]);
  448. }
  449. }
  450. }
  451. //Append folder first then files
  452. var count = 0;
  453. for (var i =0; i < folders.length; i++){
  454. var filename = folders[i].Filename;
  455. var filepath = folders[i].Filepath;
  456. var ext = filename.split(".").pop();
  457. var icon = ao_module_utils.getIconFromExt(ext);
  458. var isDir = folders[i].IsDir;
  459. if (isDir == true){
  460. icon = "yellow folder";
  461. }
  462. var fileSize = folders[i].Displaysize;
  463. $("#folderList").append(`<div class="fileObject item" fid="${count}" ondblclick="openFolder(event,this);" onclick="selectThis(this,event);" filepath="${encodeURIComponent(filepath)}" filename="${encodeURIComponent(filename)}" isDir="${isDir}">
  464. <span class="fileInfo"><i class="${icon} icon" style="margin-right:4px;"></i> ${filename}</span>
  465. </div>`);
  466. count++;
  467. }
  468. if (folders.length == 0){
  469. $("#folderList").hide();
  470. }
  471. for (var i =0; i < files.length; i++){
  472. var filename = files[i].Filename;
  473. var filepath = files[i].Filepath;
  474. var ext = filename.split(".").pop();
  475. var icon = ao_module_utils.getIconFromExt(ext);
  476. var isDir = files[i].IsDir;
  477. if (isDir == true){
  478. icon = "folder";
  479. }
  480. var fileSize = files[i].Displaysize;
  481. $("#fileList").append(`<div class="fileObject item" fid="${count}" ondblclick="chooseThisFile(this);" onclick="selectThis(this,event);" filepath="${encodeURIComponent(filepath)}" filename="${encodeURIComponent(filename)}" isDir="${isDir}">
  482. <span class="fileInfo"><i class="${icon} icon" style="margin-right:4px;margin-top: 2px;"></i> ${filename}</span>
  483. </div>`);
  484. count++;
  485. }
  486. if (files.length == 0){
  487. $("#fileList").hide();
  488. }
  489. if (folders.length == 0 && files.length == 0){
  490. //There is nothing in this dir
  491. $("#nofilesCheckmark").show();
  492. }else{
  493. $("#nofilesCheckmark").hide();
  494. }
  495. }
  496. });
  497. }
  498. function requestCSRFToken(callback){
  499. $.ajax({
  500. url: "../../system/csrf/new",
  501. success: function(token){
  502. callback(token);
  503. }
  504. })
  505. }
  506. //Open folder
  507. function openFolder(event, object){
  508. event.preventDefault();
  509. var filepath = $(object).attr("filepath");
  510. filepath = decodeURIComponent(filepath);
  511. listDir(filepath);
  512. }
  513. function selectThis(object,event){
  514. //event.preventDefault();
  515. //event.stopImmediatePropagation();
  516. //Check if this object is in suitable selection type
  517. if ($(object).attr("IsDir") == "true" && type == "file"){
  518. return;
  519. }else if ($(object).attr("IsDir") == "false" && type == "folder"){
  520. return;
  521. }else if (type == "new" && $(object).attr("IsDir") == "false"){
  522. //Use this filename as the newfile name (aka overwrite mode)
  523. var newNewFilename = $(object).attr("filename");
  524. newNewFilename = decodeURIComponent(newNewFilename);
  525. $("#filename").val(newNewFilename);
  526. return;
  527. }else if (type == "new" && $(object).attr("IsDir") == "true"){
  528. //Selected a folder in new mode. Ignore it
  529. return
  530. }
  531. if (multiSelect){
  532. if (ctrlDown){
  533. //Add this into selection list
  534. $(object).addClass("selected");
  535. }else if (shiftDown){
  536. var start = lastClickedItemID;
  537. var end = $(object).attr("fid");
  538. if (start > end){
  539. start = end;
  540. end = lastClickedItemID;
  541. }
  542. var fileObjects = $(".fileObject");
  543. for (var k = start; k <= end; k++){
  544. $(fileObjects[k]).addClass("selected");
  545. }
  546. }else{
  547. //Reset and add this into selection list
  548. $(".selected").removeClass("selected");
  549. $(object).addClass("selected");
  550. }
  551. }else{
  552. $(".selected").removeClass("selected");
  553. $(object).addClass("selected");
  554. }
  555. //Update last selected id
  556. lastClickedItemID = $(object).attr('fid');
  557. //Update title
  558. var objectCount = $(".selected").length;
  559. var typeName = "object"
  560. if (type == "file"){
  561. typeName = "file";
  562. }else if (type == "folder"){
  563. typeName = "folder";
  564. }
  565. var desc = `${typeName} selected`;
  566. if (objectCount > 1){
  567. desc = `${typeName + "s"} selected`;
  568. }
  569. ao_module_setWindowTitle(`Open (${objectCount} ${desc})`);
  570. }
  571. $(window).on("keydown",function(event){
  572. if (event.which == 17){
  573. ctrlDown = true;
  574. }else if (event.which == 16){
  575. shiftDown = true;
  576. }
  577. });
  578. $(window).on("keyup",function(event){
  579. if (event.which == 17){
  580. ctrlDown = false;
  581. }else if (event.which == 16){
  582. shiftDown = false;
  583. }
  584. });
  585. $(window).on("resize",function(){
  586. updateWindowResize();
  587. });
  588. function updateWindowResize(){
  589. if (window.innerWidth < 560){
  590. //Mobile mode
  591. $("#sidebarToggleBtn").show();
  592. $("#sidebar").hide();
  593. $("#addressbar").parent().css({
  594. "width": "100%",
  595. "margin-top": "4px"
  596. });
  597. $("#newfilenameInput").find(".input").css({
  598. "width": "100%",
  599. "margin-top": "4px"
  600. });
  601. $("#newFolderInput").find(".input").css({
  602. "width": "100%",
  603. "margin-top": "4px"
  604. });
  605. }else{
  606. $("#sidebarToggleBtn").hide();
  607. $("#sidebar").show();
  608. $("#sidebar").css("margin-top", "0px");
  609. }
  610. updateUIElements();
  611. }
  612. function initAddressBarWidth(){
  613. $("#addressbar").css("width",window.innerWidth - 220 + "px");
  614. }
  615. function chooseThisFile(object){
  616. $(".selected").removeClass('selected');
  617. $(object).addClass('selected');
  618. confirmSelection();
  619. }
  620. function parentDir(){
  621. if (currentDir.substring(currentDir.length - 1) == "/"){
  622. currentDir = currentDir.substring(0, currentDir.length - 1);
  623. }
  624. var tmp = currentDir.split("/");
  625. tmp.pop();
  626. var parentPath = tmp.join("/");
  627. if (parentPath.length == 0){
  628. //Do nothing. Already at root dir
  629. }else{
  630. listDir(parentPath);
  631. }
  632. }
  633. function backDir(){
  634. if (pathHistory.length > 1){
  635. pathHistory.pop();
  636. var targetPath = pathHistory.pop();
  637. listDir(targetPath);
  638. }
  639. }
  640. //Initialize user shortcuts
  641. function initRoots(){
  642. $.get("../../system/file_system/listRoots",function(data){
  643. $("#storagelist").html("");
  644. for (var i =0; i < data.length; i++){
  645. $('#storagelist').append(`<div class="item extrapadding" filepath="${data[i]["RootPath"]}" onclick="openShortcut(this);"><i class="disk outline icon" style="margin-right:8px;"></i> ${data[i]["RootName"]} (${data[i]["RootPath"]})</div>`);
  646. }
  647. });
  648. $.get("../../system/file_system/listRoots?user=true",function(data){
  649. $("#userlist").html("");
  650. for (var i =0; i < data.length; i++){
  651. if (data[i].IsDir == true){
  652. if (data[i]["Filename"].substring(0,1) == "."){
  653. //Do not show hidden files
  654. continue;
  655. }
  656. //Get the icon and the localization of this user root
  657. var iconAndFolderName = getUserRootIcons(data[i]["Filename"]);
  658. console.log(iconAndFolderName);
  659. $('#userlist').append(`<div class="item extrapadding" filepath="${data[i]["Filepath"]}" onclick="openShortcut(this);"><i class="${iconAndFolderName[0]} icon" style="margin-right:8px;"></i> ${iconAndFolderName[1]}</div>`);
  660. }
  661. }
  662. });
  663. }
  664. function getUserRootIcons(foldername){
  665. var icon = "folder open";
  666. var name = foldername;
  667. foldername = foldername.toLowerCase();
  668. if (foldername == "desktop"){
  669. icon = "computer";
  670. name = applocale.getString("sidebar/vroot/desktop", name);
  671. }else if (foldername == "document"){
  672. icon = "file text outline";
  673. name = applocale.getString("sidebar/vroot/document", name);
  674. }else if (foldername == "music" || foldername == "audio"){
  675. icon = "music";
  676. name = applocale.getString("sidebar/vroot/music", name);
  677. }else if (foldername == "photo" || foldername == "picture"){
  678. icon = "image";
  679. name = applocale.getString("sidebar/vroot/photo", name);
  680. }else if (foldername == "video" || foldername == "film"){
  681. icon = "video";
  682. name = applocale.getString("sidebar/vroot/video", name);
  683. }else if (foldername == "trash" || foldername == "bin" || foldername == "rubbish"){
  684. icon = "trash"
  685. name = applocale.getString("sidebar/vroot/trash", name);
  686. }else if (foldername == "download"){
  687. icon = "download"
  688. name = applocale.getString("sidebar/vroot/download", name);
  689. }else if (foldername == "www" || foldername == "web" || foldername == "mysite"){
  690. icon = "globe"
  691. name = applocale.getString("sidebar/vroot/web", name);
  692. }else if (foldername == "model"){
  693. icon = "cube"
  694. name = applocale.getString("sidebar/vroot/model", name);
  695. }else if (foldername == "appdata"){
  696. icon = "code"
  697. name = applocale.getString("sidebar/vroot/appdata", name);
  698. }
  699. return [icon, name];
  700. }
  701. function openShortcut(object){
  702. var targetdir = $(object).attr("filepath");
  703. targetdir = decodeURIComponent(targetdir);
  704. listDir(targetdir);
  705. if (window.innerWidth < 560){
  706. $("#sidebar").hide();
  707. }
  708. }
  709. </script>
  710. </body>
  711. </html>