diff --git a/html/src/app.js b/html/src/app.js
index 0907d3ca..3617ac0a 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -12579,7 +12579,8 @@ speechSynthesis.getVoices();
type,
groupKey: favorite.$groupKey,
ref: null,
- name: ''
+ name: '',
+ $selected: false
};
this.favoriteObjects.set(objectId, ctx);
if (type === 'friend') {
@@ -14444,9 +14445,8 @@ speechSynthesis.getVoices();
$app.methods.updateOpenVR = function () {
if (
this.openVR &&
- !this.isGameNoVR &&
this.isSteamVRRunning &&
- (this.isGameRunning || this.openVRAlways)
+ ((this.isGameRunning && !this.isGameNoVR) || this.openVRAlways)
) {
var hmdOverlay = false;
if (
@@ -24427,6 +24427,58 @@ speechSynthesis.getVoices();
this.avatarRemoteDatabaseProvider = provider;
};
+ // #endregion
+ // #region | App: bulk unfavorite
+
+ $app.data.bulkUnfavoriteMode = false;
+
+ $app.methods.showBulkUnfavoriteSelectionConfirm = function () {
+ var elementsTicked = [];
+ // check favorites type
+ for (var ctx of this.favoriteFriends) {
+ if (ctx.$selected) {
+ elementsTicked.push(ctx.id);
+ }
+ }
+ for (var ctx of this.favoriteWorlds) {
+ if (ctx.$selected) {
+ elementsTicked.push(ctx.id);
+ }
+ }
+ for (var ctx of this.favoriteAvatars) {
+ if (ctx.$selected) {
+ elementsTicked.push(ctx.id);
+ }
+ }
+ if (elementsTicked.length === 0) {
+ return;
+ }
+ this.$confirm(
+ `Are you sure you want to unfavorite ${elementsTicked.length} favorites?
+ This action cannot be undone.`,
+ `Delete ${elementsTicked.length} favorites?`,
+ {
+ confirmButtonText: 'Confirm',
+ cancelButtonText: 'Cancel',
+ type: 'info',
+ callback: (action) => {
+ if (action === 'confirm') {
+ this.bulkUnfavoriteSelection(elementsTicked);
+ }
+ }
+ }
+ );
+ };
+
+ $app.methods.bulkUnfavoriteSelection = function (elementsTicked) {
+ for (var id of elementsTicked) {
+ API.deleteFavorite({
+ objectId: id
+ });
+ }
+ this.bulkUnfavoriteMode = false;
+ };
+
// #endregion
// #region | App: local world favorites
diff --git a/html/src/app.scss b/html/src/app.scss
index 48c913d9..e03db206 100644
--- a/html/src/app.scss
+++ b/html/src/app.scss
@@ -741,3 +741,18 @@ i.x-user-status.busy {
.zero-margin-tabs .el-tabs__header {
margin-bottom: 0;
}
+
+.x-friend-item .el-checkbox__inner,
+.el-table__row .el-checkbox__inner {
+ width: 28px;
+ height: 28px;
+ border-radius: 4px;
+}
+
+.x-friend-item .el-checkbox__inner::after,
+.el-table__row .el-checkbox__inner::after {
+ width: 8px;
+ height: 14px;
+ left: 8px;
+ top: 2px;
+}
diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json
index beaf6b02..d45b5c82 100644
--- a/html/src/localization/strings/en.json
+++ b/html/src/localization/strings/en.json
@@ -92,6 +92,8 @@
"avatars": {
"header": "Avatars"
},
+ "bulk_unfavorite_mode": "Bulk Unfavorite Mode",
+ "bulk_unfavorite_selection": "Bulk Unfavorite Selection",
"refresh_tooltip": "Refresh all favorites",
"export": "Export",
"import": "Import",
diff --git a/html/src/mixins/tabs/favorites.pug b/html/src/mixins/tabs/favorites.pug
index b02ad143..de816332 100644
--- a/html/src/mixins/tabs/favorites.pug
+++ b/html/src/mixins/tabs/favorites.pug
@@ -1,7 +1,13 @@
mixin favoritesTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'")
- el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips")
- el-button(type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorites(); getLocalWorldFavorites()" size="small" icon="el-icon-refresh" circle style="position:relative;float:right;z-index:1")
+ div(style="font-size:13px;position:absolute;right:0;z-index:1")
+ div(v-if="bulkUnfavoriteMode" style="display:inline-block;margin-right:10px")
+ el-button(size="small" @click="showBulkUnfavoriteSelectionConfirm") {{ $t('view.favorite.bulk_unfavorite_selection') }}
+ div(style="display:inline-block;margin-right:10px")
+ span.name {{ $t('view.favorite.bulk_unfavorite_mode') }}
+ el-switch(v-model="bulkUnfavoriteMode" style="margin-left:5px")
+ el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips")
+ el-button(type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorites(); getLocalWorldFavorites()" size="small" icon="el-icon-refresh" circle)
el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading" style="height:100%")
el-tab-pane(:label="$t('view.favorite.friends.header')")
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '0'" style="border:0")
@@ -25,6 +31,10 @@ mixin favoritesTab()
span.name(v-text="favorite.ref.displayName" :style="{'color':favorite.ref.$userColour}")
location.extra(v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :traveling="favorite.ref.travelingToLocation" :link="false")
span(v-else v-text="favorite.ref.statusDescription")
+ template(v-if="bulkUnfavoriteMode")
+ el-button(type="text" size="mini" @click.stop style="margin-left:5px")
+ el-checkbox(v-model="favorite.$selected")
+ template(v-else-if="favorite.ref")
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
@@ -65,6 +75,10 @@ mixin favoritesTab()
span.name(v-text="favorite.ref.name")
span.extra(v-if="favorite.ref.occupants") {{ favorite.ref.authorName }} ({{ favorite.ref.occupants }})
span.extra(v-else v-text="favorite.ref.authorName")
+ template(v-if="bulkUnfavoriteMode")
+ el-button(type="text" size="mini" @click.stop style="margin-left:5px")
+ el-checkbox(v-model="favorite.$selected")
+ template(v-else-if="favorite.ref")
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
@@ -122,6 +136,10 @@ mixin favoritesTab()
.detail
span.name(v-text="favorite.ref.name")
span.extra(v-text="favorite.ref.authorName")
+ template(v-if="bulkUnfavoriteMode")
+ el-button(type="text" size="mini" @click.stop style="margin-left:5px")
+ el-checkbox(v-model="favorite.$selected")
+ template(v-else-if="favorite.ref")
el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
diff --git a/html/src/theme.material3.scss b/html/src/theme.material3.scss
index 0527cb76..491dbfc2 100644
--- a/html/src/theme.material3.scss
+++ b/html/src/theme.material3.scss
@@ -1865,8 +1865,11 @@ i.x-user-status {
.el-checkbox__inner::after,
.el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
- all: unset;
+ color: unset;
+ background-color: unset;
+ border: unset;
}
+
.el-checkbox__inner::after {
all: unset;
height: 20px;