Add colorpicker to change calendar color, fixes #317"
This commit is contained in:
Родитель
0ff41bc7e9
Коммит
400d0af4b7
|
@ -67,6 +67,7 @@
|
|||
}
|
||||
#app-navigation li.edit .app-navigation-entry-edit {
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
}
|
||||
#app-navigation li .app-navigation-entry-edit {
|
||||
display: none;
|
||||
|
@ -1488,3 +1489,57 @@ ol[dnd-list] .dndPlaceholder {
|
|||
.dropzone-visible > ol[dnd-list] {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
/* ColorPicker overrides. */
|
||||
#app-navigation > ul ul.colorpicker-list {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.colorpicker {
|
||||
display: block;
|
||||
height: 30px;
|
||||
height: auto;
|
||||
padding-bottom: 3px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.colorpicker .colorpicker-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.colorpicker .colorpicker-list li {
|
||||
height: 24px;
|
||||
width: 24px !important;
|
||||
}
|
||||
|
||||
.colorpicker .colorpicker-list li.selected {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.colorpicker .colorpicker-list li.randomcolour {
|
||||
background-image: url('../../img/random.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
#app-navigation .app-navigation-entry-edit input.icon-close {
|
||||
width: 36px;
|
||||
height: 38px;
|
||||
float: left;
|
||||
margin: 3px 0px;
|
||||
border-left: 0px none;
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
}
|
||||
#app-navigation .app-navigation-entry-edit input.icon-close:hover {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#app-navigation .app-navigation-entry-edit input[type="text"] {
|
||||
width: calc(100% - 72px);
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
*/
|
||||
|
||||
angular.module('Tasks').controller('AppController', [
|
||||
'$scope', 'ListsBusinessLayer', '$route', 'Status', '$timeout', '$location', '$routeParams', 'Loading', 'SettingsModel', 'Persistence', function($scope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence) {
|
||||
'$scope', '$rootScope', 'ListsBusinessLayer', '$route', 'Status', '$timeout', '$location', '$routeParams', 'Loading', 'SettingsModel', 'Persistence', function($scope, $rootScope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence) {
|
||||
'use strict';
|
||||
var AppController = (function() {
|
||||
function AppController(_$scope, _$listsbusinesslayer, _$route, _$status, _$timeout, _$location, _$routeparams, _Loading, _$settingsmodel, _persistence) {
|
||||
function AppController(_$scope, $rootScope, _$listsbusinesslayer, _$route, _$status, _$timeout, _$location, _$routeparams, _Loading, _$settingsmodel, _persistence) {
|
||||
this._$scope = _$scope;
|
||||
this._$listsbusinesslayer = _$listsbusinesslayer;
|
||||
this._$route = _$route;
|
||||
|
@ -50,6 +50,9 @@ angular.module('Tasks').controller('AppController', [
|
|||
this._$scope.closeAll = function($event) {
|
||||
if ($($event.target).closest('.close-all').length || $($event.currentTarget).is($($event.target).closest('.handler'))) {
|
||||
if (!angular.isUndefined(_$scope.route.calendarID)) {
|
||||
if (_$scope.route.listparameter == 'name') {
|
||||
$rootScope.$broadcast('cancelEditCalendar', _$scope.route.calendarID);
|
||||
}
|
||||
_$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
} else if (!angular.isUndefined(_$scope.route.collectionID)) {
|
||||
_$location.path('/collections/' + _$scope.route.collectionID);
|
||||
|
@ -75,6 +78,6 @@ angular.module('Tasks').controller('AppController', [
|
|||
}
|
||||
return AppController;
|
||||
})();
|
||||
return new AppController($scope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence);
|
||||
return new AppController($scope, $rootScope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence);
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -20,16 +20,16 @@
|
|||
*/
|
||||
|
||||
angular.module('Tasks').controller('ListController', [
|
||||
'$scope', '$window', '$routeParams', 'ListsModel', 'TasksBusinessLayer', 'CollectionsModel', 'ListsBusinessLayer', '$location',
|
||||
'$scope', '$rootScope', '$window', '$routeParams', 'ListsModel', 'TasksBusinessLayer', 'CollectionsModel', 'ListsBusinessLayer', '$location',
|
||||
'SearchBusinessLayer', 'CalendarService', 'TasksModel',
|
||||
function($scope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
function($scope, $rootScope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
SearchBusinessLayer, CalendarService, TasksModel) {
|
||||
'use strict';
|
||||
var ListController;
|
||||
ListController = (function() {
|
||||
function ListController(_$scope, _$window, _$routeParams, _$listsmodel, _$tasksbusinesslayer, _$collectionsmodel, _$listsbusinesslayer, $location,
|
||||
function ListController(_$scope, $rootScope, _$window, _$routeParams, _$listsmodel, _$tasksbusinesslayer, _$collectionsmodel, _$listsbusinesslayer, $location,
|
||||
_$searchbusinesslayer, _$calendarservice, _$tasksmodel) {
|
||||
|
||||
|
||||
this._$scope = _$scope;
|
||||
this._$window = _$window;
|
||||
this._$routeParams = _$routeParams;
|
||||
|
@ -86,21 +86,30 @@ angular.module('Tasks').controller('ListController', [
|
|||
}
|
||||
};
|
||||
|
||||
this._$scope.startRename = function(calendar) {
|
||||
this._$scope.startEdit = function(calendar) {
|
||||
_$scope.status.addingList = false;
|
||||
calendar.prepareUpdate();
|
||||
return $location.path('/calendars/' + _$scope.route.calendarID + '/edit/name');
|
||||
};
|
||||
|
||||
this._$scope.cancelRename = function(event,calendar) {
|
||||
this._$scope.checkKey = function(event,calendar) {
|
||||
if (event.keyCode === 27) {
|
||||
event.preventDefault();
|
||||
calendar.resetToPreviousState();
|
||||
$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
_$scope.cancelEdit(calendar);
|
||||
}
|
||||
};
|
||||
|
||||
this._$scope.rename = function(calendar) {
|
||||
$rootScope.$on('cancelEditCalendar', function(s, calendarUri) {
|
||||
var calendar = _$listsmodel.getByUri(calendarUri);
|
||||
_$scope.cancelEdit(calendar);
|
||||
});
|
||||
|
||||
this._$scope.cancelEdit = function(calendar) {
|
||||
calendar.resetToPreviousState();
|
||||
$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
};
|
||||
|
||||
this._$scope.saveEdit = function(calendar) {
|
||||
var name = calendar.displayname;
|
||||
if (name) {
|
||||
if (!_$listsmodel.isNameAlreadyTaken(calendar.displayname, calendar.uri)) {
|
||||
|
@ -189,7 +198,7 @@ angular.module('Tasks').controller('ListController', [
|
|||
return ListController;
|
||||
|
||||
})();
|
||||
return new ListController($scope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
return new ListController($scope, $rootScope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
SearchBusinessLayer, CalendarService, TasksModel);
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/**
|
||||
* ownCloud - Tasks App
|
||||
*
|
||||
* @author Raghu Nayyar
|
||||
* @author Georg Ehrke
|
||||
* @copyright 2016 Raghu Nayyar <beingminimal@gmail.com>
|
||||
* @copyright 2016 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* @copyright 2016 John Molakvoæ <fremulon@protonmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* https://github.com/kayellpeee/hsl_rgb_converter
|
||||
* expected hue range: [0, 360)
|
||||
* expected saturation range: [0, 1]
|
||||
* expected lightness range: [0, 1]
|
||||
*/
|
||||
var hslToRgb = function(hue, saturation, lightness) {
|
||||
'use strict';
|
||||
// based on algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
|
||||
if(Array.isArray(hue)) {
|
||||
saturation = hue[1];
|
||||
lightness = hue[2];
|
||||
hue = hue[0];
|
||||
}
|
||||
if (hue === undefined) {
|
||||
return [0, 0, 0];
|
||||
}
|
||||
saturation /= 100;
|
||||
lightness /= 100;
|
||||
|
||||
var chroma = (1 - Math.abs((2 * lightness) - 1)) * saturation;
|
||||
var huePrime = hue / 60;
|
||||
var secondComponent = chroma * (1 - Math.abs((huePrime % 2) - 1));
|
||||
|
||||
huePrime = Math.floor(huePrime);
|
||||
var red;
|
||||
var green;
|
||||
var blue;
|
||||
|
||||
if (huePrime === 0) {
|
||||
red = chroma;
|
||||
green = secondComponent;
|
||||
blue = 0;
|
||||
} else if (huePrime === 1) {
|
||||
red = secondComponent;
|
||||
green = chroma;
|
||||
blue = 0;
|
||||
} else if (huePrime === 2) {
|
||||
red = 0;
|
||||
green = chroma;
|
||||
blue = secondComponent;
|
||||
} else if (huePrime === 3) {
|
||||
red = 0;
|
||||
green = secondComponent;
|
||||
blue = chroma;
|
||||
} else if (huePrime === 4) {
|
||||
red = secondComponent;
|
||||
green = 0;
|
||||
blue = chroma;
|
||||
} else if (huePrime === 5) {
|
||||
red = chroma;
|
||||
green = 0;
|
||||
blue = secondComponent;
|
||||
}
|
||||
|
||||
var lightnessAdjustment = lightness - (chroma / 2);
|
||||
red += lightnessAdjustment;
|
||||
green += lightnessAdjustment;
|
||||
blue += lightnessAdjustment;
|
||||
|
||||
return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert rgb array to hex string
|
||||
*/
|
||||
var rgbToHex = function(r, g, b) {
|
||||
'use strict';
|
||||
if(Array.isArray(r)) {
|
||||
g = r[1];
|
||||
b = r[2];
|
||||
r = r[0];
|
||||
}
|
||||
return '#' + parseInt(r, 10).toString(16) + parseInt(g, 10).toString(16) + parseInt(b, 10).toString(16);
|
||||
};
|
||||
|
||||
var listofcolours = [
|
||||
'#31CC7C',
|
||||
'#317CCC',
|
||||
'#FF7A66',
|
||||
'#F1DB50',
|
||||
'#7C31CC',
|
||||
'#CC317C',
|
||||
'#3A3B3D',
|
||||
'#CACBCD'
|
||||
];
|
||||
|
||||
/*
|
||||
* Generate a random colour with the core generator
|
||||
*/
|
||||
var randColour = function() {
|
||||
'use strict';
|
||||
if (typeof String.prototype.toHsl === 'function') {
|
||||
return rgbToHex(hslToRgb(Math.random().toString().toHsl()));
|
||||
} else {
|
||||
return listofcolours[Math.floor(Math.random() * listofcolours.length)];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Directive: Colorpicker
|
||||
* Description: Colorpicker for the Tasks app.
|
||||
*/
|
||||
|
||||
|
||||
angular.module('Tasks').directive('colorpicker', function() {
|
||||
'use strict';
|
||||
if (typeof String.prototype.toHsl === 'function') {
|
||||
var hsl = "";
|
||||
var hslcolour = "";
|
||||
// 0 40 80 120 160 200 240 280 320
|
||||
listofcolours = ["15", "9", "4", "b", "6", "11", "74", "f", "57"];
|
||||
listofcolours.forEach(function(hash, index) {
|
||||
hsl = hash.toHsl();
|
||||
hslcolour = hslToRgb(hsl);
|
||||
listofcolours[index] = rgbToHex(hslcolour);
|
||||
});
|
||||
}
|
||||
return {
|
||||
scope: {
|
||||
selected: '=',
|
||||
customizedColors: '=colors'
|
||||
},
|
||||
restrict: 'AE',
|
||||
templateUrl: OC.filePath('tasks', 'templates', 'colorpicker.html'),
|
||||
link: function(scope, element, attr) {
|
||||
scope.colors = scope.customizedColors || listofcolours;
|
||||
scope.selected = scope.selected || scope.colors[0];
|
||||
scope.random = "#000000";
|
||||
|
||||
scope.randomizeColour = function() {
|
||||
scope.random = randColour();
|
||||
scope.pick(scope.random);
|
||||
};
|
||||
|
||||
scope.pick = function(color) {
|
||||
scope.selected = color;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
});
|
182
js/public/app.js
182
js/public/app.js
|
@ -145,10 +145,10 @@ angular.module('Tasks').run([
|
|||
]);
|
||||
|
||||
angular.module('Tasks').controller('AppController', [
|
||||
'$scope', 'ListsBusinessLayer', '$route', 'Status', '$timeout', '$location', '$routeParams', 'Loading', 'SettingsModel', 'Persistence', function($scope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence) {
|
||||
'$scope', '$rootScope', 'ListsBusinessLayer', '$route', 'Status', '$timeout', '$location', '$routeParams', 'Loading', 'SettingsModel', 'Persistence', function($scope, $rootScope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence) {
|
||||
'use strict';
|
||||
var AppController = (function() {
|
||||
function AppController(_$scope, _$listsbusinesslayer, _$route, _$status, _$timeout, _$location, _$routeparams, _Loading, _$settingsmodel, _persistence) {
|
||||
function AppController(_$scope, $rootScope, _$listsbusinesslayer, _$route, _$status, _$timeout, _$location, _$routeparams, _Loading, _$settingsmodel, _persistence) {
|
||||
this._$scope = _$scope;
|
||||
this._$listsbusinesslayer = _$listsbusinesslayer;
|
||||
this._$route = _$route;
|
||||
|
@ -175,6 +175,9 @@ angular.module('Tasks').controller('AppController', [
|
|||
this._$scope.closeAll = function($event) {
|
||||
if ($($event.target).closest('.close-all').length || $($event.currentTarget).is($($event.target).closest('.handler'))) {
|
||||
if (!angular.isUndefined(_$scope.route.calendarID)) {
|
||||
if (_$scope.route.listparameter == 'name') {
|
||||
$rootScope.$broadcast('cancelEditCalendar', _$scope.route.calendarID);
|
||||
}
|
||||
_$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
} else if (!angular.isUndefined(_$scope.route.collectionID)) {
|
||||
_$location.path('/collections/' + _$scope.route.collectionID);
|
||||
|
@ -200,7 +203,7 @@ angular.module('Tasks').controller('AppController', [
|
|||
}
|
||||
return AppController;
|
||||
})();
|
||||
return new AppController($scope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence);
|
||||
return new AppController($scope, $rootScope, ListsBusinessLayer, $route, status, $timeout, $location, $routeParams, Loading, SettingsModel, Persistence);
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -575,16 +578,16 @@ angular.module('Tasks').controller('DetailsController', [
|
|||
]);
|
||||
|
||||
angular.module('Tasks').controller('ListController', [
|
||||
'$scope', '$window', '$routeParams', 'ListsModel', 'TasksBusinessLayer', 'CollectionsModel', 'ListsBusinessLayer', '$location',
|
||||
'$scope', '$rootScope', '$window', '$routeParams', 'ListsModel', 'TasksBusinessLayer', 'CollectionsModel', 'ListsBusinessLayer', '$location',
|
||||
'SearchBusinessLayer', 'CalendarService', 'TasksModel',
|
||||
function($scope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
function($scope, $rootScope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
SearchBusinessLayer, CalendarService, TasksModel) {
|
||||
'use strict';
|
||||
var ListController;
|
||||
ListController = (function() {
|
||||
function ListController(_$scope, _$window, _$routeParams, _$listsmodel, _$tasksbusinesslayer, _$collectionsmodel, _$listsbusinesslayer, $location,
|
||||
function ListController(_$scope, $rootScope, _$window, _$routeParams, _$listsmodel, _$tasksbusinesslayer, _$collectionsmodel, _$listsbusinesslayer, $location,
|
||||
_$searchbusinesslayer, _$calendarservice, _$tasksmodel) {
|
||||
|
||||
|
||||
this._$scope = _$scope;
|
||||
this._$window = _$window;
|
||||
this._$routeParams = _$routeParams;
|
||||
|
@ -641,21 +644,30 @@ angular.module('Tasks').controller('ListController', [
|
|||
}
|
||||
};
|
||||
|
||||
this._$scope.startRename = function(calendar) {
|
||||
this._$scope.startEdit = function(calendar) {
|
||||
_$scope.status.addingList = false;
|
||||
calendar.prepareUpdate();
|
||||
return $location.path('/calendars/' + _$scope.route.calendarID + '/edit/name');
|
||||
};
|
||||
|
||||
this._$scope.cancelRename = function(event,calendar) {
|
||||
this._$scope.checkKey = function(event,calendar) {
|
||||
if (event.keyCode === 27) {
|
||||
event.preventDefault();
|
||||
calendar.resetToPreviousState();
|
||||
$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
_$scope.cancelEdit(calendar);
|
||||
}
|
||||
};
|
||||
|
||||
this._$scope.rename = function(calendar) {
|
||||
$rootScope.$on('cancelEditCalendar', function(s, calendarUri) {
|
||||
var calendar = _$listsmodel.getByUri(calendarUri);
|
||||
_$scope.cancelEdit(calendar);
|
||||
});
|
||||
|
||||
this._$scope.cancelEdit = function(calendar) {
|
||||
calendar.resetToPreviousState();
|
||||
$location.path('/calendars/' + _$scope.route.calendarID);
|
||||
};
|
||||
|
||||
this._$scope.saveEdit = function(calendar) {
|
||||
var name = calendar.displayname;
|
||||
if (name) {
|
||||
if (!_$listsmodel.isNameAlreadyTaken(calendar.displayname, calendar.uri)) {
|
||||
|
@ -744,7 +756,7 @@ angular.module('Tasks').controller('ListController', [
|
|||
return ListController;
|
||||
|
||||
})();
|
||||
return new ListController($scope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
return new ListController($scope, $rootScope, $window, $routeParams, ListsModel, TasksBusinessLayer, CollectionsModel, ListsBusinessLayer, $location,
|
||||
SearchBusinessLayer, CalendarService, TasksModel);
|
||||
}
|
||||
]);
|
||||
|
@ -1233,6 +1245,150 @@ angular.module('Tasks').directive('avatar', function() {
|
|||
};
|
||||
});
|
||||
|
||||
/* https://github.com/kayellpeee/hsl_rgb_converter
|
||||
* expected hue range: [0, 360)
|
||||
* expected saturation range: [0, 1]
|
||||
* expected lightness range: [0, 1]
|
||||
*/
|
||||
var hslToRgb = function(hue, saturation, lightness) {
|
||||
'use strict';
|
||||
// based on algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
|
||||
if(Array.isArray(hue)) {
|
||||
saturation = hue[1];
|
||||
lightness = hue[2];
|
||||
hue = hue[0];
|
||||
}
|
||||
if (hue === undefined) {
|
||||
return [0, 0, 0];
|
||||
}
|
||||
saturation /= 100;
|
||||
lightness /= 100;
|
||||
|
||||
var chroma = (1 - Math.abs((2 * lightness) - 1)) * saturation;
|
||||
var huePrime = hue / 60;
|
||||
var secondComponent = chroma * (1 - Math.abs((huePrime % 2) - 1));
|
||||
|
||||
huePrime = Math.floor(huePrime);
|
||||
var red;
|
||||
var green;
|
||||
var blue;
|
||||
|
||||
if (huePrime === 0) {
|
||||
red = chroma;
|
||||
green = secondComponent;
|
||||
blue = 0;
|
||||
} else if (huePrime === 1) {
|
||||
red = secondComponent;
|
||||
green = chroma;
|
||||
blue = 0;
|
||||
} else if (huePrime === 2) {
|
||||
red = 0;
|
||||
green = chroma;
|
||||
blue = secondComponent;
|
||||
} else if (huePrime === 3) {
|
||||
red = 0;
|
||||
green = secondComponent;
|
||||
blue = chroma;
|
||||
} else if (huePrime === 4) {
|
||||
red = secondComponent;
|
||||
green = 0;
|
||||
blue = chroma;
|
||||
} else if (huePrime === 5) {
|
||||
red = chroma;
|
||||
green = 0;
|
||||
blue = secondComponent;
|
||||
}
|
||||
|
||||
var lightnessAdjustment = lightness - (chroma / 2);
|
||||
red += lightnessAdjustment;
|
||||
green += lightnessAdjustment;
|
||||
blue += lightnessAdjustment;
|
||||
|
||||
return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert rgb array to hex string
|
||||
*/
|
||||
var rgbToHex = function(r, g, b) {
|
||||
'use strict';
|
||||
if(Array.isArray(r)) {
|
||||
g = r[1];
|
||||
b = r[2];
|
||||
r = r[0];
|
||||
}
|
||||
return '#' + parseInt(r, 10).toString(16) + parseInt(g, 10).toString(16) + parseInt(b, 10).toString(16);
|
||||
};
|
||||
|
||||
var listofcolours = [
|
||||
'#31CC7C',
|
||||
'#317CCC',
|
||||
'#FF7A66',
|
||||
'#F1DB50',
|
||||
'#7C31CC',
|
||||
'#CC317C',
|
||||
'#3A3B3D',
|
||||
'#CACBCD'
|
||||
];
|
||||
|
||||
/*
|
||||
* Generate a random colour with the core generator
|
||||
*/
|
||||
var randColour = function() {
|
||||
'use strict';
|
||||
if (typeof String.prototype.toHsl === 'function') {
|
||||
return rgbToHex(hslToRgb(Math.random().toString().toHsl()));
|
||||
} else {
|
||||
return listofcolours[Math.floor(Math.random() * listofcolours.length)];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Directive: Colorpicker
|
||||
* Description: Colorpicker for the Tasks app.
|
||||
*/
|
||||
|
||||
|
||||
angular.module('Tasks').directive('colorpicker', function() {
|
||||
'use strict';
|
||||
if (typeof String.prototype.toHsl === 'function') {
|
||||
var hsl = "";
|
||||
var hslcolour = "";
|
||||
// 0 40 80 120 160 200 240 280 320
|
||||
listofcolours = ["15", "9", "4", "b", "6", "11", "74", "f", "57"];
|
||||
listofcolours.forEach(function(hash, index) {
|
||||
hsl = hash.toHsl();
|
||||
hslcolour = hslToRgb(hsl);
|
||||
listofcolours[index] = rgbToHex(hslcolour);
|
||||
});
|
||||
}
|
||||
return {
|
||||
scope: {
|
||||
selected: '=',
|
||||
customizedColors: '=colors'
|
||||
},
|
||||
restrict: 'AE',
|
||||
templateUrl: OC.filePath('tasks', 'templates', 'colorpicker.html'),
|
||||
link: function(scope, element, attr) {
|
||||
scope.colors = scope.customizedColors || listofcolours;
|
||||
scope.selected = scope.selected || scope.colors[0];
|
||||
scope.random = "#000000";
|
||||
|
||||
scope.randomizeColour = function() {
|
||||
scope.random = randColour();
|
||||
scope.pick(scope.random);
|
||||
};
|
||||
|
||||
scope.pick = function(color) {
|
||||
scope.selected = color;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
angular.module('Tasks').directive('datepicker', function() {
|
||||
'use strict';
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<ul class="colorpicker-list">
|
||||
<li ng-repeat="color in colors"
|
||||
ng-class="{ selected: (color===selected) }"
|
||||
ng-click="pick(color)"
|
||||
ng-style="{ 'background-color':color}; "></li>
|
||||
<!--<li class="randomcolour"
|
||||
ng-click="randomizeColour()"
|
||||
ng-style="{ 'background-color':random}; "></li>-->
|
||||
</ul>
|
|
@ -57,9 +57,9 @@
|
|||
</div>
|
||||
<div class="app-navigation-entry-menu" ng-show="calendar.writable">
|
||||
<ul>
|
||||
<li title="<?php p($l->t('Rename')); ?>" ng-click="startRename(calendar)" >
|
||||
<li title="<?php p($l->t('Edit')); ?>" ng-click="startEdit(calendar)" >
|
||||
<img class="icon-rename svg" src="<?php p(image_path('core', 'actions/rename.svg'))?>"/>
|
||||
<span><?php p($l->t('Rename')); ?></span>
|
||||
<span><?php p($l->t('Edit')); ?></span>
|
||||
</li>
|
||||
<li title="<?php p($l->t('Delete')); ?>" ng-click="delete(calendar)">
|
||||
<img class="icon-delete svg" src="<?php p(image_path('core', 'actions/delete.svg'))?>"/>
|
||||
|
@ -69,9 +69,13 @@
|
|||
</div>
|
||||
<div class="app-navigation-entry-edit">
|
||||
<form>
|
||||
<input ng-model="calendar.displayname" class="edit" type="text" ng-keydown="cancelRename($event,calendar)" autofocus-on-insert>
|
||||
<input type="submit" value="" class="action icon-checkmark svg" ng-click="rename(calendar)">
|
||||
<input ng-model="calendar.displayname" class="edit" type="text" ng-keydown="checkKey($event,calendar)" autofocus-on-insert>
|
||||
<input type="cancel" value="" class="action icon-close svg" ng-click="cancelEdit(calendar)" title="<?php p($l->t('Cancel')); ?>">
|
||||
<input type="submit" value="" class="action icon-checkmark svg" ng-click="saveEdit(calendar)" title="<?php p($l->t('Save')); ?>">
|
||||
</form>
|
||||
<colorpicker class="colorpicker"
|
||||
selected="calendar.color">
|
||||
</colorpicker>
|
||||
</div>
|
||||
</li>
|
||||
<li class="newList handler" ng-class="{edit: status.addingList}">
|
||||
|
|
Загрузка…
Ссылка в новой задаче