diff --git a/access.lua b/access.lua index f40e0de..f47ef87 100644 --- a/access.lua +++ b/access.lua @@ -305,24 +305,39 @@ end -- `/yunohost/sso/assets/js/ynhpanel.js` file. -- +function scandir(directory, callback) + local i, popen = 0, io.popen + -- use find (and not ls) to list only files recursively and with their full path relative to the asked directory + local pfile = popen('cd "'..directory..'" && find * -type f') + for filename in pfile:lines() do + i = i + 1 + callback(filename) + end + pfile:close() +end + +function serveAsset(shortcut, full) + if string.match(ngx.var.uri, "^"..shortcut.."$") then + hlp.serve("/yunohost/sso/assets/"..full) + end +end + +function serveThemeFile(filename) + serveAsset("/ynhtheme/"..filename, "themes/"..conf.theme.."/"..filename) +end + if hlp.is_logged_in() then - if string.match(ngx.var.uri, "^/ynhpanel.js$") then - hlp.serve("/yunohost/sso/assets/js/ynhpanel.js") - end - if string.match(ngx.var.uri, "^/ynhpanel.css$") then - hlp.serve("/yunohost/sso/assets/css/ynhpanel.css") - end - if string.match(ngx.var.uri, "^/ynhpanel.json$") then - hlp.serve("/yunohost/sso/assets/js/ynhpanel.json") - end + -- serve ynhpanel files + serveAsset("/ynhpanel.js", "js/ynhpanel.js") + serveAsset("/ynhpanel.json", "js/ynhpanel.json") + serveAsset("/ynhpanel.css", "css/ynhpanel.css") + -- serve theme's files -- TODO : don't forget to open a PR to enable access to those -- in yunohost_panel.conf.inc - if string.match(ngx.var.uri, "^/ynhpanel_custom.js$") then - hlp.serve("/yunohost/sso/assets/themes/"..conf.theme.."/custom.js") - end - if string.match(ngx.var.uri, "^/ynhpanel_custom.css$") then - hlp.serve("/yunohost/sso/assets/themes/"..conf.theme.."/custom.css") - end + -- FIXME? I think it would be better here not to use an absolute path + -- but I didn't succeed to figure out where is the current location of the script + -- if you call it from "portal/assets/themes/" the ls fails + scandir("/usr/share/ssowat/portal/assets/themes/"..conf.theme, serveThemeFile) -- If user has no access to this URL, redirect him to the portal if not hlp.has_access() then diff --git a/portal/assets/css/ynh-style.css b/portal/assets/css/ynh-style.css index bed9c46..bb78fd5 100644 --- a/portal/assets/css/ynh-style.css +++ b/portal/assets/css/ynh-style.css @@ -70,7 +70,6 @@ html { body { background: #41444f; font-family: 'source_sans_proregular'; - overflow-y: scroll; font-size: 1em; line-height:1.5; margin: 0; @@ -128,29 +127,24 @@ img { /* Logo */ .logo { - text-align: center; - margin-bottom: 0; opacity: 0.7; -} - -.logo img { margin-top: 4%; - width: 10em; + width: 100%; + height: 10em; + background-image: url("../img/logo-ynh-white.svg"); + background-repeat: no-repeat; + background-position: center 100%; } .logged .logo { position: fixed; + width: 10em; bottom: 20px; right: 20px; z-index: 0; opacity: 0.7; + background-position: center center; } - .logged .logo img { - margin-top: 0; - width: 2.5em; - padding: 0.3em; - border-radius: 5px; - } .ynh-panel-active .logo { display: none; diff --git a/portal/assets/js/ynhpanel.js b/portal/assets/js/ynhpanel.js index a4446d9..3369950 100644 --- a/portal/assets/js/ynhpanel.js +++ b/portal/assets/js/ynhpanel.js @@ -266,12 +266,12 @@ function init_portal_button_and_overlay() var customStyle = document.createElement("link"); customStyle.setAttribute("rel", "stylesheet"); customStyle.setAttribute("type", "text/css"); - customStyle.setAttribute("href", '/ynhpanel_custom.css'); + customStyle.setAttribute("href", '/ynhtheme/custom.css'); document.getElementsByTagName("head")[0].insertBefore(customStyle, null); // Inject custom / theme js var customScript = document.createElement("script"); customScript.setAttribute("type", "text/javascript"); - customScript.setAttribute("src", '/ynhpanel_custom.js'); + customScript.setAttribute("src", '/ynhtheme/custom.js'); document.getElementsByTagName("head")[0].insertBefore(customScript, null); // Bind portal button diff --git a/portal/assets/themes/clouds/background.jpg b/portal/assets/themes/clouds/background.jpg new file mode 100644 index 0000000..32a876c Binary files /dev/null and b/portal/assets/themes/clouds/background.jpg differ diff --git a/portal/assets/themes/clouds/custom.css b/portal/assets/themes/clouds/custom.css new file mode 100644 index 0000000..574fd7f --- /dev/null +++ b/portal/assets/themes/clouds/custom.css @@ -0,0 +1,68 @@ +/* Make page texts black */ +.user-container h2, +.user-container small, +.user-container .user-mail, +.user-container .user-mail, +.overlay .footer a, +a.app-tile, +#ynh-logout { + color: black !important; +} + +/* The layout is slightly different, the apps are scollable but not the headers and footers */ +html { + height:100%; + } +body { + background-image: url("background.jpg"); + background-repeat: no-repeat; + background-size: cover; + width: 100%; + height: 100%; + overflow: hidden; +} + +.overlay { + position: absolute; + width: 100%; + height: 100%; + z-index: 10; +} + +.overlay #apps { + max-height: 70%; + overflow: auto; + +} + +.overlay .footer { + position: absolute; + bottom: 0; +} + +.listing-apps { + padding-top: 10px; +} + +/* Apps colors */ +.app-tile { + background-color: rgba(255, 255, 255, 0.5) !important; +} + +.app-tile:hover:after, +.app-tile:focus:after, +.app-tile:hover:before, +.app-tile:focus:before { + background: rgba(255, 255, 255, 0.5) !important; +} + +/* Use custom ynh logo white (there's a white one in assets, but let's not depend on it) */ +#logo { + margin-top: 0px; + z-index: 10; + background-image: url("/ynhtheme/ynhlogo.svg"); +} + +#ynh-overlay-switch { + background-image: url("/ynhtheme/ynhlogo.svg"); +} diff --git a/portal/assets/themes/clouds/custom.js b/portal/assets/themes/clouds/custom.js new file mode 100644 index 0000000..e69de29 diff --git a/portal/assets/themes/clouds/ynhlogo.svg b/portal/assets/themes/clouds/ynhlogo.svg new file mode 100644 index 0000000..f960fd3 --- /dev/null +++ b/portal/assets/themes/clouds/ynhlogo.svg @@ -0,0 +1,34 @@ + + + +]> + + + + + + + + + + + diff --git a/portal/assets/themes/random/custom.css b/portal/assets/themes/random/custom.css new file mode 100644 index 0000000..b9f3ad9 --- /dev/null +++ b/portal/assets/themes/random/custom.css @@ -0,0 +1,6 @@ +.app-tile:focus:after, +.app-tile:hover:after, +.app-tile:focus:before, +.app-tile:hover:before { + background:var(--background-color, red) !important; +} diff --git a/portal/assets/themes/random/custom.js b/portal/assets/themes/random/custom.js new file mode 100644 index 0000000..232ec86 --- /dev/null +++ b/portal/assets/themes/random/custom.js @@ -0,0 +1,128 @@ + +var ynhLib = { + + // + // RANDOMIZATION UTILITIES + + random: { + integer: function(min, max){ + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + number: function (min, max) { + return Math.random() * (max - min) + min; + }, + entry: function (array) { + return array[ynhLib.random.integer(0, array.length-1)]; + }, + rgbInteger: function () { return ynhLib.random.integer(0,255); }, + // generate random rgba color + color: function (transparency) { + // transparency + var transparency; + if (transparency === null || transparency === false) transparency = 1 + else if (typeof transparency == "number") transparency = transparency + else transparency = ynhLib.random.number (0,1); + // random color + return [ ynhLib.random.rgbInteger(), ynhLib.random.rgbInteger(), ynhLib.random.rgbInteger(), transparency ]; + }, + }, + + // + // COLOR HANDLING UTILITIES + + color: { + + // rgbColor <[number, number, number(, number)]> + toCSS: function (rgbColor) { + // rgba color + if (rgbColor.length == 4) return "rgba("+ rgbColor[0] +","+ rgbColor[1] +","+ rgbColor[2] +","+ rgbColor[3] +")" + // rgb color + else return "rgb("+ rgbColor[0] +","+ rgbColor[1] +","+ rgbColor[2] +")"; + }, + + // Luminosity function adpated from color library: https://github.com/Qix-/color + // rgbColor <[number, number, number]> + luminosity: function (rgbColor) { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + + var lum = []; + for (var i = 0; i < rgbColor.length; i++) { + var chan = rgbColor[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + // color <[number, number, number]> + getContrastColor: function (color) { + var light = "white", dark = "black"; + return ynhLib.color.luminosity(color) > 0.5 ? dark : light; + }, + + }, + + // + // UTILITIES + + queue: function (queueTo, queue) { + if (typeof queueTo != 'function') var fullQueue = queue + else if (typeof queue != 'function') var fullQueue = queueTo + else var fullQueue = function () { + queueTo.apply(this, arguments); + queue.apply(this, arguments); + }; + return fullQueue; + }, + + onWindowLoad: function(func){ + window.onload = ynhLib.queue(window.onload, func); + }, + + // + // SET APP ICON STYLE + + set_app_tile_style: function (el) { + var appColor = ynhLib.random.color(); + var appContrastColor = ynhLib.color.getContrastColor(appColor); + var style = 'background-color:'+ ynhLib.color.toCSS(appColor) +' !important; color:'+ appContrastColor +' !important; --background-color:'+ ynhLib.color.toCSS(appColor); + el.setAttribute("style", style); + }, + + // + // LOGO CUSTOMIZATION + + logo: { + + availableColors: ["cyan", "fushia", "green", "orange", "pink", "purple", "red", "yellow"], + makeLogoStyleString: function () { + return 'background-image: url("/ynhtheme/logo/'+ ynhLib.random.entry(ynhLib.logo.availableColors) +'.svg")'; + }, + + }, + + // ¬ + // + +}; + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +ynhLib.onWindowLoad(function () { + + // set apps colors + Array.each(document.getElementsByClassName("app-tile"), ynhLib.set_app_tile_style); + + // log color css string + var chosenLogoStyleString = ynhLib.logo.makeLogoStyleString(); + + // set logo color in portal + var ynhLogo = document.getElementById("logo"); + if (ynhLogo) ynhLogo.setAttribute("style", chosenLogoStyleString); + + // set overlay switch color in apps (NOTE: this is not always working, there is probably a problem of loading order) + var overlaySwitch = document.getElementById("ynh-overlay-switch"); + if (overlaySwitch) overlaySwitch.setAttribute("style", chosenLogoStyleString); + +}); diff --git a/portal/assets/themes/random/logo/cyan.svg b/portal/assets/themes/random/logo/cyan.svg new file mode 100644 index 0000000..5c0ebee --- /dev/null +++ b/portal/assets/themes/random/logo/cyan.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/fushia.svg b/portal/assets/themes/random/logo/fushia.svg new file mode 100644 index 0000000..6614e8f --- /dev/null +++ b/portal/assets/themes/random/logo/fushia.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/green.svg b/portal/assets/themes/random/logo/green.svg new file mode 100644 index 0000000..8f72257 --- /dev/null +++ b/portal/assets/themes/random/logo/green.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/orange.svg b/portal/assets/themes/random/logo/orange.svg new file mode 100644 index 0000000..eb3d421 --- /dev/null +++ b/portal/assets/themes/random/logo/orange.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/pink.svg b/portal/assets/themes/random/logo/pink.svg new file mode 100644 index 0000000..d2306f0 --- /dev/null +++ b/portal/assets/themes/random/logo/pink.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/purple.svg b/portal/assets/themes/random/logo/purple.svg new file mode 100644 index 0000000..9a7cfd4 --- /dev/null +++ b/portal/assets/themes/random/logo/purple.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/red.svg b/portal/assets/themes/random/logo/red.svg new file mode 100644 index 0000000..25c7834 --- /dev/null +++ b/portal/assets/themes/random/logo/red.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/assets/themes/random/logo/yellow.svg b/portal/assets/themes/random/logo/yellow.svg new file mode 100644 index 0000000..74c1172 --- /dev/null +++ b/portal/assets/themes/random/logo/yellow.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/portal/header.ms b/portal/header.ms index 6ffd6a7..e426a24 100644 --- a/portal/header.ms +++ b/portal/header.ms @@ -36,7 +36,7 @@