Procházet zdrojové kódy

Updated login interface theme color

Toby Chui před 3 roky
rodič
revize
157a039467

+ 38 - 20
desktop.go

@@ -13,6 +13,8 @@ import (
 
 	"imuslab.com/arozos/mod/common"
 	fs "imuslab.com/arozos/mod/filesystem"
+	"imuslab.com/arozos/mod/filesystem/arozfs"
+	"imuslab.com/arozos/mod/filesystem/shortcut"
 	module "imuslab.com/arozos/mod/modules"
 	prout "imuslab.com/arozos/mod/prouter"
 )
@@ -610,16 +612,13 @@ func desktop_preference_handler(w http.ResponseWriter, r *http.Request) {
 }
 
 func desktop_shortcutHandler(w http.ResponseWriter, r *http.Request) {
-	username, err := authAgent.GetUserName(w, r)
-
+	userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
 	if err != nil {
 		//user not logged in. Redirect to login page.
 		common.SendErrorResponse(w, "User not logged in")
 		return
 	}
 
-	userinfo, _ := userHandler.GetUserInfoFromUsername(username)
-
 	shortcutType, err := common.Mv(r, "stype", true)
 	if err != nil {
 		common.SendErrorResponse(w, err.Error())
@@ -644,31 +643,50 @@ func desktop_shortcutHandler(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	//OK to proceed. Generate a shortcut on the user desktop
-	fsh, subpath, _ := GetFSHandlerSubpathFromVpath("user:/Desktop/")
-	fshAbs := fsh.FileSystemAbstraction
+	shortcutCreationDest, err := common.Mv(r, "sdest", true)
+	if err != nil {
+		//Default create on desktop
+		shortcutCreationDest = "user:/Desktop/"
+	}
+
+	if !userinfo.CanWrite(shortcutCreationDest) {
+		common.SendErrorResponse(w, "Permission denied")
+		return
+	}
 
-	userDesktopPath, _ := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
-	if !fs.FileExists(userDesktopPath) {
-		os.MkdirAll(userDesktopPath, 0755)
+	//Resolve vpath to fsh and subpath
+	fsh, subpath, err := GetFSHandlerSubpathFromVpath(shortcutCreationDest)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
 	}
+	fshAbs := fsh.FileSystemAbstraction
 
-	//Check if there are desktop icon. If yes, override icon on module
-	if shortcutType == "module" && fs.FileExists("./web/"+filepath.ToSlash(filepath.Dir(shortcutIcon)+"/desktop_icon.png")) {
-		shortcutIcon = filepath.ToSlash(filepath.Join(filepath.Dir(shortcutIcon), "/desktop_icon.png"))
+	shorcutRealDest, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
 	}
 
-	shortcutText = strings.ReplaceAll(shortcutText, "/", "")
-	for strings.Contains(shortcutText, "../") {
-		shortcutText = strings.ReplaceAll(shortcutText, "../", "")
+	//Filter illegal characters in the shortcut filename
+	shortcutText = arozfs.FilterIllegalCharInFilename(shortcutText, " ")
+
+	//If dest not exists, create it
+	if !fshAbs.FileExists(shorcutRealDest) {
+		fshAbs.MkdirAll(shorcutRealDest, 0755)
 	}
-	shortcutFilename := userDesktopPath + "/" + shortcutText + ".shortcut"
+
+	//Generate a filename for the shortcut
+	shortcutFilename := shorcutRealDest + "/" + shortcutText + ".shortcut"
 	counter := 1
-	for fs.FileExists(shortcutFilename) {
-		shortcutFilename = userDesktopPath + "/" + shortcutText + "(" + strconv.Itoa(counter) + ")" + ".shortcut"
+	for fshAbs.FileExists(shortcutFilename) {
+		shortcutFilename = shorcutRealDest + "/" + shortcutText + "(" + strconv.Itoa(counter) + ")" + ".shortcut"
 		counter++
 	}
-	err = ioutil.WriteFile(shortcutFilename, []byte(shortcutType+"\n"+shortcutText+"\n"+shortcutPath+"\n"+shortcutIcon), 0755)
+
+	//Write the shortcut to file
+	shortcutContent := shortcut.GenerateShortcutBytes(shortcutPath, shortcutType, shortcutText, shortcutIcon)
+	err = fshAbs.WriteFile(shortcutFilename, shortcutContent, 0775)
 	if err != nil {
 		common.SendErrorResponse(w, err.Error())
 		return

+ 7 - 0
mod/filesystem/arozfs/arozfs.go

@@ -11,6 +11,7 @@ import (
 	"io"
 	"io/fs"
 	"path/filepath"
+	"regexp"
 	"strings"
 )
 
@@ -139,6 +140,12 @@ func GenericRealPathToVirtualPathTranslator(uuid string, hierarchy string, rpath
 	return uuid + ":" + rpath, nil
 }
 
+//Filter illegal characters in filename
+func FilterIllegalCharInFilename(filename string, replacement string) string {
+	re, _ := regexp.Compile(`[\\\[\]$?#<>+%!"'|{}:@]`)
+	return re.ReplaceAllString(filename, replacement)
+}
+
 /*
 	OS Independent filepath functions
 */

+ 14 - 0
mod/filesystem/shortcut/shortcut.go

@@ -2,8 +2,10 @@ package shortcut
 
 import (
 	"errors"
+	"path/filepath"
 	"strings"
 
+	"imuslab.com/arozos/mod/common"
 	"imuslab.com/arozos/mod/filesystem/arozfs"
 )
 
@@ -36,3 +38,15 @@ func ReadShortcut(shortcutContent []byte) (*arozfs.ShortcutData, error) {
 
 	return &result, nil
 }
+
+//Generate the content of a shortcut base the the four important field of shortcut information
+func GenerateShortcutBytes(shortcutTarget string, shortcutType string, shortcutText string, shortcutIcon string) []byte {
+	//Check if there are desktop icon. If yes, override icon on module
+	if shortcutType == "module" && common.FileExists(arozfs.ToSlash(filepath.Join("./web/", filepath.Dir(shortcutIcon), "/desktop_icon.png"))) {
+		shortcutIcon = arozfs.ToSlash(filepath.Join(filepath.Dir(shortcutIcon), "/desktop_icon.png"))
+	}
+
+	//Clean the shortcut text
+	shortcutText = arozfs.FilterIllegalCharInFilename(shortcutText, " ")
+	return []byte(shortcutType + "\n" + shortcutText + "\n" + shortcutTarget + "\n" + shortcutIcon)
+}

+ 57 - 27
web/SystemAO/file_system/file_explorer.html

@@ -1103,8 +1103,8 @@
             <div class="item" onclick="deleteFile();">
                 <i class="trash icon"></i> <span locale="contextmenu/delete">Delete</span>
             </div>
-            <div class="item backuponly" onclick="openBackupManager();">
-                <i class="block layout icon"></i> <span locale="contextmenu/backup">Backup & Restore</span>
+            <div class="item folderonly singleObjectOnlyHide" onclick="createDesktopShortcut();">
+                <i class="external square icon"></i> <span locale="opr/shorcut/title">Create Shortcut on Desktop</span>
             </div>
             <div class="divider vroothide"></div>
             <div class="item noSelectionOnly" onclick="refreshList();">
@@ -2067,6 +2067,8 @@
                 $(".fileObject").off("click").on('click',function(evt){
                     if (!ctrlHold && isMobile && !ctrlHold){
                         //If on mobile, click means open (only on not muilti selection mode)
+                        evt.preventDefault();
+                        evt.stopImmediatePropagation();
                         openthis(this,evt);
                         return
                     }
@@ -2103,17 +2105,6 @@
                         $(this).addClass("selected");
                         lastClickedFileID = $(this).attr("fileID");
                     }
-
-                    if ($(".fileObject.selected").length != 1){
-                        //Multiple object selected
-                        $(".singleObjectOnly").addClass("disabled");
-                        $(".singleObjectOnlyHide").hide();
-                    }else{
-                        //Single object
-                        $(".singleObjectOnly").removeClass("disabled");
-                        $(".singleObjectOnlyHide").show();
-                    }
-
                 });
 
                 //Bind right click select on items
@@ -2124,6 +2115,7 @@
                             $(".fileObject.selected").removeClass("selected");
                             $(this).addClass("selected");
                         }
+                        
                     }
                 });
 
@@ -2188,9 +2180,18 @@
                     $("#contextmenu").find(".noSelectionOnly").hide();
                     $("#contextmenu").find(".vrootonly").hide();
                     $("#contextmenu").find(".zipFileOnly").hide();
-                    
-                    //Hide backup manual
-                    $("#contextmenu").find(".backuponly").hide();
+
+                    //Hide general menu options for single / multiple
+                    if ($(".fileObject.selected").length > 1){
+                        //Multiple object selected
+                        $(".singleObjectOnly").addClass("disabled");
+                        $(".singleObjectOnlyHide").hide();
+                        console.log("Hiding");
+                    }else{
+                        //Single object
+                        $(".singleObjectOnly").removeClass("disabled");
+                        $(".singleObjectOnlyHide").show();
+                    }
 
                     //Check if this is folder or file. Replace the suitable selections
                     if ($(this).attr("type") == "folder"){
@@ -2202,6 +2203,7 @@
                         $("#contextmenu").find(".folderonly").hide();
                         $("#contextmenu").find(".fileonly").show();
                     }
+                    console.log($(this).attr("type"));
 
                     if (searchMode == true){
                         $("#contextmenu").find(".shareonly").show();
@@ -2228,7 +2230,6 @@
                             $(".zipFileOnly").show();
                         }
                     });
-
                 });
 
                 //Right click on empty space of the file selector
@@ -2273,19 +2274,11 @@
                         //Correct one. Show vroot functions
                         e.preventDefault();
                         var rootname = $(e.target).attr("rootname");
-                        var containBackup = $(e.target).attr("contain-backup") == "true";
                         $(e.target).addClass("active");
                         $("#contextmenu").find(".item").hide();
                         $("#contextmenu").find(".vroothide").hide();
                         $("#contextmenu").find(".vrootonly").show();
 
-                        //Check if this is a backup drive
-                        if (containBackup == true){
-                            $("#contextmenu").find(".backuponly").show();
-                        }else{
-                            $("#contextmenu").find(".backuponly").hide();
-                        }
-
                         //Show context menu
                         calculateContextMenuOffsets(e);
 
@@ -3031,14 +3024,51 @@
 
             function cancelDelete(){
                 deleteFileList=[];
-                
-            }
+            }            
 
             function cancelForceDelete(){
                 $("#forceDeleteConfirmBox").fadeOut(100);
                 forceDeleteList = [];
             }
 
+            function createDesktopShortcut(){
+                let folders = [];
+                let filenames = [];
+                if ($(".fileObject.selected").length == 0){
+                    return;
+                }
+                $(".fileObject.selected").each(function(){
+                    var thisFilepath = $(this).attr("filepath");
+                    var thisFilename = $(this).attr("filename");
+                    if($(this).attr("type") == "folder"){
+                        folders.push(thisFilepath);
+                        filenames.push(thisFilename);
+                    }
+                });
+
+                let targetFolder = folders[0];
+                let targetFilename = filenames[0];
+                $.ajax({
+                    url: "../../system/desktop/createShortcut",
+                    method: "POST",
+                    data: {
+                        stype: "folder",
+                        stext: targetFilename,
+                        spath: targetFolder,
+                        sicon: "img/system/folder-shortcut.png",
+                        sdest: "user:/Desktop/",
+                    },
+                    success: function(data){
+                        if (data.error !== undefined){
+                            console.log("[File Manager] Shortcut creation failed: ", data.error)
+                            msgbox("remove",applocale.getString("opr/shorcut/error", "Shortcut creation failed. See console for more information.") , 3000);
+                        }else{
+                            msgbox("checkmark", applocale.getString("opr/shorcut/ok", "Shortcut created successfully"),  3000);
+                        }
+                    }
+                })
+            }
+
             function upload(){
                 var input = document.createElement('input');
                 input.type = 'file';

+ 12 - 0
web/SystemAO/locale/file_explorer.json

@@ -92,6 +92,10 @@
                 "opr/openwith/openInNewWindow": "直接於新視窗開啟檔案",
                 "opr/openwith/cancel": "取消",
 
+                "opr/shorcut/title": "在桌面建立捷徑",
+                "opr/shorcut/ok": "捷徑建立成功",
+                "opr/shorcut/error": "桌面建立捷徑失敗",
+
                 "opr/zip/zipping": "正在壓縮 ",
                 "opr/zip/unzipping": "正在解壓縮 ",
                 "opr/zip/nozipfile": "沒有已選擇的壓縮檔",
@@ -300,6 +304,10 @@
                 "opr/openwith/openInNewWindow": "直接於新視窗開啟檔案",
                 "opr/openwith/cancel": "取消",
 
+                "opr/shorcut/title": "在桌面建立捷徑",
+                "opr/shorcut/ok": "捷徑建立成功",
+                "opr/shorcut/error": "桌面建立捷徑失敗",
+
                 "opr/zip/zipping": "正在壓縮 ",
                 "opr/zip/unzipping": "正在解壓縮 ",
                 "opr/zip/nozipfile": "沒有已選擇的壓縮檔",
@@ -505,6 +513,10 @@
                 "opr/openwith/openInNewWindow": "直接于新视窗打开文件",
                 "opr/openwith/cancel": "取消",
 
+                "opr/shortcut/title": "在桌面建立捷径", 
+                "opr/shortcut/ok": "捷径建立成功", 
+                "opr/shorcut/error": "桌面建立捷径失败",
+
                 "opr/zip/zipping": "正在压缩 ",
                 "opr/zip/unzipping": "正在解压缩 ",
                 "opr/zip/nozipfile": "没有已选择的压缩文件",

binární
web/img/public/auth_icon.png


binární
web/img/public/auth_icon.psd


+ 4 - 4
web/login.system

@@ -72,21 +72,21 @@
     }
 
     .themecolor{
-        background-color: #5fa0d9 !important;
+        background-color: #485b73 !important;
         transition: background-color 0.1s;
     }
 
     .themecolor:hover{
-        background-color: #99d0f2 !important;
+        background-color: #677c96 !important;
     }
 
     .subthemecolor{
-        background-color: #405673 !important;
+        background-color: #3e4f64 !important;
         transition: background-color 0.1s;
     }
 
     .subthemecolor:hover{
-        background-color: #5d7aa0 !important;
+        background-color: rgb(74, 88, 105) !important;
     }
 
     .loginbtn{