瀏覽代碼

Updated version number and added photo preview in share

Toby Chui 11 月之前
父節點
當前提交
7106a1736f
共有 4 個文件被更改,包括 378 次插入312 次删除
  1. 0 0
      documents/v3 arch/v3 general arch design
  2. 2 1
      main.flags.go
  3. 10 7
      main.go
  4. 366 304
      system/share/downloadPageFolder.html

文件差異過大導致無法顯示
+ 0 - 0
documents/v3 arch/v3 general arch design


+ 2 - 1
main.flags.go

@@ -33,7 +33,7 @@ var subserviceBasePort = 12810            //Next subservice port
 
 // =========== SYSTEM BUILD INFORMATION ==============
 var build_version = "development"                      //System build flag, this can be either {development / production / stable}
-var internal_version = "0.2.020"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
+var internal_version = "0.2.021"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
 var deviceUUID string                                  //The device uuid of this host
 var deviceVendor = "IMUSLAB.INC"                       //Vendor of the system
 var deviceVendorURL = "http://imuslab.com"             //Vendor contact information
@@ -49,6 +49,7 @@ var systemWideLogger *logger.Logger                            //The sync map to
 
 // =========== SYSTEM FLAGS ==============
 // Flags related to System startup
+var listen_host = flag.String("host", "", "Listening host for HTTP server")
 var listen_port = flag.Int("port", 8080, "Listening port for HTTP server")
 var tls_listen_port = flag.Int("tls_port", 8443, "Listening port for HTTPS server")
 var show_version = flag.Bool("version", false, "Show system build version")

+ 10 - 7
main.go

@@ -116,19 +116,22 @@ func main() {
 		if *use_tls {
 			if !*disable_http {
 				go func() {
-					log.Println("Standard (HTTP) Web server listening at :" + strconv.Itoa(*listen_port))
-					http.ListenAndServe(":"+strconv.Itoa(*listen_port), nil)
+					address := fmt.Sprintf("%s:%d", *listen_host, *listen_port)
+					log.Println("Standard (HTTP) Web server listening at", address)
+					http.ListenAndServe(address, nil)
 				}()
 			}
-			log.Println("Secure (HTTPS) Web server listening at :" + strconv.Itoa(*tls_listen_port))
-			http.ListenAndServeTLS(":"+strconv.Itoa(*tls_listen_port), *tls_cert, *tls_key, nil)
+			address := fmt.Sprintf("%s:%d", *listen_host, *tls_listen_port)
+			log.Println("Secure (HTTPS) Web server listening at", address)
+			http.ListenAndServeTLS(address, *tls_cert, *tls_key, nil)
 		} else {
-			log.Println("Web server listening at :" + strconv.Itoa(*listen_port))
-			http.ListenAndServe(":"+strconv.Itoa(*listen_port), nil)
+			address := fmt.Sprintf("%s:%d", *listen_host, *listen_port)
+			log.Println("Web server listening at", address)
+			http.ListenAndServe(address, nil)
 		}
 	}()
 
-	if *enable_console == true {
+	if *enable_console {
 		//Startup interactive shell for debug and basic controls
 		Console := console.NewConsole(consoleCommandHandler)
 		Console.ListenAndHandle()

+ 366 - 304
system/share/downloadPageFolder.html

@@ -1,305 +1,367 @@
-<!DOCTYPE HTML>
-<html>
-    <head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <title>{{filename}} - {{hostname}} File Share</title>
-    <meta name="description" content="Folder shared from  {{hostname}}">
-
-      <!-- Facebook Meta Tags -->
-      <meta property="og:url" content="{{requri}}">
-      <meta property="og:type" content="website">
-      <meta property="og:title" content="{{filename}}">
-      <meta property="og:description" content="File shared from {{hostname}}">
-      <meta property="og:image" content="{{opg_image}}">
-    
-      <!-- Twitter Meta Tags -->
-      <meta name="twitter:card" content="summary_large_image">
-      <meta property="twitter:domain" content="{{host}}">
-      <meta property="twitter:url" content="{{requri}}">
-      <meta name="twitter:title" content="{{filename}}">
-      <meta name="twitter:description" content="File shared from {{hostname}}">
-      <meta name="twitter:image" content="{{opg_image}}">
-      
-    <link rel="stylesheet" href="../../script/skeleton/offline.css">
-    <link rel="stylesheet" href="../../script/skeleton/normalize.css">
-    <link rel="stylesheet" href="../../script/skeleton/skeleton.css">
-    <script type="application/javascript" src="../../script/jquery.min.js"></script>
-    <link rel="icon" type="image/png" href="../../img/public/share/share.png" />
-    <style>
-
-        body{
-            padding-bottom: 100px;
-        }
-        .bar{
-            height: 12px;
-            background-color: #1a1a1a;
-            width: 100%;
-        }
-
-        .footer{
-            position: fixed;
-            bottom: 0px;
-            height: 50px;
-            width: 100%;
-            background-color: #1a1a1a;
-            padding: 20px;
-            color: white;
-        }
-
-        .fileobject{
-          cursor: pointer;
-        }
-        .fileobject:hover{
-          background-color: #f5f5f5;
-        }
-
-        .fileobject.active{
-          background-color: #f5f5f5ee;
-        }
-
-        .noselect{
-          -webkit-touch-callout: none; /* iOS Safari */
-          -webkit-user-select: none; /* Safari */
-          -khtml-user-select: none; /* Konqueror HTML */
-          -moz-user-select: none; /* Old versions of Firefox */
-          -ms-user-select: none; /* Internet Explorer/Edge */
-          user-select: none;
-        }
-
-        #filelistWrapper{
-          position: relative;
-          padding: 12px;
-          border-top: 4px solid #ffe46c;
-          -webkit-box-shadow: 11px 9px 23px 0px rgba(54,54,54,0.31); 
-          box-shadow: 11px 9px 23px 0px rgba(54,54,54,0.31);
-        }
-
-        td{
-          word-break: break-all;
-        }
-    </style>
-    </head>
-    <body>
-        <div class="bar"></div>
-        <br>
-        <div class="container">
-            <h5>{{hostname}} File Sharing</h5>
-            <h3>{{filename}}</h3>
-            <div class="row">
-                <div class="one-half column">
-                    <table class="u-full-width">
-                        <thead>
-                          <tr>
-                            <th>Property</th>
-                            <th>Value</th>
-                          </tr>
-                        </thead>
-                        <tbody>
-                          <tr>
-                            <td>MIME Type</td>
-                            <td>{{mime}}</td>
-                          </tr>
-                          <tr>
-                            <td>Folder Size</td>
-                            <td>{{size}}</td>
-                          </tr>
-                          <tr>
-                            <td>File Counts</td>
-                            <td>{{filecount}}</td>
-                          </tr>
-                          <tr>
-                            <td>Last Modification Time</td>
-                            <td>{{modtime}}</td>
-                          </tr>
-                        </tbody>
-                      </table>
-                    <a href="{{downloadurl}}"><button class="button-primary">Download All</button></a>
-                    <button id="sharebtn" onclick="share();">Share</button>
-                    <p style="font-size: 80%;"><b>Depending on folder size, zipping might take a while to complete.</b></p>
-                    <p>Request File ID: {{reqid}}<br>
-                    Request Timestamp: {{reqtime}}</p>
-                    <small>📂 Double click any item in the list to open or download</small>
-                    
-                </div>
-                <div class="one-half column" id="filelistWrapper" style="overflow-y: auto; padding-right: 0.5em; min-height: 400px;">
-                  <table class="u-full-width">
-                    <thead>
-                      <tr>
-                        <th>Filename</th>
-                        <th>Type</th>
-                        <th>Size</th>
-                      </tr>
-                    </thead>
-                    <tbody id="folderList">
-                     
-                    </tbody>
-                  </table>
-                </div>
-            </div>
-          
-        </div>
-        <div class="footer">
-            <div class="container">
-                Cloud File Sharing Interface, Powered by <a style="color: white;" href="http://arozos.com">arozos</a>
-            </div>
-        </div>
-    <script>
-      var treeFileList = {{treelist}};
-      var downloadUUID = `{{downloaduuid}}`;
-      var currentViewingRoot = ".";
-      var selectedFile = null;
-      renderFileList(treeFileList["."]);
-
-      handleWindowResize();
-      $(window).on("resize", function(e){
-        handleWindowResize();
-      });
-
-      if (location.protocol !== 'https:') {
-         document.getElementById("sharebtn").remove()
-      }
-
-      function share(){
-        let shareData = {
-          title: "{{filename}}",
-          text: '{{filename}} - File Share from {{hostname}}',
-          url: window.location.href,
-        }
-
-        navigator.share(shareData).then(() =>
-          function(){
-            //Share succ
-          }
-        ).catch((e) =>
-          function(){
-              //Share failed
-          }
-        )
-      }
-
-
-      function handleWindowResize(){
-        if (window.innerWidth < 550){
-          //Assume mobile
-          $(".footer").css("height", "20px");
-        }else{
-          $(".footer").css("height", "50px");
-        }
-      }
-      
-
-      function renderFileList(filelist){
-        $("#folderList").html("");
-        if (currentViewingRoot != "."){
-          $("#folderList").append(`<tr class="fileobject noselect" ondblclick="event.preventDefault(); parentdir();">
-              <td style="padding-left: 8px;" colspan="3" > ↩ Back</td>
-            </tr>`);
-          
-        }
-
-        filelist.forEach(file => {
-          var filetype = "File";
-          var displayName = "";
-          if (file.IsDir == true){
-            //Folder
-            filetype = "Folder";
-            displayName = "📁 " + file.Filename;
-          }else{
-            //File
-            var ext = file.Filename.split(".").pop();
-            var icon = "📄"
-            ext = ext.toLowerCase();
-            if (ext == "mp3" || ext == "wav" || ext == "flac" || ext == "aac" || ext == "ogg" || ext == ""){
-              icon = "🎵";
-            }else if (ext == "mp4" || ext == "avi" || ext == "webm" || ext == "mkv" || ext == "mov" || ext == "rvmb"){
-              icon = "🎞️";
-            }else if (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "bmp" || ext == "gif"){
-              icon = "🖼️";
-            }
-
-            displayName =  icon + " " + file.Filename;
-          }
-
-          var filenameLinker = `<a href="../../share/download/${downloadUUID}/${file.RelPath}">${displayName}</a>`;
-          if (file.IsDir == true){
-            filenameLinker = `${displayName}`;
-          }
-          $("#folderList").append(`<tr class="fileobject noselect" onclick="highlightThis(this);" filename="${file.Filename}" relpath="${file.RelPath}" type="${filetype.toLocaleLowerCase()}" ondblclick="event.preventDefault(); openThis(this);">
-              <td style="padding-left: 8px;">${filenameLinker}</td>
-              <td>${filetype}</td>
-              <td>${file.Filesize}</td>
-            </tr>`);
-          });
-      }
-
-      //Went up one level
-      function parentdir(){
-        if (currentViewingRoot == "."){
-            //Root dir. Do nothing
-            
-        }else{
-            //Subdirs. travel up
-            var dirinfo = currentViewingRoot.split("/");
-            var nextDir = ".";
-            if (currentViewingRoot.indexOf("/") < 0){
-              //Parent dir will be root
-            }else{
-              dirinfo.pop();
-              nextDir = dirinfo.join("/");
-            }
-
-            
-            //Load the filelist
-            if (treeFileList[nextDir] != undefined){
-              currentViewingRoot = nextDir;
-              renderFileList(treeFileList[nextDir]);
-            }else{
-              //Back to root on error
-              currentViewingRoot = ".";
-              renderFileList(treeFileList["."]);
-            }
-        }
-      }
-
-      function openThis(object){
-        var targetFilename = $(object).attr("filename");
-        var targetType = $(object).attr("type");
-        var targetRelPath = $(object).attr("relpath");
-        
-        if (targetType == "folder"){
-          //Folder. Build a new root file list for this
-          var targetRenderList = treeFileList[targetRelPath];
-          if (targetRenderList != undefined){
-            currentViewingRoot = targetRelPath;
-            renderFileList(targetRenderList);
-          }
-          
-        }else{
-          //File. Download it
-          window.open("../../share/download/" + downloadUUID + "/" + targetRelPath)
-        }
-      }
-
-      resizeDOMElement();
-      function resizeDOMElement(){
-        $("#filelistWrapper").css({
-          height: window.innerHeight - $("#filelistWrapper").offset().top - 100,
-        })
-      }
-
-      function highlightThis(object){
-          $(".fileobject.active").removeClass("active");
-          $(object).addClass("active");
-          $("#activeFilename").text(" (" + $(object).attr("filename") +")");
-
-          //Update the properties values
-          selectedFile = $(object);
-      }
-
-      $(window).on("resize", function(){
-        resizeDOMElement();
-      })
-    </script>
-    </body>
+<!DOCTYPE HTML>
+<html>
+    <head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title>{{filename}} - {{hostname}} File Share</title>
+    <meta name="description" content="Folder shared from  {{hostname}}">
+
+      <!-- Facebook Meta Tags -->
+      <meta property="og:url" content="{{requri}}">
+      <meta property="og:type" content="website">
+      <meta property="og:title" content="{{filename}}">
+      <meta property="og:description" content="File shared from {{hostname}}">
+      <meta property="og:image" content="{{opg_image}}">
+    
+      <!-- Twitter Meta Tags -->
+      <meta name="twitter:card" content="summary_large_image">
+      <meta property="twitter:domain" content="{{host}}">
+      <meta property="twitter:url" content="{{requri}}">
+      <meta name="twitter:title" content="{{filename}}">
+      <meta name="twitter:description" content="File shared from {{hostname}}">
+      <meta name="twitter:image" content="{{opg_image}}">
+      
+    <link rel="stylesheet" href="../../script/skeleton/offline.css">
+    <link rel="stylesheet" href="../../script/skeleton/normalize.css">
+    <link rel="stylesheet" href="../../script/skeleton/skeleton.css">
+    <script type="application/javascript" src="../../script/jquery.min.js"></script>
+    <link rel="icon" type="image/png" href="../../img/public/share/share.png" />
+    <style>
+
+        body{
+            padding-bottom: 100px;
+        }
+        .bar{
+            height: 12px;
+            background-color: #1a1a1a;
+            width: 100%;
+        }
+
+        .footer{
+            position: fixed;
+            bottom: 0px;
+            height: 50px;
+            width: 100%;
+            background-color: #1a1a1a;
+            padding: 20px;
+            color: white;
+        }
+
+        .fileobject{
+          cursor: pointer;
+        }
+        .fileobject:hover{
+          background-color: #f5f5f5;
+        }
+
+        .fileobject.active{
+          background-color: #f5f5f5ee;
+        }
+
+        .noselect{
+          -webkit-touch-callout: none; /* iOS Safari */
+          -webkit-user-select: none; /* Safari */
+          -khtml-user-select: none; /* Konqueror HTML */
+          -moz-user-select: none; /* Old versions of Firefox */
+          -ms-user-select: none; /* Internet Explorer/Edge */
+          user-select: none;
+        }
+
+        #filelistWrapper{
+          position: relative;
+          padding: 12px;
+          border-top: 4px solid #ffe46c;
+          -webkit-box-shadow: 11px 9px 23px 0px rgba(54,54,54,0.31); 
+          box-shadow: 11px 9px 23px 0px rgba(54,54,54,0.31);
+        }
+
+        td{
+          word-break: break-all;
+        }
+    </style>
+    </head>
+    <body>
+        <div class="bar"></div>
+        <br>
+        <div class="container">
+            <h5>{{hostname}} File Sharing</h5>
+            <h3>{{filename}}</h3>
+            <div class="row">
+                <div class="one-half column">
+                    <table class="u-full-width">
+                        <thead>
+                          <tr>
+                            <th>Property</th>
+                            <th>Value</th>
+                          </tr>
+                        </thead>
+                        <tbody>
+                          <tr>
+                            <td>MIME Type</td>
+                            <td>{{mime}}</td>
+                          </tr>
+                          <tr>
+                            <td>Folder Size</td>
+                            <td>{{size}}</td>
+                          </tr>
+                          <tr>
+                            <td>File Counts</td>
+                            <td>{{filecount}}</td>
+                          </tr>
+                          <tr>
+                            <td>Last Modification Time</td>
+                            <td>{{modtime}}</td>
+                          </tr>
+                        </tbody>
+                      </table>
+                    <a href="{{downloadurl}}"><button class="button-primary">Download All</button></a>
+                    <button id="sharebtn" onclick="share();">Share</button>
+                    <p style="font-size: 80%;"><b>Depending on folder size, zipping might take a while to complete.</b></p>
+                    <p>Request File ID: {{reqid}}<br>
+                    Request Timestamp: {{reqtime}}</p>
+                    <small>📂 Double click any item in the list to open or download</small>
+                    
+                </div>
+                <div class="one-half column" id="filelistWrapper" style="overflow-y: auto; padding-right: 0.5em; min-height: 400px;">
+                  <table class="u-full-width">
+                    <thead>
+                      <tr>
+                        <th>Filename</th>
+                        <th>Type</th>
+                        <th>Size</th>
+                      </tr>
+                    </thead>
+                    <tbody id="folderList">
+                     
+                    </tbody>
+                  </table>
+                </div>
+            </div>
+          
+        </div>
+        <div class="footer">
+            <div class="container">
+                Cloud File Sharing Interface, Powered by <a style="color: white;" href="http://arozos.com">arozos</a>
+            </div>
+        </div>
+    <script>
+      var treeFileList = {{treelist}};
+      var downloadUUID = `{{downloaduuid}}`;
+      var currentViewingRoot = ".";
+      var selectedFile = null;
+      renderFileList(treeFileList["."]);
+
+      handleWindowResize();
+      $(window).on("resize", function(e){
+        handleWindowResize();
+      });
+
+      if (location.protocol !== 'https:') {
+         document.getElementById("sharebtn").remove()
+      }
+
+      function share(){
+        let shareData = {
+          title: "{{filename}}",
+          text: '{{filename}} - File Share from {{hostname}}',
+          url: window.location.href,
+        }
+
+        navigator.share(shareData).then(() =>
+          function(){
+            //Share succ
+          }
+        ).catch((e) =>
+          function(){
+              //Share failed
+          }
+        )
+      }
+
+
+      function handleWindowResize(){
+        if (window.innerWidth < 550){
+          //Assume mobile
+          $(".footer").css("height", "20px");
+        }else{
+          $(".footer").css("height", "50px");
+        }
+      }
+      
+
+      function renderFileList(filelist){
+        $("#folderList").html("");
+        if (currentViewingRoot != "."){
+          $("#folderList").append(`<tr class="fileobject noselect" ondblclick="event.preventDefault(); parentdir();">
+              <td style="padding-left: 8px;" colspan="3" > ↩ Back</td>
+            </tr>`);
+          
+        }
+
+        // Add a div for thumbnail preview
+        if (!$("#thumbnail-preview").length) {
+          $("body").append(`
+            <div id="thumbnail-preview" style="
+              display: none;
+              position: fixed;
+              background: white;
+              padding: 5px;
+              border: 1px solid #ccc;
+              border-radius: 5px;
+              box-shadow: 0 0 10px rgba(0,0,0,0.2);
+              z-index: 1000;
+            ">
+              <img style="max-width: 200px; max-height: 200px;" />
+            </div>
+          `);
+        }
+
+        filelist.forEach(file => {
+          var filetype = "File";
+          var displayName = "";
+          var isImage = false;
+          if (file.IsDir == true){
+            //Folder
+            filetype = "Folder";
+            displayName = "📁 " + file.Filename;
+          }else{
+            //File
+            var ext = file.Filename.split(".").pop();
+            var icon = "📄"
+            ext = ext.toLowerCase();
+            if (ext == "mp3" || ext == "wav" || ext == "flac" || ext == "aac" || ext == "ogg" || ext == ""){
+              icon = "🎵";
+            }else if (ext == "mp4" || ext == "avi" || ext == "webm" || ext == "mkv" || ext == "mov" || ext == "rvmb"){
+              icon = "🎞️";
+            }else if (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "bmp" || ext == "gif"){
+              icon = "🖼️";
+              isImage = true;
+            }
+
+            displayName =  icon + " " + file.Filename;
+          }
+
+          var filenameLinker = `<a href="../../share/download/${downloadUUID}/${file.RelPath}">${displayName}</a>`;
+          if (file.IsDir == true){
+            filenameLinker = `${displayName}`;
+          }
+
+          var tr = $(`<tr class="fileobject noselect" onclick="highlightThis(this);" filename="${file.Filename}" relpath="${file.RelPath}" type="${filetype.toLocaleLowerCase()}" ondblclick="event.preventDefault(); openThis(this);">
+              <td style="padding-left: 8px;">${filenameLinker}</td>
+              <td>${filetype}</td>
+              <td>${file.Filesize}</td>
+            </tr>`);
+
+          // Add hover event for images
+          if (isImage) {
+            // Store the download URL as a data attribute
+            tr.attr('data-download-url', `../../share/download/${downloadUUID}/${file.RelPath}`);
+
+            // Add hover events to the entire row
+            tr.hover(
+              function(e) { // mouseenter
+                var imgUrl = $(this).attr('data-download-url');
+                $("#thumbnail-preview img").attr('src', imgUrl);
+                $("#thumbnail-preview").css({
+                  display: 'block',
+                  left: e.pageX + 20,
+                  top: e.pageY + 20
+                });
+              },
+              function() { // mouseleave
+                $("#thumbnail-preview").hide();
+              }
+            );
+
+            // Update thumbnail position on mouse move over the entire row
+            tr.mousemove(function(e) {
+              $("#thumbnail-preview").css({
+                left: e.pageX + 20,
+                top: e.pageY + 20
+              });
+            });
+          }
+
+          $("#folderList").append(tr);
+        });
+
+        // Add CSS to make the entire row hoverable
+        $("<style>")
+          .prop("type", "text/css")
+          .html(`
+            .fileobject { cursor: pointer; }
+            .fileobject:hover { background-color: rgba(0,0,0,0.05); }
+          `)
+          .appendTo("head");
+      }
+
+      //Went up one level
+      function parentdir(){
+        if (currentViewingRoot == "."){
+            //Root dir. Do nothing
+            
+        }else{
+            //Subdirs. travel up
+            var dirinfo = currentViewingRoot.split("/");
+            var nextDir = ".";
+            if (currentViewingRoot.indexOf("/") < 0){
+              //Parent dir will be root
+            }else{
+              dirinfo.pop();
+              nextDir = dirinfo.join("/");
+            }
+
+            
+            //Load the filelist
+            if (treeFileList[nextDir] != undefined){
+              currentViewingRoot = nextDir;
+              renderFileList(treeFileList[nextDir]);
+            }else{
+              //Back to root on error
+              currentViewingRoot = ".";
+              renderFileList(treeFileList["."]);
+            }
+        }
+      }
+
+      function openThis(object){
+        var targetFilename = $(object).attr("filename");
+        var targetType = $(object).attr("type");
+        var targetRelPath = $(object).attr("relpath");
+        
+        if (targetType == "folder"){
+          //Folder. Build a new root file list for this
+          var targetRenderList = treeFileList[targetRelPath];
+          if (targetRenderList != undefined){
+            currentViewingRoot = targetRelPath;
+            renderFileList(targetRenderList);
+          }
+          
+        }else{
+          //File. Download it
+          window.open("../../share/download/" + downloadUUID + "/" + targetRelPath)
+        }
+      }
+
+      resizeDOMElement();
+      function resizeDOMElement(){
+        $("#filelistWrapper").css({
+          height: window.innerHeight - $("#filelistWrapper").offset().top - 100,
+        })
+      }
+
+      function highlightThis(object){
+          $(".fileobject.active").removeClass("active");
+          $(object).addClass("active");
+          $("#activeFilename").text(" (" + $(object).attr("filename") +")");
+
+          //Update the properties values
+          selectedFile = $(object);
+      }
+
+      $(window).on("resize", function(){
+        resizeDOMElement();
+      })
+    </script>
+    </body>
 </html>

部分文件因文件數量過多而無法顯示