Merge pull request #384 from NodeBB/pulling
Move chats to a separate slideout menu on the right side Switched to the Pulling library Moved nav menu to the left side, as is normal elsewhere Added chat button on right side Unread icon on it shows unread chats Added slideout menu on right for only chats Both sides will slide open and everything Switched to drawer menus instead of the previous reveal style menus Restyle menu toggle buttonsmain
commit
0ba6304c0a
@ -1,484 +0,0 @@
|
||||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Slideout=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
var decouple = require('decouple');
|
||||
var Emitter = require('emitter');
|
||||
|
||||
/**
|
||||
* Privates
|
||||
*/
|
||||
var scrollTimeout;
|
||||
var scrolling = false;
|
||||
var doc = window.document;
|
||||
var html = doc.documentElement;
|
||||
var msPointerSupported = window.navigator.msPointerEnabled;
|
||||
var touch = {
|
||||
'start': msPointerSupported ? 'MSPointerDown' : 'touchstart',
|
||||
'move': msPointerSupported ? 'MSPointerMove' : 'touchmove',
|
||||
'end': msPointerSupported ? 'MSPointerUp' : 'touchend'
|
||||
};
|
||||
var prefix = (function prefix() {
|
||||
var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/;
|
||||
var styleDeclaration = doc.getElementsByTagName('script')[0].style;
|
||||
for (var prop in styleDeclaration) {
|
||||
if (regex.test(prop)) {
|
||||
return '-' + prop.match(regex)[0].toLowerCase() + '-';
|
||||
}
|
||||
}
|
||||
// Nothing found so far? Webkit does not enumerate over the CSS properties of the style object.
|
||||
// However (prop in style) returns the correct value, so we'll have to test for
|
||||
// the precence of a specific property
|
||||
if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; }
|
||||
if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; }
|
||||
return '';
|
||||
}());
|
||||
function extend(destination, from) {
|
||||
for (var prop in from) {
|
||||
if (from[prop]) {
|
||||
destination[prop] = from[prop];
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
function inherits(child, uber) {
|
||||
child.prototype = extend(child.prototype || {}, uber.prototype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Slideout constructor
|
||||
*/
|
||||
function Slideout(options) {
|
||||
options = options || {};
|
||||
|
||||
// Sets default values
|
||||
this._startOffsetX = 0;
|
||||
this._currentOffsetX = 0;
|
||||
this._opening = false;
|
||||
this._moved = false;
|
||||
this._opened = false;
|
||||
this._preventOpen = false;
|
||||
this._touch = options.touch === undefined ? true : options.touch && true;
|
||||
|
||||
// Sets panel
|
||||
this.panel = options.panel;
|
||||
this.menu = options.menu;
|
||||
|
||||
// Sets classnames
|
||||
if(this.panel.className.search('slideout-panel') === -1) { this.panel.className += ' slideout-panel'; }
|
||||
if(this.menu.className.search('slideout-menu') === -1) { this.menu.className += ' slideout-menu'; }
|
||||
|
||||
|
||||
// Sets options
|
||||
this._fx = options.fx || 'ease';
|
||||
this._duration = parseInt(options.duration, 10) || 300;
|
||||
this._tolerance = parseInt(options.tolerance, 10) || 70;
|
||||
this._padding = this._translateTo = parseInt(options.padding, 10) || 256;
|
||||
this._orientation = options.side === 'right' ? -1 : 1;
|
||||
this._translateTo *= this._orientation;
|
||||
|
||||
// Init touch events
|
||||
if (this._touch) {
|
||||
this._initTouchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from Emitter
|
||||
*/
|
||||
inherits(Slideout, Emitter);
|
||||
|
||||
/**
|
||||
* Opens the slideout menu.
|
||||
*/
|
||||
Slideout.prototype.open = function() {
|
||||
var self = this;
|
||||
this.emit('beforeopen');
|
||||
if (html.className.search('slideout-open') === -1) { html.className += ' slideout-open'; }
|
||||
this._setTransition();
|
||||
this._translateXTo(this._translateTo);
|
||||
this._opened = true;
|
||||
setTimeout(function() {
|
||||
self.panel.style.transition = self.panel.style['-webkit-transition'] = '';
|
||||
self.emit('open');
|
||||
}, this._duration + 50);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes slideout menu.
|
||||
*/
|
||||
Slideout.prototype.close = function() {
|
||||
var self = this;
|
||||
if (!this.isOpen() && !this._opening) { return this; }
|
||||
this.emit('beforeclose');
|
||||
this._setTransition();
|
||||
this._translateXTo(0);
|
||||
this._opened = false;
|
||||
setTimeout(function() {
|
||||
html.className = html.className.replace(/ slideout-open/, '');
|
||||
self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = '';
|
||||
self.emit('close');
|
||||
}, this._duration + 50);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles (open/close) slideout menu.
|
||||
*/
|
||||
Slideout.prototype.toggle = function() {
|
||||
return this.isOpen() ? this.close() : this.open();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the slideout is currently open, and false if it is closed.
|
||||
*/
|
||||
Slideout.prototype.isOpen = function() {
|
||||
return this._opened;
|
||||
};
|
||||
|
||||
/**
|
||||
* Translates panel and updates currentOffset with a given X point
|
||||
*/
|
||||
Slideout.prototype._translateXTo = function(translateX) {
|
||||
this._currentOffsetX = translateX;
|
||||
this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translate3d(' + translateX + 'px, 0, 0)';
|
||||
};
|
||||
|
||||
/**
|
||||
* Set transition properties
|
||||
*/
|
||||
Slideout.prototype._setTransition = function() {
|
||||
this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._fx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes touch event
|
||||
*/
|
||||
Slideout.prototype._initTouchEvents = function() {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Decouple scroll event
|
||||
*/
|
||||
this._onScrollFn = decouple(doc, 'scroll', function() {
|
||||
if (!self._moved) {
|
||||
clearTimeout(scrollTimeout);
|
||||
scrolling = true;
|
||||
scrollTimeout = setTimeout(function() {
|
||||
scrolling = false;
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Prevents touchmove event if slideout is moving
|
||||
*/
|
||||
this._preventMove = function(eve) {
|
||||
if (self._moved) {
|
||||
eve.preventDefault();
|
||||
}
|
||||
};
|
||||
doc.addEventListener(touch.move, this._preventMove);
|
||||
|
||||
/**
|
||||
* Resets values on touchstart
|
||||
*/
|
||||
this._resetTouchFn = function(eve) {
|
||||
if (typeof eve.touches === 'undefined') { return; }
|
||||
|
||||
self._moved = false;
|
||||
self._opening = false;
|
||||
self._startOffsetX = eve.touches[0].pageX;
|
||||
self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0));
|
||||
};
|
||||
this.panel.addEventListener(touch.start, this._resetTouchFn);
|
||||
|
||||
/**
|
||||
* Resets values on touchcancel
|
||||
*/
|
||||
this._onTouchCancelFn = function() {
|
||||
self._moved = false;
|
||||
self._opening = false;
|
||||
};
|
||||
this.panel.addEventListener('touchcancel', this._onTouchCancelFn);
|
||||
|
||||
/**
|
||||
* Toggles slideout on touchend
|
||||
*/
|
||||
this._onTouchEndFn = function() {
|
||||
if (self._moved) {
|
||||
(self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close();
|
||||
}
|
||||
self._moved = false;
|
||||
};
|
||||
this.panel.addEventListener(touch.end, this._onTouchEndFn);
|
||||
|
||||
/**
|
||||
* Translates panel on touchmove
|
||||
*/
|
||||
this._onTouchMoveFn = function(eve) {
|
||||
self.emit('touchmove', eve.target);
|
||||
if (scrolling || self._preventOpen || typeof eve.touches === 'undefined') { return; }
|
||||
|
||||
var dif_x = eve.touches[0].clientX - self._startOffsetX;
|
||||
var translateX = self._currentOffsetX = dif_x;
|
||||
|
||||
if (Math.abs(translateX) > self._padding) { return; }
|
||||
|
||||
if (Math.abs(dif_x) > 20) {
|
||||
self._opening = true;
|
||||
|
||||
var oriented_dif_x = dif_x * self._orientation;
|
||||
if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) { return; }
|
||||
if (oriented_dif_x <= 0) {
|
||||
translateX = dif_x + self._padding * self._orientation;
|
||||
self._opening = false;
|
||||
}
|
||||
|
||||
if (!self._moved && html.className.search('slideout-open') === -1) {
|
||||
html.className += ' slideout-open';
|
||||
}
|
||||
|
||||
self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translate3d(' + translateX + 'px, 0, 0)';
|
||||
self.emit('translate', translateX, eve.target);
|
||||
self._moved = true;
|
||||
}
|
||||
|
||||
};
|
||||
this.panel.addEventListener(touch.move, this._onTouchMoveFn);
|
||||
};
|
||||
|
||||
Slideout.prototype.enableTouch = function() {
|
||||
this._touch = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
Slideout.prototype.disableTouch = function() {
|
||||
this._touch = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
Slideout.prototype.destroy = function() {
|
||||
// Close before clean
|
||||
this.close();
|
||||
|
||||
// Remove event listeners
|
||||
doc.removeEventListener(touch.move, this._preventMove);
|
||||
this.panel.removeEventListener(touch.start, this._resetTouchFn);
|
||||
this.panel.removeEventListener('touchcancel', this._onTouchCancelFn);
|
||||
this.panel.removeEventListener(touch.end, this._onTouchEndFn);
|
||||
this.panel.removeEventListener(touch.move, this._onTouchMoveFn);
|
||||
doc.removeEventListener('scroll', this._onScrollFn);
|
||||
|
||||
// Remove methods
|
||||
this.open = this.close = function() {};
|
||||
|
||||
// Return the instance so it can be easily dereferenced
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose Slideout
|
||||
*/
|
||||
module.exports = Slideout;
|
||||
|
||||
},{"decouple":2,"emitter":3}],2:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var requestAnimFrame = (function() {
|
||||
return window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
}());
|
||||
|
||||
function decouple(node, event, fn) {
|
||||
var eve,
|
||||
tracking = false;
|
||||
|
||||
function captureEvent(e) {
|
||||
eve = e;
|
||||
track();
|
||||
}
|
||||
|
||||
function track() {
|
||||
if (!tracking) {
|
||||
requestAnimFrame(update);
|
||||
tracking = true;
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
fn.call(node, eve);
|
||||
tracking = false;
|
||||
}
|
||||
|
||||
node.addEventListener(event, captureEvent, false);
|
||||
return captureEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose decouple
|
||||
*/
|
||||
module.exports = decouple;
|
||||
|
||||
},{}],3:[function(require,module,exports){
|
||||
"use strict";
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
exports.__esModule = true;
|
||||
/**
|
||||
* Creates a new instance of Emitter.
|
||||
* @class
|
||||
* @returns {Object} Returns a new instance of Emitter.
|
||||
* @example
|
||||
* // Creates a new instance of Emitter.
|
||||
* var Emitter = require('emitter');
|
||||
*
|
||||
* var emitter = new Emitter();
|
||||
*/
|
||||
|
||||
var Emitter = (function () {
|
||||
function Emitter() {
|
||||
_classCallCheck(this, Emitter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to the collection for the specified event.
|
||||
* @memberof! Emitter.prototype
|
||||
* @function
|
||||
* @param {String} event - The event name.
|
||||
* @param {Function} listener - A listener function to add.
|
||||
* @returns {Object} Returns an instance of Emitter.
|
||||
* @example
|
||||
* // Add an event listener to "foo" event.
|
||||
* emitter.on('foo', listener);
|
||||
*/
|
||||
|
||||
Emitter.prototype.on = function on(event, listener) {
|
||||
// Use the current collection or create it.
|
||||
this._eventCollection = this._eventCollection || {};
|
||||
|
||||
// Use the current collection of an event or create it.
|
||||
this._eventCollection[event] = this._eventCollection[event] || [];
|
||||
|
||||
// Appends the listener into the collection of the given event
|
||||
this._eventCollection[event].push(listener);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a listener to the collection for the specified event that will be called only once.
|
||||
* @memberof! Emitter.prototype
|
||||
* @function
|
||||
* @param {String} event - The event name.
|
||||
* @param {Function} listener - A listener function to add.
|
||||
* @returns {Object} Returns an instance of Emitter.
|
||||
* @example
|
||||
* // Will add an event handler to "foo" event once.
|
||||
* emitter.once('foo', listener);
|
||||
*/
|
||||
|
||||
Emitter.prototype.once = function once(event, listener) {
|
||||
var self = this;
|
||||
|
||||
function fn() {
|
||||
self.off(event, fn);
|
||||
listener.apply(this, arguments);
|
||||
}
|
||||
|
||||
fn.listener = listener;
|
||||
|
||||
this.on(event, fn);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a listener from the collection for the specified event.
|
||||
* @memberof! Emitter.prototype
|
||||
* @function
|
||||
* @param {String} event - The event name.
|
||||
* @param {Function} listener - A listener function to remove.
|
||||
* @returns {Object} Returns an instance of Emitter.
|
||||
* @example
|
||||
* // Remove a given listener.
|
||||
* emitter.off('foo', listener);
|
||||
*/
|
||||
|
||||
Emitter.prototype.off = function off(event, listener) {
|
||||
|
||||
var listeners = undefined;
|
||||
|
||||
// Defines listeners value.
|
||||
if (!this._eventCollection || !(listeners = this._eventCollection[event])) {
|
||||
return this;
|
||||
}
|
||||
|
||||
listeners.forEach(function (fn, i) {
|
||||
if (fn === listener || fn.listener === listener) {
|
||||
// Removes the given listener.
|
||||
listeners.splice(i, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Removes an empty event collection.
|
||||
if (listeners.length === 0) {
|
||||
delete this._eventCollection[event];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute each item in the listener collection in order with the specified data.
|
||||
* @memberof! Emitter.prototype
|
||||
* @function
|
||||
* @param {String} event - The name of the event you want to emit.
|
||||
* @param {...Object} data - Data to pass to the listeners.
|
||||
* @returns {Object} Returns an instance of Emitter.
|
||||
* @example
|
||||
* // Emits the "foo" event with 'param1' and 'param2' as arguments.
|
||||
* emitter.emit('foo', 'param1', 'param2');
|
||||
*/
|
||||
|
||||
Emitter.prototype.emit = function emit(event) {
|
||||
var _this = this;
|
||||
|
||||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
args[_key - 1] = arguments[_key];
|
||||
}
|
||||
|
||||
var listeners = undefined;
|
||||
|
||||
// Defines listeners value.
|
||||
if (!this._eventCollection || !(listeners = this._eventCollection[event])) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Clone listeners
|
||||
listeners = listeners.slice(0);
|
||||
|
||||
listeners.forEach(function (fn) {
|
||||
return fn.apply(_this, args);
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
return Emitter;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Exports Emitter
|
||||
*/
|
||||
exports["default"] = Emitter;
|
||||
module.exports = exports["default"];
|
||||
},{}]},{},[1])(1)
|
||||
});
|
Loading…
Reference in New Issue