UNPKG

phaser3-rex-plugins

Version:
1,657 lines (1,593 loc) 142 kB
(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