phaser3-rex-plugins
Version:
1,657 lines (1,593 loc) • 142 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexfirebase = factory());
})(this, (function () { 'use strict';
function _typeof(obj) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
}, _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
var VERSION = '7.19.0';
var GetDefaultUrl = function GetDefaultUrl(version) {
if (version === undefined) {
version = VERSION;
}
return {
app: "https://www.gstatic.com/firebasejs/".concat(version, "/firebase-app.js"),
// auth: `https://www.gstatic.com/firebasejs/${version}/firebase-auth.js`,
database: "https://www.gstatic.com/firebasejs/".concat(version, "/firebase-database.js"),
firestore: "https://www.gstatic.com/firebasejs/".concat(version, "/firebase-firestore.js")
// storage: `https://www.gstatic.com/firebasejs/${version}/firebase-storage.js`,
// analytics: `https://www.gstatic.com/firebasejs/${version}/firebase-analytics.js`,
// functions: `https://www.gstatic.com/firebasejs${version}/firebase-functions.js`,
// messaging: `https://www.gstatic.com/firebasejs/${version}/firebase-messaging.js`,
// performance: `https://www.gstatic.com/firebasejs/${version}/firebase-performance.js`,
// 'remote-config': `https://www.gstatic.com/firebasejs/${version}/firebase-remote-config.js`
};
};
var Clear$1 = function Clear(obj) {
if (_typeof(obj) !== 'object' || obj === null) {
return obj;
}
if (Array.isArray(obj)) {
obj.length = 0;
} else {
for (var key in obj) {
delete obj[key];
}
}
return obj;
};
/**
* Shallow Object Clone. Will not out nested objects.
* @param {object} obj JSON object
* @param {object} ret JSON object to return, set null to return a new object
* @returns {object} this object
*/
var Clone = function Clone(obj, out) {
var objIsArray = Array.isArray(obj);
if (out === undefined) {
out = objIsArray ? [] : {};
} else {
Clear$1(out);
}
if (objIsArray) {
out.length = obj.length;
for (var i = 0, cnt = obj.length; i < cnt; i++) {
out[i] = obj[i];
}
} else {
for (var key in obj) {
out[key] = obj[key];
}
}
return out;
};
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* Creates a new Object using all values from obj1.
*
* Then scans obj2. If a property is found in obj2 that *also* exists in obj1, the value from obj2 is used, otherwise the property is skipped.
*
* @function Phaser.Utils.Objects.MergeRight
* @since 3.0.0
*
* @param {object} obj1 - The first object to merge.
* @param {object} obj2 - The second object to merge. Keys from this object which also exist in `obj1` will be copied to `obj1`.
*
* @return {object} The merged object. `obj1` and `obj2` are not modified.
*/
var MergeRight = function MergeRight(obj1, obj2) {
var clone = Clone(obj1);
for (var key in obj2) {
if (clone.hasOwnProperty(key)) {
clone[key] = obj2[key];
}
}
return clone;
};
var LoadScript = function LoadScript(url, onload) {
var scripts = document.getElementsByTagName('script');
for (var i = 0, cnt = scripts.length; i < cnt; i++) {
if (scripts[i].src.indexOf(url) != -1) {
if (onload) {
onload();
}
return;
}
}
var newScriptTag = document.createElement('script');
newScriptTag.setAttribute('src', url);
if (onload) {
newScriptTag.onload = onload;
}
document.head.appendChild(newScriptTag);
};
var LoadScriptPromise = function LoadScriptPromise(url) {
return new Promise(function (resolve, reject) {
LoadScript(url, resolve);
});
};
var Delay = function Delay(time, result) {
if (time === undefined) {
time = 0;
}
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(result);
}, time);
});
};
var AvailableTestPromise = function AvailableTestPromise(config) {
if (AvailableTest(config)) {
return Promise.resolve();
}
// console.log('test again')
return Delay(10).then(function () {
return AvailableTestPromise(config);
});
};
var AvailableTest = function AvailableTest(config) {
var testCallback;
for (var k in config) {
if (!config[k]) {
continue;
}
testCallback = TestCallbacks[k];
if (testCallback && !testCallback()) {
return false;
}
}
return true;
};
var TestCallbacks = {
database: function database() {
return firebase.database !== undefined;
},
firestore: function firestore() {
return firebase.firestore !== undefined;
}
};
var Preload = function Preload(urlConfig, firebaseConfig) {
if (typeof urlConfig === 'string') {
// Get specific version
urlConfig = GetDefaultUrl(urlConfig);
} else {
// Get default version
urlConfig = MergeRight(GetDefaultUrl(), urlConfig);
}
return LoadScriptPromise(urlConfig.app) // Load firebase-app
.then(function () {
// Load other SDK
var promises = [];
var url;
for (var k in urlConfig) {
if (k === 'app') {
continue;
}
url = urlConfig[k];
if (!url) {
continue;
}
promises.push(LoadScriptPromise(url));
}
if (promises.length === 0) {
return Promise.resolve();
} else {
return Promise.all(promises);
}
}).then(function () {
// Wait until all vairalbe are available
return AvailableTestPromise(urlConfig);
}).then(function () {
if (firebaseConfig !== undefined) {
firebase.initializeApp(firebaseConfig);
}
return Promise.resolve();
});
};
var ObjectFactory = /*#__PURE__*/function () {
function ObjectFactory() {
_classCallCheck(this, ObjectFactory);
}
_createClass(ObjectFactory, [{
key: "initializeApp",
value: function initializeApp(config) {
firebase.initializeApp(config);
return this;
}
}], [{
key: "register",
value: function register(type, callback) {
ObjectFactory.prototype[type] = callback;
}
}]);
return ObjectFactory;
}();
var EventEmitterMethods = {
setEventEmitter: function setEventEmitter(eventEmitter, EventEmitterClass) {
if (EventEmitterClass === undefined) {
EventEmitterClass = Phaser.Events.EventEmitter; // Use built-in EventEmitter class by default
}
this._privateEE = eventEmitter === true || eventEmitter === undefined;
this._eventEmitter = this._privateEE ? new EventEmitterClass() : eventEmitter;
return this;
},
destroyEventEmitter: function destroyEventEmitter() {
if (this._eventEmitter && this._privateEE) {
this._eventEmitter.shutdown();
}
return this;
},
getEventEmitter: function getEventEmitter() {
return this._eventEmitter;
},
on: function on() {
if (this._eventEmitter) {
this._eventEmitter.on.apply(this._eventEmitter, arguments);
}
return this;
},
once: function once() {
if (this._eventEmitter) {
this._eventEmitter.once.apply(this._eventEmitter, arguments);
}
return this;
},
off: function off() {
if (this._eventEmitter) {
this._eventEmitter.off.apply(this._eventEmitter, arguments);
}
return this;
},
emit: function emit(event) {
if (this._eventEmitter && event) {
this._eventEmitter.emit.apply(this._eventEmitter, arguments);
}
return this;
},
addListener: function addListener() {
if (this._eventEmitter) {
this._eventEmitter.addListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeListener: function removeListener() {
if (this._eventEmitter) {
this._eventEmitter.removeListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeAllListeners: function removeAllListeners() {
if (this._eventEmitter) {
this._eventEmitter.removeAllListeners.apply(this._eventEmitter, arguments);
}
return this;
},
listenerCount: function listenerCount() {
if (this._eventEmitter) {
return this._eventEmitter.listenerCount.apply(this._eventEmitter, arguments);
}
return 0;
},
listeners: function listeners() {
if (this._eventEmitter) {
return this._eventEmitter.listeners.apply(this._eventEmitter, arguments);
}
return [];
},
eventNames: function eventNames() {
if (this._eventEmitter) {
return this._eventEmitter.eventNames.apply(this._eventEmitter, arguments);
}
return [];
}
};
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
// Source object
// The key as a string, or an array of keys, i.e. 'banner', or 'banner.hideBanner'
// The default value to use if the key doesn't exist
/**
* Retrieves a value from an object.
*
* @function Phaser.Utils.Objects.GetValue
* @since 3.0.0
*
* @param {object} source - The object to retrieve the value from.
* @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
* @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
*
* @return {*} The value of the requested key.
*/
var GetValue = function GetValue(source, key, defaultValue) {
if (!source || typeof source === 'number') {
return defaultValue;
} else if (source.hasOwnProperty(key)) {
return source[key];
} else if (key.indexOf('.') !== -1) {
var keys = key.split('.');
var parent = source;
var value = defaultValue;
// Use for loop here so we can break early
for (var i = 0; i < keys.length; i++) {
if (parent.hasOwnProperty(keys[i])) {
// Yes it has a key property, let's carry on down
value = parent[keys[i]];
parent = parent[keys[i]];
} else {
// Can't go any further, so reset to default
value = defaultValue;
break;
}
}
return value;
} else {
return defaultValue;
}
};
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* This is a slightly modified version of jQuery.isPlainObject.
* A plain object is an object whose internal class property is [object Object].
*
* @function Phaser.Utils.Objects.IsPlainObject
* @since 3.0.0
*
* @param {object} obj - The object to inspect.
*
* @return {boolean} `true` if the object is plain, otherwise `false`.
*/
var IsPlainObject = function IsPlainObject(obj) {
// Not plain objects:
// - Any object or value whose internal [[Class]] property is not "[object Object]"
// - DOM nodes
// - window
if (_typeof(obj) !== 'object' || obj.nodeType || obj === obj.window) {
return false;
}
// Support: Firefox <20
// The try/catch suppresses exceptions thrown when attempting to access
// the "constructor" property of certain host objects, ie. |window.location|
// https://bugzilla.mozilla.org/show_bug.cgi?id=814622
try {
if (obj.constructor && !{}.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {
return false;
}
} catch (e) {
return false;
}
// If the function hasn't returned already, we're confident that
// |obj| is a plain object, created by {} or constructed with new Object
return true;
};
var Send$1 = function Send(message) {
if (!this.sendToRef || this.sendToRef.key !== this.receiverID) {
this.sendToRef = this.database.ref(this.rootPath).child(this.receiverID);
}
// Clear message
if (message === undefined) {
return this.sendToRef.remove(); // Promise
}
var d = {
message: message,
senderID: this.userID,
stamp: this.stamp
};
if (this.userName !== undefined) {
d.senderName = this.userName;
}
this.skipFirst = false;
this.stamp = !this.stamp;
return this.sendToRef.set(d);
};
var methods$8 = {
startReceiving: function startReceiving() {
if (this.isReceiving && this.receiverRef.key === this.receiverID) {
return this;
}
this.stopReceiving();
this.isReceiving = true;
this.skipFirst = true; // Skip previous message
this.receiverRef = this.database.ref(this.rootPath).child(this.receiverID);
this.receiverRef.on('value', OnReceive, this);
this.receiverRef.onDisconnect().remove();
return this;
},
stopReceiving: function stopReceiving() {
if (!this.isReceiving) {
return this;
}
this.isReceiving = false;
this.receiverRef.off('value', OnReceive, this);
this.receiverRef.remove();
this.receiverRef.onDisconnect().cancel();
return this;
}
};
var OnReceive = function OnReceive(snapshot) {
if (this.skipFirst) {
this.skipFirst = false;
return;
}
var d = snapshot.val();
if (d == null) {
return;
}
delete d.stamp;
this.history.add(d);
this.emit(this.eventNameMap.receive, d);
};
var History = /*#__PURE__*/function () {
function History(config) {
_classCallCheck(this, History);
this.maxLength = GetValue(config, 'maxLength', -1); // -1: Infinity
this.records = [];
}
_createClass(History, [{
key: "add",
value: function add(record) {
if (this.maxLength === 0) {
return this;
}
this.records.push(record);
if (this.maxLength > 0 && this.records.length > this.maxLength) {
this.records.shift();
}
return this;
}
}, {
key: "clear",
value: function clear() {
this.records.length = 0;
return this;
}
}, {
key: "changeUserName",
value: function changeUserName(userID, userName) {
if (this.maxLength === 0) {
return this;
}
this.records.forEach(function (record) {
if (record.senderID === userID) {
record.senderName = userName;
}
});
return this;
}
}]);
return History;
}();
var Broadcast = /*#__PURE__*/function () {
function Broadcast(config) {
_classCallCheck(this, Broadcast);
// Event emitter
var eventEmitter = GetValue(config, 'eventEmitter', undefined);
var EventEmitterClass = GetValue(config, 'EventEmitterClass', undefined);
this.setEventEmitter(eventEmitter, EventEmitterClass);
this.eventNameMap = GetValue(config, 'eventNames', DefaultEventNames$2);
this.database = firebase.database();
this.setRootPath(GetValue(config, 'root', ''));
// Sender
this.skipFirst = true;
this.stamp = false;
this.userInfo = {
userID: '',
userName: undefined
};
this.setSender(GetValue(config, 'senderID', ''), GetValue(config, 'senderName', ''));
this.setReceiver(GetValue(config, 'receiverID', ''));
// Receiver
this.isReceiving = false;
// History messages
var historyMaxLength = GetValue(config, 'history', 0);
if (historyMaxLength === true) {
historyMaxLength = -1;
} else if (historyMaxLength === false) {
historyMaxLength = 0;
}
this.history = new History({
maxLength: historyMaxLength
});
}
_createClass(Broadcast, [{
key: "shutdown",
value: function shutdown() {
this.stopReceiving().destroyEventEmitter();
}
}, {
key: "destroy",
value: function destroy() {
this.shutdown();
}
}, {
key: "userID",
get: function get() {
return this.userInfo.userID;
},
set: function set(value) {
this.userInfo.userID = value;
}
}, {
key: "userName",
get: function get() {
return this.userInfo.userName;
},
set: function set(value) {
this.userInfo.userName = value;
}
}, {
key: "setRootPath",
value: function setRootPath(rootPath) {
this.rootPath = rootPath;
this.sendToRef = undefined;
this.receiverRef = undefined;
return this;
}
}, {
key: "setSender",
value: function setSender(userID, userName) {
if (IsPlainObject(userID)) {
this.userInfo = userID;
} else {
this.userID = userID;
this.userName = userName;
}
return this;
}
}, {
key: "setReceiver",
value: function setReceiver(receiverID) {
this.receiverID = receiverID;
return this;
}
}, {
key: "changeUserName",
value: function changeUserName(userID, userName) {
if (userID === this.userID) {
this.userName = userName;
}
this.history.changeUserName(userID, userName);
return this;
}
}, {
key: "getHistory",
value: function getHistory() {
return this.history.records;
}
}, {
key: "clearHistory",
value: function clearHistory() {
this.history.clear();
return this;
}
}]);
return Broadcast;
}();
var methods$7 = {
send: Send$1
};
Object.assign(Broadcast.prototype, EventEmitterMethods, methods$8, methods$7);
var DefaultEventNames$2 = {
receive: 'receive'
};
var IsInValidKey = function IsInValidKey(keys) {
return keys == null || keys === '' || keys.length === 0;
};
var GetEntry$1 = function GetEntry(target, keys, defaultEntry) {
var entry = target;
if (IsInValidKey(keys)) ; else {
if (typeof keys === 'string') {
keys = keys.split('.');
}
var key;
for (var i = 0, cnt = keys.length; i < cnt; i++) {
key = keys[i];
if (entry[key] == null || _typeof(entry[key]) !== 'object') {
var newEntry;
if (i === cnt - 1) {
if (defaultEntry === undefined) {
newEntry = {};
} else {
newEntry = defaultEntry;
}
} else {
newEntry = {};
}
entry[key] = newEntry;
}
entry = entry[key];
}
}
return entry;
};
var SetValue = function SetValue(target, keys, value, delimiter) {
if (delimiter === undefined) {
delimiter = '.';
}
// no object
if (_typeof(target) !== 'object') {
return;
}
// invalid key
else if (IsInValidKey(keys)) {
// don't erase target
if (value == null) {
return;
}
// set target to another object
else if (_typeof(value) === 'object') {
target = value;
}
} else {
if (typeof keys === 'string') {
keys = keys.split(delimiter);
}
var lastKey = keys.pop();
var entry = GetEntry$1(target, keys);
entry[lastKey] = value;
}
return target;
};
ObjectFactory.register('broadcast', function (config) {
return new Broadcast(config);
});
SetValue(window, 'RexPlugins.Fire.Broadcast', Broadcast);
var Methods$9 = {
clear: function clear() {
this.items.length = 0;
Clear$1(this.itemID2Index);
return this;
},
getItems: function getItems() {
return this.items;
},
hasItem: function hasItem(itemID) {
return this.itemID2Index.hasOwnProperty(itemID);
},
getItemIndexFromItemID: function getItemIndexFromItemID(itemID) {
if (itemID == null) {
return null;
}
return this.itemID2Index[itemID];
},
getItemFromItemID: function getItemFromItemID(itemID) {
if (itemID == null) {
return null;
}
var index = this.getItemIndexFromItemID(itemID);
if (index == null) {
return null;
}
return this.items[index];
},
forEach: function forEach(callback, scope) {
this.items.forEach(callback, scope);
return this;
},
updateItemID2Index: function updateItemID2Index() {
Clear$1(this.itemID2Index);
var itemID;
for (var i = 0, cnt = this.items.length; i < cnt; i++) {
itemID = this.items[i][this.keyItemID];
this.itemID2Index[itemID] = i;
}
return this;
}
};
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Removes a single item from an array and returns it without creating gc, like the native splice does.
* Based on code by Mike Reinstein.
*
* @function Phaser.Utils.Array.SpliceOne
* @since 3.0.0
*
* @param {array} array - The array to splice from.
* @param {integer} index - The index of the item which should be spliced.
*
* @return {*} The item which was spliced (removed).
*/
var SpliceOne = function SpliceOne(array, index) {
if (index >= array.length) {
return;
}
var len = array.length - 1;
var item = array[index];
for (var i = index; i < len; i++) {
array[i] = array[i + 1];
}
array.length = len;
return item;
};
var AddChildCallback = function AddChildCallback(snapshot, prevName) {
var item = AddItem.call(this, snapshot, prevName);
this.updateItemID2Index();
this.emit(this.eventNameMap.add, item);
this.emit(this.eventNameMap.update, this.items);
};
var ChangeChildCallback = function ChangeChildCallback(snapshot, prevName) {
var prevItem = RemoveItem.call(this, snapshot);
this.updateItemID2Index();
var newItem = AddItem.call(this, snapshot, prevName);
this.updateItemID2Index();
this.emit(this.eventNameMap.change, newItem, prevItem);
this.emit(this.eventNameMap.update, this.items);
};
var RemoveChildCallback = function RemoveChildCallback(snapshot) {
var item = RemoveItem.call(this, snapshot);
this.updateItemID2Index();
this.emit(this.eventNameMap.remove, item);
this.emit(this.eventNameMap.update, this.items);
};
var GetAllChildrenCallback = function GetAllChildrenCallback(snapshot) {
this.clear();
snapshot.forEach(function (childSnapshot) {
AddItem.call(this, childSnapshot, null, true);
}.bind(this));
this.updateItemID2Index();
this.emit(this.eventNameMap.update, this.items);
};
var AddItem = function AddItem(snapshot, prevName, pushMode) {
var item;
var callback = this.getItemCallback;
var scope = this.getItemCallbackScope;
if (scope) {
item = callback.call(scope, snapshot);
} else {
item = callback(snapshot);
}
if (pushMode) {
this.items.push(item);
return item;
}
if (prevName == null) {
this.items.unshift(item);
} else {
var i = this.itemID2Index[prevName];
if (i === this.items.length - 1) {
this.items.push(item);
} else {
this.items.splice(i + 1, 0, item);
}
}
return item;
};
var RemoveItem = function RemoveItem(snapshot) {
var index = this.itemID2Index[snapshot.key];
var item = SpliceOne(this.items, index);
return item;
};
var Updater$2 = {
start: function start(query) {
this.isUpdating = false;
query.once('value', GetAllChildrenCallback, this);
return this;
},
stop: function stop() {
// Do nothing
return this;
}
};
var Updater$1 = {
start: function start(query) {
query.on('child_added', AddChildCallback, this);
query.on('child_removed', RemoveChildCallback, this);
query.on('child_moved', ChangeChildCallback, this);
query.on('child_changed', ChangeChildCallback, this);
return this;
},
stop: function stop() {
this.query.off('child_added', AddChildCallback, this);
this.query.off('child_removed', RemoveChildCallback, this);
this.query.off('child_moved', ChangeChildCallback, this);
this.query.off('child_changed', ChangeChildCallback, this);
return this;
}
};
var Updater = {
start: function start(query) {
query.on('value', GetAllChildrenCallback, this);
return this;
},
stop: function stop() {
this.query.off('value', GetAllChildrenCallback, this);
return this;
}
};
var ItemList = /*#__PURE__*/function () {
function ItemList(config) {
_classCallCheck(this, ItemList);
// Event emitter
var eventEmitter = GetValue(config, 'eventEmitter', undefined);
var EventEmitterClass = GetValue(config, 'EventEmitterClass', undefined);
this.setEventEmitter(eventEmitter, EventEmitterClass);
this.eventNameMap = GetValue(config, 'eventNames', DefaultEventNames$1);
this.isUpdating = false;
this.items = [];
this.itemID2Index = {};
this.setItemIDKey(GetValue(config, 'itemIDKey', '__itemID__'));
this.setMode(GetValue(config, 'mode', 1));
this.setGetitemCallback(GetValue(config, 'getItemCallback', DefaultGetItemCallback), GetValue(config, 'getItemCallbackScope', this));
this.setQuery(GetValue(config, 'query', undefined));
}
_createClass(ItemList, [{
key: "shutdown",
value: function shutdown() {
this.stopUpdate().clear();
}
}, {
key: "destroy",
value: function destroy() {
this.shutdown();
}
}, {
key: "setItemIDKey",
value: function setItemIDKey(key) {
this.keyItemID = key;
return this;
}
}, {
key: "setMode",
value: function setMode(mode) {
if (typeof mode === 'string') {
mode = MODE[mode];
}
this.mode = mode;
this.updater = Updaters[mode];
return this;
}
}, {
key: "setGetitemCallback",
value: function setGetitemCallback(callback, scope) {
this.getItemCallback = callback;
this.getItemCallbackScope = scope;
return this;
}
}, {
key: "setQuery",
value: function setQuery(query) {
this.query = query;
return this;
}
}, {
key: "startUpdate",
value: function startUpdate(query) {
if (query) {
this.setQuery(query);
} else if (this.query) {
query = this.query;
} else {
// !query && !this.query
return this;
}
this.stopUpdate().clear();
this.isUpdating = true;
this.updater.start.call(this, query);
return this;
}
}, {
key: "stopUpdate",
value: function stopUpdate() {
if (!this.query || !this.isUpdating) {
return this;
}
this.isUpdating = false;
this.updater.stop.call(this);
return this;
}
}]);
return ItemList;
}();
var DefaultGetItemCallback = function DefaultGetItemCallback(snapshot) {
var item = snapshot.val();
item[this.keyItemID] = snapshot.key;
return item;
};
Object.assign(ItemList.prototype, EventEmitterMethods, Methods$9);
var DefaultEventNames$1 = {
update: 'update',
add: 'add',
remove: 'remove',
change: 'change'
};
var Updaters = {
0: Updater$2,
1: Updater$1,
2: Updater
};
var MODE = {
once: 0,
child: 1,
all: 2
};
var Join = function Join(userID, userName) {
if (userID === undefined) {
userID = this.userID;
userName = this.userName;
}
if (this.contains(userID)) {
return Promise.resolve(); // Promise
}
// Prepare data
var d = {
userID: userID,
userName: userName
};
var maxUsers = this.maxUsers;
var rootRef = this.database.ref(this.rootPath);
var userRef = rootRef.push();
return userRef.onDisconnect().remove().then(function () {
return userRef.set(d);
}).then(function () {
return Delay(0);
}).then(function () {
// No user count limitation
if (maxUsers === 0) {
self.isInList = true;
return Promise.resolve();
}
// Has user count limitation
return rootRef.limitToFirst(maxUsers).once('value').then(function (snapshot) {
if (Contains(snapshot, userID)) {
self.isInList = true;
return Promise.resolve();
}
self.isInList = false;
// UserID is not in firstN list
return userRef.remove().then(function () {
return userRef.onDisconnect().cancel();
}).then(function () {
return Promise.reject();
});
});
});
};
var Contains = function Contains(snapshot, userID) {
var result = false;
snapshot.forEach(function (childSnapshot) {
var user = childSnapshot.val();
if (user.userID === userID) {
result = true;
return true;
}
});
return result;
};
var Leave = function Leave(userID) {
if (userID === undefined) {
userID = this.userID;
}
if (!this.contains(userID)) {
return Promise.resolve(); // Promise
}
var itemID = this.userID2ItemID[userID];
var userRef = this.database.ref(this.rootPath).child(itemID);
return userRef.remove(); // Promise
};
var ChangeUserName$2 = function ChangeUserName(userName) {
var self = this;
return new Promise(function (resolve, reject) {
var userRef = self.getUserRef();
if (userRef) {
// Find userRef
resolve(userRef);
} else {
// Query userRef
var query = self.rootRef.orderByChild('userID').equalTo(self.userID);
query.once('child_added').then(function (snapshot) {
resolve(snapshot.ref);
});
}
}).then(function (userRef) {
// Set userName
return userRef.child('userName').set(userName);
}).then(function () {
self.userName = userName;
return Promise.resolve();
});
};
var OnlineUserList = /*#__PURE__*/function () {
function OnlineUserList(config) {
_classCallCheck(this, OnlineUserList);
// Event emitter
var eventEmitter = GetValue(config, 'eventEmitter', undefined);
var EventEmitterClass = GetValue(config, 'EventEmitterClass', undefined);
this.setEventEmitter(eventEmitter, EventEmitterClass);
this.database = firebase.database();
this.setRootPath(GetValue(config, 'root', ''));
this.userInfo = {
userID: '',
userName: ''
};
this.setUser(GetValue(config, 'userID', ''), GetValue(config, 'userName', ''));
this.setMaxUsers(GetValue(config, 'maxUsers', 0));
this.userList = new ItemList({
eventEmitter: this.getEventEmitter(),
itemIDKey: 'joinAt',
eventNames: {
add: GetValue(config, 'eventNames.join', 'join'),
remove: GetValue(config, 'eventNames.leave', 'leave'),
update: GetValue(config, 'eventNames.update', 'update'),
change: GetValue(config, 'eventNames.change', 'change'),
init: GetValue(config, 'eventNames.init', 'init'),
changename: GetValue(config, 'eventNames.changename', 'changename')
}
});
this.isInList = false;
this.userID2ItemID = {};
this.userList.on(this.userList.eventNames.add, function (user) {
this.userID2ItemID[user.userID] = user.joinAt;
if (user.userID === this.userInfo.userID) {
this.emit(this.userList.eventNames.init, this.getUsers());
}
}, this).on(this.userList.eventNames.remove, function (user) {
delete this.userID2ItemID[user.userID];
if (user.userID === this.userID) {
this.isInList = false;
}
}, this).on(this.userList.eventNames.change, function (currUserInfo, prevUserInfo) {
var userID = currUserInfo.userID,
userName = currUserInfo.userName,
prevUserName = prevUserInfo.userName;
if (userName !== prevUserName) {
this.emit(this.userList.eventNames.changename, userID, userName, prevUserName);
}
}, this);
}
_createClass(OnlineUserList, [{
key: "shutdown",
value: function shutdown() {
this.stopUpdate().destroyEventEmitter().leave();
this.userList.shutdown();
}
}, {
key: "destroy",
value: function destroy() {
this.shutdown();
}
}, {
key: "userID",
get: function get() {
return this.userInfo.userID;
},
set: function set(value) {
this.userInfo.userID = value;
}
}, {
key: "userName",
get: function get() {
return this.userInfo.userName;
},
set: function set(value) {
this.userInfo.userName = value;
}
}, {
key: "setRootPath",
value: function setRootPath(rootPath) {
this.rootPath = rootPath;
return this;
}
}, {
key: "rootRef",
get: function get() {
return this.database.ref(this.rootPath);
}
}, {
key: "setUser",
value: function setUser(userID, userName) {
if (IsPlainObject(userID)) {
this.userInfo = userID;
} else {
this.userID = userID;
this.userName = userName;
}
return this;
}
}, {
key: "setMaxUsers",
value: function setMaxUsers(maxUsers) {
this.maxUsers = maxUsers;
return this;
}
}, {
key: "clear",
value: function clear() {
this.userList.clear();
return this;
}
}, {
key: "forEach",
value: function forEach(callback, scope) {
this.userList.forEach(callback, scope);
return this;
}
}, {
key: "isFull",
value: function isFull() {
if (this.maxUsers === 0) {
return false;
}
return this.userList.getItems().length >= this.maxUsers;
}
}, {
key: "isFirstUser",
value: function isFirstUser(userID) {
if (userID === undefined) {
userID = this.userID;
}
var user = this.usersList.getItems()[0];
return user && user.userID === userID;
}
}, {
key: "getUser",
value: function getUser(userID) {
if (userID === undefined) {
userID = this.userID;
}
if (!this.contains(userID)) {
return null;
}
var itemID = this.userID2ItemID[userID];
return this.userList.getItemFromItemID(itemID);
}
}, {
key: "getUsers",
value: function getUsers() {
return this.userList.getItems();
}
}, {
key: "getUserRef",
value: function getUserRef(userID) {
if (userID === undefined) {
userID = this.userID;
}
if (!this.contains(userID)) {
return null;
}
var itemID = this.userID2ItemID[userID];
return this.rootRef.child(itemID);
}
}, {
key: "contains",
value: function contains(userID) {
if (userID === undefined) {
userID = this.userID;
}
return this.userID2ItemID.hasOwnProperty(userID);
}
}, {
key: "startUpdate",
value: function startUpdate() {
var query = this.database.ref(this.rootPath);
if (this.maxUsers > 0) {
query = query.limitToFirst(this.maxUsers);
}
this.userList.startUpdate(query);
return this;
}
}, {
key: "stopUpdate",
value: function stopUpdate() {
this.userList.stopUpdate();
return this;
}
}]);
return OnlineUserList;
}();
var methods$6 = {
join: Join,
leave: Leave,
changeUserName: ChangeUserName$2
};
Object.assign(OnlineUserList.prototype, EventEmitterMethods, methods$6);
ObjectFactory.register('onlineUserList', function (config) {
return new OnlineUserList(config);
});
SetValue(window, 'RexPlugins.Fire.OnlineUserList', OnlineUserList);
var CreateUserList$1 = function CreateUserList(config) {
var userList = new OnlineUserList({
eventEmitter: this.getEventEmitter(),
eventNames: {
join: 'userlist.join',
// Any user join
leave: 'userlist.leave',
// Any user leave
update: 'userlist.update',
// Update user list
change: 'userlist.change',
// Any user(name) change
init: 'userlist.init',
changename: 'userlist.changename'
},
userID: this.userInfo
});
userList.on('userlist.leave', function (user) {
if (user.userID === this.userID) {
OnLeftRoom$1.call(this); // Current user is left or kicked
}
}, this);
this.on('room.join', function () {
userList.startUpdate();
}).on('room.leave', function () {
userList.stopUpdate().clear();
});
return userList;
};
var OnLeftRoom$1 = function OnLeftRoom() {
this.emit('room.leave');
// Clear room info later
var self = this;
setTimeout(function () {
self.roomID = undefined;
self.roomName = undefined;
self.doorState = undefined;
self.leftRoomFlag = false;
}, 0);
};
var CreateRoomList = function CreateRoomList(config) {
var roomList = new ItemList({
eventEmitter: this.getEventEmitter(),
root: this.getRoomFilterRef(),
itemIDKey: 'roomID',
eventNames: {
update: 'roomlist.update',
add: 'roomlist.add',
remove: 'roomlist.remove',
change: 'roomlist.change'
},
mode: 'once'
});
return roomList;
};
var CreateBroadcast$1 = function CreateBroadcast(config) {
var broadcastConfig = GetValue(config, 'broadcast', true);
if (!broadcastConfig) {
return null;
}
var broadcast = new Broadcast({
eventEmitter: this.getEventEmitter(),
eventNames: {
receive: 'broadcast.receive'
},
receiverID: 'boradcast',
senderID: this.userInfo,
history: GetValue(broadcastConfig, 'history', false)
});
this.on('room.join', function (roomConfig) {
broadcast.setRootPath(this.getRoomDataPath(roomConfig.roomID)).startReceiving();
}, this).on('room.leave', function () {
broadcast.stopReceiving();
}, this).on('userlist.changename', function (userID, userName) {
broadcast.changeUserName(userID, userName);
}, this);
return broadcast;
};
var DeepClone = function DeepClone(inObject) {
var outObject;
var value;
var key;
if (inObject == null || _typeof(inObject) !== 'object') {
// inObject is not an object
return inObject;
}
// Create an array or object to hold the values
outObject = Array.isArray(inObject) ? [] : {};
if (IsPlainObject(inObject)) {
for (key in inObject) {
value = inObject[key];
// Recursively (deep) copy for nested objects, including arrays
outObject[key] = DeepClone(value);
}
} else {
outObject = inObject;
}
return outObject;
};
var Tree = /*#__PURE__*/function () {
function Tree(data) {
_classCallCheck(this, Tree);
if (data === undefined) {
data = {};
}
this.data = data;
this.refPath = '';
}
_createClass(Tree, [{
key: "getFullPath",
value: function getFullPath(keys) {
if (typeof keys === 'string') {
if (keys === '.') {
keys = this.refPath;
} else if (keys.startsWith('..')) {
if (this.refPath !== '') {
var refPathKeys = this.refPath.split('.');
refPathKeys.pop();
keys = "".concat(refPathKeys.join('.')).concat(keys.substring(1));
} else {
// this.refPath === ''
keys = keys.substring(2);
}
} else if (keys.startsWith('.')) {
if (this.refPath !== '') {
keys = "".concat(this.refPath).concat(keys);
} else {
// this.refPath === ''
keys = keys.substring(1);
}
}
}
return keys;
}
}, {
key: "setRefPath",
value: function setRefPath(keys) {
if (keys === undefined) {
keys = '';
}
this.refPath = this.getFullPath(keys);
return this;
}
}, {
key: "setValue",
value: function setValue(keys, value) {
if (keys === undefined) {
this.clear(); // No argument
} else if (value === undefined) {
this.data = keys; // JSON keys
} else {
SetValue(this.data, this.getFullPath(keys), value);
}
return this;
}
}, {
key: "getValue",
value: function getValue(keys) {
if (keys === undefined) {
return this.data;
} else {
if (typeof keys === 'string') {
keys = this.getFullPath(keys).split('.');
}
return GetEntry(this.data, keys);
}
}
}, {
key: "cloneValue",
value: function cloneValue(keys) {
return DeepClone(this.getValue(keys));
}
}, {
key: "removeKey",
value: function removeKey(keys) {
if (keys === undefined) {
this.clear();
} else {
if (typeof keys === 'string') {
keys = this.getFullPath(keys).split('.');
}
var lastKey = keys.pop();
var entry = GetEntry(this.data, keys);
if (IsObject(entry)) {
delete entry[lastKey];
}
}
return this;
}
}, {
key: "hasKey",
value: function hasKey(keys) {
if (typeof keys === 'string') {
keys = this.getFullPath(keys).split('.');
}
var lastKey = keys.pop();
var entry = GetEntry(this.data, keys);
if (!IsObject(entry)) {
return false;
}
return entry.hasOwnProperty(lastKey);
}
}, {
key: "clear",
value: function clear() {
Clear$1(this.data);
return this;
}
}, {
key: "clone",
value: function clone(cloneData) {
var data = cloneData ? this.cloneValue() : this.data;
var tree = new Tree(data);
tree.setRefPath(this.refPath);
return tree;
}
}]);
return Tree;
}();
var IsObject = function IsObject(obj) {
return obj != null && _typeof(obj) === 'object';
};
var GetEntry = function GetEntry(data, keys) {
if (keys[0] === '') {
return data;
}
var entry = data;
for (var i = 0, cnt = keys.length; i < cnt; i++) {
if (!IsObject(entry)) {
return undefined;
}
entry = entry[keys[i]];
}
return entry;
};
var BaseUpdater = /*#__PURE__*/function () {
function BaseUpdater(config) {
_classCallCheck(this, BaseUpdater);
// Event emitter
this.setEventEmitter(config.eventEmitter, config.EventEmitterClass);
this.parent = config.parent;
this.key = config.key;
if (this.parent) {
this.fullKeyPath = ExtendKeyPath(this.parent.fullKeyPath, this.key);
} else {
this.fullKeyPath = '';
}
this.type = config.type;
this.eventNameMap = config.eventNames;
this.table = config.table;
this.database = firebase.database();
this.setRootPath();
this.children = {};
}
_createClass(BaseUpdater, [{
key: "shutdown",
value: function shutdown() {
this.stopUpdate().clear().destroyEve