From 9db728e1ad9a84ddf9d8675d2c841713169f7e08 Mon Sep 17 00:00:00 2001 From: Serghey Rodin Date: Mon, 7 Sep 2015 17:35:40 +0300 Subject: [PATCH] filemanager stuff --- web/autoescape.gif | Bin 15180 -> 0 bytes web/css/file_manager.css | 235 ++++- web/download/file/index.php | 15 + web/edit/file/index.php | 76 ++ web/file_manager/fm_api.php | 46 +- web/file_manager/fm_core.php | 248 +++-- web/images/flat_icons.png | Bin 9853 -> 12399 bytes web/images/in_progress.gif | Bin 0 -> 404 bytes web/js/app.js | 35 + web/js/file_manager.js | 1093 +++++++++++++++++++---- web/js/floating_layer.js | 13 +- web/js/i18n.js.php | 7 + web/js/templates.js | 88 +- web/templates/file_manager/main.php | 470 ++++++---- web/templates/file_manager/tab_menu.php | 33 +- 15 files changed, 1878 insertions(+), 481 deletions(-) delete mode 100644 web/autoescape.gif create mode 100644 web/download/file/index.php create mode 100644 web/edit/file/index.php create mode 100644 web/images/in_progress.gif diff --git a/web/autoescape.gif b/web/autoescape.gif deleted file mode 100644 index 0070e30e592053a6e29483e5dca761a71366f724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15180 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 lMR+3Y>PmFg_STP`>N!-0XeGr9QRD^nz&Xd0`e + +Edit file <?= htmlspecialchars($_REQUEST['path']) ?> + + + + + + + + + + + +
+ + + + + +
+ diff --git a/web/file_manager/fm_api.php b/web/file_manager/fm_api.php index b8e40fa2..80615df9 100644 --- a/web/file_manager/fm_api.php +++ b/web/file_manager/fm_api.php @@ -27,18 +27,29 @@ $fm->setRootDir($panel[$user]['HOME']); $_REQUEST['action'] = empty($_REQUEST['action']) ? '' : $_REQUEST['action']; switch ($_REQUEST['action']) { + case 'cd': + $dir = $_REQUEST['dir']; + print json_encode($fm->ls($dir)); + break; case 'rename_file': $dir = $_REQUEST['dir']; $item = $_REQUEST['item']; $target_name = $_REQUEST['target_name']; - print json_encode($fm->renameItem($dir, $item, $target_name)); + print json_encode($fm->renameFile($dir, $item, $target_name)); + break; + case 'rename_directory': + $dir = $_REQUEST['dir']; + $item = $_REQUEST['item']; + $target_name = $_REQUEST['target_name']; + + print json_encode($fm->renameDirectory($dir, $item, $target_name)); break; case 'delete_files': $dir = $_REQUEST['dir']; $item = $_REQUEST['item']; - print json_encode($fm->deleteItems($dir, $item)); + print json_encode($fm->deleteItem($dir, $item)); break; case 'create_file': $dir = $_REQUEST['dir']; @@ -50,19 +61,38 @@ switch ($_REQUEST['action']) { $dirname = $_REQUEST['dirname']; print json_encode($fm->createDir($dir, $dirname)); break; - case 'cd': - $dir = $_REQUEST['dir']; - print json_encode($fm->ls($dir)); - break; + case 'open_file': $dir = $_REQUEST['dir']; print json_encode($fm->open_file($dir)); break; - case 'copy_files': + case 'copy_file': $dir = $_REQUEST['dir']; $target_dir = $_REQUEST['dir_target']; $filename = $_REQUEST['filename']; - print json_encode($fm->copyFile($dir, $target_dir, $filename)); + $item = $_REQUEST['item']; + print json_encode($fm->copyFile($item, $dir, $target_dir, $filename)); + break; + case 'copy_directory': + $dir = $_REQUEST['dir']; + $target_dir = $_REQUEST['dir_target']; + $filename = $_REQUEST['filename']; + $item = $_REQUEST['item']; + print json_encode($fm->copyDirectory($item, $dir, $target_dir, $filename)); + break; + case 'unpack_item': + $dir = $_REQUEST['dir']; + $target_dir = $_REQUEST['dir_target']; + $filename = $_REQUEST['filename']; + $item = $_REQUEST['item']; + print json_encode($fm->unpackItem($item, $dir, $target_dir, $filename)); + break; + case 'pack_item': + $dir = $_REQUEST['dir']; + $target_dir = $_REQUEST['dir_target']; + $filename = $_REQUEST['filename']; + $item = $_REQUEST['item']; + print json_encode($fm->packItem($item, $dir, $target_dir, $filename)); break; default: //print json_encode($fm->init()); diff --git a/web/file_manager/fm_core.php b/web/file_manager/fm_core.php index 61871b1b..67ca31d5 100644 --- a/web/file_manager/fm_core.php +++ b/web/file_manager/fm_core.php @@ -32,7 +32,7 @@ class FileManager { $path = !empty($_REQUEST['dir']) ? $_REQUEST['dir'] : ''; $start_url = !empty($path) ? $this->ROOT_DIR . '/' . $path : $this->ROOT_DIR; $listing = $this->getDirectoryListing($path); - + return $data = array( 'result' => true, 'ROOT_DIR' => $this->ROOT_DIR, @@ -50,11 +50,34 @@ class FileManager { $path = $this->ROOT_DIR . '/' . $path_part; } //var_dump($path);die(); + //$path = str_replace(' ', '\ ', $path); return escapeshellarg($path); } - function deleteItems($dir, $item) { - if (is_readable($item)) { + function deleteItem($dir, $item) { + $dir = $this->formatFullPath($item); + if (is_dir($item)) { + exec (VESTA_CMD . "v-delete-fs-directory {$this->user} {$dir}", $output, $return_var); + } + else { + exec (VESTA_CMD . "v-delete-fs-file {$this->user} {$dir}", $output, $return_var); + } + + $error = self::check_return_code($return_var, $output); + + if (empty($error)) { + return array( + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + + /*if (is_readable($item)) { unlink($item); } if (is_readable($item)) { @@ -65,93 +88,194 @@ class FileManager { } return array( 'result' => true - ); + );*/ } - function copyFile($dir, $target_dir, $filename) { - // todo: checks - // todo: vesta method "create file" - if (empty($dir)) { - $dir = $this->ROOT_DIR; - } + function copyFile($item, $dir, $target_dir, $filename) { + $src = $this->formatFullPath($item); + $dst = $this->formatFullPath($target_dir); + + exec (VESTA_CMD . "v-copy-fs-file {$this->user} {$src} {$dst}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); - if (empty($target_dir)) { - $target_dir = $this->ROOT_DIR; - } - copy($dir . '/' . $filename, $target_dir.'/'.$filename); - - if (!is_readable($target_dir . '/' .$filename)) { + if (empty($error)) { return array( - 'result' => false, - 'message' => 'item was not created' + 'result' => true ); } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + } + + + function copyDirectory($item, $dir, $target_dir, $filename) { + $src = $this->formatFullPath($item); + $dst = $this->formatFullPath($target_dir); + + exec (VESTA_CMD . "v-copy-fs-directory {$this->user} {$src} {$dst}", $output, $return_var); + + + $error = self::check_return_code($return_var, $output); - return array( - 'result' => true, - 'bla' => $target_dir.'/'.$filename, - 'bla2' => $dir . '/' . $filename - ); + if (empty($error)) { + return array( + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + } + + static function check_return_code($return_var, $output) { + if ($return_var != 0) { + $error = implode('
', $output); + return $error; + //if (empty($error)) $error = __('Error code:',$return_var); + //$_SESSION['error_msg'] = $error; + } + + return null; } function createFile($dir, $filename) { - // todo: checks - // todo: vesta method "create file" - if (empty($dir)) { - $dir = $this->ROOT_DIR; - } - file_put_contents($dir . '/' . $filename, ''); + $dir = $this->formatFullPath($dir . '/' . $filename); + + exec (VESTA_CMD . "v-add-fs-file {$this->user} {$dir}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); - if (!is_readable($dir . '/' .$filename)) { + if (empty($error)) { return array( - 'result' => false, - 'message' => 'item was not created' + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error ); } - - return array( - 'result' => true - ); } - function renameItem($dir, $item, $target_name) { - if (empty($dir)) { - $dir = $this->ROOT_DIR; - } - if (is_readable($dir . '/' . $item)) { - rename($dir . '/' . $item, $dir . '/' . $target_name); - } - if (!is_readable($dir . '/' .$target_name)) { + function packItem($item, $dir, $target_dir, $filename) { + $item = $this->formatFullPath($item); + $dst_item = $this->formatFullPath($target_dir); +//print VESTA_CMD . "v-add-fs-archive {$this->user} {$item} {$dst_item}";die(); + exec (VESTA_CMD . "v-add-fs-archive {$this->user} {$item} {$dst_item}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); + + if (empty($error)) { return array( - 'result' => false, - 'message' => 'item was not renamed' + 'result' => true ); } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + } + + function unpackItem($item, $dir, $target_dir, $filename) { + $item = $this->formatFullPath($item); + $dst_item = $this->formatFullPath($target_dir); + + exec (VESTA_CMD . "v-extract-fs-archive {$this->user} {$item} {$dst_item}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); - return array( - 'result' => true - ); + if (empty($error)) { + return array( + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + } + + function renameFile($dir, $item, $target_name) { + $item = $this->formatFullPath($dir . '/' . $item); + $dst_item = $this->formatFullPath($dir . '/' . $target_name); + +// var_dump(VESTA_CMD . "v-move-fs-file {$this->user} {$item} {$dst_item}");die(); + + exec (VESTA_CMD . "v-move-fs-file {$this->user} {$item} {$dst_item}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); + + if (empty($error)) { + return array( + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error + ); + } + } + function renameDirectory($dir, $item, $target_name) { + $item = $this->formatFullPath($dir . $item); + $dst_item = $this->formatFullPath($dir . $target_name); + + if ($item == $dst_item) { + return array( + 'result' => true + ); + } + + + exec (VESTA_CMD . "v-move-fs-directory {$this->user} {$item} {$dst_item}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); + + if (empty($error)) { + return array( + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error + ); + } } function createDir($dir, $dirname) { - // todo: checks - // todo: vesta method "create file" - if (empty($dir)) { - $dir = $this->ROOT_DIR; - } + $dir = $this->formatFullPath($dir . '/' . $dirname); - mkdir($dir . '/' . $dirname); + exec (VESTA_CMD . "v-add-fs-directory {$this->user} {$dir}", $output, $return_var); + + $error = self::check_return_code($return_var, $output); - if (!is_readable($dir . '/' .$dirname)) { + if (empty($error)) { return array( - 'result' => false, - 'message' => 'item was not created' + 'result' => true + ); + } + else { + return array( + 'result' => false, + 'message' => $error ); } - - return array( - 'result' => true - ); } function getDirectoryListing($dir = '') { diff --git a/web/images/flat_icons.png b/web/images/flat_icons.png index 631f3b3c55405a9eeb6ba8f83c7260dd704afe3d..3b10800029ccd1df931a5fe3a5f5cd978cd45cf8 100644 GIT binary patch literal 12399 zcmaL81yodD)INOa?naPMq@|=&7*J4Bx|^Xvx2m7D2kCOOOU>7~;G9 z{%d{T`(Nu_--SEeb?%*W_T6XieV+a7L!_F@D*{|vTmS$F6kkI$000F6p48ZwU<@+403B&rbG)q0DoK zw+%hEs&wf!Tm@>=xM4}$wIa{v`^*f|-wm_pTk+X8j5@LppgD$!yv$)*ONJ-4o|P61mTuLGll z#v_?1SVw7lw$XL{fbOD%V}aFXF92@lO-~qJl#`PaUPeqZMvjZ9Flay|Y6yj)*-IER zK?dOjk321#RpDlhVZ@2+L!1Q;I^?~rX5H{S!^DV)XRa>b2#HvsorFN0t;B*w&Fs!E zglE0eVv~&0>=(<3K07-HhlQ@G$OtGY=FD`30TnfTl|oiz!U&!)Uc?qPSg!OVU#iYw zq0#l7&<{jSO^xBqS<}(8U)~gE$qD0bKUtD3D>x(rZ@d!|s#TO|F66?AyPm+dz6v`p z1-7+B6t9GG8ru4dm)n{9I0_j!7A7XA1dz&3+E~1^wz0AKo>0x+qUW*TlBnT{!=$f` zFtpXD@ZS6Vjh4MYJd9)Z3Cv|AOFBr{#2RAxj3xOKMrfyJyeuAIxVo{SoRy!jUr|w^ zWgRn%$J3%_MGa@AqgB*`t=_tE^R!*A3GlQW$@blfdhY4gB#ehn3hhrTu}l7lp|{^0 z{1}1D-}s;gN|}tG(G_?+!rWk2g4P#`*kk6_1uU@seA;pfS#L3M@j(H6ZZAx;18Z** z^_Q5*X4D4~hE9HzO`2(nUlqcW%&0Rh%gXsg2)bW$w!}P^Y!ZqejUuefdlie=82l9R z%k-!Glhs38tv(eKmOB{Bj%xxtnoZ#u?Su;?Gy3o8o45)W4g&)NdyU&nol8IcC)fGA zV%kH}F?iMlIloA*t5gFyW89NhzavC{wyDpc^g~T_L_RCem(v;>k7LEAi@2J`8LUfDuKw+*5F^39o4xmWI^iNK*CgG@71vLH_yL6 zEy=rmp=|&258I%~`u^mL3XBfBw!H{8GSOL0HW;eQ1T@AMT?_=5`u(jt>g z(o`r&>Gfa5&~;+9-oXUsx%-N3ZB$QU^~S7tEf2UPDHORcF8{4-@dgDw1t!Cil_3ci z6v>=owJ~&}sNK98#t}xaKBGX~bam&+Bjm01{fMm==W2k#6WMNFd_zz$Hg0Zu!TXgJ zMq{6i#Qd^f!^6YJJ3Bjk?XsrSeZ{!n+uIrND7j=@UH=td$>k6)1zarVUlSXj7aEqk zzaRO;!*r9gz0tkc2zBj^Kw1=fyv&s=|J@epj0eGg{*^?3_Wj;(zSHybP30i`ZkJxT zwyLV?!YFF++M0Q}?lP!xQwmHn{W6g`{3FG zQ{NV)4yq#~j)fXAF)=0d2)R{hb2f&op|ks*&d*|JUJyu1N{)KaYYgD%iH;L+Gv|IF zLbSC>RrbcUR>WxxB*=BGx_C!NMP--T30+Sl{wyhep)6-&!jPXpEGwg)kX}iRhKA;& z^NEyXgR4>L%^OL=aEr;!CzU*P>r^qjHKZ8w0~9mAQUoOB<>g&O=pqQUoOO-|v7xx` zM#2TCAF(k*si~=hiBV-E`tOq`63wAd?AF#+8(D#IBIaEG&+(xGPOWFttOt$jF`&5> zl$K(nqk{5Ei?xVsTZv>0t78F>(zG^$SigS=o@)9FD7mm zXb0XSm!&PJ6&&;DNMzGXymO1>g_snamB?i~tZP`r{FiFpZw$Ep*!?8DRJ^^rdjioh z_}2bIAmG|PAtB+T@hYr%sJB3+De$bohB95C;`|Sm91yH?KOP;MZXjfy`P;UpkZN^w z?1Gc0-BljDezv*)A z3#BgRH1zGjpUd=;znw1;`354$3N#4rea zX1{)Ze`(8((>Ex&wDidbf!WbG4PQ5p07Pbp>Hc7NvupKyZ2V%NX2RU?g3611(A!4c z6BB7kI1yhCzW>eSFq)YcRCbfs5$!Z}>DjFEIoZqsCvMEVMPuOltjSTLq=)jv z9XB~HQ~h-mY&usynv^~aIv~&eDna4#NJJ@TQ&ZHPxNqvBlPb0TPi=!St(no$&#do7 z+7gc6QqUTNu#oA0FRuqWko_Jb`DZyOz7s#DC5Fp{$@m%-!gNG~W7OC*AK^r*vB5y6 zHRTmChWa=N8Dyj|kxW(Ezff-0nK?VjMbp9#85kI7%wZ{T_%^@qRD+zDoz;`#5et1GPzi}PKcgH$?GE8_vHJ*%7wM|&8$4W;C zvLHeE%V<o*{3pMt=sFnQ&LnYP8U;Dkbu})i6X4vL+#FEQ!*+|)J{KY zQdjyeS$`b0@SKN7)jNuv-RkxO2A=0pfdV9+qY>(mk&&?h#)x}1*kzytv{zj1X}Rsj zK%&8~o$e4cEN$So6E&Q(>6n9?TiLxTN=Iwz8ngx1AQBS3#==tRn^hvb7s_SA_<1T? zS~}@FlX%%i>Ivs>%gP}SvELrQyO>ILa?U}>#+{)n%}o-R8fE^1mPIk8P9G z7_U5NQ>hLAMZ7&f`TItSUF%;KYObb|&&3%hvMq5}YHz8v8M}iONJn?cE-dV;9fTg< zJc+`Oz9ow?Prq3^9z|hdyefb9oShCe_a_UTzCCb5+;M?YKG*8kz+QQl5d`_d6g9(E zbwdolMaJI!{8susAj+UnEbTt|KP$$hf?eX ztjT{l^Si1}03~7$j#p~KcPxvtORSE5=9XUqYap2bHRGYTTk7lA3G4zuh7bT=g&#Q?Oq*4&vr`J zla!4(cgTV^fYv4fTACtz8jN`O+vcbAiY4osI?HuZ&VO`b?$C+{pr`k!GDt(o`7+@R zHyW#qUlfkA2)o&wF2Z3YK+Q=UkSO?l>VQ)0mg^S?G zr}Mvi(a{x2*4P`-ve>UKBYB@5r3U|_*ORC^xsGM}+PhMU?t&GpiYkI9^C#Ey6>y5u zNY!BhN_D51d|M+u%Nb_=U5;ceK3L=pwmJ$xdW@aF7dm-BPkk!w*-dferkw3CcvZjs zfXXpe6ra=*2YzI2!JlxLt=^zzg0W7Gq5@2?ci5}5)mDRov(%NLSVT)au&viDwOzNR zMChnXGsb=uQDr_(lO~Tv93oaO@cWHOHR3gt*grktt>wN&Lu>E1hKAj;7&;oEtQ4)< z1^{h1D{esMYt~v|WvU1@h!1}Ovn&vUF^HD1LduMK8K!klS9q0W3LVQY|4(haEwdvj zKi_w0sZ`J;>RhH87z|#}Av|=~4OG!cYTaH2Ptp<#tkFpJ9LFf|AUgS6 zdeA2GnN{!9^t85<0#v?~4#+&>7ci%W+XnFCcUw$*w;m60&U_`-2h_GNkdlT|ZWf^Z z26?62$Eu;;Tgo7>Auvi3&gbzGM;&M*K(V0Dx6Ho2K2H9vcLG4e&w%&BLPAc%mMGyw z49_o+w?@|JcA8a9$TzhF;UV>8xA3HbadPZ zk?ELp!M^xm(=g8|AUb}u(iwVz2IX%yk;R_T6q{4?MEK#A>_6HgotmfGv=@)uo2%p8 zIInEG-U$mkYA5N9FFSOd`jO^+wUKNwmMhQ3$tf;S(a=Ek0B+qzB$EfK-w`5Ad370h zYWer$iMwdnj7Vru?!9pC0+!BY zvwGf#!NZI04cY)xGd(>T!{;-_NYb!y;@rm_1h(!KLY`gQ6Gdd_wg(H}!D!wcv0bE+ z(Ulh~l?t7;#n9oUraQ~12iH6r0qc*cGj?@d+wSJqr`vg(s>DzaYfLJ5d#EttH57&6 zjxZTn=Z{0GzJ#H}NbG{c_deRv%S$+hK{|8%J#z?U<&LeRV}+uJo7v@?7MnXM&pm2? zDU+_N5h>(eexZC)#(}pYyAj`dct}VH?1VEaj(2noU1wvpJABYB0Jgfl(%&&aq26k= z7jzn}nDwf1=P>a3@%Ib}qV3x5Uk4h|)5Smwi#)c3`%h5W51i+au;O*?x>mAGqvl>=@R`uFa4S8VmVYWbzVT@#9wp5~$wJn!ah z0a3ah0XKM2BDJ|SmS^0)d^n(y+_EjjOO1aGhr=0R!DiGEi_%}&<<5gtuM-C9||9~HFJ3`oxD-1s;?#$Z)!U74GPkpkvv$BibXa?bP5t` zX|?94VV9Q5&YYFkec7?t^K90ccmd89Z>zM%Ky4@|Ij&DZf(P)Hh#P2J`GEIp33{PW ziEzH0&XK!~R#H+zi2hAiUAo^)Q-vQQ%Yk7-$hRKz*&5GP*>tO#3f*=~#hLqmzMM7R z4_p~^)~>$CM&s&Dt6u#F-Ftg`jR?chK={}b5E>fF&dq7u|C+sdTvXarPcP-is!Mip zF(_N0E{9Jm%^9oVls7-NS!^yFv26Mk3Y=(4RsO@R#bbf2dEDsZT1*EutvUuE=Jev? zRTyPg4(AZL`w$?s}|p?r7m2C2-`da7K+EOtfuG`FR!5y)yyj7azuTQVFZ*Xj`A38*-Czh z(-Cs%*Fqs%VWE>Vzkh!{_vlXIHmFBl{mnWgmHk+(U>tBZm7mP#IQQcBzUM?A$Cs0e z>E$5Cx;xjnOGWBFAB}-+HF65LYvEpIS?Mex;(5OJbhw1G4f9;q7HG8Q9|l)lY7>%^ zh0o5;L@DG$a@oKXN6}gAExG>c1ZP12vwrj9(o+~TR#T|cl(^HBH|3ty2^v;b@lkck z62#tM-W_>m!UPLW;I9}(9R(q}*fVpM_^5F^YK0Wuk8i?qTS(}QXA{ca5h3Rels6#7#GFHM6?v0k4t=SlcQFHaXhtUNzRVddaM8;H8UPJ}@A5-*@>N7@#o%0s@Qy750skC-?;G-SMAZ zF?fh*Ls6jLkGk-LT|Kh&Jr9>EfY0E1G`?pgEG*0k{Mj5zV|kVO%;P`ui->^010NrM z5;OEAG}ZIjQ}eQPaQy$6Fx*I&jk zC*_Isv0GBvrxL_+*sH_tZX3FpL3dYrQMnQnqTy!wYf~-MvYfvCfP0j3<771h1D{^_;xhgX`?d6C=aIP={+wVP}heq?Faq@2bHYthn&Pvo} zCsAOP_CzfxysmwnzPh2r&WkmWPK=(i+vjzgFy%jJIT=<3GfiEtBoZu>Yayov5i^^m z-Mu|SyzFW7Z<>AZB#`GTaL7`kihjzBIRnEn`QqKf{*_#Qdq7KG4)T8=2?Q-SfU3a{`o{v8p%_*4u?xex-5$gt7=AV{z@jpFbXQr z4t{ZzJ#h^aJRp?_E*7Y}o~!vwi~VKRYQLboJBp&v*i6LG%HyND*{2_9*-jifCJR60 zdsg_LG(P@uw264@9altEvBwgNG`KTi`IiBO{~mBSmSMj%sgW8U@wZ zpM;6-)s0M#i?kyJe86MX%4(Qb;u(w*5a}M|FT;J|Sl%_r%xvybK(3E;Di4u~kE}C~ zU+}U}Rv7%<+(5G#xLwQN^6PC`2Q4#JBAD>h|KPV6yQ0Mf2- z<$5u3<0=x0`p2OrV!>_w4RM#%foy?Jx%bgp?PKwl`(jSxI<0pa{C1v)qr|@Mk|``m zK-0R`#C9Ze%z^?t`=<3`r7YS6)_T43=C?gya`I>^{@)K=PHjVn&7+|6?IH$T^iU6` zZWkr?y!RR%rEFDm4r(YO34l^X=oTJ@1*2t%6E!eug(8-D{mVw^pVezfN&nB)qxT~^ zm625XXmU(%4eDvwGNq4WIxRYKn&TpjR^$BId_U>_JKUxtSC{6fMMaS~`4XG$d3`#@ z(2It`CE>!DvLV(zxD;m%H6r7wJvyJ?q6zGdH4)?FNRs=JH*DKj>c@DXYc`T;|4Sm+ zl8v}{X6;l_DKZ-&M})5CG*#tv#dkARyS&zbmL)&PFalq$LXjzuS5F0a8zb26Kj6uJ z@1r{2QCu?k!c-;`pbw0~zcr?c#6KVpVivZTN_X&Q7NyO5Ckrk?_0! zRX>M=3o#XgSORp`;4Mv=OFORu6s6PIU5%_y9yox9`*8AFG=+qK@yv4UjtsdBxl5{`0hPV``u#V9Y#H+$%KWC##*VIeo$m>ng9`euLEE34>vEFUoUyHs7u2nCie}PGtdwC^(o>N-ZaeeLIxNsp6|Jdp-+r^p zApI`}L8IWgBwBDx%2(Sj4t2Tn{)U8NxqKbSA<^*@7eMBBOV*}UL%@%2y(~?TKe1dL(b0if1*%1kpxH^`fAYI&0^eR8Km4BRO z9%A&Z;~B-*)Kc3REoQXE#rDTu&$L<}$@;(1t>7s*^JX3>Qu}A=bM+ipCcMx59krW# zvbSG^Ts>e=Glk-wj*g}v1E*3Kwl9--Bp=~zCiMCUOwUhjPi*fZW?iRwJnPsrTyf>( z^1JkI!=;}#1dnT&PM0_Oz;|}&w_~)bYHM5b{W=^8Fml*}Q6sY_&AzG!;EYL;a5kfh zF~RUC2VJ45!^zSlEZ7xkC<&;IAkDp;TzovB*vpc1dkNKxtmroPkg21Tt4juyj+>K7 z;gq9HNw*^VHQ(@}_YH({x)8c6#M3Te@#;{N{v-d7gGuyf$w}_IIb9r@zhS7&YGyb( z#%-g&(+tG@al9-%zWQ$Z0&q&-Jf!Xn#`;~$ZL;X1GsEt#cz~VyNJ+c^vo!p%Zy1jb za}+FTe*f!K zv)g0jSt4pNSyV7HAWw@;O`HFkvsR41q@Ed*Qz5!@q{d z9Jst*&rKVCRHBBfR$7++oeA7%zl?jrO!i?AZ)K2gqAeYImrhT}1FB=|CMC%?yc;EY zh_I{zo6??-Jo?G1LRIu|+Lz*S)co?1{JAJxA?bY*jv-{qJf0MPp zeBI^y4%2?NII^=G8J*k3!BvGr;aOaTM_xSA&+0?e&V4iQ?X@zh%H1pRO2jzL1#g7@EwoF>BVMw$|aKO>l)5}+5v$SCr;sC+=<1B6S< z8Z7P0%SYPOw3cT6ej~(87sH2Ygg+yI@)8Hbq`Zc8)3EHnIm`yOokp-t9CaOqkevW@ zST4)n;pH}?Nk8^IXEv34DO@|3>-SC03hJZQ%$z%~k`xp-+Q{$zN6UMFmf_1BrQE~C3=lB)D}S@P$)fQ^at)NV?HTOXh{ z?fcKT2)3r<)U8qG|NY=l`yeM1uV-K|j|K?!s05u13FojyotWI8nJ6QN=SP-Gqvoe~ zjTyLvx_yv;WBwsMz{1%8>-)tfBj8TR^O`JHVti_5-r%A=I6cU{Mt0--BY&|$b37#<*u%j`Cq`VVBx6Ez-B>b(tp@B5`Z;^~v=GhEb;{E$* z`BK5>`P}%2sJ{pI=_bQdu!v51AE%`c7+(eb>fL%vwdj3*OM+$EHp99C3<`!B?A%|v zBIpT@fLe3SP;G=FIIOJgb! z_pIL9-i|9$nKB!q&BV!!pf;R+HlMUe6e)(Sezgjj#RwrBt8$)zo!X8xA(_;$via@a zQ#}>yiP}$l=2WEs7J}GrZxc~-jr{(6xo*L$+^xiV-i+V4FJuahs1#!6*jtHn92`V> z@ktEfD$?=C$Yh|Az-tw7Y*+jrwOXw*j=%8nM`xCk|H>6#OleKgL)+6wG zOTJSKymX%$ki$TkoI%^)?-uA^g|T99f_8VxYI+~IayAoU z@q^kJVoCcr{pDt9DeC437A986NKoMA#cm}L*35*en}5WE`mMpIk;@Ei0e4p&dNwF0 zn*=&W@Ad(LAr##kh9yj?n>0{)39pQU0{$Fgvlsm?8zh4E23vg&k+)>d6b=1#x+QWU zEq*3NOZdLxp>pQ|76IeZw2n_D)qBqO?SXRkj=v|Y7{4jUCIc!{`unWrs}Ck)$P=W- zsw&Nuq~2v@tUKG3AvS04A|ohtwBNav!ih;pdU;gy-Eo*&EQY!R3^Cq4!t+wNAS1DQ z%#rC3P8sYR9z;e$vf=CkvQioY;ROkqN6v66u*JqjUY4_o;J<5+-bAHGAY_L?Fv2>) zPyFYgi(o!HWq2Awras}lf(~8>d2g(#of*;rvJl8S)|SAOeWmD!rwidaQm3J;RxA^S zcaHaD!Hr^`zEl3I2H#(om>{LORR5In%-1{mX=1zHQuB12pY6^pn<^OG-&e#+b7Vht z!c#!r8(#i>)Cea|3B|JcoRSrah!OT!!e52S{7}tG)DqqONu5K{*1puD8Z>aWzF;!q z5!x?7=IiPG-EmfqxcHHWEg5?=<0upDx#NIOmYB0YcEm~Hv;W|{IfB0g&#t>YHj~f; z(EZADYiDo&#=YdLv+#=-H_<7M4?YQVyuIzZz3-}n70Z0UiG6E!XIm^5cexW;GQ369!x{5L}k+db>Vju-fZWtTu`qye$%EG+{4%MvLyZ zT+n=-P@%-BVMQ{QU)m@JOtMHez*yU_p9UC)DXbTExr7x^xLGl#I&`woo+E}EP)Mfc zb=>Ou-%7y}5{@4;^;FnO`P(Zwb~e6}p;=6_8a=I#i1^F#l*|a6meAnK9ct%)vC>}Q z>v(kR|9c4hpREJ*>{jmx=T;IoA|v{1LBJ#q)==B&cv_y_`5OA2x1ckbi_c=Pi&vTV z7UFDA3}*kt$Z`PDlTq?d!IoCrfBIKD{<_<_B&GrbzJJA(PwnlVitv^+h|F*utn+4zT;Nz z&o|6a!^fV(ir*eHfwd{W+v_s}4aeOfL3=w0+vIaC!R>k&qM1ti{5K^+P}3A;okVt0 z#r;v32gaYvsaZ(rMyZ5U`(qfeb54(}VGZZ08XyN(#&p|uMuI&4FtAusq^X4vhuBuT zVB_{IwGMqAm*g1q^KJT5^3FrI#yY6Y^Y$+Ep5}W>4bfu)0s?VRo!VJS)PgTw~e zv50#ei1_cZ4r-TO)f9#Xb!O(Oy6kFK`zM5~( ze*ZFAHs^Kh#$fV~R{BlB8t!H8hMrbO4FgDdV{!1wTXjYt*{;s_R6@l2PjgV9#KC?f zBWz3Q&MoBB>QtiGZrl;a=)!e~#oR?%uWxUb7w#-3N^7C>avhe=s^h4rb#_$31cv%! z#;Z`e!W-79A-Bzssnh;zkfl?eYP}<{OaGo{U6I9YFk&N(XI`J7g%nie1$gkzsA#AX zx{ilO8@pj++6s!Feb0n%ED z8cS4!WjI9Km^vtHgr0GB#=t@UOQ=WHTB_x-&%4zUL1|me z(R3R*p@ZmOJyG@x^}4QOPq8Z<8pik!B>XvWA^faQ5QxnaMM(T(VG7FOSM>kI`2W4y z`@gm-GwsHwS2CrfFzcub*-J4q=jztPV;8`W{C}dy*|(_0X-IJuxVvseMzB3vO>~E{ zkQx7kQ}RgY$~<0pUqurv?&%w3Qe1{~&psGN>KxeIN3gwF^$-lM|2jH{v67)lMM+qc z7Dj9m1G?`8i(8@wpalU>L*u-Iq%1@93sseAX zduO3#=V;4Lz==buHhHZs9Ow{O{QlLRS2_1cNxXI~Oot-};|RAu{zEA);G)MB6@DA- z3_7HsY(yO}tWLgh;1H%Ql5gjbT2I*_$`W|Lh|it+bO|SXsyhWv3Bcrbq}VqMN???s zWgP(?>l#4E#}vX}m0X>BKE1>Kdp2zsu@P~eg2BkH_8}L6V1w@Vc@HE+r+6L@0s z2px&>{gQ74njB=7yw&H(^763Wor<#6M@{J}HQ{)5E5NwC@mb2Co%L!%yO`&*Dr$X5 zLiZ@D)PlqB&%<5j7q;?_LT`7F2KWfnd|OP=?nr^7lCsUU@)S=(T#^lr+RuvKEMmk@ z5|7MXD6(xbeIK#L5TOE;&)K_+5UD?2GUXb=we?p8m&QVW!l^>bfDHd1u|;BVVT!vQ zDx<2o%NL~T+O=jkd05LY0~%>5xRvxfU;&!Knr?ewfHGq4_^sEpix$iOTtxo=t_KJ@ znb_!*c>;>`WScCCys-S5m(JQvE=&ZamqzYL#w>pfrjmd5&H(_)oHiw3Kd2SSQ1)Az zId#ulFJ4iGf&*wQ?^;7q>%8lonVn^~DB53arUG^z(b9T;ot=KCDk)f6k!%u31ME0| z-$xFb20}lO` z4F(0jg5{~RE@@xDj-p>urpV8Wd@a+AC>Mi`rO>yW6Yz1 z{$;<519?S7oT%t%zM#7s$g0-t=xCMbRDIy_n%0v!u@G%tG&eJxAzAsOWALWWAa{eq zrU1y5rk)<${8k<%Kx-GhqQkOqFp0_-U0x=toQY24)G=S}3e#=#_u1oe0@8+{oR&e4 zDj#q6yrR0~TMS}(-n7MBGsm1d{vem5&+Wae7WvK8uQ#I9w!Z&*ss2qHIB(=v=)_2U zBBE;Bq`t?X)N+N#&UFb;<5(V8CRT&I80#kQCzhT5b@i zs)t;ulb$S~xYbMispe)59DkbnF+ZUINctp@ri%SddZJz>UF3_Vf!pS<*%2E!IN<+x zK`iv2HgD#JdcfdCjOYvL`@+a6~HI7O$6qMZtS!v zkgpze=2yS!jQPD>d)4ed0$RPE%*2XP7C>7#j{>NGU(|I412JD?KYpnNU*V8rj~>-+ zYUoSIJ4`Tuo9c>M8;0f5WMPntqcYqOwmn&1>j0}Q(Z>_NqJz*RFQt5&+tBW}jp&G( zQ{RKr+R<_`Zo}(+e4k@^;G4eTOIz@F3HQxUenNb32sY{MJK?dQ8gI+Sth zV7DTArL&Y$3UXI9eYHF`oO#Y_eP-Vs15&{uK(HeFoOwNH_xP% z^V7|5I{Ut9h97Eqvt(F~B?i>r_#xonPTT z!TFQzbFQCQbPpC%@@MQ712?!U3avv>0Xl^+ZuM=a*>~KQ@o~lJa~MILTykMKKbd6$ z1^Pr`Yz!pM;#Yh=Ix$|f2{PKcOqi< zF)$3W3O#b|a*3E9p|LsgmV^iE98X5$fQ$Zpc6)>zSethn{cLd^G7%>9u(%qW|(-4kAB^TW<(eilaDdXnw z#|8K5AdBYnIs4en>Q;DrpE@E31YFp`*R7Ruw@Wjk#1CfA%sgPTpsAaEY7p4}lJUW? zA5yRZ+=KQ1lZC0HJosL3fZ_k^Et^sXT^VDy??4CozYnsNc9gT{*W`;f^`+py1^|lk LDiDOM>4*OZ)LO`b literal 9853 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 diff --git a/web/images/in_progress.gif b/web/images/in_progress.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6819abfb34a3db6ebce765603d607b14e33651e GIT binary patch literal 404 zcmZ?wbhEHb)Mnsj_{hLuWnl3C|Nog&rT|IBe^Smxsfi`2DGKG8B^e5dS&0=n`H3ld znR#jX42nNl7`PZ17!?0=`?-b$J39ur8tEA@GXjNlfS3VfAOn+8OCQJSX*X{)e?H13 zeJ||u>DC8kZ4r?R)6{G4&Dyt|CtcU`diyE8Uq?3owA-;j!N^AxXd>8TMr31bj{uEP z;7?56IIHFOnwrlu67PNQNtrQY{;7pt&RzvNJJ_?&Ze06Pg>MsMs)$s6#HZT6Q+}5p z&C*E81%TGdiiN4(8Lw%U?wsno9F=b>WnG7*rn?>{@R)9v%+M)yIi1FiTcrX vD}VECG@HG3ZvWp+k0+)$$G&~0?NxTdRajt8g3>tw(O*m=3=Gzwa03GX(6yK< literal 0 HcmV?d00001 diff --git a/web/js/app.js b/web/js/app.js index f75ee780..1a3f1819 100644 --- a/web/js/app.js +++ b/web/js/app.js @@ -800,6 +800,38 @@ App.Ajax.request = function(method, data, callback, onError){ }*/ //App.Helpers.setAjaxBusy(method, data); data = data || {}; + + var prgs = $('.progress-container'); + + switch (method) { + case 'cd': + prgs.find('title').text('Opening dir'); + prgs.show(); + break; + case 'delete_files': + prgs.find('title').text('Deleting'); + prgs.show(); + break; + case 'unpack_item': + prgs.find('title').text('Unpacking'); + prgs.show(); + break; + case 'create_file': + prgs.find('title').text('Creating file'); + prgs.show(); + break; + case 'create_dir': + prgs.find('title').text('Creating directory'); + prgs.show(); + break; + case 'rename_file': + prgs.find('title').text('Renaming file'); + prgs.show(); + break; + default: + + break; + } jQuery.ajax({ url: GLOBAL.ajax_url, @@ -816,6 +848,7 @@ App.Ajax.request = function(method, data, callback, onError){ cache: false, error: function(jqXHR, textStatus, errorThrown) { + prgs.hide(); onError && onError(); if ('undefined' != typeof onError) { fb.error(textStatus); @@ -824,9 +857,11 @@ App.Ajax.request = function(method, data, callback, onError){ complete: function() { //App.Helpers.setAjaxFree(method, data); + prgs.hide(); }, success: function(reply) { + prgs.hide(); //App.Helpers.setAjaxFree(method, data); try { callback && callback(reply); diff --git a/web/js/file_manager.js b/web/js/file_manager.js index c355a7d0..361f111d 100644 --- a/web/js/file_manager.js +++ b/web/js/file_manager.js @@ -1,9 +1,13 @@ var FM = {}; +FM.Env = {}; + GLOBAL.ajax_url = '/file_manager/fm_api.php'; FM.DIR_MARKER = '  /'; +FM.errorMessageTimeout = 3500; + FM.CURRENT_TAB = ''; FM.CURRENT_A_LINE = -1; FM.CURRENT_B_LINE = -1; @@ -32,13 +36,45 @@ FM.IMAGES = {'A':[], 'B': []}; FM.IMG_FILETYPES = 'png, jpg, jpeg, gif'; +FM.SUPPORTED_ARCHIEVES = [ + 'zip', 'tgz', 'tar.gz', + 'gzip', 'tbz', 'tar.bz', + 'gz', 'zip', 'tar', 'rar' +]; + +FM.EDITABLE_FILETYPES = [ + 'txt', 'php', 'js', 'html' +]; + +FM.preselectedItems = {'A': [], 'B': []}; + FM.directoryNotAvailable = function(reply) { alert('Directory not available'); // todo: translate } FM.showError = function(type, message) { - alert(message); + if (FM.isPopupOpened()) { + var ref = FM.getPopupReference(); + if (ref.find('.warning-message').length > 0) { + ref.find('.warning-message').html('

' + message + '

'); + ref.find('.warning-message').show(); + + clearInterval(FM.Env.errorMessageHideTimeout); + FM.Env.errorMessageHideTimeout = + setTimeout(function() { + ref.find('.warning-message').fadeOut(); + }, FM.errorMessageTimeout); + return; + } + } + else { + FM.popupClose(); + var tpl = Tpl.get('popup_alert', 'FM'); + tpl.set(':TEXT', message); + + FM.popupOpen(tpl.finalize()); + } } FM.formatPath = function(dir) { @@ -95,8 +131,8 @@ FM.setActive = function(index, box) { //console.log(pos); var wwh = w_height - w_offset + pos.top; //console.info(wwh); - console.info((pos.top + w_offset) + ' > ' + w_height); - console.log((pos.top + w_offset) > w_height); + //console.info((pos.top + w_offset) + ' > ' + w_height); + //console.log((pos.top + w_offset) > w_height); /* if (pos.top > w_height) { var cur_elm = $(box).find('li.selected').position(); var cur_elm_height = $(box).find('li.selected').height(); @@ -114,6 +150,10 @@ FM.setActive = function(index, box) { FM['CURRENT_' + tab + '_LINE'] = index; FM.CURRENT_TAB = box; + + $(FM.preselectedItems[tab]).each(function(i, index) { + $(box).find('.dir:eq(' + index + ')').addClass('selected'); + }); } FM.setSecondInactive = function(index, box) { @@ -156,7 +196,8 @@ FM.open = function(dir, box, callback) { 'dir': dir }; App.Ajax.request('cd', params, function(reply) { - if (reply.result) { + FM.preselectedItems[tab] = []; + if (reply.result == true) { var html = FM.generate_listing(reply.listing, box); } else { @@ -167,10 +208,31 @@ FM.open = function(dir, box, callback) { var current_pwd = dir.trim() == '' ? FM.ROOT_DIR : dir; - $('.pwd-tab-' + tab).html(current_pwd); + FM.updateTopLevelPathBar(box, tab, current_pwd); + + + var path_a = FM['TAB_A_CURRENT_PATH'] == '' ? FM.ROOT_DIR : FM['TAB_A_CURRENT_PATH']; + var path_b = FM['TAB_B_CURRENT_PATH'] == '' ? FM.ROOT_DIR : FM['TAB_B_CURRENT_PATH']; + var url = '/list/directory/?dir_a='+path_a+'&dir_b='+path_b; + history.pushState({}, null, url); + + }); +} + +FM.updateTopLevelPathBar = function(box, tab, path) { + console.log(path); + var formattedPath = []; + path = path.replace(FM.ROOT_DIR, ''); + formattedPath.push('
'+FM.ROOT_DIR+''); + + $.each(path.split('/'), function(i, part) { + if (part.trim() == '') { + return; + } + formattedPath.push(''+part+''); }); - + $('.pwd-tab-' + tab).html(formattedPath.join('/')); } FM.isItemFile = function(item) { @@ -302,28 +364,58 @@ FM.sortItems = function(items, box) { return sorted; } +FM.isFileEditable = function(src) { + if ('undefined' == typeof src.filetype) { + return false; + } + + if ($.inArray(src.filetype, FM.EDITABLE_FILETYPES) != -1) { + return true; + } + + return false; +} + +FM.editFileFromSubcontext = function(elm) { + var elm = $(elm).hasClass('dir') ? $(elm) : $(elm).closest('.dir'); + var src = $.parseJSON($(elm).find('.source').val()); + + var myWindow = window.open('/edit/file/?path=' + src.full_path, '_blank');//, src.full_path, "width=900, height=700"); +} + +FM.downloadFileFromSubcontext = function(elm) { + var elm = $(elm).hasClass('dir') ? $(elm) : $(elm).closest('.dir'); + var src = $.parseJSON($(elm).find('.source').val()); + + var path = src.full_path; + var win = window.open('/download/file/?path=' + path, '_blank'); + win.focus(); +} + FM.openFile = function(dir, box, elm) { var tab = FM.getTabLetter(box); FM['TAB_'+tab+'_CURRENT_PATH'] = dir; + + var elm = $(elm).hasClass('dir') ? $(elm) : $(elm).closest('.dir'); var src = $.parseJSON($(elm).find('.source').val()); + console.log(elm); + if (FM.isItemPseudo(src)) { + FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], FM['TAB_' + tab]); + } + + if (FM.isFileEditable(src)) { + var myWindow = window.open('/edit/file/?path=' + src.full_path, '_blank');//, src.full_path, "width=900, height=700"); + } + else { + var path = src.full_path; + var win = window.open('/download/file/?path=' + path, '_blank'); + win.focus(); + } + - var myWindow = window.open('/edit/file/?path=' + src.full_path, '_blank');//, src.full_path, "width=900, height=700"); - /*var params = { - 'dir': dir - }; - App.Ajax.request('open_file', params, function(reply) { - if (reply.result) { - - //var html = FM.generate_listing(reply.listing, box); - } - else { - //FM.directoryNotAvailable(reply); - alert('Cannot open file'); - } - });*/ } FM.getTabLetter = function(box) { @@ -335,6 +427,10 @@ FM.getTabLetter = function(box) { return tab; } +FM.toggleSubContextMenu = function(ref) { + $(ref).find('.subcontext-menu').toggleClass('subcontext-menu-hidden'); +} + FM.generate_listing = function(reply, box) { var tab = FM.getTabLetter(box); FM.IMAGES[tab] = []; @@ -361,9 +457,12 @@ FM.generate_listing = function(reply, box) { } reply = FM.sortItems(reply, box); + $(reply).each(function(i, o) { var path = FM.formatPath(FM['TAB_'+tab+'_CURRENT_PATH']+'/'+o.name); var cl_act = o.type == 'd' ? 'onClick="FM.open(\'' + path + '\', \'' + box + '\')"' : 'onClick="FM.openFile(\''+path+'\', \'' + box + '\', this)"'; + //var cl_act = o.type == 'd' ? 'onDblClick="FM.open(\'' + path + '\', \'' + box + '\')"' : 'onDblClick="FM.openFile(\''+path+'\', \'' + box + '\', this)"'; + //var cl_act = ''; if (o.name == '') { path = FM.formatPath(back_path); @@ -382,14 +481,17 @@ FM.generate_listing = function(reply, box) { var time = o.time.split('.'); time = time[0]; + var psDate = new Date(o.date); + o.full_path = path; - o.filetype = FM.getFileType(o.name); - if(FM.IMG_FILETYPES.indexOf(o.filetype) >= 0 && o.filetype.length > 0) { - FM.IMAGES[tab][FM.IMAGES[tab].length] = {'img': "/view/file/?path=/home/admin/"+o.name+"&raw=true", 'thumb': "/view/file/?path=/home/admin/"+o.name+"&raw=true", 'id': 'img-'+i}; - cl_act = 'onClick="FM.fotoramaOpen(\'' + tab + '\', \'img-' + i +'\')"'; - } - + o.filetype = FM.getFileType(o.name); + if(FM.IMG_FILETYPES.indexOf(o.filetype) >= 0 && o.filetype.length > 0) { + FM.IMAGES[tab][FM.IMAGES[tab].length] = {'img': "/view/file/?path=/home/admin/"+o.name+"&raw=true", 'thumb': "/view/file/?path=/home/admin/"+o.name+"&raw=true", 'id': 'img-'+i}; + cl_act = 'onClick="FM.fotoramaOpen(\'' + tab + '\', \'img-' + i +'\')"'; + } + + var t_index = tab + '_' + i; var tpl = Tpl.get('entry_line', 'FM'); tpl.set(':CL_ACTION_1', cl_act); @@ -397,9 +499,21 @@ FM.generate_listing = function(reply, box) { tpl.set(':NAME', o.name); tpl.set(':PERMISSIONS', o.permissions); tpl.set(':OWNER', o.owner); - tpl.set(':SIZE', o.size); - tpl.set(':TIME', time); - tpl.set(':DATE', o.date); + tpl.set(':SIZE_VALUE', o.type == 'f' ? FM.humanFileSizeValue(o.size) : ' '); + tpl.set(':SIZE_UNIT', o.type == 'f' ? FM.humanFileSizeUnit(o.size) : ' '); + tpl.set(':TIME', (psDate.getFullYear() != new Date().getFullYear()) ? psDate.getFullYear() || "" : time); + tpl.set(':DATE', o.date.trim() != '' ? psDate.format('mmm d') : ' '/*o.date*/); + + + if (o.name == '..' || o.type == 'd') { + tpl.set(':SUBMENU_CLASS', 'hidden'); + } + else { + tpl.set(':SUBMENU_CLASS', ''); + } + /*tpl.set(':index', t_index); + tpl.set(':index1', t_index); + tpl.set(':index2', t_index);*/ if (FM.isItemDir(o)) { tpl.set(':ITEM_TYPE', 'filetype-dir'); @@ -416,17 +530,25 @@ FM.generate_listing = function(reply, box) { FM['CURRENT_'+tab+'_LINE'] = -1; } +FM.toggleCheck = function(uid) { + var ref = $('#check' + uid); + if (ref.length > 0) { + //ref.attr('checked', true); + $(ref).hasClass('checkbox-selected') ? $(ref).addClass('checkbox-selected') : $(ref).removeClass('checkbox-selected'); + } +} + FM.fotoramaOpen = function(tab, img_index) { console.log('index: ' + img_index); $('.fotorama').fotorama({ - nav: 'thumbs', - arrows: true, - click: true, - allowfullscreen: true, - fit: 'scaledown', - thumbfit: 'scaledown', - data: FM.IMAGES[tab] + nav: 'thumbs', + arrows: true, + click: true, + allowfullscreen: true, + fit: 'scaledown', + thumbfit: 'scaledown', + data: FM.IMAGES[tab] }); $('.fotorama').on('fotorama:fullscreenexit', function (e, fotorama) { @@ -437,21 +559,300 @@ FM.fotoramaOpen = function(tab, img_index) { $('.fotorama').fotorama().data('fotorama').show(img_index); } -FM.selectItem = function(item, box) { +FM.bulkOperation = function(ref) { + //console.log(ref); + var box = $(ref).parents('.menu').hasClass('menu-left') ? FM.setTabActive(FM.TAB_A, 'skip_highlights') : FM.setTabActive(FM.TAB_B, 'skip_highlights'); - if (FM.CURRENT_TAB == FM.TAB_A) { - FM.setTabActive(FM.TAB_B); - $(FM.TAB_B).find('.selected-inactive').removeClass('selected-inactive'); - $(FM.TAB_A).find('.selected').addClass('selected-inactive'); + var operation = $(ref).val(); + if ('function' == typeof FM[operation]) { + FM[operation] && FM[operation](ref); + } + + $(ref).find('option[value=-1]').attr('selected', true); +} + +FM.checkBulkStatus = function(bulkStatuses, acc) { + var status = false; + var msg = ''; + if (bulkStatuses.length == acc.length) { + $.each(bulkStatuses, function(i, o) { + if (o != true) { + msg += '

'+o+'

'; + } + }); + + if (msg == '') { + status = true; + } + } + + if (status == true) { + $('#popup .results').html(msg); + $('.controls p').replaceWith('

close

'); } else { - FM.setTabActive(FM.TAB_A); + $('#popup .results').html(msg); + $('.controls p').replaceWith('

close

'); + } +} + +FM.bulkPopupClose = function() { + FM.popupClose(); + FM.open(FM['TAB_A_CURRENT_PATH'], FM['TAB_A']); + FM.open(FM['TAB_B_CURRENT_PATH'], FM['TAB_B']); +} + +FM.humanFileSize = function(size) { + var sizes = [' Bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB']; + for (var i = 1; i < sizes.length; i++) { + if (size < Math.pow(1024, i)) return (Math.round((size/Math.pow(1024, i-1))*100)/100) + sizes[i-1]; + } + return size; +} + +FM.humanFileSizeValue = function(size) { + var sizes = ['b', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + for (var i = 1; i < sizes.length; i++) { + if (size < Math.pow(1024, i)) return (Math.round((size/Math.pow(1024, i-1))*100)/100); + } + return size; +} + +FM.humanFileSizeUnit = function(size) { + if (!parseInt(size)) return " "; + + var sizes = ['b', ' kb', ' Mb', ' Gb', ' Tb', ' Pb', ' Eb', ' Zb', ' Yb']; + for (var i = 1; i < sizes.length; i++) { + if (size < Math.pow(1024, i)) return sizes[i-1]; + } + return sizes[i]; +} + + +FM.bulkCopy = function() { + var acc = $(FM.CURRENT_TAB).find('.dir.selected'); + if (acc.length > 0) { + //FM.popupClose(); + + var cfr_html = ''; + + $.each(acc, function(i, o) { + var ref = $(o).parents('.dir'); + var src = $(ref).find('.source').val(); + src = $.parseJSON(src); + + if (!FM.isItemPseudo(o)) { + cfr_html += '
'+src.name+'
'; + } + }); + + var tpl = Tpl.get('popup_bulk', 'FM'); + tpl.set(':ACTION', 'YOU ARE COPYING'); + tpl.set(':TEXT', cfr_html); + + FM.popupOpen(tpl.finalize()); + + var bulkStatuses = []; + $.each(acc, function(i, o) { + var ref = $(o).parents('.dir'); + var src = $(ref).find('.source').val(); + src = $.parseJSON(src); + + /*if (!FM.isItemPseudo(o)) { + cfr_html += '
'+src.name+'
'; + }*/ + var tab = FM.getTabLetter(FM.CURRENT_TAB); + + var opposite_tab = 'A'; + if (tab == 'A') { + opposite_tab = 'B'; + } + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var dest = FM['TAB_' + opposite_tab + '_CURRENT_PATH' ]; + if (dest == '') { + dest = GLOBAL.ROOT_DIR; + } + + var action = FM.isItemFile(src) ? 'copy_file' : 'copy_directory'; + + var params = { + item: src.full_path, + filename: src.name, + dir: FM['TAB_' + tab + '_CURRENT_PATH'], + dir_target: dest + }; + + App.Ajax.request(action, params, function(reply) { + if (reply.result == true) { + bulkStatuses.push(true); + } + else { + //FM.showError('copy-items', reply.message); + bulkStatuses.push(reply.message); + } + + FM.checkBulkStatus(bulkStatuses, acc); + }); + }); + + } +} + +FM.bulkRemove = function() { + var acc = $(FM.CURRENT_TAB).find('.dir.selected'); + if (acc.length > 0) { + //FM.popupClose(); + + var cfr_html = ''; + + $.each(acc, function(i, o) { + var ref = $(o).parents('.dir'); + var src = $(ref).find('.source').val(); + src = $.parseJSON(src); + + if (!FM.isItemPseudo(o)) { + cfr_html += '
'+src.name+'
'; + } + }); + + var tpl = Tpl.get('popup_bulk', 'FM'); + tpl.set(':ACTION', 'YOU ARE REMOVING'); + tpl.set(':TEXT', cfr_html); + + FM.popupOpen(tpl.finalize()); + + var bulkStatuses = []; + $.each(acc, function(i, o) { + var ref = $(o).parents('.dir'); + var src = $(ref).find('.source').val(); + src = $.parseJSON(src); + + /*if (!FM.isItemPseudo(o)) { + cfr_html += '
'+src.name+'
'; + }*/ + var tab = FM.getTabLetter(FM.CURRENT_TAB); + + var opposite_tab = 'A'; + if (tab == 'A') { + opposite_tab = 'B'; + } + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var dest = FM['TAB_' + opposite_tab + '_CURRENT_PATH' ]; + if (dest == '') { + dest = GLOBAL.ROOT_DIR; + } + + var params = { + item: src.full_path, + dir: FM['TAB_' + tab + '_CURRENT_PATH'] + }; + + App.Ajax.request('delete_files', params, function(reply) { + if (reply.result == true) { + bulkStatuses.push(true); + } + else { + //FM.showError('copy-items', reply.message); + bulkStatuses.push(reply.message); + } + + FM.checkBulkStatus(bulkStatuses, acc); + }); + }); + + } +} + +FM.toggleAllItemsSelected = function() { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + var dir_items = $(FM['TAB_' + tab] ).find('.dir'); + if (selected.length == dir_items.length) { + $(box).find('.dir').removeClass('selected'); + var index = FM['CURRENT_' + tab + '_LINE']; + $(box).find('.dir:eq(' + index + ')').addClass('selected'); + } + else { + $(box).find('.dir').addClass('selected'); + } +} + +FM.selectCurrentElementAndGoToNext = function () { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + + var index = FM['CURRENT_' + tab + '_LINE']; + + if ($.inArray(index, FM.preselectedItems[tab]) != -1) { + FM.preselectedItems[tab] = $.grep(FM.preselectedItems[tab], function(i) { + return i != index; + }); + + $(box).find('.dir:eq(' + index + ')').removeClass('selected'); + //FM.preselectedItems[tab].push(index); + } + else { + $(box).find('.dir:eq(' + index + ')').addClass('selected'); + FM.preselectedItems[tab].push(index); + } + + FM.goDown(); +} + +FM.selectItem = function(item, box) { + //console.log(item); + /*if ($(item).hasClass('ch-toggle')) { + if ($(item).parents('.dir').prev('.dir').length == 0) { + var checked = $(item).parents('.dir').find('.ch-toggle').is(':checked'); + $(item).parents('.listing').find('.ch-toggle').prop('checked', checked); + } + + return; + }*/ + + + + if (FM.CURRENT_TAB == FM.TAB_A) { + FM.setTabActive(FM.TAB_B, 'skip_highlights'); + $(FM.TAB_B).find('.selected-inactive').removeClass('selected-inactive'); + // tmp + //$(FM.TAB_A).find('.selected-inactive').removeClass('selected-inactive'); + $(FM.TAB_B).find('.selected').removeClass('selected'); + + //$(FM.TAB_A).find('.selected').addClass('selected-inactive'); + $(FM.TAB_B).find('.selected').addClass('selected-inactive').removeClass('selected'); + } + else { + FM.setTabActive(FM.TAB_A, 'skip_highlights'); $(FM.TAB_A).find('.selected-inactive').removeClass('selected-inactive'); - $(FM.TAB_B).find('.selected').addClass('selected-inactive'); + //$(FM.TAB_B).find('.selected-inactive').removeClass('selected-inactive'); + //$(FM.TAB_B).find('.selected').addClass('selected-inactive'); + $(FM.TAB_A).find('.selected').removeClass('selected'); + + $(FM.TAB_A).find('.selected').addClass('selected-inactive').removeClass('selected'); } $(box).find('.active').removeClass('active'); $(box).find('.selected').removeClass('selected'); + + // + // tmp + //$(FM.TAB_A).find('.selected-inactive').removeClass('selected-inactive'); + //$(FM.TAB_B).find('.selected-inactive').removeClass('selected-inactive'); + /*if ($(item).hasClass('active')) { $(item).removeClass('active'); } @@ -465,10 +866,115 @@ FM.selectItem = function(item, box) { $(item).addClass('selected'); } + + FM.setTabActive(box); + + var item = $(item).hasClass('dir') ? item : $(item).parents('.dir'); + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var src = $(item).find('.source').val(); + src = $.parseJSON(src); + var tab = FM.getTabLetter(FM.CURRENT_TAB); + if (FM.itemIsArchieve(src)) { + $('.menu-'+tab+' .extract-btn').show(); + } + else { + $('.menu-'+tab+' .extract-btn').hide(); + } + } +FM.isItemPseudo = function(item) { + if (item.name == '.' || item.name == '..') { + return true; + } + return false; +} + +FM.itemIsArchieve = function(item) { + + if ($.inArray(item.filetype, FM.SUPPORTED_ARCHIEVES) != -1) { + return true; + } + + return false; +} + +FM.unpackItem = function() { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + if (selected.length == 0) { + return alert('No file selected'); + } + + + var src = selected.find('.source').val(); + src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_SELECTED + ); + } + + if (!FM.itemIsArchieve(src)) { + return FM.displayError( + App.Constants.FM_FILE_TYPE_NOT_SUPPORTED + ); + } + + var dst = FM['TAB_' + tab + '_CURRENT_PATH']; + if (dst == '') { + dst = GLOBAL.ROOT_DIR; + } + + var tpl = Tpl.get('popup_unpack', 'FM'); + tpl.set(':FILENAME', src.name); + tpl.set(':DST_DIRNAME', dst + '/' + src.name + '_extracted'); + FM.popupOpen(tpl.finalize()); +} + +FM.packItem = function() { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + if (selected.length == 0) { + return FM.displayError( + App.Constants.FM_NO_FILE_SELECTED + ); + } + + + var src = selected.find('.source').val(); + src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + + var dst = FM['TAB_' + tab + '_CURRENT_PATH']; + if (dst == '') { + dst = GLOBAL.ROOT_DIR; + } + + var tpl = Tpl.get('popup_pack', 'FM'); + tpl.set(':FILENAME', src.name); + tpl.set(':DST_DIRNAME', dst + '/' + src.name + '_packed.tar.gz'); + FM.popupOpen(tpl.finalize()); +} + + FM.switchTab = function() { if (FM.CURRENT_TAB == FM.TAB_A) { @@ -489,13 +995,24 @@ FM.switchTab = function() { } } -FM.setTabActive = function(box) { +FM.setTabActive = function(box, action) { FM.CURRENT_TAB = box; $('.window.active').removeClass('active'); $('.listing-left.active').removeClass('active'); $('.listing-right.active').removeClass('active'); $(FM.CURRENT_TAB).addClass('active'); $(FM.CURRENT_TAB).closest('.window').addClass('active'); + + if (action == 'skip_highlights') { + return true; + } + + if (FM.CURRENT_TAB == FM.TAB_A) { + $(FM.TAB_B).find('.selected').addClass('selected-inactive').removeClass('selected'); + } + else { + $(FM.TAB_A).find('.selected').addClass('selected-inactive').removeClass('selected'); + } } FM.confirmRename = function() { @@ -503,7 +1020,9 @@ FM.confirmRename = function() { var box = FM['TAB_' + tab]; var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (!selected) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } var src = selected.find('.source').val(); @@ -512,23 +1031,27 @@ FM.confirmRename = function() { var target_name = $('#rename-title').val(); if (target_name.trim().length == 0) { - return alert('Cannot be renamed.'); + return FM.displayError( + App.Constants.FM_FILE_NAME_CANNOT_BE_EMPTY + ); } + + var action = FM.isItemFile(src) ? 'rename_file' : 'rename_directory'; var params = { item: src.name, target_name: target_name, - dir: FM['TAB_' + tab + '_CURRENT_PATH'] + dir: FM['TAB_' + tab + '_CURRENT_PATH'] + '/' }; - App.Ajax.request('rename_file', params, function(reply) { - if (reply.result) { + App.Ajax.request(action, params, function(reply) { + if (reply.result == true) { + FM.popupClose(); FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); } else { FM.showError('rename-items', reply.message); } - FM.popupClose(); }); } @@ -536,44 +1059,189 @@ FM.renameItems = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (selected.length == 0) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } var src = selected.find('.source').val(); src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } var tpl = Tpl.get('popup_rename', 'FM'); tpl.set(':FILENAME', src.name); + tpl.set(':NEW_NAME', src.name); FM.popupOpen(tpl.finalize()); - /*var tab = FM.getTabLetter(FM.CURRENT_TAB); - var box = FM.CURRENT_TAB; - - var delete_list = $(box).find('.active'); - if (delete_list.length == 0) { - return FM.showError('hint', 'No selected items'); - } - - $(delete_list).each(function(i, o) { - var opt = $(o).find('.source').val(); - opt = $.parseJSON(opt); - prompt('Rename "' + opt.name + '" to:'); - });*/ } FM.popupOpen = function(html) { - $('
').attr('id', 'popup').html(html).flayer(); + $('
').attr('id', 'popup').html(html).flayer({ + afterStart: function(elm) { + elm.find('input[type="text"]:first').focus(); + } + }); } FM.popupClose = function() { + clearTimeout(FM.Env.errorMessageHideTimeout); return $('#popup').flayer_close(); } FM.copyItems = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + if (selected.length == 0) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + if (selected.length > 1) { // multi operation + return FM.bulkCopy(); + } + + + var src = selected.find('.source').val(); + src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var opposite_tab = 'A'; + if (tab == 'A') { + opposite_tab = 'B'; + } + + var dst = FM['TAB_' + opposite_tab + '_CURRENT_PATH']; + if (dst == '') { + dst = GLOBAL.ROOT_DIR; + } + + var tpl = Tpl.get('popup_copy', 'FM'); + tpl.set(':SRC_FILENAME', src.full_path); + tpl.set(':DST_FILENAME', dst + '/' + src.name); + FM.popupOpen(tpl.finalize()); +} + +FM.confirmUnpackItem = function () { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + if (selected.length == 0) { + return FM.displayError( + App.Constants.FM_NO_FILE_SELECTED + ); + } + + var opposite_tab = 'A'; + if (tab == 'A') { + opposite_tab = 'B'; + } + + var src = selected.find('.source').val(); + src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_SELECTED + ); + } + + if (!FM.itemIsArchieve(src)) { + return FM.displayError( + App.Constants.FM_FILE_TYPE_NOT_SUPPORTED + ); + } + + var dst = FM['TAB_' + tab + '_CURRENT_PATH']; + if (dst == '') { + dst = GLOBAL.ROOT_DIR; + } + + var params = { + item: src.full_path, + filename: src.name, + dir: FM['TAB_' + tab + '_CURRENT_PATH'], + dir_target: $('#unpack-destination').val() + }; + + App.Ajax.request('unpack_item', params, function(reply) { + if (reply.result == true) { + FM.popupClose(); + FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], FM['TAB_' + tab]); + FM.open(FM['TAB_' + opposite_tab + '_CURRENT_PATH'], FM['TAB_' + opposite_tab]); + } + else { + FM.showError('unpack_item', reply.message); + } + }); +} + +FM.confirmPackItem = function () { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var box = FM['TAB_' + tab]; + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); + if (selected.length == 0) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var opposite_tab = 'A'; + if (tab == 'A') { + opposite_tab = 'B'; + } + + var src = selected.find('.source').val(); + src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var dst = FM['TAB_' + tab + '_CURRENT_PATH']; + if (dst == '') { + dst = GLOBAL.ROOT_DIR; + } + + var params = { + item: src.full_path, + filename: src.name, + dir: FM['TAB_' + tab + '_CURRENT_PATH'], + dir_target: $('#pack-destination').val() + }; + + + App.Ajax.request('pack_item', params, function(reply) { + if (reply.result == true) { + FM.popupClose(); + FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], FM['TAB_' + tab]); + FM.open(FM['TAB_' + opposite_tab + '_CURRENT_PATH'], FM['TAB_' + opposite_tab]); + } + else { + FM.showError('unpack_item', reply.message); + } + }); +} + +FM.confirmCopyItems = function () { + var tab = FM.getTabLetter(FM.CURRENT_TAB); + var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (!selected) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } var opposite_tab = 'A'; @@ -583,24 +1251,36 @@ FM.copyItems = function() { var src = selected.find('.source').val(); src = $.parseJSON(src); - console.log(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } + + var dest = $('#copy_dest').val(); + if (dest == '') { + dest = GLOBAL.ROOT_DIR; + } + + var action = FM.isItemFile(src) ? 'copy_file' : 'copy_directory'; var params = { item: src.full_path, filename: src.name, dir: FM['TAB_' + tab + '_CURRENT_PATH'], - dir_target: FM['TAB_' + opposite_tab + '_CURRENT_PATH'] + dir_target: dest }; - App.Ajax.request('copy_files', params, function(reply) { - if (reply.result) { + App.Ajax.request(action, params, function(reply) { + if (reply.result == true) { + FM.popupClose(); FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], FM['TAB_' + tab]); FM.open(FM['TAB_' + opposite_tab + '_CURRENT_PATH'], FM['TAB_' + opposite_tab]); } else { - FM.showError('delete-items', reply.message); + FM.showError('copy-items', reply.message); } - //FM.popupClose(); }); } @@ -608,14 +1288,24 @@ FM.downloadFiles = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (!selected) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } var src = selected.find('.source').val(); src = $.parseJSON(src); - - if (src.type != 'f') { - return alert('Only files can be dosnloaded in this version'); + + if (FM.isItemPseudo(src) || FM.isItemDir(src)) { + alert('Folder downloads are in progress atm'); + } + + if (FM.isItemPseudo(src)) { + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } } var path = src.full_path; @@ -633,11 +1323,19 @@ FM.confirmDelete = function() { var box = FM['TAB_' + tab]; var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (!selected) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } var src = selected.find('.source').val(); src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } var params = { item: src.full_path, @@ -645,13 +1343,13 @@ FM.confirmDelete = function() { }; App.Ajax.request('delete_files', params, function(reply) { - if (reply.result) { + if (reply.result == true) { + FM.popupClose(); FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); } else { FM.showError('delete-items', reply.message); } - FM.popupClose(); }); } @@ -659,62 +1357,66 @@ FM.deleteItems = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); if (selected.length == 0) { - return alert('No file selected'); + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); } + if (selected.length > 1) { // multi operation + return FM.bulkRemove(); + } + + + var src = selected.find('.source').val(); src = $.parseJSON(src); + + if (FM.isItemPseudo(src)) { + return FM.displayError( + App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED + ); + } var tpl = Tpl.get('popup_delete', 'FM'); tpl.set(':FILENAME', src.name); FM.popupOpen(tpl.finalize()); - - - /*var tab = FM.getTabLetter(FM.CURRENT_TAB); - var confirmed = confirm(App.i18n.ARE_YOU_SURE); - var box = FM.CURRENT_TAB; - - var delete_list = $(box).find('.selected'); - if (delete_list.length == 0) { - return FM.showError('hint', 'No selected items'); - } - - var params = { - items: [], - dir: FM['TAB_' + tab + '_CURRENT_PATH'] - }; - $(delete_list).each(function(i, opt){ - var opt = $(o).find('.source').val(); - opt = $.parseJSON(opt); - params.items.push(opt.name); - }); - - App.Ajax.request('delete_files', params, function(reply) { - if (reply.result) { - FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); - } - else { - FM.showError('delete-items', reply.message); - } - });*/ } +FM.displayError = function(msg) { + if (FM.isPopupOpened()) { + var ref = FM.getPopupReference(); + if (ref.find('.warning-message').length > 0) { + ref.find('.warning-message').html('

' + msg + '

'); + ref.find('.warning-message').show(); + + clearInterval(FM.Env.errorMessageHideTimeout); + FM.Env.errorMessageHideTimeout = + setTimeout(function() { + ref.find('.warning-message').fadeOut(); + }, FM.errorMessageTimeout); + return; + } + } + + FM.popupClose(); + var tpl = Tpl.get('popup_alert', 'FM'); + tpl.set(':TEXT', msg); + + FM.popupOpen(tpl.finalize()); + //return alert(msg); +} + FM.confirmCreateDir = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var box = FM['TAB_' + tab]; - /*var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); - if (!selected) { - return alert('No file selected'); - } - - var src = selected.find('.source').val(); - src = $.parseJSON(src);*/ var dirname = $('#rename-title').val(); if (dirname.trim().length == 0) { - return alert('Cannot be created.'); + return FM.displayError( + App.Constants.FM_DIRECTORY_NAME_CANNOT_BE_EMPTY + ); } var params = { @@ -723,13 +1425,13 @@ FM.confirmCreateDir = function() { }; App.Ajax.request('create_dir', params, function(reply) { - if (reply.result) { + if (reply.result == true) { + FM.popupClose(); FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); } else { - FM.showError('create-file', reply.message); + FM.showError('create-dir', reply.message); } - FM.popupClose(); }); } @@ -738,44 +1440,18 @@ FM.createDir = function() { var tpl = Tpl.get('popup_create_dir', 'FM'); FM.popupOpen(tpl.finalize()); - /*var dirname = prompt('Enter dir name:'); - if (dirname.trim() != '') { - - var box = FM.CURRENT_TAB; - var tab = FM.getTabLetter(box); - var params = { - 'dirname': dirname, - 'dir': FM['TAB_' + tab + '_CURRENT_PATH'] - }; - App.Ajax.request('create_dir', params, function(reply) { - if (reply.result) { - FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); - } - else { - FM.showError('create-dir', reply.message); - } - }); - } - else { - FM.showError('dirname-empty', 'Dirname cannot be empty'); - }*/ } FM.confirmCreateFile = function() { var tab = FM.getTabLetter(FM.CURRENT_TAB); var box = FM['TAB_' + tab]; - /*var selected = $(FM['TAB_' + tab] ).find('.dir.selected'); - if (!selected) { - return alert('No file selected'); - } - - var src = selected.find('.source').val(); - src = $.parseJSON(src);*/ var filename = $('#rename-title').val(); if (filename.trim().length == 0) { - return alert('Cannot be created.'); + return FM.displayError( + App.Constants.FM_FILE_NAME_CANNOT_BE_EMPTY + ); } var params = { @@ -784,13 +1460,13 @@ FM.confirmCreateFile = function() { }; App.Ajax.request('create_file', params, function(reply) { - if (reply.result) { + if (reply.result == true) { + FM.popupClose(); FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); } else { FM.showError('create-file', reply.message); } - FM.popupClose(); }); } @@ -799,27 +1475,6 @@ FM.createFile = function() { var tpl = Tpl.get('popup_create_file', 'FM'); FM.popupOpen(tpl.finalize()); - /*var filename = prompt('Enter file name:'); - if (filename.trim() != '') { - - var box = FM.CURRENT_TAB; - var tab = FM.getTabLetter(box); - var params = { - 'filename': filename, - 'dir': FM['TAB_' + tab + '_CURRENT_PATH'] - }; - App.Ajax.request('create_file', params, function(reply) { - if (reply.result) { - FM.open(FM['TAB_' + tab + '_CURRENT_PATH'], box); - } - else { - FM.showError('create-file', reply.message); - } - }); - } - else { - FM.showError('filename-empty', 'Filename cannot be empty'); - }*/ } FM.showOrderBox = function(elm, tab) { @@ -885,12 +1540,47 @@ FM.reOrderList = function(elm){ FM.open(path, tab); } +FM.isPopupOpened = function() { + var ref = $('#popup'); + if (ref.length > 0) { + return true; + } + + return false; +} + +FM.getPopupReference = function() { + var ref = $('#popup'); + + return ref; +} + +FM.handlePopupSubmit = function() { + try { + var method = $('#popup').find('.ok').attr('onClick'); + if (method) { + method = method.replace('\(\);', '').replace('FM.', ''); + if ('function' == typeof FM[method]) { + FM[method](); + } + } + } + catch(e) { + + } +} + +FM.handlePopupCancel = function() { + FM.popupClose(); +} + FM.init(); $(document).ready(function() { + $('.progress-container').hide(); //return alert('statechange: Back'); /*$(document).bind('keydown.up', function() { @@ -915,6 +1605,17 @@ $(document).ready(function() { $('.window ul').outerHeight(hgt); + shortcut.add("Esc",function() { + if (FM.isPopupOpened()) { + return FM.handlePopupCancel(); + } + },{ + 'type': 'keydown', + 'propagate': false, + 'disable_in_input': false, + 'target': document + }); + shortcut.add("Down",function() { FM.goDown(); },{ @@ -941,8 +1642,39 @@ $(document).ready(function() { 'disable_in_input': false, 'target': document }); + + shortcut.add("Space",function() { + FM.selectCurrentElementAndGoToNext(); + },{ + 'type': 'keydown', + 'propagate': false, + 'disable_in_input': false, + 'target': document + }); + + shortcut.add("Insert",function() { + FM.selectCurrentElementAndGoToNext(); + },{ + 'type': 'keydown', + 'propagate': false, + 'disable_in_input': false, + 'target': document + }); + + + shortcut.add("ctrl+a",function() { + FM.toggleAllItemsSelected(); + },{ + 'type': 'keydown', + 'propagate': false, + 'disable_in_input': false, + 'target': document + }); shortcut.add("Enter",function() { + if (FM.isPopupOpened()) { + return FM.handlePopupSubmit(); + } var tab = FM.getTabLetter(FM.CURRENT_TAB); var elm = $(FM.CURRENT_TAB).find('.dir:eq('+FM['CURRENT_'+tab+'_LINE']+')'); @@ -964,6 +1696,8 @@ $(document).ready(function() { }); + + /* is jQuery .live() has been removed in version 1.9 onwards $(FM.TAB_A + ' .dir').live('click', function(evt) { FM.selectItem(evt.target, FM.TAB_A); @@ -973,12 +1707,19 @@ $(document).ready(function() { }); */ - $(FM.TAB_A).on('click', '.dir', function(evt) { + /*$(FM.TAB_A).on('click', '.dir', function(evt) { + //console.log(evt); + if (evt.ctrlKey || evt.metaKey || evt.altKey) { + return; + } FM.selectItem(evt.target, FM.TAB_A); }); $(FM.TAB_B).on('click', '.dir', function(evt) { + if (evt.ctrlKey || evt.metaKey || evt.altKey) { + return; + } FM.selectItem(evt.target, FM.TAB_B); - }); + });*/ $(FM.TAB_A_MENU).on('click', '.sort-by', function(evt){ FM.showOrderBox($(evt.target), FM.TAB_A); @@ -996,6 +1737,10 @@ $(document).ready(function() { $(evt.target).closest('.warning-box').hide(); }); + $('.menu-A .extract-btn').hide(); + $('.menu-B .extract-btn').hide(); + + }); diff --git a/web/js/floating_layer.js b/web/js/floating_layer.js index b0af2a90..84f6c91f 100644 --- a/web/js/floating_layer.js +++ b/web/js/floating_layer.js @@ -2,7 +2,12 @@ { jQuery.fn.flayer_close = function() { - jQuery(this).flayer.close(); + try { + jQuery(this).flayer.close(); + } + catch (e) { + fb.error(e); + } } jQuery.fn.flayer = function(params) { @@ -15,8 +20,9 @@ id : 'floating-box', className : 'floating-box-class', zIndex : 5000, - beforeStart : function(){}, - beforeEnd : function(){}, + beforeStart : function() {}, + beforeEnd : function() {}, + afterStart: function() {}, close : null, closeClass : 'close-floating-layer', outerClose : false, @@ -207,6 +213,7 @@ jQuery(ref.content).append(jQuery(elm).removeClass('hidden')); start_ovservers(); jQuery(ref.container).removeClass('hidden').css({'display':'block'}); + config.afterStart(elm); } // diff --git a/web/js/i18n.js.php b/web/js/i18n.js.php index 7fe3b619..dcf37270 100644 --- a/web/js/i18n.js.php +++ b/web/js/i18n.js.php @@ -46,3 +46,10 @@ if (!function_exists('__')) { App.i18n.ARE_YOU_SURE = ''; App.Constants.UNLIM_TRANSLATED_VALUE = ''; + +App.Constants.FM_DIRECTORY_NAME_CANNOT_BE_EMPTY = ''; +App.Constants.FM_FILE_NAME_CANNOT_BE_EMPTY = ''; +App.Constants.FM_NO_FILE_SELECTED = ''; +App.Constants.FM_NO_FILE_OR_DIRECTORY_SELECTED = ''; +App.Constants.FM_FILE_TYPE_NOT_SUPPORTED = ''; + diff --git a/web/js/templates.js b/web/js/templates.js index 21b8dbef..9cc360b1 100644 --- a/web/js/templates.js +++ b/web/js/templates.js @@ -7,31 +7,65 @@ App.Templates.html = { hint: [''] }, // file manager + // + +//\ + FM: { entry_line: ['
  • \ - \ + \ + \ \ \ ~!:NAME~!\ ~!:PERMISSIONS~!\ ~!:OWNER~!\ - ~!:SIZE~!\ + ~!:SIZE_UNIT~!\ + ~!:SIZE_VALUE~!\ ~!:DATE~!\ ~!:TIME~!\ + ••• \ +
    • Download
    • Edit
    \ +
    \
  • '], + popup_alert: [''], + popup_bulk: [''], popup_delete: [''], - popup_rename_: ['
    \ -
    Rename file "~!:FILENAME~!"
    \ - \ -
    \ + popup_copy: [''], + popup_rename: ['
    \ +
    Original name: "~!:FILENAME~!"
    \ + \ +
    \ +
    \ + \
    \
    \

    cancel

    \ @@ -43,15 +77,33 @@ App.Templates.html = {
    \
    '], - popup_rename: ['
    \ -
    Extract archive "~!:FILENAME~!" to "~!:DIRNAME~!"
    \ -
    \ + popup_pack: ['
    \ +
    Pack "~!:FILENAME~!" into:
    \
    \ - \ + \
    \ +
    \ + \
    \

    cancel

    \ -

    Extract

    \ +

    Pack

    \ +
    \ +
    '], + + popup_unpack: ['
    \ +
    Extract archive "~!:FILENAME~!" to:
    \ +
    \ + \ +
    \ +
    \ + \ +
    \ +

    cancel

    \ +

    Extract

    \
    \
    '], @@ -59,7 +111,7 @@ App.Templates.html = { popup_create_file: ['
    \
    Create file
    \ \ -
    \ +
    \
    \ \
    \ @@ -71,7 +123,7 @@ App.Templates.html = { popup_create_dir: ['
    \
    Create directory
    \ \ -
    \ +
    \
    \ \
    \ @@ -79,6 +131,12 @@ App.Templates.html = {

    cancel

    \

    create

    \
    \ +
    '], + popup_no_file_selected: ['
    \ +
    Please select a file
    \ +
    \ +

    ok

    \ +
    \
    '] } }; diff --git a/web/templates/file_manager/main.php b/web/templates/file_manager/main.php index c2cfe315..426cf4e9 100644 --- a/web/templates/file_manager/main.php +++ b/web/templates/file_manager/main.php @@ -16,19 +16,19 @@
    -
    + +
    '.$dir.''; } ?> */ ?>
    -