diff --git a/Dotnet/AppApi/Common/OVRToolkit.cs b/Dotnet/AppApi/Common/OVRToolkit.cs
index d8726d66..2fe9f064 100644
--- a/Dotnet/AppApi/Common/OVRToolkit.cs
+++ b/Dotnet/AppApi/Common/OVRToolkit.cs
@@ -89,7 +89,7 @@ namespace VRCX
/// The content of the notification.
/// [CURRENTLY UNUSED]The timeout of the notification.
/// The image of the notification.
- public void OVRTNotification(bool hudNotification, bool wristNotification, string title, string body, int timeout, string image = "")
+ public void OVRTNotification(bool hudNotification, bool wristNotification, string title, string body, int timeout, int opacity, string image = "")
{
List messages = [];
diff --git a/Dotnet/AppApi/Common/XSOverlay.cs b/Dotnet/AppApi/Common/XSOverlay.cs
index cd7fb922..be1e0ae8 100644
--- a/Dotnet/AppApi/Common/XSOverlay.cs
+++ b/Dotnet/AppApi/Common/XSOverlay.cs
@@ -13,7 +13,7 @@ namespace VRCX
/// The content of the notification.
/// The duration of the notification in milliseconds.
/// The optional image to display in the notification.
- public void XSNotification(string title, string content, int timeout, string image = "")
+ public void XSNotification(string title, string content, int timeout, int opacity, string image = "")
{
var broadcastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var endPoint = new IPEndPoint(IPAddress.Loopback, 42069);
@@ -43,7 +43,8 @@ namespace VRCX
timeout = timeout,
audioPath = string.Empty,
useBase64Icon = useBase64Icon,
- icon = icon
+ icon = icon,
+ opacity = opacity / 100f
};
var byteBuffer = JsonSerializer.SerializeToUtf8Bytes(msg);
diff --git a/src/app.js b/src/app.js
index d314e878..53dafc7e 100644
--- a/src/app.js
+++ b/src/app.js
@@ -6156,6 +6156,10 @@ console.log(`isLinux: ${LINUX}`);
'VRCX_notificationTTSNickName',
false
);
+ $app.data.notificationOpacity = await configRepository.getFloat(
+ 'VRCX_notificationOpacity',
+ 100
+ );
// It's not necessary to store it in configRepo because it's rarely used.
$app.data.isTestTTSVisible = false;
@@ -6523,6 +6527,11 @@ console.log(`isLinux: ${LINUX}`);
this.autoDeleteOldPrints
);
+ await configRepository.setInt(
+ 'VRCX_notificationOpacity',
+ this.notificationOpacity
+ );
+
this.updateSharedFeed(true);
this.updateVRConfigVars();
this.updateVRLastLocation();
@@ -7392,7 +7401,8 @@ console.log(`isLinux: ${LINUX}`);
backgroundEnabled: this.vrBackgroundEnabled,
dtHour12: this.dtHour12,
pcUptimeOnFeed: this.pcUptimeOnFeed,
- appLanguage: this.appLanguage
+ appLanguage: this.appLanguage,
+ notificationOpacity: this.notificationOpacity
};
var json = JSON.stringify(VRConfigVars);
AppApi.ExecuteVrFeedFunction('configUpdate', json);
diff --git a/src/classes/vrcxNotifications.js b/src/classes/vrcxNotifications.js
index 490838fc..2c7d94f3 100644
--- a/src/classes/vrcxNotifications.js
+++ b/src/classes/vrcxNotifications.js
@@ -579,6 +579,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -587,6 +588,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -595,6 +597,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is joining`,
timeout,
+ opacity,
image
);
break;
@@ -607,6 +610,7 @@ export default class extends baseClass {
noty.groupName
)}`,
timeout,
+ opacity,
image
);
break;
@@ -623,6 +627,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has logged in${locationName}`,
timeout,
+ opacity,
image
);
break;
@@ -631,6 +636,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has logged out`,
timeout,
+ opacity,
image
);
break;
@@ -639,6 +645,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`,
timeout,
+ opacity,
image
);
break;
@@ -652,6 +659,7 @@ export default class extends baseClass {
noty.details.worldName
)}${message}`,
timeout,
+ opacity,
image
);
break;
@@ -660,6 +668,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has requested an invite${message}`,
timeout,
+ opacity,
image
);
break;
@@ -668,6 +677,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has responded to your invite${message}`,
timeout,
+ opacity,
image
);
break;
@@ -676,6 +686,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has responded to your invite request${message}`,
timeout,
+ opacity,
image
);
break;
@@ -684,6 +695,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has sent you a friend request`,
timeout,
+ opacity,
image
);
break;
@@ -692,6 +704,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is now your friend`,
timeout,
+ opacity,
image
);
break;
@@ -700,6 +713,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is no longer your friend`,
timeout,
+ opacity,
image
);
break;
@@ -708,6 +722,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} trust level is now ${noty.trustLevel}`,
timeout,
+ opacity,
image
);
break;
@@ -716,40 +731,90 @@ export default class extends baseClass {
'VRCX',
`${noty.previousDisplayName} changed their name to ${noty.displayName}`,
timeout,
+ opacity,
image
);
break;
case 'boop':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'groupChange':
AppApi.XSNotification(
'VRCX',
`${noty.senderUsername}: ${noty.message}`,
timeout,
+ opacity,
image
);
break;
case 'group.announcement':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'group.informative':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'group.invite':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'group.joinRequest':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'group.transfer':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'group.queueReady':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'instance.closed':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'PortalSpawn':
if (noty.displayName) {
@@ -763,6 +828,7 @@ export default class extends baseClass {
noty.groupName
)}`,
timeout,
+ opacity,
image
);
} else {
@@ -770,6 +836,7 @@ export default class extends baseClass {
'VRCX',
'User has spawned a portal',
timeout,
+ opacity,
image
);
}
@@ -779,6 +846,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} changed into avatar ${noty.name}`,
timeout,
+ opacity,
image
);
break;
@@ -787,20 +855,34 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} said ${noty.text}`,
timeout,
+ opacity,
image
);
break;
case 'Event':
- AppApi.XSNotification('VRCX', noty.data, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.data,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'External':
- AppApi.XSNotification('VRCX', noty.message, timeout, image);
+ AppApi.XSNotification(
+ 'VRCX',
+ noty.message,
+ timeout,
+ opacity,
+ image
+ );
break;
case 'VideoPlay':
AppApi.XSNotification(
'VRCX',
`Now playing: ${noty.notyName}`,
timeout,
+ opacity,
image
);
break;
@@ -809,6 +891,7 @@ export default class extends baseClass {
'VRCX',
`Blocked user ${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -817,6 +900,7 @@ export default class extends baseClass {
'VRCX',
`Blocked user ${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -825,6 +909,7 @@ export default class extends baseClass {
'VRCX',
`Muted user ${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -833,6 +918,7 @@ export default class extends baseClass {
'VRCX',
`Muted user ${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -841,6 +927,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has blocked you`,
timeout,
+ opacity,
image
);
break;
@@ -849,6 +936,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has unblocked you`,
timeout,
+ opacity,
image
);
break;
@@ -857,6 +945,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has muted you`,
timeout,
+ opacity,
image
);
break;
@@ -865,6 +954,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has unmuted you`,
timeout,
+ opacity,
image
);
break;
@@ -889,6 +979,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -899,6 +990,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -909,6 +1001,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is joining`,
timeout,
+ opacity,
image
);
break;
@@ -923,6 +1016,7 @@ export default class extends baseClass {
noty.groupName
)}`,
timeout,
+ opacity,
image
);
break;
@@ -941,6 +1035,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has logged in${locationName}`,
timeout,
+ opacity,
image
);
break;
@@ -951,6 +1046,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has logged out`,
timeout,
+ opacity,
image
);
break;
@@ -961,6 +1057,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`,
timeout,
+ opacity,
image
);
break;
@@ -976,6 +1073,7 @@ export default class extends baseClass {
noty.details.worldName
)}${message}`,
timeout,
+ opacity,
image
);
break;
@@ -986,6 +1084,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has requested an invite${message}`,
timeout,
+ opacity,
image
);
break;
@@ -996,6 +1095,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has responded to your invite${message}`,
timeout,
+ opacity,
image
);
break;
@@ -1006,6 +1106,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has responded to your invite request${message}`,
timeout,
+ opacity,
image
);
break;
@@ -1016,6 +1117,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername} has sent you a friend request`,
timeout,
+ opacity,
image
);
break;
@@ -1026,6 +1128,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is now your friend`,
timeout,
+ opacity,
image
);
break;
@@ -1036,6 +1139,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} is no longer your friend`,
timeout,
+ opacity,
image
);
break;
@@ -1046,6 +1150,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} trust level is now ${noty.trustLevel}`,
timeout,
+ opacity,
image
);
break;
@@ -1056,6 +1161,7 @@ export default class extends baseClass {
'VRCX',
`${noty.previousDisplayName} changed their name to ${noty.displayName}`,
timeout,
+ opacity,
image
);
break;
@@ -1066,6 +1172,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1076,6 +1183,7 @@ export default class extends baseClass {
'VRCX',
`${noty.senderUsername}: ${noty.message}`,
timeout,
+ opacity,
image
);
break;
@@ -1086,6 +1194,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1096,6 +1205,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1106,6 +1216,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1116,6 +1227,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1126,6 +1238,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1136,6 +1249,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1146,6 +1260,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1163,6 +1278,7 @@ export default class extends baseClass {
noty.groupName
)}`,
timeout,
+ opacity,
image
);
} else {
@@ -1172,6 +1288,7 @@ export default class extends baseClass {
'VRCX',
'User has spawned a portal',
timeout,
+ opacity,
image
);
}
@@ -1183,6 +1300,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} changed into avatar ${noty.name}`,
timeout,
+ opacity,
image
);
break;
@@ -1193,6 +1311,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} said ${noty.text}`,
timeout,
+ opacity,
image
);
break;
@@ -1203,6 +1322,7 @@ export default class extends baseClass {
'VRCX',
noty.data,
timeout,
+ opacity,
image
);
break;
@@ -1213,6 +1333,7 @@ export default class extends baseClass {
'VRCX',
noty.message,
timeout,
+ opacity,
image
);
break;
@@ -1223,6 +1344,7 @@ export default class extends baseClass {
'VRCX',
`Now playing: ${noty.notyName}`,
timeout,
+ opacity,
image
);
break;
@@ -1233,6 +1355,7 @@ export default class extends baseClass {
'VRCX',
`Blocked user ${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -1243,6 +1366,7 @@ export default class extends baseClass {
'VRCX',
`Blocked user ${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -1253,6 +1377,7 @@ export default class extends baseClass {
'VRCX',
`Muted user ${noty.displayName} has joined`,
timeout,
+ opacity,
image
);
break;
@@ -1263,6 +1388,7 @@ export default class extends baseClass {
'VRCX',
`Muted user ${noty.displayName} has left`,
timeout,
+ opacity,
image
);
break;
@@ -1273,6 +1399,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has blocked you`,
timeout,
+ opacity,
image
);
break;
@@ -1283,6 +1410,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has unblocked you`,
timeout,
+ opacity,
image
);
break;
@@ -1293,6 +1421,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has muted you`,
timeout,
+ opacity,
image
);
break;
@@ -1303,6 +1432,7 @@ export default class extends baseClass {
'VRCX',
`${noty.displayName} has unmuted you`,
timeout,
+ opacity,
image
);
break;
diff --git a/src/localization/en/en.json b/src/localization/en/en.json
index 7e15e990..14af8e73 100644
--- a/src/localization/en/en.json
+++ b/src/localization/en/en.json
@@ -453,6 +453,7 @@
"ovrtoolkit_hud_notifications": "OVR Toolkit HUD Notifications",
"ovrtoolkit_wrist_notifications": "OVR Toolkit Wrist Notifications",
"user_images": "User Images (slower)",
+ "notification_opacity": "Notification Opacity",
"notification_timeout": "Notification Timeout"
},
"conditions": {
diff --git a/src/mixins/tabs/settings.pug b/src/mixins/tabs/settings.pug
index 726cee6a..4b343107 100644
--- a/src/mixins/tabs/settings.pug
+++ b/src/mixins/tabs/settings.pug
@@ -579,9 +579,19 @@ mixin settingsTab
:value='ovrtWristNotifications'
@change='saveOpenVROption("VRCX_ovrtWristNotifications")')
simple-switch(
- :label='$t("view.settings.notifications.notifications.steamvr_notifications.user_images")'
+ :label='$t("view.settings.notifications.notifications.steamvr_notifications.ovrtoolkit_wrist_notifications")'
:value='imageNotifications'
@change='saveOpenVROption("VRCX_imageNotifications")')
+ .options-container-item
+ span.name(style='vertical-align: top; padding-top: 10px') {{ $t('view.settings.notifications.notifications.steamvr_notifications.notification_opacity') }}
+ el-slider(
+ v-model='notificationOpacity'
+ @input='saveOpenVROption("VRCX_notificationOpacity")'
+ :show-tooltip='false'
+ :min='0'
+ :max='100'
+ show-input
+ style='display: inline-block; width: 300px')
.options-container-item
el-button(
size='small'
diff --git a/src/vr.js b/src/vr.js
index 6428c86c..75ebe0db 100644
--- a/src/vr.js
+++ b/src/vr.js
@@ -166,7 +166,8 @@ Vue.component('marquee-text', MarqueeText);
onlineForTimer: '',
wristFeed: [],
devices: [],
- deviceCount: 0
+ deviceCount: 0,
+ notificationOpacity: 100
},
computed: {},
methods: {
@@ -203,6 +204,10 @@ Vue.component('marquee-text', MarqueeText);
this.cpuUsageEnabled || this.pcUptimeEnabled
);
}
+ if (this.config.notificationOpacity !== this.notificationOpacity) {
+ this.notificationOpacity = this.config.notificationOpacity;
+ this.setNotyOpacity(this.notificationOpacity);
+ }
};
$app.methods.updateOnlineFriendCount = function (count) {
@@ -272,6 +277,19 @@ Vue.component('marquee-text', MarqueeText);
});
};
+ $app.methods.setNotyOpacity = function (value) {
+ var opacity = parseFloat(value / 100).toFixed(2);
+ let element = document.getElementById('noty-opacity');
+ if (!element) {
+ document.body.insertAdjacentHTML(
+ 'beforeend',
+ ``
+ );
+ element = document.getElementById('noty-opacity');
+ }
+ element.innerHTML = `.noty_layout { opacity: ${opacity}; }`;
+ };
+
$app.methods.updateStatsLoop = async function () {
try {
this.currentTime = new Date()