Desktop Notifications

This commit is contained in:
Natsumi
2021-01-14 14:14:18 +13:00
parent bb33562bf3
commit d32c1f9078
7 changed files with 281 additions and 42 deletions

View File

@@ -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 = [];

View File

@@ -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 {

View File

@@ -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

View File

@@ -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) {