This commit is contained in:
pa
2026-02-03 20:54:32 +09:00
parent 8decb568fe
commit 20457ff082
19 changed files with 421 additions and 435 deletions

View File

@@ -145,7 +145,9 @@
:model-value="group.visibility === visibility"
indicator-position="right"
@select="handleVisibilitySelection(group, visibility)">
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
<span>{{
t(`view.favorite.visibility.${visibility}`)
}}</span>
</DropdownMenuCheckboxItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
@@ -536,6 +538,7 @@
import { Badge } from '../../components/ui/badge';
import { Slider } from '../../components/ui/slider';
import { Switch } from '../../components/ui/switch';
import { debounce } from '../../shared/utils';
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
import AvatarExportDialog from './dialogs/AvatarExportDialog.vue';
@@ -570,7 +573,6 @@
favoriteAvatarGroups,
localAvatarFavorites,
selectedFavoriteAvatars,
avatarImportDialogInput,
isFavoriteLoading,
localAvatarFavoriteGroups
} = storeToRefs(favoriteStore);
@@ -582,7 +584,7 @@
newLocalAvatarFavoriteGroup,
localAvatarFavoritesList,
refreshFavorites,
getLocalWorldFavorites,
getLocalAvatarFavorites,
handleFavoriteGroup,
checkInvalidLocalAvatars,
removeInvalidLocalAvatars
@@ -979,7 +981,7 @@
function handleGroupClick(type, key) {
if (hasSearchInput.value) {
avatarFavoriteSearch.value = '';
searchAvatarFavorites('');
doSearchAvatarFavorites('');
}
selectGroup(type, key, { userInitiated: true });
}
@@ -1031,7 +1033,7 @@
function handleRefreshFavorites() {
refreshFavorites();
getLocalWorldFavorites();
getLocalAvatarFavorites();
}
function handleVisibilitySelection(group, visibility) {
@@ -1264,7 +1266,7 @@
.catch(() => {});
}
function searchAvatarFavorites(value) {
function doSearchAvatarFavorites(value) {
if (typeof value === 'string') {
avatarFavoriteSearch.value = value;
}
@@ -1274,6 +1276,7 @@
return;
}
const results = [];
const seen = new Set();
localAvatarFavoriteGroups.value.forEach((group) => {
const favorites = localAvatarFavorites.value[group];
if (!favorites) {
@@ -1289,7 +1292,8 @@
return;
}
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
if (!results.some((r) => r.id === ref.id)) {
if (!seen.has(ref.id)) {
seen.add(ref.id);
results.push(ref);
}
}
@@ -1306,13 +1310,15 @@
return;
}
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
if (!results.some((r) => r.id === ref.id)) {
if (!seen.has(ref.id)) {
seen.add(ref.id);
results.push(ref);
}
}
});
avatarFavoriteSearchResults.value = results;
}
const searchAvatarFavorites = debounce(doSearchAvatarFavorites, 200);
async function refreshLocalAvatarFavorites() {
if (refreshingLocalFavorites.value) {

View File

@@ -148,7 +148,9 @@
:model-value="group.visibility === visibility"
indicator-position="right"
@select="handleVisibilitySelection(group, visibility)">
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
<span>{{
t(`view.favorite.visibility.${visibility}`)
}}</span>
</DropdownMenuCheckboxItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
@@ -325,12 +327,12 @@
} from '../../components/ui/select';
import { useAppearanceSettingsStore, useFavoriteStore, useModalStore, useUserStore } from '../../stores';
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '../../components/ui/resizable';
import { debounce, userImage } from '../../shared/utils';
import { Badge } from '../../components/ui/badge';
import { Slider } from '../../components/ui/slider';
import { Switch } from '../../components/ui/switch';
import { favoriteRequest } from '../../api';
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
import { userImage } from '../../shared/utils';
import FavoritesFriendItem from './components/FavoritesFriendItem.vue';
import FriendExportDialog from './dialogs/FriendExportDialog.vue';
@@ -683,12 +685,12 @@
function handleGroupClick(type, key) {
if (hasSearchInput.value) {
friendFavoriteSearch.value = '';
searchFriendFavorites('');
doSearchFriendFavorites('');
}
selectGroup(type, key);
}
function searchFriendFavorites(searchTerm) {
function doSearchFriendFavorites(searchTerm) {
const search = searchTerm.trim().toLowerCase();
if (search.length < 3) {
friendFavoriteSearchResults.value = [];
@@ -703,6 +705,7 @@
});
friendFavoriteSearchResults.value = filtered;
}
const searchFriendFavorites = debounce(doSearchFriendFavorites, 200);
function toggleFriendSelection(id, value) {
if (value) {

View File

@@ -148,7 +148,9 @@
:model-value="group.visibility === visibility"
indicator-position="right"
@select="handleVisibilitySelection(group, visibility)">
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
<span>{{
t(`view.favorite.visibility.${visibility}`)
}}</span>
</DropdownMenuCheckboxItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
@@ -470,6 +472,7 @@
import { Badge } from '../../components/ui/badge';
import { Slider } from '../../components/ui/slider';
import { Switch } from '../../components/ui/switch';
import { debounce } from '../../shared/utils';
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
import FavoritesWorldItem from './components/FavoritesWorldItem.vue';
@@ -813,7 +816,7 @@
type: 'cards',
key: `local:${activeLocalGroupName.value}:${index}`,
items: items.slice(index, index + safeColumns).map((favorite) => ({
key: favorite.id ?? favorite.worldId ?? favorite.name ?? `${index}:${Math.random()}`,
key: favorite.id ?? favorite.worldId ?? favorite.name ?? `${activeLocalGroupName.value}:${index}`,
favorite
}))
});
@@ -939,7 +942,7 @@
function handleGroupClick(type, key) {
if (hasSearchInput.value) {
worldFavoriteSearch.value = '';
searchWorldFavorites('');
doSearchWorldFavorites('');
}
selectGroup(type, key, { userInitiated: true });
}
@@ -1171,7 +1174,7 @@
.catch(() => {});
}
function searchWorldFavorites(worldFavoriteSearch) {
function doSearchWorldFavorites(worldFavoriteSearch) {
const search = worldFavoriteSearch.trim().toLowerCase();
if (search.length < 3) {
worldFavoriteSearchResults.value = [];
@@ -1186,6 +1189,7 @@
});
worldFavoriteSearchResults.value = filtered;
}
const searchWorldFavorites = debounce(doSearchWorldFavorites, 200);
function handleVisibilitySelection(group, visibility) {
const menuKey = remoteGroupMenuKey(group.key);

View File

@@ -5,7 +5,6 @@ import { Button } from '../../components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '../../components/ui/tooltip';
import {
@@ -24,6 +23,7 @@ const { t } = i18n.global;
const expandedRow = ({ row }) => {
const original = row.original;
const type = original.type;
const { showFullscreenImageDialog } = useGalleryStore();
if (type === 'GPS') {
return (
<div class="pl-5 text-sm">
@@ -81,7 +81,6 @@ const expandedRow = ({ row }) => {
}
if (type === 'Avatar') {
const { showFullscreenImageDialog } = useGalleryStore();
return (
<div class="pl-5 text-sm">
<div class="flex items-center">
@@ -243,16 +242,14 @@ export const columns = [
const longText = formatDateFilter(createdAt, 'long');
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
);
}
},
@@ -280,7 +277,7 @@ export const columns = [
const original = row.original;
return (
<span
class="cursor-pointer pr-2.5 cursor-pointer"
class="cursor-pointer pr-2.5"
onClick={() => showUserDialog(original.userId)}
>
{original.displayName}

View File

@@ -3,7 +3,6 @@ import { Button } from '../../components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '../../components/ui/tooltip';
import { ArrowRight, ArrowUpDown, Trash2, X } from 'lucide-vue-next';
@@ -49,16 +48,14 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
const longText = formatDateFilter(createdAt, 'long');
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
);
}
},

View File

@@ -3,7 +3,7 @@
<div class="friend-card__header">
<div>
<Avatar class="friend-card__avatar" :style="{ width: `${avatarSize}px`, height: `${avatarSize}px` }">
<AvatarImage :src="userImage(props.friend.ref, true)" />
<AvatarImage :src="userImage(friend.ref, true)" />
<AvatarFallback>{{ avatarFallback }}</AvatarFallback>
</Avatar>
</div>

View File

@@ -4,7 +4,6 @@ import { Button } from '../../components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '../../components/ui/tooltip';
import { ArrowUpDown, FileText, Trash2, X } from 'lucide-vue-next';
@@ -65,16 +64,14 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
const longText = formatDateFilter(createdAt, 'long');
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
);
}
},
@@ -275,30 +272,26 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
</button>
) : null}
{canShowPrevious ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
showPreviousInstancesInfoDialog(
original.location
)
}
>
<FileText class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'dialog.previous_instances.info'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
showPreviousInstancesInfoDialog(
original.location
)
}
>
<FileText class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t('dialog.previous_instances.info')}
</span>
</TooltipContent>
</Tooltip>
) : null}
</div>
);

View File

@@ -3,7 +3,6 @@ import { Button } from '../../components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '../../components/ui/tooltip';
import { ArrowUpDown, Trash2, X } from 'lucide-vue-next';
@@ -50,16 +49,14 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
const longText = formatDateFilter(createdAt, 'long');
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
);
}
},

View File

@@ -438,7 +438,8 @@
.catch((err) => {
handleNotificationHide({ params });
notificationRequest.hideNotificationV2(params.notificationId);
throw err;
console.error('Notification response failed', err);
toast.error('Error');
});
}

View File

@@ -4,7 +4,6 @@ import { Button } from '../../components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipWrapper
} from '../../components/ui/tooltip';
@@ -129,16 +128,14 @@ export const createColumns = ({
const longText = formatDateFilter(createdAt, 'long');
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span>{shortText}</span>
</TooltipTrigger>
<TooltipContent side="right">
<span>{longText}</span>
</TooltipContent>
</Tooltip>
);
}
},
@@ -164,32 +161,28 @@ export const createColumns = ({
) {
return (
<Badge variant="outline" class="text-muted-foreground">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span
class="cursor-pointer"
onClick={() =>
showWorldDialog(
original.location
)
}
>
{label}
</span>
</TooltipTrigger>
<TooltipContent side="top">
{original.location ? (
<Location
location={original.location}
hint={original.worldName}
grouphint={original.groupName}
link={true}
/>
) : null}
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span
class="cursor-pointer"
onClick={() =>
showWorldDialog(original.location)
}
>
{label}
</span>
</TooltipTrigger>
<TooltipContent side="top">
{original.location ? (
<Location
location={original.location}
hint={original.worldName}
grouphint={original.groupName}
link={true}
/>
) : null}
</TooltipContent>
</Tooltip>
</Badge>
);
}
@@ -197,25 +190,21 @@ export const createColumns = ({
if (original.link) {
return (
<Badge variant="outline" class="text-muted-foreground">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span
class="cursor-pointer"
onClick={() =>
openNotificationLink(
original.link
)
}
>
{label}
</span>
</TooltipTrigger>
<TooltipContent side="top">
<span>{original.linkText}</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span
class="cursor-pointer"
onClick={() =>
openNotificationLink(original.link)
}
>
{label}
</span>
</TooltipTrigger>
<TooltipContent side="top">
<span>{original.linkText}</span>
</TooltipContent>
</Tooltip>
</Badge>
);
}
@@ -548,41 +537,88 @@ export const createColumns = ({
!original.$isExpired ? (
<span class="inline-flex items-center gap-2">
{original.type === 'friendRequest' ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
acceptFriendRequestNotification(
original
)
}
>
<Check class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.accept'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
acceptFriendRequestNotification(
original
)
}
>
<Check class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.accept'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
{original.type === 'invite' ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
showSendInviteResponseDialog(
original
)
}
>
<MessageCircle class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.decline_with_message'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
{original.type === 'requestInvite' ? (
<span class="inline-flex items-center">
{canInvite() ? (
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
acceptRequestInvite(
original
)
}
>
<Check class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.invite'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
showSendInviteResponseDialog(
showSendInviteRequestResponseDialog(
original
)
}
@@ -598,61 +634,6 @@ export const createColumns = ({
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : null}
{original.type === 'requestInvite' ? (
<span class="inline-flex items-center">
{canInvite() ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
acceptRequestInvite(
original
)
}
>
<Check class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.invite'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : null}
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
showSendInviteRequestResponseDialog(
original
)
}
>
<MessageCircle class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.decline_with_message'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</span>
) : null}
@@ -687,136 +668,128 @@ export const createColumns = ({
);
return (
<TooltipProvider
<Tooltip
key={`${response.text}:${response.type}`}
>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={onClick}
>
<ResponseIcon class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{response.text}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={onClick}
>
<ResponseIcon class="h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{response.text}
</span>
</TooltipContent>
</Tooltip>
);
})
: null}
{showDecline ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
shiftHeld.value
? hideNotification(
original
)
: hideNotificationPrompt(
original
)
}
>
<X
class={
shiftHeld.value
? hideNotification(
original
)
: hideNotificationPrompt(
original
)
? 'h-4 w-4 text-red-600'
: 'h-4 w-4'
}
>
<X
class={
shiftHeld.value
? 'h-4 w-4 text-red-600'
: 'h-4 w-4'
}
/>
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.decline'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
/>
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.decline'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
{original.type === 'group.queueReady' ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
shiftHeld.value
? deleteNotificationLog(
original
)
: deleteNotificationLogPrompt(
original
)
}
>
{shiftHeld.value ? (
<X class="h-4 w-4 text-red-600" />
) : (
<Trash2 class="h-4 w-4" />
)}
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.delete_log'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
shiftHeld.value
? deleteNotificationLog(
original
)
: deleteNotificationLogPrompt(
original
)
}
>
{shiftHeld.value ? (
<X class="h-4 w-4 text-red-600" />
) : (
<Trash2 class="h-4 w-4" />
)}
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.delete_log'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
</span>
) : null}
{showDeleteLog ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
shiftHeld.value
? deleteNotificationLog(
original
)
: deleteNotificationLogPrompt(
original
)
}
>
{shiftHeld.value ? (
<X class="h-4 w-4 text-red-600" />
) : (
<Trash2 class="h-4 w-4" />
)}
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.delete_log'
)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
onClick={() =>
shiftHeld.value
? deleteNotificationLog(
original
)
: deleteNotificationLogPrompt(
original
)
}
>
{shiftHeld.value ? (
<X class="h-4 w-4 text-red-600" />
) : (
<Trash2 class="h-4 w-4" />
)}
</button>
</TooltipTrigger>
<TooltipContent side="top">
<span>
{t(
'view.notification.actions.delete_log'
)}
</span>
</TooltipContent>
</Tooltip>
) : null}
</div>
);

View File

@@ -75,7 +75,8 @@
await inviteMessagesRequest
.editInviteMessage(params, messageType, slot)
.catch((err) => {
throw err;
console.error('Invite response message update failed', err);
toast.error('Error');
})
.then((args) => {
if (args.json[slot].message === I.messageSlot.message) {
@@ -96,7 +97,8 @@
notificationRequest
.sendInviteResponsePhoto(params, I.invite.id)
.catch((err) => {
throw err;
console.error('Invite response photo failed', err);
toast.error('Error');
})
.then((args) => {
notificationRequest.hideNotification({
@@ -112,7 +114,8 @@
notificationRequest
.sendInviteResponse(params, I.invite.id)
.catch((err) => {
throw err;
console.error('Invite response failed', err);
toast.error('Error');
})
.then((args) => {
notificationRequest.hideNotification({

View File

@@ -61,7 +61,8 @@
notificationRequest
.sendInviteResponsePhoto(params, D.invite.id)
.catch((err) => {
throw err;
console.error('Invite response photo failed', err);
toast.error(t('message.error'));
})
.then((args) => {
notificationRequest.hideNotification({
@@ -77,7 +78,8 @@
notificationRequest
.sendInviteResponse(params, D.invite.id)
.catch((err) => {
throw err;
console.error('Invite response failed', err);
toast.error('Error');
})
.then((args) => {
notificationRequest.hideNotification({

View File

@@ -31,12 +31,12 @@
}}</span>
<span v-if="!item.ref.isFriend" class="block truncate text-xs"></span>
<span
v-else-if="item.ref.state === 'offline'"
v-else-if="item.ref.state === 'active'"
class="block truncate text-xs"
>{{ t('side_panel.search_result_active') }}</span
>
<span
v-else-if="item.ref.state === 'active'"
v-else-if="item.ref.state === 'offline'"
class="block truncate text-xs"
>{{ t('side_panel.search_result_offline') }}</span
>
@@ -120,7 +120,7 @@
import { useI18n } from 'vue-i18n';
import { useFriendStore, useGroupStore, useSearchStore } from '../../stores';
import { userImage } from '../../shared/utils';
import { debounce, userImage } from '../../shared/utils';
import FriendsSidebar from './components/FriendsSidebar.vue';
import GroupsSidebar from './components/GroupsSidebar.vue';
@@ -139,13 +139,18 @@
const quickSearchQuery = ref('');
const isQuickSearchOpen = ref(false);
watch(
quickSearchQuery,
(value) => {
quickSearchRemoteMethod(String(value ?? ''));
},
{ immediate: true }
);
const runQuickSearch = debounce((value) => {
quickSearchRemoteMethod(value);
}, 200);
watch(quickSearchQuery, (value) => {
const query = String(value ?? '').trim();
if (!query) {
quickSearchRemoteMethod('');
return;
}
runQuickSearch(query);
});
function handleQuickSearchSelect(value) {
if (!value) {

View File

@@ -68,6 +68,9 @@
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import Location from '@/components/Location.vue';
import Timer from '@/components/Timer.vue';
import { useAppearanceSettingsStore, useFriendStore, useUserStore } from '../../../stores';
import { userImage, userStatusClass } from '../../../shared/utils';

View File

@@ -74,7 +74,7 @@
</template>
<template v-else-if="item.row.type === 'friend-item'">
<friend-item
<FriendItem
:friend="item.row.friend"
:style="item.row.itemStyle"
:is-group-by-instance="item.row.isGroupByInstance" />

View File

@@ -161,7 +161,7 @@
width: 100%;
display: flex;
align-items: flex-start;
padding: 0 12x 0 12px;
padding: 0 12px;
}
.date {