mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 06:43:51 +02:00
Add feed filters, vuejs-toggle-switch, OnPlayerJoining, and refactor vr.js
This commit is contained in:
5
html/package-lock.json
generated
5
html/package-lock.json
generated
@@ -12394,6 +12394,11 @@
|
||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"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": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"stylelint-scss": "^3.18.0",
|
||||
"vue": "^2.6.12",
|
||||
"vue-data-tables": "^3.4.5",
|
||||
"vue-lazyload": "^1.3.3"
|
||||
"vue-lazyload": "^1.3.3",
|
||||
"vuejs-toggle-switch": "^1.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
174
html/src/app.js
174
html/src/app.js
@@ -8,6 +8,7 @@ import Noty from 'noty';
|
||||
import Vue from 'vue';
|
||||
import VueLazyload from 'vue-lazyload';
|
||||
import { DataTables } from 'vue-data-tables';
|
||||
import ToggleSwitch from 'vuejs-toggle-switch'
|
||||
import ElementUI from 'element-ui';
|
||||
import locale from 'element-ui/lib/locale/lang/en';
|
||||
|
||||
@@ -3415,7 +3416,6 @@ speechSynthesis.getVoices();
|
||||
AppApi.CheckGameRunning().then(([isGameRunning, isGameNoVR]) => {
|
||||
if (isGameRunning !== this.isGameRunning) {
|
||||
this.isGameRunning = isGameRunning;
|
||||
sharedRepository.setBool('is_game_running', isGameRunning);
|
||||
Discord.SetTimestamps(Date.now(), 0);
|
||||
}
|
||||
this.isGameNoVR = isGameNoVR;
|
||||
@@ -3472,9 +3472,7 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
var ctx = data[--i];
|
||||
// GPS, Online, Offline, Status, Avatar
|
||||
if ((ctx.type !== 'Avatar') &&
|
||||
!((ctx.type === 'GPS') && (ctx.location[0] === 'private') && (this.hidePrivateFromFeed === true)) &&
|
||||
!(((ctx.type === 'Online') || (ctx.type === 'Offline')) && (this.hideLoginsFromFeed === true))) {
|
||||
if (ctx.type !== 'Avatar') {
|
||||
arr.push({
|
||||
...ctx,
|
||||
isFriend: this.friends.has(ctx.userId),
|
||||
@@ -3483,6 +3481,7 @@ speechSynthesis.getVoices();
|
||||
++j;
|
||||
}
|
||||
}
|
||||
// invite, requestInvite, friendRequest
|
||||
var { data } = this.notificationTable;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
var ctx = data[i];
|
||||
@@ -5705,7 +5704,6 @@ speechSynthesis.getVoices();
|
||||
$app.data.openVRAlways = configRepository.getBool('openVRAlways');
|
||||
$app.data.overlaybutton = configRepository.getBool('VRCX_overlaybutton');
|
||||
$app.data.hidePrivateFromFeed = configRepository.getBool('VRCX_hidePrivateFromFeed');
|
||||
$app.data.hideLoginsFromFeed = configRepository.getBool('VRCX_hideLoginsFromFeed');
|
||||
$app.data.hideDevicesFromFeed = configRepository.getBool('VRCX_hideDevicesFromFeed');
|
||||
$app.data.overlayNotifications = configRepository.getBool('VRCX_overlayNotifications');
|
||||
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed');
|
||||
@@ -5717,10 +5715,10 @@ speechSynthesis.getVoices();
|
||||
configRepository.setBool('openVRAlways', this.openVRAlways);
|
||||
configRepository.setBool('VRCX_overlaybutton', this.overlaybutton);
|
||||
configRepository.setBool('VRCX_hidePrivateFromFeed', this.hidePrivateFromFeed);
|
||||
configRepository.setBool('VRCX_hideLoginsFromFeed', this.hideLoginsFromFeed);
|
||||
configRepository.setBool('VRCX_hideDevicesFromFeed', this.hideDevicesFromFeed);
|
||||
configRepository.setBool('VRCX_overlayNotifications', this.overlayNotifications);
|
||||
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
$app.data.TTSvoices = speechSynthesis.getVoices();
|
||||
var saveNotificationTTS = function () {
|
||||
@@ -5729,12 +5727,12 @@ speechSynthesis.getVoices();
|
||||
if (this.notificationTTS) {
|
||||
this.speak('Notification text-to-speech enabled');
|
||||
}
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
$app.watch.openVR = saveOpenVROption;
|
||||
$app.watch.openVRAlways = saveOpenVROption;
|
||||
$app.watch.overlaybutton = saveOpenVROption;
|
||||
$app.watch.hidePrivateFromFeed = saveOpenVROption;
|
||||
$app.watch.hideLoginsFromFeed = saveOpenVROption;
|
||||
$app.watch.hideDevicesFromFeed = saveOpenVROption;
|
||||
$app.watch.overlayNotifications = saveOpenVROption;
|
||||
$app.watch.minimalFeed = saveOpenVROption;
|
||||
@@ -5744,6 +5742,7 @@ speechSynthesis.getVoices();
|
||||
$app.watch.isDarkMode = function () {
|
||||
configRepository.setBool('isDarkMode', this.isDarkMode);
|
||||
$appDarkStyle.disabled = this.isDarkMode === false;
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
$app.data.isStartAtWindowsStartup = configRepository.getBool('VRCX_StartAtWindowsStartup');
|
||||
$app.data.isStartAsMinimizedState = (VRCXStorage.Get('VRCX_StartAsMinimizedState') === 'true');
|
||||
@@ -5760,40 +5759,142 @@ speechSynthesis.getVoices();
|
||||
$app.watch.isStartAsMinimizedState = saveVRCXWindowOption;
|
||||
$app.watch.isCloseToTray = saveVRCXWindowOption;
|
||||
$app.watch.isAutoLogin = saveVRCXWindowOption;
|
||||
if (!configRepository.getString('VRCX_notificationTimeout')) {
|
||||
$app.data.notificationTimeout = 3000;
|
||||
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);
|
||||
}
|
||||
|
||||
//setting defaults
|
||||
if (!configRepository.getString('VRCX_notificationPosition')) {
|
||||
$app.data.notificationPosition = 'topCenter';
|
||||
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')) {
|
||||
$app.data.notificationTTSVoice = '0';
|
||||
configRepository.setString('VRCX_notificationTTSVoice', $app.data.notificationTTSVoice);
|
||||
}
|
||||
$app.data.notificationJoinLeaveFilter = configRepository.getString('VRCX_notificationJoinLeaveFilter');
|
||||
$app.methods.changeNotificationJoinLeaveFilter = function () {
|
||||
configRepository.setString('VRCX_notificationJoinLeaveFilter', this.notificationJoinLeaveFilter);
|
||||
if (!configRepository.getString('sharedFeedFilters')) {
|
||||
var sharedFeedFilters = {
|
||||
noty: {},
|
||||
wrist: {}
|
||||
};
|
||||
sharedFeedFilters.noty.Location = 'Off';
|
||||
sharedFeedFilters.noty.OnPlayerJoined = 'VIP';
|
||||
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.notificationOnlineOfflineFilter = configRepository.getString('VRCX_notificationOnlineOfflineFilter');
|
||||
$app.methods.changeNotificationOnlineOfflineFilter = function () {
|
||||
configRepository.setString('VRCX_notificationOnlineOfflineFilter', this.notificationOnlineOfflineFilter);
|
||||
$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.methods.changeNotificationPosition = function () {
|
||||
configRepository.setString('VRCX_notificationPosition', this.notificationPosition);
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
|
||||
sharedRepository.setBool('is_game_running', false);
|
||||
var isGameRunningStateChange = function () {
|
||||
sharedRepository.setBool('is_game_running', this.isGameRunning);
|
||||
$app.lastLocation = '';
|
||||
if (this.isGameRunning) {
|
||||
API.currentUser.$online_for = Date.now();
|
||||
@@ -5872,6 +5973,7 @@ speechSynthesis.getVoices();
|
||||
var voiceName = voices[index].name;
|
||||
speechSynthesis.cancel();
|
||||
this.speak(voiceName);
|
||||
AppApi.RefreshVR();
|
||||
};
|
||||
|
||||
$app.methods.speak = function (text) {
|
||||
@@ -7579,6 +7681,28 @@ speechSynthesis.getVoices();
|
||||
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.data.launchDialog = {
|
||||
|
||||
@@ -567,3 +567,19 @@ i.x-user-status.busy {
|
||||
display: inline-block;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -515,18 +515,18 @@ html
|
||||
span.name VRCPlus Profile Icons
|
||||
el-switch(v-model="displayVRCPlusIconsAsAvatar")
|
||||
div.options-container
|
||||
span.header Friends Sort Option
|
||||
span.header Side Pannel Sorting Options
|
||||
div.options-container-item
|
||||
span.name VIP
|
||||
el-switch(v-model="orderFriendsGroup0" inactive-text="by name" active-text="by state")
|
||||
div.options-container-item
|
||||
span.name ONLINE
|
||||
span.name Online
|
||||
el-switch(v-model="orderFriendsGroup1" inactive-text="by name" active-text="by state")
|
||||
div.options-container-item
|
||||
span.name ACTIVE
|
||||
span.name Active
|
||||
el-switch(v-model="orderFriendsGroup2" inactive-text="by name" active-text="by state")
|
||||
div.options-container-item
|
||||
span.name OFFLINE
|
||||
span.name Offline
|
||||
el-switch(v-model="orderFriendsGroup3" inactive-text="by name" active-text="by state")
|
||||
div.options-container
|
||||
span.header Discord Presence
|
||||
@@ -560,9 +560,6 @@ html
|
||||
div.options-container-item
|
||||
span.name Hide VR Devices
|
||||
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
|
||||
span.name Hide Private Worlds
|
||||
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-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
|
||||
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
|
||||
span.header Application
|
||||
div.options-container-item
|
||||
@@ -1206,6 +1191,107 @@ html
|
||||
div(style="display:flex")
|
||||
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
|
||||
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")
|
||||
@@ -1480,6 +1566,30 @@ html
|
||||
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
|
||||
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
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
||||
494
html/src/vr.js
494
html/src/vr.js
@@ -573,9 +573,21 @@ speechSynthesis.getVoices();
|
||||
currentTime: new Date().toJSON(),
|
||||
currentUserStatus: null,
|
||||
cpuUsage: 0,
|
||||
feeds: [],
|
||||
isGameRunning: false,
|
||||
lastLocation: '',
|
||||
lastFeedEntry: [],
|
||||
feedFilters: [],
|
||||
wristFeed: [],
|
||||
notyMap: [],
|
||||
devices: [],
|
||||
overlayNotificationsToggle: false,
|
||||
notificationTTSToggle: false,
|
||||
notificationTTSVoice: '0',
|
||||
hideDevicesToggle: false,
|
||||
isMinimalFeed: false,
|
||||
notificationPosition: 'topCenter',
|
||||
notificationTimeout: '3000',
|
||||
notificationTheme: 'relax'
|
||||
},
|
||||
computed: {},
|
||||
methods: {},
|
||||
@@ -600,6 +612,8 @@ speechSynthesis.getVoices();
|
||||
// FIXME: 어케 복구하냐 이건
|
||||
throw err;
|
||||
}).then((args) => {
|
||||
this.initConfigVars();
|
||||
this.initNotyMap();
|
||||
this.updateLoop();
|
||||
this.updateCpuUsageLoop();
|
||||
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 () {
|
||||
try {
|
||||
this.currentTime = new Date().toJSON();
|
||||
this.currentUserStatus = sharedRepository.getString('current_user_status');
|
||||
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) => {
|
||||
devices.forEach((device) => {
|
||||
device[2] = parseInt(device[2], 10);
|
||||
});
|
||||
this.devices = devices;
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.devices = '';
|
||||
}
|
||||
await this.updateSharedFeed();
|
||||
await this.updateSharedFeeds();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
@@ -645,185 +706,228 @@ speechSynthesis.getVoices();
|
||||
setTimeout(() => this.updateCpuUsageLoop(), 1000);
|
||||
};
|
||||
|
||||
$app.methods.updateSharedFeed = 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';
|
||||
}
|
||||
|
||||
$app.methods.updateSharedFeeds = async function () {
|
||||
var feeds = sharedRepository.getArray('feeds');
|
||||
if (feeds === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _feeds = this.feeds;
|
||||
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;
|
||||
}
|
||||
var notys = [];
|
||||
this.feeds.forEach((feed) => {
|
||||
if (((notificationOnlineOfflineFilter === "Friends") && (feed.isFriend)) ||
|
||||
((notificationOnlineOfflineFilter === "VIP") && (feed.isFavorite))) {
|
||||
if (feed.type === 'Online' ||
|
||||
feed.type === 'Offline') {
|
||||
if (!map[feed.displayName] ||
|
||||
map[feed.displayName] < feed.created_at) {
|
||||
map[feed.displayName] = feed.created_at;
|
||||
notys.push(feed);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (feed.type === 'Friend' ||
|
||||
feed.type === 'Unfriend') {
|
||||
if (!map[feed.displayName] ||
|
||||
map[feed.displayName] < feed.created_at) {
|
||||
map[feed.displayName] = feed.created_at;
|
||||
notys.push(feed);
|
||||
}
|
||||
}
|
||||
});
|
||||
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')) {
|
||||
var text = '';
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
text = `<strong>${noty.data}</strong> has joined`;
|
||||
break;
|
||||
case 'OnPlayerLeft':
|
||||
text = `<strong>${noty.data}</strong> has left`;
|
||||
break;
|
||||
case 'Online':
|
||||
text = `<strong>${noty.displayName}</strong> has logged in`;
|
||||
break;
|
||||
case 'Offline':
|
||||
text = `<strong>${noty.displayName}</strong> has logged out`;
|
||||
break;
|
||||
case 'invite':
|
||||
text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName}`;
|
||||
break;
|
||||
case 'requestInvite':
|
||||
text = `<strong>${noty.senderUsername}</strong> has requested an invite`;
|
||||
break;
|
||||
case 'friendRequest':
|
||||
text = `<strong>${noty.senderUsername}</strong> has sent you a friend request`;
|
||||
break;
|
||||
case 'Friend':
|
||||
text = `<strong>${noty.displayName}</strong> is now your friend`;
|
||||
break;
|
||||
case 'Unfriend':
|
||||
text = `<strong>${noty.displayName}</strong> has unfriended you`;
|
||||
break;
|
||||
}
|
||||
if (text) {
|
||||
new Noty({
|
||||
type: 'alert',
|
||||
theme: theme,
|
||||
timeout: notificationTimeout,
|
||||
layout: notificationPosition,
|
||||
text: text
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
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;
|
||||
case 'Friend':
|
||||
this.speak(`${noty.displayName} is now your friend`);
|
||||
break;
|
||||
case 'Unfriend':
|
||||
this.speak(`${noty.displayName} has unfriended you`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if ((this.lastFeedEntry !== undefined) &&
|
||||
(feeds[0].created_at === this.lastFeedEntry.created_at)) {
|
||||
return;
|
||||
}
|
||||
this.lastFeedEntry = feeds[0];
|
||||
|
||||
// OnPlayerJoining
|
||||
var bias = new Date(Date.now() - 120000).toJSON();
|
||||
for (i = 0; i < feeds.length; i++) {
|
||||
var ctx = feeds[i];
|
||||
if ((ctx.created_at < bias) || (ctx.type === 'Location')) {
|
||||
break;
|
||||
}
|
||||
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 (this.hidePrivateFromFeed) {
|
||||
for (var i = 0; i < feeds.length; i++) {
|
||||
var feed = feeds[i];
|
||||
if ((feed.type === 'GPS') && (feed.location[0] === 'private')) {
|
||||
feeds.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.appType === '1') {
|
||||
this.updateSharedFeedWrist(feeds);
|
||||
}
|
||||
if (this.appType === '2') {
|
||||
this.updateSharedFeedNoty(feeds);
|
||||
}
|
||||
};
|
||||
|
||||
$app.methods.updateSharedFeedWrist = async function (feeds) {
|
||||
var filter = this.feedFilters.wrist;
|
||||
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);
|
||||
}
|
||||
} 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 notyToPlay = [];
|
||||
filtered.forEach((feed) => {
|
||||
var displayName = '';
|
||||
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');
|
||||
}
|
||||
if ((displayName) && (!this.notyMap[displayName]) ||
|
||||
(this.notyMap[displayName] < feed.created_at)) {
|
||||
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 = '';
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
text = `<strong>${noty.data}</strong> has joined`;
|
||||
break;
|
||||
case 'OnPlayerLeft':
|
||||
text = `<strong>${noty.data}</strong> has left`;
|
||||
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':
|
||||
text = `<strong>${noty.displayName}</strong> has logged in`;
|
||||
break;
|
||||
case 'Offline':
|
||||
text = `<strong>${noty.displayName}</strong> has logged out`;
|
||||
break;
|
||||
case 'Status':
|
||||
text = `<strong>${noty.displayName}</strong> status is now <i>${noty.status[0].status}</i> ${noty.status[0].statusDescription}`;
|
||||
break;
|
||||
case 'invite':
|
||||
text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName}`;
|
||||
break;
|
||||
case 'requestInvite':
|
||||
text = `<strong>${noty.senderUsername}</strong> has requested an invite`;
|
||||
break;
|
||||
case 'friendRequest':
|
||||
text = `<strong>${noty.senderUsername}</strong> has sent you a friend request`;
|
||||
break;
|
||||
case 'Friend':
|
||||
text = `<strong>${noty.displayName}</strong> is now your friend`;
|
||||
break;
|
||||
case 'Unfriend':
|
||||
text = `<strong>${noty.displayName}</strong> has unfriended you`;
|
||||
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) {
|
||||
new Noty({
|
||||
type: 'alert',
|
||||
theme: this.notificationTheme,
|
||||
timeout: this.notificationTimeout,
|
||||
layout: this.notificationPosition,
|
||||
text: text
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
if (this.notificationTTSToggle) {
|
||||
switch (noty.type) {
|
||||
case 'OnPlayerJoined':
|
||||
this.speak(`${noty.data} has joined`);
|
||||
break;
|
||||
case 'OnPlayerLeft':
|
||||
this.speak(`${noty.data} has left`);
|
||||
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':
|
||||
this.speak(`${noty.displayName} has logged in`);
|
||||
break;
|
||||
case 'Offline':
|
||||
this.speak(`${noty.displayName} has logged out`);
|
||||
break;
|
||||
case 'Status':
|
||||
this.speak(`${noty.displayName} status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`);
|
||||
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;
|
||||
case 'Friend':
|
||||
this.speak(`${noty.displayName} is now your friend`);
|
||||
break;
|
||||
case 'Unfriend':
|
||||
this.speak(`${noty.displayName} has unfriended you`);
|
||||
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) {
|
||||
@@ -842,10 +946,40 @@ speechSynthesis.getVoices();
|
||||
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) {
|
||||
var tts = new SpeechSynthesisUtterance();
|
||||
var voices = speechSynthesis.getVoices();
|
||||
var voiceIndex = configRepository.getString('VRCX_notificationTTSVoice');
|
||||
var voiceIndex = this.notificationTTSVoice;
|
||||
tts.voice = voices[voiceIndex];
|
||||
tts.text = text;
|
||||
speechSynthesis.speak(tts);
|
||||
|
||||
@@ -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="vr.css")
|
||||
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-friend-list(ref="list" style="color:#aaa")
|
||||
template(v-if="isMinimalFeed === true")
|
||||
template(v-for="feed in feeds")
|
||||
template(v-if="isMinimalFeed")
|
||||
template(v-for="feed in wristFeed")
|
||||
.x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||
.detail
|
||||
span.extra
|
||||
@@ -47,6 +47,12 @@ html
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate('HH:MI') }}
|
||||
| ◀️ #[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 }")
|
||||
.detail
|
||||
span.extra
|
||||
@@ -88,7 +94,7 @@ html
|
||||
span.time {{ feed.created_at | formatDate('HH:MI') }}
|
||||
| 🤝 #[span.name(v-text="feed.displayName")] {{ feed.previousTrustLevel }} #[i.el-icon-right] {{ feed.trustLevel }}
|
||||
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 }")
|
||||
.detail
|
||||
span.extra
|
||||
@@ -119,6 +125,11 @@ html
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate('HH:MI') }}
|
||||
| #[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 }")
|
||||
.detail
|
||||
span.extra
|
||||
|
||||
@@ -274,3 +274,19 @@ i.x-user-status.joinme {
|
||||
i.x-user-status.busy {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user