mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-02 04:56:06 +02:00
834 lines
24 KiB
JavaScript
834 lines
24 KiB
JavaScript
import { computed, reactive, ref, shallowReactive, watch } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
|
|
|
|
import {
|
|
compareByCreatedAt,
|
|
compareByDisplayName,
|
|
compareByLocationAt,
|
|
compareByName,
|
|
compareByUpdatedAt,
|
|
isRealInstance,
|
|
parseLocation,
|
|
replaceBioSymbols
|
|
} from '../shared/utils';
|
|
import { getAllUserMemos } from '../coordinators/memoCoordinator';
|
|
import { instanceRequest, userRequest } from '../api';
|
|
import { AppDebug } from '../services/appConfig';
|
|
import { database } from '../services/database';
|
|
import { runUpdateCurrentUserLocationFlow } from '../coordinators/locationCoordinator';
|
|
import { useAppearanceSettingsStore } from './settings/appearance';
|
|
import { useFriendStore } from './friend';
|
|
import { useInstanceStore } from './instance';
|
|
import { useLocationStore } from './location';
|
|
import { syncFriendSearchIndex } from '../coordinators/searchIndexCoordinator';
|
|
import { useUiStore } from './ui';
|
|
import { watchState } from '../services/watchState';
|
|
|
|
import * as workerTimers from 'worker-timers';
|
|
|
|
export const useUserStore = defineStore('User', () => {
|
|
const appearanceSettingsStore = useAppearanceSettingsStore();
|
|
const friendStore = useFriendStore();
|
|
const locationStore = useLocationStore();
|
|
const instanceStore = useInstanceStore();
|
|
const uiStore = useUiStore();
|
|
|
|
|
|
const currentUser = ref({
|
|
acceptedPrivacyVersion: 0,
|
|
acceptedTOSVersion: 0,
|
|
accountDeletionDate: null,
|
|
accountDeletionLog: null,
|
|
activeFriends: [],
|
|
ageVerificationStatus: '',
|
|
ageVerified: false,
|
|
allowAvatarCopying: false,
|
|
badges: [],
|
|
bio: '',
|
|
bioLinks: [],
|
|
currentAvatar: '',
|
|
currentAvatarImageUrl: '',
|
|
currentAvatarTags: [],
|
|
currentAvatarThumbnailImageUrl: '',
|
|
date_joined: '',
|
|
developerType: '',
|
|
discordDetails: {
|
|
global_name: '',
|
|
id: ''
|
|
},
|
|
discordId: '',
|
|
displayName: '',
|
|
emailVerified: false,
|
|
fallbackAvatar: '',
|
|
friendGroupNames: [],
|
|
friendKey: '',
|
|
friends: [],
|
|
googleId: '',
|
|
hasBirthday: false,
|
|
hasDiscordFriendsOptOut: false,
|
|
hasEmail: false,
|
|
hasLoggedInFromClient: false,
|
|
hasPendingEmail: false,
|
|
hasSharedConnectionsOptOut: false,
|
|
hideContentFilterSettings: false,
|
|
homeLocation: '',
|
|
id: '',
|
|
isAdult: true,
|
|
isBoopingEnabled: false,
|
|
isFriend: false,
|
|
last_activity: '',
|
|
last_login: '',
|
|
last_mobile: null,
|
|
last_platform: '',
|
|
obfuscatedEmail: '',
|
|
obfuscatedPendingEmail: '',
|
|
oculusId: '',
|
|
offlineFriends: [],
|
|
onlineFriends: [],
|
|
pastDisplayNames: [],
|
|
picoId: '',
|
|
presence: {
|
|
avatarThumbnail: '',
|
|
currentAvatarTags: '',
|
|
debugflag: '',
|
|
displayName: '',
|
|
groups: [],
|
|
id: '',
|
|
instance: '',
|
|
instanceType: '',
|
|
platform: '',
|
|
profilePicOverride: '',
|
|
status: '',
|
|
travelingToInstance: '',
|
|
travelingToWorld: '',
|
|
userIcon: '',
|
|
world: ''
|
|
},
|
|
profilePicOverride: '',
|
|
profilePicOverrideThumbnail: '',
|
|
pronouns: '',
|
|
queuedInstance: '',
|
|
state: '',
|
|
status: '',
|
|
statusDescription: '',
|
|
statusFirstTime: false,
|
|
statusHistory: [],
|
|
steamDetails: {},
|
|
steamId: '',
|
|
tags: [],
|
|
twoFactorAuthEnabled: false,
|
|
twoFactorAuthEnabledDate: null,
|
|
unsubscribe: false,
|
|
updated_at: '',
|
|
userIcon: '',
|
|
userLanguage: '',
|
|
userLanguageCode: '',
|
|
username: '',
|
|
viveId: '',
|
|
// VRCX
|
|
$online_for: Date.now(),
|
|
$offline_for: null,
|
|
$location_at: Date.now(),
|
|
$travelingToTime: Date.now(),
|
|
$previousAvatarSwapTime: null,
|
|
$homeLocation: {},
|
|
$isVRCPlus: false,
|
|
$isModerator: false,
|
|
$isTroll: false,
|
|
$isProbableTroll: false,
|
|
$trustLevel: 'Visitor',
|
|
$trustClass: 'x-tag-untrusted',
|
|
$userColour: '',
|
|
$trustSortNum: 1,
|
|
$languages: [],
|
|
$locationTag: '',
|
|
$travelingToLocation: ''
|
|
});
|
|
|
|
const userDialog = ref({
|
|
visible: false,
|
|
loading: false,
|
|
activeTab: 'Info',
|
|
lastActiveTab: 'Info',
|
|
id: '',
|
|
ref: {},
|
|
friend: {},
|
|
isFriend: false,
|
|
note: '',
|
|
incomingRequest: false,
|
|
outgoingRequest: false,
|
|
isBlock: false,
|
|
isMute: false,
|
|
isHideAvatar: false,
|
|
isShowAvatar: false,
|
|
isInteractOff: false,
|
|
isMuteChat: false,
|
|
isFavorite: false,
|
|
$location: {},
|
|
$homeLocationName: '',
|
|
users: [],
|
|
instance: {
|
|
id: '',
|
|
tag: '',
|
|
$location: {},
|
|
friendCount: 0,
|
|
users: [],
|
|
shortName: '',
|
|
ref: {}
|
|
},
|
|
worlds: [],
|
|
avatars: [],
|
|
isWorldsLoading: false,
|
|
isFavoriteWorldsLoading: false,
|
|
isAvatarsLoading: false,
|
|
isGroupsLoading: false,
|
|
userFavoriteWorlds: [],
|
|
userGroups: {
|
|
groups: [],
|
|
ownGroups: [],
|
|
mutualGroups: [],
|
|
remainingGroups: []
|
|
},
|
|
|
|
worldSorting: {
|
|
name: 'dialog.user.worlds.sorting.updated',
|
|
value: 'updated'
|
|
},
|
|
worldOrder: {
|
|
name: 'dialog.user.worlds.order.descending',
|
|
value: 'descending'
|
|
},
|
|
groupSorting: {
|
|
name: 'dialog.user.groups.sorting.alphabetical',
|
|
value: 'alphabetical'
|
|
},
|
|
mutualFriendSorting: {
|
|
name: 'dialog.user.mutual_friends.sorting.alphabetical',
|
|
value: 'alphabetical'
|
|
},
|
|
avatarSorting: 'update',
|
|
avatarReleaseStatus: 'all',
|
|
memo: '',
|
|
$avatarInfo: {
|
|
ownerId: '',
|
|
avatarName: '',
|
|
fileCreatedAt: ''
|
|
},
|
|
representedGroup: {
|
|
bannerId: '',
|
|
bannerUrl: '',
|
|
description: '',
|
|
discriminator: '',
|
|
groupId: '',
|
|
iconUrl: '',
|
|
id: '',
|
|
isRepresenting: false,
|
|
memberCount: 0,
|
|
memberVisibility: '',
|
|
name: '',
|
|
ownerId: '',
|
|
privacy: '',
|
|
shortCode: '',
|
|
$thumbnailUrl: '',
|
|
$memberId: ''
|
|
},
|
|
isRepresentedGroupLoading: false,
|
|
joinCount: 0,
|
|
timeSpent: 0,
|
|
lastSeen: '',
|
|
avatarModeration: 0,
|
|
previousDisplayNames: [],
|
|
dateFriended: '',
|
|
unFriended: false,
|
|
dateFriendedInfo: [],
|
|
mutualFriendCount: 0,
|
|
mutualGroupCount: 0,
|
|
mutualFriends: [],
|
|
isMutualFriendsLoading: false
|
|
});
|
|
|
|
const currentTravelers = reactive(new Map());
|
|
const subsetOfLanguages = ref([]);
|
|
const languageDialog = ref({
|
|
visible: false,
|
|
loading: false,
|
|
languageChoice: false,
|
|
languages: []
|
|
});
|
|
const sendBoopDialog = ref({
|
|
visible: false,
|
|
userId: ''
|
|
});
|
|
const showUserDialogHistory = reactive(new Set());
|
|
const customUserTags = reactive(new Map());
|
|
|
|
const state = reactive({
|
|
instancePlayerCount: new Map(),
|
|
lastNoteCheck: null,
|
|
lastDbNoteDate: null,
|
|
notes: new Map()
|
|
});
|
|
|
|
const cachedUsers = shallowReactive(new Map());
|
|
const cachedUserIdsByDisplayName = shallowReactive(new Map());
|
|
|
|
function addCachedUserDisplayNameEntry(displayName, userId) {
|
|
if (!displayName || !userId) {
|
|
return;
|
|
}
|
|
let userIds = cachedUserIdsByDisplayName.get(displayName);
|
|
if (!userIds) {
|
|
userIds = new Set();
|
|
cachedUserIdsByDisplayName.set(displayName, userIds);
|
|
}
|
|
userIds.add(userId);
|
|
}
|
|
|
|
function removeCachedUserDisplayNameEntry(displayName, userId) {
|
|
if (!displayName || !userId) {
|
|
return;
|
|
}
|
|
const userIds = cachedUserIdsByDisplayName.get(displayName);
|
|
if (!userIds) {
|
|
return;
|
|
}
|
|
userIds.delete(userId);
|
|
if (userIds.size === 0) {
|
|
cachedUserIdsByDisplayName.delete(displayName);
|
|
}
|
|
}
|
|
|
|
function syncCachedUserDisplayName(ref, previousDisplayName = '') {
|
|
if (!ref?.id) {
|
|
return;
|
|
}
|
|
if (previousDisplayName && previousDisplayName !== ref.displayName) {
|
|
removeCachedUserDisplayNameEntry(previousDisplayName, ref.id);
|
|
}
|
|
addCachedUserDisplayNameEntry(ref.displayName, ref.id);
|
|
}
|
|
|
|
function setCachedUser(
|
|
ref,
|
|
previousDisplayName = '',
|
|
{ skipIndex = false } = {}
|
|
) {
|
|
if (!ref?.id) {
|
|
return;
|
|
}
|
|
cachedUsers.set(ref.id, ref);
|
|
if (!skipIndex) {
|
|
syncCachedUserDisplayName(ref, previousDisplayName);
|
|
}
|
|
}
|
|
|
|
function deleteCachedUser(userId) {
|
|
const ref = cachedUsers.get(userId);
|
|
if (!ref) {
|
|
return false;
|
|
}
|
|
removeCachedUserDisplayNameEntry(ref.displayName, userId);
|
|
return cachedUsers.delete(userId);
|
|
}
|
|
|
|
function clearCachedUsers() {
|
|
cachedUsers.clear();
|
|
cachedUserIdsByDisplayName.clear();
|
|
}
|
|
|
|
function rebuildCachedUserDisplayNameIndex() {
|
|
cachedUserIdsByDisplayName.clear();
|
|
for (const ref of cachedUsers.values()) {
|
|
addCachedUserDisplayNameEntry(ref.displayName, ref.id);
|
|
}
|
|
}
|
|
|
|
const isLocalUserVrcPlusSupporter = computed(
|
|
() => currentUser.value.$isVRCPlus || AppDebug.debugVrcPlus
|
|
);
|
|
|
|
watch(
|
|
() => watchState.isLoggedIn,
|
|
(isLoggedIn) => {
|
|
if (!isLoggedIn) {
|
|
currentTravelers.clear();
|
|
showUserDialogHistory.clear();
|
|
state.instancePlayerCount.clear();
|
|
customUserTags.clear();
|
|
state.notes.clear();
|
|
subsetOfLanguages.value = [];
|
|
uiStore.clearDialogCrumbs();
|
|
}
|
|
},
|
|
{ flush: 'sync' }
|
|
);
|
|
|
|
watch(
|
|
() => watchState.isFriendsLoaded,
|
|
(isFriendsLoaded) => {
|
|
if (isFriendsLoaded) {
|
|
getAllUserMemos();
|
|
initUserNotes();
|
|
}
|
|
},
|
|
{ flush: 'sync' }
|
|
);
|
|
|
|
/**
|
|
* @param {object} ref
|
|
*/
|
|
function applyUserLanguage(ref) {
|
|
if (!ref || !ref.tags || !subsetOfLanguages.value) {
|
|
return;
|
|
}
|
|
|
|
ref.$languages = [];
|
|
const languagePrefix = 'language_';
|
|
const prefixLength = languagePrefix.length;
|
|
|
|
for (const tag of ref.tags) {
|
|
if (tag.startsWith(languagePrefix)) {
|
|
const key = tag.substring(prefixLength);
|
|
const value = subsetOfLanguages.value[key];
|
|
|
|
if (value !== undefined) {
|
|
ref.$languages.push({ key, value });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {object} ref
|
|
*/
|
|
function applyPresenceLocation(ref) {
|
|
const presence = ref.presence;
|
|
if (isRealInstance(presence.world)) {
|
|
ref.$locationTag = `${presence.world}:${presence.instance}`;
|
|
} else {
|
|
ref.$locationTag = presence.world;
|
|
}
|
|
if (isRealInstance(presence.travelingToWorld)) {
|
|
ref.$travelingToLocation = `${presence.travelingToWorld}:${presence.travelingToInstance}`;
|
|
} else {
|
|
ref.$travelingToLocation = presence.travelingToWorld;
|
|
}
|
|
runUpdateCurrentUserLocationFlow();
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} updateInstanceOccupants
|
|
*/
|
|
function applyUserDialogLocation(updateInstanceOccupants = false) {
|
|
let addUser;
|
|
let friend;
|
|
let ref;
|
|
const D = userDialog.value;
|
|
if (!D.visible) {
|
|
return;
|
|
}
|
|
const L = parseLocation(D.ref.$location?.tag);
|
|
if (updateInstanceOccupants && L.isRealInstance) {
|
|
instanceRequest.getInstance({
|
|
worldId: L.worldId,
|
|
instanceId: L.instanceId
|
|
});
|
|
}
|
|
D.$location = L;
|
|
L.user = {};
|
|
if (L.userId) {
|
|
ref = cachedUsers.get(L.userId);
|
|
if (typeof ref === 'undefined') {
|
|
userRequest
|
|
.getUser({
|
|
userId: L.userId
|
|
})
|
|
.then((args) => {
|
|
if (args.ref.id === L.userId) {
|
|
Object.assign(L.user, args.ref);
|
|
D.$location = L;
|
|
applyUserDialogLocation();
|
|
}
|
|
});
|
|
} else {
|
|
L.user = ref;
|
|
}
|
|
}
|
|
const users = [];
|
|
let friendCount = 0;
|
|
const playersInInstance = locationStore.lastLocation.playerList;
|
|
const cachedCurrentUser = cachedUsers.get(currentUser.value.id);
|
|
const currentLocation = cachedCurrentUser?.$location?.tag;
|
|
if (!L.isOffline && currentLocation === L.tag) {
|
|
ref = cachedUsers.get(currentUser.value.id);
|
|
if (typeof ref !== 'undefined') {
|
|
users.push(ref); // add self
|
|
}
|
|
}
|
|
// dont use gamelog when using api location
|
|
if (
|
|
locationStore.lastLocation.location === L.tag &&
|
|
playersInInstance.size > 0
|
|
) {
|
|
const friendsInInstance = locationStore.lastLocation.friendList;
|
|
for (friend of friendsInInstance.values()) {
|
|
// if friend isn't in instance add them
|
|
addUser = !users.some(function (user) {
|
|
return friend.userId === user.id;
|
|
});
|
|
if (addUser) {
|
|
ref = cachedUsers.get(friend.userId);
|
|
if (typeof ref !== 'undefined') {
|
|
users.push(ref);
|
|
}
|
|
}
|
|
}
|
|
friendCount = users.length - 1;
|
|
}
|
|
if (!L.isOffline) {
|
|
for (friend of friendStore.friends.values()) {
|
|
if (typeof friend.ref === 'undefined') {
|
|
continue;
|
|
}
|
|
if (
|
|
friend.ref.location === locationStore.lastLocation.location
|
|
) {
|
|
// don't add friends to currentUser gameLog instance (except when traveling)
|
|
continue;
|
|
}
|
|
if (friend.ref.$location.tag === L.tag) {
|
|
if (
|
|
friend.state !== 'online' &&
|
|
friend.ref.location === 'private'
|
|
) {
|
|
// don't add offline friends to private instances
|
|
continue;
|
|
}
|
|
// if friend isn't in instance add them
|
|
addUser = !users.some(function (user) {
|
|
return friend.name === user.displayName;
|
|
});
|
|
if (addUser) {
|
|
users.push(friend.ref);
|
|
}
|
|
}
|
|
}
|
|
friendCount = users.length;
|
|
}
|
|
if (appearanceSettingsStore.instanceUsersSortAlphabetical) {
|
|
users.sort(compareByDisplayName);
|
|
} else {
|
|
users.sort(compareByLocationAt);
|
|
}
|
|
D.users = users;
|
|
if (
|
|
(L.worldId &&
|
|
currentLocation === L.tag &&
|
|
playersInInstance.size > 0) ||
|
|
!L.isRealInstance
|
|
) {
|
|
D.instance = {
|
|
id: L.instanceId,
|
|
tag: L.tag,
|
|
$location: L,
|
|
friendCount: 0,
|
|
users: [],
|
|
shortName: '',
|
|
ref: {}
|
|
};
|
|
}
|
|
const instanceRef = instanceStore.cachedInstances.get(L.tag) || {};
|
|
Object.assign(D.instance.ref, instanceRef);
|
|
D.instance.friendCount = friendCount;
|
|
}
|
|
|
|
/**
|
|
* @param array
|
|
*/
|
|
function sortUserDialogAvatars(array) {
|
|
const D = userDialog.value;
|
|
if (D.avatarSorting === 'update') {
|
|
array.sort(compareByUpdatedAt);
|
|
} else if (D.avatarSorting === 'createdAt') {
|
|
array.sort(compareByCreatedAt);
|
|
} else {
|
|
array.sort(compareByName);
|
|
}
|
|
D.avatars = array;
|
|
}
|
|
|
|
/**
|
|
*/
|
|
async function initUserNotes() {
|
|
state.lastNoteCheck = new Date();
|
|
state.lastDbNoteDate = null;
|
|
state.notes.clear();
|
|
try {
|
|
const users = cachedUsers;
|
|
const dbNotes = await database.getAllUserNotes();
|
|
for (const note of dbNotes) {
|
|
state.notes.set(note.userId, note.note);
|
|
const user = users.get(note.userId);
|
|
if (user) {
|
|
user.note = note.note;
|
|
const friendCtx = friendStore.friends.get(note.userId);
|
|
if (friendCtx) {
|
|
syncFriendSearchIndex(friendCtx);
|
|
}
|
|
}
|
|
if (
|
|
!state.lastDbNoteDate ||
|
|
state.lastDbNoteDate < note.createdAt
|
|
) {
|
|
state.lastDbNoteDate = note.createdAt;
|
|
}
|
|
}
|
|
await getLatestUserNotes();
|
|
} catch (error) {
|
|
console.error('Error initializing user notes:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*/
|
|
async function getLatestUserNotes() {
|
|
state.lastNoteCheck = new Date();
|
|
const params = {
|
|
offset: 0,
|
|
n: 10
|
|
};
|
|
const newNotes = new Map();
|
|
let done = false;
|
|
try {
|
|
for (let i = 0; i < 100; i++) {
|
|
params.offset = i * params.n;
|
|
const args = await userRequest.getUserNotes(params);
|
|
for (const note of args.json) {
|
|
if (
|
|
state.lastDbNoteDate &&
|
|
state.lastDbNoteDate > note.createdAt
|
|
) {
|
|
done = true;
|
|
}
|
|
if (
|
|
!state.lastDbNoteDate ||
|
|
state.lastDbNoteDate < note.createdAt
|
|
) {
|
|
state.lastDbNoteDate = note.createdAt;
|
|
}
|
|
note.note = replaceBioSymbols(note.note);
|
|
newNotes.set(note.targetUserId, note);
|
|
}
|
|
if (done || args.json.length === 0) {
|
|
break;
|
|
}
|
|
params.n = 100;
|
|
await new Promise((resolve) => {
|
|
workerTimers.setTimeout(resolve, 1000);
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching user notes:', error);
|
|
}
|
|
const users = cachedUsers;
|
|
|
|
for (const note of newNotes.values()) {
|
|
const newNote = {
|
|
userId: note.targetUserId,
|
|
displayName: note.targetUser?.displayName || note.targetUserId,
|
|
note: note.note,
|
|
createdAt: note.createdAt
|
|
};
|
|
await database.addUserNote(newNote);
|
|
state.notes.set(note.targetUserId, note.note);
|
|
const user = users.get(note.targetUserId);
|
|
if (user) {
|
|
user.note = note.note;
|
|
const friendCtx = friendStore.friends.get(note.targetUserId);
|
|
if (friendCtx) {
|
|
syncFriendSearchIndex(friendCtx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param userId
|
|
* @param newNote
|
|
*/
|
|
async function checkNote(userId, newNote) {
|
|
if (
|
|
!state.lastNoteCheck ||
|
|
state.lastNoteCheck.getTime() + 5 * 60 * 1000 > Date.now()
|
|
) {
|
|
return;
|
|
}
|
|
const existingNote = state.notes.get(userId);
|
|
if (typeof existingNote !== 'undefined' && !newNote) {
|
|
console.log('deleting note', userId);
|
|
state.notes.delete(userId);
|
|
await database.deleteUserNote(userId);
|
|
return;
|
|
}
|
|
if (typeof existingNote === 'undefined' || existingNote !== newNote) {
|
|
console.log('detected note change', userId, newNote);
|
|
await getLatestUserNotes();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param userId
|
|
*/
|
|
function showSendBoopDialog(userId) {
|
|
sendBoopDialog.value.userId = userId;
|
|
sendBoopDialog.value.visible = true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} value
|
|
*/
|
|
function setUserDialogMemo(value) {
|
|
userDialog.value.memo = value;
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} value
|
|
*/
|
|
function setUserDialogVisible(value) {
|
|
userDialog.value.visible = value;
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} value
|
|
*/
|
|
function setUserDialogIsFavorite(value) {
|
|
userDialog.value.isFavorite = value;
|
|
}
|
|
|
|
/**
|
|
* @param {string} value
|
|
*/
|
|
function setCurrentUserColour(value) {
|
|
currentUser.value.$userColour = value;
|
|
}
|
|
|
|
/**
|
|
* @param {string} location
|
|
* @param {string} travelingToLocation
|
|
* @param {number} timestamp
|
|
*/
|
|
function setCurrentUserLocationState(
|
|
location,
|
|
travelingToLocation,
|
|
timestamp = Date.now()
|
|
) {
|
|
currentUser.value.$location_at = timestamp;
|
|
currentUser.value.$travelingToTime = timestamp;
|
|
currentUser.value.$locationTag = location;
|
|
currentUser.value.$travelingToLocation = travelingToLocation;
|
|
}
|
|
|
|
/**
|
|
* @param {number} value
|
|
*/
|
|
function setCurrentUserTravelingToTime(value) {
|
|
currentUser.value.$travelingToTime = value;
|
|
}
|
|
|
|
/**
|
|
* @param {object} value
|
|
*/
|
|
function setCurrentUser(value) {
|
|
currentUser.value = value;
|
|
}
|
|
|
|
/**
|
|
* @param {object} value
|
|
*/
|
|
function setSubsetOfLanguages(value) {
|
|
subsetOfLanguages.value = value;
|
|
}
|
|
|
|
/**
|
|
* @param {Array} value
|
|
*/
|
|
function setLanguageDialogLanguages(value) {
|
|
languageDialog.value.languages = value;
|
|
}
|
|
|
|
/**
|
|
*/
|
|
function markCurrentUserGameStarted() {
|
|
currentUser.value.$online_for = Date.now();
|
|
currentUser.value.$offline_for = '';
|
|
currentUser.value.$previousAvatarSwapTime = Date.now();
|
|
}
|
|
|
|
/**
|
|
*/
|
|
function markCurrentUserGameStopped() {
|
|
currentUser.value.$online_for = 0;
|
|
currentUser.value.$offline_for = Date.now();
|
|
currentUser.value.$previousAvatarSwapTime = null;
|
|
}
|
|
|
|
/**
|
|
*/
|
|
function toggleSharedConnectionsOptOut() {
|
|
userRequest.saveCurrentUser({
|
|
hasSharedConnectionsOptOut:
|
|
!currentUser.value.hasSharedConnectionsOptOut
|
|
});
|
|
}
|
|
|
|
/**
|
|
*/
|
|
function toggleDiscordFriendsOptOut() {
|
|
userRequest.saveCurrentUser({
|
|
hasDiscordFriendsOptOut: !currentUser.value.hasDiscordFriendsOptOut
|
|
});
|
|
}
|
|
|
|
return {
|
|
state,
|
|
|
|
currentUser,
|
|
currentTravelers,
|
|
userDialog,
|
|
subsetOfLanguages,
|
|
languageDialog,
|
|
sendBoopDialog,
|
|
showUserDialogHistory,
|
|
customUserTags,
|
|
cachedUsers,
|
|
cachedUserIdsByDisplayName,
|
|
isLocalUserVrcPlusSupporter,
|
|
applyUserLanguage,
|
|
applyPresenceLocation,
|
|
applyUserDialogLocation,
|
|
setCachedUser,
|
|
syncCachedUserDisplayName,
|
|
deleteCachedUser,
|
|
clearCachedUsers,
|
|
rebuildCachedUserDisplayNameIndex,
|
|
sortUserDialogAvatars,
|
|
initUserNotes,
|
|
showSendBoopDialog,
|
|
setUserDialogMemo,
|
|
setUserDialogVisible,
|
|
setUserDialogIsFavorite,
|
|
setCurrentUserColour,
|
|
setCurrentUserLocationState,
|
|
setCurrentUserTravelingToTime,
|
|
setCurrentUser,
|
|
setSubsetOfLanguages,
|
|
setLanguageDialogLanguages,
|
|
markCurrentUserGameStarted,
|
|
markCurrentUserGameStopped,
|
|
checkNote,
|
|
toggleSharedConnectionsOptOut,
|
|
toggleDiscordFriendsOptOut
|
|
};
|
|
});
|