diff --git a/app/css/custom.css b/app/css/custom.php similarity index 89% rename from app/css/custom.css rename to app/css/custom.php index c8e6324d..38415372 100644 --- a/app/css/custom.css +++ b/app/css/custom.php @@ -1,3 +1,9 @@ + + + /* Theme Name: RaspAP default Author: @billz @@ -47,9 +53,15 @@ body { } .card .card-header { - border-color: #d8224c; - background-color: #d8224c; + border-color: ; color: #fff; + background-color: ; +} + +.btn-primary { + color: ; + border-color: ; + background-color: #fff; } .card-footer { @@ -82,9 +94,7 @@ a.nav-link.active { } .btn-primary { - color: #d8224c; background-color: #fff; - border-color: #d8224c; } .btn-warning { @@ -92,8 +102,8 @@ a.nav-link.active { } .btn-primary:hover { - background-color: #c61931; - border-color: #c61931; + background-color: ; + border-color: ; } i.fa.fa-bars { diff --git a/app/img/raspAP-logo.svg b/app/img/raspAP-logo.php similarity index 80% rename from app/img/raspAP-logo.svg rename to app/img/raspAP-logo.php index 294fd2cb..c23399ab 100644 --- a/app/img/raspAP-logo.svg +++ b/app/img/raspAP-logo.php @@ -1,3 +1,8 @@ + + \ No newline at end of file + style="fill:;fill-opacity:1;fill-rule:nonzero;stroke:none" + d="m 0,0 c 101.94,0 185.667,-79.438 192.56,-179.664 l 27.962,-1.857 C 214.513,-65.087 117.899,27.791 0,27.791 c -5.31,0 -10.576,-0.2 -15.792,-0.571 l 1.84,-27.728 C -9.343,-0.177 -4.691,0 0,0" /> diff --git a/app/js/custom.js b/app/js/custom.js index 3fe9ef47..0a35d917 100644 --- a/app/js/custom.js +++ b/app/js/custom.js @@ -375,8 +375,9 @@ function getCookie(cname) { return (value != null) ? unescape(value[1]) : null; } +// Define themes var themes = { - "default": "custom.css", + "default": "custom.php", "hackernews" : "hackernews.css", "lightsout" : "lightsout.css", } diff --git a/app/js/huebee.js b/app/js/huebee.js new file mode 100644 index 00000000..895e1287 --- /dev/null +++ b/app/js/huebee.js @@ -0,0 +1,22 @@ +// Initialize Huebee color picker +var elem = document.querySelector('.color-input'); +var hueb = new Huebee( elem, { + notation: 'hex', + saturations: 2, + customColors: [ '#d8224c', '#dd4814', '#ea0', '#19f', '#333' ], + className: 'light-picker', + hue0: 210 +}); + +// Set custom color if defined +var color = getCookie('color'); +if (color == null || color == '') { + color = '#d8224c'; +} +hueb.setColor(color); + +// Change event +hueb.on( 'change', function( color, hue, sat, lum ) { + setCookie('color',color,90); +}) + diff --git a/config/config.php b/config/config.php index bfe464f6..86ad87bf 100755 --- a/config/config.php +++ b/config/config.php @@ -1,5 +1,6 @@ 0.5; + // cursor + var gridPosition = this.colorGrid[ color.toUpperCase() ]; + this.updateCursor( gridPosition ); + // set texts & backgrounds + this.setTexts(); + this.setBackgrounds(); + // event + if ( !wasSameColor ) { + this.emitEvent( 'change', [ color, swatch.hue, swatch.sat, swatch.lum ] ); + } +}; + +proto.setTexts = function() { + if ( !this.setTextElems ) { + return; + } + for ( var i = 0; i < this.setTextElems.length; i++ ) { + var elem = this.setTextElems[i]; + var property = elem.nodeName == 'INPUT' ? 'value' : 'textContent'; + elem[ property ] = this.color; + } +}; + +proto.setBackgrounds = function() { + if ( !this.setBGElems ) { + return; + } + var textColor = this.isLight ? '#222' : 'white'; + for ( var i = 0; i < this.setBGElems.length; i++ ) { + var elem = this.setBGElems[i]; + elem.style.backgroundColor = this.color; + elem.style.color = textColor; + } +}; + +proto.updateCursor = function( position ) { + if ( !this.isOpen ) { + return; + } + // show cursor if color is on the grid + var classMethod = position ? 'remove' : 'add'; + this.cursor.classList[ classMethod ]('is-hidden'); + + if ( !position ) { + return; + } + var gridSize = this.gridSize; + var offset = this.canvasOffset; + var border = this.cursorBorder; + this.cursor.style.left = position.x * gridSize + offset.x - border + 'px'; + this.cursor.style.top = position.y * gridSize + offset.y - border + 'px'; +}; + +// -------------------------- htmlInit -------------------------- // + +var console = window.console; + +function htmlInit() { + var elems = document.querySelectorAll('[data-huebee]'); + for ( var i = 0; i < elems.length; i++ ) { + var elem = elems[i]; + var attr = elem.getAttribute('data-huebee'); + var options; + try { + options = attr && JSON.parse( attr ); + } catch ( error ) { + // log error, do not initialize + if ( console ) { + console.error( 'Error parsing data-huebee on ' + elem.className + + ': ' + error ); + } + continue; + } + // initialize + new Huebee( elem, options ); + } +} + +var readyState = document.readyState; +if ( readyState == 'complete' || readyState == 'interactive' ) { + htmlInit(); +} else { + document.addEventListener( 'DOMContentLoaded', htmlInit ); +} + +// -------------------------- Huebee.data -------------------------- // + +Huebee.data = function( elem ) { + elem = getQueryElement( elem ); + var id = elem && elem.huebeeGUID; + return id && instances[ id ]; +}; + +// -------------------------- getSwatch -------------------------- // + +// proxy canvas used to check colors +var proxyCanvas = document.createElement('canvas'); +proxyCanvas.width = proxyCanvas.height = 1; +var proxyCtx = proxyCanvas.getContext('2d'); + +function getSwatch( color ) { + // check that color value is valid + proxyCtx.clearRect( 0, 0, 1, 1 ); + proxyCtx.fillStyle = '#010203'; // reset value + proxyCtx.fillStyle = color; + proxyCtx.fillRect( 0, 0, 1, 1 ); + var data = proxyCtx.getImageData( 0, 0, 1, 1 ).data; + // convert to array, imageData not array, #10 + data = [ data[0], data[1], data[2], data[3] ]; + if ( data.join(',') == '1,2,3,255' ) { + // invalid color + return; + } + // convert rgb to hsl + var hsl = rgb2hsl.apply( this, data ); + return { + color: color.trim(), + hue: hsl[0], + sat: hsl[1], + lum: hsl[2], + }; +} + +// -------------------------- utils -------------------------- // + +function extend( a, b ) { + for ( var prop in b ) { + a[ prop ] = b[ prop ]; + } + return a; +} + +function getQueryElement( elem ) { + if ( typeof elem == 'string' ) { + elem = document.querySelector( elem ); + } + return elem; +} + +function hsl2hex( h, s, l ) { + var rgb = hsl2rgb( h, s, l ); + return rgb2hex( rgb ); +} + +// thx jfsiii +// https://github.com/jfsiii/chromath/blob/master/src/static.js#L312 +/* eslint-disable max-statements-per-line */ +function hsl2rgb( h, s, l ) { + + var C = ( 1 - Math.abs( 2 * l - 1 ) ) * s; + var hp = h/60; + var X = C * ( 1 - Math.abs( hp % 2 - 1 ) ); + var rgb, m; + + switch ( Math.floor( hp ) ) { + case 0: rgb = [ C, X, 0 ]; break; + case 1: rgb = [ X, C, 0 ]; break; + case 2: rgb = [ 0, C, X ]; break; + case 3: rgb = [ 0, X, C ]; break; + case 4: rgb = [ X, 0, C ]; break; + case 5: rgb = [ C, 0, X ]; break; + default: rgb = [ 0, 0, 0 ]; + } + + m = l - ( C/2 ); + rgb = rgb.map( function( v ) { + return v + m; + } ); + + return rgb; +} + +function rgb2hsl( r, g, b ) { + r /= 255; g /= 255; b /= 255; + + var M = Math.max( r, g, b ); + var m = Math.min( r, g, b ); + var C = M - m; + var L = 0.5 * ( M + m ); + var S = C === 0 ? 0 : C / ( 1 - Math.abs( 2 * L - 1 ) ); + + var h; + if ( C === 0 ) { + h = 0; // spec'd as undefined, but usually set to 0 + } else if ( M === r ) { + h = ( ( g - b )/C ) % 6; + } else if ( M === g ) { + h = ( ( b - r )/C ) + 2; + } else if ( M === b ) { + h = ( ( r - g )/C ) + 4; + } + + var H = 60 * h; + + return [ H, parseFloat( S ), parseFloat( L ) ]; +} +/* eslint-enable max-statements-per-line */ + +function rgb2hex( rgb ) { + var hex = rgb.map( function( value ) { + value = Math.round( value * 255 ); + var hexNum = value.toString( 16 ).toUpperCase(); + // left pad 0 + hexNum = hexNum.length < 2 ? '0' + hexNum : hexNum; + return hexNum; + } ); + + return '#' + hex.join(''); +} + +// #123456 -> #135 +// grab first digit from hex +// not mathematically accurate, but makes for better palette +function roundHex( hex ) { + return '#' + hex[1] + hex[3] + hex[5]; +} + +// -------------------------- -------------------------- // + +return Huebee; + +} ) ); diff --git a/dist/huebee/huebee.pkgd.min.js b/dist/huebee/huebee.pkgd.min.js new file mode 100644 index 00000000..fdd8c3ac --- /dev/null +++ b/dist/huebee/huebee.pkgd.min.js @@ -0,0 +1,22 @@ +/*! + * Huebee PACKAGED v2.1.0 + * 1-click color picker + * MIT license + * https://huebee.buzz + * Copyright 2020 Metafizzy + */ +(function(t,e){if(typeof define=="function"&&define.amd){define("ev-emitter/ev-emitter",e)}else if(typeof module=="object"&&module.exports){module.exports=e()}else{t.EvEmitter=e()}})(typeof window!="undefined"?window:this,function(){"use strict";function t(){}var e=t.prototype;e.on=function(t,e){if(!t||!e){return}var i=this._events=this._events||{};var n=i[t]=i[t]||[];if(n.indexOf(e)==-1){n.push(e)}return this};e.once=function(t,e){if(!t||!e){return}this.on(t,e);var i=this._onceEvents=this._onceEvents||{};var n=i[t]=i[t]||{};n[e]=true;return this};e.off=function(t,e){var i=this._events&&this._events[t];if(!i||!i.length){return}var n=i.indexOf(e);if(n!=-1){i.splice(n,1)}return this};e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(!i||!i.length){return}i=i.slice(0);e=e||[];var n=this._onceEvents&&this._onceEvents[t];for(var o=0;o.5;var o=this.colorGrid[e.toUpperCase()];this.updateCursor(o);this.setTexts();this.setBackgrounds();if(!i){this.emitEvent("change",[e,t.hue,t.sat,t.lum])}};o.setTexts=function(){if(!this.setTextElems){return}for(var t=0;t'app/js/dashboardchart.js', 'defer'=>false); + $extraFooterScripts[] = array('src'=>'app/js/linkquality.js', 'defer'=>false); } diff --git a/includes/defaults.php b/includes/defaults.php index e1346112..42f95821 100755 --- a/includes/defaults.php +++ b/includes/defaults.php @@ -5,6 +5,7 @@ if (!defined('RASPI_CONFIG')) { } $defaults = [ + 'RASPI_BRAND_TEXT' => 'RaspAP', 'RASPI_VERSION' => '2.4.1', 'RASPI_CONFIG_NETWORKING' => RASPI_CONFIG.'/networking', 'RASPI_ADMIN_DETAILS' => RASPI_CONFIG.'/raspap.auth', diff --git a/includes/functions.php b/includes/functions.php index 55d1d1f7..4d299314 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -417,3 +417,38 @@ function formatDateAgo($datetime, $full = false) if (!$full) $string = array_slice($string, 0, 1); return $string ? implode(', ', $string) . ' ago' : 'just now'; } + +function getThemeOpt() +{ + if (!isset($_COOKIE['theme'])) { + $theme = "custom.php"; + } else { + $theme = $_COOKIE['theme']; + } + return 'app/css/'.htmlspecialchars($theme, ENT_QUOTES); +} + +function getColorOpt() +{ + if (!isset($_COOKIE['color'])) { + $color = "#d8224c"; + } else { + $color = $_COOKIE['color']; + } + return $color; +} +function getSidebarState() +{ + if ($_COOKIE['sidebarToggled'] == 'true' ) { + return"toggled"; + } +} + +// Returns bridged AP mode status +function getBridgedState() +{ + $arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini'); + // defaults to false + return $arrHostapdConf['BridgedEnable']; +} + diff --git a/includes/themes.php b/includes/themes.php index 7dde1824..58afe68a 100755 --- a/includes/themes.php +++ b/includes/themes.php @@ -3,7 +3,7 @@ * * */ -function DisplayThemeConfig() +function DisplayThemeConfig(&$extraFooterScripts) { $themes = [ "default" => "RaspAP (default)", @@ -11,11 +11,14 @@ function DisplayThemeConfig() "lightsout" => "Lights Out" ]; $themeFiles = [ - "default" => "custom.css", + "default" => "custom.php", "hackernews" => "hackernews.css", "lightsout" => "lightsout.css" ]; $selectedTheme = array_search($_COOKIE['theme'], $themeFiles); echo renderTemplate("themes", compact("themes", "selectedTheme")); + + $extraFooterScripts[] = array('src'=>'dist/huebee/huebee.pkgd.min.js', 'defer'=>false); + $extraFooterScripts[] = array('src'=>'app/js/huebee.js', 'defer'=>false); } diff --git a/index.php b/index.php index d6682b8e..80106b2d 100755 --- a/index.php +++ b/index.php @@ -45,21 +45,9 @@ require_once 'includes/torproxy.php'; $output = $return = 0; $page = $_GET['page']; -if (!isset($_COOKIE['theme'])) { - $theme = "custom.css"; -} else { - $theme = $_COOKIE['theme']; -} -$theme_url = 'app/css/'.htmlspecialchars($theme, ENT_QUOTES); - -if ($_COOKIE['sidebarToggled'] == 'true' ) { - $toggleState = "toggled"; -} - -// Get Bridged AP mode status -$arrHostapdConf = parse_ini_file('/etc/raspap/hostapd.ini'); -// defaults to false -$bridgedEnabled = $arrHostapdConf['BridgedEnable']; +$theme_url = getThemeOpt(); +$toggleState = getSidebarState(); +$bridgedEnabled = getBridgedState(); ?> @@ -82,6 +70,9 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable']; + + + @@ -112,13 +103,13 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];