mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-18 22:33:50 +02:00
OVR Toolkit Notifications (#751)
* Added OVR Toolkit notification support * Change order * Self identify by user-agent. * Fix comments
This commit is contained in:
162
Dotnet/AppApi/OVRToolkit.cs
Normal file
162
Dotnet/AppApi/OVRToolkit.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading.Tasks;
|
||||
using Websocket.Client;
|
||||
|
||||
namespace VRCX
|
||||
{
|
||||
public partial class AppApi
|
||||
{
|
||||
private static readonly Uri _ovrtWebsocketUri = new("ws://127.0.0.1:11450/api");
|
||||
private IWebsocketClient _ovrtWebsocketClient;
|
||||
private object _ovrtLock = new();
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_ovrtLock)
|
||||
{
|
||||
if (_ovrtWebsocketClient != null)
|
||||
return;
|
||||
|
||||
var dotnetWebsocketClientFactory = new Func<ClientWebSocket>(() =>
|
||||
{
|
||||
var client = new ClientWebSocket
|
||||
{
|
||||
Options =
|
||||
{
|
||||
KeepAliveInterval = TimeSpan.FromSeconds(5),
|
||||
}
|
||||
};
|
||||
client.Options.SetRequestHeader("user-agent", Program.Version);
|
||||
return client;
|
||||
});
|
||||
|
||||
_ovrtWebsocketClient = new WebsocketClient(_ovrtWebsocketUri, dotnetWebsocketClientFactory)
|
||||
{
|
||||
Name = "OVRToolkit Websocket",
|
||||
// Swap ReconnectTimeout when Ping is implemented
|
||||
// ReconnectTimeout = TimeSpan.FromSeconds(20),
|
||||
ReconnectTimeout = null,
|
||||
ErrorReconnectTimeout = TimeSpan.FromSeconds(30),
|
||||
};
|
||||
|
||||
_ovrtWebsocketClient.ReconnectionHappened.Subscribe(info =>
|
||||
{
|
||||
logger.ConditionalDebug("[OVRToolkit Websocket] Reconnection happened, type: {0}", info?.Type.ToString());
|
||||
});
|
||||
_ovrtWebsocketClient.DisconnectionHappened.Subscribe(info =>
|
||||
{
|
||||
logger.ConditionalDebug("[OVRToolkit Websocket] Disconnection happened, type: {0}", info?.Type.ToString());
|
||||
});
|
||||
_ovrtWebsocketClient.MessageReceived.Subscribe(msg =>
|
||||
{
|
||||
logger.ConditionalDebug("[OVRToolkit Websocket] Message received: {0}", msg.Text);
|
||||
});
|
||||
|
||||
_ovrtWebsocketClient.Start().Wait();
|
||||
|
||||
// Uncomment when Ping is implemented
|
||||
// Task.Run(PingLoop);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays an OVRToolkit notification with the specified title and body.
|
||||
/// HUD ntoficcation - Visible in the lower part of the HMD view and moves with the head.
|
||||
/// </summary>
|
||||
/// <param name="hudNotification">Whether or not to display a HUD notification.</param>
|
||||
/// <param name="wristNotification">Whether or not to display a Wrist notification.</param>
|
||||
/// <param name="title">The title of the notification.</param>
|
||||
/// <param name="body">The content of the notification.</param>
|
||||
/// <param name="timeout">[CURRENTLY UNUSED]The timeout of the notification.</param>
|
||||
/// <param name="image">[CURRENTLY UNUSED]The image of the notification.</param>
|
||||
public void OVRTNotification(bool hudNotification, bool wristNotification, string title, string body, int timeout, string image = "")
|
||||
{
|
||||
List<OVRTMessage> messages = [];
|
||||
|
||||
// Uncomment when Image notification is implemented
|
||||
/*
|
||||
if(!string.IsNullOrWhiteSpace(image) && File.Exists(image))
|
||||
{
|
||||
image = Convert.ToBase64String(File.ReadAllBytes(image));
|
||||
}
|
||||
else
|
||||
{
|
||||
image = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAHaGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIxLTA0LTA4VDE0OjU3OjAxKzEyOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wNC0wOFQxNjozMzoxMCsxMjowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wNC0wOFQxNjozMzoxMCsxMjowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2YTY5MmQzYi03ZTJkLTNiNGUtYTMzZC1hN2MwOTNlOGU0OTkiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo1NTE2MWIyMi1hYzgxLTY3NDYtODAyYi1kODIzYWFmN2RjYjciIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ZjJjNTA2ZS02YTVhLWRhNGEtOTg5Mi02NDZiMzQ0MGQxZTgiPiA8cGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPiA8cmRmOkJhZz4gPHJkZjpsaT5hZG9iZTpkb2NpZDpwaG90b3Nob3A6NmJmOGE5MTgtY2QzZS03OTRjLTk3NzktMzM0YjYwZWJiNTYyPC9yZGY6bGk+IDwvcmRmOkJhZz4gPC9waG90b3Nob3A6RG9jdW1lbnRBbmNlc3RvcnM+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6N2YyYzUwNmUtNmE1YS1kYTRhLTk4OTItNjQ2YjM0NDBkMWU4IiBzdEV2dDp3aGVuPSIyMDIxLTA0LTA4VDE0OjU3OjAxKzEyOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmJhM2ZjODI3LTM0ZjQtYjU0OC05ZGFiLTZhMTZlZmQzZjAxMSIgc3RFdnQ6d2hlbj0iMjAyMS0wNC0wOFQxNTowMTozMSsxMjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo2YTY5MmQzYi03ZTJkLTNiNGUtYTMzZC1hN2MwOTNlOGU0OTkiIHN0RXZ0OndoZW49IjIwMjEtMDQtMDhUMTY6MzM6MTArMTI6MDAiIHN0RXZ0OnNv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";
|
||||
}
|
||||
*/
|
||||
|
||||
if (hudNotification)
|
||||
{
|
||||
messages.Add(new OVRTMessage
|
||||
{
|
||||
messageType = "SendNotification",
|
||||
json = System.Text.Json.JsonSerializer.Serialize(new OVRTNotificationMessage
|
||||
{
|
||||
title = title,
|
||||
body = body
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (wristNotification)
|
||||
{
|
||||
messages.Add(new OVRTMessage
|
||||
{
|
||||
messageType = "SendWristNotification",
|
||||
json = System.Text.Json.JsonSerializer.Serialize(new OVRTNotificationMessage
|
||||
{
|
||||
body = title + " - " + body
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (messages.Count > 0)
|
||||
{
|
||||
if (_ovrtWebsocketClient == null)
|
||||
Initialize();
|
||||
|
||||
if (_ovrtWebsocketClient.IsRunning)
|
||||
{
|
||||
foreach (var message in messages)
|
||||
{
|
||||
_ovrtWebsocketClient.Send(System.Text.Json.JsonSerializer.Serialize(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task PingLoop()
|
||||
{
|
||||
var pingMessage = System.Text.Json.JsonSerializer.Serialize(new OVRTMessage
|
||||
{
|
||||
messageType = "Ping",
|
||||
json = string.Empty,
|
||||
});
|
||||
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
|
||||
if (_ovrtWebsocketClient?.IsRunning != true)
|
||||
continue;
|
||||
|
||||
_ovrtWebsocketClient?.Send(pingMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private struct OVRTMessage
|
||||
{
|
||||
public string messageType { get; set; }
|
||||
public string json { get; set; }
|
||||
}
|
||||
|
||||
private struct OVRTNotificationMessage
|
||||
{
|
||||
public string title { get; set; }
|
||||
public string body { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,7 +282,7 @@ namespace VRCX
|
||||
|
||||
var thread = new Thread(() =>
|
||||
{
|
||||
using (var openFileDialog = new OpenFileDialog())
|
||||
using (var openFileDialog = new System.Windows.Forms.OpenFileDialog())
|
||||
{
|
||||
openFileDialog.DefaultExt = ".json";
|
||||
openFileDialog.Filter = "JSON Files (*.json)|*.json";
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageReference Include="Websocket.Client" Version="5.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CefSharpAfterBuildDebug" AfterTargets="AfterBuild">
|
||||
|
||||
345
html/src/app.js
345
html/src/app.js
@@ -6369,6 +6369,8 @@ speechSynthesis.getVoices();
|
||||
playDesktopToast = true;
|
||||
}
|
||||
var playXSNotification = this.xsNotifications;
|
||||
var playOvrtHudNotifications = this.ovrtHudNotifications;
|
||||
var playOvrtWristNotifications = this.ovrtWristNotifications;
|
||||
var playOverlayNotification = false;
|
||||
if (
|
||||
this.overlayNotifications &&
|
||||
@@ -6399,7 +6401,13 @@ speechSynthesis.getVoices();
|
||||
if (playNotificationTTS) {
|
||||
this.playNotyTTS(noty, message);
|
||||
}
|
||||
if (playDesktopToast || playXSNotification || playOverlayNotification) {
|
||||
if (playDesktopToast || playXSNotification || playOvrtHudNotifications || playOvrtWristNotifications || playOverlayNotification) {
|
||||
// Currently images are not supported on OVRT, I have future-proofed the code for when they are.
|
||||
// Remove this when OVRT supports images and uncomment the two if statements below.
|
||||
if (playOvrtHudNotifications || playOvrtWristNotifications) {
|
||||
this.displayOvrtNotification(playOvrtHudNotifications, playOvrtWristNotifications, noty, message, '');
|
||||
}
|
||||
|
||||
if (this.imageNotifications) {
|
||||
this.notySaveImage(noty).then((image) => {
|
||||
if (playXSNotification) {
|
||||
@@ -6411,6 +6419,9 @@ speechSynthesis.getVoices();
|
||||
if (playOverlayNotification) {
|
||||
this.displayOverlayNotification(noty, message, image);
|
||||
}
|
||||
//if (playOvrtHudNotifications || playOvrtWristNotifications) {
|
||||
// this.displayOvrtNotification(playOvrtHudNotifications, playOvrtWristNotifications, noty, message, image);
|
||||
//}
|
||||
});
|
||||
} else {
|
||||
if (playXSNotification) {
|
||||
@@ -6422,6 +6433,9 @@ speechSynthesis.getVoices();
|
||||
if (playOverlayNotification) {
|
||||
this.displayOverlayNotification(noty, message, '');
|
||||
}
|
||||
//if (playOvrtHudNotifications || playOvrtWristNotifications) {
|
||||
// this.displayOvrtNotification(playOvrtHudNotifications, playOvrtWristNotifications, noty, message, '');
|
||||
//}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -6964,6 +6978,319 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
};
|
||||
|
||||
$app.methods.displayOvrtNotification = function (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 ${this.displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
)}`,
|
||||
timeout,
|
||||
image
|
||||
);
|
||||
break;
|
||||
case 'Online':
|
||||
var locationName = '';
|
||||
if (noty.worldName) {
|
||||
locationName = ` to ${this.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 ${this.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 '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.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 ${this.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;
|
||||
}
|
||||
};
|
||||
|
||||
$app.methods.displayDesktopToast = function (noty, message, image) {
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
@@ -14452,6 +14779,14 @@ speechSynthesis.getVoices();
|
||||
'VRCX_xsNotifications',
|
||||
true
|
||||
);
|
||||
$app.data.ovrtHudNotifications = await configRepository.getBool(
|
||||
'VRCX_ovrtHudNotifications',
|
||||
true
|
||||
);
|
||||
$app.data.ovrtWristNotifications = await configRepository.getBool(
|
||||
'VRCX_ovrtWristNotifications',
|
||||
false
|
||||
);
|
||||
$app.data.imageNotifications = await configRepository.getBool(
|
||||
'VRCX_imageNotifications',
|
||||
true
|
||||
@@ -14644,6 +14979,14 @@ speechSynthesis.getVoices();
|
||||
'VRCX_xsNotifications',
|
||||
this.xsNotifications
|
||||
);
|
||||
await configRepository.setBool(
|
||||
'VRCX_ovrtHudNotifications',
|
||||
this.ovrtHudNotifications
|
||||
);
|
||||
await configRepository.setBool(
|
||||
'VRCX_ovrtWristNotifications',
|
||||
this.ovrtWristNotifications
|
||||
);
|
||||
await configRepository.setBool(
|
||||
'VRCX_imageNotifications',
|
||||
this.imageNotifications
|
||||
|
||||
@@ -314,6 +314,8 @@
|
||||
"overlay_notifications": "Overlay Notifications",
|
||||
"notification_position": "Notification Position",
|
||||
"xsoverlay_notifications": "XSOverlay Notifications",
|
||||
"ovrtoolkit_hud_notifications": "OVR Toolkit HUD Notifications",
|
||||
"ovrtoolkit_wrist_notifications": "OVR Toolkit Wrist Notifications",
|
||||
"user_images": "User Images (slower)",
|
||||
"notification_timeout": "Notification Timeout"
|
||||
},
|
||||
|
||||
@@ -257,6 +257,12 @@ mixin settingsTab()
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.xsoverlay_notifications') }}
|
||||
el-switch(v-model="xsNotifications" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.ovrtoolkit_hud_notifications') }}
|
||||
el-switch(v-model="ovrtHudNotifications" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.ovrtoolkit_wrist_notifications') }}
|
||||
el-switch(v-model="ovrtWristNotifications" @change="saveOpenVROption")
|
||||
div.options-container-item
|
||||
span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.user_images') }}
|
||||
el-switch(v-model="imageNotifications" @change="saveOpenVROption")
|
||||
|
||||
Reference in New Issue
Block a user