Files
VRCX/src/classes/vrcxNotifications.js
pa e792ed481b refactor: dialogs (#1224)
* refactor: dialogs

* fix: storeAvatarImage

* FriendLog.vue

* FriendLog.vue

* FriendLog.vue

* GameLog.vue

* fix: next day button jumping to the wrong date

* sync master

* fix: launchGame

* Notification.vue

* Feed.vue

* Search.vue

* Profile.vue

* PlayerList.vue

* Login.vue

* utils

* update dialog

* del gameLog.pug

* fix

* fix: group role cannot be displayed currently

* fix: "Hide Friends in Same Instance" hides players in unrelated private instances (#1210)

* fix

* fix: "Hide Friends in Same Instance" does not work when "Split Favorite Friends" is enabled

* fix Notification.vue message

* fix: deleteFavoriteNoConfirm

* fix: feed status style

* fix: infinite loading when deleting note

* fix: private players will not be hidden when 'Hide Friends in Same Instance', and 'Hide Friends in Same Instance' will not work when 'Split Favorite Friends'
2025-05-14 20:01:15 +10:00

1622 lines
61 KiB
JavaScript

import { userRequest } from '../api';
import { displayLocation } from '../composables/instance/utils';
import { extractFileId, extractFileVersion } from '../composables/shared/utils';
import { $app, API, baseClass } from './baseClass.js';
export default class extends baseClass {
constructor(_app, _API, _t) {
super(_app, _API, _t);
}
_data = {
notyMap: []
};
_methods = {
queueGameLogNoty(noty) {
// remove join/leave notifications when switching worlds
if (
noty.type === 'OnPlayerJoined' ||
noty.type === 'BlockedOnPlayerJoined' ||
noty.type === 'MutedOnPlayerJoined'
) {
var bias = this.lastLocation.date + 30 * 1000; // 30 secs
if (Date.parse(noty.created_at) <= bias) {
return;
}
}
if (
noty.type === 'OnPlayerLeft' ||
noty.type === 'BlockedOnPlayerLeft' ||
noty.type === 'MutedOnPlayerLeft'
) {
var bias = this.lastLocationDestinationTime + 5 * 1000; // 5 secs
if (Date.parse(noty.created_at) <= bias) {
return;
}
}
if (
noty.type === 'Notification' ||
noty.type === 'LocationDestination'
// skip unused entries
) {
return;
}
if (noty.type === 'VideoPlay') {
if (!noty.videoName) {
// skip video without name
return;
}
noty.notyName = noty.videoName;
if (noty.displayName) {
// add requester's name to noty
noty.notyName = `${noty.videoName} (${noty.displayName})`;
}
}
if (
noty.type !== 'VideoPlay' &&
noty.displayName === API.currentUser.displayName
) {
// remove current user
return;
}
noty.isFriend = false;
noty.isFavorite = false;
if (noty.userId) {
noty.isFriend = this.friends.has(noty.userId);
noty.isFavorite = this.localFavoriteFriends.has(noty.userId);
} else if (noty.displayName) {
for (var ref of API.cachedUsers.values()) {
if (ref.displayName === noty.displayName) {
noty.isFriend = this.friends.has(ref.id);
noty.isFavorite = this.localFavoriteFriends.has(ref.id);
break;
}
}
}
var notyFilter = this.sharedFeedFilters.noty;
if (
notyFilter[noty.type] &&
(notyFilter[noty.type] === 'On' ||
notyFilter[noty.type] === 'Everyone' ||
(notyFilter[noty.type] === 'Friends' && noty.isFriend) ||
(notyFilter[noty.type] === 'VIP' && noty.isFavorite))
) {
this.playNoty(noty);
}
},
queueFeedNoty(noty) {
if (noty.type === 'Avatar') {
return;
}
// hide private worlds from feed
if (
this.hidePrivateFromFeed &&
noty.type === 'GPS' &&
noty.location === 'private'
) {
return;
}
noty.isFriend = this.friends.has(noty.userId);
noty.isFavorite = this.localFavoriteFriends.has(noty.userId);
var notyFilter = this.sharedFeedFilters.noty;
if (
notyFilter[noty.type] &&
(notyFilter[noty.type] === 'Everyone' ||
(notyFilter[noty.type] === 'Friends' && noty.isFriend) ||
(notyFilter[noty.type] === 'VIP' && noty.isFavorite))
) {
this.playNoty(noty);
}
},
queueNotificationNoty(noty) {
noty.isFriend = this.friends.has(noty.senderUserId);
noty.isFavorite = this.localFavoriteFriends.has(noty.senderUserId);
var notyFilter = this.sharedFeedFilters.noty;
if (
notyFilter[noty.type] &&
(notyFilter[noty.type] === 'On' ||
notyFilter[noty.type] === 'Friends' ||
(notyFilter[noty.type] === 'VIP' && noty.isFavorite))
) {
this.playNoty(noty);
}
},
queueFriendLogNoty(noty) {
if (noty.type === 'FriendRequest') {
return;
}
noty.isFriend = this.friends.has(noty.userId);
noty.isFavorite = this.localFavoriteFriends.has(noty.userId);
var notyFilter = this.sharedFeedFilters.noty;
if (
notyFilter[noty.type] &&
(notyFilter[noty.type] === 'On' ||
notyFilter[noty.type] === 'Friends' ||
(notyFilter[noty.type] === 'VIP' && noty.isFavorite))
) {
this.playNoty(noty);
}
},
queueModerationNoty(noty) {
noty.isFriend = false;
noty.isFavorite = false;
if (noty.userId) {
noty.isFriend = this.friends.has(noty.userId);
noty.isFavorite = this.localFavoriteFriends.has(noty.userId);
}
var notyFilter = this.sharedFeedFilters.noty;
if (notyFilter[noty.type] && notyFilter[noty.type] === 'On') {
this.playNoty(noty);
}
},
playNoty(noty) {
if (
API.currentUser.status === 'busy' ||
!this.friendLogInitStatus
) {
return;
}
var displayName = '';
if (noty.displayName) {
displayName = noty.displayName;
} else if (noty.senderUsername) {
displayName = noty.senderUsername;
} else if (noty.sourceDisplayName) {
displayName = noty.sourceDisplayName;
}
if (displayName) {
// don't play noty twice
var notyId = `${noty.type},${displayName}`;
if (
this.notyMap[notyId] &&
this.notyMap[notyId] >= noty.created_at
) {
return;
}
this.notyMap[notyId] = noty.created_at;
}
var bias = new Date(Date.now() - 60000).toJSON();
if (noty.created_at < bias) {
// don't play noty if it's over 1min old
return;
}
const notiConditions = {
Always: () => true,
'Inside VR': () => this.isSteamVRRunning,
'Outside VR': () => !this.isSteamVRRunning,
'Game Closed': () => !this.isGameRunning, // Also known as "Outside VRChat"
'Game Running': () => this.isGameRunning, // Also known as "Inside VRChat"
'Desktop Mode': () => this.isGameNoVR && this.isGameRunning,
AFK: () =>
this.afkDesktopToast &&
this.isHmdAfk &&
this.isGameRunning &&
!this.isGameNoVR
};
const playNotificationTTS =
notiConditions[this.notificationTTS]?.();
const playDesktopToast =
notiConditions[this.desktopToast]?.() ||
notiConditions['AFK']();
const playOverlayToast = notiConditions[this.overlayToast]?.();
const playOverlayNotification =
this.overlayNotifications && playOverlayToast;
const playXSNotification = this.xsNotifications && playOverlayToast;
const playOvrtHudNotifications =
this.ovrtHudNotifications && playOverlayToast;
const playOvrtWristNotifications =
this.ovrtWristNotifications && playOverlayToast;
var message = '';
if (noty.title) {
message = `${noty.title}, ${noty.message}`;
} else if (noty.message) {
message = noty.message;
}
var messageList = [
'inviteMessage',
'requestMessage',
'responseMessage'
];
for (var k = 0; k < messageList.length; k++) {
if (
typeof noty.details !== 'undefined' &&
typeof noty.details[messageList[k]] !== 'undefined'
) {
message = `, ${noty.details[messageList[k]]}`;
}
}
if (playNotificationTTS) {
this.playNotyTTS(noty, displayName, message);
}
if (
playDesktopToast ||
playXSNotification ||
playOvrtHudNotifications ||
playOvrtWristNotifications ||
playOverlayNotification
) {
if (this.imageNotifications) {
this.notySaveImage(noty).then((image) => {
if (playXSNotification) {
this.displayXSNotification(noty, message, image);
}
if (
playOvrtHudNotifications ||
playOvrtWristNotifications
) {
this.displayOvrtNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
noty,
message,
image
);
}
if (playDesktopToast) {
this.displayDesktopToast(noty, message, image);
}
if (playOverlayNotification) {
this.displayOverlayNotification(
noty,
message,
image
);
}
});
} else {
if (playXSNotification) {
this.displayXSNotification(noty, message, '');
}
if (
playOvrtHudNotifications ||
playOvrtWristNotifications
) {
this.displayOvrtNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
noty,
message,
''
);
}
if (playDesktopToast) {
this.displayDesktopToast(noty, message, '');
}
if (playOverlayNotification) {
this.displayOverlayNotification(noty, message, '');
}
}
}
},
getUserIdFromNoty(noty) {
var userId = '';
if (noty.userId) {
userId = noty.userId;
} else if (noty.senderUserId) {
userId = noty.senderUserId;
} else if (noty.sourceUserId) {
userId = noty.sourceUserId;
} else if (noty.displayName) {
for (var ref of API.cachedUsers.values()) {
if (ref.displayName === noty.displayName) {
userId = ref.id;
break;
}
}
}
return userId;
},
async notyGetImage(noty) {
var imageUrl = '';
var userId = this.getUserIdFromNoty(noty);
if (noty.thumbnailImageUrl) {
imageUrl = noty.thumbnailImageUrl;
} else if (noty.details && noty.details.imageUrl) {
imageUrl = noty.details.imageUrl;
} else if (noty.imageUrl) {
imageUrl = noty.imageUrl;
} else if (userId && !userId.startsWith('grp_')) {
imageUrl = await userRequest
.getCachedUser({
userId
})
.catch((err) => {
console.error(err);
return '';
})
.then((args) => {
if (!args.json) {
return '';
}
if (
this.displayVRCPlusIconsAsAvatar &&
args.json.userIcon
) {
return args.json.userIcon;
}
if (args.json.profilePicOverride) {
return args.json.profilePicOverride;
}
return args.json.currentAvatarThumbnailImageUrl;
});
}
return imageUrl;
},
async notySaveImage(noty) {
var imageUrl = await this.notyGetImage(noty);
var fileId = extractFileId(imageUrl);
var fileVersion = extractFileVersion(imageUrl);
var imageLocation = '';
try {
if (fileId && fileVersion) {
imageLocation = await AppApi.GetImage(
imageUrl,
fileId,
fileVersion
);
} else if (imageUrl) {
fileVersion = imageUrl.split('/').pop(); // 1416226261.thumbnail-500.png
fileId = fileVersion.split('.').shift(); // 1416226261
imageLocation = await AppApi.GetImage(
imageUrl,
fileId,
fileVersion
);
}
} catch (err) {
console.error(imageUrl, err);
}
return imageLocation;
},
displayOverlayNotification(noty, message, imageFile) {
var image = '';
if (imageFile) {
image = `file:///${imageFile}`;
}
AppApi.ExecuteVrOverlayFunction(
'playNoty',
JSON.stringify({ noty, message, image })
);
},
async playNotyTTS(noty, displayName, message) {
if (this.notificationTTSNickName) {
var userId = this.getUserIdFromNoty(noty);
var memo = await $app.getUserMemo(userId);
if (memo.memo) {
var array = memo.memo.split('\n');
var nickName = array[0];
displayName = nickName;
}
}
switch (noty.type) {
case 'OnPlayerJoined':
this.speak(`${displayName} has joined`);
break;
case 'OnPlayerLeft':
this.speak(`${displayName} has left`);
break;
case 'OnPlayerJoining':
this.speak(`${displayName} is joining`);
break;
case 'GPS':
this.speak(
`${displayName} is in ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`
);
break;
case 'Online':
var locationName = '';
if (noty.worldName) {
locationName = ` to ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`;
}
this.speak(`${displayName} has logged in${locationName}`);
break;
case 'Offline':
this.speak(`${displayName} has logged out`);
break;
case 'Status':
this.speak(
`${displayName} status is now ${noty.status} ${noty.statusDescription}`
);
break;
case 'invite':
this.speak(
`${displayName} has invited you to ${displayLocation(
noty.details.worldId,
noty.details.worldName,
noty.groupName
)}${message}`
);
break;
case 'requestInvite':
this.speak(
`${displayName} has requested an invite${message}`
);
break;
case 'inviteResponse':
this.speak(
`${displayName} has responded to your invite${message}`
);
break;
case 'requestInviteResponse':
this.speak(
`${displayName} has responded to your invite request${message}`
);
break;
case 'friendRequest':
this.speak(`${displayName} has sent you a friend request`);
break;
case 'Friend':
this.speak(`${displayName} is now your friend`);
break;
case 'Unfriend':
this.speak(`${displayName} is no longer your friend`);
break;
case 'TrustLevel':
this.speak(
`${displayName} trust level is now ${noty.trustLevel}`
);
break;
case 'DisplayName':
this.speak(
`${noty.previousDisplayName} changed their name to ${noty.displayName}`
);
break;
case 'boop':
this.speak(noty.message);
break;
case 'groupChange':
this.speak(`${displayName} ${noty.message}`);
break;
case 'group.announcement':
this.speak(noty.message);
break;
case 'group.informative':
this.speak(noty.message);
break;
case 'group.invite':
this.speak(noty.message);
break;
case 'group.joinRequest':
this.speak(noty.message);
break;
case 'group.transfer':
this.speak(noty.message);
break;
case 'group.queueReady':
this.speak(noty.message);
break;
case 'instance.closed':
this.speak(noty.message);
break;
case 'PortalSpawn':
if (displayName) {
this.speak(
`${displayName} has spawned a portal to ${displayLocation(
noty.instanceId,
noty.worldName,
noty.groupName
)}`
);
} else {
this.speak('User has spawned a portal');
}
break;
case 'AvatarChange':
this.speak(
`${displayName} changed into avatar ${noty.name}`
);
break;
case 'ChatBoxMessage':
this.speak(`${displayName} said ${noty.text}`);
break;
case 'Event':
this.speak(noty.data);
break;
case 'External':
this.speak(noty.message);
break;
case 'VideoPlay':
this.speak(`Now playing: ${noty.notyName}`);
break;
case 'BlockedOnPlayerJoined':
this.speak(`Blocked user ${displayName} has joined`);
break;
case 'BlockedOnPlayerLeft':
this.speak(`Blocked user ${displayName} has left`);
break;
case 'MutedOnPlayerJoined':
this.speak(`Muted user ${displayName} has joined`);
break;
case 'MutedOnPlayerLeft':
this.speak(`Muted user ${displayName} has left`);
break;
case 'Blocked':
this.speak(`${displayName} has blocked you`);
break;
case 'Unblocked':
this.speak(`${displayName} has unblocked you`);
break;
case 'Muted':
this.speak(`${displayName} has muted you`);
break;
case 'Unmuted':
this.speak(`${displayName} has unmuted you`);
break;
}
},
displayXSNotification(noty, message, image) {
var timeout = Math.floor(
parseInt(this.notificationTimeout, 10) / 1000
);
switch (noty.type) {
case 'OnPlayerJoined':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has joined`,
timeout,
image
);
break;
case 'OnPlayerLeft':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has left`,
timeout,
image
);
break;
case 'OnPlayerJoining':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} is joining`,
timeout,
image
);
break;
case 'GPS':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} is in ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`,
timeout,
image
);
break;
case 'Online':
var locationName = '';
if (noty.worldName) {
locationName = ` to ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`;
}
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has logged in${locationName}`,
timeout,
image
);
break;
case 'Offline':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has logged out`,
timeout,
image
);
break;
case 'Status':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`,
timeout,
image
);
break;
case 'invite':
AppApi.XSNotification(
'VRCX',
`${
noty.senderUsername
} has invited you to ${displayLocation(
noty.details.worldId,
noty.details.worldName
)}${message}`,
timeout,
image
);
break;
case 'requestInvite':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername} has requested an invite${message}`,
timeout,
image
);
break;
case 'inviteResponse':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername} has responded to your invite${message}`,
timeout,
image
);
break;
case 'requestInviteResponse':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername} has responded to your invite request${message}`,
timeout,
image
);
break;
case 'friendRequest':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername} has sent you a friend request`,
timeout,
image
);
break;
case 'Friend':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} is now your friend`,
timeout,
image
);
break;
case 'Unfriend':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} is no longer your friend`,
timeout,
image
);
break;
case 'TrustLevel':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} trust level is now ${noty.trustLevel}`,
timeout,
image
);
break;
case 'DisplayName':
AppApi.XSNotification(
'VRCX',
`${noty.previousDisplayName} changed their name to ${noty.displayName}`,
timeout,
image
);
break;
case 'boop':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'groupChange':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername}: ${noty.message}`,
timeout,
image
);
break;
case 'group.announcement':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'group.informative':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'group.invite':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'group.joinRequest':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'group.transfer':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'group.queueReady':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'instance.closed':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'PortalSpawn':
if (noty.displayName) {
AppApi.XSNotification(
'VRCX',
`${
noty.displayName
} has spawned a portal to ${displayLocation(
noty.instanceId,
noty.worldName,
noty.groupName
)}`,
timeout,
image
);
} else {
AppApi.XSNotification(
'VRCX',
'User has spawned a portal',
timeout,
image
);
}
break;
case 'AvatarChange':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} changed into avatar ${noty.name}`,
timeout,
image
);
break;
case 'ChatBoxMessage':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} said ${noty.text}`,
timeout,
image
);
break;
case 'Event':
AppApi.XSNotification('VRCX', noty.data, timeout, image);
break;
case 'External':
AppApi.XSNotification('VRCX', noty.message, timeout, image);
break;
case 'VideoPlay':
AppApi.XSNotification(
'VRCX',
`Now playing: ${noty.notyName}`,
timeout,
image
);
break;
case 'BlockedOnPlayerJoined':
AppApi.XSNotification(
'VRCX',
`Blocked user ${noty.displayName} has joined`,
timeout,
image
);
break;
case 'BlockedOnPlayerLeft':
AppApi.XSNotification(
'VRCX',
`Blocked user ${noty.displayName} has left`,
timeout,
image
);
break;
case 'MutedOnPlayerJoined':
AppApi.XSNotification(
'VRCX',
`Muted user ${noty.displayName} has joined`,
timeout,
image
);
break;
case 'MutedOnPlayerLeft':
AppApi.XSNotification(
'VRCX',
`Muted user ${noty.displayName} has left`,
timeout,
image
);
break;
case 'Blocked':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has blocked you`,
timeout,
image
);
break;
case 'Unblocked':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has unblocked you`,
timeout,
image
);
break;
case 'Muted':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has muted you`,
timeout,
image
);
break;
case 'Unmuted':
AppApi.XSNotification(
'VRCX',
`${noty.displayName} has unmuted you`,
timeout,
image
);
break;
}
},
displayOvrtNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
noty,
message,
image
) {
var timeout = Math.floor(
parseInt(this.notificationTimeout, 10) / 1000
);
switch (noty.type) {
case 'OnPlayerJoined':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has joined`,
timeout,
image
);
break;
case 'OnPlayerLeft':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has left`,
timeout,
image
);
break;
case 'OnPlayerJoining':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} is joining`,
timeout,
image
);
break;
case 'GPS':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} is in ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`,
timeout,
image
);
break;
case 'Online':
var locationName = '';
if (noty.worldName) {
locationName = ` to ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`;
}
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has logged in${locationName}`,
timeout,
image
);
break;
case 'Offline':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has logged out`,
timeout,
image
);
break;
case 'Status':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`,
timeout,
image
);
break;
case 'invite':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${
noty.senderUsername
} has invited you to ${displayLocation(
noty.details.worldId,
noty.details.worldName
)}${message}`,
timeout,
image
);
break;
case 'requestInvite':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.senderUsername} has requested an invite${message}`,
timeout,
image
);
break;
case 'inviteResponse':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.senderUsername} has responded to your invite${message}`,
timeout,
image
);
break;
case 'requestInviteResponse':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.senderUsername} has responded to your invite request${message}`,
timeout,
image
);
break;
case 'friendRequest':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.senderUsername} has sent you a friend request`,
timeout,
image
);
break;
case 'Friend':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} is now your friend`,
timeout,
image
);
break;
case 'Unfriend':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} is no longer your friend`,
timeout,
image
);
break;
case 'TrustLevel':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} trust level is now ${noty.trustLevel}`,
timeout,
image
);
break;
case 'DisplayName':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.previousDisplayName} changed their name to ${noty.displayName}`,
timeout,
image
);
break;
case 'boop':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'groupChange':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.senderUsername}: ${noty.message}`,
timeout,
image
);
break;
case 'group.announcement':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'group.informative':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'group.invite':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'group.joinRequest':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'group.transfer':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'group.queueReady':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'instance.closed':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'PortalSpawn':
if (noty.displayName) {
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${
noty.displayName
} has spawned a portal to ${displayLocation(
noty.instanceId,
noty.worldName,
noty.groupName
)}`,
timeout,
image
);
} else {
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
'User has spawned a portal',
timeout,
image
);
}
break;
case 'AvatarChange':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} changed into avatar ${noty.name}`,
timeout,
image
);
break;
case 'ChatBoxMessage':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} said ${noty.text}`,
timeout,
image
);
break;
case 'Event':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.data,
timeout,
image
);
break;
case 'External':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
noty.message,
timeout,
image
);
break;
case 'VideoPlay':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`Now playing: ${noty.notyName}`,
timeout,
image
);
break;
case 'BlockedOnPlayerJoined':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`Blocked user ${noty.displayName} has joined`,
timeout,
image
);
break;
case 'BlockedOnPlayerLeft':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`Blocked user ${noty.displayName} has left`,
timeout,
image
);
break;
case 'MutedOnPlayerJoined':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`Muted user ${noty.displayName} has joined`,
timeout,
image
);
break;
case 'MutedOnPlayerLeft':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`Muted user ${noty.displayName} has left`,
timeout,
image
);
break;
case 'Blocked':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has blocked you`,
timeout,
image
);
break;
case 'Unblocked':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has unblocked you`,
timeout,
image
);
break;
case 'Muted':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has muted you`,
timeout,
image
);
break;
case 'Unmuted':
AppApi.OVRTNotification(
playOvrtHudNotifications,
playOvrtWristNotifications,
'VRCX',
`${noty.displayName} has unmuted you`,
timeout,
image
);
break;
}
},
desktopNotification(displayName, message, image) {
if (WINDOWS) {
AppApi.DesktopNotification(displayName, message, image);
} else {
window.electron.desktopNotification(
displayName,
message,
image
);
}
},
displayDesktopToast(noty, message, image) {
switch (noty.type) {
case 'OnPlayerJoined':
this.desktopNotification(
noty.displayName,
'has joined',
image
);
break;
case 'OnPlayerLeft':
this.desktopNotification(
noty.displayName,
'has left',
image
);
break;
case 'OnPlayerJoining':
this.desktopNotification(
noty.displayName,
'is joining',
image
);
break;
case 'GPS':
this.desktopNotification(
noty.displayName,
`is in ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`,
image
);
break;
case 'Online':
var locationName = '';
if (noty.worldName) {
locationName = ` to ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`;
}
this.desktopNotification(
noty.displayName,
`has logged in${locationName}`,
image
);
break;
case 'Offline':
this.desktopNotification(
noty.displayName,
'has logged out',
image
);
break;
case 'Status':
this.desktopNotification(
noty.displayName,
`status is now ${noty.status} ${noty.statusDescription}`,
image
);
break;
case 'invite':
this.desktopNotification(
noty.senderUsername,
`has invited you to ${displayLocation(
noty.details.worldId,
noty.details.worldName
)}${message}`,
image
);
break;
case 'requestInvite':
this.desktopNotification(
noty.senderUsername,
`has requested an invite${message}`,
image
);
break;
case 'inviteResponse':
this.desktopNotification(
noty.senderUsername,
`has responded to your invite${message}`,
image
);
break;
case 'requestInviteResponse':
this.desktopNotification(
noty.senderUsername,
`has responded to your invite request${message}`,
image
);
break;
case 'friendRequest':
this.desktopNotification(
noty.senderUsername,
'has sent you a friend request',
image
);
break;
case 'Friend':
this.desktopNotification(
noty.displayName,
'is now your friend',
image
);
break;
case 'Unfriend':
this.desktopNotification(
noty.displayName,
'is no longer your friend',
image
);
break;
case 'TrustLevel':
this.desktopNotification(
noty.displayName,
`trust level is now ${noty.trustLevel}`,
image
);
break;
case 'DisplayName':
this.desktopNotification(
noty.previousDisplayName,
`changed their name to ${noty.displayName}`,
image
);
break;
case 'boop':
this.desktopNotification(
noty.senderUsername,
noty.message,
image
);
break;
case 'groupChange':
this.desktopNotification(
noty.senderUsername,
noty.message,
image
);
break;
case 'group.announcement':
this.desktopNotification(
'Group Announcement',
noty.message,
image
);
break;
case 'group.informative':
this.desktopNotification(
'Group Informative',
noty.message,
image
);
break;
case 'group.invite':
this.desktopNotification(
'Group Invite',
noty.message,
image
);
break;
case 'group.joinRequest':
this.desktopNotification(
'Group Join Request',
noty.message,
image
);
break;
case 'group.transfer':
this.desktopNotification(
'Group Transfer Request',
noty.message,
image
);
break;
case 'group.queueReady':
this.desktopNotification(
'Instance Queue Ready',
noty.message,
image
);
break;
case 'instance.closed':
this.desktopNotification(
'Instance Closed',
noty.message,
image
);
break;
case 'PortalSpawn':
if (noty.displayName) {
this.desktopNotification(
noty.displayName,
`has spawned a portal to ${displayLocation(
noty.instanceId,
noty.worldName,
noty.groupName
)}`,
image
);
} else {
this.desktopNotification(
'',
'User has spawned a portal',
image
);
}
break;
case 'AvatarChange':
this.desktopNotification(
noty.displayName,
`changed into avatar ${noty.name}`,
image
);
break;
case 'ChatBoxMessage':
this.desktopNotification(
noty.displayName,
`said ${noty.text}`,
image
);
break;
case 'Event':
this.desktopNotification('Event', noty.data, image);
break;
case 'External':
this.desktopNotification('External', noty.message, image);
break;
case 'VideoPlay':
this.desktopNotification(
'Now playing',
noty.notyName,
image
);
break;
case 'BlockedOnPlayerJoined':
this.desktopNotification(
noty.displayName,
'blocked user has joined',
image
);
break;
case 'BlockedOnPlayerLeft':
this.desktopNotification(
noty.displayName,
'blocked user has left',
image
);
break;
case 'MutedOnPlayerJoined':
this.desktopNotification(
noty.displayName,
'muted user has joined',
image
);
break;
case 'MutedOnPlayerLeft':
this.desktopNotification(
noty.displayName,
'muted user has left',
image
);
break;
case 'Blocked':
this.desktopNotification(
noty.displayName,
'has blocked you',
image
);
break;
case 'Unblocked':
this.desktopNotification(
noty.displayName,
'has unblocked you',
image
);
break;
case 'Muted':
this.desktopNotification(
noty.displayName,
'has muted you',
image
);
break;
case 'Unmuted':
this.desktopNotification(
noty.displayName,
'has unmuted you',
image
);
break;
}
}
};
}