diff --git a/src/stores/favorite.js b/src/stores/favorite.js index 166db828..52231fbb 100644 --- a/src/stores/favorite.js +++ b/src/stores/favorite.js @@ -162,6 +162,12 @@ export const useFavoriteStore = defineStore('Favorite', () => { .map((fav) => fav.id) ); + const localFriendFavoritesList = computed(() => + Object.values(localFriendFavorites) + .flat() + .map((userId) => userId) + ); + const groupedByGroupKeyFavoriteFriends = computed(() => { const groupedByGroupKeyFavoriteFriends = {}; favoriteFriends.value.forEach((friend) => { @@ -1765,6 +1771,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { localAvatarFavoriteGroups, favoriteDialog, localWorldFavoritesList, + localFriendFavoritesList, localWorldFavoriteGroups, localFriendFavorites, diff --git a/src/views/Favorites/FavoritesAvatar.vue b/src/views/Favorites/FavoritesAvatar.vue index b998d4f7..6357053d 100644 --- a/src/views/Favorites/FavoritesAvatar.vue +++ b/src/views/Favorites/FavoritesAvatar.vue @@ -591,7 +591,8 @@ localAvatarFavorites, selectedFavoriteAvatars, isFavoriteLoading, - localAvatarFavoriteGroups + localAvatarFavoriteGroups, + avatarImportDialogInput } = storeToRefs(favoriteStore); const { showAvatarImportDialog, @@ -1239,11 +1240,13 @@ description: 'Continue? Clear Group', title: 'Confirm' }) - .then(() => { - favoriteRequest.clearFavoriteGroup({ - type: ctx.type, - group: ctx.name - }); + .then(({ ok }) => { + if (ok) { + favoriteRequest.clearFavoriteGroup({ + type: ctx.type, + group: ctx.name + }); + } }) .catch(() => {}); } @@ -1276,10 +1279,14 @@ function promptLocalAvatarFavoriteGroupDelete(group) { modalStore .confirm({ - description: `Trash2 Group? ${group}`, + description: `Delete Group? ${group}`, title: 'Confirm' }) - .then(() => deleteLocalAvatarFavoriteGroup(group)) + .then(({ ok }) => { + if (ok) { + deleteLocalAvatarFavoriteGroup(group); + } + }) .catch(() => {}); } @@ -1400,6 +1407,55 @@ refreshingLocalFavorites.value = false; } + function toggleSelectAllAvatars() { + if (!activeRemoteGroup.value) { + return; + } + if (isAllAvatarsSelected.value) { + selectedFavoriteAvatars.value = []; + } else { + selectedFavoriteAvatars.value = currentRemoteFavorites.value.map((fav) => fav.id); + } + } + + function copySelectedAvatars() { + if (!selectedFavoriteAvatars.value.length) { + return; + } + const idList = selectedFavoriteAvatars.value.map((id) => `${id}\n`).join(''); + avatarImportDialogInput.value = idList; + showAvatarImportDialog(); + } + + function showAvatarBulkUnfavoriteSelectionConfirm() { + if (!selectedFavoriteAvatars.value.length) { + return; + } + const total = selectedFavoriteAvatars.value.length; + modalStore + .confirm({ + description: `Are you sure you want to unfavorite ${total} favorites? + This action cannot be undone.`, + title: `Delete ${total} favorites?` + }) + .then(({ ok }) => { + if (ok) { + bulkUnfavoriteSelectedAvatars(selectedFavoriteAvatars.value); + } + }) + .catch(() => {}); + } + + function bulkUnfavoriteSelectedAvatars(ids) { + ids.forEach((id) => { + favoriteRequest.deleteFavorite({ + objectId: id + }); + }); + selectedFavoriteAvatars.value = []; + avatarEditMode.value = false; + } + onBeforeUnmount(() => { cancelLocalAvatarRefresh(); if (avatarSplitterObserver) { diff --git a/src/views/Favorites/FavoritesFriend.vue b/src/views/Favorites/FavoritesFriend.vue index 11420811..10b27725 100644 --- a/src/views/Favorites/FavoritesFriend.vue +++ b/src/views/Favorites/FavoritesFriend.vue @@ -930,7 +930,7 @@ modalStore .confirm({ description: `Are you sure you want to unfavorite ${total} favorites?\n This action cannot be undone.`, - title: `Trash2 ${total} favorites?` + title: `Delete ${total} favorites?` }) .then(({ ok }) => ok && bulkUnfavoriteSelectedFriends([...selectedFavoriteFriends.value])) .catch(() => {}); @@ -958,11 +958,13 @@ description: 'Continue? Clear Group', title: 'Confirm' }) - .then(() => { - favoriteRequest.clearFavoriteGroup({ - type: ctx.type, - group: ctx.name - }); + .then(({ ok }) => { + if (ok) { + favoriteRequest.clearFavoriteGroup({ + type: ctx.type, + group: ctx.name + }); + } }) .catch(() => {}); } diff --git a/src/views/Favorites/FavoritesWorld.vue b/src/views/Favorites/FavoritesWorld.vue index 8c293653..cded076e 100644 --- a/src/views/Favorites/FavoritesWorld.vue +++ b/src/views/Favorites/FavoritesWorld.vue @@ -1095,9 +1095,13 @@ .confirm({ description: `Are you sure you want to unfavorite ${total} favorites? This action cannot be undone.`, - title: `Trash2 ${total} favorites?` + title: `Delete ${total} favorites?` + }) + .then(({ ok }) => { + if (ok) { + bulkUnfavoriteSelectedWorlds([...selectedFavoriteWorlds.value]); + } }) - .then(() => bulkUnfavoriteSelectedWorlds([...selectedFavoriteWorlds.value])) .catch(() => {}); } @@ -1170,10 +1174,14 @@ function promptLocalWorldFavoriteGroupDelete(group) { modalStore .confirm({ - description: `Trash2 Group? ${group}`, + description: `Delete Group? ${group}`, title: 'Confirm' }) - .then(() => deleteLocalWorldFavoriteGroup(group)) + .then(({ ok }) => { + if (ok) { + deleteLocalWorldFavoriteGroup(group); + } + }) .catch(() => {}); } @@ -1183,11 +1191,13 @@ description: 'Continue? Clear Group', title: 'Confirm' }) - .then(() => { - favoriteRequest.clearFavoriteGroup({ - type: ctx.type, - group: ctx.name - }); + .then(({ ok }) => { + if (ok) { + favoriteRequest.clearFavoriteGroup({ + type: ctx.type, + group: ctx.name + }); + } }) .catch(() => {}); } diff --git a/src/views/Favorites/dialogs/FriendExportDialog.vue b/src/views/Favorites/dialogs/FriendExportDialog.vue index 78d7885e..5a604f55 100644 --- a/src/views/Favorites/dialogs/FriendExportDialog.vue +++ b/src/views/Favorites/dialogs/FriendExportDialog.vue @@ -12,7 +12,7 @@ - All Favorites + None +
{ - if (!friendExportFavoriteGroup.value || friendExportFavoriteGroup.value === group) { - favoriteFriends.value.forEach((ref) => { - if (group.key === ref.groupKey) { - lines.push(`${formatter(ref.id)},${formatter(ref.name)}`); - } - }); + + if (friendExportFavoriteGroup.value) { + favoriteFriendGroups.value.forEach((group) => { + if (friendExportFavoriteGroup.value === group) { + favoriteFriends.value.forEach((ref) => { + if (group.key === ref.groupKey) { + lines.push(`${formatter(ref.id)},${formatter(ref.name)}`); + } + }); + } + }); + } else if (friendExportLocalFavoriteGroup.value) { + const favoriteGroup = localFriendFavorites.value[friendExportLocalFavoriteGroup.value]; + if (!favoriteGroup) { + return; } - }); + favoriteGroup.forEach((userId) => { + const ref = cachedUsers.value.get(userId); + if (typeof ref !== 'undefined') { + lines.push(`${formatter(ref.id)},${formatter(ref.displayName)}`); + } + }); + } else { + // export all + favoriteFriends.value.forEach((ref) => { + lines.push(`${formatter(ref.id)},${formatter(ref.name)}`); + }); + for (let i = 0; i < localFriendFavoritesList.value.length; ++i) { + const userId = localFriendFavoritesList.value[i]; + const ref = cachedUsers.value.get(userId); + if (typeof ref !== 'undefined') { + lines.push(`${formatter(ref.id)},${formatter(ref.displayName)}`); + } + } + } friendExportContent.value = lines.join('\n'); } function selectFriendExportGroup(group) { friendExportFavoriteGroup.value = group; + friendExportLocalFavoriteGroup.value = null; friendExportFavoriteGroupSelection.value = group?.name ?? FRIEND_EXPORT_ALL_VALUE; + friendExportLocalFavoriteGroupSelection.value = FRIEND_EXPORT_NONE_VALUE; + updateFriendExportDialog(); + } + + function selectFriendExportLocalGroup(groupName) { + friendExportLocalFavoriteGroup.value = groupName; + friendExportFavoriteGroup.value = null; + friendExportFavoriteGroupSelection.value = FRIEND_EXPORT_ALL_VALUE; + friendExportLocalFavoriteGroupSelection.value = groupName ?? FRIEND_EXPORT_NONE_VALUE; updateFriendExportDialog(); } diff --git a/src/views/Favorites/dialogs/FriendImportDialog.vue b/src/views/Favorites/dialogs/FriendImportDialog.vue index 5b6f7803..c6e9e105 100644 --- a/src/views/Favorites/dialogs/FriendImportDialog.vue +++ b/src/views/Favorites/dialogs/FriendImportDialog.vue @@ -25,26 +25,44 @@ :rows="10" style="margin-top: 10px" input-class="resize-none" /> -
-
- +
+
+
+ + + +
{{ friendImportTable.data.length }} / {{ @@ -64,7 +82,11 @@ @@ -118,10 +140,10 @@ const emit = defineEmits(['update:friendImportDialogInput']); const { showUserDialog } = useUserStore(); - const { favoriteFriendGroups, friendImportDialogInput, friendImportDialogVisible } = + const { favoriteFriendGroups, friendImportDialogInput, friendImportDialogVisible, localFriendFavoriteGroups } = storeToRefs(useFavoriteStore()); const { showFullscreenImageDialog } = useGalleryStore(); - const { getCachedFavoritesByObjectId } = useFavoriteStore(); + const { getCachedFavoritesByObjectId, localFriendFavGroupLength, addLocalFriendFavorite } = useFavoriteStore(); const friendImportDialog = ref({ loading: false, @@ -131,11 +153,13 @@ userIdList: new Set(), errors: '', friendImportFavoriteGroup: null, + friendImportLocalFavoriteGroup: null, importProgress: 0, importProgressTotal: 0 }); const friendImportFavoriteGroupSelection = ref(''); + const friendImportLocalFavoriteGroupSelection = ref(''); const friendImportTable = ref({ data: [], @@ -203,6 +227,11 @@ } } + function handleFriendImportLocalGroupSelect(value) { + friendImportLocalFavoriteGroupSelection.value = value; + selectFriendImportLocalGroup(value || null); + } + function cancelFriendImport() { friendImportDialog.value.loading = false; } @@ -215,13 +244,23 @@ friendImportDialog.value.userIdList = new Set(); } function selectFriendImportGroup(group) { + friendImportDialog.value.friendImportLocalFavoriteGroup = null; friendImportDialog.value.friendImportFavoriteGroup = group; friendImportFavoriteGroupSelection.value = group?.name ?? ''; + friendImportLocalFavoriteGroupSelection.value = ''; } + + function selectFriendImportLocalGroup(group) { + friendImportDialog.value.friendImportFavoriteGroup = null; + friendImportDialog.value.friendImportLocalFavoriteGroup = group; + friendImportFavoriteGroupSelection.value = ''; + friendImportLocalFavoriteGroupSelection.value = group ?? ''; + } + async function importFriendImportTable() { const D = friendImportDialog.value; D.loading = true; - if (!D.friendImportFavoriteGroup) { + if (!D.friendImportFavoriteGroup && !D.friendImportLocalFavoriteGroup) { return; } const data = [...friendImportTable.value.data].reverse(); @@ -233,10 +272,14 @@ break; } ref = data[i]; - if (getCachedFavoritesByObjectId(ref.id)) { - throw new Error('Friend is already in favorites'); + if (D.friendImportFavoriteGroup) { + if (getCachedFavoritesByObjectId(ref.id)) { + throw new Error('Friend is already in favorites'); + } + await addFavoriteUser(ref, D.friendImportFavoriteGroup, false); + } else if (D.friendImportLocalFavoriteGroup) { + addLocalFriendFavorite(ref.id, D.friendImportLocalFavoriteGroup); } - await addFavoriteUser(ref, D.friendImportFavoriteGroup, false); removeFromArray(friendImportTable.value.data, ref); D.userIdList.delete(ref.id); D.importProgress++;