Changed color picker library and moved color logic to front end
Since the old library was GPLv3 i changed the color picker to tiny-color-picker which is MIT. Also extracted the styles to a shared view and move color calculation logic to javascript side.
Showing
10 changed files
with
56 additions
and
99 deletions
| 1 | -<?php | 1 | +<?php namespace BookStack\Http\Controllers; |
| 2 | - | ||
| 3 | -namespace BookStack\Http\Controllers; | ||
| 4 | 2 | ||
| 5 | use Illuminate\Http\Request; | 3 | use Illuminate\Http\Request; |
| 6 | 4 | ||
| 7 | use BookStack\Http\Requests; | 5 | use BookStack\Http\Requests; |
| 8 | -use BookStack\Http\Controllers\Controller; | ||
| 9 | use Setting; | 6 | use Setting; |
| 10 | 7 | ||
| 11 | class SettingController extends Controller | 8 | class SettingController extends Controller |
| 12 | { | 9 | { |
| 13 | /** | 10 | /** |
| 14 | * Display a listing of the settings. | 11 | * Display a listing of the settings. |
| 15 | - * | ||
| 16 | * @return Response | 12 | * @return Response |
| 17 | */ | 13 | */ |
| 18 | public function index() | 14 | public function index() |
| ... | @@ -22,11 +18,9 @@ class SettingController extends Controller | ... | @@ -22,11 +18,9 @@ class SettingController extends Controller |
| 22 | return view('settings/index'); | 18 | return view('settings/index'); |
| 23 | } | 19 | } |
| 24 | 20 | ||
| 25 | - | ||
| 26 | /** | 21 | /** |
| 27 | * Update the specified settings in storage. | 22 | * Update the specified settings in storage. |
| 28 | - * | 23 | + * @param Request $request |
| 29 | - * @param Request $request | ||
| 30 | * @return Response | 24 | * @return Response |
| 31 | */ | 25 | */ |
| 32 | public function update(Request $request) | 26 | public function update(Request $request) |
| ... | @@ -35,12 +29,9 @@ class SettingController extends Controller | ... | @@ -35,12 +29,9 @@ class SettingController extends Controller |
| 35 | $this->checkPermission('settings-manage'); | 29 | $this->checkPermission('settings-manage'); |
| 36 | 30 | ||
| 37 | // Cycles through posted settings and update them | 31 | // Cycles through posted settings and update them |
| 38 | - foreach($request->all() as $name => $value) { | 32 | + foreach ($request->all() as $name => $value) { |
| 39 | - if(strpos($name, 'setting-') !== 0) continue; | 33 | + if (strpos($name, 'setting-') !== 0) continue; |
| 40 | $key = str_replace('setting-', '', trim($name)); | 34 | $key = str_replace('setting-', '', trim($name)); |
| 41 | - if($key == 'app-color') { | ||
| 42 | - Setting::put('app-color-rgba', $this->hex2rgba($value, 0.15)); | ||
| 43 | - } | ||
| 44 | Setting::put($key, $value); | 35 | Setting::put($key, $value); |
| 45 | } | 36 | } |
| 46 | 37 | ||
| ... | @@ -48,51 +39,4 @@ class SettingController extends Controller | ... | @@ -48,51 +39,4 @@ class SettingController extends Controller |
| 48 | return redirect('/settings'); | 39 | return redirect('/settings'); |
| 49 | } | 40 | } |
| 50 | 41 | ||
| 51 | - /** | ||
| 52 | - * Adapted from http://mekshq.com/how-to-convert-hexadecimal-color-code-to-rgb-or-rgba-using-php/ | ||
| 53 | - * Converts a hex color code in to an RGBA string. | ||
| 54 | - * | ||
| 55 | - * @param string $color | ||
| 56 | - * @param float|boolean $opacity | ||
| 57 | - * @return boolean|string | ||
| 58 | - */ | ||
| 59 | - protected function hex2rgba($color, $opacity = false) | ||
| 60 | - { | ||
| 61 | - // Return false if no color provided | ||
| 62 | - if(empty($color)) { | ||
| 63 | - return false; | ||
| 64 | - } | ||
| 65 | - // Trim any whitespace | ||
| 66 | - $color = trim($color); | ||
| 67 | - | ||
| 68 | - // Sanitize $color if "#" is provided | ||
| 69 | - if($color[0] == '#' ) { | ||
| 70 | - $color = substr($color, 1); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - // Check if color has 6 or 3 characters and get values | ||
| 74 | - if(strlen($color) == 6) { | ||
| 75 | - $hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] ); | ||
| 76 | - } elseif( strlen( $color ) == 3 ) { | ||
| 77 | - $hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] ); | ||
| 78 | - } else { | ||
| 79 | - return false; | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - // Convert hexadec to rgb | ||
| 83 | - $rgb = array_map('hexdec', $hex); | ||
| 84 | - | ||
| 85 | - // Check if opacity is set(rgba or rgb) | ||
| 86 | - if($opacity) { | ||
| 87 | - if(abs($opacity) > 1) | ||
| 88 | - $opacity = 1.0; | ||
| 89 | - $output = 'rgba('.implode(",",$rgb).','.$opacity.')'; | ||
| 90 | - } else { | ||
| 91 | - $output = 'rgb('.implode(",",$rgb).')'; | ||
| 92 | - } | ||
| 93 | - | ||
| 94 | - // Return rgb(a) color string | ||
| 95 | - return $output; | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | } | 42 | } | ... | ... |
This diff is collapsed.
Click to expand it.
public/libs/jscolor/jscolor.min.js
deleted
100644 → 0
This diff is collapsed.
Click to expand it.
| ... | @@ -175,3 +175,4 @@ These are the great projects used to help build BookStack: | ... | @@ -175,3 +175,4 @@ These are the great projects used to help build BookStack: |
| 175 | * [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font/icons.html) | 175 | * [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font/icons.html) |
| 176 | * [Dropzone.js](http://www.dropzonejs.com/) | 176 | * [Dropzone.js](http://www.dropzonejs.com/) |
| 177 | * [ZeroClipboard](http://zeroclipboard.org/) | 177 | * [ZeroClipboard](http://zeroclipboard.org/) |
| 178 | +* [TinyColorPicker](http://www.dematte.at/tinyColorPicker/index.html) | ... | ... |
| ... | @@ -95,7 +95,7 @@ $(function () { | ... | @@ -95,7 +95,7 @@ $(function () { |
| 95 | scrollTop.style.display = 'block'; | 95 | scrollTop.style.display = 'block'; |
| 96 | scrollTopShowing = true; | 96 | scrollTopShowing = true; |
| 97 | setTimeout(() => { | 97 | setTimeout(() => { |
| 98 | - scrollTop.style.opacity = 1; | 98 | + scrollTop.style.opacity = 0.4; |
| 99 | }, 1); | 99 | }, 1); |
| 100 | } else if (scrollTopShowing && document.body.scrollTop < scrollTopBreakpoint) { | 100 | } else if (scrollTopShowing && document.body.scrollTop < scrollTopBreakpoint) { |
| 101 | scrollTop.style.opacity = 0; | 101 | scrollTop.style.opacity = 0; | ... | ... |
| ... | @@ -138,7 +138,7 @@ $loadingSize: 10px; | ... | @@ -138,7 +138,7 @@ $loadingSize: 10px; |
| 138 | // Back to top link | 138 | // Back to top link |
| 139 | $btt-size: 40px; | 139 | $btt-size: 40px; |
| 140 | #back-to-top { | 140 | #back-to-top { |
| 141 | - background-color: rgba($primary, 0.4); | 141 | + background-color: $primary; |
| 142 | position: fixed; | 142 | position: fixed; |
| 143 | bottom: $-m; | 143 | bottom: $-m; |
| 144 | right: $-l; | 144 | right: $-l; |
| ... | @@ -154,7 +154,7 @@ $btt-size: 40px; | ... | @@ -154,7 +154,7 @@ $btt-size: 40px; |
| 154 | overflow: hidden; | 154 | overflow: hidden; |
| 155 | &:hover { | 155 | &:hover { |
| 156 | width: $btt-size*3.4; | 156 | width: $btt-size*3.4; |
| 157 | - background-color: rgba($primary, 1); | 157 | + opacity: 1 !important; |
| 158 | span { | 158 | span { |
| 159 | display: inline-block; | 159 | display: inline-block; |
| 160 | } | 160 | } | ... | ... |
| ... | @@ -17,25 +17,8 @@ | ... | @@ -17,25 +17,8 @@ |
| 17 | <script src="/libs/jquery/jquery.min.js?version=2.1.4"></script> | 17 | <script src="/libs/jquery/jquery.min.js?version=2.1.4"></script> |
| 18 | 18 | ||
| 19 | @yield('head') | 19 | @yield('head') |
| 20 | - @if(Setting::get('app-color')) | 20 | + |
| 21 | - <style> | 21 | + @include('partials/custom-styles') |
| 22 | - header{ | ||
| 23 | - background-color: #{{ Setting::get('app-color') }}; | ||
| 24 | - } | ||
| 25 | - .faded-small{ | ||
| 26 | - background-color: {{ Setting::get('app-color-rgba') }}; | ||
| 27 | - } | ||
| 28 | - .button-base, .button, input[type="button"], input[type="submit"] { | ||
| 29 | - background-color: #{{ Setting::get('app-color') }}; | ||
| 30 | - } | ||
| 31 | - .button-base:hover, .button:hover, input[type="button"]:hover, input[type="submit"]:hover { | ||
| 32 | - background-color: #{{ Setting::get('app-color') }}; | ||
| 33 | - } | ||
| 34 | - p.primary:hover, p .primary:hover, span.primary:hover, .text-primary:hover { | ||
| 35 | - color: #{{ Setting::get('app-color') }}; | ||
| 36 | - } | ||
| 37 | - </style> | ||
| 38 | - @endif | ||
| 39 | </head> | 22 | </head> |
| 40 | <body class="@yield('body-class')" ng-app="bookStack"> | 23 | <body class="@yield('body-class')" ng-app="bookStack"> |
| 41 | 24 | ||
| ... | @@ -62,7 +45,7 @@ | ... | @@ -62,7 +45,7 @@ |
| 62 | <div class="float right"> | 45 | <div class="float right"> |
| 63 | <div class="links text-center"> | 46 | <div class="links text-center"> |
| 64 | <a href="/books"><i class="zmdi zmdi-book"></i>Books</a> | 47 | <a href="/books"><i class="zmdi zmdi-book"></i>Books</a> |
| 65 | - @if(isset($currentUser) && $currentUser->can('settings-manage')) | 48 | + @if(isset($currentUser) && userCan('settings-manage')) |
| 66 | <a href="/settings"><i class="zmdi zmdi-settings"></i>Settings</a> | 49 | <a href="/settings"><i class="zmdi zmdi-settings"></i>Settings</a> |
| 67 | @endif | 50 | @endif |
| 68 | @if(!isset($signedIn) || !$signedIn) | 51 | @if(!isset($signedIn) || !$signedIn) | ... | ... |
| 1 | +@if(Setting::get('app-color')) | ||
| 2 | + <style> | ||
| 3 | + header, #back-to-top { | ||
| 4 | + background-color: {{ Setting::get('app-color') }}; | ||
| 5 | + } | ||
| 6 | + .faded-small { | ||
| 7 | + background-color: {{ Setting::get('app-color-light') }}; | ||
| 8 | + } | ||
| 9 | + .button-base, .button, input[type="button"], input[type="submit"] { | ||
| 10 | + background-color: {{ Setting::get('app-color') }}; | ||
| 11 | + } | ||
| 12 | + .button-base:hover, .button:hover, input[type="button"]:hover, input[type="submit"]:hover, .button:focus { | ||
| 13 | + background-color: {{ Setting::get('app-color') }}; | ||
| 14 | + } | ||
| 15 | + .setting-nav a.selected { | ||
| 16 | + border-bottom-color: {{ Setting::get('app-color') }}; | ||
| 17 | + } | ||
| 18 | + p.primary:hover, p .primary:hover, span.primary:hover, .text-primary:hover, a, a:hover, a:focus { | ||
| 19 | + color: {{ Setting::get('app-color') }}; | ||
| 20 | + } | ||
| 21 | + </style> | ||
| 22 | +@endif | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -15,19 +15,7 @@ | ... | @@ -15,19 +15,7 @@ |
| 15 | 15 | ||
| 16 | <!-- Scripts --> | 16 | <!-- Scripts --> |
| 17 | <script src="/libs/jquery/jquery.min.js?version=2.1.4"></script> | 17 | <script src="/libs/jquery/jquery.min.js?version=2.1.4"></script> |
| 18 | - @if(Setting::get('app-color')) | 18 | + @include('partials/custom-styles') |
| 19 | - <style> | ||
| 20 | - header { | ||
| 21 | - background-color: #{{ Setting::get('app-color') }}; | ||
| 22 | - } | ||
| 23 | - .faded-small { | ||
| 24 | - background-color: {{ Setting::get('app-color-rgba') }}} | ||
| 25 | - } | ||
| 26 | - .button-base, .button, input[type="button"], input[type="submit"] { | ||
| 27 | - background-color: #{{ Setting::get('app-color') }} !IMPORTANT; | ||
| 28 | - } | ||
| 29 | - </style> | ||
| 30 | - @endif | ||
| 31 | </head> | 19 | </head> |
| 32 | <body class="@yield('body-class')" ng-app="bookStack"> | 20 | <body class="@yield('body-class')" ng-app="bookStack"> |
| 33 | 21 | ... | ... |
| ... | @@ -37,8 +37,9 @@ | ... | @@ -37,8 +37,9 @@ |
| 37 | </div> | 37 | </div> |
| 38 | <div class="form-group" id="color-control"> | 38 | <div class="form-group" id="color-control"> |
| 39 | <label for="setting-app-color">Application Primary Color</label> | 39 | <label for="setting-app-color">Application Primary Color</label> |
| 40 | - <p class="small">This should be a hex value.</p> | 40 | + <p class="small">This should be a hex value. <br> Leave empty to reset to the default color.</p> |
| 41 | - <input class="jscolor" type="text" value="{{ Setting::get('app-color', '') }}" name="setting-app-color" id="setting-app-color" placeholder="0288D1"> | 41 | + <input type="text" value="{{ Setting::get('app-color', '') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1"> |
| 42 | + <input type="hidden" value="{{ Setting::get('app-color-light', '') }}" name="setting-app-color-light" id="setting-app-color-light" placeholder="rgba(21, 101, 192, 0.15)"> | ||
| 42 | </div> | 43 | </div> |
| 43 | </div> | 44 | </div> |
| 44 | </div> | 45 | </div> |
| ... | @@ -96,5 +97,23 @@ | ... | @@ -96,5 +97,23 @@ |
| 96 | @stop | 97 | @stop |
| 97 | 98 | ||
| 98 | @section('scripts') | 99 | @section('scripts') |
| 99 | - <script src="/libs/jscolor/jscolor.min.js?version=2.0.4"></script> | 100 | + <script src="/libs/jq-color-picker/tiny-color-picker.min.js?version=1.0.0"></script> |
| 101 | + <script type="text/javascript"> | ||
| 102 | + $('#setting-app-color').colorPicker({ | ||
| 103 | + opacity: false, | ||
| 104 | + renderCallback: function($elm, toggled) { | ||
| 105 | + var hexVal = '#' + this.color.colors.HEX; | ||
| 106 | + var rgb = this.color.colors.RND.rgb; | ||
| 107 | + var rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')'; | ||
| 108 | + // Set textbox color to hex color code. | ||
| 109 | + var isEmpty = $.trim($elm.val()).length === 0; | ||
| 110 | + if (!isEmpty) $elm.val(hexVal); | ||
| 111 | + $('#setting-app-color-light').val(isEmpty ? '' : rgbLightVal); | ||
| 112 | + // Set page elements to provide preview | ||
| 113 | + $('#header, .image-picker .button').css('background-color', hexVal); | ||
| 114 | + $('.faded-small').css('background-color', rgbLightVal); | ||
| 115 | + $('.setting-nav a.selected').css('border-bottom-color', hexVal); | ||
| 116 | + } | ||
| 117 | + }); | ||
| 118 | + </script> | ||
| 100 | @stop | 119 | @stop |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment