clean up sidebar css

This commit is contained in:
pa
2026-03-08 20:12:34 +09:00
parent 08033e99b6
commit 3d3ad27ca0
4 changed files with 114 additions and 21 deletions

View File

@@ -0,0 +1,69 @@
/*
* Status icon styles for avatar status indicator dots and mask cutouts.
*/
.status-icon::after {
position: absolute;
right: 0.75px;
bottom: 0.75px;
width: 9px;
height: 9px;
content: '';
background: var(--status-offline);
border-radius: 50%;
}
.status-icon.active::after {
background: var(--status-active);
}
.status-icon.online::after {
background: var(--status-online);
}
.status-icon.joinme::after {
background: var(--status-joinme);
mask-image: url(/images/masks/joinme.svg);
}
.status-icon.askme::after {
background: var(--status-askme);
mask-image: url(/images/masks/askme.svg);
}
.status-icon.busy::after {
background: var(--status-busy);
mask-image: url(/images/masks/busy.svg);
}
.status-icon.offline::after {
background: var(--status-offline);
}
.active img,
.offline img {
filter: grayscale(1);
}
.friend-row:hover .active img,
.friend-row:hover .offline img {
filter: none;
}
/* Avatar mask cutout for status dot */
.status-icon img {
mask-image: url(/images/masks/usercutout.svg);
}
.status-icon.mobile img {
mask-image: url(/images/masks/usercutoutmobile.svg);
}
.status-icon.mobile::after {
right: -2px;
bottom: -0.5px;
width: 14px;
height: 14px;
border-radius: 0;
mask-image: url(/images/masks/phone.svg) !important;
}

View File

@@ -1,8 +1,10 @@
<template>
<div class="x-friend-item hover:bg-muted/50" @click="showUserDialog(friend.id)">
<div
class="box-border flex items-center p-1.5 text-[13px] cursor-pointer hover:bg-muted/50 hover:rounded-lg"
@click="showUserDialog(friend.id)">
<template v-if="friend.ref">
<div
class="avatar"
class="relative inline-block flex-none size-9 mr-2.5"
:class="isFriendActiveOrOffline ? undefined : userStatusClass(friend.ref, friend.pendingOffline)">
<Avatar class="size-full rounded-full">
<AvatarImage :src="userImage(friend.ref, true)" class="object-cover" />
@@ -11,11 +13,17 @@
</AvatarFallback>
</Avatar>
</div>
<div class="detail h-9 flex flex-col justify-between">
<span v-if="!hideNicknames && friend.$nickName" class="name" :style="{ color: friend.ref.$userColour }">
<div class="flex-1 overflow-hidden h-9 flex flex-col justify-between">
<span
v-if="!hideNicknames && friend.$nickName"
class="block truncate font-medium leading-[18px]"
:style="{ color: friend.ref.$userColour }">
{{ friend.ref.displayName }} ({{ friend.$nickName }})
</span>
<span v-else class="name" :style="{ color: friend.ref.$userColour }"
<span
v-else
class="block truncate font-medium leading-[18px]"
:style="{ color: friend.ref.$userColour }"
>{{ friend.ref.displayName
}}{{ isGroupByInstance && allFavoriteFriendIds.has(friend.id) ? ' ⭐' : '' }}</span
>
@@ -71,6 +79,8 @@
import { useAppearanceSettingsStore, useFriendStore, useUserStore } from '../../../stores';
import { userImage, userStatusClass } from '../../../shared/utils';
import '@/styles/status-icon.css';
const props = defineProps({
friend: { type: Object, required: true },
isGroupByInstance: Boolean

View File

@@ -1,7 +1,7 @@
<template>
<div class="relative h-full">
<div ref="scrollViewportRef" class="h-full w-full overflow-auto">
<div class="x-friend-list px-1.5 py-2.5">
<div class="px-1.5 py-2.5">
<div v-if="virtualRows.length" class="relative w-full box-border" :style="virtualContainerStyle">
<template v-for="item in virtualItems" :key="String(item.virtualItem.key)">
<div
@@ -12,7 +12,7 @@
:style="rowStyle(item)">
<template v-if="item.row.type === 'toggle-header'">
<div
class="x-friend-group flex cursor-pointer items-center pt-4 pb-1.5 text-xs"
class="flex cursor-pointer items-center pt-4 pb-1.5 text-xs"
:style="item.row.headerPadding ? { padding: item.row.headerPadding } : undefined"
@click="item.row.onClick && item.row.onClick()">
<ChevronDown
@@ -31,15 +31,22 @@
<ContextMenu>
<ContextMenuTrigger as-child>
<div
class="x-friend-item hover:bg-muted/50"
class="friend-row box-border flex items-center p-1.5 text-[13px] cursor-pointer hover:bg-muted/50 hover:rounded-lg"
@click="showUserDialog(currentUser.id)">
<div class="avatar" :class="userStatusClass(currentUser)">
<img :src="userImage(currentUser)" loading="lazy" />
<div
class="relative inline-block flex-none size-9 mr-2.5"
:class="userStatusClass(currentUser)">
<img
class="size-full rounded-full object-cover"
:src="userImage(currentUser)"
loading="lazy" />
</div>
<div class="detail h-9 flex flex-col justify-between">
<span class="name" :style="{ color: currentUser.$userColour }">{{
currentUser.displayName
}}</span>
<div class="flex-1 overflow-hidden h-9 flex flex-col justify-between">
<span
class="block truncate font-medium leading-[18px]"
:style="{ color: currentUser.$userColour }"
>{{ currentUser.displayName }}</span
>
<Location
v-if="isGameRunning && !gameLogDisabled"
class="extra block truncate text-xs"
@@ -208,6 +215,8 @@
import Location from '../../../components/Location.vue';
import configRepository from '../../../service/config';
import '@/styles/status-icon.css';
const { t } = useI18n();
const friendStore = useFriendStore();

View File

@@ -1,7 +1,7 @@
<template>
<div ref="scrollRootRef" class="relative h-full">
<div ref="scrollViewportRef" class="h-full w-full overflow-auto">
<div class="x-friend-list px-1.5 py-2.5">
<div class="px-1.5 py-2.5">
<div v-if="virtualRows.length" class="relative w-full box-border" :style="virtualContainerStyle">
<template v-for="item in virtualItems" :key="String(item.virtualItem.key)">
<div
@@ -12,7 +12,7 @@
:style="rowStyle(item)">
<template v-if="item.row.type === 'group-header'">
<div
class="x-friend-group cursor-pointer pt-4 pb-1.5 text-xs"
class="cursor-pointer pt-4 pb-1.5 text-xs"
:style="
item.row.headerPaddingTop
? { paddingTop: item.row.headerPaddingTop }
@@ -32,13 +32,18 @@
<template v-else-if="item.row.type === 'group-item'">
<ContextMenu>
<ContextMenuTrigger as-child>
<div class="x-friend-item" @click="showGroupDialog(item.row.ownerId)">
<div
class="box-border flex items-center p-1.5 text-[13px] cursor-pointer hover:bg-muted/50 hover:rounded-lg"
@click="showGroupDialog(item.row.ownerId)">
<template v-if="item.row.isVisible">
<div class="avatar">
<img :src="getSmallGroupIconUrl(item.row.iconUrl)" loading="lazy" />
<div class="relative inline-block flex-none size-9 mr-2.5">
<img
class="size-full rounded-full object-cover"
:src="getSmallGroupIconUrl(item.row.iconUrl)"
loading="lazy" />
</div>
<div class="detail">
<span class="name">
<div class="flex-1 overflow-hidden">
<span class="block truncate font-medium leading-[18px]">
<span v-text="item.row.name"></span>
<span class="ml-1.5 font-normal">
({{ item.row.userCount }}/{{ item.row.capacity }})