diff --git a/html/src/classes/baseClass.js b/html/src/classes/baseClass.js index 9bc2ccfb..963fa3ab 100644 --- a/html/src/classes/baseClass.js +++ b/html/src/classes/baseClass.js @@ -1,5 +1,4 @@ -import _utils from './utils'; -let $utils = new _utils().$utils; +import $utils from './utils'; /* eslint-disable no-unused-vars */ let $app = {}; let API = {}; diff --git a/html/src/classes/utils.js b/html/src/classes/utils.js index 76ea1b91..4518d011 100644 --- a/html/src/classes/utils.js +++ b/html/src/classes/utils.js @@ -1,302 +1,300 @@ -export default class { - $utils = { - removeFromArray(array, item) { - var { length } = array; - for (var i = 0; i < length; ++i) { - if (array[i] === item) { - array.splice(i, 1); - return true; - } +export default { + removeFromArray(array, item) { + var { length } = array; + for (var i = 0; i < length; ++i) { + if (array[i] === item) { + array.splice(i, 1); + return true; } - return false; - }, - - arraysMatch(a, b) { - if (!Array.isArray(a) || !Array.isArray(b)) { - return false; - } - return ( - a.length === b.length && - a.every( - (element, index) => - JSON.stringify(element) === JSON.stringify(b[index]) - ) - ); - }, - - escapeTag(tag) { - var s = String(tag); - return s.replace(/["&'<>]/g, (c) => `&#${c.charCodeAt(0)};`); - }, - - escapeTagRecursive(obj) { - if (typeof obj === 'string') { - return this.escapeTag(obj); - } - if (typeof obj === 'object') { - for (var key in obj) { - obj[key] = this.escapeTagRecursive(obj[key]); - } - } - return obj; - }, - - timeToText(sec) { - var n = Number(sec); - if (isNaN(n)) { - return this.escapeTag(sec); - } - n = Math.floor(n / 1000); - var arr = []; - if (n < 0) { - n = -n; - } - if (n >= 86400) { - arr.push(`${Math.floor(n / 86400)}d`); - n %= 86400; - } - if (n >= 3600) { - arr.push(`${Math.floor(n / 3600)}h`); - n %= 3600; - } - if (n >= 60) { - arr.push(`${Math.floor(n / 60)}m`); - n %= 60; - } - if (arr.length === 0 && n < 60) { - arr.push(`${n}s`); - } - return arr.join(' '); - }, - - textToHex(text) { - var s = String(text); - return s - .split('') - .map((c) => c.charCodeAt(0).toString(16)) - .join(' '); - }, - - commaNumber(num) { - if (!num) { - return '0'; - } - var s = String(Number(num)); - return s.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); - }, - - parseLocation(tag) { - var _tag = String(tag || ''); - var ctx = { - tag: _tag, - isOffline: false, - isPrivate: false, - isTraveling: false, - worldId: '', - instanceId: '', - instanceName: '', - accessType: '', - accessTypeName: '', - region: '', - shortName: '', - userId: null, - hiddenId: null, - privateId: null, - friendsId: null, - groupId: null, - groupAccessType: null, - canRequestInvite: false, - strict: false - }; - if (_tag === 'offline' || _tag === 'offline:offline') { - ctx.isOffline = true; - } else if (_tag === 'private' || _tag === 'private:private') { - ctx.isPrivate = true; - } else if (_tag === 'traveling' || _tag === 'traveling:traveling') { - ctx.isTraveling = true; - } else if (_tag.startsWith('local') === false) { - var sep = _tag.indexOf(':'); - // technically not part of instance id, but might be there when coping id from url so why not support it - var shortNameQualifier = '&shortName='; - var shortNameIndex = _tag.indexOf(shortNameQualifier); - if (shortNameIndex >= 0) { - ctx.shortName = _tag.substr( - shortNameIndex + shortNameQualifier.length - ); - _tag = _tag.substr(0, shortNameIndex); - } - if (sep >= 0) { - ctx.worldId = _tag.substr(0, sep); - ctx.instanceId = _tag.substr(sep + 1); - ctx.instanceId.split('~').forEach((s, i) => { - if (i) { - var A = s.indexOf('('); - var Z = A >= 0 ? s.lastIndexOf(')') : -1; - var key = Z >= 0 ? s.substr(0, A) : s; - var value = A < Z ? s.substr(A + 1, Z - A - 1) : ''; - if (key === 'hidden') { - ctx.hiddenId = value; - } else if (key === 'private') { - ctx.privateId = value; - } else if (key === 'friends') { - ctx.friendsId = value; - } else if (key === 'canRequestInvite') { - ctx.canRequestInvite = true; - } else if (key === 'region') { - ctx.region = value; - } else if (key === 'group') { - ctx.groupId = value; - } else if (key === 'groupAccessType') { - ctx.groupAccessType = value; - } else if (key === 'strict') { - ctx.strict = true; - } - } else { - ctx.instanceName = s; - } - }); - ctx.accessType = 'public'; - if (ctx.privateId !== null) { - if (ctx.canRequestInvite) { - // InvitePlus - ctx.accessType = 'invite+'; - } else { - // InviteOnly - ctx.accessType = 'invite'; - } - ctx.userId = ctx.privateId; - } else if (ctx.friendsId !== null) { - // FriendsOnly - ctx.accessType = 'friends'; - ctx.userId = ctx.friendsId; - } else if (ctx.hiddenId !== null) { - // FriendsOfGuests - ctx.accessType = 'friends+'; - ctx.userId = ctx.hiddenId; - } else if (ctx.groupId !== null) { - // Group - ctx.accessType = 'group'; - } - ctx.accessTypeName = ctx.accessType; - if (ctx.groupAccessType !== null) { - if (ctx.groupAccessType === 'public') { - ctx.accessTypeName = 'groupPublic'; - } else if (ctx.groupAccessType === 'plus') { - ctx.accessTypeName = 'groupPlus'; - } - } - } else { - ctx.worldId = _tag; - } - } - return ctx; - }, - - displayLocation(location, worldName, groupName) { - var text = worldName; - var L = this.parseLocation(location); - if (L.isOffline) { - text = 'Offline'; - } else if (L.isPrivate) { - text = 'Private'; - } else if (L.isTraveling) { - text = 'Traveling'; - } else if (L.worldId) { - if (groupName) { - text = `${worldName} ${L.accessTypeName}(${groupName})`; - } else if (L.instanceId) { - text = `${worldName} ${L.accessTypeName}`; - } - } - return text; - }, - - extractFileId(s) { - var match = String(s).match(/file_[0-9A-Za-z-]+/); - return match ? match[0] : ''; - }, - - extractFileVersion(s) { - var match = /(?:\/file_[0-9A-Za-z-]+\/)([0-9]+)/gi.exec(s); - return match ? match[1] : ''; - }, - - extractVariantVersion(url) { - if (!url) { - return '0'; - } - try { - const params = new URLSearchParams(new URL(url).search); - const version = params.get('v'); - if (version) { - return version; - } - return '0'; - } catch { - return '0'; - } - }, - - buildTreeData(json) { - var node = []; - for (var key in json) { - if (key[0] === '$') { - continue; - } - var value = json[key]; - if (Array.isArray(value) && value.length === 0) { - node.push({ - key, - value: '[]' - }); - } else if ( - value === Object(value) && - Object.keys(value).length === 0 - ) { - node.push({ - key, - value: '{}' - }); - } else if (Array.isArray(value)) { - node.push({ - children: value.map((val, idx) => { - if (val === Object(val)) { - return { - children: this.buildTreeData(val), - key: idx - }; - } - return { - key: idx, - value: val - }; - }), - key - }); - } else if (value === Object(value)) { - node.push({ - children: this.buildTreeData(value), - key - }); - } else { - node.push({ - key, - value: String(value) - }); - } - } - node.sort(function (a, b) { - var A = String(a.key).toUpperCase(); - var B = String(b.key).toUpperCase(); - if (A < B) { - return -1; - } - if (A > B) { - return 1; - } - return 0; - }); - return node; } - }; -} + return false; + }, + + arraysMatch(a, b) { + if (!Array.isArray(a) || !Array.isArray(b)) { + return false; + } + return ( + a.length === b.length && + a.every( + (element, index) => + JSON.stringify(element) === JSON.stringify(b[index]) + ) + ); + }, + + escapeTag(tag) { + var s = String(tag); + return s.replace(/["&'<>]/g, (c) => `&#${c.charCodeAt(0)};`); + }, + + escapeTagRecursive(obj) { + if (typeof obj === 'string') { + return this.escapeTag(obj); + } + if (typeof obj === 'object') { + for (var key in obj) { + obj[key] = this.escapeTagRecursive(obj[key]); + } + } + return obj; + }, + + timeToText(sec) { + var n = Number(sec); + if (isNaN(n)) { + return this.escapeTag(sec); + } + n = Math.floor(n / 1000); + var arr = []; + if (n < 0) { + n = -n; + } + if (n >= 86400) { + arr.push(`${Math.floor(n / 86400)}d`); + n %= 86400; + } + if (n >= 3600) { + arr.push(`${Math.floor(n / 3600)}h`); + n %= 3600; + } + if (n >= 60) { + arr.push(`${Math.floor(n / 60)}m`); + n %= 60; + } + if (arr.length === 0 && n < 60) { + arr.push(`${n}s`); + } + return arr.join(' '); + }, + + textToHex(text) { + var s = String(text); + return s + .split('') + .map((c) => c.charCodeAt(0).toString(16)) + .join(' '); + }, + + commaNumber(num) { + if (!num) { + return '0'; + } + var s = String(Number(num)); + return s.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); + }, + + parseLocation(tag) { + var _tag = String(tag || ''); + var ctx = { + tag: _tag, + isOffline: false, + isPrivate: false, + isTraveling: false, + worldId: '', + instanceId: '', + instanceName: '', + accessType: '', + accessTypeName: '', + region: '', + shortName: '', + userId: null, + hiddenId: null, + privateId: null, + friendsId: null, + groupId: null, + groupAccessType: null, + canRequestInvite: false, + strict: false + }; + if (_tag === 'offline' || _tag === 'offline:offline') { + ctx.isOffline = true; + } else if (_tag === 'private' || _tag === 'private:private') { + ctx.isPrivate = true; + } else if (_tag === 'traveling' || _tag === 'traveling:traveling') { + ctx.isTraveling = true; + } else if (_tag.startsWith('local') === false) { + var sep = _tag.indexOf(':'); + // technically not part of instance id, but might be there when coping id from url so why not support it + var shortNameQualifier = '&shortName='; + var shortNameIndex = _tag.indexOf(shortNameQualifier); + if (shortNameIndex >= 0) { + ctx.shortName = _tag.substr( + shortNameIndex + shortNameQualifier.length + ); + _tag = _tag.substr(0, shortNameIndex); + } + if (sep >= 0) { + ctx.worldId = _tag.substr(0, sep); + ctx.instanceId = _tag.substr(sep + 1); + ctx.instanceId.split('~').forEach((s, i) => { + if (i) { + var A = s.indexOf('('); + var Z = A >= 0 ? s.lastIndexOf(')') : -1; + var key = Z >= 0 ? s.substr(0, A) : s; + var value = A < Z ? s.substr(A + 1, Z - A - 1) : ''; + if (key === 'hidden') { + ctx.hiddenId = value; + } else if (key === 'private') { + ctx.privateId = value; + } else if (key === 'friends') { + ctx.friendsId = value; + } else if (key === 'canRequestInvite') { + ctx.canRequestInvite = true; + } else if (key === 'region') { + ctx.region = value; + } else if (key === 'group') { + ctx.groupId = value; + } else if (key === 'groupAccessType') { + ctx.groupAccessType = value; + } else if (key === 'strict') { + ctx.strict = true; + } + } else { + ctx.instanceName = s; + } + }); + ctx.accessType = 'public'; + if (ctx.privateId !== null) { + if (ctx.canRequestInvite) { + // InvitePlus + ctx.accessType = 'invite+'; + } else { + // InviteOnly + ctx.accessType = 'invite'; + } + ctx.userId = ctx.privateId; + } else if (ctx.friendsId !== null) { + // FriendsOnly + ctx.accessType = 'friends'; + ctx.userId = ctx.friendsId; + } else if (ctx.hiddenId !== null) { + // FriendsOfGuests + ctx.accessType = 'friends+'; + ctx.userId = ctx.hiddenId; + } else if (ctx.groupId !== null) { + // Group + ctx.accessType = 'group'; + } + ctx.accessTypeName = ctx.accessType; + if (ctx.groupAccessType !== null) { + if (ctx.groupAccessType === 'public') { + ctx.accessTypeName = 'groupPublic'; + } else if (ctx.groupAccessType === 'plus') { + ctx.accessTypeName = 'groupPlus'; + } + } + } else { + ctx.worldId = _tag; + } + } + return ctx; + }, + + displayLocation(location, worldName, groupName) { + var text = worldName; + var L = this.parseLocation(location); + if (L.isOffline) { + text = 'Offline'; + } else if (L.isPrivate) { + text = 'Private'; + } else if (L.isTraveling) { + text = 'Traveling'; + } else if (L.worldId) { + if (groupName) { + text = `${worldName} ${L.accessTypeName}(${groupName})`; + } else if (L.instanceId) { + text = `${worldName} ${L.accessTypeName}`; + } + } + return text; + }, + + extractFileId(s) { + var match = String(s).match(/file_[0-9A-Za-z-]+/); + return match ? match[0] : ''; + }, + + extractFileVersion(s) { + var match = /(?:\/file_[0-9A-Za-z-]+\/)([0-9]+)/gi.exec(s); + return match ? match[1] : ''; + }, + + extractVariantVersion(url) { + if (!url) { + return '0'; + } + try { + const params = new URLSearchParams(new URL(url).search); + const version = params.get('v'); + if (version) { + return version; + } + return '0'; + } catch { + return '0'; + } + }, + + buildTreeData(json) { + var node = []; + for (var key in json) { + if (key[0] === '$') { + continue; + } + var value = json[key]; + if (Array.isArray(value) && value.length === 0) { + node.push({ + key, + value: '[]' + }); + } else if ( + value === Object(value) && + Object.keys(value).length === 0 + ) { + node.push({ + key, + value: '{}' + }); + } else if (Array.isArray(value)) { + node.push({ + children: value.map((val, idx) => { + if (val === Object(val)) { + return { + children: this.buildTreeData(val), + key: idx + }; + } + return { + key: idx, + value: val + }; + }), + key + }); + } else if (value === Object(value)) { + node.push({ + children: this.buildTreeData(value), + key + }); + } else { + node.push({ + key, + value: String(value) + }); + } + } + node.sort(function (a, b) { + var A = String(a.key).toUpperCase(); + var B = String(b.key).toUpperCase(); + if (A < B) { + return -1; + } + if (A > B) { + return 1; + } + return 0; + }); + return node; + } +}; diff --git a/html/src/vr.js b/html/src/vr.js index a553ac52..ccc978c8 100644 --- a/html/src/vr.js +++ b/html/src/vr.js @@ -16,12 +16,11 @@ import * as workerTimers from 'worker-timers'; import MarqueeText from 'vue-marquee-text-component'; import * as localizedStrings from './localization/localizedStrings.js'; -import _utils from './classes/utils.js'; +import $utils from './classes/utils.js'; Vue.component('marquee-text', MarqueeText); (async function () { - const $utils = new _utils().$utils; let $app = {}; await CefSharp.BindObjectAsync('AppApiVr');