mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 06:43:51 +02:00
Desktop Notifications
This commit is contained in:
@@ -3436,7 +3436,7 @@ speechSynthesis.getVoices();
|
||||
var { data } = this.gameLogTable;
|
||||
var i = data.length;
|
||||
var j = 0;
|
||||
while (j < 25) {
|
||||
while (j < 30) {
|
||||
if (i <= 0) {
|
||||
break;
|
||||
}
|
||||
@@ -3466,7 +3466,7 @@ speechSynthesis.getVoices();
|
||||
var { data } = this.feedTable;
|
||||
var i = data.length;
|
||||
var j = 0;
|
||||
while (j < 25) {
|
||||
while (j < 30) {
|
||||
if (i <= 0) {
|
||||
break;
|
||||
}
|
||||
@@ -3515,8 +3515,8 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
if (arr.length > 25) {
|
||||
arr.length = 25;
|
||||
if (arr.length > 30) {
|
||||
arr.length = 30;
|
||||
}
|
||||
sharedRepository.setArray('feeds', arr);
|
||||
};
|
||||
@@ -3835,23 +3835,16 @@ speechSynthesis.getVoices();
|
||||
$app.data.orderFriendsGroup1 = configRepository.getBool('orderFriendGroup1');
|
||||
$app.data.orderFriendsGroup2 = configRepository.getBool('orderFriendGroup2');
|
||||
$app.data.orderFriendsGroup3 = configRepository.getBool('orderFriendGroup3');
|
||||
$app.data.displayVRCPlusIconsAsAvatar = configRepository.getBool('displayVRCPlusIconsAsAvatar');
|
||||
var saveOrderFriendGroup = function () {
|
||||
configRepository.setBool('orderFriendGroup0', this.orderFriendsGroup0);
|
||||
configRepository.setBool('orderFriendGroup1', this.orderFriendsGroup1);
|
||||
configRepository.setBool('orderFriendGroup2', this.orderFriendsGroup2);
|
||||
configRepository.setBool('orderFriendGroup3', this.orderFriendsGroup3);
|
||||
configRepository.setBool('displayVRCPlusIconsAsAvatar', this.displayVRCPlusIconsAsAvatar);
|
||||
};
|
||||
$app.watch.orderFriendsGroup0 = saveOrderFriendGroup;
|
||||
$app.watch.orderFriendsGroup1 = saveOrderFriendGroup;
|
||||
$app.watch.orderFriendsGroup2 = saveOrderFriendGroup;
|
||||
$app.watch.orderFriendsGroup3 = saveOrderFriendGroup;
|
||||
$app.watch.displayVRCPlusIconsAsAvatar = saveOrderFriendGroup;
|
||||
if (configRepository.getBool('displayVRCPlusIconsAsAvatar') === null) {
|
||||
$app.data.displayVRCPlusIconsAsAvatar = true;
|
||||
configRepository.setBool('displayVRCPlusIconsAsAvatar', $app.data.displayVRCPlusIconsAsAvatar);
|
||||
}
|
||||
|
||||
$app.methods.fetchActiveFriend = function (userId) {
|
||||
this.pendingActiveFriends.add(userId);
|
||||
@@ -5706,7 +5699,9 @@ speechSynthesis.getVoices();
|
||||
$app.data.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed');
|
||||
$app.data.hideDevicesFromFeed = configRepository.getBool('VRCX_hideDevicesFromFeed');
|
||||
$app.data.overlayNotifications = configRepository.getBool('VRCX_overlayNotifications');
|
||||
$app.data.desktopToast = configRepository.getBool('VRCX_desktopToast');
|
||||
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed');
|
||||
$app.data.displayVRCPlusIconsAsAvatar = configRepository.getBool('displayVRCPlusIconsAsAvatar');
|
||||
$app.data.notificationTTS = configRepository.getBool('VRCX_notificationTTS');
|
||||
$app.data.notificationTTSVoice = configRepository.getString('VRCX_notificationTTSVoice');
|
||||
$app.data.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
|
||||
@@ -5717,7 +5712,9 @@ speechSynthesis.getVoices();
|
||||
configRepository.setBool('VRCX_hidePrivateFromFeed', this.hidePrivateFromFeed);
|
||||
configRepository.setBool('VRCX_hideDevicesFromFeed', this.hideDevicesFromFeed);
|
||||
configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications);
|
||||
configRepository.setBool('VRCX_desktopToast', this.desktopToast);
|
||||
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
|
||||
configRepository.setBool('displayVRCPlusIconsAsAvatar', this.displayVRCPlusIconsAsAvatar);
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
$app.data.TTSvoices = speechSynthesis.getVoices();
|
||||
@@ -5735,7 +5732,9 @@ speechSynthesis.getVoices();
|
||||
$app.watch.hidePrivateFromFeed = saveOpenVROption;
|
||||
$app.watch.hideDevicesFromFeed = saveOpenVROption;
|
||||
$app.watch.overlayNotifications = saveOpenVROption;
|
||||
$app.watch.desktopToast = saveOpenVROption;
|
||||
$app.watch.minimalFeed = saveOpenVROption;
|
||||
$app.watch.displayVRCPlusIconsAsAvatar = saveOpenVROption;
|
||||
$app.watch.notificationTTS = saveNotificationTTS;
|
||||
$app.data.isDarkMode = configRepository.getBool('isDarkMode');
|
||||
$appDarkStyle.disabled = $app.data.isDarkMode === false;
|
||||
@@ -5761,6 +5760,10 @@ speechSynthesis.getVoices();
|
||||
$app.watch.isAutoLogin = saveVRCXWindowOption;
|
||||
|
||||
//setting defaults
|
||||
if (configRepository.getBool('displayVRCPlusIconsAsAvatar') === null) {
|
||||
$app.data.displayVRCPlusIconsAsAvatar = true;
|
||||
configRepository.setBool('displayVRCPlusIconsAsAvatar', $app.data.displayVRCPlusIconsAsAvatar);
|
||||
}
|
||||
if (!configRepository.getString('VRCX_notificationPosition')) {
|
||||
$app.data.notificationPosition = 'topCenter';
|
||||
configRepository.setString('VRCX_notificationPosition', $app.data.notificationPosition);
|
||||
@@ -5907,6 +5910,17 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
$app.watch.isGameRunning = isGameRunningStateChange;
|
||||
|
||||
sharedRepository.setBool('is_Game_No_VR', false);
|
||||
var isGameNoVRStateChange = function () {
|
||||
sharedRepository.setBool('is_Game_No_VR', this.isGameNoVR);
|
||||
}
|
||||
$app.watch.isGameNoVR = isGameNoVRStateChange;
|
||||
|
||||
var lastLocationStateChange = function () {
|
||||
sharedRepository.setString('last_location', $app.lastLocation);
|
||||
}
|
||||
$app.watch.lastLocation = lastLocationStateChange;
|
||||
|
||||
API.$on('LOGIN', function () {
|
||||
$app.currentUserTreeData = [];
|
||||
$app.pastDisplayNameTable.data = [];
|
||||
|
||||
@@ -555,7 +555,12 @@ i.x-user-status.busy {
|
||||
|
||||
.options-container .header {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.options-container .sub-header {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.options-container-item {
|
||||
|
||||
@@ -557,18 +557,34 @@ html
|
||||
div.options-container-item
|
||||
span.name(style="min-width:137px") Overlay Button
|
||||
el-switch(v-model="overlaybutton" inactive-text="Grip" active-text="Menu" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name Hide VR Devices
|
||||
el-switch(v-model="hideDevicesFromFeed" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name Hide Private Worlds
|
||||
el-switch(v-model="hidePrivateFromFeed" :disabled="!openVR")
|
||||
br
|
||||
span.sub-header Display Options
|
||||
div.options-container-item
|
||||
span.name Minimal Feed Icons
|
||||
el-switch(v-model="minimalFeed" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name Hide Private Worlds
|
||||
el-switch(v-model="hidePrivateFromFeed" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name Hide VR Devices
|
||||
el-switch(v-model="hideDevicesFromFeed" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-notebook-2" @click="showWristFeedFiltersDialog()" :disabled="!openVR") Wrist Feed Filters
|
||||
br
|
||||
span.sub-header Notification Options
|
||||
div.options-container-item
|
||||
span.name Overlay Notifications
|
||||
el-switch(v-model="overlayNotifications" :disabled="!openVR")
|
||||
div.options-container-item
|
||||
span.name Desktop Notifications
|
||||
el-switch(v-model="desktopToast" :disabled="!openVR")
|
||||
|
||||
div.options-container-item
|
||||
el-button(size="small" icon="el-icon-chat-square" @click="showNotyFeedFiltersDialog()" :disabled="!openVR") Notification Filters
|
||||
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
|
||||
br
|
||||
span.sub-header TTS Options
|
||||
div.options-container-item
|
||||
span.name Notification TTS
|
||||
el-switch(v-model="notificationTTS" :disabled="!openVR")
|
||||
@@ -577,13 +593,7 @@ html
|
||||
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.options-container-item
|
||||
el-button(size="small" icon="el-icon-notebook-2" @click="showWristFeedFiltersDialog()" :disabled="!openVR") Wrist Feed Filters
|
||||
el-button(size="small" icon="el-icon-chat-square" @click="showNotyFeedFiltersDialog()" :disabled="!overlayNotifications || !openVR") Notification Filters
|
||||
div.options-container-item
|
||||
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-dropdown-item(v-if="voice" v-for="(voice, index) in TTSvoices" :key="index" v-text="voice.name" :command="index")
|
||||
div.options-container
|
||||
span.header Application
|
||||
div.options-container-item
|
||||
|
||||
199
html/src/vr.js
199
html/src/vr.js
@@ -564,6 +564,113 @@ speechSynthesis.getVoices();
|
||||
});
|
||||
};
|
||||
|
||||
// API: User
|
||||
|
||||
API.cachedUsers = new Map();
|
||||
|
||||
API.$on('USER', function (args) {
|
||||
args.ref = this.applyUser(args.json);
|
||||
});
|
||||
|
||||
API.applyUser = function (json) {
|
||||
var ref = this.cachedUsers.get(json.id);
|
||||
if (ref === undefined) {
|
||||
ref = {
|
||||
id: '',
|
||||
username: '',
|
||||
displayName: '',
|
||||
userIcon: '',
|
||||
bio: '',
|
||||
bioLinks: [],
|
||||
currentAvatarImageUrl: '',
|
||||
currentAvatarThumbnailImageUrl: '',
|
||||
status: '',
|
||||
statusDescription: '',
|
||||
state: '',
|
||||
tags: [],
|
||||
developerType: '',
|
||||
last_login: '',
|
||||
last_platform: '',
|
||||
allowAvatarCopying: false,
|
||||
isFriend: false,
|
||||
location: '',
|
||||
worldId: '',
|
||||
instanceId: '',
|
||||
// VRCX
|
||||
...json
|
||||
};
|
||||
this.cachedUsers.set(ref.id, ref);
|
||||
} else {
|
||||
var props = {};
|
||||
for (var prop in ref) {
|
||||
if (ref[prop] !== Object(ref[prop])) {
|
||||
props[prop] = true;
|
||||
}
|
||||
}
|
||||
var $ref = { ...ref };
|
||||
Object.assign(ref, json);
|
||||
for (var prop in ref) {
|
||||
if (ref[prop] !== Object(ref[prop])) {
|
||||
props[prop] = true;
|
||||
}
|
||||
}
|
||||
var has = false;
|
||||
for (var prop in props) {
|
||||
var asis = $ref[prop];
|
||||
var tobe = ref[prop];
|
||||
if (asis === tobe) {
|
||||
delete props[prop];
|
||||
} else {
|
||||
has = true;
|
||||
props[prop] = [
|
||||
tobe,
|
||||
asis
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
return ref;
|
||||
};
|
||||
|
||||
/*
|
||||
params: {
|
||||
userId: string
|
||||
}
|
||||
*/
|
||||
API.getUser = function (params) {
|
||||
return this.call(`users/${params.userId}`, {
|
||||
method: 'GET'
|
||||
}).then((json) => {
|
||||
var args = {
|
||||
json,
|
||||
params
|
||||
};
|
||||
this.$emit('USER', args);
|
||||
return args;
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
params: {
|
||||
userId: string
|
||||
}
|
||||
*/
|
||||
API.getCachedUser = function (params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var ref = this.cachedUsers.get(params.userId);
|
||||
if (ref === undefined) {
|
||||
this.getUser(params).catch(reject).then(resolve);
|
||||
} else {
|
||||
resolve({
|
||||
cache: true,
|
||||
json: ref,
|
||||
params,
|
||||
ref
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var $app = {
|
||||
data: {
|
||||
API,
|
||||
@@ -574,17 +681,20 @@ speechSynthesis.getVoices();
|
||||
currentUserStatus: null,
|
||||
cpuUsage: 0,
|
||||
isGameRunning: false,
|
||||
isGameNoVR: false,
|
||||
lastLocation: '',
|
||||
lastFeedEntry: [],
|
||||
feedFilters: [],
|
||||
wristFeed: [],
|
||||
notyMap: [],
|
||||
devices: [],
|
||||
desktopToastToggle: false,
|
||||
overlayNotificationsToggle: false,
|
||||
notificationTTSToggle: false,
|
||||
notificationTTSVoice: '0',
|
||||
hideDevicesToggle: false,
|
||||
isMinimalFeed: false,
|
||||
displayVRCPlusIconsAsAvatar: false,
|
||||
notificationPosition: 'topCenter',
|
||||
notificationTimeout: '3000',
|
||||
notificationTheme: 'relax'
|
||||
@@ -613,14 +723,13 @@ speechSynthesis.getVoices();
|
||||
throw err;
|
||||
}).then((args) => {
|
||||
this.initConfigVars();
|
||||
this.initNotyMap();
|
||||
if (this.appType === '1') {
|
||||
this.updateCpuUsageLoop();
|
||||
}
|
||||
if (this.appType === '2') {
|
||||
this.initNotyMap();
|
||||
}
|
||||
this.updateLoop();
|
||||
this.updateCpuUsageLoop();
|
||||
this.$nextTick(function () {
|
||||
if (this.appType === '1') {
|
||||
this.$el.style.display = '';
|
||||
}
|
||||
});
|
||||
return args;
|
||||
});
|
||||
}
|
||||
@@ -630,9 +739,11 @@ speechSynthesis.getVoices();
|
||||
this.notificationTTSToggle = configRepository.getBool('VRCX_notificationTTS');
|
||||
this.notificationTTSVoice = configRepository.getString('VRCX_notificationTTSVoice');
|
||||
this.overlayNotificationsToggle = configRepository.getBool('VRCX_overlayNotifications');
|
||||
this.desktopToastToggle = configRepository.getBool('VRCX_desktopToast');
|
||||
this.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed');
|
||||
this.hideDevicesToggle = configRepository.getBool('VRCX_hideDevicesFromFeed');
|
||||
this.isMinimalFeed = configRepository.getBool('VRCX_minimalFeed');
|
||||
this.displayVRCPlusIconsAsAvatar = configRepository.getBool('displayVRCPlusIconsAsAvatar');
|
||||
this.feedFilters = JSON.parse(configRepository.getString('sharedFeedFilters'));
|
||||
this.notificationPosition = configRepository.getString('VRCX_notificationPosition');
|
||||
this.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
|
||||
@@ -678,8 +789,9 @@ speechSynthesis.getVoices();
|
||||
this.currentTime = new Date().toJSON();
|
||||
this.currentUserStatus = sharedRepository.getString('current_user_status');
|
||||
this.isGameRunning = sharedRepository.getBool('is_game_running');
|
||||
this.isGameNoVR = sharedRepository.getBool('is_Game_No_VR');
|
||||
this.lastLocation = sharedRepository.getString('last_location');
|
||||
if (!this.hideDevicesToggle) {
|
||||
if ((!this.hideDevicesToggle) && (this.appType === '1')) {
|
||||
AppApi.GetVRDevices().then((devices) => {
|
||||
devices.forEach((device) => {
|
||||
device[2] = parseInt(device[2], 10);
|
||||
@@ -824,8 +936,14 @@ speechSynthesis.getVoices();
|
||||
if ((this.currentUserStatus === 'busy') || (!this.isGameRunning)) {
|
||||
return;
|
||||
}
|
||||
notyToPlay.forEach(async (noty) => {
|
||||
if (this.overlayNotificationsToggle) {
|
||||
var bias = new Date(Date.now() - 60000).toJSON();
|
||||
var noty = {};
|
||||
for (var i = 0; i < notyToPlay.length; i++) {
|
||||
noty = notyToPlay[i];
|
||||
if (noty.created_at < bias) {
|
||||
continue;
|
||||
}
|
||||
if ((this.overlayNotificationsToggle) && (!this.isGameNoVR)) {
|
||||
var text = '';
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
@@ -927,7 +1045,66 @@ speechSynthesis.getVoices();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
if ((this.desktopToastToggle) && (this.isGameNoVR)) {
|
||||
var imageURL = '';
|
||||
if (noty.userId) {
|
||||
await API.getCachedUser({
|
||||
userId: noty.userId
|
||||
}).catch((err) => {
|
||||
throw err;
|
||||
}).then((args) => {
|
||||
imageURL = args.json.currentAvatarThumbnailImageUrl;
|
||||
if ((this.displayVRCPlusIconsAsAvatar) && (args.json.userIcon)) {
|
||||
imageURL = args.json.userIcon;
|
||||
}
|
||||
});
|
||||
}
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
AppApi.DesktopNotification(noty.data, 'has joined', imageURL);
|
||||
break;
|
||||
case 'OnPlayerLeft':
|
||||
AppApi.DesktopNotification(noty.data, 'has left', imageURL);
|
||||
break;
|
||||
case 'OnPlayerJoining':
|
||||
AppApi.DesktopNotification(noty.data, 'is joining', imageURL);
|
||||
break;
|
||||
case 'GPS':
|
||||
AppApi.DesktopNotification(noty.displayName, 'is in ' + await this.displayLocation(noty.location[0]), imageURL);
|
||||
break;
|
||||
case 'Online':
|
||||
AppApi.DesktopNotification(noty.displayName, 'has logged in', imageURL);
|
||||
break;
|
||||
case 'Offline':
|
||||
AppApi.DesktopNotification(noty.displayName, 'has logged out', imageURL);
|
||||
break;
|
||||
case 'Status':
|
||||
AppApi.DesktopNotification(noty.displayName, `status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`, imageURL);
|
||||
break;
|
||||
case 'invite':
|
||||
AppApi.DesktopNotification(noty.senderUsername, `has invited you to ${noty.details.worldName}`, imageURL);
|
||||
break;
|
||||
case 'requestInvite':
|
||||
AppApi.DesktopNotification(noty.senderUsername, 'has requested an invite', imageURL);
|
||||
break;
|
||||
case 'friendRequest':
|
||||
AppApi.DesktopNotification(noty.senderUsername, 'has sent you a friend request', imageURL);
|
||||
break;
|
||||
case 'Friend':
|
||||
AppApi.DesktopNotification(noty.displayName, 'has sent you a friend request', imageURL);
|
||||
break;
|
||||
case 'Unfriend':
|
||||
AppApi.DesktopNotification(noty.displayName, 'has unfriended you', imageURL);
|
||||
break;
|
||||
case 'TrustLevel':
|
||||
AppApi.DesktopNotification(noty.displayName, `trust level is now ${noty.trustLevel}`, imageURL);
|
||||
break;
|
||||
case 'DisplayName':
|
||||
AppApi.DesktopNotification(noty.previousDisplayName, `changed their name to ${noty.displayName}`, imageURL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$app.methods.userStatusClass = function (user) {
|
||||
|
||||
Reference in New Issue
Block a user