feat: add option to sort favorites world by player count (#674)

This commit is contained in:
pa
2026-03-16 13:37:54 +09:00
parent 9bf380f2fc
commit 2a5039b6c9
5 changed files with 50 additions and 17 deletions

View File

@@ -744,6 +744,7 @@
"sort_favorite_by": "Sort Favorites by",
"sort_favorite_by_name": "Name",
"sort_favorite_by_date": "Date",
"sort_favorite_by_players": "Players",
"sort_instance_users_by": "Sort Instance Users by",
"sort_instance_users_by_time": "Time",
"sort_instance_users_by_alphabet": "Alphabetical",

View File

@@ -2,7 +2,7 @@
<div class="x-container">
<div class="flex flex-col h-full min-h-0 pb-0">
<FavoritesToolbar
:sort-favorites="sortFavorites"
:sort-value="sortFavorites ? 'date' : 'name'"
v-model:search-query="avatarFavoriteSearch"
:search-placeholder="t('view.favorite.avatars.search')"
v-model:toolbar-menu-open="avatarToolbarMenuOpen"
@@ -12,7 +12,7 @@
v-model:card-spacing-value="avatarCardSpacingValue"
:card-spacing-percent="avatarCardSpacingPercent"
:card-spacing-slider="avatarCardSpacingSlider"
@update:sort-favorites="handleSortFavoritesChange"
@update:sort-value="handleSortFavoritesChange"
@search="searchAvatarFavorites"
@import="handleAvatarImportClick"
@export="handleAvatarExportClick" />
@@ -606,7 +606,7 @@
* @param value
*/
function handleSortFavoritesChange(value) {
const next = Boolean(value);
const next = value === 'date';
if (next !== sortFavorites.value) {
setSortFavorites();
}

View File

@@ -2,7 +2,7 @@
<div class="x-container">
<div class="flex flex-col h-full min-h-0 pb-0">
<FavoritesToolbar
:sort-favorites="sortFavorites"
:sort-value="sortFavorites ? 'date' : 'name'"
v-model:search-query="friendFavoriteSearch"
:search-placeholder="t('view.favorite.worlds.search')"
v-model:toolbar-menu-open="friendToolbarMenuOpen"
@@ -12,7 +12,7 @@
v-model:card-spacing-value="friendCardSpacingValue"
:card-spacing-percent="friendCardSpacingPercent"
:card-spacing-slider="friendCardSpacingSlider"
@update:sort-favorites="handleSortFavoritesChange"
@update:sort-value="handleSortFavoritesChange"
@search="searchFriendFavorites"
@import="handleFriendImportClick"
@export="handleFriendExportClick" />
@@ -490,7 +490,7 @@
* @param value
*/
function handleSortFavoritesChange(value) {
const next = Boolean(value);
const next = value === 'date';
if (next !== sortFavorites.value) {
setSortFavorites();
}

View File

@@ -2,7 +2,8 @@
<div class="x-container">
<div class="flex flex-col h-full min-h-0 pb-0">
<FavoritesToolbar
:sort-favorites="sortFavorites"
:sort-value="worldSortValue"
:extra-sort-options="worldExtraSortOptions"
v-model:search-query="worldFavoriteSearch"
:search-placeholder="t('view.favorite.worlds.search')"
v-model:toolbar-menu-open="worldToolbarMenuOpen"
@@ -12,7 +13,7 @@
v-model:card-spacing-value="worldCardSpacingValue"
:card-spacing-percent="worldCardSpacingPercent"
:card-spacing-slider="worldCardSpacingSlider"
@update:sort-favorites="handleSortFavoritesChange"
@update:sort-value="handleSortValueChange"
@search="searchWorldFavorites"
@import="handleWorldImportClick"
@export="handleWorldExportClick" />
@@ -500,6 +501,16 @@
const refreshCancelToken = ref(null);
const worldEditMode = ref(false);
const worldToolbarMenuOpen = ref(false);
const worldSortMode = ref('none');
const worldExtraSortOptions = computed(() => [
{ value: 'players', label: t('view.settings.appearance.appearance.sort_favorite_by_players') }
]);
const worldSortValue = computed(() => {
if (worldSortMode.value === 'players') return 'players';
return sortFavorites.value ? 'date' : 'name';
});
const {
activeGroupMenu,
@@ -589,14 +600,22 @@
if (!activeRemoteGroup.value) {
return [];
}
return groupedWorldFavorites.value[activeRemoteGroup.value.key] || [];
const list = groupedWorldFavorites.value[activeRemoteGroup.value.key] || [];
if (worldSortMode.value === 'players') {
return list.toSorted((a, b) => (b.ref?.occupants ?? 0) - (a.ref?.occupants ?? 0));
}
return list;
});
const currentLocalFavorites = computed(() => {
if (!activeLocalGroupName.value) {
return [];
}
return localWorldFavorites.value[activeLocalGroupName.value] || [];
const list = localWorldFavorites.value[activeLocalGroupName.value] || [];
if (worldSortMode.value === 'players') {
return list.toSorted((a, b) => (b.occupants ?? 0) - (a.occupants ?? 0));
}
return list;
});
const localFavoritesViewportRef = ref(null);
@@ -683,8 +702,13 @@
*
* @param value
*/
function handleSortFavoritesChange(value) {
const next = Boolean(value);
function handleSortValueChange(value) {
if (value === 'players') {
worldSortMode.value = 'players';
return;
}
worldSortMode.value = 'none';
const next = value === 'date';
if (next !== sortFavorites.value) {
setSortFavorites();
}

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex items-center justify-between gap-3 mb-3 flex-wrap">
<div>
<Select :model-value="sortFavorites" @update:modelValue="$emit('update:sortFavorites', $event)">
<Select :model-value="sortValue" @update:modelValue="$emit('update:sortValue', $event)">
<SelectTrigger size="sm" class="min-w-[200px]">
<span class="flex items-center gap-2">
<ArrowUpDown class="h-4 w-4" />
@@ -11,15 +11,22 @@
<SelectContent>
<SelectGroup>
<SelectItem
:value="false"
value="name"
:text-value="t('view.settings.appearance.appearance.sort_favorite_by_name')">
{{ t('view.settings.appearance.appearance.sort_favorite_by_name') }}
</SelectItem>
<SelectItem
:value="true"
value="date"
:text-value="t('view.settings.appearance.appearance.sort_favorite_by_date')">
{{ t('view.settings.appearance.appearance.sort_favorite_by_date') }}
</SelectItem>
<SelectItem
v-for="option in extraSortOptions"
:key="option.value"
:value="option.value"
:text-value="option.label">
{{ option.label }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
@@ -91,7 +98,8 @@
import { useI18n } from 'vue-i18n';
defineProps({
sortFavorites: { type: Boolean, default: false },
sortValue: { type: String, default: 'name' },
extraSortOptions: { type: Array, default: () => [] },
searchQuery: { type: String, default: '' },
searchPlaceholder: { type: String, default: '' },
toolbarMenuOpen: { type: Boolean, default: false },
@@ -104,7 +112,7 @@
});
defineEmits([
'update:sortFavorites',
'update:sortValue',
'update:searchQuery',
'update:toolbarMenuOpen',
'update:cardScaleValue',