mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
fix
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
import { ArrowUp } from 'lucide-vue-next';
|
import { ArrowUp } from 'lucide-vue-next';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
||||||
@@ -122,23 +122,21 @@
|
|||||||
<Teleport v-if="teleportTarget" :to="teleportTarget">
|
<Teleport v-if="teleportTarget" :to="teleportTarget">
|
||||||
<Transition name="back-to-top">
|
<Transition name="back-to-top">
|
||||||
<div v-if="visible" :style="wrapperStyle">
|
<div v-if="visible" :style="wrapperStyle">
|
||||||
<TooltipProvider v-if="tooltip">
|
<Tooltip v-if="tooltip">
|
||||||
<Tooltip>
|
<TooltipTrigger as-child>
|
||||||
<TooltipTrigger as-child>
|
<Button
|
||||||
<Button
|
size="icon"
|
||||||
size="icon"
|
variant="secondary"
|
||||||
variant="secondary"
|
class="rounded-full shadow"
|
||||||
class="rounded-full shadow"
|
aria-label="Back to top"
|
||||||
aria-label="Back to top"
|
@click="scrollToTop">
|
||||||
@click="scrollToTop">
|
<ArrowUp class="h-4 w-4" />
|
||||||
<ArrowUp class="h-4 w-4" />
|
</Button>
|
||||||
</Button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
{{ tooltipText }}
|
||||||
{{ tooltipText }}
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
@@ -155,23 +153,21 @@
|
|||||||
|
|
||||||
<Transition v-else name="back-to-top">
|
<Transition v-else name="back-to-top">
|
||||||
<div v-if="visible" :style="wrapperStyle">
|
<div v-if="visible" :style="wrapperStyle">
|
||||||
<TooltipProvider v-if="tooltip">
|
<Tooltip v-if="tooltip">
|
||||||
<Tooltip>
|
<TooltipTrigger as-child>
|
||||||
<TooltipTrigger as-child>
|
<Button
|
||||||
<Button
|
size="icon"
|
||||||
size="icon"
|
variant="secondary"
|
||||||
variant="secondary"
|
class="rounded-full shadow"
|
||||||
class="rounded-full shadow"
|
aria-label="Back to top"
|
||||||
aria-label="Back to top"
|
@click="scrollToTop">
|
||||||
@click="scrollToTop">
|
<ArrowUp class="h-4 w-4" />
|
||||||
<ArrowUp class="h-4 w-4" />
|
</Button>
|
||||||
</Button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
{{ tooltipText }}
|
||||||
{{ tooltipText }}
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
|
|||||||
+22
-19
@@ -59,7 +59,7 @@ export const useFeedStore = defineStore('Feed', () => {
|
|||||||
init();
|
init();
|
||||||
|
|
||||||
function feedSearch(row) {
|
function feedSearch(row) {
|
||||||
const value = feedTable.value.search.toUpperCase();
|
const value = feedTable.value.search.trim().toUpperCase();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -140,25 +140,28 @@ export const useFeedStore = defineStore('Feed', () => {
|
|||||||
feedTable.value.vip
|
feedTable.value.vip
|
||||||
);
|
);
|
||||||
feedTable.value.loading = true;
|
feedTable.value.loading = true;
|
||||||
let vipList = [];
|
try {
|
||||||
if (feedTable.value.vip) {
|
let vipList = [];
|
||||||
vipList = Array.from(friendStore.localFavoriteFriends.values());
|
if (feedTable.value.vip) {
|
||||||
|
vipList = Array.from(friendStore.localFavoriteFriends.values());
|
||||||
|
}
|
||||||
|
const search = feedTable.value.search.trim();
|
||||||
|
const rows = search
|
||||||
|
? await database.searchFeedDatabase(
|
||||||
|
search,
|
||||||
|
feedTable.value.filter,
|
||||||
|
vipList,
|
||||||
|
vrcxStore.searchLimit
|
||||||
|
)
|
||||||
|
: await database.lookupFeedDatabase(
|
||||||
|
feedTable.value.filter,
|
||||||
|
vipList
|
||||||
|
);
|
||||||
|
feedTableData.value = [];
|
||||||
|
feedTableData.value = [...feedTableData.value, ...rows];
|
||||||
|
} finally {
|
||||||
|
feedTable.value.loading = false;
|
||||||
}
|
}
|
||||||
const search = feedTable.value.search.trim();
|
|
||||||
const rows = search
|
|
||||||
? await database.searchFeedDatabase(
|
|
||||||
search,
|
|
||||||
feedTable.value.filter,
|
|
||||||
vipList,
|
|
||||||
vrcxStore.searchLimit
|
|
||||||
)
|
|
||||||
: await database.lookupFeedDatabase(
|
|
||||||
feedTable.value.filter,
|
|
||||||
vipList
|
|
||||||
);
|
|
||||||
feedTableData.value = [];
|
|
||||||
feedTableData.value = [...feedTableData.value, ...rows];
|
|
||||||
feedTable.value.loading = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFeed(feed) {
|
function addFeed(feed) {
|
||||||
|
|||||||
+28
-25
@@ -397,32 +397,35 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
|||||||
gameLogTable.value.vip
|
gameLogTable.value.vip
|
||||||
);
|
);
|
||||||
gameLogTable.value.loading = true;
|
gameLogTable.value.loading = true;
|
||||||
let vipList = [];
|
try {
|
||||||
if (gameLogTable.value.vip) {
|
let vipList = [];
|
||||||
vipList = Array.from(friendStore.localFavoriteFriends.values());
|
if (gameLogTable.value.vip) {
|
||||||
}
|
vipList = Array.from(friendStore.localFavoriteFriends.values());
|
||||||
const search = gameLogTable.value.search.trim();
|
}
|
||||||
let rows = [];
|
const search = gameLogTable.value.search.trim();
|
||||||
if (search) {
|
let rows = [];
|
||||||
rows = await database.searchGameLogDatabase(
|
if (search) {
|
||||||
search,
|
rows = await database.searchGameLogDatabase(
|
||||||
gameLogTable.value.filter,
|
search,
|
||||||
vipList,
|
gameLogTable.value.filter,
|
||||||
vrcxStore.searchLimit
|
vipList,
|
||||||
);
|
vrcxStore.searchLimit
|
||||||
} else {
|
);
|
||||||
rows = await database.lookupGameLogDatabase(
|
} else {
|
||||||
gameLogTable.value.filter,
|
rows = await database.lookupGameLogDatabase(
|
||||||
vipList
|
gameLogTable.value.filter,
|
||||||
);
|
vipList
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
row.isFriend = gameLogIsFriend(row);
|
row.isFriend = gameLogIsFriend(row);
|
||||||
row.isFavorite = gameLogIsFavorite(row);
|
row.isFavorite = gameLogIsFavorite(row);
|
||||||
|
}
|
||||||
|
gameLogTableData.value = rows;
|
||||||
|
} finally {
|
||||||
|
gameLogTable.value.loading = false;
|
||||||
}
|
}
|
||||||
gameLogTableData.value = rows;
|
|
||||||
gameLogTable.value.loading = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addGameLog(entry) {
|
function addGameLog(entry) {
|
||||||
@@ -475,7 +478,7 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function gameLogSearch(row) {
|
function gameLogSearch(row) {
|
||||||
const value = gameLogTable.value.search.toUpperCase();
|
const value = gameLogTable.value.search.trim().toUpperCase();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,9 @@
|
|||||||
:model-value="group.visibility === visibility"
|
:model-value="group.visibility === visibility"
|
||||||
indicator-position="right"
|
indicator-position="right"
|
||||||
@select="handleVisibilitySelection(group, visibility)">
|
@select="handleVisibilitySelection(group, visibility)">
|
||||||
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
|
<span>{{
|
||||||
|
t(`view.favorite.visibility.${visibility}`)
|
||||||
|
}}</span>
|
||||||
</DropdownMenuCheckboxItem>
|
</DropdownMenuCheckboxItem>
|
||||||
</DropdownMenuSubContent>
|
</DropdownMenuSubContent>
|
||||||
</DropdownMenuPortal>
|
</DropdownMenuPortal>
|
||||||
@@ -536,6 +538,7 @@
|
|||||||
import { Badge } from '../../components/ui/badge';
|
import { Badge } from '../../components/ui/badge';
|
||||||
import { Slider } from '../../components/ui/slider';
|
import { Slider } from '../../components/ui/slider';
|
||||||
import { Switch } from '../../components/ui/switch';
|
import { Switch } from '../../components/ui/switch';
|
||||||
|
import { debounce } from '../../shared/utils';
|
||||||
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
||||||
|
|
||||||
import AvatarExportDialog from './dialogs/AvatarExportDialog.vue';
|
import AvatarExportDialog from './dialogs/AvatarExportDialog.vue';
|
||||||
@@ -570,7 +573,6 @@
|
|||||||
favoriteAvatarGroups,
|
favoriteAvatarGroups,
|
||||||
localAvatarFavorites,
|
localAvatarFavorites,
|
||||||
selectedFavoriteAvatars,
|
selectedFavoriteAvatars,
|
||||||
avatarImportDialogInput,
|
|
||||||
isFavoriteLoading,
|
isFavoriteLoading,
|
||||||
localAvatarFavoriteGroups
|
localAvatarFavoriteGroups
|
||||||
} = storeToRefs(favoriteStore);
|
} = storeToRefs(favoriteStore);
|
||||||
@@ -582,7 +584,7 @@
|
|||||||
newLocalAvatarFavoriteGroup,
|
newLocalAvatarFavoriteGroup,
|
||||||
localAvatarFavoritesList,
|
localAvatarFavoritesList,
|
||||||
refreshFavorites,
|
refreshFavorites,
|
||||||
getLocalWorldFavorites,
|
getLocalAvatarFavorites,
|
||||||
handleFavoriteGroup,
|
handleFavoriteGroup,
|
||||||
checkInvalidLocalAvatars,
|
checkInvalidLocalAvatars,
|
||||||
removeInvalidLocalAvatars
|
removeInvalidLocalAvatars
|
||||||
@@ -979,7 +981,7 @@
|
|||||||
function handleGroupClick(type, key) {
|
function handleGroupClick(type, key) {
|
||||||
if (hasSearchInput.value) {
|
if (hasSearchInput.value) {
|
||||||
avatarFavoriteSearch.value = '';
|
avatarFavoriteSearch.value = '';
|
||||||
searchAvatarFavorites('');
|
doSearchAvatarFavorites('');
|
||||||
}
|
}
|
||||||
selectGroup(type, key, { userInitiated: true });
|
selectGroup(type, key, { userInitiated: true });
|
||||||
}
|
}
|
||||||
@@ -1031,7 +1033,7 @@
|
|||||||
|
|
||||||
function handleRefreshFavorites() {
|
function handleRefreshFavorites() {
|
||||||
refreshFavorites();
|
refreshFavorites();
|
||||||
getLocalWorldFavorites();
|
getLocalAvatarFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleVisibilitySelection(group, visibility) {
|
function handleVisibilitySelection(group, visibility) {
|
||||||
@@ -1264,7 +1266,7 @@
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchAvatarFavorites(value) {
|
function doSearchAvatarFavorites(value) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
avatarFavoriteSearch.value = value;
|
avatarFavoriteSearch.value = value;
|
||||||
}
|
}
|
||||||
@@ -1274,6 +1276,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const results = [];
|
const results = [];
|
||||||
|
const seen = new Set();
|
||||||
localAvatarFavoriteGroups.value.forEach((group) => {
|
localAvatarFavoriteGroups.value.forEach((group) => {
|
||||||
const favorites = localAvatarFavorites.value[group];
|
const favorites = localAvatarFavorites.value[group];
|
||||||
if (!favorites) {
|
if (!favorites) {
|
||||||
@@ -1289,7 +1292,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
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);
|
results.push(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1306,13 +1310,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
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);
|
results.push(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
avatarFavoriteSearchResults.value = results;
|
avatarFavoriteSearchResults.value = results;
|
||||||
}
|
}
|
||||||
|
const searchAvatarFavorites = debounce(doSearchAvatarFavorites, 200);
|
||||||
|
|
||||||
async function refreshLocalAvatarFavorites() {
|
async function refreshLocalAvatarFavorites() {
|
||||||
if (refreshingLocalFavorites.value) {
|
if (refreshingLocalFavorites.value) {
|
||||||
|
|||||||
@@ -148,7 +148,9 @@
|
|||||||
:model-value="group.visibility === visibility"
|
:model-value="group.visibility === visibility"
|
||||||
indicator-position="right"
|
indicator-position="right"
|
||||||
@select="handleVisibilitySelection(group, visibility)">
|
@select="handleVisibilitySelection(group, visibility)">
|
||||||
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
|
<span>{{
|
||||||
|
t(`view.favorite.visibility.${visibility}`)
|
||||||
|
}}</span>
|
||||||
</DropdownMenuCheckboxItem>
|
</DropdownMenuCheckboxItem>
|
||||||
</DropdownMenuSubContent>
|
</DropdownMenuSubContent>
|
||||||
</DropdownMenuPortal>
|
</DropdownMenuPortal>
|
||||||
@@ -325,12 +327,12 @@
|
|||||||
} from '../../components/ui/select';
|
} from '../../components/ui/select';
|
||||||
import { useAppearanceSettingsStore, useFavoriteStore, useModalStore, useUserStore } from '../../stores';
|
import { useAppearanceSettingsStore, useFavoriteStore, useModalStore, useUserStore } from '../../stores';
|
||||||
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '../../components/ui/resizable';
|
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '../../components/ui/resizable';
|
||||||
|
import { debounce, userImage } from '../../shared/utils';
|
||||||
import { Badge } from '../../components/ui/badge';
|
import { Badge } from '../../components/ui/badge';
|
||||||
import { Slider } from '../../components/ui/slider';
|
import { Slider } from '../../components/ui/slider';
|
||||||
import { Switch } from '../../components/ui/switch';
|
import { Switch } from '../../components/ui/switch';
|
||||||
import { favoriteRequest } from '../../api';
|
import { favoriteRequest } from '../../api';
|
||||||
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
||||||
import { userImage } from '../../shared/utils';
|
|
||||||
|
|
||||||
import FavoritesFriendItem from './components/FavoritesFriendItem.vue';
|
import FavoritesFriendItem from './components/FavoritesFriendItem.vue';
|
||||||
import FriendExportDialog from './dialogs/FriendExportDialog.vue';
|
import FriendExportDialog from './dialogs/FriendExportDialog.vue';
|
||||||
@@ -683,12 +685,12 @@
|
|||||||
function handleGroupClick(type, key) {
|
function handleGroupClick(type, key) {
|
||||||
if (hasSearchInput.value) {
|
if (hasSearchInput.value) {
|
||||||
friendFavoriteSearch.value = '';
|
friendFavoriteSearch.value = '';
|
||||||
searchFriendFavorites('');
|
doSearchFriendFavorites('');
|
||||||
}
|
}
|
||||||
selectGroup(type, key);
|
selectGroup(type, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchFriendFavorites(searchTerm) {
|
function doSearchFriendFavorites(searchTerm) {
|
||||||
const search = searchTerm.trim().toLowerCase();
|
const search = searchTerm.trim().toLowerCase();
|
||||||
if (search.length < 3) {
|
if (search.length < 3) {
|
||||||
friendFavoriteSearchResults.value = [];
|
friendFavoriteSearchResults.value = [];
|
||||||
@@ -703,6 +705,7 @@
|
|||||||
});
|
});
|
||||||
friendFavoriteSearchResults.value = filtered;
|
friendFavoriteSearchResults.value = filtered;
|
||||||
}
|
}
|
||||||
|
const searchFriendFavorites = debounce(doSearchFriendFavorites, 200);
|
||||||
|
|
||||||
function toggleFriendSelection(id, value) {
|
function toggleFriendSelection(id, value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
|||||||
@@ -148,7 +148,9 @@
|
|||||||
:model-value="group.visibility === visibility"
|
:model-value="group.visibility === visibility"
|
||||||
indicator-position="right"
|
indicator-position="right"
|
||||||
@select="handleVisibilitySelection(group, visibility)">
|
@select="handleVisibilitySelection(group, visibility)">
|
||||||
<span>{{ t(`view.favorite.visibility.${visibility}`) }}</span>
|
<span>{{
|
||||||
|
t(`view.favorite.visibility.${visibility}`)
|
||||||
|
}}</span>
|
||||||
</DropdownMenuCheckboxItem>
|
</DropdownMenuCheckboxItem>
|
||||||
</DropdownMenuSubContent>
|
</DropdownMenuSubContent>
|
||||||
</DropdownMenuPortal>
|
</DropdownMenuPortal>
|
||||||
@@ -470,6 +472,7 @@
|
|||||||
import { Badge } from '../../components/ui/badge';
|
import { Badge } from '../../components/ui/badge';
|
||||||
import { Slider } from '../../components/ui/slider';
|
import { Slider } from '../../components/ui/slider';
|
||||||
import { Switch } from '../../components/ui/switch';
|
import { Switch } from '../../components/ui/switch';
|
||||||
|
import { debounce } from '../../shared/utils';
|
||||||
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
import { useFavoritesCardScaling } from './composables/useFavoritesCardScaling.js';
|
||||||
|
|
||||||
import FavoritesWorldItem from './components/FavoritesWorldItem.vue';
|
import FavoritesWorldItem from './components/FavoritesWorldItem.vue';
|
||||||
@@ -813,7 +816,7 @@
|
|||||||
type: 'cards',
|
type: 'cards',
|
||||||
key: `local:${activeLocalGroupName.value}:${index}`,
|
key: `local:${activeLocalGroupName.value}:${index}`,
|
||||||
items: items.slice(index, index + safeColumns).map((favorite) => ({
|
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
|
favorite
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
@@ -939,7 +942,7 @@
|
|||||||
function handleGroupClick(type, key) {
|
function handleGroupClick(type, key) {
|
||||||
if (hasSearchInput.value) {
|
if (hasSearchInput.value) {
|
||||||
worldFavoriteSearch.value = '';
|
worldFavoriteSearch.value = '';
|
||||||
searchWorldFavorites('');
|
doSearchWorldFavorites('');
|
||||||
}
|
}
|
||||||
selectGroup(type, key, { userInitiated: true });
|
selectGroup(type, key, { userInitiated: true });
|
||||||
}
|
}
|
||||||
@@ -1171,7 +1174,7 @@
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchWorldFavorites(worldFavoriteSearch) {
|
function doSearchWorldFavorites(worldFavoriteSearch) {
|
||||||
const search = worldFavoriteSearch.trim().toLowerCase();
|
const search = worldFavoriteSearch.trim().toLowerCase();
|
||||||
if (search.length < 3) {
|
if (search.length < 3) {
|
||||||
worldFavoriteSearchResults.value = [];
|
worldFavoriteSearchResults.value = [];
|
||||||
@@ -1186,6 +1189,7 @@
|
|||||||
});
|
});
|
||||||
worldFavoriteSearchResults.value = filtered;
|
worldFavoriteSearchResults.value = filtered;
|
||||||
}
|
}
|
||||||
|
const searchWorldFavorites = debounce(doSearchWorldFavorites, 200);
|
||||||
|
|
||||||
function handleVisibilitySelection(group, visibility) {
|
function handleVisibilitySelection(group, visibility) {
|
||||||
const menuKey = remoteGroupMenuKey(group.key);
|
const menuKey = remoteGroupMenuKey(group.key);
|
||||||
|
|||||||
+10
-13
@@ -5,7 +5,6 @@ import { Button } from '../../components/ui/button';
|
|||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger
|
TooltipTrigger
|
||||||
} from '../../components/ui/tooltip';
|
} from '../../components/ui/tooltip';
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +23,7 @@ const { t } = i18n.global;
|
|||||||
const expandedRow = ({ row }) => {
|
const expandedRow = ({ row }) => {
|
||||||
const original = row.original;
|
const original = row.original;
|
||||||
const type = original.type;
|
const type = original.type;
|
||||||
|
const { showFullscreenImageDialog } = useGalleryStore();
|
||||||
if (type === 'GPS') {
|
if (type === 'GPS') {
|
||||||
return (
|
return (
|
||||||
<div class="pl-5 text-sm">
|
<div class="pl-5 text-sm">
|
||||||
@@ -81,7 +81,6 @@ const expandedRow = ({ row }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Avatar') {
|
if (type === 'Avatar') {
|
||||||
const { showFullscreenImageDialog } = useGalleryStore();
|
|
||||||
return (
|
return (
|
||||||
<div class="pl-5 text-sm">
|
<div class="pl-5 text-sm">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -243,16 +242,14 @@ export const columns = [
|
|||||||
const longText = formatDateFilter(createdAt, 'long');
|
const longText = formatDateFilter(createdAt, 'long');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span>{shortText}</span>
|
||||||
<span>{shortText}</span>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="right">
|
||||||
<TooltipContent side="right">
|
<span>{longText}</span>
|
||||||
<span>{longText}</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -280,7 +277,7 @@ export const columns = [
|
|||||||
const original = row.original;
|
const original = row.original;
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
class="cursor-pointer pr-2.5 cursor-pointer"
|
class="cursor-pointer pr-2.5"
|
||||||
onClick={() => showUserDialog(original.userId)}
|
onClick={() => showUserDialog(original.userId)}
|
||||||
>
|
>
|
||||||
{original.displayName}
|
{original.displayName}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Button } from '../../components/ui/button';
|
|||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger
|
TooltipTrigger
|
||||||
} from '../../components/ui/tooltip';
|
} from '../../components/ui/tooltip';
|
||||||
import { ArrowRight, ArrowUpDown, Trash2, X } from 'lucide-vue-next';
|
import { ArrowRight, ArrowUpDown, Trash2, X } from 'lucide-vue-next';
|
||||||
@@ -49,16 +48,14 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
|||||||
const longText = formatDateFilter(createdAt, 'long');
|
const longText = formatDateFilter(createdAt, 'long');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span>{shortText}</span>
|
||||||
<span>{shortText}</span>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="right">
|
||||||
<TooltipContent side="right">
|
<span>{longText}</span>
|
||||||
<span>{longText}</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="friend-card__header">
|
<div class="friend-card__header">
|
||||||
<div>
|
<div>
|
||||||
<Avatar class="friend-card__avatar" :style="{ width: `${avatarSize}px`, height: `${avatarSize}px` }">
|
<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>
|
<AvatarFallback>{{ avatarFallback }}</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { Button } from '../../components/ui/button';
|
|||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger
|
TooltipTrigger
|
||||||
} from '../../components/ui/tooltip';
|
} from '../../components/ui/tooltip';
|
||||||
import { ArrowUpDown, FileText, Trash2, X } from 'lucide-vue-next';
|
import { ArrowUpDown, FileText, Trash2, X } from 'lucide-vue-next';
|
||||||
@@ -65,16 +64,14 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
|||||||
const longText = formatDateFilter(createdAt, 'long');
|
const longText = formatDateFilter(createdAt, 'long');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span>{shortText}</span>
|
||||||
<span>{shortText}</span>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="right">
|
||||||
<TooltipContent side="right">
|
<span>{longText}</span>
|
||||||
<span>{longText}</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -275,30 +272,26 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
|||||||
</button>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
{canShowPrevious ? (
|
{canShowPrevious ? (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={() =>
|
||||||
onClick={() =>
|
showPreviousInstancesInfoDialog(
|
||||||
showPreviousInstancesInfoDialog(
|
original.location
|
||||||
original.location
|
)
|
||||||
)
|
}
|
||||||
}
|
>
|
||||||
>
|
<FileText class="h-4 w-4" />
|
||||||
<FileText class="h-4 w-4" />
|
</button>
|
||||||
</button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
<span>
|
||||||
<span>
|
{t('dialog.previous_instances.info')}
|
||||||
{t(
|
</span>
|
||||||
'dialog.previous_instances.info'
|
</TooltipContent>
|
||||||
)}
|
</Tooltip>
|
||||||
</span>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Button } from '../../components/ui/button';
|
|||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger
|
TooltipTrigger
|
||||||
} from '../../components/ui/tooltip';
|
} from '../../components/ui/tooltip';
|
||||||
import { ArrowUpDown, Trash2, X } from 'lucide-vue-next';
|
import { ArrowUpDown, Trash2, X } from 'lucide-vue-next';
|
||||||
@@ -50,16 +49,14 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
|||||||
const longText = formatDateFilter(createdAt, 'long');
|
const longText = formatDateFilter(createdAt, 'long');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span>{shortText}</span>
|
||||||
<span>{shortText}</span>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="right">
|
||||||
<TooltipContent side="right">
|
<span>{longText}</span>
|
||||||
<span>{longText}</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -438,7 +438,8 @@
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
handleNotificationHide({ params });
|
handleNotificationHide({ params });
|
||||||
notificationRequest.hideNotificationV2(params.notificationId);
|
notificationRequest.hideNotificationV2(params.notificationId);
|
||||||
throw err;
|
console.error('Notification response failed', err);
|
||||||
|
toast.error('Error');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+224
-251
@@ -4,7 +4,6 @@ import { Button } from '../../components/ui/button';
|
|||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
TooltipWrapper
|
TooltipWrapper
|
||||||
} from '../../components/ui/tooltip';
|
} from '../../components/ui/tooltip';
|
||||||
@@ -129,16 +128,14 @@ export const createColumns = ({
|
|||||||
const longText = formatDateFilter(createdAt, 'long');
|
const longText = formatDateFilter(createdAt, 'long');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span>{shortText}</span>
|
||||||
<span>{shortText}</span>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="right">
|
||||||
<TooltipContent side="right">
|
<span>{longText}</span>
|
||||||
<span>{longText}</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -164,32 +161,28 @@ export const createColumns = ({
|
|||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<Badge variant="outline" class="text-muted-foreground">
|
<Badge variant="outline" class="text-muted-foreground">
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span
|
||||||
<span
|
class="cursor-pointer"
|
||||||
class="cursor-pointer"
|
onClick={() =>
|
||||||
onClick={() =>
|
showWorldDialog(original.location)
|
||||||
showWorldDialog(
|
}
|
||||||
original.location
|
>
|
||||||
)
|
{label}
|
||||||
}
|
</span>
|
||||||
>
|
</TooltipTrigger>
|
||||||
{label}
|
<TooltipContent side="top">
|
||||||
</span>
|
{original.location ? (
|
||||||
</TooltipTrigger>
|
<Location
|
||||||
<TooltipContent side="top">
|
location={original.location}
|
||||||
{original.location ? (
|
hint={original.worldName}
|
||||||
<Location
|
grouphint={original.groupName}
|
||||||
location={original.location}
|
link={true}
|
||||||
hint={original.worldName}
|
/>
|
||||||
grouphint={original.groupName}
|
) : null}
|
||||||
link={true}
|
</TooltipContent>
|
||||||
/>
|
</Tooltip>
|
||||||
) : null}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -197,25 +190,21 @@ export const createColumns = ({
|
|||||||
if (original.link) {
|
if (original.link) {
|
||||||
return (
|
return (
|
||||||
<Badge variant="outline" class="text-muted-foreground">
|
<Badge variant="outline" class="text-muted-foreground">
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<span
|
||||||
<span
|
class="cursor-pointer"
|
||||||
class="cursor-pointer"
|
onClick={() =>
|
||||||
onClick={() =>
|
openNotificationLink(original.link)
|
||||||
openNotificationLink(
|
}
|
||||||
original.link
|
>
|
||||||
)
|
{label}
|
||||||
}
|
</span>
|
||||||
>
|
</TooltipTrigger>
|
||||||
{label}
|
<TooltipContent side="top">
|
||||||
</span>
|
<span>{original.linkText}</span>
|
||||||
</TooltipTrigger>
|
</TooltipContent>
|
||||||
<TooltipContent side="top">
|
</Tooltip>
|
||||||
<span>{original.linkText}</span>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -548,41 +537,88 @@ export const createColumns = ({
|
|||||||
!original.$isExpired ? (
|
!original.$isExpired ? (
|
||||||
<span class="inline-flex items-center gap-2">
|
<span class="inline-flex items-center gap-2">
|
||||||
{original.type === 'friendRequest' ? (
|
{original.type === 'friendRequest' ? (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={() =>
|
||||||
onClick={() =>
|
acceptFriendRequestNotification(
|
||||||
acceptFriendRequestNotification(
|
original
|
||||||
original
|
)
|
||||||
)
|
}
|
||||||
}
|
>
|
||||||
>
|
<Check class="h-4 w-4" />
|
||||||
<Check class="h-4 w-4" />
|
</button>
|
||||||
</button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
<span>
|
||||||
<span>
|
{t(
|
||||||
{t(
|
'view.notification.actions.accept'
|
||||||
'view.notification.actions.accept'
|
)}
|
||||||
)}
|
</span>
|
||||||
</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{original.type === 'invite' ? (
|
{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>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
showSendInviteResponseDialog(
|
showSendInviteRequestResponseDialog(
|
||||||
original
|
original
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -598,61 +634,6 @@ export const createColumns = ({
|
|||||||
</span>
|
</span>
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</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>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@@ -687,136 +668,128 @@ export const createColumns = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider
|
<Tooltip
|
||||||
key={`${response.text}:${response.type}`}
|
key={`${response.text}:${response.type}`}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={onClick}
|
||||||
onClick={onClick}
|
>
|
||||||
>
|
<ResponseIcon class="h-4 w-4" />
|
||||||
<ResponseIcon class="h-4 w-4" />
|
</button>
|
||||||
</button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
<span>
|
||||||
<span>
|
{response.text}
|
||||||
{response.text}
|
</span>
|
||||||
</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
{showDecline ? (
|
{showDecline ? (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={() =>
|
||||||
onClick={() =>
|
shiftHeld.value
|
||||||
|
? hideNotification(
|
||||||
|
original
|
||||||
|
)
|
||||||
|
: hideNotificationPrompt(
|
||||||
|
original
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<X
|
||||||
|
class={
|
||||||
shiftHeld.value
|
shiftHeld.value
|
||||||
? hideNotification(
|
? 'h-4 w-4 text-red-600'
|
||||||
original
|
: 'h-4 w-4'
|
||||||
)
|
|
||||||
: hideNotificationPrompt(
|
|
||||||
original
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<X
|
</button>
|
||||||
class={
|
</TooltipTrigger>
|
||||||
shiftHeld.value
|
<TooltipContent side="top">
|
||||||
? 'h-4 w-4 text-red-600'
|
<span>
|
||||||
: 'h-4 w-4'
|
{t(
|
||||||
}
|
'view.notification.actions.decline'
|
||||||
/>
|
)}
|
||||||
</button>
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipContent>
|
||||||
<TooltipContent side="top">
|
</Tooltip>
|
||||||
<span>
|
|
||||||
{t(
|
|
||||||
'view.notification.actions.decline'
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{original.type === 'group.queueReady' ? (
|
{original.type === 'group.queueReady' ? (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={() =>
|
||||||
onClick={() =>
|
shiftHeld.value
|
||||||
shiftHeld.value
|
? deleteNotificationLog(
|
||||||
? deleteNotificationLog(
|
original
|
||||||
original
|
)
|
||||||
)
|
: deleteNotificationLogPrompt(
|
||||||
: deleteNotificationLogPrompt(
|
original
|
||||||
original
|
)
|
||||||
)
|
}
|
||||||
}
|
>
|
||||||
>
|
{shiftHeld.value ? (
|
||||||
{shiftHeld.value ? (
|
<X class="h-4 w-4 text-red-600" />
|
||||||
<X class="h-4 w-4 text-red-600" />
|
) : (
|
||||||
) : (
|
<Trash2 class="h-4 w-4" />
|
||||||
<Trash2 class="h-4 w-4" />
|
)}
|
||||||
)}
|
</button>
|
||||||
</button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
<span>
|
||||||
<span>
|
{t(
|
||||||
{t(
|
'view.notification.actions.delete_log'
|
||||||
'view.notification.actions.delete_log'
|
)}
|
||||||
)}
|
</span>
|
||||||
</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
) : null}
|
) : null}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
{showDeleteLog ? (
|
{showDeleteLog ? (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
||||||
class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
|
onClick={() =>
|
||||||
onClick={() =>
|
shiftHeld.value
|
||||||
shiftHeld.value
|
? deleteNotificationLog(
|
||||||
? deleteNotificationLog(
|
original
|
||||||
original
|
)
|
||||||
)
|
: deleteNotificationLogPrompt(
|
||||||
: deleteNotificationLogPrompt(
|
original
|
||||||
original
|
)
|
||||||
)
|
}
|
||||||
}
|
>
|
||||||
>
|
{shiftHeld.value ? (
|
||||||
{shiftHeld.value ? (
|
<X class="h-4 w-4 text-red-600" />
|
||||||
<X class="h-4 w-4 text-red-600" />
|
) : (
|
||||||
) : (
|
<Trash2 class="h-4 w-4" />
|
||||||
<Trash2 class="h-4 w-4" />
|
)}
|
||||||
)}
|
</button>
|
||||||
</button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="top">
|
||||||
<TooltipContent side="top">
|
<span>
|
||||||
<span>
|
{t(
|
||||||
{t(
|
'view.notification.actions.delete_log'
|
||||||
'view.notification.actions.delete_log'
|
)}
|
||||||
)}
|
</span>
|
||||||
</span>
|
</TooltipContent>
|
||||||
</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -75,7 +75,8 @@
|
|||||||
await inviteMessagesRequest
|
await inviteMessagesRequest
|
||||||
.editInviteMessage(params, messageType, slot)
|
.editInviteMessage(params, messageType, slot)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw err;
|
console.error('Invite response message update failed', err);
|
||||||
|
toast.error('Error');
|
||||||
})
|
})
|
||||||
.then((args) => {
|
.then((args) => {
|
||||||
if (args.json[slot].message === I.messageSlot.message) {
|
if (args.json[slot].message === I.messageSlot.message) {
|
||||||
@@ -96,7 +97,8 @@
|
|||||||
notificationRequest
|
notificationRequest
|
||||||
.sendInviteResponsePhoto(params, I.invite.id)
|
.sendInviteResponsePhoto(params, I.invite.id)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw err;
|
console.error('Invite response photo failed', err);
|
||||||
|
toast.error('Error');
|
||||||
})
|
})
|
||||||
.then((args) => {
|
.then((args) => {
|
||||||
notificationRequest.hideNotification({
|
notificationRequest.hideNotification({
|
||||||
@@ -112,7 +114,8 @@
|
|||||||
notificationRequest
|
notificationRequest
|
||||||
.sendInviteResponse(params, I.invite.id)
|
.sendInviteResponse(params, I.invite.id)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw err;
|
console.error('Invite response failed', err);
|
||||||
|
toast.error('Error');
|
||||||
})
|
})
|
||||||
.then((args) => {
|
.then((args) => {
|
||||||
notificationRequest.hideNotification({
|
notificationRequest.hideNotification({
|
||||||
|
|||||||
@@ -61,7 +61,8 @@
|
|||||||
notificationRequest
|
notificationRequest
|
||||||
.sendInviteResponsePhoto(params, D.invite.id)
|
.sendInviteResponsePhoto(params, D.invite.id)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw err;
|
console.error('Invite response photo failed', err);
|
||||||
|
toast.error(t('message.error'));
|
||||||
})
|
})
|
||||||
.then((args) => {
|
.then((args) => {
|
||||||
notificationRequest.hideNotification({
|
notificationRequest.hideNotification({
|
||||||
@@ -77,7 +78,8 @@
|
|||||||
notificationRequest
|
notificationRequest
|
||||||
.sendInviteResponse(params, D.invite.id)
|
.sendInviteResponse(params, D.invite.id)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw err;
|
console.error('Invite response failed', err);
|
||||||
|
toast.error('Error');
|
||||||
})
|
})
|
||||||
.then((args) => {
|
.then((args) => {
|
||||||
notificationRequest.hideNotification({
|
notificationRequest.hideNotification({
|
||||||
|
|||||||
@@ -31,12 +31,12 @@
|
|||||||
}}</span>
|
}}</span>
|
||||||
<span v-if="!item.ref.isFriend" class="block truncate text-xs"></span>
|
<span v-if="!item.ref.isFriend" class="block truncate text-xs"></span>
|
||||||
<span
|
<span
|
||||||
v-else-if="item.ref.state === 'offline'"
|
v-else-if="item.ref.state === 'active'"
|
||||||
class="block truncate text-xs"
|
class="block truncate text-xs"
|
||||||
>{{ t('side_panel.search_result_active') }}</span
|
>{{ t('side_panel.search_result_active') }}</span
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
v-else-if="item.ref.state === 'active'"
|
v-else-if="item.ref.state === 'offline'"
|
||||||
class="block truncate text-xs"
|
class="block truncate text-xs"
|
||||||
>{{ t('side_panel.search_result_offline') }}</span
|
>{{ t('side_panel.search_result_offline') }}</span
|
||||||
>
|
>
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { useFriendStore, useGroupStore, useSearchStore } from '../../stores';
|
import { useFriendStore, useGroupStore, useSearchStore } from '../../stores';
|
||||||
import { userImage } from '../../shared/utils';
|
import { debounce, userImage } from '../../shared/utils';
|
||||||
|
|
||||||
import FriendsSidebar from './components/FriendsSidebar.vue';
|
import FriendsSidebar from './components/FriendsSidebar.vue';
|
||||||
import GroupsSidebar from './components/GroupsSidebar.vue';
|
import GroupsSidebar from './components/GroupsSidebar.vue';
|
||||||
@@ -139,13 +139,18 @@
|
|||||||
const quickSearchQuery = ref('');
|
const quickSearchQuery = ref('');
|
||||||
const isQuickSearchOpen = ref(false);
|
const isQuickSearchOpen = ref(false);
|
||||||
|
|
||||||
watch(
|
const runQuickSearch = debounce((value) => {
|
||||||
quickSearchQuery,
|
quickSearchRemoteMethod(value);
|
||||||
(value) => {
|
}, 200);
|
||||||
quickSearchRemoteMethod(String(value ?? ''));
|
|
||||||
},
|
watch(quickSearchQuery, (value) => {
|
||||||
{ immediate: true }
|
const query = String(value ?? '').trim();
|
||||||
);
|
if (!query) {
|
||||||
|
quickSearchRemoteMethod('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runQuickSearch(query);
|
||||||
|
});
|
||||||
|
|
||||||
function handleQuickSearchSelect(value) {
|
function handleQuickSearchSelect(value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
|||||||
@@ -68,6 +68,9 @@
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import Location from '@/components/Location.vue';
|
||||||
|
import Timer from '@/components/Timer.vue';
|
||||||
|
|
||||||
import { useAppearanceSettingsStore, useFriendStore, useUserStore } from '../../../stores';
|
import { useAppearanceSettingsStore, useFriendStore, useUserStore } from '../../../stores';
|
||||||
import { userImage, userStatusClass } from '../../../shared/utils';
|
import { userImage, userStatusClass } from '../../../shared/utils';
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else-if="item.row.type === 'friend-item'">
|
<template v-else-if="item.row.type === 'friend-item'">
|
||||||
<friend-item
|
<FriendItem
|
||||||
:friend="item.row.friend"
|
:friend="item.row.friend"
|
||||||
:style="item.row.itemStyle"
|
:style="item.row.itemStyle"
|
||||||
:is-group-by-instance="item.row.isGroupByInstance" />
|
:is-group-by-instance="item.row.isGroupByInstance" />
|
||||||
|
|||||||
@@ -161,7 +161,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding: 0 12x 0 12px;
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.date {
|
.date {
|
||||||
|
|||||||
Reference in New Issue
Block a user