| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 | <html>    <head>        <title locale="title/title">File Share</title>        <link rel="stylesheet" href="../../script/semantic/semantic.min.css">        <script src="../../script/jquery.min.js"></script>        <script src="../../script/semantic/semantic.min.js"></script>        <script src="../../script/ao_module.js"></script>        <script type="text/javascript" src="../../script/applocale.js"></script>        <script type="text/javascript" src="../../script/qrcode.min.js"></script>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">        <style>            body:not(.darkTheme){                background: rgba(255,255,255,01) !important;            }            body.darkTheme{                background-color: #242330 !important;            }            .sub.header.darkTheme{                color: rgba(255, 255, 255, 0.623) !important;            }            .darkTheme:not(a){                color: #eeeeee;            }            .yellow.message.darkTheme{                box-shadow: none !important;                border: 0px solid transparent !important;                background-color: #5e550e !important;            }            .dropDown.darkTheme:not(.icon){                background-color: #413f57 !important;                border: 1px solid white;            }            .dropdown.darkThem  .ui.label{                color: rgb(175, 175, 175);                background-color: #2f2d3d !important;            }            .dropdown.darkThem  .ui.label:hover{                color: white;                opacity: 0.8;            }        </style>    </head>    <body>        <div id="main" class="ui stackable grid">            <div class="eight wide column">                <div style="width: 100%;" class="qrcode" align="center">                    <div style="display: block; margin-left: auto; margin-right: auto;" align="center">                        <div id="qrcode" style="border: 10px solid white; background-color: white;">                            <h1><br><i class="ui loading spinner icon"></i><br></h1>                        </div>                    </div>                    <div style="width: 80%; text-align: center;">                    <a id="sharelink" href="" target="_blank" style="margin-top:8px; font-size: 120%; padding-left: 20px; padding-right: 20px; word-break: break-all; overflow-wrap: anywhere;"></a>                    </div>                                    </div>            </div>            <div id="shareSettingOptions" class="eight wide column" style="padding-left: 12px; display:none;">                <div class="ui header whiteTheme">                    <span locale="share/setting/title">Share Settings</span>                    <div class="sub header whiteTheme" locale="share/setting/subtitle">Change who can see this file</div>                </div>                <div id="shareSettingForm" class="ui form">                    <div class="field">                        <label><p class="whiteTheme" locale="share/setting/options">Visable options:</p></label>                        <div class="ui checkboxes">                            <div class="ui radio checkbox">                                <input id="anyone" type="radio" class="shareoption" name="shareopt" value="anyone" onchange="updateSharePermission(this);">                                <label for="anyone">                                    <div class="ui header">                                        <div class="content whiteTheme">                                            <i class="globe icon"></i> <span locale="share/setting/anyoneWithLink">Anyone with the link</span>                                            <div class="sub header whiteTheme" locale="share/setting/anyoneWithLink/desc">Anyone who has the link can access this file</div>                                        </div>                                    </div>                                </label>                            </div>                            <br><br>                            <div class="ui radio checkbox">                                <input id="signedin" type="radio" class="shareoption" value="signedin" name="shareopt" onchange="updateSharePermission(this);">                                <label for="signedin">                                    <div class="ui header">                                        <div class="content whiteTheme">                                            <i class="user circle outline icon"></i> <span locale="share/setting/anyoneSignedIn">Anyone signed in</span>                                            <div class="sub header whiteTheme" locale="share/setting/anyoneSignedIn/desc">Anyone who has signed in can access this file</div>                                        </div>                                    </div>                                </label>                            </div>                            <br><br>                            <div class="ui radio checkbox">                                <input id="samegroup" type="radio" class="shareoption" value="samegroup" name="shareopt" onchange="updateSharePermission(this);">                                <label for="samegroup">                                    <div class="ui header">                                        <div class="content whiteTheme">                                            <i class="users icon"></i> <span locale="share/setting/sameGroup">Users in the same group</span>                                            <div class="sub header whiteTheme" locale="share/setting/sameGroup/desc">Anyone who is in the same group as you do</div>                                        </div>                                    </div>                                </label>                            </div>                            <br><br>                            <div class="ui accordion" id="advanceShare">                                <div class="title">                                    <i class="dropdown icon"></i>                                    <span locale="share/setting/advance/title">Advance Share Options</span>                                </div>                                <div class="content">                                    <div class="ui radio checkbox">                                        <input id="users" type="radio" class="shareoption" value="users" name="shareopt" onchange="updateSharePermission(this);">                                        <label for="users">                                            <div class="ui header">                                                <div class="content whiteTheme">                                                    <i class="clipboard check icon"></i> <span locale="share/setting/advance/users">Selected Users</span>                                                    <div class="sub header whiteTheme" locale="share/setting/advance/usersDesc">Selected users with matching user name</div>                                                </div>                                            </div>                                        </label>                                    </div>                                    <div id="userselector">                                        <p style="margin-top: 1em;" locale="share/setting/advance/usersInstruct"">Select target users from the list below</p>                                        <select id="targetUsersList" class="ui fluid search dropdown" multiple="">                                            <option value="">Users</option>                                        </select>                                        <div id="noUserWarning" class="ui yellow message"  style="display:none;">                                            <i class="caret up icon"></i> <span locale="share/setting/advance/addUserToSave">Add at least one target share user to save changes</span>                                        </div>                                    </div>                                    <div class="ui radio checkbox" style="margin-top: 1em;">                                        <input id="groups" type="radio" class="shareoption" value="groups" name="shareopt" onchange="updateSharePermission(this);">                                        <label for="groups">                                            <div class="ui header">                                                <div class="content whiteTheme">                                                    <i class="sitemap icon"></i> <span locale="share/setting/advance/groups">Selected Groups</span>                                                    <div class="sub header whiteTheme" locale="share/setting/advance/groupsDesc">All the users that has access to any one of the selected group(s)</div>                                                </div>                                            </div>                                        </label>                                    </div>                                    <div id="groupselector">                                        <p style="margin-top: 1em;" locale="share/setting/advance/groupsInstruct">Select target groups from the list below</p>                                        <select id="targetGroupList" class="ui fluid search dropdown" multiple="">                                            <option value="">Groups</option>                                        </select>                                        <div id="noGroupWarning" class="ui yellow message" style="display:none;">                                            <i class="caret up icon"></i> <span locale="share/setting/advance/addGroupToSave">Add at least one target share group to save changes</span>                                        </div>                                    </div>                                </div>                            </div>                        <br><br>                        <div id="udpateNotification" style="display:none; position: fixed; bottom: 1em; right: 1em;" class="ui green inverted segment">                                <i class=" checkmark icon"></i> <span locale="share/setting/updated">Share Setting Updated</span>                        </div>                        </div>                    </div>                </div>            </div>        </div>        <div class="ui divider actionButton"></div>        <div class="actionButton" style="width: 100%; padding-right: 12px;" align="right">            <div class="ui button popupbuttons whiteTheme allowHover" onclick="copyLinkToClipboard(this)">                <i class="copy icon"></i> <span locale="button/copy">Copy</span>            </div>             <div id="sharingRemoveBtn" class="ui red button popupbuttons negative whiteTheme allowHover" onclick="removeSharing()">                <i class="remove icon"></i> <span locale="button/remove">Remove</span>            </div>         </div>        <script>            /*                Usage: Pass in file descriptor to start share a file                var fd = encodeURIComponent(JSON.stringify({                        filename: "test.txt",                        filepath: "user:/Desktop/test.txt"                    })                );                window.open("file_share.html#" + fd);                                If you want to preset a file sharing mode (aka your module handle the share mode picking),                Pass in with the "shareMode" paramter. Example fd as follow:                {                    filename: "test.txt",                    filepath: "user:/Desktop/test.txt",                    shareMode: "signedin"                }                To remove a share, pass in "remove" for the share mode                Supported Share Mode keywords {anyone/signedin/samegroup/remove}                Other supported flags                {                    QRCode: {true/false} //Show or Hide the QR Code and link                    ActionButtons: {true/false} //Show or Hide the action button on the bottom                }            */            var sharCurrentEditingUUID = "";            var shareingFileData = {};            var darkTheme = false;            var initialized = false;            var fileSharingURL = "";            var relpath = "../../";                        function applyDarkThemeMode(){                $(".whiteTheme").removeClass("whiteTheme").addClass("darkTheme");                $("*:not(button)").addClass("darkTheme");                $("body").addClass("darkTheme");                $(".ui.button").addClass("inverted");                darkTheme = true;            }            function removeQRCodeInDarkTheme(){                if (darkTheme){                    $("#qrcode").css({                        "border":"0px solid transparent",                        "background-color":"#242330",                    })                }            }            if ($(parent) && $(parent.document).find("body").hasClass("darkTheme")){                //Switch to darkTheme mode immediately                applyDarkThemeMode();            }               PageReady();            function PageReady(){                if (initialized){                    return;                }                //Load User & Group List                $.get(relpath + "../system/users/list", function(data){                    var groups = {};                    $("#targetUsersList").html(`<option value="">Users</option>`);                    data.forEach(user => {                        $("#targetUsersList").append(`<option value="${user[0]}">${user[0]}</option>`);                        var userGroups = user[1];                        userGroups.forEach(thisGroup => {                            groups[thisGroup] = true;                        });                    });                    $("#targetGroupList").html(`<option value="">Groups</option>`);                    for (var [key, value] of Object.entries(groups)) {                        $("#targetGroupList").append(`<option value="${key}">${key}</option>`);                    }                    //Initiate the share details                    initFileDetails(shareingFileData, function(shareUUID){                        //Set the mode of share if it is defined                        if (shareingFileData.shareMode !== undefined && shareingFileData.shareMode == "remove"){                            //Remove the share UUID                            removeSharing();                            return;                        }                        if (shareingFileData.shareMode !== undefined){                            //As the share mode is defined by the caller, hide the setting interface                            $("#shareSettingOptions").hide();                            $("#sharelink").parent().css({                                "width": "100%",                                "text-align": "left",                            });                            $.ajax({                                url: relpath + "../system/file_system/share/edit",                                data: {uuid: sharCurrentEditingUUID, mode: shareingFileData.shareMode},                                success: function(data){                                    if (data.error !== undefined){                                        alert(data.error);                                        return;                                    }                                                                        //Update the checkbox                                    $(".shareoption").each(function(){                                        if ($(this)[0].value != shareingFileData.shareMode){                                            $(this)[0].checked = false;                                        }else{                                            $(this)[0].checked = true;                                        }                                                                        });                                }                            });                        }else{                            //Default: show the setting to allow user adjustment                            $("#main").css({                                "margin-top":"0em",                                "padding": "4px"                            });                            $("#shareSettingOptions").show();                        }                        $(".accordion").accordion();                    });                });                //Load theme style                $.get(relpath + "../system/file_system/preference?key=file_explorer/theme",function(data){                    if (data == "darkTheme"){                        applyDarkThemeMode();                    }                });                initialized = true;                //Do localization                applocale.init(relpath + "../SystemAO/locale/file_share.json", function(){                    applocale.translate();                });                $(".checkbox").checkbox();                $(".dropdown").dropdown();                var inputFile = ao_module_loadInputFiles();                if (inputFile == null){                    //No file selected                    $(".shareoption").parent().addClass("disabled");                    $("#qrcode").html(`<h1>No File</h1>`);                    $("#sharelink").text(``);                    $("#sharingRemoveBtn").addClass("disabled");                    return                }                //Make sure one file is choicen each time                inputFile = inputFile[0];                 console.log("inputFile", inputFile);                shareingFileData = inputFile;                //Filter out the nessary display flags                if (shareingFileData.QRCode !== undefined && shareingFileData.QRCode == false){                    $(".qrcode").hide();                    $("#shareSettingOptions").attr("class", "sixteen wide column");                    $("#shareSettingOptions").css("padding", "1em");                    $(".eight.wide").hide();                }                if (shareingFileData.ActionButtons !== undefined && shareingFileData.ActionButtons == false){                    $(".actionButton").hide();                }            }            function initFileDetails(shareingFileData, callback=undefined){                $.ajax({                    url: relpath + "../system/file_system/share/new",                    data: {path: shareingFileData.filepath},                    success: function(data){                        if (data.error !== undefined){                            alert(data.error);                        }else{                            console.log(data);                            updateShareLinkInfo(data.UUID);                            sharCurrentEditingUUID = data.UUID;                            $(".shareoption").each(function(){                                if ($(this)[0].value != data.Permission){                                    $(this)[0].checked = false;                                }else{                                    $(this)[0].checked = true;                                    if (data.Permission == "users"){                                        $("#advanceShare").accordion("open", 0);                                        $("#targetUsersList").dropdown("set selected", data.Accessibles);                                        $("#targetUsersList").parent().removeClass("disabled");                                        $("#targetGroupList").parent().addClass("disabled");                                    }else if (data.Permission == "groups"){                                        $("#advanceShare").accordion("open", 0);                                        $("#targetGroupList").dropdown("set selected", data.Accessibles);                                        $("#targetUsersList").parent().addClass("disabled");                                        $("#targetGroupList").parent().removeClass("disabled");                                    }else{                                        $("#targetGroupList").parent().addClass("disabled");                                        $("#targetUsersList").parent().addClass("disabled");                                    }                                }                                                           });                                                      $("#targetUsersList").on("change", function(evt){                                updateSharePermissionByType("users");                            });                            $("#targetGroupList").on("change", function(evt){                                updateSharePermissionByType("groups");                            });                                                                       //If the file is from desktop, set share icon                            if (ao_module_virtualDesktop == true){                                var fileDir = shareingFileData.filepath.split("/");                                fileDir.pop();                                fileDir = fileDir.join("/");                                if (fileDir == "user:/Desktop"){                                    //Remove share icon                                    parent.setFileShareIndicator(shareingFileData.filename);                                }                            }                            if (callback != undefined){                                callback(data.UUID)                            }                        }                    }                });            }            function removeSharing(){                if (sharCurrentEditingUUID == ""){                    return                }                //The target file to remove                $.ajax({                    url: relpath + "../system/file_system/share/delete",                    data: {path: shareingFileData.filepath},                    success: function(data){                        if (data.error !== undefined){                            alert(data.error);                        }else{                            //Removed!                            $(".button").addClass('disabled');                            $(".checkbox").addClass("disabled");                            $("#sharelink").text("");                            $("#sharelink").attr("href", "#");                            $("#qrcode").html(`<br><br><h1><i class="green checkmark icon"></i> ${applocale.getString("message/removed", "Share Removed")}</h1>`);                            removeQRCodeInDarkTheme();                            //If the file is located on desktop and it is web desktop mode                            if (ao_module_virtualDesktop == true){                                var fileDir = shareingFileData.filepath.split("/");                                fileDir.pop();                                fileDir = fileDir.join("/");                                if (fileDir == "user:/Desktop"){                                    //Remove share icon                                    parent.removeFileShareIndicator(shareingFileData.filename);                                }                            }                        }                    }                });            }            function updateSharePermission(object){                var newPermission = $(object).attr('value');                updateSharePermissionByType(newPermission);            }               function updateSharePermissionByType(newPermission){                if (newPermission == "users"){                    //Build the user list                    $("#targetUsersList").parent().removeClass("disabled");                    $("#targetGroupList").parent().addClass("disabled");                    var selectedUsers = $("#targetUsersList").val();                    $("#noGroupWarning").slideUp("fast");                    if (selectedUsers.length == 0){                        //Show tips message                        $("#noUserWarning").slideDown("fast");                        return;                    }else{                        $("#noUserWarning").slideUp("fast");                    }                    //Rewrite it to permission handling description                    newPermission = "users:" + selectedUsers.join(",");                }else if (newPermission == "groups"){                    //Build the group list                    $("#targetUsersList").parent().addClass("disabled");                    $("#targetGroupList").parent().removeClass("disabled");                    var selectedGroups = $("#targetGroupList").val();                    $("#noUserWarning").slideUp("fast");                    if (selectedGroups.length == 0){                        //Show tips message                        $("#noGroupWarning").slideDown("fast");                        return;                    }else{                        $("#noGroupWarning").slideUp("fast");                    }                    //Rewrite it to permission handling description                    newPermission = "groups:" + selectedGroups.join(",");                }                $.ajax({                    url: relpath + "../system/file_system/share/edit",                    data: {uuid: sharCurrentEditingUUID, mode: newPermission},                    success: function(data){                        if (data.error !== undefined){                            alert(data.error);                            return;                        }                        $("#udpateNotification").stop().finish().fadeIn("fast").delay(3000).fadeOut("fast");                    }                });            }            function updateShareLinkInfo(uuid){                $("#qrcode").html("");                let protocol = "https://";                if (location.protocol !== 'https:') {                    protocol = "http://";                }                var port = ":" + window.location.port;                if (window.location.port == ""){                    port = "";                }                var shareURL = protocol + window.location.hostname + port + "/share/" + uuid;                sharCurrentEditingUUID = uuid;                fileSharingURL = shareURL;                new QRCode(document.getElementById("qrcode"), shareURL);                $("#sharelink").text(shareURL);                $("#sharelink").attr("href", shareURL)            }            /*                Dynamic Script Loader                This is a really experimental implementation of importing a script from anywhere                under the ArozOS web root. This section of code must be written in plain JS to make sure                it works without jQuery and other libraries.                This function try to load jQuery and ao_module from the script folder.                Also loading the semantic js and the css main body            */           /*            //The possible location for desktop.system, standard webapp module, SystemAO interfaces and iui sub-interfaces            let possibleLocations = ["script/", "../script/", "../../script/", "../../../script/"];            let loopCount = Math.min(possibleLocations.length, JSON.parse(JSON.stringify(window.location.toString())).split("/").length - 3);            function tryLoad(relpath, filename, successCallback=undefined){                var request = new XMLHttpRequest();                  request.open('GET', relpath + filename, true);                request.onreadystatechange = function(){                    if (request.readyState === 4){                        if (request.status == 200 || request.status == 304) {                              if (typeof(successCallback) != "undefined"){                                successCallback(relpath, filename);                            }                        }                    }                };                request.send();            }            function injectOtherJavaScriptLibrary(relpath){                //Check if ao_module is loaded                if (typeof(ao_module_virtualDesktop) == "undefined"){                    var script = document.createElement('script');                    script.setAttribute('src', relpath + "ao_module.js");                    document.getElementsByTagName('head')[0].appendChild(script);                }else{                    //This routine already run                    return;                }                //Inject QR Code library                var script = document.createElement('script');                script.setAttribute('src', relpath + "qrcode.min.js");                document.getElementsByTagName('head')[0].appendChild(script);                //Inject applocale                script = document.createElement('script');                script.setAttribute('src', relpath + "applocale.js");                document.getElementsByTagName('head')[0].appendChild(script);                //Inject semmantic css and js anyway                var head  = document.getElementsByTagName('head')[0];                var link  = document.createElement('link');                link.id   = "semantic";                link.rel  = 'stylesheet';                link.type = 'text/css';                link.href = relpath + 'semantic/semantic.min.css';                link.media = 'all';                head.appendChild(link);                var script = document.createElement('script');                script.setAttribute('src', relpath + "semantic/semantic.min.js");                document.getElementsByTagName('head')[0].appendChild(script);                setTimeout(function(){                    PageReady();                }, 1000);            }            //Load jQuery first            if (typeof(window.jQuery) == "undefined"){                //jQuery not found. Load it                for (var i = 0; i < loopCount; i++){                    var relpath = possibleLocations[i];                    tryLoad(relpath, "jquery.min.js", function(relpath, filename){                        //Generate the jquery script element                        var script = document.createElement('script');                                                script.setAttribute('src', relpath + filename);                        document.getElementsByTagName('head')[0].appendChild(script);                                                doAfterJqueryLoaded(function(){                            injectOtherJavaScriptLibrary(relpath);                        });                                            });                }            }else{                //jQuery exists. Load ao_module                injectOtherJavaScriptLibrary();            }            function doAfterJqueryLoaded(callback){                setTimeout(function(){                    //Wait until it is loaded                    if (typeof(window.jQuery) == "undefined"){                        doAfterJqueryLoaded(callback);                        return                    }else{                        callback();                    }                }), 300;            }            */            function copyLinkToClipboard(btn){                //Copy text                const area = document.createElement('textarea');                document.body.appendChild(area);                area.value = fileSharingURL;                area.select();                document.execCommand('copy');                document.body.removeChild(area);                //Do visual feedback                let oldContent = $(btn).html();                $(btn).html(`<i class="green checkmark icon"></i> ${applocale.getString("button/copied","Copied!")}`);                setTimeout(function(){                    $(btn).html(oldContent);                }, 3000);            }        </script>    </body></html>
 |