mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Notification TTS
This commit is contained in:
@@ -39,6 +39,7 @@ namespace VRCX
|
|||||||
cefSettings.CefCommandLineArgs.Add("disable-spell-checking");
|
cefSettings.CefCommandLineArgs.Add("disable-spell-checking");
|
||||||
cefSettings.CefCommandLineArgs.Add("disable-pdf-extension");
|
cefSettings.CefCommandLineArgs.Add("disable-pdf-extension");
|
||||||
cefSettings.CefCommandLineArgs.Add("disable-extensions");
|
cefSettings.CefCommandLineArgs.Add("disable-extensions");
|
||||||
|
cefSettings.CefCommandLineArgs["autoplay-policy"] = "no-user-gesture-required";
|
||||||
// cefSettings.CefCommandLineArgs.Add("allow-universal-access-from-files");
|
// cefSettings.CefCommandLineArgs.Add("allow-universal-access-from-files");
|
||||||
// cefSettings.CefCommandLineArgs.Add("disable-web-security");
|
// cefSettings.CefCommandLineArgs.Add("disable-web-security");
|
||||||
cefSettings.SetOffScreenRenderingBestPerformanceArgs();
|
cefSettings.SetOffScreenRenderingBestPerformanceArgs();
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import configRepository from './repository/config.js';
|
|||||||
import webApiService from './service/webapi.js';
|
import webApiService from './service/webapi.js';
|
||||||
import gameLogService from './service/gamelog.js'
|
import gameLogService from './service/gamelog.js'
|
||||||
|
|
||||||
|
speechSynthesis.getVoices();
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
await CefSharp.BindObjectAsync(
|
await CefSharp.BindObjectAsync(
|
||||||
'AppApi',
|
'AppApi',
|
||||||
@@ -3411,6 +3413,7 @@ import gameLogService from './service/gamelog.js'
|
|||||||
AppApi.CheckGameRunning().then(([isGameRunning, isGameNoVR]) => {
|
AppApi.CheckGameRunning().then(([isGameRunning, isGameNoVR]) => {
|
||||||
if (isGameRunning !== this.isGameRunning) {
|
if (isGameRunning !== this.isGameRunning) {
|
||||||
this.isGameRunning = isGameRunning;
|
this.isGameRunning = isGameRunning;
|
||||||
|
sharedRepository.setBool('isGameRunning', isGameRunning);
|
||||||
Discord.SetTimestamps(Date.now(), 0);
|
Discord.SetTimestamps(Date.now(), 0);
|
||||||
}
|
}
|
||||||
this.isGameNoVR = isGameNoVR;
|
this.isGameNoVR = isGameNoVR;
|
||||||
@@ -5690,6 +5693,8 @@ import gameLogService from './service/gamelog.js'
|
|||||||
$app.data.hideDevicesFromFeed = configRepository.getBool('VRCX_hideDevicesFromFeed');
|
$app.data.hideDevicesFromFeed = configRepository.getBool('VRCX_hideDevicesFromFeed');
|
||||||
$app.data.overlayNotifications = configRepository.getBool('VRCX_overlayNotifications');
|
$app.data.overlayNotifications = configRepository.getBool('VRCX_overlayNotifications');
|
||||||
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed');
|
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed');
|
||||||
|
$app.data.notificationTTS = configRepository.getBool('VRCX_notificationTTS');
|
||||||
|
$app.data.notificationTTSVoice = configRepository.getString('VRCX_notificationTTSVoice');
|
||||||
$app.data.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
|
$app.data.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
|
||||||
var saveOpenVROption = function () {
|
var saveOpenVROption = function () {
|
||||||
configRepository.setBool('openVR', this.openVR);
|
configRepository.setBool('openVR', this.openVR);
|
||||||
@@ -5700,6 +5705,13 @@ import gameLogService from './service/gamelog.js'
|
|||||||
configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications);
|
configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications);
|
||||||
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
|
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
|
||||||
};
|
};
|
||||||
|
$app.data.TTSvoices = speechSynthesis.getVoices();
|
||||||
|
var saveNotificationTTS = function () {
|
||||||
|
configRepository.setBool('VRCX_notificationTTS', this.notificationTTS);
|
||||||
|
if (this.notificationTTS) {
|
||||||
|
this.speak('Notification text-to-speech enabled');
|
||||||
|
}
|
||||||
|
};
|
||||||
$app.watch.openVR = saveOpenVROption;
|
$app.watch.openVR = saveOpenVROption;
|
||||||
$app.watch.openVRAlways = saveOpenVROption;
|
$app.watch.openVRAlways = saveOpenVROption;
|
||||||
$app.watch.hidePrivateFromFeed = saveOpenVROption;
|
$app.watch.hidePrivateFromFeed = saveOpenVROption;
|
||||||
@@ -5707,6 +5719,7 @@ import gameLogService from './service/gamelog.js'
|
|||||||
$app.watch.hideDevicesFromFeed = saveOpenVROption;
|
$app.watch.hideDevicesFromFeed = saveOpenVROption;
|
||||||
$app.watch.overlayNotifications = saveOpenVROption;
|
$app.watch.overlayNotifications = saveOpenVROption;
|
||||||
$app.watch.minimalFeed = saveOpenVROption;
|
$app.watch.minimalFeed = saveOpenVROption;
|
||||||
|
$app.watch.notificationTTS = saveNotificationTTS;
|
||||||
$app.data.isDarkMode = configRepository.getBool('isDarkMode');
|
$app.data.isDarkMode = configRepository.getBool('isDarkMode');
|
||||||
$appDarkStyle.disabled = $app.data.isDarkMode === false;
|
$appDarkStyle.disabled = $app.data.isDarkMode === false;
|
||||||
$app.watch.isDarkMode = function () {
|
$app.watch.isDarkMode = function () {
|
||||||
@@ -5744,6 +5757,10 @@ import gameLogService from './service/gamelog.js'
|
|||||||
$app.data.notificationPosition = 'topCenter';
|
$app.data.notificationPosition = 'topCenter';
|
||||||
configRepository.setString('VRCX_notificationPosition', $app.data.notificationPosition);
|
configRepository.setString('VRCX_notificationPosition', $app.data.notificationPosition);
|
||||||
}
|
}
|
||||||
|
if (!configRepository.getString('VRCX_notificationTTSVoice')) {
|
||||||
|
$app.data.notificationTTSVoice = '0';
|
||||||
|
configRepository.setString('VRCX_notificationTTSVoice', $app.data.notificationTTSVoice);
|
||||||
|
}
|
||||||
$app.data.notificationJoinLeaveFilter = configRepository.getString('VRCX_notificationJoinLeaveFilter');
|
$app.data.notificationJoinLeaveFilter = configRepository.getString('VRCX_notificationJoinLeaveFilter');
|
||||||
$app.methods.changeNotificationJoinLeaveFilter = function () {
|
$app.methods.changeNotificationJoinLeaveFilter = function () {
|
||||||
configRepository.setString('VRCX_notificationJoinLeaveFilter', this.notificationJoinLeaveFilter);
|
configRepository.setString('VRCX_notificationJoinLeaveFilter', this.notificationJoinLeaveFilter);
|
||||||
@@ -5816,6 +5833,22 @@ import gameLogService from './service/gamelog.js'
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.methods.changeTTSVoice = function (index) {
|
||||||
|
this.notificationTTSVoice = index;
|
||||||
|
configRepository.setString('VRCX_notificationTTSVoice', this.notificationTTSVoice);
|
||||||
|
var voices = speechSynthesis.getVoices();
|
||||||
|
var voiceName = voices[index].name;
|
||||||
|
this.speak(voiceName);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.speak = function (text) {
|
||||||
|
var tts = new SpeechSynthesisUtterance();
|
||||||
|
var voices = speechSynthesis.getVoices();
|
||||||
|
tts.voice = voices[this.notificationTTSVoice];
|
||||||
|
tts.text = text;
|
||||||
|
speechSynthesis.speak(tts);
|
||||||
|
};
|
||||||
|
|
||||||
$app.methods.refreshConfigTreeData = function () {
|
$app.methods.refreshConfigTreeData = function () {
|
||||||
this.configTreeData = buildTreeData(API.cachedConfig);
|
this.configTreeData = buildTreeData(API.cachedConfig);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -568,13 +568,22 @@ html
|
|||||||
div(style="font-size:12px;margin-top:5px")
|
div(style="font-size:12px;margin-top:5px")
|
||||||
span(style="display:inline-block;min-width:150px") Overlay Notifications
|
span(style="display:inline-block;min-width:150px") Overlay Notifications
|
||||||
el-switch(v-model="overlayNotifications" :disabled="!openVR")
|
el-switch(v-model="overlayNotifications" :disabled="!openVR")
|
||||||
|
div(style="font-size:12px;margin-top:5px")
|
||||||
|
span(style="display:inline-block;min-width:150px") Notification TTS
|
||||||
|
el-switch(v-model="notificationTTS" :disabled="!openVR")
|
||||||
|
div(style="font-size:12px;margin-top:5px")
|
||||||
|
span(style="display:inline-block;min-width:150px") TTS Voice
|
||||||
|
el-dropdown(@command="(voice) => changeTTSVoice(voice)" trigger="click" size="small")
|
||||||
|
el-button(v-text="TTSvoices[notificationTTSVoice].name" size="mini" :disabled="!openVR || !notificationTTS")
|
||||||
|
el-dropdown-menu(#default="dropdown")
|
||||||
|
el-dropdown-item(v-if="voice" v-for="(voice, index) in TTSvoices" :key="index" v-text="voice.name" :command="index")
|
||||||
div(style="font-size:12px;margin-top:5px")
|
div(style="font-size:12px;margin-top:5px")
|
||||||
el-button(size="small" icon="el-icon-time" @click="promptNotificationTimeout()" :disabled="!overlayNotifications || !openVR") Notification Timeout
|
el-button(size="small" icon="el-icon-time" @click="promptNotificationTimeout()" :disabled="!overlayNotifications || !openVR") Notification Timeout
|
||||||
el-button(size="small" icon="el-icon-rank" @click="showNotificationPositionDialog()" :disabled="!overlayNotifications || !openVR") Notification Position
|
el-button(size="small" icon="el-icon-rank" @click="showNotificationPositionDialog()" :disabled="!overlayNotifications || !openVR") Notification Position
|
||||||
div(style="font-size:12px;margin-top:5px")
|
div(style="font-size:12px;margin-top:5px")
|
||||||
span Join/Leave Notifications
|
span Join/Leave Notifications
|
||||||
br
|
br
|
||||||
el-radio-group(v-model="notificationJoinLeaveFilter" size="mini" @change="changeNotificationJoinLeaveFilter" :disabled="!overlayNotifications || !openVR")
|
el-radio-group(v-model="notificationJoinLeaveFilter" size="mini" @change="changeNotificationJoinLeaveFilter" :disabled="!overlayNotifications && !notificationTTS || !openVR")
|
||||||
el-radio(label="VIP" v-model="notificationJoinLeaveFilter") VIP
|
el-radio(label="VIP" v-model="notificationJoinLeaveFilter") VIP
|
||||||
el-radio(label="Friends" v-model="notificationJoinLeaveFilter") Friends
|
el-radio(label="Friends" v-model="notificationJoinLeaveFilter") Friends
|
||||||
el-radio(label="Everyone" v-model="notificationJoinLeaveFilter") Everyone
|
el-radio(label="Everyone" v-model="notificationJoinLeaveFilter") Everyone
|
||||||
@@ -582,7 +591,7 @@ html
|
|||||||
div(style="font-size:12px;margin-top:5px")
|
div(style="font-size:12px;margin-top:5px")
|
||||||
span Online/Offline Notifications
|
span Online/Offline Notifications
|
||||||
br
|
br
|
||||||
el-radio-group(v-model="notificationOnlineOfflineFilter" size="mini" @change="changeNotificationOnlineOfflineFilter" :disabled="!overlayNotifications || !openVR")
|
el-radio-group(v-model="notificationOnlineOfflineFilter" size="mini" @change="changeNotificationOnlineOfflineFilter" :disabled="!overlayNotifications && !notificationTTS || !openVR")
|
||||||
el-radio(label="VIP" v-model="notificationOnlineOfflineFilter") VIP
|
el-radio(label="VIP" v-model="notificationOnlineOfflineFilter") VIP
|
||||||
el-radio(label="Friends" v-model="notificationOnlineOfflineFilter") Friends
|
el-radio(label="Friends" v-model="notificationOnlineOfflineFilter") Friends
|
||||||
el-radio(label="Off" v-model="notificationOnlineOfflineFilter") Off
|
el-radio(label="Off" v-model="notificationOnlineOfflineFilter") Off
|
||||||
|
|||||||
116
html/src/vr.js
116
html/src/vr.js
@@ -13,6 +13,8 @@ import sharedRepository from './repository/shared.js';
|
|||||||
import configRepository from './repository/config.js';
|
import configRepository from './repository/config.js';
|
||||||
import webApiService from './service/webapi.js';
|
import webApiService from './service/webapi.js';
|
||||||
|
|
||||||
|
speechSynthesis.getVoices();
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
await CefSharp.BindObjectAsync(
|
await CefSharp.BindObjectAsync(
|
||||||
'AppApi',
|
'AppApi',
|
||||||
@@ -662,7 +664,7 @@ import webApiService from './service/webapi.js';
|
|||||||
var _feeds = this.feeds;
|
var _feeds = this.feeds;
|
||||||
this.feeds = feeds;
|
this.feeds = feeds;
|
||||||
|
|
||||||
if (this.appType === '2') {
|
if ((this.appType === '2') && sharedRepository.getBool('isGameRunning')) {
|
||||||
var map = {};
|
var map = {};
|
||||||
_feeds.forEach((feed) => {
|
_feeds.forEach((feed) => {
|
||||||
if (feed.type === 'OnPlayerJoined' ||
|
if (feed.type === 'OnPlayerJoined' ||
|
||||||
@@ -690,47 +692,47 @@ import webApiService from './service/webapi.js';
|
|||||||
if (this.currentUserStatus === 'busy') {
|
if (this.currentUserStatus === 'busy') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (configRepository.getBool('VRCX_overlayNotifications') === true) {
|
var notys = [];
|
||||||
var notys = [];
|
this.feeds.forEach((feed) => {
|
||||||
this.feeds.forEach((feed) => {
|
if (((notificationOnlineOfflineFilter === "Friends") && (feed.isFriend)) ||
|
||||||
if (((notificationOnlineOfflineFilter === "Friends") && (feed.isFriend)) ||
|
((notificationOnlineOfflineFilter === "VIP") && (feed.isFavorite))) {
|
||||||
((notificationOnlineOfflineFilter === "VIP") && (feed.isFavorite))) {
|
if (feed.type === 'Online' ||
|
||||||
if (feed.type === 'Online' ||
|
feed.type === 'Offline') {
|
||||||
feed.type === 'Offline') {
|
if (!map[feed.displayName] ||
|
||||||
if (!map[feed.displayName] ||
|
map[feed.displayName] < feed.created_at) {
|
||||||
map[feed.displayName] < feed.created_at) {
|
map[feed.displayName] = feed.created_at;
|
||||||
map[feed.displayName] = feed.created_at;
|
|
||||||
notys.push(feed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((notificationJoinLeaveFilter === "Everyone") ||
|
|
||||||
((notificationJoinLeaveFilter === "Friends") && (feed.isFriend)) ||
|
|
||||||
((notificationJoinLeaveFilter === "VIP") && (feed.isFavorite))) {
|
|
||||||
if (feed.type === 'OnPlayerJoined' ||
|
|
||||||
feed.type === 'OnPlayerLeft') {
|
|
||||||
if (!map[feed.data] ||
|
|
||||||
map[feed.data] < feed.created_at) {
|
|
||||||
map[feed.data] = feed.created_at;
|
|
||||||
notys.push(feed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (feed.type === 'invite' ||
|
|
||||||
feed.type === 'requestInvite' ||
|
|
||||||
feed.type === 'friendRequest') {
|
|
||||||
if (!map[feed.senderUsername] ||
|
|
||||||
map[feed.senderUsername] < feed.created_at) {
|
|
||||||
map[feed.senderUsername] = feed.created_at;
|
|
||||||
notys.push(feed);
|
notys.push(feed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} else if ((notificationJoinLeaveFilter === "Everyone") ||
|
||||||
var bias = new Date(Date.now() - 60000).toJSON();
|
((notificationJoinLeaveFilter === "Friends") && (feed.isFriend)) ||
|
||||||
var theme = 'relax';
|
((notificationJoinLeaveFilter === "VIP") && (feed.isFavorite))) {
|
||||||
if (configRepository.getBool('isDarkMode') === true) {
|
if (feed.type === 'OnPlayerJoined' ||
|
||||||
theme = 'sunset';
|
feed.type === 'OnPlayerLeft') {
|
||||||
|
if (!map[feed.data] ||
|
||||||
|
map[feed.data] < feed.created_at) {
|
||||||
|
map[feed.data] = feed.created_at;
|
||||||
|
notys.push(feed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (feed.type === 'invite' ||
|
||||||
|
feed.type === 'requestInvite' ||
|
||||||
|
feed.type === 'friendRequest') {
|
||||||
|
if (!map[feed.senderUsername] ||
|
||||||
|
map[feed.senderUsername] < feed.created_at) {
|
||||||
|
map[feed.senderUsername] = feed.created_at;
|
||||||
|
notys.push(feed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
notys.forEach((noty) => {
|
});
|
||||||
if (noty.created_at > bias) {
|
var bias = new Date(Date.now() - 60000).toJSON();
|
||||||
|
var theme = 'relax';
|
||||||
|
if (configRepository.getBool('isDarkMode') === true) {
|
||||||
|
theme = 'sunset';
|
||||||
|
}
|
||||||
|
notys.forEach((noty) => {
|
||||||
|
if (noty.created_at > bias) {
|
||||||
|
if (configRepository.getBool('VRCX_overlayNotifications')) {
|
||||||
switch (noty.type) {
|
switch (noty.type) {
|
||||||
case 'OnPlayerJoined':
|
case 'OnPlayerJoined':
|
||||||
new Noty({
|
new Noty({
|
||||||
@@ -797,8 +799,33 @@ import webApiService from './service/webapi.js';
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
if (configRepository.getBool('VRCX_notificationTTS')) {
|
||||||
}
|
switch (noty.type) {
|
||||||
|
case 'OnPlayerJoined':
|
||||||
|
this.speak(`${noty.data} has joined`);
|
||||||
|
break;
|
||||||
|
case 'OnPlayerLeft':
|
||||||
|
this.speak(`${noty.data} has left`);
|
||||||
|
break;
|
||||||
|
case 'Online':
|
||||||
|
this.speak(`${noty.displayName} has logged in`);
|
||||||
|
break;
|
||||||
|
case 'Offline':
|
||||||
|
this.speak(`${noty.displayName} has logged out`);
|
||||||
|
break;
|
||||||
|
case 'invite':
|
||||||
|
this.speak(`${noty.senderUsername} has invited you to ${noty.details.worldName}`);
|
||||||
|
break;
|
||||||
|
case 'requestInvite':
|
||||||
|
this.speak(`${noty.senderUsername} has requested an invite`);
|
||||||
|
break;
|
||||||
|
case 'friendRequest':
|
||||||
|
this.speak(`${noty.senderUsername} has sent you a friend request`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -818,6 +845,15 @@ import webApiService from './service/webapi.js';
|
|||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.methods.speak = function (text) {
|
||||||
|
var tts = new SpeechSynthesisUtterance();
|
||||||
|
var voices = speechSynthesis.getVoices();
|
||||||
|
var voiceIndex = configRepository.getString('VRCX_notificationTTSVoice');
|
||||||
|
tts.voice = voices[voiceIndex];
|
||||||
|
tts.text = text;
|
||||||
|
speechSynthesis.speak(tts);
|
||||||
|
};
|
||||||
|
|
||||||
$app = new Vue($app);
|
$app = new Vue($app);
|
||||||
window.$app = $app;
|
window.$app = $app;
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user