Add feed filters, vuejs-toggle-switch, OnPlayerJoining, and refactor vr.js

This commit is contained in:
Natsumi
2021-01-11 11:03:09 +13:00
parent 89d644d2d0
commit 15c57959e8
8 changed files with 649 additions and 232 deletions
+5
View File
@@ -12394,6 +12394,11 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"vuejs-toggle-switch": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/vuejs-toggle-switch/-/vuejs-toggle-switch-1.3.2.tgz",
"integrity": "sha512-HkSB0hBWgol/o2LY9c1E/f4x+pE09uzlKAYs8bdmHexyudFO1/O1xFJA9M9aDe8DpIAXNxrZCwNwIZdCV97Sdw=="
},
"watchpack": { "watchpack": {
"version": "1.7.5", "version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
+2 -1
View File
@@ -45,6 +45,7 @@
"stylelint-scss": "^3.18.0", "stylelint-scss": "^3.18.0",
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-data-tables": "^3.4.5", "vue-data-tables": "^3.4.5",
"vue-lazyload": "^1.3.3" "vue-lazyload": "^1.3.3",
"vuejs-toggle-switch": "^1.3.2"
} }
} }
+149 -25
View File
@@ -8,6 +8,7 @@ import Noty from 'noty';
import Vue from 'vue'; import Vue from 'vue';
import VueLazyload from 'vue-lazyload'; import VueLazyload from 'vue-lazyload';
import { DataTables } from 'vue-data-tables'; import { DataTables } from 'vue-data-tables';
import ToggleSwitch from 'vuejs-toggle-switch'
import ElementUI from 'element-ui'; import ElementUI from 'element-ui';
import locale from 'element-ui/lib/locale/lang/en'; import locale from 'element-ui/lib/locale/lang/en';
@@ -3415,7 +3416,6 @@ speechSynthesis.getVoices();
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('is_game_running', isGameRunning);
Discord.SetTimestamps(Date.now(), 0); Discord.SetTimestamps(Date.now(), 0);
} }
this.isGameNoVR = isGameNoVR; this.isGameNoVR = isGameNoVR;
@@ -3472,9 +3472,7 @@ speechSynthesis.getVoices();
} }
var ctx = data[--i]; var ctx = data[--i];
// GPS, Online, Offline, Status, Avatar // GPS, Online, Offline, Status, Avatar
if ((ctx.type !== 'Avatar') && if (ctx.type !== 'Avatar') {
!((ctx.type === 'GPS') && (ctx.location[0] === 'private') && (this.hidePrivateFromFeed === true)) &&
!(((ctx.type === 'Online') || (ctx.type === 'Offline')) && (this.hideLoginsFromFeed === true))) {
arr.push({ arr.push({
...ctx, ...ctx,
isFriend: this.friends.has(ctx.userId), isFriend: this.friends.has(ctx.userId),
@@ -3483,6 +3481,7 @@ speechSynthesis.getVoices();
++j; ++j;
} }
} }
// invite, requestInvite, friendRequest
var { data } = this.notificationTable; var { data } = this.notificationTable;
for (i = 0; i < data.length; i++) { for (i = 0; i < data.length; i++) {
var ctx = data[i]; var ctx = data[i];
@@ -5705,7 +5704,6 @@ speechSynthesis.getVoices();
$app.data.openVRAlways = configRepository.getBool('openVRAlways'); $app.data.openVRAlways = configRepository.getBool('openVRAlways');
$app.data.overlaybutton = configRepository.getBool('VRCX_overlaybutton'); $app.data.overlaybutton = configRepository.getBool('VRCX_overlaybutton');
$app.data.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed'); $app.data.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed');
$app.data.hideLoginsFromFeed = configRepository.getBool('VRCX_hideLoginsFromFeed');
$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');
@@ -5717,10 +5715,10 @@ speechSynthesis.getVoices();
configRepository.setBool('openVRAlways', this.openVRAlways); configRepository.setBool('openVRAlways', this.openVRAlways);
configRepository.setBool('VRCX_overlaybutton', this.overlaybutton); configRepository.setBool('VRCX_overlaybutton', this.overlaybutton);
configRepository.setBool('VRCX_hidePrivateFromFeed', this.hidePrivateFromFeed); configRepository.setBool('VRCX_hidePrivateFromFeed', this.hidePrivateFromFeed);
configRepository.setBool('VRCX_hideLoginsFromFeed', this.hideLoginsFromFeed);
configRepository.setBool('VRCX_hideDevicesFromFeed', this.hideDevicesFromFeed); configRepository.setBool('VRCX_hideDevicesFromFeed', this.hideDevicesFromFeed);
configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications); configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications);
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed); configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
AppApi.RefreshVR();
}; };
$app.data.TTSvoices = speechSynthesis.getVoices(); $app.data.TTSvoices = speechSynthesis.getVoices();
var saveNotificationTTS = function () { var saveNotificationTTS = function () {
@@ -5729,12 +5727,12 @@ speechSynthesis.getVoices();
if (this.notificationTTS) { if (this.notificationTTS) {
this.speak('Notification text-to-speech enabled'); this.speak('Notification text-to-speech enabled');
} }
AppApi.RefreshVR();
}; };
$app.watch.openVR = saveOpenVROption; $app.watch.openVR = saveOpenVROption;
$app.watch.openVRAlways = saveOpenVROption; $app.watch.openVRAlways = saveOpenVROption;
$app.watch.overlaybutton = saveOpenVROption; $app.watch.overlaybutton = saveOpenVROption;
$app.watch.hidePrivateFromFeed = saveOpenVROption; $app.watch.hidePrivateFromFeed = saveOpenVROption;
$app.watch.hideLoginsFromFeed = saveOpenVROption;
$app.watch.hideDevicesFromFeed = saveOpenVROption; $app.watch.hideDevicesFromFeed = saveOpenVROption;
$app.watch.overlayNotifications = saveOpenVROption; $app.watch.overlayNotifications = saveOpenVROption;
$app.watch.minimalFeed = saveOpenVROption; $app.watch.minimalFeed = saveOpenVROption;
@@ -5744,6 +5742,7 @@ speechSynthesis.getVoices();
$app.watch.isDarkMode = function () { $app.watch.isDarkMode = function () {
configRepository.setBool('isDarkMode', this.isDarkMode); configRepository.setBool('isDarkMode', this.isDarkMode);
$appDarkStyle.disabled = this.isDarkMode === false; $appDarkStyle.disabled = this.isDarkMode === false;
AppApi.RefreshVR();
}; };
$app.data.isStartAtWindowsStartup = configRepository.getBool('VRCX_StartAtWindowsStartup'); $app.data.isStartAtWindowsStartup = configRepository.getBool('VRCX_StartAtWindowsStartup');
$app.data.isStartAsMinimizedState = (VRCXStorage.Get('VRCX_StartAsMinimizedState') === 'true'); $app.data.isStartAsMinimizedState = (VRCXStorage.Get('VRCX_StartAsMinimizedState') === 'true');
@@ -5760,40 +5759,142 @@ speechSynthesis.getVoices();
$app.watch.isStartAsMinimizedState = saveVRCXWindowOption; $app.watch.isStartAsMinimizedState = saveVRCXWindowOption;
$app.watch.isCloseToTray = saveVRCXWindowOption; $app.watch.isCloseToTray = saveVRCXWindowOption;
$app.watch.isAutoLogin = saveVRCXWindowOption; $app.watch.isAutoLogin = saveVRCXWindowOption;
if (!configRepository.getString('VRCX_notificationTimeout')) {
$app.data.notificationTimeout = 3000; //setting defaults
configRepository.setString('VRCX_notificationTimeout', $app.data.notificationTimeout);
}
if (!configRepository.getString('VRCX_notificationJoinLeaveFilter')) {
$app.data.notificationJoinLeaveFilter = 'VIP';
configRepository.setString('VRCX_notificationJoinLeaveFilter', $app.data.notificationJoinLeaveFilter);
}
if (!configRepository.getString('VRCX_notificationOnlineOfflineFilter')) {
$app.data.notificationOnlineOfflineFilter = 'VIP';
configRepository.setString('VRCX_notificationOnlineOfflineFilter', $app.data.notificationOnlineOfflineFilter);
}
if (!configRepository.getString('VRCX_notificationPosition')) { if (!configRepository.getString('VRCX_notificationPosition')) {
$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_notificationTimeout')) {
$app.data.notificationTimeout = 3000;
configRepository.setString('VRCX_notificationTimeout', $app.data.notificationTimeout);
}
if (!configRepository.getString('VRCX_notificationTTSVoice')) { if (!configRepository.getString('VRCX_notificationTTSVoice')) {
$app.data.notificationTTSVoice = '0'; $app.data.notificationTTSVoice = '0';
configRepository.setString('VRCX_notificationTTSVoice', $app.data.notificationTTSVoice); configRepository.setString('VRCX_notificationTTSVoice', $app.data.notificationTTSVoice);
} }
$app.data.notificationJoinLeaveFilter = configRepository.getString('VRCX_notificationJoinLeaveFilter'); if (!configRepository.getString('sharedFeedFilters')) {
$app.methods.changeNotificationJoinLeaveFilter = function () { var sharedFeedFilters = {
configRepository.setString('VRCX_notificationJoinLeaveFilter', this.notificationJoinLeaveFilter); noty: {},
wrist: {}
}; };
$app.data.notificationOnlineOfflineFilter = configRepository.getString('VRCX_notificationOnlineOfflineFilter'); sharedFeedFilters.noty.Location = 'Off';
$app.methods.changeNotificationOnlineOfflineFilter = function () { sharedFeedFilters.noty.OnPlayerJoined = 'VIP';
configRepository.setString('VRCX_notificationOnlineOfflineFilter', this.notificationOnlineOfflineFilter); sharedFeedFilters.noty.OnPlayerLeft = 'VIP';
sharedFeedFilters.noty.OnPlayerJoining = 'VIP';
sharedFeedFilters.noty.Online = 'VIP';
sharedFeedFilters.noty.Offline = 'VIP';
sharedFeedFilters.noty.GPS = 'Off';
sharedFeedFilters.noty.Status = 'Off';
sharedFeedFilters.noty.invite = 'Friends';
sharedFeedFilters.noty.requestInvite = 'Friends';
sharedFeedFilters.noty.friendRequest = 'On';
sharedFeedFilters.noty.Friend = 'On';
sharedFeedFilters.noty.Unfriend = 'On';
sharedFeedFilters.noty.DisplayName = 'VIP';
sharedFeedFilters.noty.TrustLevel = 'VIP';
sharedFeedFilters.wrist.Location = 'On';
sharedFeedFilters.wrist.OnPlayerJoined = 'Everyone';
sharedFeedFilters.wrist.OnPlayerLeft = 'Everyone';
sharedFeedFilters.wrist.OnPlayerJoining = 'Friends';
sharedFeedFilters.wrist.Online = 'Friends';
sharedFeedFilters.wrist.Offline = 'Friends';
sharedFeedFilters.wrist.GPS = 'Friends';
sharedFeedFilters.wrist.Status = 'Friends';
sharedFeedFilters.wrist.invite = 'Friends';
sharedFeedFilters.wrist.requestInvite = 'Friends';
sharedFeedFilters.wrist.friendRequest = 'On';
sharedFeedFilters.wrist.Friend = 'On';
sharedFeedFilters.wrist.Unfriend = 'On';
sharedFeedFilters.wrist.DisplayName = 'Friends';
sharedFeedFilters.wrist.TrustLevel = 'Friends';
configRepository.setString('sharedFeedFilters', JSON.stringify(sharedFeedFilters));
}
$app.data.sharedFeedFilters = JSON.parse(configRepository.getString('sharedFeedFilters'));
$app.data.toggleSwitchOptionsEveryone = {
layout: {
backgroundColor: "white",
selectedBackgroundColor: "#409eff",
selectedColor: "white",
color: "#409eff",
borderColor: "#409eff",
fontWeight: "bold",
fontFamily: '"Noto Sans JP", "Noto Sans KR", "Meiryo UI", "Malgun Gothic", "Segoe UI", "sans-serif"'
},
size: {
height: 1.5,
width: 15,
padding: 0.1,
fontSize: 0.75
},
items: {
labels: [{ name: "Off" }, { name: "VIP" }, { name: "Friends" }, { name: "Everyone" }]
}
}; };
$app.data.toggleSwitchOptionsFriends = {
layout: {
backgroundColor: "white",
selectedBackgroundColor: "#409eff",
selectedColor: "white",
color: "#409eff",
borderColor: "#409eff",
fontWeight: "bold",
fontFamily: '"Noto Sans JP", "Noto Sans KR", "Meiryo UI", "Malgun Gothic", "Segoe UI", "sans-serif"'
},
size: {
height: 1.5,
width: 11.25,
padding: 0.1,
fontSize: 0.75
},
items: {
labels: [{ name: "Off" }, { name: "VIP" }, { name: "Friends" }]
}
};
$app.data.toggleSwitchOptionsOn = {
layout: {
backgroundColor: "white",
selectedBackgroundColor: "#409eff",
selectedColor: "white",
color: "#409eff",
borderColor: "#409eff",
fontWeight: "bold",
fontFamily: '"Noto Sans JP", "Noto Sans KR", "Meiryo UI", "Malgun Gothic", "Segoe UI", "sans-serif"'
},
size: {
height: 1.5,
width: 7.5,
padding: 0.1,
fontSize: 0.75
},
items: {
labels: [{ name: "Off" }, { name: "On" }]
}
};
$app.methods.saveSharedFeedFilters = function () {
this.notyFeedFiltersDialog.visible = false;
this.wristFeedFiltersDialog.visible = false;
configRepository.setString('sharedFeedFilters', JSON.stringify(this.sharedFeedFilters));
AppApi.RefreshVR();
}
$app.methods.cancelSharedFeedFilters = function () {
this.notyFeedFiltersDialog.visible = false;
this.wristFeedFiltersDialog.visible = false;
this.sharedFeedFilters = JSON.parse(configRepository.getString('sharedFeedFilters'));
}
$app.data.notificationPosition = configRepository.getString('VRCX_notificationPosition'); $app.data.notificationPosition = configRepository.getString('VRCX_notificationPosition');
$app.methods.changeNotificationPosition = function () { $app.methods.changeNotificationPosition = function () {
configRepository.setString('VRCX_notificationPosition', this.notificationPosition); configRepository.setString('VRCX_notificationPosition', this.notificationPosition);
AppApi.RefreshVR();
}; };
sharedRepository.setBool('is_game_running', false);
var isGameRunningStateChange = function () { var isGameRunningStateChange = function () {
sharedRepository.setBool('is_game_running', this.isGameRunning);
$app.lastLocation = ''; $app.lastLocation = '';
if (this.isGameRunning) { if (this.isGameRunning) {
API.currentUser.$online_for = Date.now(); API.currentUser.$online_for = Date.now();
@@ -5872,6 +5973,7 @@ speechSynthesis.getVoices();
var voiceName = voices[index].name; var voiceName = voices[index].name;
speechSynthesis.cancel(); speechSynthesis.cancel();
this.speak(voiceName); this.speak(voiceName);
AppApi.RefreshVR();
}; };
$app.methods.speak = function (text) { $app.methods.speak = function (text) {
@@ -7579,6 +7681,28 @@ speechSynthesis.getVoices();
this.notificationPositionDialog.visible = true; this.notificationPositionDialog.visible = true;
}; };
// App: Noty feed filters
$app.data.notyFeedFiltersDialog = {
visible: false
};
$app.methods.showNotyFeedFiltersDialog = function () {
this.$nextTick(() => adjustDialogZ(this.$refs.notyFeedFiltersDialog.$el));
this.notyFeedFiltersDialog.visible = true;
};
// App: Wrist feed filters
$app.data.wristFeedFiltersDialog = {
visible: false
};
$app.methods.showWristFeedFiltersDialog = function () {
this.$nextTick(() => adjustDialogZ(this.$refs.wristFeedFiltersDialog.$el));
this.wristFeedFiltersDialog.visible = true;
};
// App: Launch Dialog // App: Launch Dialog
$app.data.launchDialog = { $app.data.launchDialog = {
+16
View File
@@ -567,3 +567,19 @@ i.x-user-status.busy {
display: inline-block; display: inline-block;
min-width: 175px; min-width: 175px;
} }
.toggle-switch {
display: inline-block;
}
.toggle-list {
font-size: 12px;
}
.toggle-list .toggle-name {
display: inline-block;
min-width: 100px;
padding: 2px 5px 2px 0;
vertical-align: top;
text-align: right;
}
+132 -22
View File
@@ -515,18 +515,18 @@ html
span.name VRCPlus Profile Icons span.name VRCPlus Profile Icons
el-switch(v-model="displayVRCPlusIconsAsAvatar") el-switch(v-model="displayVRCPlusIconsAsAvatar")
div.options-container div.options-container
span.header Friends Sort Option span.header Side Pannel Sorting Options
div.options-container-item div.options-container-item
span.name VIP span.name VIP
el-switch(v-model="orderFriendsGroup0" inactive-text="by name" active-text="by state") el-switch(v-model="orderFriendsGroup0" inactive-text="by name" active-text="by state")
div.options-container-item div.options-container-item
span.name ONLINE span.name Online
el-switch(v-model="orderFriendsGroup1" inactive-text="by name" active-text="by state") el-switch(v-model="orderFriendsGroup1" inactive-text="by name" active-text="by state")
div.options-container-item div.options-container-item
span.name ACTIVE span.name Active
el-switch(v-model="orderFriendsGroup2" inactive-text="by name" active-text="by state") el-switch(v-model="orderFriendsGroup2" inactive-text="by name" active-text="by state")
div.options-container-item div.options-container-item
span.name OFFLINE span.name Offline
el-switch(v-model="orderFriendsGroup3" inactive-text="by name" active-text="by state") el-switch(v-model="orderFriendsGroup3" inactive-text="by name" active-text="by state")
div.options-container div.options-container
span.header Discord Presence span.header Discord Presence
@@ -560,9 +560,6 @@ html
div.options-container-item div.options-container-item
span.name Hide VR Devices span.name Hide VR Devices
el-switch(v-model="hideDevicesFromFeed" :disabled="!openVR") el-switch(v-model="hideDevicesFromFeed" :disabled="!openVR")
div.options-container-item
span.name Hide Online/Offline
el-switch(v-model="hideLoginsFromFeed" :disabled="!openVR")
div.options-container-item div.options-container-item
span.name Hide Private Worlds span.name Hide Private Worlds
el-switch(v-model="hidePrivateFromFeed" :disabled="!openVR") el-switch(v-model="hidePrivateFromFeed" :disabled="!openVR")
@@ -581,24 +578,12 @@ html
el-button(v-text="TTSvoices[notificationTTSVoice].name" size="mini" :disabled="!openVR || !notificationTTS") el-button(v-text="TTSvoices[notificationTTSVoice].name" size="mini" :disabled="!openVR || !notificationTTS")
el-dropdown-menu(#default="dropdown") 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") 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 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-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.options-container-item
span Join/Leave Notifications
br
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="Friends" v-model="notificationJoinLeaveFilter") Friends
el-radio(label="Everyone" v-model="notificationJoinLeaveFilter") Everyone
el-radio(label="Off" v-model="notificationJoinLeaveFilter") Off
div.options-container-item
span Online/Offline Notifications
br
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="Friends" v-model="notificationOnlineOfflineFilter") Friends
el-radio(label="Off" v-model="notificationOnlineOfflineFilter") Off
div.options-container div.options-container
span.header Application span.header Application
div.options-container-item div.options-container-item
@@ -1206,6 +1191,107 @@ html
div(style="display:flex") div(style="display:flex")
el-button(type="primary" size="small" style="margin-left:auto" @click="notificationPositionDialog.visible = false") OK el-button(type="primary" size="small" style="margin-left:auto" @click="notificationPositionDialog.visible = false") OK
//- dialog: Noty feed filters
el-dialog.x-dialog(ref="notyFeedFiltersDialog" :visible.sync="notyFeedFiltersDialog.visible" title="Notification Filters" width="400px")
div.toggle-list
div
span.toggle-name OnPlayerJoining
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupOnPlayerJoining" v-model="sharedFeedFilters.noty.OnPlayerJoining" class="toggle-switch")
div
span.toggle-name OnPlayerJoined
toggle-switch(:options="toggleSwitchOptionsEveryone" group="switchNotyGroupOnPlayerJoined" v-model="sharedFeedFilters.noty.OnPlayerJoined" class="toggle-switch")
div
span.toggle-name OnPlayerLeft
toggle-switch(:options="toggleSwitchOptionsEveryone" group="switchNotyGroupOnPlayerLeft" v-model="sharedFeedFilters.noty.OnPlayerLeft" class="toggle-switch")
div
span.toggle-name Online
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupOnline" v-model="sharedFeedFilters.noty.Online" class="toggle-switch")
div
span.toggle-name Offline
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupOffline" v-model="sharedFeedFilters.noty.Offline" class="toggle-switch")
div
span.toggle-name GPS
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupGPS" v-model="sharedFeedFilters.noty.GPS" class="toggle-switch")
div
span.toggle-name Status
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupStatus" v-model="sharedFeedFilters.noty.Status" class="toggle-switch")
div
span.toggle-name Invite
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGroupinvite" v-model="sharedFeedFilters.noty.invite" class="toggle-switch")
div
span.toggle-name Request Invite
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGrouprequestInvite" v-model="sharedFeedFilters.noty.requestInvite" class="toggle-switch")
div
span.toggle-name Friend Request
toggle-switch(:options="toggleSwitchOptionsOn" group="switchNotyGrouprequestfriendRequest" v-model="sharedFeedFilters.noty.friendRequest" class="toggle-switch")
div
span.toggle-name New Friend
toggle-switch(:options="toggleSwitchOptionsOn" group="switchNotyGrouprequestFriend" v-model="sharedFeedFilters.noty.Friend" class="toggle-switch")
div
span.toggle-name Unfriend
toggle-switch(:options="toggleSwitchOptionsOn" group="switchNotyGrouprequestUnfriend" v-model="sharedFeedFilters.noty.Unfriend" class="toggle-switch")
div
span.toggle-name DisplayName
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGrouprequestDisplayName" v-model="sharedFeedFilters.noty.DisplayName" class="toggle-switch")
div
span.toggle-name TrustLevel
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchNotyGrouprequestTrustLevel" v-model="sharedFeedFilters.noty.TrustLevel" class="toggle-switch")
template(#footer)
el-button(type="small" @click="cancelSharedFeedFilters") Cancel
el-button(type="primary" size="small" style="margin-left:10px" @click="saveSharedFeedFilters") Save
//- dialog: wrist feed filters
el-dialog.x-dialog(ref="wristFeedFiltersDialog" :visible.sync="wristFeedFiltersDialog.visible" title="Wrist Feed Filters" width="400px")
div.toggle-list
div
span.toggle-name Self Location
toggle-switch(:options="toggleSwitchOptionsOn" group="switchWristGroupLocation" v-model="sharedFeedFilters.wrist.Location" class="toggle-switch")
div
span.toggle-name OnPlayerJoining
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupOnPlayerJoining" v-model="sharedFeedFilters.wrist.OnPlayerJoining" class="toggle-switch")
div
span.toggle-name OnPlayerJoined
toggle-switch(:options="toggleSwitchOptionsEveryone" group="switchWristGroupOnPlayerJoined" v-model="sharedFeedFilters.wrist.OnPlayerJoined" class="toggle-switch")
div
span.toggle-name OnPlayerLeft
toggle-switch(:options="toggleSwitchOptionsEveryone" group="switchWristGroupOnPlayerLeft" v-model="sharedFeedFilters.wrist.OnPlayerLeft" class="toggle-switch")
div
span.toggle-name Online
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupOnline" v-model="sharedFeedFilters.wrist.Online" class="toggle-switch")
div
span.toggle-name Offline
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupOffline" v-model="sharedFeedFilters.wrist.Offline" class="toggle-switch")
div
span.toggle-name GPS
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupGPS" v-model="sharedFeedFilters.wrist.GPS" class="toggle-switch")
div
span.toggle-name Status
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupStatus" v-model="sharedFeedFilters.wrist.Status" class="toggle-switch")
div
span.toggle-name Invite
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGroupinvite" v-model="sharedFeedFilters.wrist.invite" class="toggle-switch")
div
span.toggle-name Request Invite
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGrouprequestInvite" v-model="sharedFeedFilters.wrist.requestInvite" class="toggle-switch")
div
span.toggle-name Friend Request
toggle-switch(:options="toggleSwitchOptionsOn" group="switchWristGrouprequestfriendRequest" v-model="sharedFeedFilters.wrist.friendRequest" class="toggle-switch")
div
span.toggle-name New Friend
toggle-switch(:options="toggleSwitchOptionsOn" group="switchWristGrouprequestFriend" v-model="sharedFeedFilters.wrist.Friend" class="toggle-switch")
div
span.toggle-name Unfriend
toggle-switch(:options="toggleSwitchOptionsOn" group="switchWristGrouprequestUnfriend" v-model="sharedFeedFilters.wrist.Unfriend" class="toggle-switch")
div
span.toggle-name DisplayName
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGrouprequestDisplayName" v-model="sharedFeedFilters.wrist.DisplayName" class="toggle-switch")
div
span.toggle-name TrustLevel
toggle-switch(:options="toggleSwitchOptionsFriends" group="switchWristGrouprequestTrustLevel" v-model="sharedFeedFilters.wrist.TrustLevel" class="toggle-switch")
template(#footer)
el-button(type="small" @click="cancelSharedFeedFilters") Cancel
el-button(type="primary" size="small" @click="saveSharedFeedFilters") Save
//- dialog: open source software notice //- dialog: open source software notice
el-dialog.x-dialog(:visible.sync="ossDialog" title="Open Source Software Notice" width="650px") el-dialog.x-dialog(:visible.sync="ossDialog" title="Open Source Software Notice" width="650px")
div(style="height:350px;overflow:hidden scroll;word-break:break-all") div(style="height:350px;overflow:hidden scroll;word-break:break-all")
@@ -1480,6 +1566,30 @@ html
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") vuejs-toggle-switch
pre(style="font-size:12px;white-space:pre-line").
MIT License
Copyright (c) 2018 Lars-Martin Hejll
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+233 -99
View File
@@ -573,9 +573,21 @@ speechSynthesis.getVoices();
currentTime: new Date().toJSON(), currentTime: new Date().toJSON(),
currentUserStatus: null, currentUserStatus: null,
cpuUsage: 0, cpuUsage: 0,
feeds: [], isGameRunning: false,
lastLocation: '',
lastFeedEntry: [],
feedFilters: [],
wristFeed: [],
notyMap: [],
devices: [], devices: [],
overlayNotificationsToggle: false,
notificationTTSToggle: false,
notificationTTSVoice: '0',
hideDevicesToggle: false,
isMinimalFeed: false, isMinimalFeed: false,
notificationPosition: 'topCenter',
notificationTimeout: '3000',
notificationTheme: 'relax'
}, },
computed: {}, computed: {},
methods: {}, methods: {},
@@ -600,6 +612,8 @@ speechSynthesis.getVoices();
// FIXME: 어케 복구하냐 이건 // FIXME: 어케 복구하냐 이건
throw err; throw err;
}).then((args) => { }).then((args) => {
this.initConfigVars();
this.initNotyMap();
this.updateLoop(); this.updateLoop();
this.updateCpuUsageLoop(); this.updateCpuUsageLoop();
this.$nextTick(function () { this.$nextTick(function () {
@@ -612,23 +626,70 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.initConfigVars = function () {
this.notificationTTSToggle = configRepository.getBool('VRCX_notificationTTS');
this.notificationTTSVoice = configRepository.getString('VRCX_notificationTTSVoice');
this.overlayNotificationsToggle = configRepository.getBool('VRCX_overlayNotifications');
this.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed');
this.hideDevicesToggle = configRepository.getBool('VRCX_hideDevicesFromFeed');
this.isMinimalFeed = configRepository.getBool('VRCX_minimalFeed');
this.feedFilters = JSON.parse(configRepository.getString('sharedFeedFilters'));
this.notificationPosition = configRepository.getString('VRCX_notificationPosition');
this.notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
if (configRepository.getBool('isDarkMode')) {
this.notificationTheme = 'sunset';
} else {
this.notificationTheme = 'relax';
}
};
$app.methods.initNotyMap = function () {
var feeds = sharedRepository.getArray('feeds');
if (feeds === null) {
return;
}
var filter = this.feedFilters.noty;
var filtered = [];
feeds.forEach((feed) => {
if (filter[feed.type]) {
if ((filter[feed.type] !== 'Off') &&
((filter[feed.type] === 'Everyone') || (filter[feed.type] === 'On') ||
((filter[feed.type] === 'Friends') && (feed.isFriend)) ||
((filter[feed.type] === 'VIP') && (feed.isFavorite)))) {
var displayName = '';
if (feed.data) {
displayName = feed.data;
} else if (feed.displayName) {
displayName = feed.displayName;
} else if (feed.senderUsername) {
displayName = feed.senderUsername;
}
if ((displayName) && (!this.notyMap[displayName]) ||
(this.notyMap[displayName] < feed.created_at)) {
this.notyMap[displayName] = feed.created_at;
}
}
}
});
};
$app.methods.updateLoop = async function () { $app.methods.updateLoop = async function () {
try { try {
this.currentTime = new Date().toJSON(); this.currentTime = new Date().toJSON();
this.currentUserStatus = sharedRepository.getString('current_user_status'); this.currentUserStatus = sharedRepository.getString('current_user_status');
this.isGameRunning = sharedRepository.getBool('is_game_running'); this.isGameRunning = sharedRepository.getBool('is_game_running');
if (configRepository.getBool('VRCX_hideDevicesFromFeed') === false) { this.lastLocation = sharedRepository.getString('last_location');
if (!this.hideDevicesToggle) {
AppApi.GetVRDevices().then((devices) => { AppApi.GetVRDevices().then((devices) => {
devices.forEach((device) => { devices.forEach((device) => {
device[2] = parseInt(device[2], 10); device[2] = parseInt(device[2], 10);
}); });
this.devices = devices; this.devices = devices;
}); });
} } else {
else {
this.devices = ''; this.devices = '';
} }
await this.updateSharedFeed(); await this.updateSharedFeeds();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
@@ -645,111 +706,126 @@ speechSynthesis.getVoices();
setTimeout(() => this.updateCpuUsageLoop(), 1000); setTimeout(() => this.updateCpuUsageLoop(), 1000);
}; };
$app.methods.updateSharedFeed = async function () { $app.methods.updateSharedFeeds = async function () {
// TODO: block mute hideAvatar unfriend
this.isMinimalFeed = configRepository.getBool('VRCX_minimalFeed');
var notificationPosition = configRepository.getString('VRCX_notificationPosition');
var notificationTimeout = configRepository.getString('VRCX_notificationTimeout');
var notificationJoinLeaveFilter = configRepository.getString('VRCX_notificationJoinLeaveFilter');
var notificationOnlineOfflineFilter = configRepository.getString('VRCX_notificationOnlineOfflineFilter');
var theme = 'relax';
if (configRepository.getBool('isDarkMode') === true) {
theme = 'sunset';
}
var feeds = sharedRepository.getArray('feeds'); var feeds = sharedRepository.getArray('feeds');
if (feeds === null) { if (feeds === null) {
return; return;
} }
if ((this.lastFeedEntry !== undefined) &&
var _feeds = this.feeds; (feeds[0].created_at === this.lastFeedEntry.created_at)) {
this.feeds = feeds;
if ((this.appType === '2') && this.isGameRunning) {
var map = {};
_feeds.forEach((feed) => {
if (feed.type === 'OnPlayerJoined' ||
feed.type === 'OnPlayerLeft') {
if (!map[feed.data] ||
map[feed.data] < feed.created_at) {
map[feed.data] = feed.created_at;
}
} else if (feed.type === 'Online' ||
feed.type === 'Offline') {
if (!map[feed.displayName] ||
map[feed.displayName] < feed.created_at) {
map[feed.displayName] = feed.created_at;
}
} 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;
}
} else if (feed.type === 'Friend' ||
feed.type === 'Unfriend') {
if (!map[feed.displayName] ||
map[feed.displayName] < feed.created_at) {
map[feed.displayName] = feed.created_at;
}
}
});
// disable notification on busy
if (this.currentUserStatus === 'busy') {
return; return;
} }
var notys = []; this.lastFeedEntry = feeds[0];
this.feeds.forEach((feed) => {
if (((notificationOnlineOfflineFilter === "Friends") && (feed.isFriend)) || // OnPlayerJoining
((notificationOnlineOfflineFilter === "VIP") && (feed.isFavorite))) { var bias = new Date(Date.now() - 120000).toJSON();
if (feed.type === 'Online' || for (i = 0; i < feeds.length; i++) {
feed.type === 'Offline') { var ctx = feeds[i];
if (!map[feed.displayName] || if ((ctx.created_at < bias) || (ctx.type === 'Location')) {
map[feed.displayName] < feed.created_at) { break;
map[feed.displayName] = feed.created_at; }
notys.push(feed); if ((ctx.type === 'GPS') && (ctx.location[0] === this.lastLocation)) {
var joining = true;
for (var k = 0; k < feeds.length; k++) {
var feedItem = feeds[k];
if ((feedItem.type === 'OnPlayerJoined') && (feedItem.data === ctx.displayName)) {
joining = false;
break;
}
if ((feedItem.created_at < bias) || (feedItem.type === 'Location') ||
((feedItem.type === 'GPS') && (feedItem.location !== ctx.location[0]) &&
(feedItem.displayName === ctx.displayName))) {
break;
}
}
if (joining) {
var onPlayerJoining = {};
onPlayerJoining.created_at = ctx.created_at;
onPlayerJoining.data = ctx.displayName;
onPlayerJoining.isFavorite = ctx.isFavorite;
onPlayerJoining.isFriend = ctx.isFriend;
onPlayerJoining.type = 'OnPlayerJoining';
feeds.splice(i, 0, onPlayerJoining);
i++;
} }
} }
} }
if ((notificationJoinLeaveFilter === "Everyone") ||
((notificationJoinLeaveFilter === "Friends") && (feed.isFriend)) || if (this.hidePrivateFromFeed) {
((notificationJoinLeaveFilter === "VIP") && (feed.isFavorite))) { for (var i = 0; i < feeds.length; i++) {
if (feed.type === 'OnPlayerJoined' || var feed = feeds[i];
feed.type === 'OnPlayerLeft') { if ((feed.type === 'GPS') && (feed.location[0] === 'private')) {
if (!map[feed.data] || feeds.splice(i, 1);
map[feed.data] < feed.created_at) { i--;
map[feed.data] = feed.created_at;
notys.push(feed);
} }
} }
} }
if (feed.type === 'invite' ||
feed.type === 'requestInvite' || if (this.appType === '1') {
feed.type === 'friendRequest') { this.updateSharedFeedWrist(feeds);
if (!map[feed.senderUsername] ||
map[feed.senderUsername] < feed.created_at) {
map[feed.senderUsername] = feed.created_at;
notys.push(feed);
} }
if (this.appType === '2') {
this.updateSharedFeedNoty(feeds);
} }
if (feed.type === 'Friend' || };
feed.type === 'Unfriend') {
if (!map[feed.displayName] || $app.methods.updateSharedFeedWrist = async function (feeds) {
map[feed.displayName] < feed.created_at) { var filter = this.feedFilters.wrist;
map[feed.displayName] = feed.created_at; var filtered = [];
notys.push(feed); feeds.forEach((feed) => {
if (filter[feed.type]) {
if ((filter[feed.type] !== 'Off') &&
((filter[feed.type] === 'Everyone') || (filter[feed.type] === 'On') ||
((filter[feed.type] === 'Friends') && (feed.isFriend)) ||
((filter[feed.type] === 'VIP') && (feed.isFavorite)))) {
filtered.push(feed);
}
} else {
console.error(`missing feed filter for ${feed.type}`);
filtered.push(feed);
}
});
this.wristFeed = filtered;
};
$app.methods.updateSharedFeedNoty = async function (feeds) {
var filter = this.feedFilters.noty;
var filtered = [];
feeds.forEach((feed) => {
if (filter[feed.type]) {
if ((filter[feed.type] !== 'Off') &&
((filter[feed.type] === 'Everyone') || (filter[feed.type] === 'On') ||
((filter[feed.type] === 'Friends') && (feed.isFriend)) ||
((filter[feed.type] === 'VIP') && (feed.isFavorite)))) {
filtered.push(feed);
} }
} }
}); });
var bias = new Date(Date.now() - 60000).toJSON(); var notyToPlay = [];
var theme = 'relax'; filtered.forEach((feed) => {
if (configRepository.getBool('isDarkMode') === true) { var displayName = '';
theme = 'sunset'; if (feed.displayName) {
displayName = feed.displayName;
} else if (feed.senderUsername) {
displayName = feed.senderUsername;
} else if (feed.data) {
displayName = feed.data;
} else {
console.error('missing displayName');
} }
notys.forEach((noty) => { if ((displayName) && (!this.notyMap[displayName]) ||
if (noty.created_at > bias) { (this.notyMap[displayName] < feed.created_at)) {
if (configRepository.getBool('VRCX_overlayNotifications')) { this.notyMap[displayName] = feed.created_at;
notyToPlay.push(feed);
}
});
// disable notifications when busy or game isn't running
if ((this.currentUserStatus === 'busy') || (!this.isGameRunning)) {
return;
}
notyToPlay.forEach(async (noty) => {
if (this.overlayNotificationsToggle) {
var text = ''; var text = '';
switch (noty.type) { switch (noty.type) {
case 'OnPlayerJoined': case 'OnPlayerJoined':
@@ -758,12 +834,21 @@ speechSynthesis.getVoices();
case 'OnPlayerLeft': case 'OnPlayerLeft':
text = `<strong>${noty.data}</strong> has left`; text = `<strong>${noty.data}</strong> has left`;
break; break;
case 'OnPlayerJoining':
text = `<strong>${noty.data}</strong> is joining`;
break;
case 'GPS':
text = '<strong>' + noty.displayName + '</strong> is in ' + await this.displayLocation(noty.location[0]);
break;
case 'Online': case 'Online':
text = `<strong>${noty.displayName}</strong> has logged in`; text = `<strong>${noty.displayName}</strong> has logged in`;
break; break;
case 'Offline': case 'Offline':
text = `<strong>${noty.displayName}</strong> has logged out`; text = `<strong>${noty.displayName}</strong> has logged out`;
break; break;
case 'Status':
text = `<strong>${noty.displayName}</strong> status is now <i>${noty.status[0].status}</i> ${noty.status[0].statusDescription}`;
break;
case 'invite': case 'invite':
text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName}`; text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName}`;
break; break;
@@ -779,18 +864,24 @@ speechSynthesis.getVoices();
case 'Unfriend': case 'Unfriend':
text = `<strong>${noty.displayName}</strong> has unfriended you`; text = `<strong>${noty.displayName}</strong> has unfriended you`;
break; break;
case 'TrustLevel':
text = `<strong>${noty.displayName}</strong> trust level is now ${noty.trustLevel}`;
break;
case 'DisplayName':
text = `<strong>${noty.previousDisplayName}</strong> changed their name to ${noty.displayName}`;
break;
} }
if (text) { if (text) {
new Noty({ new Noty({
type: 'alert', type: 'alert',
theme: theme, theme: this.notificationTheme,
timeout: notificationTimeout, timeout: this.notificationTimeout,
layout: notificationPosition, layout: this.notificationPosition,
text: text text: text
}).show(); }).show();
} }
} }
if (configRepository.getBool('VRCX_notificationTTS')) { if (this.notificationTTSToggle) {
switch (noty.type) { switch (noty.type) {
case 'OnPlayerJoined': case 'OnPlayerJoined':
this.speak(`${noty.data} has joined`); this.speak(`${noty.data} has joined`);
@@ -798,12 +889,21 @@ speechSynthesis.getVoices();
case 'OnPlayerLeft': case 'OnPlayerLeft':
this.speak(`${noty.data} has left`); this.speak(`${noty.data} has left`);
break; break;
case 'OnPlayerJoining':
this.speak(`${noty.data} is joining`);
break;
case 'GPS':
this.speak(noty.displayName + ' is in ' + await this.displayLocation(noty.location[0]));
break;
case 'Online': case 'Online':
this.speak(`${noty.displayName} has logged in`); this.speak(`${noty.displayName} has logged in`);
break; break;
case 'Offline': case 'Offline':
this.speak(`${noty.displayName} has logged out`); this.speak(`${noty.displayName} has logged out`);
break; break;
case 'Status':
this.speak(`${noty.displayName} status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`);
break;
case 'invite': case 'invite':
this.speak(`${noty.senderUsername} has invited you to ${noty.details.worldName}`); this.speak(`${noty.senderUsername} has invited you to ${noty.details.worldName}`);
break; break;
@@ -819,11 +919,15 @@ speechSynthesis.getVoices();
case 'Unfriend': case 'Unfriend':
this.speak(`${noty.displayName} has unfriended you`); this.speak(`${noty.displayName} has unfriended you`);
break; break;
} case 'TrustLevel':
this.speak(`${noty.displayName} trust level is now ${noty.trustLevel}`);
break;
case 'DisplayName':
this.speak(`${noty.previousDisplayName} changed their name to ${noty.displayName}`);
break;
} }
} }
}); });
}
}; };
$app.methods.userStatusClass = function (user) { $app.methods.userStatusClass = function (user) {
@@ -842,10 +946,40 @@ speechSynthesis.getVoices();
return style; return style;
}; };
$app.methods.displayLocation = async function (location) {
var text = '';
var L = API.parseLocation(location);
if (L.isOffline) {
text = 'Offline';
} else if (L.isPrivate) {
text = 'Private';
} else if (L.worldId) {
var ref = API.cachedWorlds.get(L.worldId);
if (ref === undefined) {
await API.getWorld({
worldId: L.worldId
}).then((args) => {
if (L.tag === location) {
if (L.instanceId) {
text = `${args.json.name} ${L.accessType}`;
} else {
text = args.json.name;
}
}
});
} else if (L.instanceId) {
text = `${ref.name} ${L.accessType}`;
} else {
text = ref.name;
}
}
return text;
};
$app.methods.speak = function (text) { $app.methods.speak = function (text) {
var tts = new SpeechSynthesisUtterance(); var tts = new SpeechSynthesisUtterance();
var voices = speechSynthesis.getVoices(); var voices = speechSynthesis.getVoices();
var voiceIndex = configRepository.getString('VRCX_notificationTTSVoice'); var voiceIndex = this.notificationTTSVoice;
tts.voice = voices[voiceIndex]; tts.voice = voices[voiceIndex];
tts.text = text; tts.text = text;
speechSynthesis.speak(tts); speechSynthesis.speak(tts);
+15 -4
View File
@@ -12,11 +12,11 @@ html
link(rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Sans+KR&display=swap") link(rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Sans+KR&display=swap")
link(rel="stylesheet" href="vr.css") link(rel="stylesheet" href="vr.css")
body body
.x-app#x-app(style="display:none" :class="{ 'x-app-type': appType === '1' }") .x-app#x-app(v-if="appType === '1'" class="x-app-type")
.x-container(style="flex:1") .x-container(style="flex:1")
.x-friend-list(ref="list" style="color:#aaa") .x-friend-list(ref="list" style="color:#aaa")
template(v-if="isMinimalFeed === true") template(v-if="isMinimalFeed")
template(v-for="feed in feeds") template(v-for="feed in wristFeed")
.x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra
@@ -47,6 +47,12 @@ html
span.extra span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }} span.time {{ feed.created_at | formatDate('HH:MI') }}
| ◀️ #[span.name(v-text="feed.data")] | ◀️ #[span.name(v-text="feed.data")]
div(v-else-if="feed.type === 'OnPlayerJoining'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail
span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }}
span.spin ▶️
span.name(v-text="feed.data" style="margin-left:20px")
div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra
@@ -88,7 +94,7 @@ html
span.time {{ feed.created_at | formatDate('HH:MI') }} span.time {{ feed.created_at | formatDate('HH:MI') }}
| 🤝 #[span.name(v-text="feed.displayName")] {{ feed.previousTrustLevel }} #[i.el-icon-right] {{ feed.trustLevel }} | 🤝 #[span.name(v-text="feed.displayName")] {{ feed.previousTrustLevel }} #[i.el-icon-right] {{ feed.trustLevel }}
template(v-else) template(v-else)
template(v-for="feed in feeds") template(v-for="feed in wristFeed")
.x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra
@@ -119,6 +125,11 @@ html
span.extra span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }} span.time {{ feed.created_at | formatDate('HH:MI') }}
| #[span.name(v-text="feed.data")] has left | #[span.name(v-text="feed.data")] has left
div(v-else-if="feed.type === 'OnPlayerJoining'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail
span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }}
| #[span.name(v-text="feed.data")] is joining
div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra
+16
View File
@@ -274,3 +274,19 @@ i.x-user-status.joinme {
i.x-user-status.busy { i.x-user-status.busy {
background: #f56c6c; background: #f56c6c;
} }
.spin {
animation: rotation 2.5s infinite linear;
position: absolute;
width: 14px;
height: 28px;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}