diff --git a/html/app.js b/html/app.js
index d57c211e..db9c28e4 100644
--- a/html/app.js
+++ b/html/app.js
@@ -89,7 +89,9 @@ if (window.CefSharp) {
this.Set(key, JSON.stringify(value));
};
- setInterval(() => VRCXStorage.Flush(), 5 * 60 * 1000);
+ setInterval(function () {
+ VRCXStorage.Flush();
+ }, 5 * 60 * 1000);
Noty.overrideDefaults({
/*
@@ -103,7 +105,7 @@ if (window.CefSharp) {
timeout: 6000
});
- var isObject = (any) => any === Object(any);
+ var isObject = (arg) => arg === Object(arg);
var removeFromArray = function (array, item) {
var { length } = array;
@@ -215,32 +217,31 @@ if (window.CefSharp) {
return;
}
try {
- var { length } = handlers;
- for (var i = 0; i < length; ++i) {
- handlers[i].apply(this, args);
+ for (var handler of handlers) {
+ handler.apply(this, args);
}
} catch (err) {
console.error(err);
}
};
- API.$on = function (name, fx) {
+ API.$on = function (name, fn) {
var handlers = this.eventHandlers.get(name);
if (handlers === undefined) {
handlers = [];
this.eventHandlers.set(name, handlers);
}
- handlers.push(fx);
+ handlers.push(fn);
};
- API.$off = function (name, fx) {
+ API.$off = function (name, fn) {
var handlers = this.eventHandlers.get(name);
if (handlers === undefined) {
return;
}
var { length } = handlers;
for (var i = 0; i < length; ++i) {
- if (handlers[i] === fx) {
+ if (handlers[i] === fn) {
if (length > 1) {
handlers.splice(i, 1);
} else {
@@ -254,52 +255,55 @@ if (window.CefSharp) {
API.pendingGetRequests = new Map();
API.call = function (endpoint, options) {
- var input = `https://api.vrchat.cloud/api/1/${endpoint}`;
+ var resource = `https://api.vrchat.cloud/api/1/${endpoint}`;
var init = {
method: 'GET',
mode: 'cors',
credentials: 'include',
cache: 'no-cache',
+ redirect: 'follow',
referrerPolicy: 'no-referrer',
...options
};
+ var { params } = init;
var isGetRequest = init.method === 'GET';
-
if (isGetRequest) {
// transform body to url
- if (isObject(init.body)) {
- var url = new URL(input);
- for (var key in init.body) {
- url.searchParams.set(key, init.body[key]);
+ if (isObject(params)) {
+ var url = new URL(resource);
+ var { searchParams } = url;
+ for (var key in params) {
+ searchParams.set(key, params[key]);
}
- input = url.toString();
+ resource = url.toString();
}
- delete init.body;
// merge requests
- var request = this.pendingGetRequests.get(input);
- if (request) {
- return request;
+ var req = this.pendingGetRequests.get(resource);
+ if (req !== undefined) {
+ return req;
}
} else {
init.headers = {
'Content-Type': 'application/json;charset=utf-8',
...init.headers
};
- init.body = isObject(init.body)
- ? JSON.stringify(init.body)
+ init.body = isObject(params)
+ ? JSON.stringify(params)
: '{}';
}
-
- var req = fetch(input, init).catch((err) => {
+ var req = fetch(resource, init).catch((err) => {
this.$throw(0, err);
}).then((res) => res.json().catch(() => {
- if (!res.ok) {
- this.$throw(res.status);
- }
- this.$throw(0, 'Invalid JSON');
- }).then((json) => {
if (res.ok) {
- if (json.success) {
+ this.$throw(0, 'Invalid JSON response');
+ }
+ this.$throw(res.status);
+ }).then((json) => {
+ if (isObject(json) === false) {
+ this.$throw(0, 'Invalid JSON response');
+ }
+ if (res.ok) {
+ if (isObject(json.success)) {
new Noty({
type: 'success',
text: escapeTag(json.success.message)
@@ -321,14 +325,12 @@ if (window.CefSharp) {
}
return json;
}));
-
if (isGetRequest) {
req.finally(() => {
- this.pendingGetRequests.delete(input);
+ this.pendingGetRequests.delete(resource);
});
- this.pendingGetRequests.set(input, req);
+ this.pendingGetRequests.set(resource, req);
}
-
return req;
};
@@ -407,9 +409,10 @@ if (window.CefSharp) {
527: 'Railgun Listener to origin error'
};
+ // FIXME : extra를 없애줘
API.$throw = function (code, error, extra) {
var text = [];
- if (code) {
+ if (code > 0) {
var status = this.statusCodes[code];
if (status) {
text.push(`${code} ${status}`);
@@ -437,14 +440,14 @@ if (window.CefSharp) {
if (typeof options.handle === 'function') {
options.handle.call(this, args, options);
}
- if (args.json.length &&
- (options.param.offset += args.json.length,
+ if (args.json.length > 0 &&
+ (options.params.offset += args.json.length,
// eslint-disable-next-line no-nested-ternary
options.N > 0
- ? options.N > options.param.offset
+ ? options.N > options.params.offset
: options.N < 0
? args.json.length
- : options.param.n === args.json.length)) {
+ : options.params.n === args.json.length)) {
this.bulk(options);
} else if (typeof options.done === 'function') {
options.done.call(this, true, options);
@@ -453,7 +456,7 @@ if (window.CefSharp) {
};
API.bulk = function (options) {
- this[options.fn](options.param).catch((err) => {
+ this[options.fn](options.params).catch((err) => {
if (typeof options.done === 'function') {
options.done.call(this, false, options);
}
@@ -466,7 +469,7 @@ if (window.CefSharp) {
API.cachedConfig = {};
API.$on('CONFIG', function (args) {
- args.ref = this.updateConfig(args.json);
+ args.ref = this.applyConfig(args.json);
});
API.getConfig = function () {
@@ -474,6 +477,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json
};
this.$emit('CONFIG', args);
@@ -481,20 +485,21 @@ if (window.CefSharp) {
});
};
- API.updateConfig = function (ref) {
- var ctx = {
+ API.applyConfig = function (json) {
+ var ref = {
clientApiKey: '',
- ...ref
+ ...json
};
- this.cachedConfig = ctx;
- return ctx;
+ this.cachedConfig = ref;
+ return ref;
};
// API: Location
API.parseLocation = function (tag) {
- var L = {
- tag: String(tag || ''),
+ tag = String(tag || '');
+ var ctx = {
+ tag,
isOffline: false,
isPrivate: false,
worldId: '',
@@ -507,16 +512,16 @@ if (window.CefSharp) {
friendsId: null,
canRequestInvite: false
};
- if (L.tag === 'offline') {
- L.isOffline = true;
- } else if (L.tag === 'private') {
- L.isPrivate = true;
- } else if (!L.tag.startsWith('local')) {
- var sep = L.tag.indexOf(':');
+ if (tag === 'offline') {
+ ctx.isOffline = true;
+ } else if (tag === 'private') {
+ ctx.isPrivate = true;
+ } else if (tag.startsWith('local') === false) {
+ var sep = tag.indexOf(':');
if (sep >= 0) {
- L.worldId = L.tag.substr(0, sep);
- L.instanceId = L.tag.substr(sep + 1);
- L.instanceId.split('~').forEach((s, i) => {
+ 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
@@ -529,42 +534,42 @@ if (window.CefSharp) {
? s.substr(A + 1, Z - A - 1)
: '';
if (key === 'hidden') {
- L.hiddenId = value;
+ ctx.hiddenId = value;
} else if (key === 'private') {
- L.privateId = value;
+ ctx.privateId = value;
} else if (key === 'friends') {
- L.friendsId = value;
+ ctx.friendsId = value;
} else if (key === 'canRequestInvite') {
- L.canRequestInvite = true;
+ ctx.canRequestInvite = true;
}
} else {
- L.instanceName = s;
+ ctx.instanceName = s;
}
});
- L.accessType = 'public';
- if (L.privateId !== null) {
- if (L.canRequestInvite) {
+ ctx.accessType = 'public';
+ if (ctx.privateId !== null) {
+ if (ctx.canRequestInvite) {
// InvitePlus
- L.accessType = 'invite+';
+ ctx.accessType = 'invite+';
} else {
// InviteOnly
- L.accessType = 'invite';
+ ctx.accessType = 'invite';
}
- L.userId = L.privateId;
- } else if (L.friendsId !== null) {
+ ctx.userId = ctx.privateId;
+ } else if (ctx.friendsId !== null) {
// FriendsOnly
- L.accessType = 'friends';
- L.userId = L.friendsId;
- } else if (L.hiddenId !== null) {
+ ctx.accessType = 'friends';
+ ctx.userId = ctx.friendsId;
+ } else if (ctx.hiddenId !== null) {
// FriendsOfGuests
- L.accessType = 'friends+';
- L.userId = L.hiddenId;
+ ctx.accessType = 'friends+';
+ ctx.userId = ctx.hiddenId;
}
} else {
- L.worldId = L.tag;
+ ctx.worldId = tag;
}
}
- return L;
+ return ctx;
};
Vue.component('launch', {
@@ -616,25 +621,23 @@ if (window.CefSharp) {
this.text = 'Private';
} else if (L.worldId) {
var ref = API.cachedWorlds.get(L.worldId);
- if (ref) {
- if (L.instanceId) {
- this.text = `${ref.name} #${L.instanceName} ${L.accessType}`;
- } else {
- this.text = ref.name;
- }
- } else {
+ if (ref === undefined) {
API.getWorld({
worldId: L.worldId
}).then((args) => {
if (L.tag === this.location) {
if (L.instanceId) {
- this.text = `${args.ref.name} #${L.instanceName} ${L.accessType}`;
+ this.text = `${args.json.name} #${L.instanceName} ${L.accessType}`;
} else {
- this.text = args.ref.name;
+ this.text = args.json.name;
}
}
return args;
});
+ } else if (L.instanceId) {
+ this.text = `${ref.name} #${L.instanceName} ${L.accessType}`;
+ } else {
+ this.text = ref.name;
}
}
},
@@ -678,16 +681,16 @@ if (window.CefSharp) {
// setNewPassword: PUT auth/password {emailToken: string, id: string, password: string}
API.isLoggedIn = false;
- API.currentUser = {};
API.cachedUsers = new Map();
+ API.currentUser = {};
API.$on('LOGOUT', function () {
- this.isLoggedIn = false;
VRCX.DeleteAllCookies();
+ this.isLoggedIn = false;
});
API.$on('USER:CURRENT', function (args) {
- args.ref = this.updateCurrentUser(args.json);
+ args.ref = this.applyCurrentUser(args.json);
});
API.$on('USER:CURRENT:SAVE', function (args) {
@@ -695,18 +698,21 @@ if (window.CefSharp) {
});
API.$on('USER', function (args) {
- args.ref = this.updateUser(args.json);
+ args.ref = this.applyUser(args.json);
});
API.$on('USER:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('USER', {
- param: {
- userId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('USER', {
+ ref: null,
+ json,
+ params: {
+ userId: json.id
+ }
+ });
+ }
+ }
});
API.logout = function () {
@@ -718,21 +724,22 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
username: string,
password: string
}
*/
- API.login = function (param) {
+ API.login = function (params) {
return this.call(`auth/user?apiKey=${this.cachedConfig.clientApiKey}`, {
method: 'GET',
headers: {
- Authorization: `Basic ${btoa(encodeURIComponent(`${param.username}:${param.password}`).replace(/%([0-9A-F]{2})/gu, (_, s) => String.fromCharCode(parseInt(s, 16))).replace('%', '%25'))}`
+ Authorization: `Basic ${btoa(encodeURIComponent(`${params.username}:${params.password}`).replace(/%([0-9A-F]{2})/gu, (_, s) => String.fromCharCode(parseInt(s, 16))).replace('%', '%25'))}`
}
}).then((json) => {
var args = {
- param,
+ ref: null,
json,
+ params,
origin: true
};
if (json.requiresTwoFactorAuth) {
@@ -745,18 +752,19 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
steamTicket: string
}
*/
- API.loginWithSteam = function (param) {
+ API.loginWithSteam = function (params) {
return this.call(`auth/steam?apiKey=${this.cachedConfig.clientApiKey}`, {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
+ ref: null,
json,
+ params,
origin: true
};
if (json.requiresTwoFactorAuth) {
@@ -769,18 +777,19 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
code: string
}
*/
- API.verifyOTP = function (param) {
+ API.verifyOTP = function (params) {
return this.call('auth/twofactorauth/otp/verify', {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('OTP', args);
return args;
@@ -788,18 +797,19 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
code: string
}
*/
- API.verifyTOTP = function (param) {
+ API.verifyTOTP = function (params) {
return this.call('auth/twofactorauth/totp/verify', {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('TOTP', args);
return args;
@@ -811,6 +821,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json,
origin: true
};
@@ -823,18 +834,16 @@ if (window.CefSharp) {
});
};
- API.updateCurrentUser = function (ref) {
- var ctx = null;
+ API.applyCurrentUser = function (json) {
+ var ref = this.currentUser;
if (this.isLoggedIn) {
- ctx = this.currentUser;
- Object.assign(ctx, ref);
- if (ctx.$homeLocation.tag !== ctx.homeLocation) {
- ctx.$homeLocation = this.parseLocation(ctx.homeLocation);
+ Object.assign(ref, json);
+ if (ref.homeLocation !== ref.$homeLocation.tag) {
+ ref.$homeLocation = this.parseLocation(ref.homeLocation);
}
} else {
- this.isLoggedIn = true;
- ctx = {
- id: ref.id,
+ ref = {
+ id: '',
username: '',
displayName: '',
bio: '',
@@ -858,33 +867,35 @@ if (window.CefSharp) {
onlineFriends: [],
activeFriends: [],
offlineFriends: [],
- // custom
+ // VRCX
$homeLocation: {},
//
- ...ref
+ ...json
};
- ctx.$homeLocation = this.parseLocation(ctx.homeLocation);
- this.currentUser = ctx;
+ ref.$homeLocation = this.parseLocation(ref.homeLocation);
+ this.currentUser = ref;
+ this.isLoggedIn = true;
this.$emit('LOGIN', {
- json: ref,
- ref: ctx
+ json,
+ ref
});
}
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.getUser = function (param) {
- return this.call(`users/${param.userId}`, {
+ API.getUser = function (params) {
+ return this.call(`users/${params.userId}`, {
method: 'GET'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('USER', args);
return args;
@@ -892,63 +903,72 @@ if (window.CefSharp) {
};
var userUpdateQueue = [];
- var userUpdateTimer = false;
- var queueUserUpdate = (args) => {
- userUpdateQueue.push(args);
- if (userUpdateTimer === false) {
- userUpdateTimer = setTimeout(() => {
- userUpdateTimer = false;
- userUpdateQueue.forEach((v) => API.$emit('USER:UPDATE', v));
- userUpdateQueue.length = 0;
- }, 1);
+ var userUpdateTimer = null;
+ var queueUserUpdate = function (ctx) {
+ userUpdateQueue.push(ctx);
+ if (userUpdateTimer !== null) {
+ return;
+ }
+ userUpdateTimer = setTimeout(function () {
+ userUpdateTimer = null;
+ var { length } = userUpdateQueue;
+ for (var i = 0; i < length; ++i) {
+ API.$emit('USER:UPDATE', userUpdateQueue[i]);
+ }
+ userUpdateQueue.length = 0;
+ }, 1);
+ };
+
+ var applyUserTrustLevel = function (ref) {
+ ref.$isVIP = ref.developerType &&
+ ref.developerType !== 'none';
+ ref.$isTroll = false;
+ var { tags } = ref;
+ if (Array.isArray(tags)) {
+ if (tags.includes('admin_moderator')) {
+ ref.$isVIP = true;
+ }
+ if (tags.includes('system_troll') ||
+ tags.includes('system_probable_troll')) {
+ ref.$isTroll = true;
+ }
+ if (tags.includes('system_legend')) {
+ ref.$trustLevel = 'Legendary User';
+ ref.$trustClass = 'x-tag-legendary';
+ } else if (tags.includes('system_trust_legend')) {
+ ref.$trustLevel = 'Veteran User';
+ ref.$trustClass = 'x-tag-legend';
+ } else if (tags.includes('system_trust_veteran')) {
+ ref.$trustLevel = 'Trusted User';
+ ref.$trustClass = 'x-tag-veteran';
+ } else if (tags.includes('system_trust_trusted')) {
+ ref.$trustLevel = 'Known User';
+ ref.$trustClass = 'x-tag-trusted';
+ } else if (tags.includes('system_trust_known')) {
+ ref.$trustLevel = 'User';
+ ref.$trustClass = 'x-tag-known';
+ } else if (tags.includes('system_trust_basic')) {
+ ref.$trustLevel = 'New User';
+ ref.$trustClass = 'x-tag-basic';
+ } else {
+ ref.$trustLevel = 'Visitor';
+ ref.$trustClass = 'x-tag-untrusted';
+ }
+ }
+ if (ref.$isVIP) {
+ ref.$trustLevel = 'VRChat Team';
+ ref.$trustClass = 'x-tag-vip';
+ } else if (ref.$isTroll) {
+ ref.$trustLevel = 'Nuisance';
+ ref.$trustClass = 'x-tag-troll';
}
};
- API.updateUser = function (ref) {
- var ctx = this.cachedUsers.get(ref.id);
- if (ctx) {
- var prop = {};
- for (var key in ctx) {
- if (isObject(ctx[key]) === false) {
- prop[key] = true;
- }
- }
- var _ctx = { ...ctx };
- Object.assign(ctx, ref);
- if (ctx.$location.tag !== ctx.location) {
- ctx.$location = this.parseLocation(ctx.location);
- }
- for (var key in ctx) {
- if (isObject(ctx[key]) === false) {
- prop[key] = true;
- }
- }
- var has = false;
- for (var key in prop) {
- if (ctx[key] === _ctx[key]) {
- delete prop[key];
- } else {
- has = true;
- prop[key] = [
- ctx[key],
- _ctx[key]
- ];
- }
- }
- if (has) {
- if (prop.location) {
- var now = Date.now();
- prop.location.push(now - ctx.$location_at);
- ctx.$location_at = now;
- }
- queueUserUpdate({
- ref: ctx,
- prop
- });
- }
- } else {
- ctx = {
- id: ref.id,
+ API.applyUser = function (json) {
+ var ref = this.cachedUsers.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
username: '',
displayName: '',
bio: '',
@@ -968,81 +988,88 @@ if (window.CefSharp) {
location: '',
worldId: '',
instanceId: '',
- // custom
- $isFriend: false,
+ // VRCX
$location: {},
$location_at: Date.now(),
- $isModerator: false,
+ $isVIP: false,
$isTroll: false,
$trustLevel: 'Visitor',
$trustClass: 'x-tag-untrusted',
//
- ...ref
+ ...json
};
- ctx.$location = this.parseLocation(ctx.location);
- this.cachedUsers.set(ctx.id, ctx);
- }
- ctx.$isModerator = ctx.developerType &&
- ctx.developerType !== 'none';
- if (ctx.tags) {
- ctx.$isModerator = ctx.$isModerator || ctx.tags.includes('admin_moderator');
- ctx.$isTroll = ctx.tags.includes('system_probable_troll') ||
- ctx.tags.includes('system_troll');
- if (ctx.$isTroll) {
- ctx.$trustLevel = 'Nuisance';
- ctx.$trustClass = 'x-tag-troll';
- } else if (ctx.tags.includes('system_legend')) {
- ctx.$trustLevel = 'Legendary User';
- ctx.$trustClass = 'x-tag-legendary';
- } else if (ctx.tags.includes('system_trust_legend')) {
- ctx.$trustLevel = 'Veteran User';
- ctx.$trustClass = 'x-tag-legend';
- } else if (ctx.tags.includes('system_trust_veteran')) {
- ctx.$trustLevel = 'Trusted User';
- ctx.$trustClass = 'x-tag-veteran';
- } else if (ctx.tags.includes('system_trust_trusted')) {
- ctx.$trustLevel = 'Known User';
- ctx.$trustClass = 'x-tag-trusted';
- } else if (ctx.tags.includes('system_trust_known')) {
- ctx.$trustLevel = 'User';
- ctx.$trustClass = 'x-tag-known';
- } else if (ctx.tags.includes('system_trust_basic')) {
- ctx.$trustLevel = 'New User';
- ctx.$trustClass = 'x-tag-basic';
- } else {
- ctx.$trustLevel = 'Visitor';
- ctx.$trustClass = 'x-tag-untrusted';
+ ref.$location = this.parseLocation(ref.location);
+ applyUserTrustLevel(ref);
+ this.cachedUsers.set(ref.id, ref);
+ } else {
+ var props = {};
+ for (var prop in ref) {
+ if (isObject(ref[prop]) === false) {
+ props[prop] = true;
+ }
+ }
+ var $ref = { ...ref };
+ Object.assign(ref, json);
+ if (ref.location !== ref.$location.tag) {
+ ref.$location = this.parseLocation(ref.location);
+ }
+ applyUserTrustLevel(ref);
+ for (var prop in ref) {
+ if (isObject(ref[prop]) === false) {
+ props[prop] = true;
+ }
+ }
+ var has = false;
+ for (var prop in props) {
+ var asis = $ref[prop];
+ var tobe = ref[prop];
+ if (asis === tobe) {
+ delete props[prop];
+ } else {
+ has = true;
+ props[prop] = [
+ tobe,
+ asis
+ ];
+ }
+ }
+ if (has) {
+ if (props.location) {
+ var ts = Date.now();
+ props.location.push(ts - ref.$location_at);
+ ref.$location_at = ts;
+ }
+ queueUserUpdate({
+ ref,
+ props
+ });
}
}
- if (ctx.$isModerator) {
- ctx.$trustLevel = 'VRChat Team';
- ctx.$trustClass = 'x-tag-vip';
- }
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.getCachedUser = function (param) {
+ API.getCachedUser = function (params) {
return new Promise((resolve, reject) => {
- var ctx = this.cachedUsers.get(param.userId);
- if (ctx === undefined) {
- this.getUser(param).catch(reject).then(resolve);
- return;
+ var ref = this.cachedUsers.get(params.userId);
+ if (ref === undefined) {
+ this.getUser(params).catch(reject).then(resolve);
+ } else {
+ resolve({
+ cache: true,
+ ref,
+ params
+ });
}
- resolve({
- cache: true,
- ref: ctx,
- param
- });
});
};
/*
- param: {
+ params: {
n: number,
offset: number,
search: string,
@@ -1050,14 +1077,15 @@ if (window.CefSharp) {
order: string ('ascending', 'descending')
}
*/
- API.getUsers = function (param) {
+ API.getUsers = function (params) {
return this.call('users', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('USER:LIST', args);
return args;
@@ -1065,21 +1093,21 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
status: string ('active', 'join me', 'busy', 'offline'),
statusDescription: string
}
*/
- API.saveCurrentUser = function (param) {
+ API.saveCurrentUser = function (params) {
return this.call(`users/${this.currentUser.id}`, {
method: 'PUT',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
- // FIXME: handle this
this.$emit('USER:CURRENT:SAVE', args);
return args;
});
@@ -1090,45 +1118,47 @@ if (window.CefSharp) {
API.cachedWorlds = new Map();
API.$on('WORLD', function (args) {
- args.ref = this.updateWorld(args.json);
+ args.ref = this.applyWorld(args.json);
});
API.$on('WORLD:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('WORLD', {
- param: {
- worldId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('WORLD', {
+ ref: null,
+ json,
+ params: {
+ worldId: json.id
+ }
+ });
+ }
+ }
});
/*
- param: {
+ params: {
worldId: string
}
*/
- API.getWorld = function (param) {
- return this.call(`worlds/${param.worldId}`, {
+ API.getWorld = function (params) {
+ return this.call(`worlds/${params.worldId}`, {
method: 'GET'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('WORLD', args);
return args;
});
};
- API.updateWorld = function (ref) {
- var ctx = this.cachedWorlds.get(ref.id);
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyWorld = function (json) {
+ var ref = this.cachedWorlds.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
name: '',
description: '',
authorId: '',
@@ -1146,7 +1176,6 @@ if (window.CefSharp) {
unityPackageUrlObject: {},
unityPackages: [],
version: 0,
- previewYoutubeId: '',
favorites: 0,
created_at: '',
updated_at: '',
@@ -1159,41 +1188,43 @@ if (window.CefSharp) {
privateOccupants: 0,
occupants: 0,
instances: [],
- // custom
+ // VRCX
$isLabs: false,
//
- ...ref
+ ...json
};
- this.cachedWorlds.set(ctx.id, ctx);
+ this.cachedWorlds.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
}
- if (ctx.tags) {
- ctx.$isLabs = ctx.tags.includes('system_labs');
+ if (Array.isArray(ref.tags)) {
+ ref.$isLabs = ref.tags.includes('system_labs');
}
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
worldId: string
}
*/
- API.getCachedWorld = function (param) {
+ API.getCachedWorld = function (params) {
return new Promise((resolve, reject) => {
- var ctx = this.cachedWorlds.get(param.worldId);
- if (ctx) {
+ var ref = this.cachedWorlds.get(params.worldId);
+ if (ref === undefined) {
+ this.getWorld(params).catch(reject).then(resolve);
+ } else {
resolve({
cache: true,
- ref: ctx,
- param
+ ref,
+ params
});
- } else {
- this.getWorld(param).catch(reject).then(resolve);
}
});
};
/*
- param: {
+ params: {
n: number,
offset: number,
search: string,
@@ -1203,20 +1234,22 @@ if (window.CefSharp) {
order: string ('ascending','descending'),
releaseStatus: string ('public','private','hidden','all'),
featured: boolean
- }
+ },
+ option: string
*/
- API.getWorlds = function (param, option) {
+ API.getWorlds = function (params, option) {
var endpoint = 'worlds';
- if (option) {
+ if (option !== undefined) {
endpoint = `worlds/${option}`;
}
return this.call(endpoint, {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('WORLD:LIST', args);
return args;
@@ -1225,110 +1258,114 @@ if (window.CefSharp) {
// API: Friend
- API.friend404 = new Map();
+ API.friends200 = new Set();
+ API.friends404 = new Map();
API.isFriendLoading = false;
API.$on('LOGIN', function () {
- this.friend404.clear();
+ this.friends200.clear();
+ this.friends404.clear();
this.isFriendLoading = false;
});
API.$on('FRIEND:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('USER', {
- param: {
- userId: json.id
- },
- json
- });
- var user = this.cachedUsers.get(json.id);
- if (user === undefined) {
- return;
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('USER', {
+ ref: null,
+ json,
+ params: {
+ userId: json.id
+ }
+ });
+ this.friends200.add(json.id);
+ this.friends404.delete(json.id);
}
- user.$isFriend = true;
- this.friend404.delete(json.id);
- });
+ }
});
- API.checkFriends = function (mark) {
- if (!mark) {
- return this.currentUser.friends.every((id) => {
- var user = this.cachedUsers.get(id);
- if (user &&
- user.$isFriend) {
- return true;
- }
- // NOTE: NaN이면 false라서 괜찮음
- return this.friend404.get(id) >= 2;
- });
+ API.isAllFriendsRetrived = function (flag) {
+ var { friends } = this.currentUser;
+ if (Array.isArray(friends) === false) {
+ return false;
}
- this.currentUser.friends.forEach((id) => {
- var ctx = this.cachedUsers.get(id);
- if (!(ctx &&
- ctx.$isFriend)) {
- var hit = Number(this.friend404.get(id)) || 0;
- if (hit < 2) {
- this.friend404.set(id, hit + 1);
+ if (flag) {
+ for (var id of friends) {
+ if (this.friends200.has(id)) {
+ continue;
+ }
+ var n = this.friends404.get(id) || 0;
+ if (n < 2) {
+ this.friends404.set(id, n + 1);
}
}
- });
+ } else {
+ for (var id of friends) {
+ if (this.friends200.has(id) === false ||
+ this.friends404.get(id) < 2) {
+ return false;
+ }
+ }
+ }
return true;
};
API.refreshFriend = function () {
- var param = {
+ var params = {
n: 100,
offset: 0,
offline: false
};
var N = this.currentUser.onlineFriends.length;
- if (!N) {
+ if (N === 0) {
N = this.currentUser.friends.length;
- if (!N ||
- this.checkFriends(false)) {
+ if (N === 0 ||
+ this.isAllFriendsRetrived(false)) {
return;
}
- param.offline = true;
+ params.offline = true;
}
- if (!this.isFriendLoading) {
- this.isFriendLoading = true;
- this.bulk({
- fn: 'getFriends',
- N,
- param,
- done: (ok, options) => {
- if (this.checkFriends(param.offline)) {
- this.isFriendLoading = false;
- } else {
- N = this.currentUser.friends.length - param.offset;
- if (N <= 0) {
- N = this.currentUser.friends.length;
- }
- options.N = N;
- param.offset = 0;
- param.offline = true;
- this.bulk(options);
- }
+ if (this.isFriendLoading) {
+ return;
+ }
+ this.isFriendLoading = true;
+ this.bulk({
+ fn: 'getFriends',
+ N,
+ params,
+ done(ok, options) {
+ if (this.isAllFriendsRetrived(params.offline)) {
+ this.isFriendLoading = false;
+ return;
}
- });
- }
+ var { length } = this.currentUser.friends;
+ options.N = length - params.offset;
+ if (options.N <= 0) {
+ options.N = length;
+ }
+ params.offset = 0;
+ params.offline = true;
+ this.bulk(options);
+ }
+ });
};
/*
- param: {
+ params: {
n: number,
offset: number,
offline: boolean
}
*/
- API.getFriends = function (param) {
+ API.getFriends = function (params) {
return this.call('auth/user/friends', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FRIEND:LIST', args);
return args;
@@ -1336,17 +1373,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.sendFriendRequest = function (param) {
- return this.call(`user/${param.userId}/friendRequest`, {
+ API.sendFriendRequest = function (params) {
+ return this.call(`user/${params.userId}/friendRequest`, {
method: 'POST'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FRIEND:REQUEST', args);
return args;
@@ -1354,17 +1392,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.cancelFriendRequest = function (param) {
- return this.call(`user/${param.userId}/friendRequest`, {
+ API.cancelFriendRequest = function (params) {
+ return this.call(`user/${params.userId}/friendRequest`, {
method: 'DELETE'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FRIEND:REQUEST:CANCEL', args);
return args;
@@ -1372,17 +1411,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.deleteFriend = function (param) {
- return this.call(`auth/user/friends/${param.userId}`, {
+ API.deleteFriend = function (params) {
+ return this.call(`auth/user/friends/${params.userId}`, {
method: 'DELETE'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FRIEND:DELETE', args);
return args;
@@ -1390,17 +1430,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
userId: string
}
*/
- API.getFriendStatus = function (param) {
- return this.call(`user/${param.userId}/friendStatus`, {
+ API.getFriendStatus = function (params) {
+ return this.call(`user/${params.userId}/friendStatus`, {
method: 'GET'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FRIEND:STATUS', args);
return args;
@@ -1412,18 +1453,21 @@ if (window.CefSharp) {
API.cachedAvatars = new Map();
API.$on('AVATAR', function (args) {
- args.ref = this.updateAvatar(args.json);
+ args.ref = this.applyAvatar(args.json);
});
API.$on('AVATAR:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('AVATAR', {
- param: {
- avatarId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('AVATAR', {
+ ref: null,
+ json,
+ params: {
+ avatarId: json.id
+ }
+ });
+ }
+ }
});
API.$on('AVATAR:SELECT', function (args) {
@@ -1431,30 +1475,29 @@ if (window.CefSharp) {
});
/*
- param: {
+ params: {
avatarId: string
}
*/
- API.getAvatar = function (param) {
- return this.call(`avatars/${param.avatarId}`, {
+ API.getAvatar = function (params) {
+ return this.call(`avatars/${params.avatarId}`, {
method: 'GET'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('AVATAR', args);
return args;
});
};
- API.updateAvatar = function (ref) {
- var ctx = this.cachedAvatars.get(ref.id);
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyAvatar = function (json) {
+ var ref = this.cachedAvatars.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
name: '',
description: '',
authorId: '',
@@ -1471,35 +1514,37 @@ if (window.CefSharp) {
unityPackageUrlObject: {},
created_at: '',
updated_at: '',
- ...ref
+ ...json
};
- this.cachedAvatars.set(ctx.id, ctx);
+ this.cachedAvatars.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
}
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
avatarId: string
}
*/
- API.getCachedAvatar = function (param) {
+ API.getCachedAvatar = function (params) {
return new Promise((resolve, reject) => {
- var ctx = this.cachedAvatars.get(param.avatarId);
- if (ctx) {
+ var ref = this.cachedAvatars.get(params.avatarId);
+ if (ref === undefined) {
+ this.getAvatar(params).catch(reject).then(resolve);
+ } else {
resolve({
cache: true,
- ref: ctx,
- param
+ ref,
+ params
});
- } else {
- this.getAvatar(param).catch(reject).then(resolve);
}
});
};
/*
- param: {
+ params: {
n: number,
offset: number,
search: string,
@@ -1511,14 +1556,15 @@ if (window.CefSharp) {
featured: boolean
}
*/
- API.getAvatars = function (param) {
+ API.getAvatars = function (params) {
return this.call('avatars', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('AVATAR:LIST', args);
return args;
@@ -1526,18 +1572,19 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
avatarId: string
}
*/
- API.selectAvatar = function (param) {
- return this.call(`avatars/${param.avatarId}/select`, {
+ API.selectAvatar = function (params) {
+ return this.call(`avatars/${params.avatarId}/select`, {
method: 'PUT',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('AVATAR:SELECT', args);
return args;
@@ -1555,107 +1602,111 @@ if (window.CefSharp) {
});
API.$on('NOTIFICATION', function (args) {
- args.ref = this.updateNotification(args.json);
+ args.ref = this.applyNotification(args.json);
});
API.$on('NOTIFICATION:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('NOTIFICATION', {
- param: {
- notificationId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('NOTIFICATION', {
+ ref: null,
+ json,
+ params: {
+ notificationId: json.id
+ }
+ });
+ }
+ }
});
API.$on('NOTIFICATION:ACCEPT', function (args) {
- var ctx = this.cachedNotifications.get(args.param.notificationId);
- if (ctx &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- args.ref = ctx;
- this.$emit('NOTIFICATION:@DELETE', {
- param: {
- notificationId: ctx.id
- },
- ref: ctx
- });
- this.$emit('FRIEND:ADD', {
- param: {
- userId: ctx.senderUserId
- }
- });
+ var ref = this.cachedNotifications.get(args.params.notificationId);
+ if (ref === undefined ||
+ ref.$isDeleted) {
+ return;
}
+ args.ref = ref;
+ ref.$isDeleted = true;
+ this.$emit('NOTIFICATION:@DELETE', {
+ ref,
+ params: {
+ notificationId: ref.id
+ }
+ });
+ this.$emit('FRIEND:ADD', {
+ ref: null,
+ params: {
+ userId: ref.senderUserId
+ }
+ });
});
API.$on('NOTIFICATION:HIDE', function (args) {
- var ctx = this.cachedNotifications.get(args.param.notificationId);
- if (ctx &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- args.ref = ctx;
- this.$emit('NOTIFICATION:@DELETE', {
- param: {
- notificationId: ctx.id
- },
- ref: ctx
- });
+ var ref = this.cachedNotifications.get(args.params.notificationId);
+ if (ref === undefined &&
+ ref.$isDeleted) {
+ return;
}
+ args.ref = ref;
+ ref.$isDeleted = true;
+ this.$emit('NOTIFICATION:@DELETE', {
+ ref,
+ params: {
+ notificationId: ref.id
+ }
+ });
});
- API.markAllNotificationsAsExpired = function () {
- for (var ctx of this.cachedNotifications.values()) {
- if (!ctx.$isDeleted) {
- ctx.$isExpired = true;
- }
+ API.expireNotifications = function () {
+ for (var ref of this.cachedNotifications.values()) {
+ ref.$isExpired = true;
}
};
- API.checkExpiredNotifcations = function () {
- for (var ctx of this.cachedNotifications.values()) {
- if (ctx.$isExpired &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- this.$emit('NOTIFICATION:@DELETE', {
- param: {
- notificationId: ctx.id
- },
- ref: ctx
- });
+ API.deleteExpiredNotifcations = function () {
+ for (var ref of this.cachedNotifications.values()) {
+ if (ref.$isDeleted ||
+ ref.$isExpired === false) {
+ continue;
}
+ ref.$isDeleted = true;
+ this.$emit('NOTIFICATION:@DELETE', {
+ ref,
+ params: {
+ notificationId: ref.id
+ }
+ });
}
};
API.refreshNotification = function () {
// NOTE : 캐시 때문에 after=~ 로는 갱신이 안됨. 그래서 첨부터 불러옴
- if (!this.isNotificationLoading) {
- this.isNotificationLoading = true;
- this.markAllNotificationsAsExpired();
- this.bulk({
- fn: 'getNotifications',
- N: -1,
- param: {
- n: 100,
- offset: 0
- },
- done: (ok) => {
- if (ok) {
- this.checkExpiredNotifcations();
- }
- this.isNotificationLoading = false;
- }
- });
+ if (this.isNotificationLoading) {
+ return;
}
+ this.isNotificationLoading = true;
+ this.expireNotifications();
+ this.bulk({
+ fn: 'getNotifications',
+ N: -1,
+ params: {
+ n: 100,
+ offset: 0
+ },
+ done(ok) {
+ if (ok) {
+ this.deleteExpiredNotifcations();
+ }
+ this.isNotificationLoading = false;
+ }
+ });
};
- API.updateNotification = function (ref) {
- var ctx = this.cachedNotifications.get(ref.id);
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyNotification = function (json) {
+ var ref = this.cachedNotifications.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
senderUserId: '',
senderUsername: '',
type: '',
@@ -1663,32 +1714,35 @@ if (window.CefSharp) {
details: {},
seen: false,
created_at: '',
- // custom
+ // VRCX
$isDeleted: false,
$isExpired: false,
//
- ...ref
+ ...json
};
- this.cachedNotifications.set(ctx.id, ctx);
+ this.cachedNotifications.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
+ ref.$isExpired = false;
}
- if (isObject(ctx.details)) {
+ if (isObject(ref.details) === false) {
var details = {};
- try {
- var json = JSON.parse(ctx.details);
- if (isObject(json)) {
- details = json;
+ if (ref.details !== '{}') {
+ try {
+ var obj = JSON.parse(ref.details);
+ if (isObject(obj)) {
+ details = obj;
+ }
+ } catch (err) {
}
- } catch (err) {
- console.error(err);
}
- ctx.details = details;
+ ref.details = details;
}
- ctx.$isExpired = false;
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
n: number,
offset: number,
sent: boolean,
@@ -1696,14 +1750,15 @@ if (window.CefSharp) {
after: string (ISO8601 or 'five_minutes_ago')
}
*/
- API.getNotifications = function (param) {
+ API.getNotifications = function (params) {
return this.call('auth/user/notifications', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('NOTIFICATION:LIST', args);
return args;
@@ -1715,16 +1770,17 @@ if (window.CefSharp) {
method: 'PUT'
}).then((json) => {
var args = {
+ ref: null,
json
};
- // FIXME: 고쳐줘
+ // FIXME: NOTIFICATION:CLEAR 핸들링
this.$emit('NOTIFICATION:CLEAR', args);
return args;
});
};
/*
- param: {
+ params: {
receiverUserId: string,
type: string,
message: string,
@@ -1732,14 +1788,15 @@ if (window.CefSharp) {
details: json-string
}
*/
- API.sendNotification = function (param) {
- return this.call(`user/${param.receiverUserId}/notification`, {
+ API.sendNotification = function (params) {
+ return this.call(`user/${params.receiverUserId}/notification`, {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('NOTIFICATION:SEND', args);
return args;
@@ -1747,17 +1804,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
notificationId: string
}
*/
- API.acceptNotification = function (param) {
- return this.call(`auth/user/notifications/${param.notificationId}/accept`, {
+ API.acceptNotification = function (params) {
+ return this.call(`auth/user/notifications/${params.notificationId}/accept`, {
method: 'PUT'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('NOTIFICATION:ACCEPT', args);
return args;
@@ -1765,17 +1823,18 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
notificationId: string
}
*/
- API.hideNotification = function (param) {
- return this.call(`auth/user/notifications/${param.notificationId}/hide`, {
+ API.hideNotification = function (params) {
+ return this.call(`auth/user/notifications/${params.notificationId}/hide`, {
method: 'PUT'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('NOTIFICATION:HIDE', args);
return args;
@@ -1783,11 +1842,11 @@ if (window.CefSharp) {
};
API.getFriendRequest = function (userId) {
- for (var ctx of this.cachedNotifications.values()) {
- if (ctx.type === 'friendRequest' &&
- ctx.senderUserId === userId &&
- !ctx.$isDeleted) {
- return ctx.id;
+ for (var ref of this.cachedNotifications.values()) {
+ if (ref.$isDeleted === false &&
+ ref.type === 'friendRequest' &&
+ ref.senderUserId === userId) {
+ return ref.id;
}
}
return '';
@@ -1804,112 +1863,113 @@ if (window.CefSharp) {
});
API.$on('PLAYER-MODERATION', function (args) {
- args.ref = this.updatePlayerModeration(args.json);
+ args.ref = this.applyPlayerModeration(args.json);
});
API.$on('PLAYER-MODERATION:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('PLAYER-MODERATION', {
- param: {
- playerModerationId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('PLAYER-MODERATION', {
+ ref: null,
+ json,
+ params: {
+ playerModerationId: json.id
+ }
+ });
+ }
+ }
});
API.$on('PLAYER-MODERATION:SEND', function (args) {
this.$emit('PLAYER-MODERATION', {
- param: {
+ ref: null,
+ json: args.json,
+ params: {
playerModerationId: args.json.id
- },
- json: args.json
+ }
});
});
API.$on('PLAYER-MODERATION:DELETE', function (args) {
- this.handleDeletePlayerModeration(args.param.type, args.param.moderated);
- });
-
- API.markAllPlayerModerationsAsExpired = function () {
- for (var ctx of this.cachedPlayerModerations.values()) {
- if (!ctx.$isDeleted) {
- ctx.$isExpired = true;
- }
- }
- };
-
- API.checkExpiredPlayerModerations = function () {
- for (var ctx of this.cachedPlayerModerations.values()) {
- if (ctx.$isExpired &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
+ var { type, moderated } = args.param;
+ var cuid = this.currentUser.id;
+ for (var ref of this.cachedPlayerModerations.values()) {
+ if (ref.$isDeleted === false &&
+ ref.type === type &&
+ ref.targetUserId === moderated &&
+ ref.sourceUserId === cuid) {
+ ref.$isDeleted = true;
this.$emit('PLAYER-MODERATION:@DELETE', {
- param: {
- playerModerationId: ctx.id
- },
- ref: ctx
+ ref,
+ params: {
+ playerModerationId: ref.id
+ }
});
}
}
+ });
+
+ API.expirePlayerModerations = function () {
+ for (var ref of this.cachedPlayerModerations.values()) {
+ ref.$isExpired = true;
+ }
};
- API.refreshPlayerModeration = function () {
- if (!this.isPlayerModerationLoading) {
- this.isPlayerModerationLoading = true;
- this.markAllPlayerModerationsAsExpired();
- Promise.all([
- this.getPlayerModerations(),
- this.getPlayerModerationsAgainstMe()
- ]).finally(() => {
- this.isPlayerModerationLoading = false;
- }).then(() => {
- this.checkExpiredPlayerModerations();
+ API.deleteExpiredPlayerModerations = function () {
+ for (var ref of this.cachedPlayerModerations.values()) {
+ if (ref.$isDeleted ||
+ ref.$isExpired === false) {
+ continue;
+ }
+ ref.$isDeleted = true;
+ this.$emit('PLAYER-MODERATION:@DELETE', {
+ ref,
+ params: {
+ playerModerationId: ref.id
+ }
});
}
};
- API.handleDeletePlayerModeration = function (type, moderated) {
- var cuid = this.currentUser.id;
- for (var ctx of this.cachedPlayerModerations.values()) {
- if (ctx.type === type &&
- ctx.targetUserId === moderated &&
- ctx.sourceUserId === cuid &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- this.$emit('PLAYER-MODERATION:@DELETE', {
- param: {
- playerModerationId: ctx.id
- },
- ref: ctx
- });
- }
+ API.refreshPlayerModeration = function () {
+ if (this.isPlayerModerationLoading) {
+ return;
}
+ this.isPlayerModerationLoading = true;
+ this.expirePlayerModerations();
+ Promise.all([
+ this.getPlayerModerations(),
+ this.getPlayerModerationsAgainstMe()
+ ]).finally(() => {
+ this.isPlayerModerationLoading = false;
+ }).then(() => {
+ this.deleteExpiredPlayerModerations();
+ });
};
- API.updatePlayerModeration = function (ref) {
- var ctx = this.cachedPlayerModerations.get(ref.id);
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyPlayerModeration = function (json) {
+ var ref = this.cachedPlayerModerations.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
type: '',
sourceUserId: '',
sourceDisplayName: '',
targetUserId: '',
targetDisplayName: '',
created: '',
- // custom
+ // VRCX
$isDeleted: false,
$isExpired: false,
//
- ...ref
+ ...json
};
- this.cachedPlayerModerations.set(ctx.id, ctx);
+ this.cachedPlayerModerations.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
+ ref.$isExpired = false;
}
- ctx.$isExpired = false;
- return ctx;
+ return ref;
};
API.getPlayerModerations = function () {
@@ -1917,6 +1977,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json
};
this.$emit('PLAYER-MODERATION:LIST', args);
@@ -1929,6 +1990,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json
};
this.$emit('PLAYER-MODERATION:LIST', args);
@@ -1937,20 +1999,21 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
moderated: string,
type: string
}
*/
// old-way: POST auth/user/blocks {blocked:userId}
- API.sendPlayerModeration = function (param) {
+ API.sendPlayerModeration = function (params) {
return this.call('auth/user/playermoderations', {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('PLAYER-MODERATION:SEND', args);
return args;
@@ -1958,20 +2021,21 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
moderated: string,
type: string
}
*/
// old-way: PUT auth/user/unblocks {blocked:userId}
- API.deletePlayerModeration = function (param) {
+ API.deletePlayerModeration = function (params) {
return this.call('auth/user/unplayermoderate', {
method: 'PUT',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('PLAYER-MODERATION:DELETE', args);
return args;
@@ -1980,9 +2044,9 @@ if (window.CefSharp) {
// API: Favorite
- API.favorite = {};
- API.favoriteGroup = {};
- API.favoriteObject = {};
+ API.cachedFavorites = new Map();
+ API.cachedFavoritesByObjectId = new Map();
+ API.cachedFavoriteGroups = new Map();
API.favoriteFriendGroups = [];
API.favoriteWorldGroups = [];
API.favoriteAvatarGroups = [];
@@ -1990,9 +2054,9 @@ if (window.CefSharp) {
API.isFavoriteGroupLoading = false;
API.$on('LOGIN', function () {
- this.favorite = {};
- this.favoriteGroup = {};
- this.favoriteObject = {};
+ this.cachedFavorites.clear();
+ this.cachedFavoritesByObjectId.clear();
+ this.cachedFavoriteGroups.clear();
this.favoriteFriendGroups = [];
this.favoriteWorldGroups = [];
this.favoriteAvatarGroups = [];
@@ -2002,335 +2066,307 @@ if (window.CefSharp) {
});
API.$on('FAVORITE', function (args) {
- var ref = this.updateFavorite(args.json);
- args.ref = ref;
- if (!ref.$isExpired &&
- this.favoriteObject[ref.favoriteId] !== ref) {
- this.favoriteObject[ref.favoriteId] = ref;
- if (ref.type === 'friend') {
- this.favoriteFriendGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- ++ctx.count;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'world') {
- this.favoriteWorldGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- ++ctx.count;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'avatar') {
- this.favoriteAvatarGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- ++ctx.count;
- return true;
- }
- return false;
- });
- }
+ var ref = this.applyFavorite(args.json);
+ if (ref.$isDeleted) {
+ return;
}
+ args.ref = ref;
+ this.cachedFavoritesByObjectId.set(ref.favoriteId, ref);
});
API.$on('FAVORITE:@DELETE', function (args) {
var { ref } = args;
- if (this.favoriteObject[ref.favoriteId]) {
- delete this.favoriteObject[ref.favoriteId];
- if (ref.type === 'friend') {
- this.favoriteFriendGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- --ctx.count;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'world') {
- this.favoriteWorldGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- --ctx.count;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'avatar') {
- this.favoriteAvatarGroups.find((ctx) => {
- if (ctx.name === ref.$group) {
- --ctx.count;
- return true;
- }
- return false;
- });
- }
+ if (ref.$groupRef !== null) {
+ --ref.$groupRef.count;
}
});
API.$on('FAVORITE:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('FAVORITE', {
- param: {
- favoriteId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('FAVORITE', {
+ ref: null,
+ json,
+ params: {
+ favoriteId: json.id
+ }
+ });
+ }
+ }
});
API.$on('FAVORITE:ADD', function (args) {
this.$emit('FAVORITE', {
- param: {
+ ref: null,
+ json: args.json,
+ params: {
favoriteId: args.json.id
- },
- json: args.json
+ }
});
});
API.$on('FAVORITE:DELETE', function (args) {
- this.handleDeleteFavorite(args.param.objectId);
+ var ref = this.cachedFavoritesByObjectId.get(args.params.objectId);
+ if (ref === undefined ||
+ ref.$isDeleted) {
+ return;
+ }
+ ref.$isDeleted = true;
+ API.$emit('FAVORITE:@DELETE', {
+ ref,
+ params: {
+ favoriteId: ref.id
+ }
+ });
});
API.$on('FAVORITE:GROUP', function (args) {
- var ref = this.updateFavoriteGroup(args.json);
+ var ref = this.applyFavoriteGroup(args.json);
+ if (ref.$isDeleted) {
+ return;
+ }
args.ref = ref;
- if (!ref.$isDeleted) {
- if (ref.type === 'friend') {
- this.favoriteFriendGroups.find((ctx) => {
- if (ctx.name === ref.name) {
- ctx.displayName = ref.displayName;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'world') {
- this.favoriteWorldGroups.find((ctx) => {
- if (ctx.name === ref.name) {
- ctx.displayName = ref.displayName;
- return true;
- }
- return false;
- });
- } else if (ref.type === 'avatar') {
- this.favoriteAvatarGroups.find((ctx) => {
- if (ctx.name === ref.name) {
- ctx.displayName = ref.displayName;
- return true;
- }
- return false;
- });
- }
+ if (ref.$groupRef !== null) {
+ ref.$groupRef.displayName = ref.displayName;
}
});
API.$on('FAVORITE:GROUP:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('FAVORITE:GROUP', {
- param: {
- favoriteGroupId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('FAVORITE:GROUP', {
+ ref: null,
+ json,
+ params: {
+ favoriteGroupId: json.id
+ }
+ });
+ }
+ }
});
API.$on('FAVORITE:GROUP:SAVE', function (args) {
this.$emit('FAVORITE:GROUP', {
- param: {
+ ref: null,
+ json: args.json,
+ params: {
favoriteGroupId: args.json.id
- },
- json: args.json
+ }
});
});
API.$on('FAVORITE:GROUP:CLEAR', function (args) {
- this.handleClearFavoriteGroup(args.param.group);
+ var key = `${args.params.type}:${args.params.group}`;
+ for (var ref of this.cachedFavorites.values()) {
+ if (ref.$isDeleted ||
+ ref.$groupKey !== key) {
+ continue;
+ }
+ ref.$isDeleted = true;
+ API.$emit('FAVORITE:@DELETE', {
+ ref,
+ params: {
+ favoriteId: ref.id
+ }
+ });
+ }
});
API.$on('FAVORITE:FRIEND:LIST', function (args) {
- args.json.forEach((json) => {
- this.$emit('USER', {
- param: {
- userId: json.id
- },
- json
- });
- });
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ this.$emit('USER', {
+ ref: null,
+ json,
+ params: {
+ userId: json.id
+ }
+ });
+ }
+ }
});
API.$on('FAVORITE:WORLD:LIST', function (args) {
- args.json.forEach((json) => {
- if (json.id !== '???') {
- // FIXME
- // json.favoriteId로 따로 불러와야 하나?
- // 근데 ???가 많으면 과다 요청이 될듯
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ if (json.id === '???') {
+ // FIXME
+ // json.favoriteId로 따로 불러와야 하나?
+ // 근데 ???가 많으면 과다 요청이 될듯
+ continue;
+ }
this.$emit('WORLD', {
- param: {
+ ref: null,
+ json,
+ params: {
worldId: json.id
- },
- json
+ }
});
}
- });
+ }
});
API.$on('FAVORITE:AVATAR:LIST', function (args) {
- args.json.forEach((json) => {
- if (json.releaseStatus !== 'hidden') {
- // NOTE: 얘는 또 더미 데이터로 옴
+ if (Array.isArray(args.json)) {
+ for (var json of args.json) {
+ if (json.releaseStatus === 'hidden') {
+ // NOTE: 얘는 또 더미 데이터로 옴
+ continue;
+ }
this.$emit('AVATAR', {
- param: {
+ ref: null,
+ json,
+ params: {
avatarId: json.id
- },
- json
+ }
});
}
- });
+ }
});
- API.markAllFavoritesAsExpired = function () {
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (!ctx.$isDeleted) {
- ctx.$isExpired = true;
- }
+ API.expireFavorites = function () {
+ for (var ref of this.cachedFavorites.values()) {
+ ref.$isExpired = true;
}
};
- API.checkExpiredFavorites = function () {
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.$isExpired &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- this.$emit('FAVORITE:@DELETE', {
- param: {
- favoriteId: ctx.id
- },
- ref: ctx
- });
+ API.deleteExpiredFavorites = function () {
+ for (var ref of this.cachedFavorites.values()) {
+ if (ref.$isDeleted ||
+ ref.$isExpired === false) {
+ continue;
}
+ ref.$isDeleted = true;
+ this.$emit('FAVORITE:@DELETE', {
+ ref,
+ params: {
+ favoriteId: ref.id
+ }
+ });
}
};
API.refreshFavorite = function () {
- if (!this.isFavoriteLoading) {
- this.isFavoriteLoading = true;
- this.markAllFavoritesAsExpired();
- this.bulk({
- fn: 'getFavorites',
- N: -1,
- param: {
- n: 100,
- offset: 0
- },
- done: (ok) => {
- if (ok) {
- this.checkExpiredFavorites();
- }
- this.refreshFavoriteGroup();
- this.refreshFavoriteFriends();
- this.refreshFavoriteWorlds();
- this.refreshFavoriteAvatars();
- this.isFavoriteLoading = false;
- }
- });
+ if (this.isFavoriteLoading) {
+ return;
}
+ this.isFavoriteLoading = true;
+ this.expireFavorites();
+ this.bulk({
+ fn: 'getFavorites',
+ N: -1,
+ params: {
+ n: 100,
+ offset: 0
+ },
+ done(ok) {
+ if (ok) {
+ this.deleteExpiredFavorites();
+ }
+ this.refreshFavoriteGroup();
+ this.refreshFavoriteFriends();
+ this.refreshFavoriteWorlds();
+ this.refreshFavoriteAvatars();
+ this.isFavoriteLoading = false;
+ }
+ });
};
API.refreshFavoriteFriends = function () {
var N = 0;
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.type === 'friend' &&
- !ctx.$isDeleted) {
+ for (var ref of this.cachedFavorites.values()) {
+ if (ref.$isDeleted === false &&
+ ref.type === 'friend') {
++N;
}
}
- if (N) {
- this.bulk({
- fn: 'getFavoriteFriends',
- N,
- param: {
- n: 100,
- offset: 0
- }
- });
+ // FIXME
+ // N이 0일땐 -1로 해야하지 않나?
+ // refreshFavoriteWorlds, refreshFavoriteAvatars 도 마찬가지
+ if (N === 0) {
+ return;
}
+ this.bulk({
+ fn: 'getFavoriteFriends',
+ N,
+ params: {
+ n: 100,
+ offset: 0
+ }
+ });
};
API.refreshFavoriteWorlds = function () {
var N = 0;
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.type === 'world' &&
- !ctx.$isDeleted) {
+ for (var ref of this.cachedFavorites.values()) {
+ if (ref.$isDeleted === false &&
+ ref.type === 'world') {
++N;
}
}
- if (N) {
- this.bulk({
- fn: 'getFavoriteWorlds',
- N,
- param: {
- n: 100,
- offset: 0
- }
- });
+ if (N === 0) {
+ return;
}
+ this.bulk({
+ fn: 'getFavoriteWorlds',
+ N,
+ params: {
+ n: 100,
+ offset: 0
+ }
+ });
};
API.refreshFavoriteAvatars = function () {
var N = 0;
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.type === 'avatar' &&
- !ctx.$isDeleted) {
+ for (var ref of this.cachedFavorites.values()) {
+ if (ref.$isDeleted === false &&
+ ref.type === 'avatar') {
++N;
}
}
- if (N) {
- this.bulk({
- fn: 'getFavoriteAvatars',
- N,
- param: {
- n: 100,
- offset: 0
+ if (N === 0) {
+ return;
+ }
+ this.bulk({
+ fn: 'getFavoriteAvatars',
+ N,
+ params: {
+ n: 100,
+ offset: 0
+ }
+ });
+ };
+
+ API.expireFavoriteGroups = function () {
+ for (var ref of this.cachedFavoriteGroups.values()) {
+ ref.$isExpired = true;
+ }
+ };
+
+ API.deleteExpiredFavoriteGroups = function () {
+ for (var ref of this.cachedFavoriteGroups.values()) {
+ if (ref.$isDeleted ||
+ ref.$isExpired === false) {
+ continue;
+ }
+ ref.$isDeleted = true;
+ this.$emit('FAVORITE:GROUP:@DELETE', {
+ ref,
+ params: {
+ favoriteGroupId: ref.id
}
});
}
};
- API.markAllFavoriteGroupsAsExpired = function () {
- for (var key in this.favoriteGroup) {
- var ctx = this.favoriteGroup[key];
- if (!ctx.$isDeleted) {
- ctx.$isExpired = true;
- }
- }
- };
-
- API.checkExpiredFavoriteGroups = function () {
- for (var key in this.favoriteGroup) {
- var ctx = this.favoriteGroup[key];
- if (ctx.$isExpired &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- this.$emit('FAVORITE:GROUP:@DELETE', {
- param: {
- favoriteGroupId: ctx.id
- },
- ref: ctx
- });
- }
- }
- };
-
- API.resetFavoriteGroup = function () {
+ API.buildFavoriteGroups = function () {
// 96 = ['group_0', 'group_1', 'group_2'] x 32
this.favoriteFriendGroups = [];
for (var i = 0; i < 3; ++i) {
this.favoriteFriendGroups.push({
+ ref: null,
+ key: `friend:group_${i}`,
type: 'friend',
name: `group_${i}`,
displayName: `Group ${i + 1}`,
@@ -2342,6 +2378,8 @@ if (window.CefSharp) {
this.favoriteWorldGroups = [];
for (var i = 0; i < 4; ++i) {
this.favoriteWorldGroups.push({
+ ref: null,
+ key: `world:worlds${i + 1}`,
type: 'world',
name: `worlds${i + 1}`,
displayName: `Group ${i + 1}`,
@@ -2353,6 +2391,8 @@ if (window.CefSharp) {
this.favoriteAvatarGroups = [];
for (var i = 0; i < 1; ++i) {
this.favoriteAvatarGroups.push({
+ ref: null,
+ key: `avatar:avatars${i + 1}`,
type: 'avatar',
name: `avatars${i + 1}`,
displayName: `Group ${i + 1}`,
@@ -2360,178 +2400,149 @@ if (window.CefSharp) {
count: 0
});
}
- };
-
- API.assignFavoriteGroup = function () {
- var assign = [];
- var set1 = function (array, ref) {
- if (!assign[ref.id]) {
- array.find((ctx) => {
- if (ctx.name === ref.name &&
- !ctx.$isAssign) {
- ctx.$isAssign = true;
- ctx.displayName = ref.displayName;
- assign[ref.id] = true;
- return true;
- }
- return false;
- });
+ // assign the same name first
+ for (var ref of this.cachedFavoriteGroups.values()) {
+ if (ref.$isDeleted) {
+ continue;
}
- };
- var set2 = function (array, ref) {
- if (!assign[ref.id]) {
- array.find((ctx) => {
- if (!ctx.$isAssign) {
- ctx.$isAssign = true;
- ctx.name = ref.name;
- ctx.displayName = ref.displayName;
- assign[ref.id] = true;
- return true;
- }
- return false;
- });
+ var groups = null;
+ if (ref.type === 'friend') {
+ groups = this.favoriteFriendGroups;
+ } else if (ref.type === 'world') {
+ groups = this.favoriteWorldGroups;
+ } else if (ref.type === 'avatar') {
+ groups = this.favoriteAvatarGroups;
+ } else {
+ continue;
}
- };
- for (var key in this.favoriteGroup) {
- var ctx = this.favoriteGroup[key];
- if (!ctx.$isDeleted) {
- if (ctx.type === 'friend') {
- set1(this.favoriteFriendGroups, ctx);
- } else if (ctx.type === 'world') {
- set1(this.favoriteWorldGroups, ctx);
- } else if (ctx.type === 'avatar') {
- set1(this.favoriteAvatarGroups, ctx);
+ for (var group of groups) {
+ if (group.ref === null &&
+ group.name === ref.name) {
+ group.ref = ref;
+ group.displayName = ref.displayName;
+ ref.$groupRef = group;
+ break;
}
}
}
- for (var key in this.favoriteGroup) {
- var ctx = this.favoriteGroup[key];
- if (!ctx.$isDeleted) {
- if (ctx.type === 'friend') {
- set2(this.favoriteFriendGroups, ctx);
- } else if (ctx.type === 'world') {
- set2(this.favoriteWorldGroups, ctx);
- } else if (ctx.type === 'avatar') {
- set2(this.favoriteAvatarGroups, ctx);
+ // assign the rest
+ for (var ref of this.cachedFavoriteGroups.values()) {
+ if (ref.$isDeleted ||
+ ref.$ref) {
+ continue;
+ }
+ var groups = null;
+ if (ref.type === 'friend') {
+ groups = this.favoriteFriendGroups;
+ } else if (ref.type === 'world') {
+ groups = this.favoriteWorldGroups;
+ } else if (ref.type === 'avatar') {
+ groups = this.favoriteAvatarGroups;
+ } else {
+ continue;
+ }
+ for (var group of groups) {
+ if (group.ref === null) {
+ group.ref = ref;
+ group.key = `${group.type}:${group.name}`;
+ group.name = ref.name;
+ group.displayName = ref.displayName;
+ ref.$groupRef = group;
+ break;
}
}
}
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (!ctx.$isDeleted) {
- if (ctx.type === 'friend') {
- // eslint-disable-next-line no-loop-func
- this.favoriteFriendGroups.find((ref) => {
- if (ref.name === ctx.$group) {
- ++ref.count;
- return true;
- }
- return false;
- });
- } else if (ctx.type === 'world') {
- // eslint-disable-next-line no-loop-func
- this.favoriteWorldGroups.find((ref) => {
- if (ref.name === ctx.$group) {
- ++ref.count;
- return true;
- }
- return false;
- });
- } else if (ctx.type === 'avatar') {
- // eslint-disable-next-line no-loop-func
- this.favoriteAvatarGroups.find((ref) => {
- if (ref.name === ctx.$group) {
- ++ref.count;
- return true;
- }
- return false;
- });
- }
+ // cache groups
+ var groupByTypeName = {};
+ for (var groups of [
+ this.favoriteFriendGroups,
+ this.favoriteWorldGroups,
+ this.favoriteAvatarGroups
+ ]) {
+ for (var group of groups) {
+ groupByTypeName[group.key] = group;
+ }
+ }
+ for (var ref of this.cachedFavorites.values()) {
+ ref.$groupRef = null;
+ if (ref.$isDeleted) {
+ continue;
+ }
+ var group = groupByTypeName[ref.$groupKey];
+ if (group !== undefined) {
+ ref.$groupRef = group;
+ ++group.count;
}
}
};
API.refreshFavoriteGroup = function () {
- if (!this.isFavoriteGroupLoading) {
- this.isFavoriteGroupLoading = true;
- this.markAllFavoriteGroupsAsExpired();
- this.bulk({
- fn: 'getFavoriteGroups',
- N: -1,
- param: {
- n: 100,
- offset: 0
- },
- done: (ok) => {
- if (ok) {
- this.checkExpiredFavoriteGroups();
- this.resetFavoriteGroup();
- this.assignFavoriteGroup();
- }
- this.isFavoriteGroupLoading = false;
+ if (this.isFavoriteGroupLoading) {
+ return;
+ }
+ this.isFavoriteGroupLoading = true;
+ this.expireFavoriteGroups();
+ this.bulk({
+ fn: 'getFavoriteGroups',
+ N: -1,
+ params: {
+ n: 100,
+ offset: 0
+ },
+ done(ok) {
+ if (ok) {
+ this.deleteExpiredFavoriteGroups();
+ this.buildFavoriteGroups();
}
- });
- }
- };
-
- API.handleDeleteFavorite = function (objectId) {
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.favoriteId === objectId &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- API.$emit('FAVORITE:@DELETE', {
- param: {
- favoriteId: ctx.id
- },
- ref: ctx
- });
+ this.isFavoriteGroupLoading = false;
}
- }
+ });
};
- API.updateFavorite = function (ref) {
- var ctx = this.favorite[ref.id];
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyFavorite = function (json) {
+ var ref = this.cachedFavorites.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
type: '',
favoriteId: '',
tags: [],
- // custom
+ // VRCX
$isDeleted: false,
$isExpired: false,
- $group: '',
+ $groupKey: '',
+ $groupRef: null,
//
- ...ref
+ ...json
};
- this.favorite[ctx.id] = ctx;
+ this.cachedFavorites.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
+ ref.$isExpired = false;
}
- ctx.$isExpired = false;
- if (ctx.tags) {
- ctx.$group = ctx.tags[0];
+ if (Array.isArray(ref.tags)) {
+ ref.$groupKey = `${ref.type}:${String(ref.tags[0])}`;
}
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
n: number,
offset: number,
type: string,
tag: string
}
*/
- API.getFavorites = function (param) {
+ API.getFavorites = function (params) {
return this.call('favorites', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:LIST', args);
return args;
@@ -2539,20 +2550,21 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
type: string,
favoriteId: string (objectId),
tags: string
}
*/
- API.addFavorite = function (param) {
+ API.addFavorite = function (params) {
return this.call('favorites', {
method: 'POST',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:ADD', args);
return args;
@@ -2560,30 +2572,29 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
objectId: string
}
*/
- API.deleteFavorite = function (param) {
- return this.call(`favorites/${param.objectId}`, {
+ API.deleteFavorite = function (params) {
+ return this.call(`favorites/${params.objectId}`, {
method: 'DELETE'
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:DELETE', args);
return args;
});
};
- API.updateFavoriteGroup = function (ref) {
- var ctx = this.favoriteGroup[ref.id];
- if (ctx) {
- Object.assign(ctx, ref);
- } else {
- ctx = {
- id: ref.id,
+ API.applyFavoriteGroup = function (json) {
+ var ref = this.cachedFavoriteGroups.get(json.id);
+ if (ref === undefined) {
+ ref = {
+ id: '',
ownerId: '',
ownerDisplayName: '',
name: '',
@@ -2591,33 +2602,37 @@ if (window.CefSharp) {
type: '',
visibility: '',
tags: [],
- // custom
+ // VRCX
$isDeleted: false,
$isExpired: false,
+ $groupRef: null,
//
- ...ref
+ ...json
};
- this.favoriteGroup[ctx.id] = ctx;
+ this.cachedFavoriteGroups.set(ref.id, ref);
+ } else {
+ Object.assign(ref, json);
+ ref.$isExpired = false;
}
- ctx.$isExpired = false;
- return ctx;
+ return ref;
};
/*
- param: {
+ params: {
n: number,
offset: number,
type: string
}
*/
- API.getFavoriteGroups = function (param) {
+ API.getFavoriteGroups = function (params) {
return this.call('favorite/groups', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:GROUP:LIST', args);
return args;
@@ -2625,21 +2640,22 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
type: string,
group: string (name),
displayName: string,
visibility: string
}
*/
- API.saveFavoriteGroup = function (param) {
- return this.call(`favorite/group/${param.type}/${param.group}/${this.currentUser.id}`, {
+ API.saveFavoriteGroup = function (params) {
+ return this.call(`favorite/group/${params.type}/${params.group}/${this.currentUser.id}`, {
method: 'PUT',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:GROUP:SAVE', args);
return args;
@@ -2647,55 +2663,41 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
type: string,
group: string (name)
}
*/
- API.clearFavoriteGroup = function (param) {
- return this.call(`favorite/group/${param.type}/${param.group}/${this.currentUser.id}`, {
+ API.clearFavoriteGroup = function (params) {
+ return this.call(`favorite/group/${params.type}/${params.group}/${this.currentUser.id}`, {
method: 'DELETE',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:GROUP:CLEAR', args);
return args;
});
};
- API.handleClearFavoriteGroup = function (name) {
- for (var key in this.favorite) {
- var ctx = this.favorite[key];
- if (ctx.$group === name &&
- !ctx.$isDeleted) {
- ctx.$isDeleted = true;
- API.$emit('FAVORITE:@DELETE', {
- param: {
- favoriteId: ctx.id
- },
- ref: ctx
- });
- }
- }
- };
-
/*
- param: {
+ params: {
n: number,
offset: number
}
*/
- API.getFavoriteFriends = function (param) {
+ API.getFavoriteFriends = function (params) {
return this.call('auth/user/friends/favorite', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:FRIEND:LIST', args);
return args;
@@ -2703,19 +2705,20 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
n: number,
offset: number
}
*/
- API.getFavoriteWorlds = function (param) {
+ API.getFavoriteWorlds = function (params) {
return this.call('worlds/favorites', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:WORLD:LIST', args);
return args;
@@ -2723,19 +2726,20 @@ if (window.CefSharp) {
};
/*
- param: {
+ params: {
n: number,
offset: number
}
*/
- API.getFavoriteAvatars = function (param) {
+ API.getFavoriteAvatars = function (params) {
return this.call('avatars/favorites', {
method: 'GET',
- body: param
+ params
}).then((json) => {
var args = {
- param,
- json
+ ref: null,
+ json,
+ params
};
this.$emit('FAVORITE:AVATAR:LIST', args);
return args;
@@ -2744,14 +2748,14 @@ if (window.CefSharp) {
// API: WebSocket
- API.webSocket = false;
+ API.webSocket = null;
API.$on('LOGOUT', function () {
this.closeWebSocket();
});
API.$on('USER:CURRENT', function () {
- if (this.webSocket === false) {
+ if (this.webSocket === null) {
this.getAuth();
}
});
@@ -2767,22 +2771,25 @@ if (window.CefSharp) {
switch (type) {
case 'notification':
this.$emit('NOTIFICATION', {
- param: {
+ ref: null,
+ json: content,
+ params: {
notificationId: content.id
- },
- json: content
+ }
});
break;
case 'friend-add':
this.$emit('USER', {
- param: {
+ ref: null,
+ json: content.user,
+ params: {
userId: content.userId
- },
- json: content.user
+ }
});
this.$emit('FRIEND:ADD', {
- param: {
+ ref: null,
+ params: {
userId: content.userId
}
});
@@ -2790,7 +2797,8 @@ if (window.CefSharp) {
case 'friend-delete':
this.$emit('FRIEND:DELETE', {
- param: {
+ ref: null,
+ params: {
userId: content.userId
}
});
@@ -2798,85 +2806,94 @@ if (window.CefSharp) {
case 'friend-online':
this.$emit('USER', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
location: content.location,
...content.user
+ },
+ params: {
+ userId: content.userId
}
});
this.$emit('FRIEND:STATE', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
state: 'online'
+ },
+ params: {
+ userId: content.userId
}
});
break;
case 'friend-active':
this.$emit('USER', {
- param: {
+ ref: null,
+ json: content.user,
+ params: {
userId: content.userId
- },
- json: content.user
+ }
});
this.$emit('FRIEND:STATE', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
state: 'active'
+ },
+ params: {
+ userId: content.userId
}
});
break;
case 'friend-offline':
this.$emit('FRIEND:STATE', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
state: 'offline'
+ },
+ params: {
+ userId: content.userId
}
});
break;
case 'friend-update':
this.$emit('USER', {
- param: {
+ ref: null,
+ json: content.user,
+ params: {
userId: content.userId
- },
- json: content.user
+ }
});
break;
case 'friend-location':
if (content.world) {
this.$emit('WORLD', {
- param: {
+ ref: null,
+ json: content.world,
+ params: {
worldId: content.world.id
- },
- json: content.world
+ }
});
}
if (content.userId === this.currentUser.id) {
this.$emit('USER', {
- param: {
+ ref: null,
+ json: content.user,
+ params: {
userId: content.userId
- },
- json: content.user
+ }
});
} else {
this.$emit('USER', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
location: content.location,
...content.user
+ },
+ params: {
+ userId: content.userId
}
});
}
@@ -2884,29 +2901,32 @@ if (window.CefSharp) {
case 'user-update':
this.$emit('USER:CURRENT', {
- param: {
+ ref: null,
+ json: content.user,
+ params: {
userId: content.userId
- },
- json: content.user
+ }
});
break;
case 'user-location':
- if (content.world) {
+ if (isObject(content.world)) {
this.$emit('WORLD', {
- param: {
+ ref: null,
+ json: content.world,
+ params: {
worldId: content.world.id
- },
- json: content.world
+ }
});
}
this.$emit('USER', {
- param: {
- userId: content.userId
- },
+ ref: null,
json: {
id: content.userId,
location: content.location
+ },
+ params: {
+ userId: content.userId
}
});
break;
@@ -2921,6 +2941,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json
};
this.$emit('AUTH', args);
@@ -2929,26 +2950,26 @@ if (window.CefSharp) {
};
API.connectWebSocket = function (token) {
- if (this.webSocket === false) {
+ if (this.webSocket === null) {
var socket = new WebSocket(`wss://pipeline.vrchat.cloud/?auth=${token}`);
socket.onclose = () => {
if (this.webSocket === socket) {
- this.webSocket = false;
+ this.webSocket = null;
}
try {
socket.close();
} catch (err) {
- console.error(err);
}
};
socket.onerror = socket.onclose;
- socket.onmessage = (e) => {
+ socket.onmessage = ({ data }) => {
try {
- var json = JSON.parse(e.data);
+ var json = JSON.parse(data);
if (json.content) {
json.content = JSON.parse(json.content);
}
this.$emit('PIPELINE', {
+ ref: null,
json
});
} catch (err) {
@@ -2960,13 +2981,12 @@ if (window.CefSharp) {
};
API.closeWebSocket = function () {
- if (this.webSocket !== false) {
+ if (this.webSocket !== null) {
var socket = this.webSocket;
- this.webSocket = false;
+ this.webSocket = null;
try {
socket.close();
} catch (err) {
- console.error(err);
}
}
};
@@ -2978,6 +2998,7 @@ if (window.CefSharp) {
method: 'GET'
}).then((json) => {
var args = {
+ ref: null,
json
};
this.$emit('VISITS', args);
@@ -2998,29 +3019,27 @@ if (window.CefSharp) {
var node = [];
for (var key in json) {
var value = json[key];
- if (isObject(value)) {
- if (Array.isArray(value)) {
- node.push({
- children: value.map((val, idx) => {
- if (isObject(val)) {
- return {
- children: buildTreeData(val),
- key: idx
- };
- }
+ if (Array.isArray(value)) {
+ node.push({
+ children: value.map((val, idx) => {
+ if (isObject(val)) {
return {
- key: idx,
- value: val
+ children: buildTreeData(val),
+ key: idx
};
- }),
- key
- });
- } else {
- node.push({
- children: buildTreeData(value),
- key
- });
- }
+ }
+ return {
+ key: idx,
+ value: val
+ };
+ }),
+ key
+ });
+ } else if (isObject(value)) {
+ node.push({
+ children: buildTreeData(value),
+ key
+ });
} else {
node.push({
key,
@@ -3080,8 +3099,10 @@ if (window.CefSharp) {
}
});
- setInterval(() => {
- $timers.forEach((v) => v.update());
+ setInterval(function () {
+ for (var $timer of $timers) {
+ $timer.update();
+ }
}, 5000);
var $app = {
@@ -3104,7 +3125,7 @@ if (window.CefSharp) {
API.$on('SHOW_LAUNCH_DIALOG', (tag) => this.showLaunchDialog(tag));
setInterval(() => this.update(), 1000);
this.update();
- this.$nextTick(() => {
+ this.$nextTick(function () {
this.$el.style.display = '';
this.loginForm.loading = true;
API.getConfig().catch((err) => {
@@ -3125,7 +3146,8 @@ if (window.CefSharp) {
$app.methods.checkAppVersion = function () {
var url = 'https://api.github.com/repos/pypy-vrc/VRCX/releases/latest';
fetch(url).then((res) => res.json()).then((json) => {
- if (json.name &&
+ if (isObject(json) &&
+ json.name &&
json.published_at) {
this.latestAppVersion = `${json.name} (${formatDate(json.published_at, 'YYYY-MM-DD HH24:MI:SS')})`;
if (json.name > this.appVersion) {
@@ -3146,50 +3168,50 @@ if (window.CefSharp) {
};
var insertOrUpdateArrayById = (array, json) => {
- var insertOrUpdate = array.some((val, idx, arr) => {
- if (val.id === json.id) {
- $app.$set(arr, idx, json);
- return true;
+ var { id } = json;
+ var { length } = array;
+ for (var i = 0; i < length; ++i) {
+ if (array[i].id === id) {
+ Vue.set(array, i, json);
+ return;
}
- return false;
- });
- if (!insertOrUpdate) {
- array.push(json);
}
+ array.push(json);
};
$app.methods.update = function () {
- if (API.isLoggedIn) {
- if (--this.nextRefresh <= 0) {
- this.nextRefresh = 60;
- API.getCurrentUser().catch((err1) => {
- if (err1.status_code === 401) {
- API.getConfig().then((args) => {
- API.login({
- username: this.loginForm.username,
- password: this.loginForm.password
- }).catch((err2) => {
- if (err2.status_code === 401) {
- API.logout();
- }
- throw err2;
- });
- return args;
+ if (API.isLoggedIn === false) {
+ return;
+ }
+ if (--this.nextRefresh <= 0) {
+ this.nextRefresh = 60;
+ API.getCurrentUser().catch((err1) => {
+ if (err1.status_code === 401) {
+ API.getConfig().then((args) => {
+ API.login({
+ username: this.loginForm.username,
+ password: this.loginForm.password
+ }).catch((err2) => {
+ if (err2.status_code === 401) {
+ API.logout();
+ }
+ throw err2;
});
- }
- throw err1;
- });
- }
- this.refreshGameLog();
- VRCX.IsGameRunning().then((running) => {
- if (this.isGameRunning !== running) {
- this.isGameRunning = running;
- Discord.SetTimestamps(Date.now(), 0);
+ return args;
+ });
}
- this.updateDiscord();
- this.updateOpenVR();
+ throw err1;
});
}
+ this.refreshGameLog();
+ VRCX.IsGameRunning().then((running) => {
+ if (running !== this.isGameRunning) {
+ this.isGameRunning = running;
+ Discord.SetTimestamps(Date.now(), 0);
+ }
+ this.updateDiscord();
+ this.updateOpenVR();
+ });
};
$app.methods.updateSharedFeed = function () {
@@ -3209,10 +3231,10 @@ if (window.CefSharp) {
var isFriend = false;
var isFavorite = false;
for (var key in API.user) {
- var ctx = API.cachedUsers.get(key);
- if (ctx.displayName === ref.data) {
- isFriend = Boolean(this.friend[ctx.id]);
- isFavorite = Boolean(API.favoriteObject[ctx.id]);
+ var ref = API.cachedUsers.get(key);
+ if (ref.displayName === ref.data) {
+ isFriend = Boolean(this.friend[ref.id]);
+ isFavorite = API.cachedFavoritesByObjectId.has(ref.id);
break;
}
}
@@ -3238,7 +3260,7 @@ if (window.CefSharp) {
arr.push({
...ref,
isFriend: Boolean(this.friend[ref.userId]),
- isFavorite: Boolean(API.favoriteObject[ref.userId])
+ isFavorite: API.cachedFavoritesByObjectId.has(ref.userId)
});
++j;
}
@@ -3348,11 +3370,11 @@ if (window.CefSharp) {
});
API.$on('LOGIN', function (args) {
- $app.$refs.menu.activeIndex = 'feed';
new Noty({
type: 'success',
text: `Hello there, ${escapeTag(args.ref.displayName)}!`
}).show();
+ $app.$refs.menu.activeIndex = 'feed';
});
$app.data.loginForm = {
@@ -3427,7 +3449,8 @@ if (window.CefSharp) {
};
$app.methods.loadMemo = function (id) {
- return VRCXStorage.Get(`memo_${id}`);
+ var key = `memo_${id}`;
+ return VRCXStorage.Get(key);
};
$app.methods.saveMemo = function (id, memo) {
@@ -3510,15 +3533,15 @@ if (window.CefSharp) {
});
API.$on('FRIEND:ADD', function (args) {
- $app.addFriend(args.param.userId);
+ $app.addFriend(args.params.userId);
});
API.$on('FRIEND:DELETE', function (args) {
- $app.removeFriend(args.param.userId);
+ $app.removeFriend(args.params.userId);
});
API.$on('FRIEND:STATE', function (args) {
- $app.updateFriend(args.param.userId, args.json.state);
+ $app.updateFriend(args.params.userId, args.json.state);
});
API.$on('FAVORITE', function (args) {
@@ -3561,53 +3584,54 @@ if (window.CefSharp) {
};
$app.methods.addFriend = function (id, state) {
- if (!this.friend[id]) {
- var ref = API.cachedUsers.get(id);
- var ctx = {
- id,
- state: state || 'offline',
- ref,
- vip: Boolean(API.favoriteObject[id]),
- name: '',
- no: ++this.friendNo,
- memo: this.loadMemo(id)
- };
- if (ref) {
- ctx.name = ref.name;
- } else {
- ref = this.friendLog[id];
- if (ref &&
- ref.displayName) {
- ctx.name = ref.displayName;
- }
+ if (this.friend[id]) {
+ return;
+ }
+ var ref = API.cachedUsers.get(id);
+ var ctx = {
+ id,
+ state: state || 'offline',
+ ref,
+ vip: API.cachedFavoritesByObjectId.has(id),
+ name: '',
+ no: ++this.friendNo,
+ memo: this.loadMemo(id)
+ };
+ if (ref) {
+ ctx.name = ref.name;
+ } else {
+ ref = this.friendLog[id];
+ if (ref &&
+ ref.displayName) {
+ ctx.name = ref.displayName;
}
- this.$set(this.friend, id, ctx);
- if (ctx.state === 'online') {
- if (ctx.vip) {
- this.sortFriendGroup0 = true;
- this.friendGroup0_.push(ctx);
- this.friendGroupA_.unshift(ctx);
- } else {
- this.sortFriendGroup1 = true;
- this.friendGroup1_.push(ctx);
- this.friendGroupB_.unshift(ctx);
- }
- } else if (ctx.state === 'active') {
- this.sortFriendGroup2 = true;
- this.friendGroup2_.push(ctx);
- this.friendGroupC_.unshift(ctx);
+ }
+ Vue.set(this.friend, id, ctx);
+ if (ctx.state === 'online') {
+ if (ctx.vip) {
+ this.sortFriendGroup0 = true;
+ this.friendGroup0_.push(ctx);
+ this.friendGroupA_.unshift(ctx);
} else {
- this.sortFriendGroup3 = true;
- this.friendGroup3_.push(ctx);
- this.friendGroupD_.unshift(ctx);
+ this.sortFriendGroup1 = true;
+ this.friendGroup1_.push(ctx);
+ this.friendGroupB_.unshift(ctx);
}
+ } else if (ctx.state === 'active') {
+ this.sortFriendGroup2 = true;
+ this.friendGroup2_.push(ctx);
+ this.friendGroupC_.unshift(ctx);
+ } else {
+ this.sortFriendGroup3 = true;
+ this.friendGroup3_.push(ctx);
+ this.friendGroupD_.unshift(ctx);
}
};
$app.methods.removeFriend = function (id) {
var ctx = this.friend[id];
if (ctx) {
- this.$delete(this.friend, id);
+ Vue.delete(this.friend, id);
if (ctx.state === 'online') {
if (ctx.vip) {
removeFromArray(this.friendGroup0_, ctx);
@@ -3630,7 +3654,7 @@ if (window.CefSharp) {
var ctx = this.friend[id];
if (ctx) {
var ref = API.cachedUsers.get(id);
- var vip = Boolean(API.favoriteObject[id]);
+ var vip = API.cachedFavoritesByObjectId.has(id);
if (state === undefined ||
ctx.state === state) {
if (ctx.ref !== ref) {
@@ -3933,7 +3957,8 @@ if (window.CefSharp) {
{
prop: 'userId',
value: false,
- filterFn: (row, filter) => !filter.value || Boolean(API.favoriteObject[row.userId])
+ filterFn: (row, filter) => !filter.value ||
+ API.cachedFavoritesByObjectId.has(row.userId)
}
],
tableProps: {
@@ -3963,51 +3988,51 @@ if (window.CefSharp) {
});
API.$on('USER:UPDATE', function (args) {
- var { ref, prop } = args;
+ var { ref, props } = args;
if ($app.friend[ref.id]) {
- if (prop.location) {
- if (prop.location[0] === 'offline') {
+ if (props.location) {
+ if (props.location[0] === 'offline') {
$app.addFeed('Offline', ref, {
- location: prop.location[1],
- time: prop.location[2]
+ location: props.location[1],
+ time: props.location[2]
});
- } else if (prop.location[1] === 'offline') {
+ } else if (props.location[1] === 'offline') {
$app.addFeed('Online', ref, {
- location: prop.location[0]
+ location: props.location[0]
});
} else {
$app.addFeed('GPS', ref, {
location: [
- prop.location[0],
- prop.location[1]
+ props.location[0],
+ props.location[1]
],
- time: prop.location[2]
+ time: props.location[2]
});
}
}
- if (prop.currentAvatarThumbnailImageUrl) {
+ if (props.currentAvatarThumbnailImageUrl) {
$app.addFeed('Avatar', ref, {
- avatar: prop.currentAvatarThumbnailImageUrl
+ avatar: props.currentAvatarThumbnailImageUrl
});
}
- if (prop.status ||
- prop.statusDescription) {
+ if (props.status ||
+ props.statusDescription) {
$app.addFeed('Status', ref, {
status: [
{
- status: prop.status
- ? prop.status[0]
+ status: props.status
+ ? props.status[0]
: ref.status,
- statusDescription: prop.statusDescription
- ? prop.statusDescription[0]
+ statusDescription: props.statusDescription
+ ? props.statusDescription[0]
: ref.statusDescription
},
{
- status: prop.status
- ? prop.status[1]
+ status: props.status
+ ? props.status[1]
: ref.status,
- statusDescription: prop.statusDescription
- ? prop.statusDescription[1]
+ statusDescription: props.statusDescription
+ ? props.statusDescription[1]
: ref.statusDescription
}
]
@@ -4285,15 +4310,15 @@ if (window.CefSharp) {
};
$app.methods.moreSearchUser = function (go) {
- var param = this.searchUserParam;
+ var params = this.searchUserParam;
if (go) {
- param.offset += param.n * go;
- if (param.offset < 0) {
- param.offset = 0;
+ params.offset += params.n * go;
+ if (params.offset < 0) {
+ params.offset = 0;
}
}
this.isSearchUserLoading = true;
- API.getUsers(param).finally(() => {
+ API.getUsers(params).finally(() => {
this.isSearchUserLoading = false;
}).then((args) => {
this.searchUsers = [];
@@ -4306,30 +4331,30 @@ if (window.CefSharp) {
$app.methods.searchWorld = function (ref) {
this.searchWorldOption = '';
- var param = {
+ var params = {
n: 10,
offset: 0
};
switch (ref.sortHeading) {
case 'featured':
- param.sort = 'order';
- param.featured = 'true';
+ params.sort = 'order';
+ params.featured = 'true';
break;
case 'trending':
- param.sort = 'popularity';
- param.featured = 'false';
+ params.sort = 'popularity';
+ params.featured = 'false';
break;
case 'updated':
- param.sort = 'updated';
+ params.sort = 'updated';
break;
case 'created':
- param.sort = 'created';
+ params.sort = 'created';
break;
case 'publication':
- param.sort = 'publicationDate';
+ params.sort = 'publicationDate';
break;
case 'shuffle':
- param.sort = 'shuffle';
+ params.sort = 'shuffle';
break;
case 'active':
this.searchWorldOption = 'active';
@@ -4341,40 +4366,40 @@ if (window.CefSharp) {
this.searchWorldOption = 'favorites';
break;
case 'labs':
- param.sort = 'labsPublicationDate';
+ params.sort = 'labsPublicationDate';
break;
case 'heat':
- param.sort = 'heat';
- param.featured = 'false';
+ params.sort = 'heat';
+ params.featured = 'false';
break;
default:
- param.sort = 'popularity';
- param.search = this.searchText;
+ params.sort = 'popularity';
+ params.search = this.searchText;
break;
}
- param.order = ref.sortOrder || 'descending';
+ params.order = ref.sortOrder || 'descending';
if (ref.sortOwnership === 'mine') {
- param.user = 'me';
- param.releaseStatus = 'all';
+ params.user = 'me';
+ params.releaseStatus = 'all';
}
if (ref.tag) {
- param.tag = ref.tag;
+ params.tag = ref.tag;
}
// TODO: option.platform
- this.searchWorldParam = param;
+ this.searchWorldParam = params;
this.moreSearchWorld();
};
$app.methods.moreSearchWorld = function (go) {
- var param = this.searchWorldParam;
+ var params = this.searchWorldParam;
if (go) {
- param.offset += param.n * go;
- if (param.offset < 0) {
- param.offset = 0;
+ params.offset += params.n * go;
+ if (params.offset < 0) {
+ params.offset = 0;
}
}
this.isSearchWorldLoading = true;
- API.getWorlds(param, this.searchWorldOption).finally(() => {
+ API.getWorlds(params, this.searchWorldOption).finally(() => {
this.isSearchWorldLoading = false;
}).then((args) => {
this.searchWorlds = [];
@@ -4386,42 +4411,42 @@ if (window.CefSharp) {
};
$app.methods.searchAvatar = function (option) {
- var param = {
+ var params = {
n: 10,
offset: 0
};
switch (option) {
case 'updated':
- param.sort = 'updated';
+ params.sort = 'updated';
break;
case 'created':
- param.sort = 'created';
+ params.sort = 'created';
break;
case 'mine':
- param.user = 'me';
- param.releaseStatus = 'all';
+ params.user = 'me';
+ params.releaseStatus = 'all';
break;
default:
- param.sort = 'popularity';
- param.search = this.searchText;
+ params.sort = 'popularity';
+ params.search = this.searchText;
break;
}
- param.order = 'descending';
+ params.order = 'descending';
// TODO: option.platform
- this.searchAvatarParam = param;
+ this.searchAvatarParam = params;
this.moreSearchAvatar();
};
$app.methods.moreSearchAvatar = function (go) {
- var param = this.searchAvatarParam;
+ var params = this.searchAvatarParam;
if (go) {
- param.offset += param.n * go;
- if (param.offset < 0) {
- param.offset = 0;
+ params.offset += params.n * go;
+ if (params.offset < 0) {
+ params.offset = 0;
}
}
this.isSearchAvatarLoading = true;
- API.getAvatars(param).finally(() => {
+ API.getAvatars(params).finally(() => {
this.isSearchAvatarLoading = false;
}).then((args) => {
this.searchAvatars = [];
@@ -4457,27 +4482,27 @@ if (window.CefSharp) {
});
API.$on('FAVORITE', function (args) {
- $app.updateFavorite(args.ref.type, args.ref.favoriteId);
+ $app.applyFavorite(args.ref.type, args.ref.favoriteId);
});
API.$on('FAVORITE:@DELETE', function (args) {
- $app.updateFavorite(args.ref.type, args.ref.favoriteId);
+ $app.applyFavorite(args.ref.type, args.ref.favoriteId);
});
API.$on('USER', function (args) {
- $app.updateFavorite('friend', args.ref.id);
+ $app.applyFavorite('friend', args.ref.id);
});
API.$on('WORLD', function (args) {
- $app.updateFavorite('world', args.ref.id);
+ $app.applyFavorite('world', args.ref.id);
});
API.$on('AVATAR', function (args) {
- $app.updateFavorite('avatar', args.ref.id);
+ $app.applyFavorite('avatar', args.ref.id);
});
- $app.methods.updateFavorite = function (type, objectId) {
- var favorite = API.favoriteObject[objectId];
+ $app.methods.applyFavorite = function (type, objectId) {
+ var favorite = API.cachedFavoritesByObjectId.get(objectId);
if (type === 'friend') {
var ctx = this.favoriteFriend[objectId];
if (favorite) {
@@ -4494,7 +4519,7 @@ if (window.CefSharp) {
} else {
ctx = {
id: objectId,
- group: favorite.$group,
+ groupKey: favorite.$groupKey,
ref,
name: ''
};
@@ -4507,12 +4532,12 @@ if (window.CefSharp) {
ctx.name = ref.displayName;
}
}
- this.$set(this.favoriteFriend, objectId, ctx);
+ Vue.set(this.favoriteFriend, objectId, ctx);
this.favoriteFriends_.push(ctx);
this.sortFavoriteFriends = true;
}
} else if (ctx) {
- this.$delete(this.favoriteFriend, objectId);
+ Vue.delete(this.favoriteFriend, objectId);
removeFromArray(this.favoriteFriends_, ctx);
}
} else if (type === 'world') {
@@ -4531,19 +4556,19 @@ if (window.CefSharp) {
} else {
ctx = {
id: objectId,
- group: favorite.$group,
+ groupKey: favorite.$groupKey,
ref,
name: ''
};
if (ref) {
ctx.name = ref.name;
}
- this.$set(this.favoriteWorld, objectId, ctx);
+ Vue.set(this.favoriteWorld, objectId, ctx);
this.favoriteWorlds_.push(ctx);
this.sortFavoriteWorlds = true;
}
} else {
- this.$delete(this.favoriteWorld, objectId);
+ Vue.delete(this.favoriteWorld, objectId);
removeFromArray(this.favoriteWorlds_, ctx);
}
} else if (type === 'avatar') {
@@ -4562,19 +4587,19 @@ if (window.CefSharp) {
} else {
ctx = {
id: objectId,
- group: favorite.$group,
+ groupKey: favorite.$groupKey,
ref,
name: ''
};
if (ref) {
ctx.name = ref.name;
}
- this.$set(this.favoriteAvatar, objectId, ctx);
+ Vue.set(this.favoriteAvatar, objectId, ctx);
this.favoriteAvatars_.push(ctx);
this.sortFavoriteAvatars = true;
}
} else {
- this.$delete(this.favoriteAvatar, objectId);
+ Vue.delete(this.favoriteAvatar, objectId);
removeFromArray(this.favoriteAvatars_, ctx);
}
}
@@ -4723,15 +4748,15 @@ if (window.CefSharp) {
});
API.$on('FRIEND:ADD', function (args) {
- $app.addFriendship(args.param.userId);
+ $app.addFriendship(args.params.userId);
});
API.$on('FRIEND:DELETE', function (args) {
- $app.deleteFriendship(args.param.userId);
+ $app.deleteFriendship(args.params.userId);
});
API.$on('FRIEND:REQUEST', function (args) {
- var ref = this.cachedUsers.get(args.param.userId);
+ var ref = this.cachedUsers.get(args.params.userId);
if (ref) {
$app.friendLogTable.data.push({
created_at: new Date().toJSON(),
@@ -4744,7 +4769,7 @@ if (window.CefSharp) {
});
API.$on('FRIEND:REQUEST:CANCEL', function (args) {
- var ref = this.cachedUsers.get(args.param.userId);
+ var ref = this.cachedUsers.get(args.params.userId);
if (ref) {
$app.friendLogTable.data.push({
created_at: new Date().toJSON(),
@@ -4797,7 +4822,7 @@ if (window.CefSharp) {
displayName: null,
trustLevel: null
};
- this.$set(this.friendLog, id, ctx);
+ Vue.set(this.friendLog, id, ctx);
var ref = API.cachedUsers.get(id);
if (ref) {
ctx.displayName = ref.displayName;
@@ -4817,7 +4842,7 @@ if (window.CefSharp) {
$app.methods.deleteFriendship = function (id) {
var ctx = this.friendLog[id];
if (ctx) {
- this.$delete(this.friendLog, id);
+ Vue.delete(this.friendLog, id);
this.friendLogTable.data.push({
created_at: new Date().toJSON(),
type: 'Unfriend',
@@ -4948,9 +4973,9 @@ if (window.CefSharp) {
var insertOrUpdate = $app.playerModerationTable.data.some((val, idx, arr) => {
if (val.id === args.ref.id) {
if (args.ref.$isExpired) {
- $app.$delete(arr, idx);
+ Vue.delete(arr, idx);
} else {
- $app.$set(arr, idx, args.ref);
+ Vue.set(arr, idx, args.ref);
}
return true;
}
@@ -4966,7 +4991,7 @@ if (window.CefSharp) {
API.$on('PLAYER-MODERATION:@DELETE', function (args) {
$app.playerModerationTable.data.find((val, idx, arr) => {
if (val.id === args.ref.id) {
- $app.$delete(arr, idx);
+ Vue.delete(arr, idx);
return true;
}
return false;
@@ -5034,9 +5059,9 @@ if (window.CefSharp) {
var insertOrUpdate = $app.notificationTable.data.some((val, idx, arr) => {
if (val.id === args.ref.id) {
if (args.ref.$isExpired) {
- $app.$delete(arr, idx);
+ Vue.delete(arr, idx);
} else {
- $app.$set(arr, idx, args.ref);
+ Vue.set(arr, idx, args.ref);
}
return true;
}
@@ -5052,7 +5077,7 @@ if (window.CefSharp) {
API.$on('NOTIFICATION:@DELETE', function (args) {
$app.notificationTable.data.find((val, idx, arr) => {
if (val.id === args.ref.id) {
- $app.$delete(arr, idx);
+ Vue.delete(arr, idx);
return true;
}
return false;
@@ -5312,7 +5337,7 @@ if (window.CefSharp) {
if (D.visible &&
args.ref.id === D.id) {
D.ref = args.ref;
- $app.updateUserDialogLocation();
+ $app.applyUserDialogLocation();
}
});
@@ -5320,14 +5345,14 @@ if (window.CefSharp) {
var D = $app.userDialog;
if (D.visible &&
args.ref.id === D.$location.worldId) {
- $app.updateUserDialogLocation();
+ $app.applyUserDialogLocation();
}
});
API.$on('FRIEND:STATUS', function (args) {
var D = $app.userDialog;
if (D.visible &&
- args.param.userId === D.id) {
+ args.params.userId === D.id) {
D.isFriend = args.json.isFriend;
D.incomingRequest = args.json.incomingRequest;
D.outgoingRequest = args.json.outgoingRequest;
@@ -5337,7 +5362,7 @@ if (window.CefSharp) {
API.$on('FRIEND:REQUEST', function (args) {
var D = $app.userDialog;
if (D.visible &&
- args.param.userId === D.id) {
+ args.params.userId === D.id) {
if (args.json.success) {
D.isFriend = true;
} else {
@@ -5349,7 +5374,7 @@ if (window.CefSharp) {
API.$on('FRIEND:REQUEST:CANCEL', function (args) {
var D = $app.userDialog;
if (D.visible &&
- args.param.userId === D.id) {
+ args.params.userId === D.id) {
D.outgoingRequest = false;
}
});
@@ -5386,7 +5411,7 @@ if (window.CefSharp) {
API.$on('FRIEND:DELETE', function (args) {
var D = $app.userDialog;
if (D.visible &&
- args.param.userId === D.id) {
+ args.params.userId === D.id) {
D.isFriend = false;
}
});
@@ -5477,8 +5502,8 @@ if (window.CefSharp) {
}
}
}
- D.isFavorite = Boolean(API.favoriteObject[D.id]);
- this.updateUserDialogLocation();
+ D.isFavorite = API.cachedFavoritesByObjectId.has(D.id);
+ this.applyUserDialogLocation();
D.worlds = [];
D.avatars = [];
D.isWorldsLoading = false;
@@ -5499,14 +5524,14 @@ if (window.CefSharp) {
userId: D.id
});
if (args.cache) {
- API.getUser(args.param);
+ API.getUser(args.params);
}
}
return args;
});
};
- $app.methods.updateUserDialogLocation = function () {
+ $app.methods.applyUserDialogLocation = function () {
var D = this.userDialog;
var L = API.parseLocation(D.ref.location);
D.$location = L;
@@ -5518,7 +5543,7 @@ if (window.CefSharp) {
API.getUser({
userId: L.userId
}).then((args) => {
- this.$set(L, 'user', args.ref);
+ Vue.set(L, 'user', args.ref);
return args;
});
}
@@ -5594,7 +5619,7 @@ if (window.CefSharp) {
var D = this.userDialog;
if (!D.isWorldsLoading) {
D.isWorldsLoading = true;
- var param = {
+ var params = {
n: 100,
offset: 0,
sort: 'updated',
@@ -5603,14 +5628,14 @@ if (window.CefSharp) {
userId: D.id,
releaseStatus: 'public'
};
- if (param.userId === API.currentUser.id) {
- param.user = 'me';
- param.releaseStatus = 'all';
+ if (params.userId === API.currentUser.id) {
+ params.user = 'me';
+ params.releaseStatus = 'all';
}
API.bulk({
fn: 'getWorlds',
N: -1,
- param,
+ params,
handle: (args) => {
args.json.forEach((json) => {
insertOrUpdateArrayById(D.worlds, json);
@@ -5642,7 +5667,7 @@ if (window.CefSharp) {
var D = this.userDialog;
if (!D.isAvatarsLoading) {
D.isAvatarsLoading = true;
- var param = {
+ var params = {
n: 100,
offset: 0,
sort: 'updated',
@@ -5651,14 +5676,14 @@ if (window.CefSharp) {
userId: D.id,
releaseStatus: 'public'
};
- if (param.userId === API.currentUser.id) {
- param.user = 'me';
- param.releaseStatus = 'all';
+ if (params.userId === API.currentUser.id) {
+ params.user = 'me';
+ params.releaseStatus = 'all';
}
API.bulk({
fn: 'getAvatars',
N: -1,
- param,
+ params,
handle: (args) => {
args.json.forEach((json) => {
insertOrUpdateArrayById(D.avatars, json);
@@ -5858,7 +5883,7 @@ if (window.CefSharp) {
D.fileSize = `${(ref.file.sizeInBytes / 1048576).toFixed(2)} MiB`;
});
}
- $app.updateWorldDialogInstances();
+ $app.applyWorldDialogInstances();
}
});
@@ -5901,11 +5926,11 @@ if (window.CefSharp) {
if (D.id === args.ref.id) {
D.loading = false;
D.ref = args.ref;
- D.isFavorite = Boolean(API.favoriteObject[D.id]);
+ D.isFavorite = API.cachedFavoritesByObjectId.has(D.id);
D.rooms = [];
- this.updateWorldDialogInstances();
+ this.applyWorldDialogInstances();
if (args.cache) {
- API.getWorld(args.param);
+ API.getWorld(args.params);
}
}
return args;
@@ -5913,7 +5938,7 @@ if (window.CefSharp) {
}
};
- $app.methods.updateWorldDialogInstances = function () {
+ $app.methods.applyWorldDialogInstances = function () {
var D = this.worldDialog;
if (D.ref.instances) {
var map = {};
@@ -5965,7 +5990,7 @@ if (window.CefSharp) {
API.getUser({
userId: L.userId
}).then((args) => {
- this.$set(L, 'user', args.ref);
+ Vue.set(L, 'user', args.ref);
return args;
});
}
@@ -6131,9 +6156,9 @@ if (window.CefSharp) {
if (D.id === args.ref.id) {
D.loading = false;
D.ref = args.ref;
- D.isFavorite = Boolean(API.favoriteObject[D.ref.id]);
+ D.isFavorite = API.cachedFavoritesByObjectId.has(D.ref.id);
if (args.cache) {
- API.getAvatar(args.param);
+ API.getAvatar(args.params);
}
}
return args;
@@ -6280,7 +6305,7 @@ if (window.CefSharp) {
var D = this.inviteDialog;
if (!D.loading) {
D.loading = true;
- var param = {
+ var params = {
receiverUserId: '',
type: 'invite',
message: '',
@@ -6292,8 +6317,8 @@ if (window.CefSharp) {
};
var invite = () => {
if (D.userIds.length) {
- param.receiverUserId = D.userIds.shift();
- API.sendNotification(param).finally(invite);
+ params.receiverUserId = D.userIds.shift();
+ API.sendNotification(params).finally(invite);
} else {
D.loading = false;
D.visible = false;
diff --git a/html/index.html b/html/index.html
index 5ac16dd8..4611d639 100644
--- a/html/index.html
+++ b/html/index.html
@@ -322,7 +322,7 @@