Эх сурвалжийг харах

Added ignore network drive folder size calculation

Toby Chui 2 жил өмнө
parent
commit
3de9e55d0a

+ 14 - 10
file_system.go

@@ -2454,17 +2454,21 @@ func system_fs_getFileProperties(w http.ResponseWriter, r *http.Request) {
 	filesize := fileStat.Size()
 	//Get file overall size if this is folder
 	if fileStat.IsDir() {
-		var size int64
-		fshAbs.Walk(rpath, func(_ string, info os.FileInfo, err error) error {
-			if err != nil {
+		if fsh.IsNetworkDrive() {
+			filesize = -1
+		} else {
+			var size int64 = 0
+			fshAbs.Walk(rpath, func(_ string, info os.FileInfo, err error) error {
+				if err != nil {
+					return err
+				}
+				if !info.IsDir() {
+					size += info.Size()
+				}
 				return err
-			}
-			if !info.IsDir() {
-				size += info.Size()
-			}
-			return err
-		})
-		filesize = size
+			})
+			filesize = size
+		}
 	}
 
 	//Get file owner

+ 445 - 432
web/SystemAO/file_system/file_properties.html

@@ -1,433 +1,446 @@
-<html>
-    <head>
-        <title locale="title/title">File Properties</title>
-        <meta charset="UTF-8">
-        <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
-        <link rel="stylesheet" href="../../script/semantic/semantic.css">
-        <script type="text/javascript" src="../../script/jquery.min.js"></script>
-        <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
-        <script type="text/javascript" src="../../script/ao_module.js"></script>
-        <script type="text/javascript" src="../../script/applocale.js"></script>
-        <style>
-            body{
-                overflow:hidden;
-            }
-
-        </style>
-    </head>
-    <body id="filePropertiesWindow">
-        <br>
-        <div class="ui container">
-            <h3 class="ui header">
-                <span locale="title/title">File Properties</span>
-                <div class="sub header" locale="title/desc">Basic File Information</div>
-            </h3>
-            <div class="ui divider"></div>
-            <div id="properties">
-
-            </div>
-            <br>
-            <button style="display:none;" class="ui small blue fluid button singleFileOnly" onclick="changeDefaultWebApp();" locale="button/changeDefault">Change Default WebApp</button>
-            <button style="display:none; margin-top: 4px;" class="ui small fluid button singleFileOnly" onclick="viewVersionHistory();" locale="button/versionHistory">View Version History</button>
-            <button style="margin-top: 4px;" class="ui small fluid button linuxonly" onclick="openFilePermissionPanel();" locale="button/changeFilePermission">Change File Permissions</button>
-            <br>
-        </div>
-        <div id="filesizeLoader" class="ui active dimmer">
-            <div class="ui indeterminate text loader" locale="loader/loadingFileSize">Calculating File Size</div>
-        </div>
-        <script>
-            //Initiate the view model
-            var files = ao_module_loadInputFiles();
-            var fileProperties = [];
-            var fileInfo = {};
-            function initFileProperties(){
-                $("#properties").html("");
-                if (files.length == 1){
-                    //There are only 1 file to be shown
-                    getFileProp(files[0], renderSingleObject);
-                }else if (files.length > 1){
-                    for (var i =0; i < files.length; i++){
-                        getFileProp(files[i], function(data){
-                            fileProperties.push(data);
-                            if (fileProperties.length == files.length){
-                                renderMultipleObjects();
-                            }
-                        });
-                    }
-                }
-            }
-
-            applocale.init("../locale/file_properties.json", function(){
-                applocale.translate();
-                initFileProperties();
-            });
-
-           
-          
-
-            //Hide windows / linux only operations
-            $.get("/system/info/getArOZInfo", function(data){
-                if (data.HostOS == "windows"){
-                    $(".linuxonly").hide();
-                }else{
-                    $(".windowsonly").hide();
-                }
-            });
-
-            function viewVersionHistory(){
-                var hashPassthrough = encodeURIComponent(JSON.stringify(files));
-                ao_module_newfw({
-                    url: "SystemAO/file_system/file_versions.html#" + hashPassthrough,
-                    width: 570,
-                    height: 480,
-                    appicon: "SystemAO/file_system/img/properties.png",
-                    title: "File Version History",
-                });
-            }
-
-            function getFileProp(vpath, callback){
-                $.ajax({
-                    url: "../../system/file_system/getProperties",
-                    data: {path: vpath},
-                    method: "POST",
-                    success: function(data){
-                        callback(data);
-                        fileInfo = data;
-                        //Initialize system theme
-                        fpw_loadPreference("file_explorer/theme",function(data){
-                            if (data.error === undefined){
-                                if (data == "darkTheme"){
-                                    fpw_toggleDarkTheme();
-                                }else{
-                                    //White theme. Do nothing
-                                }
-                            }
-                        });
-
-                    }
-                })
-            }
-
-            function openFilePermissionPanel(){
-                var hashPassthrough = encodeURIComponent(JSON.stringify(files));
-                ao_module_newfw({
-                    url: "SystemAO/file_system/file_permission.html#" + hashPassthrough,
-                    width: 340,
-                    height: 480,
-                    appicon: "SystemAO/file_system/img/properties.png",
-                    title: "File Permissions",
-                });
-            }
-
-            function renderMultipleObjects(){
-                hideLoader();
-                var filesizeSum = sumProperties(fileProperties, "Filesize");
-                $("#properties").append(ui_getInput(fileProperties[0].VirtualDirname + "/", "Root Name"));
-                var filecount = 0;
-                var foldercount = 0;
-                for (var i =0; i < fileProperties.length; i++){
-                    if (fileProperties[i].IsDirectory){
-                        foldercount++;
-                    }else{
-                        filecount++;
-                    }
-                }
-                $("#properties").append(ui_getText(applocale.getString("selection/multi", "Multiple selections")));
-                $("#properties").append(ui_getText(filecount + applocale.getString("counter/files", " Files")));
-                $("#properties").append(ui_getText(foldercount + applocale.getString("counter/folders", " Folders")));
-
-                //Append other properties as table
-                $("#properties").append(ui_getTable(
-                        [],
-                        [
-                            ["Virtual Directory", fileProperties[0].VirtualDirname + "/"],
-                            ["Storage Directory", fileProperties[0].StorageDirname + "/"],
-                            ["Total Size", bytesToSize(filesizeSum) + ` (${filesizeSum} bytes)`],
-                        ]
-                    ));
-
-                
-            }
-
-            function sumProperties(data, propName){
-                var sum = 0;
-                for (var i = 0; i < data.length; i++){
-                    sum += data[i][propName];
-                }
-                return sum;
-            }
-            
-            //Render one object property to the ui element
-            function renderSingleObject(data){
-                hideLoader();
-                if (data.error !== undefined){
-                    //Something went wrong
-                    $("#properties").append(`<h4 class="ui header">
-                        <i class="question icon"></i>
-                        <div class="content">
-                            File Properties Unknown
-                            <div class="sub header">The system were unable to read the selected file properties.</div>
-                        </div>
-                    </h4>
-                    <div class="ui divider"></div>
-                    <small>${data.error}</small>
-                    `);
-                }else{
-                    //Append Filename
-                    var filesizeText = "File Size";
-                    if (data.IsDirectory){
-                        $("#properties").append(ui_getInput(data.Basename, "Folder Name"));
-                        filesizeText = "Folder Size";
-                    }else{
-                        $("#properties").append(ui_getInput(data.Basename, "File Name"));
-                    }
-                    
-                    //Append MIME Type
-                    $("#properties").append(ui_getText(data.MimeType));
-                    
-                    //Get the default opener
-                    if (!data.IsDirectory){
-                      
-
-                        //Check if this file is shortcut
-                        if ( data.Basename.split(".").pop() == "shortcut"){
-                            //This is shortcut file
-                            $("#properties").append(ui_getTable(
-                                        [],
-                                        [
-                                            ["Virtual Path", data.VirtualPath],
-                                            ["Storage Path", data.StoragePath],
-                                            ["Permission", data.Permission],
-                                            ["Last Modified", generateDisplayLastModTime(data.LastModTime)],
-                                            ["File Type", "System Shortcut"],
-                                            ["Owner",data.Owner],
-
-                                        ]
-                                    ));
-                        }else{
-                            //Normal Files
-                            $(".singleFileOnly").show();
-                            $.ajax({
-                                url: "../../system/modules/getDefault",
-                                method: "GET",
-                                data: {
-                                    opr: "launch",
-                                    ext: "." + data.Basename.split(".").pop(),
-                                    mode: "launch"
-                                },
-                                success: function(openerinfo) {
-                                    //Check if the module is set.
-                                    var defaultWebAppField = ["Default WebApp",`<img class="ui mini spaced image" style="margin-left: 0px; padding-right: 8px;" src="../../${openerinfo.IconPath}">` + openerinfo.Name];
-                                    if ( openerinfo.Name == undefined){
-                                        //Not set. 
-                                        defaultWebAppField = ["Default WebApp", `<a href="#" onclick="changeDefaultWebApp();">Set Default WebApp</a>`];
-                                    }
-                                    //Append other properties as table
-                                    $("#properties").append(ui_getTable(
-                                        [],
-                                        [
-                                            defaultWebAppField,
-                                            ["Virtual Path", data.VirtualPath],
-                                            ["Storage Path", data.StoragePath],
-                                            [filesizeText, bytesToSize(data.Filesize) + ` (${data.Filesize} bytes)`],
-                                            ["Permission", data.Permission],
-                                            ["Last Modified", generateDisplayLastModTime(data.LastModTime)],
-                                            ["File Type", "File"],
-                                            ["Owner",data.Owner],
-
-                                        ]
-                                    ));
-                                }
-                            });
-                        }
-                        
-                    }else{
-                        $("#properties").append(ui_getTable(
-                            [],
-                            [
-                                ["Virtual Path", data.VirtualPath],
-                                ["Storage Path", data.StoragePath],
-                                [filesizeText, bytesToSize(data.Filesize) + ` (${data.Filesize} bytes)`],
-                                ["Permission", data.Permission],
-                                ["Last Modified", generateDisplayLastModTime(data.LastModTime)],
-                                ["File Type", "Folder"],
-                                ["Owner",data.Owner],
-
-                            ]
-                        ));
-                    }
-                   
-
-                }
-                
-            }
-
-            function hideLoader(){
-                $("#filesizeLoader").hide();
-                $("body").css('overflow-y',"auto");
-            }
-
-            //Model rendering scripts
-            function ui_getInput(value, placeholder="", type="text"){
-                return `<div class="ui fluid small input">
-                            <input type="${type}" placeholder="${placeholder}" value="${value}" readonly="true">
-                        </div>`
-            }
-
-            function ui_getText(value, color="black"){
-                return `<p style="color:${color}; margin-bottom:0px;">${value}</p>`;
-            }
-
-            function ui_getDivider(){
-                return `<div class="ui divider"></div>`;
-            }
-
-            //head is a 1D array and table is 2D array
-            function ui_getTable(heads, table){
-                html =  `<table class="ui very basic fluid table">`;
-                if (heads.length > 0){
-                    html += `<thead><tr>`;
-                    for (var i =0; i < heads.length; i++){
-                        html += `<th>${heads[i]}</th>`;
-                    }
-                    html += `</tr></thead>`;
-                }
-                html += `<tbody>`;
-                for (var i =0; i < table.length; i++){
-                    html += `<tr>`;
-                    for (var j =0; j < table[i].length; j++){
-                        var keyString = table[i][j];
-                        if (j == 0 && applocale){
-                            keyString = applocale.getString("properties/key/" + keyString.trim(), keyString);
-                        }
-                        html += `<td style="word-break: break-all;">${keyString}</td>`
-                    }
-                    html += `</tr>`;
-                }
-                
-                html += `</tbody>
-                        </table>`;
-                return html
-            }
-
-            function bytesToSize(bytes) {
-                var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
-                if (bytes == 0) return '0 Byte';
-                var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
-                return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
-            }
-
-            /*
-
-            Updates Oct 2020 - Matching File Explorer Theme on other file system tabs
-
-            */
-           
-            function fpw_toggleDarkTheme(){
-                $("#filePropertiesWindow").css({
-                    "background-color":"#242330",
-                    "color":"white",
-                });
-
-                $("#filePropertiesWindow td,.header,p,div").css({
-                    "color":"white",
-                });
-
-                $("#filePropertiesWindow .input").addClass("inverted transparent big")
-            }
-
-
-            function fpw_loadPreference(key, callback){
-                $.get("../../system/file_system/preference?key=" + key,function(data){
-                    callback(data);
-                });
-            }
-
-
-            /*
-                Updates 30 Jan 2021: Added change of file opener
-            */
-
-             //Open Opener Selector for the given file
-            function changeDefaultWebApp(){
-                var ext = fileInfo.Ext;
-                var openFileList = [];
-                var openFileObject = {
-                    filepath: fileInfo.VirtualPath,
-                    filename: fileInfo.Basename,
-                }
-                openFileList.push(openFileObject);
-                var openParamter = encodeURIComponent(JSON.stringify(openFileObject));
-                ao_module_newfw({
-                    url: "SystemAO/file_system/defaultOpener.html#" + openParamter,
-                    width: 320,
-                    height: 510,
-                    appicon: "SystemAO/file_system/img/opener.png",
-                    title: "Default WebApp for " + ext,
-                    parent: ao_module_windowID,
-                    callback: "handleRefresh"
-                });
-            }
-
-            function handleRefresh(){
-                //Default opener changed. Update the display
-                initFileProperties();
-            }
-
-            /*
-                Updates 9 April 2021: Added day compare for last modification days
-            */
-
-            function generateDisplayLastModTime(lastModTime){
-                //Try to split the date into js date format
-                var dateInfo = (lastModTime.split(" ")[0]).split("-");
-                var modTime = new Date(dateInfo[0],dateInfo[1],dateInfo[2]);
-                var diff = calcDate(new Date(), modTime);
-                var displayText = "Unknown";
-                if (diff[2] > 0){
-                    //years
-                    displayText = diff[2] + applocale.getString("lastmod/time/year", " year");
-                    if (diff[2] > 1){
-                        displayText += applocale.getString("lastmod/time/s", "s")
-                    }
-
-                    displayText += applocale.getString("lastmod/time/ago", " ago");
-                    
-                }else if (diff[1] > 0){
-                    //months
-                    displayText = diff[1] +  applocale.getString("lastmod/time/month", "  month");
-                    if (diff[1] > 1){
-                        displayText += applocale.getString("lastmod/time/s", "s")
-                    }
-
-                    displayText += applocale.getString("lastmod/time/ago", " ago");
-                }else if (diff [0] > 0){
-                    //days
-                    displayText = diff[0] + applocale.getString("lastmod/time/days", "  day");
-                    if (diff[0] > 1){
-                        displayText += applocale.getString("lastmod/time/s", "s");
-                    }
-
-                    displayText += applocale.getString("lastmod/time/ago", " ago");
-                }else{
-                    //just now
-                    displayText = applocale.getString("lastmod/time/today", "Today");
-                }
-
-                return displayText + " (" + lastModTime + ")";
-            }
-
-            function calcDate(date1 = new Date(),date2) {
-                var diff = Math.floor(date1.getTime() - date2.getTime());
-                var day = 1000 * 60 * 60 * 24;
-
-                var days = Math.floor(diff/day);
-                var months = Math.floor(days/31);
-                var years = Math.floor(months/12);
-
-
-                return [days, months, years];
-            }
-        </script>
-    </body>
+<html>
+    <head>
+        <title locale="title/title">File Properties</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
+        <link rel="stylesheet" href="../../script/semantic/semantic.css">
+        <script type="text/javascript" src="../../script/jquery.min.js"></script>
+        <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
+        <script type="text/javascript" src="../../script/ao_module.js"></script>
+        <script type="text/javascript" src="../../script/applocale.js"></script>
+        <style>
+            body{
+                overflow:hidden;
+            }
+
+        </style>
+    </head>
+    <body id="filePropertiesWindow">
+        <br>
+        <div class="ui container">
+            <h3 class="ui header">
+                <span locale="title/title">File Properties</span>
+                <div class="sub header" locale="title/desc">Basic File Information</div>
+            </h3>
+            <div class="ui divider"></div>
+            <div id="properties">
+
+            </div>
+            <br>
+            <button style="display:none;" class="ui small blue fluid button singleFileOnly" onclick="changeDefaultWebApp();" locale="button/changeDefault">Change Default WebApp</button>
+            <button style="display:none; margin-top: 4px;" class="ui small fluid button singleFileOnly" onclick="viewVersionHistory();" locale="button/versionHistory">View Version History</button>
+            <button style="margin-top: 4px;" class="ui small fluid button linuxonly" onclick="openFilePermissionPanel();" locale="button/changeFilePermission">Change File Permissions</button>
+            <br>
+        </div>
+        <div id="filesizeLoader" class="ui active dimmer">
+            <div class="ui indeterminate text loader" locale="loader/loadingFileSize">Calculating File Size</div>
+        </div>
+        <script>
+            //Initiate the view model
+            var files = ao_module_loadInputFiles();
+            var fileProperties = [];
+            var fileInfo = {};
+            function initFileProperties(){
+                $("#properties").html("");
+                if (files.length == 1){
+                    //There are only 1 file to be shown
+                    getFileProp(files[0], renderSingleObject);
+                }else if (files.length > 1){
+                    for (var i =0; i < files.length; i++){
+                        getFileProp(files[i], function(data){
+                            fileProperties.push(data);
+                            if (fileProperties.length == files.length){
+                                renderMultipleObjects();
+                            }
+                        });
+                    }
+                }
+            }
+
+            applocale.init("../locale/file_properties.json", function(){
+                applocale.translate();
+                initFileProperties();
+            });
+
+           
+          
+
+            //Hide windows / linux only operations
+            $.get("/system/info/getArOZInfo", function(data){
+                if (data.HostOS == "windows"){
+                    $(".linuxonly").hide();
+                }else{
+                    $(".windowsonly").hide();
+                }
+            });
+
+            function viewVersionHistory(){
+                var hashPassthrough = encodeURIComponent(JSON.stringify(files));
+                ao_module_newfw({
+                    url: "SystemAO/file_system/file_versions.html#" + hashPassthrough,
+                    width: 570,
+                    height: 480,
+                    appicon: "SystemAO/file_system/img/properties.png",
+                    title: "File Version History",
+                });
+            }
+
+            function getFileProp(vpath, callback){
+                $.ajax({
+                    url: "../../system/file_system/getProperties",
+                    data: {path: vpath},
+                    method: "POST",
+                    success: function(data){
+                        callback(data);
+                        fileInfo = data;
+                        //Initialize system theme
+                        fpw_loadPreference("file_explorer/theme",function(data){
+                            if (data.error === undefined){
+                                if (data == "darkTheme"){
+                                    fpw_toggleDarkTheme();
+                                }else{
+                                    //White theme. Do nothing
+                                }
+                            }
+                        });
+
+                    }
+                })
+            }
+
+            function openFilePermissionPanel(){
+                var hashPassthrough = encodeURIComponent(JSON.stringify(files));
+                ao_module_newfw({
+                    url: "SystemAO/file_system/file_permission.html#" + hashPassthrough,
+                    width: 340,
+                    height: 480,
+                    appicon: "SystemAO/file_system/img/properties.png",
+                    title: "File Permissions",
+                });
+            }
+
+            function renderMultipleObjects(){
+                hideLoader();
+                var filesizeSum = sumProperties(fileProperties, "Filesize");
+                $("#properties").append(ui_getInput(fileProperties[0].VirtualDirname + "/", "Root Name"));
+                var filecount = 0;
+                var foldercount = 0;
+                for (var i =0; i < fileProperties.length; i++){
+                    if (fileProperties[i].IsDirectory){
+                        foldercount++;
+                    }else{
+                        filecount++;
+                    }
+                }
+                $("#properties").append(ui_getText(applocale.getString("selection/multi", "Multiple selections")));
+                $("#properties").append(ui_getText(filecount + applocale.getString("counter/files", " Files")));
+                $("#properties").append(ui_getText(foldercount + applocale.getString("counter/folders", " Folders")));
+                
+                let totalSizeText = bytesToSize(filesizeSum) + ` (${filesizeSum} bytes)`
+                if (filesizeSum < 0){
+                    //Network folder. Do not render size
+                    totalSizeText = `<i class="times circle outline yellow icon"></i> ${applocale.getString("properties/error/Not available for network folders", "Not available for network folders")}`;
+                }
+
+                //Append other properties as table
+                $("#properties").append(ui_getTable(
+                        [],
+                        [
+                            ["Virtual Directory", fileProperties[0].VirtualDirname + "/"],
+                            ["Storage Directory", fileProperties[0].StorageDirname + "/"],
+                            ["Total Size", totalSizeText],
+                        ]
+                    ));
+
+                
+            }
+
+            function sumProperties(data, propName){
+                var sum = 0;
+                for (var i = 0; i < data.length; i++){
+                    sum += data[i][propName];
+                }
+                return sum;
+            }
+            
+            //Render one object property to the ui element
+            function renderSingleObject(data){
+                hideLoader();
+                if (data.error !== undefined){
+                    //Something went wrong
+                    $("#properties").append(`<h4 class="ui header">
+                        <i class="question icon"></i>
+                        <div class="content">
+                            File Properties Unknown
+                            <div class="sub header">The system were unable to read the selected file properties.</div>
+                        </div>
+                    </h4>
+                    <div class="ui divider"></div>
+                    <small>${data.error}</small>
+                    `);
+                }else{
+                    //Append Filename
+                    var filesizeText = "File Size";
+                    if (data.IsDirectory){
+                        $("#properties").append(ui_getInput(data.Basename, "Folder Name"));
+                        filesizeText = "Folder Size";
+                    }else{
+                        $("#properties").append(ui_getInput(data.Basename, "File Name"));
+                    }
+                    
+                    //Append MIME Type
+                    $("#properties").append(ui_getText(data.MimeType));
+                    
+                    //Get the default opener
+                    if (!data.IsDirectory){
+                        //Check if this file is shortcut
+                        if ( data.Basename.split(".").pop() == "shortcut"){
+                            //This is shortcut file
+                            $("#properties").append(ui_getTable(
+                                        [],
+                                        [
+                                            ["Virtual Path", data.VirtualPath],
+                                            ["Storage Path", data.StoragePath],
+                                            ["Permission", data.Permission],
+                                            ["Last Modified", generateDisplayLastModTime(data.LastModTime)],
+                                            ["File Type", "System Shortcut"],
+                                            ["Owner",data.Owner],
+
+                                        ]
+                                    ));
+                        }else{
+                            //Normal Files
+                            $(".singleFileOnly").show();
+                            $.ajax({
+                                url: "../../system/modules/getDefault",
+                                method: "GET",
+                                data: {
+                                    opr: "launch",
+                                    ext: "." + data.Basename.split(".").pop(),
+                                    mode: "launch"
+                                },
+                                success: function(openerinfo) {
+                                    //Check if the module is set.
+                                    var defaultWebAppField = ["Default WebApp",`<img class="ui mini spaced image" style="margin-left: 0px; padding-right: 8px;" src="../../${openerinfo.IconPath}">` + openerinfo.Name];
+                                    if ( openerinfo.Name == undefined){
+                                        //Not set. 
+                                        defaultWebAppField = ["Default WebApp", `<a href="#" onclick="changeDefaultWebApp();">Set Default WebApp</a>`];
+                                    }
+                                    //Append other properties as table
+                                    $("#properties").append(ui_getTable(
+                                        [],
+                                        [
+                                            defaultWebAppField,
+                                            ["Virtual Path", data.VirtualPath],
+                                            ["Storage Path", data.StoragePath],
+                                            [filesizeText, bytesToSize(data.Filesize) + ` (${data.Filesize} bytes)`],
+                                            ["Permission", data.Permission],
+                                            ["Last Modified", generateDisplayLastModTime(data.LastModTime)],
+                                            ["File Type", "File"],
+                                            ["Owner",data.Owner],
+
+                                        ]
+                                    ));
+                                }
+                            });
+                        }
+                        
+                    }else{
+                        let folderSizeText = bytesToSize(data.Filesize) + ` (${data.Filesize} bytes)`;
+                        if (data.Filesize < 0){
+                            //Network folder. Do not render size
+                            folderSizeText = `<i class="times circle outline yellow icon"></i> ${applocale.getString("properties/error/Not available for network folders", "Not available for network folders")}`;
+                        }
+                        let lastModTimeText = generateDisplayLastModTime(data.LastModTime);
+                        if (data.LastModUnix == 0){
+                            lastModTimeText = `<i class="times circle outline yellow icon"></i> ${applocale.getString("properties/error/No record", "No record")}`;
+                        }
+                        $("#properties").append(ui_getTable(
+                            [],
+                            [
+                                ["Virtual Path", data.VirtualPath],
+                                ["Storage Path", data.StoragePath],
+                                [filesizeText, folderSizeText ],
+                                ["Permission", data.Permission],
+                                ["Last Modified", lastModTimeText],
+                                ["File Type", "Folder"],
+                                ["Owner",data.Owner],
+
+                            ]
+                        ));
+                    }
+                   
+
+                }
+                
+            }
+
+            function hideLoader(){
+                $("#filesizeLoader").hide();
+                $("body").css('overflow-y',"auto");
+            }
+
+            //Model rendering scripts
+            function ui_getInput(value, placeholder="", type="text"){
+                return `<div class="ui fluid small input">
+                            <input type="${type}" placeholder="${placeholder}" value="${value}" readonly="true">
+                        </div>`
+            }
+
+            function ui_getText(value, color="black"){
+                return `<p style="color:${color}; margin-bottom:0px;">${value}</p>`;
+            }
+
+            function ui_getDivider(){
+                return `<div class="ui divider"></div>`;
+            }
+
+            //head is a 1D array and table is 2D array
+            function ui_getTable(heads, table){
+                html =  `<table class="ui very basic fluid table">`;
+                if (heads.length > 0){
+                    html += `<thead><tr>`;
+                    for (var i =0; i < heads.length; i++){
+                        html += `<th>${heads[i]}</th>`;
+                    }
+                    html += `</tr></thead>`;
+                }
+                html += `<tbody>`;
+                for (var i =0; i < table.length; i++){
+                    html += `<tr>`;
+                    for (var j =0; j < table[i].length; j++){
+                        var keyString = table[i][j];
+                        if (j == 0 && applocale){
+                            keyString = applocale.getString("properties/key/" + keyString.trim(), keyString);
+                        }
+                        html += `<td style="word-break: break-all;">${keyString}</td>`
+                    }
+                    html += `</tr>`;
+                }
+                
+                html += `</tbody>
+                        </table>`;
+                return html
+            }
+
+            function bytesToSize(bytes) {
+                var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+                if (bytes == 0) return '0 Byte';
+                var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
+                return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
+            }
+
+            /*
+
+            Updates Oct 2020 - Matching File Explorer Theme on other file system tabs
+
+            */
+           
+            function fpw_toggleDarkTheme(){
+                $("#filePropertiesWindow").css({
+                    "background-color":"#242330",
+                    "color":"white",
+                });
+
+                $("#filePropertiesWindow td,.header,p,div").css({
+                    "color":"white",
+                });
+
+                $("#filePropertiesWindow .input").addClass("inverted transparent big")
+            }
+
+
+            function fpw_loadPreference(key, callback){
+                $.get("../../system/file_system/preference?key=" + key,function(data){
+                    callback(data);
+                });
+            }
+
+
+            /*
+                Updates 30 Jan 2021: Added change of file opener
+            */
+
+             //Open Opener Selector for the given file
+            function changeDefaultWebApp(){
+                var ext = fileInfo.Ext;
+                var openFileList = [];
+                var openFileObject = {
+                    filepath: fileInfo.VirtualPath,
+                    filename: fileInfo.Basename,
+                }
+                openFileList.push(openFileObject);
+                var openParamter = encodeURIComponent(JSON.stringify(openFileObject));
+                ao_module_newfw({
+                    url: "SystemAO/file_system/defaultOpener.html#" + openParamter,
+                    width: 320,
+                    height: 510,
+                    appicon: "SystemAO/file_system/img/opener.png",
+                    title: "Default WebApp for " + ext,
+                    parent: ao_module_windowID,
+                    callback: "handleRefresh"
+                });
+            }
+
+            function handleRefresh(){
+                //Default opener changed. Update the display
+                initFileProperties();
+            }
+
+            /*
+                Updates 9 April 2021: Added day compare for last modification days
+            */
+
+            function generateDisplayLastModTime(lastModTime){
+                //Try to split the date into js date format
+                var dateInfo = (lastModTime.split(" ")[0]).split("-");
+                var modTime = new Date(dateInfo[0],dateInfo[1],dateInfo[2]);
+                var diff = calcDate(new Date(), modTime);
+                var displayText = "Unknown";
+                if (diff[2] > 0){
+                    //years
+                    displayText = diff[2] + applocale.getString("lastmod/time/year", " year");
+                    if (diff[2] > 1){
+                        displayText += applocale.getString("lastmod/time/s", "s")
+                    }
+
+                    displayText += applocale.getString("lastmod/time/ago", " ago");
+                    
+                }else if (diff[1] > 0){
+                    //months
+                    displayText = diff[1] +  applocale.getString("lastmod/time/month", "  month");
+                    if (diff[1] > 1){
+                        displayText += applocale.getString("lastmod/time/s", "s")
+                    }
+
+                    displayText += applocale.getString("lastmod/time/ago", " ago");
+                }else if (diff [0] > 0){
+                    //days
+                    displayText = diff[0] + applocale.getString("lastmod/time/days", "  day");
+                    if (diff[0] > 1){
+                        displayText += applocale.getString("lastmod/time/s", "s");
+                    }
+
+                    displayText += applocale.getString("lastmod/time/ago", " ago");
+                }else{
+                    //just now
+                    displayText = applocale.getString("lastmod/time/today", "Today");
+                }
+
+                return displayText + " (" + lastModTime + ")";
+            }
+
+            function calcDate(date1 = new Date(),date2) {
+                var diff = Math.floor(date1.getTime() - date2.getTime());
+                var day = 1000 * 60 * 60 * 24;
+
+                var days = Math.floor(diff/day);
+                var months = Math.floor(days/31);
+                var years = Math.floor(months/12);
+
+
+                return [days, months, years];
+            }
+        </script>
+    </body>
 </html>

+ 9 - 0
web/SystemAO/locale/file_properties.json

@@ -38,6 +38,9 @@
                 "counter/files": " 個檔案",
                 "counter/folders": " 個資料夾",
 
+                "properties/error/Not available for network folders":"不適用於網絡資料夾",
+                "properties/error/No record":"沒有記錄",
+
                 "":""
             }
         },
@@ -77,6 +80,9 @@
                 "counter/files": " 個檔案",
                 "counter/folders": " 個資料夾",
 
+                "properties/error/Not available for network folders":"不適用於網絡資料夾",
+                "properties/error/No record":"沒有記錄",
+
                 "":""
             }
         },
@@ -116,6 +122,9 @@
                 "counter/files": " 个文件",
                 "counter/folders": " 个文件夹",
 
+                "properties/error/Not available for network folders":"不适用于网络资料夹",
+                "properties/error/No record":"没有记录",
+
                 "":""
             }
         }