mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 06:56:04 +02:00
add local favorites friend
This commit is contained in:
@@ -30,6 +30,27 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="favoriteDialog.type === 'friend'" style="margin-top: 20px">
|
||||||
|
<span style="display: block; text-align: center">{{ t('dialog.favorite.local_favorites') }}</span>
|
||||||
|
<template v-for="group in localFriendFavoriteGroups" :key="group">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
v-if="hasLocalFriendFavorite(favoriteDialog.objectId, group)"
|
||||||
|
style="width: 100%; white-space: initial"
|
||||||
|
class="my-1"
|
||||||
|
@click="removeLocalFriendFavorite(favoriteDialog.objectId, group)">
|
||||||
|
<Check />{{ group }} ({{ localFriendFavGroupLength(group) }})
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
v-else
|
||||||
|
style="width: 100%; white-space: initial"
|
||||||
|
class="my-1"
|
||||||
|
@click="addLocalFriendFavorite(favoriteDialog.objectId, group)">
|
||||||
|
{{ group }} ({{ localFriendFavGroupLength(group) }})
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
<div v-if="favoriteDialog.type === 'world'" style="margin-top: 20px">
|
<div v-if="favoriteDialog.type === 'world'" style="margin-top: 20px">
|
||||||
<span style="display: block; text-align: center">{{ t('dialog.favorite.local_favorites') }}</span>
|
<span style="display: block; text-align: center">{{ t('dialog.favorite.local_favorites') }}</span>
|
||||||
<template v-for="group in localWorldFavoriteGroups" :key="group">
|
<template v-for="group in localWorldFavoriteGroups" :key="group">
|
||||||
@@ -99,7 +120,8 @@
|
|||||||
favoriteWorldGroups,
|
favoriteWorldGroups,
|
||||||
favoriteDialog,
|
favoriteDialog,
|
||||||
localWorldFavoriteGroups,
|
localWorldFavoriteGroups,
|
||||||
localAvatarFavoriteGroups
|
localAvatarFavoriteGroups,
|
||||||
|
localFriendFavoriteGroups
|
||||||
} = storeToRefs(favoriteStore);
|
} = storeToRefs(favoriteStore);
|
||||||
const {
|
const {
|
||||||
localWorldFavGroupLength,
|
localWorldFavGroupLength,
|
||||||
@@ -110,7 +132,11 @@
|
|||||||
localAvatarFavGroupLength,
|
localAvatarFavGroupLength,
|
||||||
removeLocalAvatarFavorite,
|
removeLocalAvatarFavorite,
|
||||||
removeLocalWorldFavorite,
|
removeLocalWorldFavorite,
|
||||||
deleteFavoriteNoConfirm
|
deleteFavoriteNoConfirm,
|
||||||
|
localFriendFavGroupLength,
|
||||||
|
addLocalFriendFavorite,
|
||||||
|
hasLocalFriendFavorite,
|
||||||
|
removeLocalFriendFavorite
|
||||||
} = favoriteStore;
|
} = favoriteStore;
|
||||||
const { isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore());
|
const { isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore());
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { avatarFavorites } from './database/avatarFavorites.js';
|
import { avatarFavorites } from './database/avatarFavorites.js';
|
||||||
import { feed } from './database/feed.js';
|
import { feed } from './database/feed.js';
|
||||||
|
import { friendFavorites } from './database/friendFavorites.js';
|
||||||
import { friendLogCurrent } from './database/friendLogCurrent.js';
|
import { friendLogCurrent } from './database/friendLogCurrent.js';
|
||||||
import { friendLogHistory } from './database/friendLogHistory.js';
|
import { friendLogHistory } from './database/friendLogHistory.js';
|
||||||
import { gameLog } from './database/gameLog.js';
|
import { gameLog } from './database/gameLog.js';
|
||||||
@@ -30,6 +31,7 @@ const database = {
|
|||||||
...friendLogCurrent,
|
...friendLogCurrent,
|
||||||
...memos,
|
...memos,
|
||||||
...avatarFavorites,
|
...avatarFavorites,
|
||||||
|
...friendFavorites,
|
||||||
...worldFavorites,
|
...worldFavorites,
|
||||||
...tableAlter,
|
...tableAlter,
|
||||||
...tableFixes,
|
...tableFixes,
|
||||||
@@ -126,6 +128,9 @@ const database = {
|
|||||||
await sqliteService.executeNonQuery(
|
await sqliteService.executeNonQuery(
|
||||||
`CREATE TABLE IF NOT EXISTS favorite_avatar (id INTEGER PRIMARY KEY, created_at TEXT, avatar_id TEXT, group_name TEXT)`
|
`CREATE TABLE IF NOT EXISTS favorite_avatar (id INTEGER PRIMARY KEY, created_at TEXT, avatar_id TEXT, group_name TEXT)`
|
||||||
);
|
);
|
||||||
|
await sqliteService.executeNonQuery(
|
||||||
|
`CREATE TABLE IF NOT EXISTS favorite_friend (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, group_name TEXT)`
|
||||||
|
);
|
||||||
await sqliteService.executeNonQuery(
|
await sqliteService.executeNonQuery(
|
||||||
`CREATE TABLE IF NOT EXISTS memos (user_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)`
|
`CREATE TABLE IF NOT EXISTS memos (user_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import sqliteService from '../sqlite.js';
|
||||||
|
|
||||||
|
const friendFavorites = {
|
||||||
|
addFriendToLocalFavorites(userId, groupName) {
|
||||||
|
sqliteService.executeNonQuery(
|
||||||
|
'INSERT OR REPLACE INTO favorite_friend (user_id, group_name, created_at) VALUES (@user_id, @group_name, @created_at)',
|
||||||
|
{
|
||||||
|
'@user_id': userId,
|
||||||
|
'@group_name': groupName,
|
||||||
|
'@created_at': new Date().toJSON()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFriendFromLocalFavorites(userId, groupName) {
|
||||||
|
sqliteService.executeNonQuery(
|
||||||
|
`DELETE FROM favorite_friend WHERE user_id = @user_id AND group_name = @group_name`,
|
||||||
|
{
|
||||||
|
'@user_id': userId,
|
||||||
|
'@group_name': groupName
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renameFriendFavoriteGroup(newGroupName, groupName) {
|
||||||
|
sqliteService.executeNonQuery(
|
||||||
|
`UPDATE favorite_friend SET group_name = @new_group_name WHERE group_name = @group_name`,
|
||||||
|
{
|
||||||
|
'@new_group_name': newGroupName,
|
||||||
|
'@group_name': groupName
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteFriendFavoriteGroup(groupName) {
|
||||||
|
sqliteService.executeNonQuery(
|
||||||
|
`DELETE FROM favorite_friend WHERE group_name = @group_name`,
|
||||||
|
{
|
||||||
|
'@group_name': groupName
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getFriendFavorites() {
|
||||||
|
const data = [];
|
||||||
|
await sqliteService.execute((dbRow) => {
|
||||||
|
const row = {
|
||||||
|
created_at: dbRow[1],
|
||||||
|
userId: dbRow[2],
|
||||||
|
groupName: dbRow[3]
|
||||||
|
};
|
||||||
|
data.push(row);
|
||||||
|
}, 'SELECT * FROM favorite_friend');
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { friendFavorites };
|
||||||
+179
-1
@@ -81,6 +81,8 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
|
|
||||||
const localAvatarFavorites = reactive({});
|
const localAvatarFavorites = reactive({});
|
||||||
|
|
||||||
|
const localFriendFavorites = reactive({});
|
||||||
|
|
||||||
const selectedFavoriteFriends = ref([]);
|
const selectedFavoriteFriends = ref([]);
|
||||||
const selectedFavoriteWorlds = ref([]);
|
const selectedFavoriteWorlds = ref([]);
|
||||||
const selectedFavoriteAvatars = ref([]);
|
const selectedFavoriteAvatars = ref([]);
|
||||||
@@ -189,6 +191,18 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
return favoriteGroup.length;
|
return favoriteGroup.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const localFriendFavoriteGroups = computed(() =>
|
||||||
|
Object.keys(localFriendFavorites).sort()
|
||||||
|
);
|
||||||
|
|
||||||
|
const localFriendFavGroupLength = computed(() => (group) => {
|
||||||
|
const favoriteGroup = localFriendFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return favoriteGroup.length;
|
||||||
|
});
|
||||||
|
|
||||||
function syncFavoriteSelection(list, selectionRef) {
|
function syncFavoriteSelection(list, selectionRef) {
|
||||||
if (!Array.isArray(list)) {
|
if (!Array.isArray(list)) {
|
||||||
selectionRef.value = [];
|
selectionRef.value = [];
|
||||||
@@ -1514,6 +1528,157 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
sortLocalWorldFavorites();
|
sortLocalWorldFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} userId
|
||||||
|
* @param {string} group
|
||||||
|
*/
|
||||||
|
function addLocalFriendFavorite(userId, group) {
|
||||||
|
if (hasLocalFriendFavorite(userId, group)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!localFriendFavorites[group]) {
|
||||||
|
localFriendFavorites[group] = [];
|
||||||
|
}
|
||||||
|
localFriendFavorites[group].unshift(userId);
|
||||||
|
database.addFriendToLocalFavorites(userId, group);
|
||||||
|
if (
|
||||||
|
favoriteDialog.value.visible &&
|
||||||
|
favoriteDialog.value.objectId === userId
|
||||||
|
) {
|
||||||
|
updateFavoriteDialog(userId);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
generalSettingsStore.localFavoriteFriendsGroups.includes(
|
||||||
|
`local:${group}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
friendStore.updateLocalFavoriteFriends();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} userId
|
||||||
|
* @param {string} group
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function hasLocalFriendFavorite(userId, group) {
|
||||||
|
const favoriteGroup = localFriendFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return favoriteGroup.includes(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} userId
|
||||||
|
* @param {string} group
|
||||||
|
*/
|
||||||
|
function removeLocalFriendFavorite(userId, group) {
|
||||||
|
const favoriteGroup = localFriendFavorites[group];
|
||||||
|
if (favoriteGroup) {
|
||||||
|
const idx = favoriteGroup.indexOf(userId);
|
||||||
|
if (idx !== -1) {
|
||||||
|
favoriteGroup.splice(idx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
database.removeFriendFromLocalFavorites(userId, group);
|
||||||
|
if (
|
||||||
|
favoriteDialog.value.visible &&
|
||||||
|
favoriteDialog.value.objectId === userId
|
||||||
|
) {
|
||||||
|
updateFavoriteDialog(userId);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
generalSettingsStore.localFavoriteFriendsGroups.includes(
|
||||||
|
`local:${group}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
friendStore.updateLocalFavoriteFriends();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} group
|
||||||
|
*/
|
||||||
|
function deleteLocalFriendFavoriteGroup(group) {
|
||||||
|
delete localFriendFavorites[group];
|
||||||
|
database.deleteFriendFavoriteGroup(group);
|
||||||
|
if (
|
||||||
|
generalSettingsStore.localFavoriteFriendsGroups.includes(
|
||||||
|
`local:${group}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
friendStore.updateLocalFavoriteFriends();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} newName
|
||||||
|
* @param {string} group
|
||||||
|
*/
|
||||||
|
function renameLocalFriendFavoriteGroup(newName, group) {
|
||||||
|
if (localFriendFavoriteGroups.value.includes(newName)) {
|
||||||
|
toast.error(
|
||||||
|
t('prompt.local_favorite_group_rename.message.error', {
|
||||||
|
name: newName
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localFriendFavorites[newName] = localFriendFavorites[group];
|
||||||
|
delete localFriendFavorites[group];
|
||||||
|
database.renameFriendFavoriteGroup(newName, group);
|
||||||
|
const oldKey = `local:${group}`;
|
||||||
|
const idx =
|
||||||
|
generalSettingsStore.localFavoriteFriendsGroups.indexOf(oldKey);
|
||||||
|
if (idx !== -1) {
|
||||||
|
const updated = [
|
||||||
|
...generalSettingsStore.localFavoriteFriendsGroups
|
||||||
|
];
|
||||||
|
updated[idx] = `local:${newName}`;
|
||||||
|
generalSettingsStore.setLocalFavoriteFriendsGroups(updated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} group
|
||||||
|
*/
|
||||||
|
function newLocalFriendFavoriteGroup(group) {
|
||||||
|
if (localFriendFavoriteGroups.value.includes(group)) {
|
||||||
|
toast.error(
|
||||||
|
t('prompt.new_local_favorite_group.message.error', {
|
||||||
|
name: group
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!localFriendFavorites[group]) {
|
||||||
|
localFriendFavorites[group] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function getLocalFriendFavorites() {
|
||||||
|
const localFavorites = Object.create(null);
|
||||||
|
|
||||||
|
const favorites = await database.getFriendFavorites();
|
||||||
|
for (let i = 0; i < favorites.length; ++i) {
|
||||||
|
const favorite = favorites[i];
|
||||||
|
if (!localFavorites[favorite.groupName]) {
|
||||||
|
localFavorites[favorite.groupName] = [];
|
||||||
|
}
|
||||||
|
localFavorites[favorite.groupName].unshift(favorite.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(localFavorites).length === 0) {
|
||||||
|
localFavorites.Favorites = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceReactiveObject(localFriendFavorites, localFavorites);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} objectId
|
* @param {string} objectId
|
||||||
@@ -1545,6 +1710,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
|
|
||||||
async function saveSortFavoritesOption() {
|
async function saveSortFavoritesOption() {
|
||||||
getLocalWorldFavorites();
|
getLocalWorldFavorites();
|
||||||
|
getLocalFriendFavorites();
|
||||||
appearanceSettingsStore.setSortFavorites();
|
appearanceSettingsStore.setSortFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1552,6 +1718,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
refreshFavorites();
|
refreshFavorites();
|
||||||
getLocalWorldFavorites();
|
getLocalWorldFavorites();
|
||||||
getLocalAvatarFavorites();
|
getLocalAvatarFavorites();
|
||||||
|
getLocalFriendFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareByFavoriteSortOrder(a, b) {
|
function compareByFavoriteSortOrder(a, b) {
|
||||||
@@ -1588,6 +1755,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
localWorldFavoritesList,
|
localWorldFavoritesList,
|
||||||
|
|
||||||
localWorldFavoriteGroups,
|
localWorldFavoriteGroups,
|
||||||
|
localFriendFavorites,
|
||||||
|
localFriendFavoriteGroups,
|
||||||
|
|
||||||
|
localFriendFavGroupLength,
|
||||||
groupedByGroupKeyFavoriteFriends,
|
groupedByGroupKeyFavoriteFriends,
|
||||||
selectedFavoriteFriends,
|
selectedFavoriteFriends,
|
||||||
selectedFavoriteWorlds,
|
selectedFavoriteWorlds,
|
||||||
@@ -1632,6 +1803,13 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
|||||||
getCachedFavoritesByObjectId,
|
getCachedFavoritesByObjectId,
|
||||||
checkInvalidLocalAvatars,
|
checkInvalidLocalAvatars,
|
||||||
removeInvalidLocalAvatars,
|
removeInvalidLocalAvatars,
|
||||||
getCachedFavoriteGroupsByTypeName
|
getCachedFavoriteGroupsByTypeName,
|
||||||
|
addLocalFriendFavorite,
|
||||||
|
hasLocalFriendFavorite,
|
||||||
|
removeLocalFriendFavorite,
|
||||||
|
deleteLocalFriendFavoriteGroup,
|
||||||
|
renameLocalFriendFavoriteGroup,
|
||||||
|
newLocalFriendFavoriteGroup,
|
||||||
|
getLocalFriendFavorites
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -317,6 +317,17 @@ export const useFriendStore = defineStore('Friend', () => {
|
|||||||
localFavoriteFriends.add(ref.favoriteId);
|
localFavoriteFriends.add(ref.favoriteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const selectedKey of generalSettingsStore.localFavoriteFriendsGroups) {
|
||||||
|
if (selectedKey.startsWith('local:')) {
|
||||||
|
const groupName = selectedKey.slice(6);
|
||||||
|
const userIds = favoriteStore.localFriendFavorites[groupName];
|
||||||
|
if (userIds) {
|
||||||
|
for (let i = 0; i < userIds.length; ++i) {
|
||||||
|
localFavoriteFriends.add(userIds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
updateSidebarFavorites();
|
updateSidebarFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,86 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="group-section">
|
||||||
|
<div class="group-section__header">
|
||||||
|
<span>{{ t('view.favorite.worlds.local_favorites') }}</span>
|
||||||
|
<Button
|
||||||
|
class="rounded-full"
|
||||||
|
size="icon-sm"
|
||||||
|
variant="ghost"
|
||||||
|
@click.stop="getLocalFriendFavorites"
|
||||||
|
><RefreshCcw />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="group-section__list">
|
||||||
|
<template v-if="localFriendFavoriteGroups.length">
|
||||||
|
<div
|
||||||
|
v-for="group in localFriendFavoriteGroups"
|
||||||
|
:key="group"
|
||||||
|
:class="[
|
||||||
|
'group-item',
|
||||||
|
{ 'is-active': !hasSearchInput && isGroupActive('local', group) }
|
||||||
|
]"
|
||||||
|
@click="handleGroupClick('local', group)">
|
||||||
|
<div class="group-item__top">
|
||||||
|
<span class="group-item__name">{{ group }}</span>
|
||||||
|
<div class="group-item__right">
|
||||||
|
<span class="group-item__count">{{
|
||||||
|
localFriendFavGroupLength(group)
|
||||||
|
}}</span>
|
||||||
|
<div class="group-item__bottom">
|
||||||
|
<DropdownMenu
|
||||||
|
:open="activeGroupMenu === localGroupMenuKey(group)"
|
||||||
|
@update:open="
|
||||||
|
handleGroupMenuVisible(localGroupMenuKey(group), $event)
|
||||||
|
">
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
class="rounded-full"
|
||||||
|
size="icon-sm"
|
||||||
|
variant="ghost"
|
||||||
|
@click.stop
|
||||||
|
><Ellipsis
|
||||||
|
/></Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent side="right" class="w-50">
|
||||||
|
<DropdownMenuItem @click="handleLocalRename(group)">
|
||||||
|
<span>{{ t('view.favorite.rename_tooltip') }}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
variant="destructive"
|
||||||
|
@click="handleLocalDelete(group)">
|
||||||
|
<span>{{ t('view.favorite.delete_tooltip') }}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-else class="group-empty">
|
||||||
|
<DataTableEmpty type="nodata" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!isCreatingLocalGroup"
|
||||||
|
class="group-item group-item--new"
|
||||||
|
@click="startLocalGroupCreation">
|
||||||
|
<Plus />
|
||||||
|
<span>{{ t('view.favorite.worlds.new_group') }}</span>
|
||||||
|
</div>
|
||||||
|
<InputGroupField
|
||||||
|
v-else
|
||||||
|
ref="newLocalGroupInput"
|
||||||
|
v-model="newLocalGroupName"
|
||||||
|
size="sm"
|
||||||
|
class="group-item__input"
|
||||||
|
:placeholder="t('view.favorite.worlds.new_group')"
|
||||||
|
@keyup.enter="handleLocalGroupCreationConfirm"
|
||||||
|
@keyup.esc="cancelLocalGroupCreation"
|
||||||
|
@blur="cancelLocalGroupCreation" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
<ResizableHandle @dragging="setFriendSplitterDragging" />
|
<ResizableHandle @dragging="setFriendSplitterDragging" />
|
||||||
@@ -197,11 +277,17 @@
|
|||||||
<small>{{ activeRemoteGroup.count }}/{{ activeRemoteGroup.capacity }}</small>
|
<small>{{ activeRemoteGroup.count }}/{{ activeRemoteGroup.capacity }}</small>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
<span v-else-if="activeLocalGroupName">
|
||||||
|
{{ activeLocalGroupName }}
|
||||||
|
<small>{{ activeLocalGroupCount }}</small>
|
||||||
|
</span>
|
||||||
<span v-else>No Group Selected</span>
|
<span v-else>No Group Selected</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="favorites-content__edit">
|
<div class="favorites-content__edit">
|
||||||
<span>{{ t('view.favorite.edit_mode') }}</span>
|
<span>{{ t('view.favorite.edit_mode') }}</span>
|
||||||
<Switch v-model="friendEditMode" :disabled="isSearchActive || !activeRemoteGroup" />
|
<Switch
|
||||||
|
v-model="friendEditMode"
|
||||||
|
:disabled="isSearchActive || (!activeRemoteGroup && !activeLocalGroupName)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="favorites-content__edit-actions">
|
<div class="favorites-content__edit-actions">
|
||||||
@@ -259,6 +345,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="!isSearchActive && activeLocalGroupName && isLocalGroupSelected">
|
||||||
|
<div class="favorites-content__scroll favorites-content__scroll--native">
|
||||||
|
<template v-if="currentLocalFriendFavorites.length">
|
||||||
|
<div
|
||||||
|
class="favorites-card-list"
|
||||||
|
:style="friendFavoritesGridStyle(currentLocalFriendFavorites.length)">
|
||||||
|
<FavoritesFriendItem
|
||||||
|
v-for="favorite in currentLocalFriendFavorites"
|
||||||
|
:key="favorite.id"
|
||||||
|
:favorite="favorite"
|
||||||
|
:group="{ key: activeLocalGroupName, type: 'local' }"
|
||||||
|
:selected="selectedFavoriteFriends.includes(favorite.id)"
|
||||||
|
:edit-mode="friendEditMode"
|
||||||
|
@toggle-select="toggleFriendSelection(favorite.id, $event)"
|
||||||
|
@click="showUserDialog(favorite.id)" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-else class="favorites-empty">
|
||||||
|
<DataTableEmpty type="nodata" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template v-else-if="!isSearchActive">
|
<template v-else-if="!isSearchActive">
|
||||||
<div class="favorites-empty">No Group Selected</div>
|
<div class="favorites-empty">No Group Selected</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -309,11 +417,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ArrowUpDown, Check, Ellipsis, MoreHorizontal, Plus, RefreshCcw, RefreshCw } from 'lucide-vue-next';
|
||||||
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
|
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||||
import { ArrowUpDown, Check, Ellipsis, MoreHorizontal, RefreshCw } from 'lucide-vue-next';
|
import { InputGroupField, InputGroupSearch } from '@/components/ui/input-group';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { DataTableEmpty } from '@/components/ui/data-table';
|
import { DataTableEmpty } from '@/components/ui/data-table';
|
||||||
import { InputGroupSearch } from '@/components/ui/input-group';
|
|
||||||
import { Spinner } from '@/components/ui/spinner';
|
import { Spinner } from '@/components/ui/spinner';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { toast } from 'vue-sonner';
|
import { toast } from 'vue-sonner';
|
||||||
@@ -372,10 +480,24 @@
|
|||||||
groupedByGroupKeyFavoriteFriends,
|
groupedByGroupKeyFavoriteFriends,
|
||||||
selectedFavoriteFriends,
|
selectedFavoriteFriends,
|
||||||
friendImportDialogInput,
|
friendImportDialogInput,
|
||||||
isFavoriteLoading
|
isFavoriteLoading,
|
||||||
|
localFriendFavorites,
|
||||||
|
localFriendFavoriteGroups
|
||||||
} = storeToRefs(favoriteStore);
|
} = storeToRefs(favoriteStore);
|
||||||
const { showFriendImportDialog, refreshFavorites, getLocalWorldFavorites, handleFavoriteGroup } = favoriteStore;
|
const {
|
||||||
const { showUserDialog } = useUserStore();
|
showFriendImportDialog,
|
||||||
|
refreshFavorites,
|
||||||
|
getLocalWorldFavorites,
|
||||||
|
getLocalFriendFavorites,
|
||||||
|
handleFavoriteGroup,
|
||||||
|
localFriendFavGroupLength,
|
||||||
|
deleteLocalFriendFavoriteGroup,
|
||||||
|
renameLocalFriendFavoriteGroup,
|
||||||
|
newLocalFriendFavoriteGroup
|
||||||
|
} = favoriteStore;
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const { showUserDialog } = userStore;
|
||||||
|
const { cachedUsers } = storeToRefs(userStore);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -431,6 +553,9 @@
|
|||||||
const selectedGroup = ref(null);
|
const selectedGroup = ref(null);
|
||||||
const activeGroupMenu = ref(null);
|
const activeGroupMenu = ref(null);
|
||||||
const friendToolbarMenuOpen = ref(false);
|
const friendToolbarMenuOpen = ref(false);
|
||||||
|
const isCreatingLocalGroup = ref(false);
|
||||||
|
const newLocalGroupName = ref('');
|
||||||
|
const newLocalGroupInput = ref(null);
|
||||||
|
|
||||||
function handleSortFavoritesChange(value) {
|
function handleSortFavoritesChange(value) {
|
||||||
const next = Boolean(value);
|
const next = Boolean(value);
|
||||||
@@ -443,6 +568,8 @@
|
|||||||
const hasSearchInput = computed(() => friendFavoriteSearch.value.trim().length > 0);
|
const hasSearchInput = computed(() => friendFavoriteSearch.value.trim().length > 0);
|
||||||
const isSearchActive = computed(() => friendFavoriteSearch.value.trim().length >= 3);
|
const isSearchActive = computed(() => friendFavoriteSearch.value.trim().length >= 3);
|
||||||
const isRemoteGroupSelected = computed(() => selectedGroup.value?.type === 'remote');
|
const isRemoteGroupSelected = computed(() => selectedGroup.value?.type === 'remote');
|
||||||
|
const isLocalGroupSelected = computed(() => selectedGroup.value?.type === 'local');
|
||||||
|
const localGroupMenuKey = (key) => `local:${key}`;
|
||||||
|
|
||||||
const closeFriendToolbarMenu = () => {
|
const closeFriendToolbarMenu = () => {
|
||||||
friendToolbarMenuOpen.value = false;
|
friendToolbarMenuOpen.value = false;
|
||||||
@@ -603,6 +730,36 @@
|
|||||||
return groupedByGroupKeyFavoriteFriends.value[activeRemoteGroup.value.key] || [];
|
return groupedByGroupKeyFavoriteFriends.value[activeRemoteGroup.value.key] || [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const activeLocalGroupName = computed(() => {
|
||||||
|
if (!isLocalGroupSelected.value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return selectedGroup.value.key;
|
||||||
|
});
|
||||||
|
|
||||||
|
const activeLocalGroupCount = computed(() => {
|
||||||
|
if (!activeLocalGroupName.value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const favorites = localFriendFavorites.value[activeLocalGroupName.value];
|
||||||
|
return favorites ? favorites.length : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentLocalFriendFavorites = computed(() => {
|
||||||
|
if (!activeLocalGroupName.value) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const userIds = localFriendFavorites.value[activeLocalGroupName.value] || [];
|
||||||
|
return userIds.map((userId) => {
|
||||||
|
const ref = cachedUsers.value.get(userId);
|
||||||
|
return {
|
||||||
|
id: userId,
|
||||||
|
ref: ref || undefined,
|
||||||
|
name: ref?.displayName || userId
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const isAllFriendsSelected = computed(() => {
|
const isAllFriendsSelected = computed(() => {
|
||||||
if (!activeRemoteGroup.value || !currentFriendFavorites.value.length) {
|
if (!activeRemoteGroup.value || !currentFriendFavorites.value.length) {
|
||||||
return false;
|
return false;
|
||||||
@@ -642,6 +799,7 @@
|
|||||||
function handleRefreshFavorites() {
|
function handleRefreshFavorites() {
|
||||||
refreshFavorites();
|
refreshFavorites();
|
||||||
getLocalWorldFavorites();
|
getLocalWorldFavorites();
|
||||||
|
getLocalFriendFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGroupMenuVisible(key, visible) {
|
function handleGroupMenuVisible(key, visible) {
|
||||||
@@ -670,6 +828,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (localFriendFavoriteGroups.value.length) {
|
||||||
|
selectGroup('local', localFriendFavoriteGroups.value[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
selectedGroup.value = null;
|
selectedGroup.value = null;
|
||||||
clearSelectedFriends();
|
clearSelectedFriends();
|
||||||
}
|
}
|
||||||
@@ -681,6 +843,9 @@
|
|||||||
if (group.type === 'remote') {
|
if (group.type === 'remote') {
|
||||||
return favoriteFriendGroups.value.some((item) => item.key === group.key);
|
return favoriteFriendGroups.value.some((item) => item.key === group.key);
|
||||||
}
|
}
|
||||||
|
if (group.type === 'local') {
|
||||||
|
return localFriendFavoriteGroups.value.includes(group.key);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,6 +1040,75 @@
|
|||||||
}
|
}
|
||||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startLocalGroupCreation() {
|
||||||
|
isCreatingLocalGroup.value = true;
|
||||||
|
newLocalGroupName.value = '';
|
||||||
|
nextTick(() => {
|
||||||
|
newLocalGroupInput.value?.$el?.focus?.();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelLocalGroupCreation() {
|
||||||
|
isCreatingLocalGroup.value = false;
|
||||||
|
newLocalGroupName.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLocalGroupCreationConfirm() {
|
||||||
|
const name = newLocalGroupName.value.trim();
|
||||||
|
if (!name) {
|
||||||
|
cancelLocalGroupCreation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newLocalFriendFavoriteGroup(name);
|
||||||
|
isCreatingLocalGroup.value = false;
|
||||||
|
newLocalGroupName.value = '';
|
||||||
|
selectGroup('local', name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLocalRename(group) {
|
||||||
|
handleGroupMenuVisible(localGroupMenuKey(group), false);
|
||||||
|
modalStore
|
||||||
|
.prompt({
|
||||||
|
title: t('prompt.change_favorite_group_name.header'),
|
||||||
|
description: t('prompt.change_favorite_group_name.description'),
|
||||||
|
confirmText: t('prompt.change_favorite_group_name.change'),
|
||||||
|
cancelText: t('prompt.change_favorite_group_name.cancel'),
|
||||||
|
pattern: /\S+/,
|
||||||
|
inputValue: group,
|
||||||
|
errorMessage: t('prompt.change_favorite_group_name.input_error')
|
||||||
|
})
|
||||||
|
.then(({ ok, value }) => {
|
||||||
|
if (!ok) return;
|
||||||
|
const newName = value.trim();
|
||||||
|
if (!newName || newName === group) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
renameLocalFriendFavoriteGroup(newName, group);
|
||||||
|
if (isGroupActive('local', group)) {
|
||||||
|
selectGroup('local', newName);
|
||||||
|
}
|
||||||
|
toast.success(t('prompt.change_favorite_group_name.message.success'));
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLocalDelete(group) {
|
||||||
|
handleGroupMenuVisible(localGroupMenuKey(group), false);
|
||||||
|
modalStore
|
||||||
|
.confirm({
|
||||||
|
description: 'Continue? Delete Group',
|
||||||
|
title: 'Confirm'
|
||||||
|
})
|
||||||
|
.then(({ ok }) => {
|
||||||
|
if (!ok) return;
|
||||||
|
deleteLocalFriendFavoriteGroup(group);
|
||||||
|
if (isGroupActive('local', group)) {
|
||||||
|
selectDefaultGroup();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -1007,6 +1241,19 @@
|
|||||||
padding: 12px 0;
|
padding: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.group-item--new {
|
||||||
|
border-style: dashed;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-item__input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.favorites-content {
|
.favorites-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
<Checkbox v-model="isSelected" />
|
<Checkbox v-model="isSelected" />
|
||||||
</div>
|
</div>
|
||||||
<div class="favorites-search-card__action-group">
|
<div class="favorites-search-card__action-group">
|
||||||
<div class="favorites-search-card__action favorites-search-card__action--full" @click.stop>
|
<div
|
||||||
|
v-if="group?.type !== 'local'"
|
||||||
|
class="favorites-search-card__action favorites-search-card__action--full"
|
||||||
|
@click.stop>
|
||||||
<FavoritesMoveDropdown
|
<FavoritesMoveDropdown
|
||||||
:favoriteGroup="favoriteFriendGroups"
|
:favoriteGroup="favoriteFriendGroups"
|
||||||
:currentGroup="group"
|
:currentGroup="group"
|
||||||
@@ -106,7 +109,7 @@
|
|||||||
const emit = defineEmits(['click', 'toggle-select']);
|
const emit = defineEmits(['click', 'toggle-select']);
|
||||||
|
|
||||||
const { favoriteFriendGroups } = storeToRefs(useFavoriteStore());
|
const { favoriteFriendGroups } = storeToRefs(useFavoriteStore());
|
||||||
const { showFavoriteDialog } = useFavoriteStore();
|
const { showFavoriteDialog, removeLocalFriendFavorite } = useFavoriteStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const isSelected = computed({
|
const isSelected = computed({
|
||||||
@@ -133,8 +136,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function handleDeleteFavorite() {
|
function handleDeleteFavorite() {
|
||||||
|
if (props.group?.type === 'local') {
|
||||||
|
removeLocalFriendFavorite(props.favorite.id, props.group.key);
|
||||||
|
} else {
|
||||||
favoriteRequest.deleteFavorite({
|
favoriteRequest.deleteFavorite({
|
||||||
objectId: props.favorite.id
|
objectId: props.favorite.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -119,9 +119,22 @@
|
|||||||
<SelectValue :placeholder="t('view.settings.general.favorites.group_placeholder')" />
|
<SelectValue :placeholder="t('view.settings.general.favorites.group_placeholder')" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
<SelectItem v-for="group in favoriteFriendGroups" :key="group.key" :value="group.key">
|
<SelectItem v-for="group in favoriteFriendGroups" :key="group.key" :value="group.key">
|
||||||
{{ group.displayName }}
|
{{ group.displayName }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
<template v-if="localFriendFavoriteGroups.length">
|
||||||
|
<SelectSeparator />
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectItem
|
||||||
|
v-for="group in localFriendFavoriteGroups"
|
||||||
|
:key="'local:' + group"
|
||||||
|
:value="'local:' + group">
|
||||||
|
{{ group }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</template>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
@@ -189,7 +202,15 @@
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../../components/ui/select';
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectSeparator,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue
|
||||||
|
} from '../../../../components/ui/select';
|
||||||
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore } from '../../../../stores';
|
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore } from '../../../../stores';
|
||||||
import { ToggleGroup, ToggleGroupItem } from '../../../../components/ui/toggle-group';
|
import { ToggleGroup, ToggleGroupItem } from '../../../../components/ui/toggle-group';
|
||||||
import { links } from '../../../../shared/constants';
|
import { links } from '../../../../shared/constants';
|
||||||
@@ -231,7 +252,7 @@
|
|||||||
promptProxySettings
|
promptProxySettings
|
||||||
} = generalSettingsStore;
|
} = generalSettingsStore;
|
||||||
|
|
||||||
const { favoriteFriendGroups } = storeToRefs(favoriteStore);
|
const { favoriteFriendGroups, localFriendFavoriteGroups } = storeToRefs(favoriteStore);
|
||||||
|
|
||||||
const { appVersion, autoUpdateVRCX, latestAppVersion, noUpdater } = storeToRefs(vrcxUpdaterStore);
|
const { appVersion, autoUpdateVRCX, latestAppVersion, noUpdater } = storeToRefs(vrcxUpdaterStore);
|
||||||
const { setAutoUpdateVRCX, checkForVRCXUpdate, showVRCXUpdateDialog, showChangeLogDialog } = vrcxUpdaterStore;
|
const { setAutoUpdateVRCX, checkForVRCXUpdate, showVRCXUpdateDialog, showChangeLogDialog } = vrcxUpdaterStore;
|
||||||
|
|||||||
@@ -101,6 +101,7 @@
|
|||||||
useFavoriteStore,
|
useFavoriteStore,
|
||||||
useFriendStore,
|
useFriendStore,
|
||||||
useGameStore,
|
useGameStore,
|
||||||
|
useGeneralSettingsStore,
|
||||||
useLocationStore,
|
useLocationStore,
|
||||||
useUserStore
|
useUserStore
|
||||||
} from '../../../stores';
|
} from '../../../stores';
|
||||||
@@ -114,6 +115,8 @@
|
|||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const generalSettingsStore = useGeneralSettingsStore();
|
||||||
|
|
||||||
const friendStore = useFriendStore();
|
const friendStore = useFriendStore();
|
||||||
const { vipFriends, onlineFriends, activeFriends, offlineFriends, friendsInSameInstance } =
|
const { vipFriends, onlineFriends, activeFriends, offlineFriends, friendsInSameInstance } =
|
||||||
storeToRefs(friendStore);
|
storeToRefs(friendStore);
|
||||||
@@ -121,7 +124,8 @@
|
|||||||
storeToRefs(useAppearanceSettingsStore());
|
storeToRefs(useAppearanceSettingsStore());
|
||||||
const { gameLogDisabled } = storeToRefs(useAdvancedSettingsStore());
|
const { gameLogDisabled } = storeToRefs(useAdvancedSettingsStore());
|
||||||
const { showUserDialog } = useUserStore();
|
const { showUserDialog } = useUserStore();
|
||||||
const { favoriteFriendGroups, groupedByGroupKeyFavoriteFriends } = storeToRefs(useFavoriteStore());
|
const { favoriteFriendGroups, groupedByGroupKeyFavoriteFriends, localFriendFavorites } =
|
||||||
|
storeToRefs(useFavoriteStore());
|
||||||
const { lastLocation, lastLocationDestination } = storeToRefs(useLocationStore());
|
const { lastLocation, lastLocationDestination } = storeToRefs(useLocationStore());
|
||||||
const { isGameRunning } = storeToRefs(useGameStore());
|
const { isGameRunning } = storeToRefs(useGameStore());
|
||||||
const { currentUser } = storeToRefs(useUserStore());
|
const { currentUser } = storeToRefs(useUserStore());
|
||||||
@@ -191,6 +195,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const selectedKey of generalSettingsStore.localFavoriteFriendsGroups) {
|
||||||
|
if (selectedKey.startsWith('local:')) {
|
||||||
|
const groupName = selectedKey.slice(6);
|
||||||
|
const userIds = localFriendFavorites.value?.[groupName];
|
||||||
|
if (userIds && userIds.length) {
|
||||||
|
const filteredFriends = vipFriends.value.filter((friend) => {
|
||||||
|
if (isSidebarGroupByInstance.value && isHideFriendsInSameInstance.value) {
|
||||||
|
return userIds.includes(friend.id) && !sameInstanceFriendId.value.has(friend.id);
|
||||||
|
}
|
||||||
|
return userIds.includes(friend.id);
|
||||||
|
});
|
||||||
|
if (filteredFriends.length > 0) {
|
||||||
|
result.push(
|
||||||
|
filteredFriends.map((item) => ({
|
||||||
|
groupName,
|
||||||
|
key: selectedKey,
|
||||||
|
...item
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result.sort((a, b) => a[0].key.localeCompare(b[0].key));
|
return result.sort((a, b) => a[0].key.localeCompare(b[0].key));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user