file_selector.html 32 KB

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