diff --git a/PlexRequests.UI/Content/custom.css b/PlexRequests.UI/Content/custom.css
index a8c70de18..c571269b4 100644
--- a/PlexRequests.UI/Content/custom.css
+++ b/PlexRequests.UI/Content/custom.css
@@ -120,3 +120,6 @@ label {
background-color: #5cb85c !important;
border-color: #5cb85c !important; }
+#movieList .mix {
+ display: none; }
+
diff --git a/PlexRequests.UI/Content/custom.min.css b/PlexRequests.UI/Content/custom.min.css
index 37bb1257f..8385aac7b 100644
--- a/PlexRequests.UI/Content/custom.min.css
+++ b/PlexRequests.UI/Content/custom.min.css
@@ -1 +1 @@
-@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}
\ No newline at end of file
+@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}
\ No newline at end of file
diff --git a/PlexRequests.UI/Content/custom.scss b/PlexRequests.UI/Content/custom.scss
index a87a44a97..e1944c04c 100644
--- a/PlexRequests.UI/Content/custom.scss
+++ b/PlexRequests.UI/Content/custom.scss
@@ -157,3 +157,7 @@ label {
background-color: $success-colour $i;
border-color: $success-colour $i;
}
+
+#movieList .mix{
+ display: none;
+}
\ No newline at end of file
diff --git a/PlexRequests.UI/Content/jquery.mixitup.js b/PlexRequests.UI/Content/jquery.mixitup.js
new file mode 100644
index 000000000..b23a60279
--- /dev/null
+++ b/PlexRequests.UI/Content/jquery.mixitup.js
@@ -0,0 +1,2098 @@
+/**!
+ * MixItUp v2.1.11
+ *
+ * @copyright Copyright 2015 KunkaLabs Limited.
+ * @author KunkaLabs Limited.
+ * @link https://mixitup.kunkalabs.com
+ *
+ * @license Commercial use requires a commercial license.
+ * https://mixitup.kunkalabs.com/licenses/
+ *
+ * Non-commercial use permitted under terms of CC-BY-NC license.
+ * http://creativecommons.org/licenses/by-nc/3.0/
+ */
+
+(function($, undf){
+ 'use strict';
+
+ /**
+ * MixItUp Constructor Function
+ * @constructor
+ * @extends jQuery
+ */
+
+ $.MixItUp = function(){
+ var self = this;
+
+ self._execAction('_constructor', 0);
+
+ $.extend(self, {
+
+ /* Public Properties
+ ---------------------------------------------------------------------- */
+
+ selectors: {
+ target: '.mix',
+ filter: '.filter',
+ sort: '.sort'
+ },
+
+ animation: {
+ enable: true,
+ effects: 'fade scale',
+ duration: 600,
+ easing: 'ease',
+ perspectiveDistance: '3000',
+ perspectiveOrigin: '50% 50%',
+ queue: true,
+ queueLimit: 1,
+ animateChangeLayout: false,
+ animateResizeContainer: true,
+ animateResizeTargets: false,
+ staggerSequence: false,
+ reverseOut: false
+ },
+
+ callbacks: {
+ onMixLoad: false,
+ onMixStart: false,
+ onMixBusy: false,
+ onMixEnd: false,
+ onMixFail: false,
+ _user: false
+ },
+
+ controls: {
+ enable: true,
+ live: false,
+ toggleFilterButtons: false,
+ toggleLogic: 'or',
+ activeClass: 'active'
+ },
+
+ layout: {
+ display: 'inline-block',
+ containerClass: '',
+ containerClassFail: 'fail'
+ },
+
+ load: {
+ filter: 'all',
+ sort: false
+ },
+
+ /* Private Properties
+ ---------------------------------------------------------------------- */
+
+ _$body: null,
+ _$container: null,
+ _$targets: null,
+ _$parent: null,
+ _$sortButtons: null,
+ _$filterButtons: null,
+
+ _suckMode: false,
+ _mixing: false,
+ _sorting: false,
+ _clicking: false,
+ _loading: true,
+ _changingLayout: false,
+ _changingClass: false,
+ _changingDisplay: false,
+
+ _origOrder: [],
+ _startOrder: [],
+ _newOrder: [],
+ _activeFilter: null,
+ _toggleArray: [],
+ _toggleString: '',
+ _activeSort: 'default:asc',
+ _newSort: null,
+ _startHeight: null,
+ _newHeight: null,
+ _incPadding: true,
+ _newDisplay: null,
+ _newClass: null,
+ _targetsBound: 0,
+ _targetsDone: 0,
+ _queue: [],
+
+ _$show: $(),
+ _$hide: $()
+ });
+
+ self._execAction('_constructor', 1);
+ };
+
+ /**
+ * MixItUp Prototype
+ * @override
+ */
+
+ $.MixItUp.prototype = {
+ constructor: $.MixItUp,
+
+ /* Static Properties
+ ---------------------------------------------------------------------- */
+
+ _instances: {},
+ _handled: {
+ _filter: {},
+ _sort: {}
+ },
+ _bound: {
+ _filter: {},
+ _sort: {}
+ },
+ _actions: {},
+ _filters: {},
+
+ /* Static Methods
+ ---------------------------------------------------------------------- */
+
+ /**
+ * Extend
+ * @since 2.1.0
+ * @param {object} new properties/methods
+ * @extends {object} prototype
+ */
+
+ extend: function(extension){
+ for(var key in extension){
+ $.MixItUp.prototype[key] = extension[key];
+ }
+ },
+
+ /**
+ * Add Action
+ * @since 2.1.0
+ * @param {string} hook name
+ * @param {string} namespace
+ * @param {function} function to execute
+ * @param {number} priority
+ * @extends {object} $.MixItUp.prototype._actions
+ */
+
+ addAction: function(hook, name, func, priority){
+ $.MixItUp.prototype._addHook('_actions', hook, name, func, priority);
+ },
+
+ /**
+ * Add Filter
+ * @since 2.1.0
+ * @param {string} hook name
+ * @param {string} namespace
+ * @param {function} function to execute
+ * @param {number} priority
+ * @extends {object} $.MixItUp.prototype._filters
+ */
+
+ addFilter: function(hook, name, func, priority){
+ $.MixItUp.prototype._addHook('_filters', hook, name, func, priority);
+ },
+
+ /**
+ * Add Hook
+ * @since 2.1.0
+ * @param {string} type of hook
+ * @param {string} hook name
+ * @param {function} function to execute
+ * @param {number} priority
+ * @extends {object} $.MixItUp.prototype._filters
+ */
+
+ _addHook: function(type, hook, name, func, priority){
+ var collection = $.MixItUp.prototype[type],
+ obj = {};
+
+ priority = (priority === 1 || priority === 'post') ? 'post' : 'pre';
+
+ obj[hook] = {};
+ obj[hook][priority] = {};
+ obj[hook][priority][name] = func;
+
+ $.extend(true, collection, obj);
+ },
+
+
+ /* Private Methods
+ ---------------------------------------------------------------------- */
+
+ /**
+ * Initialise
+ * @since 2.0.0
+ * @param {object} domNode
+ * @param {object} config
+ */
+
+ _init: function(domNode, config){
+ var self = this;
+
+ self._execAction('_init', 0, arguments);
+
+ config && $.extend(true, self, config);
+
+ self._$body = $('body');
+ self._domNode = domNode;
+ self._$container = $(domNode);
+ self._$container.addClass(self.layout.containerClass);
+ self._id = domNode.id;
+
+ self._platformDetect();
+
+ self._brake = self._getPrefixedCSS('transition', 'none');
+
+ self._refresh(true);
+
+ self._$parent = self._$targets.parent().length ? self._$targets.parent() : self._$container;
+
+ if(self.load.sort){
+ self._newSort = self._parseSort(self.load.sort);
+ self._newSortString = self.load.sort;
+ self._activeSort = self.load.sort;
+ self._sort();
+ self._printSort();
+ }
+
+ self._activeFilter = self.load.filter === 'all' ?
+ self.selectors.target :
+ self.load.filter === 'none' ?
+ '' :
+ self.load.filter;
+
+ self.controls.enable && self._bindHandlers();
+
+ if(self.controls.toggleFilterButtons){
+ self._buildToggleArray();
+
+ for(var i = 0; i < self._toggleArray.length; i++){
+ self._updateControls({filter: self._toggleArray[i], sort: self._activeSort}, true);
+ };
+ } else if(self.controls.enable){
+ self._updateControls({filter: self._activeFilter, sort: self._activeSort});
+ }
+
+ self._filter();
+
+ self._init = true;
+
+ self._$container.data('mixItUp',self);
+
+ self._execAction('_init', 1, arguments);
+
+ self._buildState();
+
+ self._$targets.css(self._brake);
+
+ self._goMix(self.animation.enable);
+ },
+
+ /**
+ * Platform Detect
+ * @since 2.0.0
+ */
+
+ _platformDetect: function(){
+ var self = this,
+ vendorsTrans = ['Webkit', 'Moz', 'O', 'ms'],
+ vendorsRAF = ['webkit', 'moz'],
+ chrome = window.navigator.appVersion.match(/Chrome\/(\d+)\./) || false,
+ ff = typeof InstallTrigger !== 'undefined',
+ prefix = function(el){
+ for (var i = 0; i < vendorsTrans.length; i++){
+ if (vendorsTrans[i] + 'Transition' in el.style){
+ return {
+ prefix: '-'+vendorsTrans[i].toLowerCase()+'-',
+ vendor: vendorsTrans[i]
+ };
+ };
+ };
+ return 'transition' in el.style ? '' : false;
+ },
+ transPrefix = prefix(self._domNode);
+
+ self._execAction('_platformDetect', 0);
+
+ self._chrome = chrome ? parseInt(chrome[1], 10) : false;
+ self._ff = ff ? parseInt(window.navigator.userAgent.match(/rv:([^)]+)\)/)[1]) : false;
+ self._prefix = transPrefix.prefix;
+ self._vendor = transPrefix.vendor;
+ self._suckMode = window.atob && self._prefix ? false : true;
+
+ self._suckMode && (self.animation.enable = false);
+ (self._ff && self._ff <= 4) && (self.animation.enable = false);
+
+ /* Polyfills
+ ---------------------------------------------------------------------- */
+
+ /**
+ * window.requestAnimationFrame
+ */
+
+ for(var x = 0; x < vendorsRAF.length && !window.requestAnimationFrame; x++){
+ window.requestAnimationFrame = window[vendorsRAF[x]+'RequestAnimationFrame'];
+ }
+
+ /**
+ * Object.getPrototypeOf
+ */
+
+ if(typeof Object.getPrototypeOf !== 'function'){
+ if(typeof 'test'.__proto__ === 'object'){
+ Object.getPrototypeOf = function(object){
+ return object.__proto__;
+ };
+ } else {
+ Object.getPrototypeOf = function(object){
+ return object.constructor.prototype;
+ };
+ }
+ }
+
+ /**
+ * Element.nextElementSibling
+ */
+
+ if(self._domNode.nextElementSibling === undf){
+ Object.defineProperty(Element.prototype, 'nextElementSibling',{
+ get: function(){
+ var el = this.nextSibling;
+
+ while(el){
+ if(el.nodeType ===1){
+ return el;
+ }
+ el = el.nextSibling;
+ }
+ return null;
+ }
+ });
+ }
+
+ self._execAction('_platformDetect', 1);
+ },
+
+ /**
+ * Refresh
+ * @since 2.0.0
+ * @param {boolean} init
+ * @param {boolean} force
+ */
+
+ _refresh: function(init, force){
+ var self = this;
+
+ self._execAction('_refresh', 0, arguments);
+
+ self._$targets = self._$container.find(self.selectors.target);
+
+ for(var i = 0; i < self._$targets.length; i++){
+ var target = self._$targets[i];
+
+ if(target.dataset === undf || force){
+
+ target.dataset = {};
+
+ for(var j = 0; j < target.attributes.length; j++){
+
+ var attr = target.attributes[j],
+ name = attr.name,
+ val = attr.value;
+
+ if(name.indexOf('data-') > -1){
+ var dataName = self._helpers._camelCase(name.substring(5,name.length));
+ target.dataset[dataName] = val;
+ }
+ }
+ }
+
+ if(target.mixParent === undf){
+ target.mixParent = self._id;
+ }
+ }
+
+ if(
+ (self._$targets.length && init) ||
+ (!self._origOrder.length && self._$targets.length)
+ ){
+ self._origOrder = [];
+
+ for(var i = 0; i < self._$targets.length; i++){
+ var target = self._$targets[i];
+
+ self._origOrder.push(target);
+ }
+ }
+
+ self._execAction('_refresh', 1, arguments);
+ },
+
+ /**
+ * Bind Handlers
+ * @since 2.0.0
+ */
+
+ _bindHandlers: function(){
+ var self = this,
+ filters = $.MixItUp.prototype._bound._filter,
+ sorts = $.MixItUp.prototype._bound._sort;
+
+ self._execAction('_bindHandlers', 0);
+
+ if(self.controls.live){
+ self._$body
+ .on('click.mixItUp.'+self._id, self.selectors.sort, function(){
+ self._processClick($(this), 'sort');
+ })
+ .on('click.mixItUp.'+self._id, self.selectors.filter, function(){
+ self._processClick($(this), 'filter');
+ });
+ } else {
+ self._$sortButtons = $(self.selectors.sort);
+ self._$filterButtons = $(self.selectors.filter);
+
+ self._$sortButtons.on('click.mixItUp.'+self._id, function(){
+ self._processClick($(this), 'sort');
+ });
+
+ self._$filterButtons.on('click.mixItUp.'+self._id, function(){
+ self._processClick($(this), 'filter');
+ });
+ }
+
+ filters[self.selectors.filter] = (filters[self.selectors.filter] === undf) ? 1 : filters[self.selectors.filter] + 1;
+ sorts[self.selectors.sort] = (sorts[self.selectors.sort] === undf) ? 1 : sorts[self.selectors.sort] + 1;
+
+ self._execAction('_bindHandlers', 1);
+ },
+
+ /**
+ * Process Click
+ * @since 2.0.0
+ * @param {object} $button
+ * @param {string} type
+ */
+
+ _processClick: function($button, type){
+ var self = this,
+ trackClick = function($button, type, off){
+ var proto = $.MixItUp.prototype;
+
+ proto._handled['_'+type][self.selectors[type]] = (proto._handled['_'+type][self.selectors[type]] === undf) ?
+ 1 :
+ proto._handled['_'+type][self.selectors[type]] + 1;
+
+ if(proto._handled['_'+type][self.selectors[type]] === proto._bound['_'+type][self.selectors[type]]){
+ $button[(off ? 'remove' : 'add')+'Class'](self.controls.activeClass);
+ delete proto._handled['_'+type][self.selectors[type]];
+ }
+ };
+
+ self._execAction('_processClick', 0, arguments);
+
+ if(!self._mixing || (self.animation.queue && self._queue.length < self.animation.queueLimit)){
+ self._clicking = true;
+
+ if(type === 'sort'){
+ var sort = $button.attr('data-sort');
+
+ if(!$button.hasClass(self.controls.activeClass) || sort.indexOf('random') > -1){
+ $(self.selectors.sort).removeClass(self.controls.activeClass);
+ trackClick($button, type);
+ self.sort(sort);
+ }
+ }
+
+ if(type === 'filter') {
+ var filter = $button.attr('data-filter'),
+ ndx,
+ seperator = self.controls.toggleLogic === 'or' ? ',' : '';
+
+ if(!self.controls.toggleFilterButtons){
+ if(!$button.hasClass(self.controls.activeClass)){
+ $(self.selectors.filter).removeClass(self.controls.activeClass);
+ trackClick($button, type);
+ self.filter(filter);
+ }
+ } else {
+ self._buildToggleArray();
+
+ if(!$button.hasClass(self.controls.activeClass)){
+ trackClick($button, type);
+
+ self._toggleArray.push(filter);
+ } else {
+ trackClick($button, type, true);
+ ndx = self._toggleArray.indexOf(filter);
+ self._toggleArray.splice(ndx, 1);
+ }
+
+ self._toggleArray = $.grep(self._toggleArray,function(n){return(n);});
+
+ self._toggleString = self._toggleArray.join(seperator);
+
+ self.filter(self._toggleString);
+ }
+ }
+
+ self._execAction('_processClick', 1, arguments);
+ } else {
+ if(typeof self.callbacks.onMixBusy === 'function'){
+ self.callbacks.onMixBusy.call(self._domNode, self._state, self);
+ }
+ self._execAction('_processClickBusy', 1, arguments);
+ }
+ },
+
+ /**
+ * Build Toggle Array
+ * @since 2.0.0
+ */
+
+ _buildToggleArray: function(){
+ var self = this,
+ activeFilter = self._activeFilter.replace(/\s/g, '');
+
+ self._execAction('_buildToggleArray', 0, arguments);
+
+ if(self.controls.toggleLogic === 'or'){
+ self._toggleArray = activeFilter.split(',');
+ } else {
+ self._toggleArray = activeFilter.split('.');
+
+ !self._toggleArray[0] && self._toggleArray.shift();
+
+ for(var i = 0, filter; filter = self._toggleArray[i]; i++){
+ self._toggleArray[i] = '.'+filter;
+ }
+ }
+
+ self._execAction('_buildToggleArray', 1, arguments);
+ },
+
+ /**
+ * Update Controls
+ * @since 2.0.0
+ * @param {object} command
+ * @param {boolean} multi
+ */
+
+ _updateControls: function(command, multi){
+ var self = this,
+ output = {
+ filter: command.filter,
+ sort: command.sort
+ },
+ update = function($el, filter){
+ try {
+ (multi && type === 'filter' && !(output.filter === 'none' || output.filter === '')) ?
+ $el.filter(filter).addClass(self.controls.activeClass) :
+ $el.removeClass(self.controls.activeClass).filter(filter).addClass(self.controls.activeClass);
+ } catch(e) {}
+ },
+ type = 'filter',
+ $el = null;
+
+ self._execAction('_updateControls', 0, arguments);
+
+ (command.filter === undf) && (output.filter = self._activeFilter);
+ (command.sort === undf) && (output.sort = self._activeSort);
+ (output.filter === self.selectors.target) && (output.filter = 'all');
+
+ for(var i = 0; i < 2; i++){
+ $el = self.controls.live ? $(self.selectors[type]) : self['_$'+type+'Buttons'];
+ $el && update($el, '[data-'+type+'="'+output[type]+'"]');
+ type = 'sort';
+ }
+
+ self._execAction('_updateControls', 1, arguments);
+ },
+
+ /**
+ * Filter (private)
+ * @since 2.0.0
+ */
+
+ _filter: function(){
+ var self = this;
+
+ self._execAction('_filter', 0);
+
+ for(var i = 0; i < self._$targets.length; i++){
+ var $target = $(self._$targets[i]);
+
+ if($target.is(self._activeFilter)){
+ self._$show = self._$show.add($target);
+ } else {
+ self._$hide = self._$hide.add($target);
+ }
+ }
+
+ self._execAction('_filter', 1);
+ },
+
+ /**
+ * Sort (private)
+ * @since 2.0.0
+ */
+
+ _sort: function(){
+ var self = this,
+ arrayShuffle = function(oldArray){
+ var newArray = oldArray.slice(),
+ len = newArray.length,
+ i = len;
+
+ while(i--){
+ var p = parseInt(Math.random()*len);
+ var t = newArray[i];
+ newArray[i] = newArray[p];
+ newArray[p] = t;
+ };
+ return newArray;
+ };
+
+ self._execAction('_sort', 0);
+
+ self._startOrder = [];
+
+ for(var i = 0; i < self._$targets.length; i++){
+ var target = self._$targets[i];
+
+ self._startOrder.push(target);
+ }
+
+ switch(self._newSort[0].sortBy){
+ case 'default':
+ self._newOrder = self._origOrder;
+ break;
+ case 'random':
+ self._newOrder = arrayShuffle(self._startOrder);
+ break;
+ case 'custom':
+ self._newOrder = self._newSort[0].order;
+ break;
+ default:
+ self._newOrder = self._startOrder.concat().sort(function(a, b){
+ return self._compare(a, b);
+ });
+ }
+
+ self._execAction('_sort', 1);
+ },
+
+ /**
+ * Compare Algorithm
+ * @since 2.0.0
+ * @param {string|number} a
+ * @param {string|number} b
+ * @param {number} depth (recursion)
+ * @return {number}
+ */
+
+ _compare: function(a, b, depth){
+ depth = depth ? depth : 0;
+
+ var self = this,
+ order = self._newSort[depth].order,
+ getData = function(el){
+ return el.dataset[self._newSort[depth].sortBy] || 0;
+ },
+ attrA = isNaN(getData(a) * 1) ? getData(a).toLowerCase() : getData(a) * 1,
+ attrB = isNaN(getData(b) * 1) ? getData(b).toLowerCase() : getData(b) * 1;
+
+ if(attrA < attrB)
+ return order === 'asc' ? -1 : 1;
+ if(attrA > attrB)
+ return order === 'asc' ? 1 : -1;
+ if(attrA === attrB && self._newSort.length > depth+1)
+ return self._compare(a, b, depth+1);
+
+ return 0;
+ },
+
+ /**
+ * Print Sort
+ * @since 2.0.0
+ * @param {boolean} reset
+ */
+
+ _printSort: function(reset){
+ var self = this,
+ order = reset ? self._startOrder : self._newOrder,
+ targets = self._$parent[0].querySelectorAll(self.selectors.target),
+ nextSibling = targets.length ? targets[targets.length -1].nextElementSibling : null,
+ frag = document.createDocumentFragment();
+
+ self._execAction('_printSort', 0, arguments);
+
+ for(var i = 0; i < targets.length; i++){
+ var target = targets[i],
+ whiteSpace = target.nextSibling;
+
+ if(target.style.position === 'absolute') continue;
+
+ if(whiteSpace && whiteSpace.nodeName === '#text'){
+ self._$parent[0].removeChild(whiteSpace);
+ }
+
+ self._$parent[0].removeChild(target);
+ }
+
+ for(var i = 0; i < order.length; i++){
+ var el = order[i];
+
+ if(self._newSort[0].sortBy === 'default' && self._newSort[0].order === 'desc' && !reset){
+ var firstChild = frag.firstChild;
+ frag.insertBefore(el, firstChild);
+ frag.insertBefore(document.createTextNode(' '), el);
+ } else {
+ frag.appendChild(el);
+ frag.appendChild(document.createTextNode(' '));
+ }
+ }
+
+ nextSibling ?
+ self._$parent[0].insertBefore(frag, nextSibling) :
+ self._$parent[0].appendChild(frag);
+
+ self._execAction('_printSort', 1, arguments);
+ },
+
+ /**
+ * Parse Sort
+ * @since 2.0.0
+ * @param {string} sortString
+ * @return {array} newSort
+ */
+
+ _parseSort: function(sortString){
+ var self = this,
+ rules = typeof sortString === 'string' ? sortString.split(' ') : [sortString],
+ newSort = [];
+
+ for(var i = 0; i < rules.length; i++){
+ var rule = typeof sortString === 'string' ? rules[i].split(':') : ['custom', rules[i]],
+ ruleObj = {
+ sortBy: self._helpers._camelCase(rule[0]),
+ order: rule[1] || 'asc'
+ };
+
+ newSort.push(ruleObj);
+
+ if(ruleObj.sortBy === 'default' || ruleObj.sortBy === 'random') break;
+ }
+
+ return self._execFilter('_parseSort', newSort, arguments);
+ },
+
+ /**
+ * Parse Effects
+ * @since 2.0.0
+ * @return {object} effects
+ */
+
+ _parseEffects: function(){
+ var self = this,
+ effects = {
+ opacity: '',
+ transformIn: '',
+ transformOut: '',
+ filter: ''
+ },
+ parse = function(effect, extract, reverse){
+ if(self.animation.effects.indexOf(effect) > -1){
+ if(extract){
+ var propIndex = self.animation.effects.indexOf(effect+'(');
+ if(propIndex > -1){
+ var str = self.animation.effects.substring(propIndex),
+ match = /\(([^)]+)\)/.exec(str),
+ val = match[1];
+
+ return {val: val};
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ },
+ negate = function(value, invert){
+ if(invert){
+ return value.charAt(0) === '-' ? value.substr(1, value.length) : '-'+value;
+ } else {
+ return value;
+ }
+ },
+ buildTransform = function(key, invert){
+ var transforms = [
+ ['scale', '.01'],
+ ['translateX', '20px'],
+ ['translateY', '20px'],
+ ['translateZ', '20px'],
+ ['rotateX', '90deg'],
+ ['rotateY', '90deg'],
+ ['rotateZ', '180deg'],
+ ];
+
+ for(var i = 0; i < transforms.length; i++){
+ var prop = transforms[i][0],
+ def = transforms[i][1],
+ inverted = invert && prop !== 'scale';
+
+ effects[key] += parse(prop) ? prop+'('+negate(parse(prop, true).val || def, inverted)+') ' : '';
+ }
+ };
+
+ effects.opacity = parse('fade') ? parse('fade',true).val || '0' : '1';
+
+ buildTransform('transformIn');
+
+ self.animation.reverseOut ? buildTransform('transformOut', true) : (effects.transformOut = effects.transformIn);
+
+ effects.transition = {};
+
+ effects.transition = self._getPrefixedCSS('transition','all '+self.animation.duration+'ms '+self.animation.easing+', opacity '+self.animation.duration+'ms linear');
+
+ self.animation.stagger = parse('stagger') ? true : false;
+ self.animation.staggerDuration = parseInt(parse('stagger') ? (parse('stagger',true).val ? parse('stagger',true).val : 100) : 100);
+
+ return self._execFilter('_parseEffects', effects);
+ },
+
+ /**
+ * Build State
+ * @since 2.0.0
+ * @param {boolean} future
+ * @return {object} futureState
+ */
+
+ _buildState: function(future){
+ var self = this,
+ state = {};
+
+ self._execAction('_buildState', 0);
+
+ state = {
+ activeFilter: self._activeFilter === '' ? 'none' : self._activeFilter,
+ activeSort: future && self._newSortString ? self._newSortString : self._activeSort,
+ fail: !self._$show.length && self._activeFilter !== '',
+ $targets: self._$targets,
+ $show: self._$show,
+ $hide: self._$hide,
+ totalTargets: self._$targets.length,
+ totalShow: self._$show.length,
+ totalHide: self._$hide.length,
+ display: future && self._newDisplay ? self._newDisplay : self.layout.display
+ };
+
+ if(future){
+ return self._execFilter('_buildState', state);
+ } else {
+ self._state = state;
+
+ self._execAction('_buildState', 1);
+ }
+ },
+
+ /**
+ * Go Mix
+ * @since 2.0.0
+ * @param {boolean} animate
+ */
+
+ _goMix: function(animate){
+ var self = this,
+ phase1 = function(){
+ if(self._chrome && (self._chrome === 31)){
+ chromeFix(self._$parent[0]);
+ }
+
+ self._setInter();
+
+ phase2();
+ },
+ phase2 = function(){
+ var scrollTop = window.pageYOffset,
+ scrollLeft = window.pageXOffset,
+ docHeight = document.documentElement.scrollHeight;
+
+ self._getInterMixData();
+
+ self._setFinal();
+
+ self._getFinalMixData();
+
+ (window.pageYOffset !== scrollTop) && window.scrollTo(scrollLeft, scrollTop);
+
+ self._prepTargets();
+
+ if(window.requestAnimationFrame){
+ requestAnimationFrame(phase3);
+ } else {
+ setTimeout(function(){
+ phase3();
+ },20);
+ }
+ },
+ phase3 = function(){
+ self._animateTargets();
+
+ if(self._targetsBound === 0){
+ self._cleanUp();
+ }
+ },
+ chromeFix = function(grid){
+ var parent = grid.parentElement,
+ placeholder = document.createElement('div'),
+ frag = document.createDocumentFragment();
+
+ parent.insertBefore(placeholder, grid);
+ frag.appendChild(grid);
+ parent.replaceChild(grid, placeholder);
+ },
+ futureState = self._buildState(true);
+
+ self._execAction('_goMix', 0, arguments);
+
+ !self.animation.duration && (animate = false);
+
+ self._mixing = true;
+
+ self._$container.removeClass(self.layout.containerClassFail);
+
+ if(typeof self.callbacks.onMixStart === 'function'){
+ self.callbacks.onMixStart.call(self._domNode, self._state, futureState, self);
+ }
+
+ self._$container.trigger('mixStart', [self._state, futureState, self]);
+
+ self._getOrigMixData();
+
+ if(animate && !self._suckMode){
+
+ window.requestAnimationFrame ?
+ requestAnimationFrame(phase1) :
+ phase1();
+
+ } else {
+ self._cleanUp();
+ }
+
+ self._execAction('_goMix', 1, arguments);
+ },
+
+ /**
+ * Get Target Data
+ * @since 2.0.0
+ */
+
+ _getTargetData: function(el, stage){
+ var self = this,
+ elStyle;
+
+ el.dataset[stage+'PosX'] = el.offsetLeft;
+ el.dataset[stage+'PosY'] = el.offsetTop;
+
+ if(self.animation.animateResizeTargets){
+ elStyle = !self._suckMode ?
+ window.getComputedStyle(el) :
+ {
+ marginBottom: '',
+ marginRight: ''
+ };
+
+ el.dataset[stage+'MarginBottom'] = parseInt(elStyle.marginBottom);
+ el.dataset[stage+'MarginRight'] = parseInt(elStyle.marginRight);
+ el.dataset[stage+'Width'] = el.offsetWidth;
+ el.dataset[stage+'Height'] = el.offsetHeight;
+ }
+ },
+
+ /**
+ * Get Original Mix Data
+ * @since 2.0.0
+ */
+
+ _getOrigMixData: function(){
+ var self = this,
+ parentStyle = !self._suckMode ? window.getComputedStyle(self._$parent[0]) : {boxSizing: ''},
+ parentBS = parentStyle.boxSizing || parentStyle[self._vendor+'BoxSizing'];
+
+ self._incPadding = (parentBS === 'border-box');
+
+ self._execAction('_getOrigMixData', 0);
+
+ !self._suckMode && (self.effects = self._parseEffects());
+
+ self._$toHide = self._$hide.filter(':visible');
+ self._$toShow = self._$show.filter(':hidden');
+ self._$pre = self._$targets.filter(':visible');
+
+ self._startHeight = self._incPadding ?
+ self._$parent.outerHeight() :
+ self._$parent.height();
+
+ for(var i = 0; i < self._$pre.length; i++){
+ var el = self._$pre[i];
+
+ self._getTargetData(el, 'orig');
+ }
+
+ self._execAction('_getOrigMixData', 1);
+ },
+
+ /**
+ * Set Intermediate Positions
+ * @since 2.0.0
+ */
+
+ _setInter: function(){
+ var self = this;
+
+ self._execAction('_setInter', 0);
+
+ if(self._changingLayout && self.animation.animateChangeLayout){
+ self._$toShow.css('display',self._newDisplay);
+
+ if(self._changingClass){
+ self._$container
+ .removeClass(self.layout.containerClass)
+ .addClass(self._newClass);
+ }
+ } else {
+ self._$toShow.css('display', self.layout.display);
+ }
+
+ self._execAction('_setInter', 1);
+ },
+
+ /**
+ * Get Intermediate Mix Data
+ * @since 2.0.0
+ */
+
+ _getInterMixData: function(){
+ var self = this;
+
+ self._execAction('_getInterMixData', 0);
+
+ for(var i = 0; i < self._$toShow.length; i++){
+ var el = self._$toShow[i];
+
+ self._getTargetData(el, 'inter');
+ }
+
+ for(var i = 0; i < self._$pre.length; i++){
+ var el = self._$pre[i];
+
+ self._getTargetData(el, 'inter');
+ }
+
+ self._execAction('_getInterMixData', 1);
+ },
+
+ /**
+ * Set Final Positions
+ * @since 2.0.0
+ */
+
+ _setFinal: function(){
+ var self = this;
+
+ self._execAction('_setFinal', 0);
+
+ self._sorting && self._printSort();
+
+ self._$toHide.removeStyle('display');
+
+ if(self._changingLayout && self.animation.animateChangeLayout){
+ self._$pre.css('display',self._newDisplay);
+ }
+
+ self._execAction('_setFinal', 1);
+ },
+
+ /**
+ * Get Final Mix Data
+ * @since 2.0.0
+ */
+
+ _getFinalMixData: function(){
+ var self = this;
+
+ self._execAction('_getFinalMixData', 0);
+
+ for(var i = 0; i < self._$toShow.length; i++){
+ var el = self._$toShow[i];
+
+ self._getTargetData(el, 'final');
+ }
+
+ for(var i = 0; i < self._$pre.length; i++){
+ var el = self._$pre[i];
+
+ self._getTargetData(el, 'final');
+ }
+
+ self._newHeight = self._incPadding ?
+ self._$parent.outerHeight() :
+ self._$parent.height();
+
+ self._sorting && self._printSort(true);
+
+ self._$toShow.removeStyle('display');
+
+ self._$pre.css('display',self.layout.display);
+
+ if(self._changingClass && self.animation.animateChangeLayout){
+ self._$container
+ .removeClass(self._newClass)
+ .addClass(self.layout.containerClass);
+ }
+
+ self._execAction('_getFinalMixData', 1);
+ },
+
+ /**
+ * Prepare Targets
+ * @since 2.0.0
+ */
+
+ _prepTargets: function(){
+ var self = this,
+ transformCSS = {
+ _in: self._getPrefixedCSS('transform', self.effects.transformIn),
+ _out: self._getPrefixedCSS('transform', self.effects.transformOut)
+ };
+
+ self._execAction('_prepTargets', 0);
+
+ if(self.animation.animateResizeContainer){
+ self._$parent.css('height',self._startHeight+'px');
+ }
+
+ for(var i = 0; i < self._$toShow.length; i++){
+ var el = self._$toShow[i],
+ $el = $(el);
+
+ el.style.opacity = self.effects.opacity;
+ el.style.display = (self._changingLayout && self.animation.animateChangeLayout) ?
+ self._newDisplay :
+ self.layout.display;
+
+ $el.css(transformCSS._in);
+
+ if(self.animation.animateResizeTargets){
+ el.style.width = el.dataset.finalWidth+'px';
+ el.style.height = el.dataset.finalHeight+'px';
+ el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1)+'px';
+ el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1)+'px';
+ }
+ }
+
+ for(var i = 0; i < self._$pre.length; i++){
+ var el = self._$pre[i],
+ $el = $(el),
+ translate = {
+ x: el.dataset.origPosX - el.dataset.interPosX,
+ y: el.dataset.origPosY - el.dataset.interPosY
+ },
+ transformCSS = self._getPrefixedCSS('transform','translate('+translate.x+'px,'+translate.y+'px)');
+
+ $el.css(transformCSS);
+
+ if(self.animation.animateResizeTargets){
+ el.style.width = el.dataset.origWidth+'px';
+ el.style.height = el.dataset.origHeight+'px';
+
+ if(el.dataset.origWidth - el.dataset.finalWidth){
+ el.style.marginRight = -(el.dataset.origWidth - el.dataset.interWidth) + (el.dataset.origMarginRight * 1)+'px';
+ }
+
+ if(el.dataset.origHeight - el.dataset.finalHeight){
+ el.style.marginBottom = -(el.dataset.origHeight - el.dataset.interHeight) + (el.dataset.origMarginBottom * 1) +'px';
+ }
+ }
+ }
+
+ self._execAction('_prepTargets', 1);
+ },
+
+ /**
+ * Animate Targets
+ * @since 2.0.0
+ */
+
+ _animateTargets: function(){
+ var self = this;
+
+ self._execAction('_animateTargets', 0);
+
+ self._targetsDone = 0;
+ self._targetsBound = 0;
+
+ self._$parent
+ .css(self._getPrefixedCSS('perspective', self.animation.perspectiveDistance+'px'))
+ .css(self._getPrefixedCSS('perspective-origin', self.animation.perspectiveOrigin));
+
+ if(self.animation.animateResizeContainer){
+ self._$parent
+ .css(self._getPrefixedCSS('transition','height '+self.animation.duration+'ms ease'))
+ .css('height',self._newHeight+'px');
+ }
+
+ for(var i = 0; i < self._$toShow.length; i++){
+ var el = self._$toShow[i],
+ $el = $(el),
+ translate = {
+ x: el.dataset.finalPosX - el.dataset.interPosX,
+ y: el.dataset.finalPosY - el.dataset.interPosY
+ },
+ delay = self._getDelay(i),
+ toShowCSS = {};
+
+ el.style.opacity = '';
+
+ for(var j = 0; j < 2; j++){
+ var a = j === 0 ? a = self._prefix : '';
+
+ if(self._ff && self._ff <= 20){
+ toShowCSS[a+'transition-property'] = 'all';
+ toShowCSS[a+'transition-timing-function'] = self.animation.easing+'ms';
+ toShowCSS[a+'transition-duration'] = self.animation.duration+'ms';
+ }
+
+ toShowCSS[a+'transition-delay'] = delay+'ms';
+ toShowCSS[a+'transform'] = 'translate('+translate.x+'px,'+translate.y+'px)';
+ }
+
+ if(self.effects.transform || self.effects.opacity){
+ self._bindTargetDone($el);
+ }
+
+ (self._ff && self._ff <= 20) ?
+ $el.css(toShowCSS) :
+ $el.css(self.effects.transition).css(toShowCSS);
+ }
+
+ for(var i = 0; i < self._$pre.length; i++){
+ var el = self._$pre[i],
+ $el = $(el),
+ translate = {
+ x: el.dataset.finalPosX - el.dataset.interPosX,
+ y: el.dataset.finalPosY - el.dataset.interPosY
+ },
+ delay = self._getDelay(i);
+
+ if(!(
+ el.dataset.finalPosX === el.dataset.origPosX &&
+ el.dataset.finalPosY === el.dataset.origPosY
+ )){
+ self._bindTargetDone($el);
+ }
+
+ $el.css(self._getPrefixedCSS('transition', 'all '+self.animation.duration+'ms '+self.animation.easing+' '+delay+'ms'));
+ $el.css(self._getPrefixedCSS('transform', 'translate('+translate.x+'px,'+translate.y+'px)'));
+
+ if(self.animation.animateResizeTargets){
+ if(el.dataset.origWidth - el.dataset.finalWidth && el.dataset.finalWidth * 1){
+ el.style.width = el.dataset.finalWidth+'px';
+ el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth)+(el.dataset.finalMarginRight * 1)+'px';
+ }
+
+ if(el.dataset.origHeight - el.dataset.finalHeight && el.dataset.finalHeight * 1){
+ el.style.height = el.dataset.finalHeight+'px';
+ el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight)+(el.dataset.finalMarginBottom * 1) +'px';
+ }
+ }
+ }
+
+ if(self._changingClass){
+ self._$container
+ .removeClass(self.layout.containerClass)
+ .addClass(self._newClass);
+ }
+
+ for(var i = 0; i < self._$toHide.length; i++){
+ var el = self._$toHide[i],
+ $el = $(el),
+ delay = self._getDelay(i),
+ toHideCSS = {};
+
+ for(var j = 0; j<2; j++){
+ var a = j === 0 ? a = self._prefix : '';
+
+ toHideCSS[a+'transition-delay'] = delay+'ms';
+ toHideCSS[a+'transform'] = self.effects.transformOut;
+ toHideCSS.opacity = self.effects.opacity;
+ }
+
+ $el.css(self.effects.transition).css(toHideCSS);
+
+ if(self.effects.transform || self.effects.opacity){
+ self._bindTargetDone($el);
+ };
+ }
+
+ self._execAction('_animateTargets', 1);
+
+ },
+
+ /**
+ * Bind Targets TransitionEnd
+ * @since 2.0.0
+ * @param {object} $el
+ */
+
+ _bindTargetDone: function($el){
+ var self = this,
+ el = $el[0];
+
+ self._execAction('_bindTargetDone', 0, arguments);
+
+ if(!el.dataset.bound){
+
+ el.dataset.bound = true;
+ self._targetsBound++;
+
+ $el.on('webkitTransitionEnd.mixItUp transitionend.mixItUp',function(e){
+ if(
+ (e.originalEvent.propertyName.indexOf('transform') > -1 ||
+ e.originalEvent.propertyName.indexOf('opacity') > -1) &&
+ $(e.originalEvent.target).is(self.selectors.target)
+ ){
+ $el.off('.mixItUp');
+ el.dataset.bound = '';
+ self._targetDone();
+ }
+ });
+ }
+
+ self._execAction('_bindTargetDone', 1, arguments);
+ },
+
+ /**
+ * Target Done
+ * @since 2.0.0
+ */
+
+ _targetDone: function(){
+ var self = this;
+
+ self._execAction('_targetDone', 0);
+
+ self._targetsDone++;
+
+ (self._targetsDone === self._targetsBound) && self._cleanUp();
+
+ self._execAction('_targetDone', 1);
+ },
+
+ /**
+ * Clean Up
+ * @since 2.0.0
+ */
+
+ _cleanUp: function(){
+ var self = this,
+ targetStyles = self.animation.animateResizeTargets ?
+ 'transform opacity width height margin-bottom margin-right' :
+ 'transform opacity',
+ unBrake = function(){
+ self._$targets.removeStyle('transition', self._prefix);
+ };
+
+ self._execAction('_cleanUp', 0);
+
+ !self._changingLayout ?
+ self._$show.css('display',self.layout.display) :
+ self._$show.css('display',self._newDisplay);
+
+ self._$targets.css(self._brake);
+
+ self._$targets
+ .removeStyle(targetStyles, self._prefix)
+ .removeAttr('data-inter-pos-x data-inter-pos-y data-final-pos-x data-final-pos-y data-orig-pos-x data-orig-pos-y data-orig-height data-orig-width data-final-height data-final-width data-inter-width data-inter-height data-orig-margin-right data-orig-margin-bottom data-inter-margin-right data-inter-margin-bottom data-final-margin-right data-final-margin-bottom');
+
+ self._$hide.removeStyle('display');
+
+ self._$parent.removeStyle('height transition perspective-distance perspective perspective-origin-x perspective-origin-y perspective-origin perspectiveOrigin', self._prefix);
+
+ if(self._sorting){
+ self._printSort();
+ self._activeSort = self._newSortString;
+ self._sorting = false;
+ }
+
+ if(self._changingLayout){
+ if(self._changingDisplay){
+ self.layout.display = self._newDisplay;
+ self._changingDisplay = false;
+ }
+
+ if(self._changingClass){
+ self._$parent.removeClass(self.layout.containerClass).addClass(self._newClass);
+ self.layout.containerClass = self._newClass;
+ self._changingClass = false;
+ }
+
+ self._changingLayout = false;
+ }
+
+ self._refresh();
+
+ self._buildState();
+
+ if(self._state.fail){
+ self._$container.addClass(self.layout.containerClassFail);
+ }
+
+ self._$show = $();
+ self._$hide = $();
+
+ if(window.requestAnimationFrame){
+ requestAnimationFrame(unBrake);
+ }
+
+ self._mixing = false;
+
+ if(typeof self.callbacks._user === 'function'){
+ self.callbacks._user.call(self._domNode, self._state, self);
+ }
+
+ if(typeof self.callbacks.onMixEnd === 'function'){
+ self.callbacks.onMixEnd.call(self._domNode, self._state, self);
+ }
+
+ self._$container.trigger('mixEnd', [self._state, self]);
+
+ if(self._state.fail){
+ (typeof self.callbacks.onMixFail === 'function') && self.callbacks.onMixFail.call(self._domNode, self._state, self);
+ self._$container.trigger('mixFail', [self._state, self]);
+ }
+
+ if(self._loading){
+ (typeof self.callbacks.onMixLoad === 'function') && self.callbacks.onMixLoad.call(self._domNode, self._state, self);
+ self._$container.trigger('mixLoad', [self._state, self]);
+ }
+
+ if(self._queue.length){
+ self._execAction('_queue', 0);
+
+ self.multiMix(self._queue[0][0],self._queue[0][1],self._queue[0][2]);
+ self._queue.splice(0, 1);
+ }
+
+ self._execAction('_cleanUp', 1);
+
+ self._loading = false;
+ },
+
+ /**
+ * Get Prefixed CSS
+ * @since 2.0.0
+ * @param {string} property
+ * @param {string} value
+ * @param {boolean} prefixValue
+ * @return {object} styles
+ */
+
+ _getPrefixedCSS: function(property, value, prefixValue){
+ var self = this,
+ styles = {},
+ prefix = '',
+ i = -1;
+
+ for(i = 0; i < 2; i++){
+ prefix = i === 0 ? self._prefix : '';
+ prefixValue ? styles[prefix+property] = prefix+value : styles[prefix+property] = value;
+ }
+
+ return self._execFilter('_getPrefixedCSS', styles, arguments);
+ },
+
+ /**
+ * Get Delay
+ * @since 2.0.0
+ * @param {number} i
+ * @return {number} delay
+ */
+
+ _getDelay: function(i){
+ var self = this,
+ n = typeof self.animation.staggerSequence === 'function' ? self.animation.staggerSequence.call(self._domNode, i, self._state) : i,
+ delay = self.animation.stagger ? n * self.animation.staggerDuration : 0;
+
+ return self._execFilter('_getDelay', delay, arguments);
+ },
+
+ /**
+ * Parse MultiMix Arguments
+ * @since 2.0.0
+ * @param {array} args
+ * @return {object} output
+ */
+
+ _parseMultiMixArgs: function(args){
+ var self = this,
+ output = {
+ command: null,
+ animate: self.animation.enable,
+ callback: null
+ };
+
+ for(var i = 0; i < args.length; i++){
+ var arg = args[i];
+
+ if(arg !== null){
+ if(typeof arg === 'object' || typeof arg === 'string'){
+ output.command = arg;
+ } else if(typeof arg === 'boolean'){
+ output.animate = arg;
+ } else if(typeof arg === 'function'){
+ output.callback = arg;
+ }
+ }
+ }
+
+ return self._execFilter('_parseMultiMixArgs', output, arguments);
+ },
+
+ /**
+ * Parse Insert Arguments
+ * @since 2.0.0
+ * @param {array} args
+ * @return {object} output
+ */
+
+ _parseInsertArgs: function(args){
+ var self = this,
+ output = {
+ index: 0,
+ $object: $(),
+ multiMix: {filter: self._state.activeFilter},
+ callback: null
+ };
+
+ for(var i = 0; i < args.length; i++){
+ var arg = args[i];
+
+ if(typeof arg === 'number'){
+ output.index = arg;
+ } else if(typeof arg === 'object' && arg instanceof $){
+ output.$object = arg;
+ } else if(typeof arg === 'object' && self._helpers._isElement(arg)){
+ output.$object = $(arg);
+ } else if(typeof arg === 'object' && arg !== null){
+ output.multiMix = arg;
+ } else if(typeof arg === 'boolean' && !arg){
+ output.multiMix = false;
+ } else if(typeof arg === 'function'){
+ output.callback = arg;
+ }
+ }
+
+ return self._execFilter('_parseInsertArgs', output, arguments);
+ },
+
+ /**
+ * Execute Action
+ * @since 2.0.0
+ * @param {string} methodName
+ * @param {boolean} isPost
+ * @param {array} args
+ */
+
+ _execAction: function(methodName, isPost, args){
+ var self = this,
+ context = isPost ? 'post' : 'pre';
+
+ if(!self._actions.isEmptyObject && self._actions.hasOwnProperty(methodName)){
+ for(var key in self._actions[methodName][context]){
+ self._actions[methodName][context][key].call(self, args);
+ }
+ }
+ },
+
+ /**
+ * Execute Filter
+ * @since 2.0.0
+ * @param {string} methodName
+ * @param {mixed} value
+ * @return {mixed} value
+ */
+
+ _execFilter: function(methodName, value, args){
+ var self = this;
+
+ if(!self._filters.isEmptyObject && self._filters.hasOwnProperty(methodName)){
+ for(var key in self._filters[methodName]){
+ return self._filters[methodName][key].call(self, args);
+ }
+ } else {
+ return value;
+ }
+ },
+
+ /* Helpers
+ ---------------------------------------------------------------------- */
+
+ _helpers: {
+
+ /**
+ * CamelCase
+ * @since 2.0.0
+ * @param {string}
+ * @return {string}
+ */
+
+ _camelCase: function(string){
+ return string.replace(/-([a-z])/g, function(g){
+ return g[1].toUpperCase();
+ });
+ },
+
+ /**
+ * Is Element
+ * @since 2.1.3
+ * @param {object} element to test
+ * @return {boolean}
+ */
+
+ _isElement: function(el){
+ if(window.HTMLElement){
+ return el instanceof HTMLElement;
+ } else {
+ return (
+ el !== null &&
+ el.nodeType === 1 &&
+ el.nodeName === 'string'
+ );
+ }
+ }
+ },
+
+ /* Public Methods
+ ---------------------------------------------------------------------- */
+
+ /**
+ * Is Mixing
+ * @since 2.0.0
+ * @return {boolean}
+ */
+
+ isMixing: function(){
+ var self = this;
+
+ return self._execFilter('isMixing', self._mixing);
+ },
+
+ /**
+ * Filter (public)
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ filter: function(){
+ var self = this,
+ args = self._parseMultiMixArgs(arguments);
+
+ self._clicking && (self._toggleString = '');
+
+ self.multiMix({filter: args.command}, args.animate, args.callback);
+ },
+
+ /**
+ * Sort (public)
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ sort: function(){
+ var self = this,
+ args = self._parseMultiMixArgs(arguments);
+
+ self.multiMix({sort: args.command}, args.animate, args.callback);
+ },
+
+ /**
+ * Change Layout (public)
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ changeLayout: function(){
+ var self = this,
+ args = self._parseMultiMixArgs(arguments);
+
+ self.multiMix({changeLayout: args.command}, args.animate, args.callback);
+ },
+
+ /**
+ * MultiMix
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ multiMix: function(){
+ var self = this,
+ args = self._parseMultiMixArgs(arguments);
+
+ self._execAction('multiMix', 0, arguments);
+
+ if(!self._mixing){
+ if(self.controls.enable && !self._clicking){
+ self.controls.toggleFilterButtons && self._buildToggleArray();
+ self._updateControls(args.command, self.controls.toggleFilterButtons);
+ }
+
+ (self._queue.length < 2) && (self._clicking = false);
+
+ delete self.callbacks._user;
+ if(args.callback) self.callbacks._user = args.callback;
+
+ var sort = args.command.sort,
+ filter = args.command.filter,
+ changeLayout = args.command.changeLayout;
+
+ self._refresh();
+
+ if(sort){
+ self._newSort = self._parseSort(sort);
+ self._newSortString = sort;
+
+ self._sorting = true;
+ self._sort();
+ }
+
+ if(filter !== undf){
+ filter = (filter === 'all') ? self.selectors.target : filter;
+
+ self._activeFilter = filter;
+ }
+
+ self._filter();
+
+ if(changeLayout){
+ self._newDisplay = (typeof changeLayout === 'string') ? changeLayout : changeLayout.display || self.layout.display;
+ self._newClass = changeLayout.containerClass || '';
+
+ if(
+ self._newDisplay !== self.layout.display ||
+ self._newClass !== self.layout.containerClass
+ ){
+ self._changingLayout = true;
+
+ self._changingClass = (self._newClass !== self.layout.containerClass);
+ self._changingDisplay = (self._newDisplay !== self.layout.display);
+ }
+ }
+
+ self._$targets.css(self._brake);
+
+ self._goMix(args.animate ^ self.animation.enable ? args.animate : self.animation.enable);
+
+ self._execAction('multiMix', 1, arguments);
+
+ } else {
+ if(self.animation.queue && self._queue.length < self.animation.queueLimit){
+ self._queue.push(arguments);
+
+ (self.controls.enable && !self._clicking) && self._updateControls(args.command);
+
+ self._execAction('multiMixQueue', 1, arguments);
+
+ } else {
+ if(typeof self.callbacks.onMixBusy === 'function'){
+ self.callbacks.onMixBusy.call(self._domNode, self._state, self);
+ }
+ self._$container.trigger('mixBusy', [self._state, self]);
+
+ self._execAction('multiMixBusy', 1, arguments);
+ }
+ }
+ },
+
+ /**
+ * Insert
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ insert: function(){
+ var self = this,
+ args = self._parseInsertArgs(arguments),
+ callback = (typeof args.callback === 'function') ? args.callback : null,
+ frag = document.createDocumentFragment(),
+ target = (function(){
+ self._refresh();
+
+ if(self._$targets.length){
+ return (args.index < self._$targets.length || !self._$targets.length) ?
+ self._$targets[args.index] :
+ self._$targets[self._$targets.length-1].nextElementSibling;
+ } else {
+ return self._$parent[0].children[0];
+ }
+ })();
+
+ self._execAction('insert', 0, arguments);
+
+ if(args.$object){
+ for(var i = 0; i < args.$object.length; i++){
+ var el = args.$object[i];
+
+ frag.appendChild(el);
+ frag.appendChild(document.createTextNode(' '));
+ }
+
+ self._$parent[0].insertBefore(frag, target);
+ }
+
+ self._execAction('insert', 1, arguments);
+
+ if(typeof args.multiMix === 'object'){
+ self.multiMix(args.multiMix, callback);
+ }
+ },
+
+ /**
+ * Prepend
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ prepend: function(){
+ var self = this,
+ args = self._parseInsertArgs(arguments);
+
+ self.insert(0, args.$object, args.multiMix, args.callback);
+ },
+
+ /**
+ * Append
+ * @since 2.0.0
+ * @param {array} arguments
+ */
+
+ append: function(){
+ var self = this,
+ args = self._parseInsertArgs(arguments);
+
+ self.insert(self._state.totalTargets, args.$object, args.multiMix, args.callback);
+ },
+
+ /**
+ * Get Option
+ * @since 2.0.0
+ * @param {string} string
+ * @return {mixed} value
+ */
+
+ getOption: function(string){
+ var self = this,
+ getProperty = function(obj, prop){
+ var parts = prop.split('.'),
+ last = parts.pop(),
+ l = parts.length,
+ i = 1,
+ current = parts[0] || prop;
+
+ while((obj = obj[current]) && i < l){
+ current = parts[i];
+ i++;
+ }
+
+ if(obj !== undf){
+ return obj[last] !== undf ? obj[last] : obj;
+ }
+ };
+
+ return string ? self._execFilter('getOption', getProperty(self, string), arguments) : self;
+ },
+
+ /**
+ * Set Options
+ * @since 2.0.0
+ * @param {object} config
+ */
+
+ setOptions: function(config){
+ var self = this;
+
+ self._execAction('setOptions', 0, arguments);
+
+ typeof config === 'object' && $.extend(true, self, config);
+
+ self._execAction('setOptions', 1, arguments);
+ },
+
+ /**
+ * Get State
+ * @since 2.0.0
+ * @return {object} state
+ */
+
+ getState: function(){
+ var self = this;
+
+ return self._execFilter('getState', self._state, self);
+ },
+
+ /**
+ * Force Refresh
+ * @since 2.1.2
+ */
+
+ forceRefresh: function(){
+ var self = this;
+
+ self._refresh(false, true);
+ },
+
+ /**
+ * Destroy
+ * @since 2.0.0
+ * @param {boolean} hideAll
+ */
+
+ destroy: function(hideAll){
+ var self = this,
+ filters = $.MixItUp.prototype._bound._filter,
+ sorts = $.MixItUp.prototype._bound._sort;
+
+ self._execAction('destroy', 0, arguments);
+
+ self._$body
+ .add($(self.selectors.sort))
+ .add($(self.selectors.filter))
+ .off('.mixItUp');
+
+ for(var i = 0; i < self._$targets.length; i++){
+ var target = self._$targets[i];
+
+ hideAll && (target.style.display = '');
+
+ delete target.mixParent;
+ }
+
+ self._execAction('destroy', 1, arguments);
+
+ if(filters[self.selectors.filter] && filters[self.selectors.filter] > 1) {
+ filters[self.selectors.filter]--;
+ } else if(filters[self.selectors.filter] === 1) {
+ delete filters[self.selectors.filter];
+ }
+
+ if(sorts[self.selectors.sort] && sorts[self.selectors.sort] > 1) {
+ sorts[self.selectors.sort]--;
+ } else if(sorts[self.selectors.sort] === 1) {
+ delete sorts[self.selectors.sort];
+ }
+
+ delete $.MixItUp.prototype._instances[self._id];
+ }
+
+ };
+
+ /* jQuery Methods
+ ---------------------------------------------------------------------- */
+
+ /**
+ * jQuery .mixItUp() method
+ * @since 2.0.0
+ * @extends $.fn
+ */
+
+ $.fn.mixItUp = function(){
+ var args = arguments,
+ dataReturn = [],
+ eachReturn,
+ _instantiate = function(domNode, settings){
+ var instance = new $.MixItUp(),
+ rand = function(){
+ return ('00000'+(Math.random()*16777216<<0).toString(16)).substr(-6).toUpperCase();
+ };
+
+ instance._execAction('_instantiate', 0, arguments);
+
+ domNode.id = !domNode.id ? 'MixItUp'+rand() : domNode.id;
+
+ if(!instance._instances[domNode.id]){
+ instance._instances[domNode.id] = instance;
+ instance._init(domNode, settings);
+ }
+
+ instance._execAction('_instantiate', 1, arguments);
+ };
+
+ eachReturn = this.each(function(){
+ if(args && typeof args[0] === 'string'){
+ var instance = $.MixItUp.prototype._instances[this.id];
+ if(args[0] === 'isLoaded'){
+ dataReturn.push(instance ? true : false);
+ } else {
+ var data = instance[args[0]](args[1], args[2], args[3]);
+ if(data !== undf)dataReturn.push(data);
+ }
+ } else {
+ _instantiate(this, args[0]);
+ }
+ });
+
+ if(dataReturn.length){
+ return dataReturn.length > 1 ? dataReturn : dataReturn[0];
+ } else {
+ return eachReturn;
+ }
+ };
+
+ /**
+ * jQuery .removeStyle() method
+ * @since 2.0.0
+ * @extends $.fn
+ */
+
+ $.fn.removeStyle = function(style, prefix){
+ prefix = prefix ? prefix : '';
+
+ return this.each(function(){
+ var el = this,
+ styles = style.split(' ');
+
+ for(var i = 0; i < styles.length; i++){
+ for(var j = 0; j < 4; j++){
+ switch (j) {
+ case 0:
+ var prop = styles[i];
+ break;
+ case 1:
+ var prop = $.MixItUp.prototype._helpers._camelCase(prop);
+ break;
+ case 2:
+ var prop = prefix+styles[i];
+ break;
+ case 3:
+ var prop = $.MixItUp.prototype._helpers._camelCase(prefix+styles[i]);
+ }
+
+ if(
+ el.style[prop] !== undf &&
+ typeof el.style[prop] !== 'unknown' &&
+ el.style[prop].length > 0
+ ){
+ el.style[prop] = '';
+ }
+
+ if(!prefix && j === 1)break;
+ }
+ }
+
+ if(el.attributes && el.attributes.style && el.attributes.style !== undf && el.attributes.style.value === ''){
+ el.attributes.removeNamedItem('style');
+ }
+ });
+ };
+
+})(jQuery);
\ No newline at end of file
diff --git a/PlexRequests.UI/Content/requests.js b/PlexRequests.UI/Content/requests.js
index 1a387b86c..1d44e0625 100644
--- a/PlexRequests.UI/Content/requests.js
+++ b/PlexRequests.UI/Content/requests.js
@@ -13,6 +13,7 @@ var tvimer = 0;
movieLoad();
tvLoad();
+
// Approve all
$('#approveAll').click(function () {
$.ajax({
@@ -274,6 +275,15 @@ function movieLoad() {
var html = searchTemplate(context);
$("#movieList").append(html);
});
+ $('#movieList').mixItUp({
+ layout: {
+ display: 'block'
+ },
+ load: {
+ filter: 'all'
+ }
+ });
+
});
};
@@ -286,6 +296,14 @@ function tvLoad() {
var html = searchTemplate(context);
$("#tvList").append(html);
});
+ $('#tvList').mixItUp({
+ layout: {
+ display: 'block'
+ },
+ load: {
+ filter: 'all'
+ }
+ });
});
};
diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj
index 69af5770c..33633179e 100644
--- a/PlexRequests.UI/PlexRequests.UI.csproj
+++ b/PlexRequests.UI/PlexRequests.UI.csproj
@@ -223,6 +223,9 @@