diff --git a/src/localization/en.json b/src/localization/en.json
index 08bfd0a1..d3c52111 100644
--- a/src/localization/en.json
+++ b/src/localization/en.json
@@ -315,6 +315,9 @@
"favorite": {
"worlds": {
"search": "Search",
+ "search_by_tag": "Search by Tag",
+ "search_mode_name": "Name",
+ "search_mode_tag": "Tag",
"vrchat_favorites": "VRChat Favorites",
"local_favorites": "Local Favorites",
"new_group": "New Group",
diff --git a/src/views/Favorites/FavoritesWorld.vue b/src/views/Favorites/FavoritesWorld.vue
index 0fe6bf3c..075643d0 100644
--- a/src/views/Favorites/FavoritesWorld.vue
+++ b/src/views/Favorites/FavoritesWorld.vue
@@ -5,7 +5,9 @@
:sort-value="worldSortValue"
:extra-sort-options="worldExtraSortOptions"
v-model:search-query="worldFavoriteSearch"
- :search-placeholder="t('view.favorite.worlds.search')"
+ :search-placeholder="worldSearchPlaceholder"
+ v-model:search-mode="worldSearchMode"
+ :search-mode-visible="true"
v-model:toolbar-menu-open="worldToolbarMenuOpen"
v-model:card-scale-value="worldCardScaleValue"
:card-scale-percent="worldCardScalePercent"
@@ -502,6 +504,13 @@
const worldEditMode = ref(false);
const worldToolbarMenuOpen = ref(false);
const worldSortMode = ref('none');
+ const worldSearchMode = ref('name');
+
+ const worldSearchPlaceholder = computed(() =>
+ worldSearchMode.value === 'tag'
+ ? t('view.favorite.worlds.search_by_tag')
+ : t('view.favorite.worlds.search')
+ );
const worldExtraSortOptions = computed(() => [
{ value: 'players', label: t('view.settings.appearance.appearance.sort_favorite_by_players') }
@@ -745,6 +754,12 @@
}
});
+ watch(worldSearchMode, () => {
+ if (isSearchActive.value) {
+ doSearchWorldFavorites();
+ }
+ });
+
watch([currentLocalFavorites, worldCardScale, worldCardSpacing, activeLocalGroupName], () => {
nextTick(() => {
localVirtualizer.value?.measure?.();
@@ -1000,16 +1015,25 @@
*
* @param worldFavoriteSearch
*/
- function doSearchWorldFavorites(worldFavoriteSearch) {
- const search = worldFavoriteSearch.trim().toLowerCase();
+ function doSearchWorldFavorites(searchInput) {
+ const search = (searchInput ?? worldFavoriteSearch.value).trim().toLowerCase();
if (search.length < 3) {
worldFavoriteSearchResults.value = [];
return;
}
+ const isTagMode = worldSearchMode.value === 'tag';
const filtered = searchableWorldEntries.value.filter((ref) => {
if (!ref || typeof ref.id === 'undefined' || typeof ref.name === 'undefined') {
return false;
}
+ if (isTagMode) {
+ if (Array.isArray(ref.tags)) {
+ return ref.tags.some(
+ (tag) => tag.startsWith('author_tag_') && tag.substring(11).toLowerCase().includes(search)
+ );
+ }
+ return false;
+ }
const authorName = ref.authorName || '';
return ref.name.toLowerCase().includes(search) || authorName.toLowerCase().includes(search);
});
diff --git a/src/views/Favorites/components/FavoritesToolbar.vue b/src/views/Favorites/components/FavoritesToolbar.vue
index 29cccdca..c7252960 100644
--- a/src/views/Favorites/components/FavoritesToolbar.vue
+++ b/src/views/Favorites/components/FavoritesToolbar.vue
@@ -37,7 +37,24 @@
class="flex-1"
:placeholder="searchPlaceholder"
@update:modelValue="$emit('update:searchQuery', $event)"
- @input="$emit('search')" />
+ @input="$emit('search')">
+
+
+
+ {{ t('view.favorite.worlds.search_mode_name') }}
+
+
+ {{ t('view.favorite.worlds.search_mode_tag') }}
+
+
+
+
@@ -91,6 +108,7 @@
DropdownMenuSeparator,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
+ import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { ArrowUpDown, Ellipsis } from 'lucide-vue-next';
import { Button } from '@/components/ui/button';
import { InputGroupSearch } from '@/components/ui/input-group';
@@ -102,6 +120,8 @@
extraSortOptions: { type: Array, default: () => [] },
searchQuery: { type: String, default: '' },
searchPlaceholder: { type: String, default: '' },
+ searchMode: { type: String, default: 'name' },
+ searchModeVisible: { type: Boolean, default: false },
toolbarMenuOpen: { type: Boolean, default: false },
cardScaleValue: { type: Array, default: () => [50] },
cardScalePercent: { type: Number, default: 100 },
@@ -114,6 +134,7 @@
defineEmits([
'update:sortValue',
'update:searchQuery',
+ 'update:searchMode',
'update:toolbarMenuOpen',
'update:cardScaleValue',
'update:cardSpacingValue',