Анимации, профиль, медиа

This commit is contained in:
Халимов Рустам
2026-04-02 02:37:03 +03:00
parent 4ae7dd60ce
commit 9df7d7aaf1
24 changed files with 1365 additions and 1527 deletions
+18 -4
View File
@@ -17,11 +17,25 @@ export class AppApi {
});
}
static async getTrendingGifs() {
return httpClient.request<any>('/klipy/trending');
static async getTrendingGifs(page: number = 1) {
return httpClient.request<any>(`/klipy/trending?page=${page}`);
}
static async searchKlipyGifs(query: string) {
return httpClient.request<any>(`/klipy/search?q=${encodeURIComponent(query)}`);
static async searchKlipyGifs(query: string, page: number = 1) {
return httpClient.request<any>(`/klipy/search?q=${encodeURIComponent(query)}&page=${page}`);
}
static async getRecentGifs(page: number = 1) {
return httpClient.request<any>(`/klipy/recent?page=${page}`);
}
static async getGifCategories(countryCode: string = 'RU') {
return httpClient.request<any>(`/klipy/categories?countryCode=${countryCode}`);
}
static async markGifShared(gifId: string, query: string = '') {
return httpClient.request<void>(`/klipy/${gifId}/share?q=${encodeURIComponent(query)}`, {
method: 'POST'
});
}
}
@@ -40,7 +40,7 @@ function AvatarInner({ src, name, size = 'md', className = '', online }: AvatarP
/>
) : (
<div
className={`${sizeClass} rounded-full bg-gradient-to-br from-primary/80 to-primary flex items-center justify-center text-on-primary font-bold tracking-tighter`}
className={`${sizeClass} rounded-full ${gradientClass} flex items-center justify-center text-on-primary font-black tracking-tighter shadow-inner`}
>
{initials}
</div>
@@ -46,7 +46,7 @@ export default function ImageLightbox({ url, images, initialIndex = 0, onClose }
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-[9999] bg-black flex items-center justify-center"
className="fixed inset-0 z-[20000] bg-black flex items-center justify-center"
onClick={onClose}
>
{/* Top bar */}
@@ -165,9 +165,9 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{/* ── Premium header with avatar ── */}
<div className="relative overflow-hidden flex-shrink-0">
{/* Animated gradient backdrop */}
<div className="absolute inset-0 bg-gradient-to-br from-knot-500/40 via-purple-600/25 to-transparent pointer-events-none" />
<div className="absolute -top-20 -right-20 w-56 h-56 bg-knot-500/15 rounded-full blur-[80px] pointer-events-none" />
<div className="absolute -bottom-10 -left-10 w-40 h-40 bg-purple-600/10 rounded-full blur-[60px] pointer-events-none" />
<div className="absolute inset-0 bg-gradient-to-br from-primary/30 via-primary-container/20 to-transparent pointer-events-none" />
<div className="absolute -top-20 -right-20 w-56 h-56 bg-primary/10 rounded-full blur-[80px] pointer-events-none" />
<div className="absolute -bottom-10 -left-10 w-40 h-40 bg-primary-container/10 rounded-full blur-[60px] pointer-events-none" />
<div className="relative p-6 pb-5">
<div className="flex items-start justify-between mb-5">
@@ -178,9 +178,8 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{user?.avatar ? (
<img src={user.avatar} alt="" className="w-[72px] h-[72px] rounded-full object-cover ring-[3px] ring-surface" />
) : (
<div className="w-[72px] h-[72px] rounded-full bg-gradient-to-br from-surface to-surface-secondary flex items-center justify-center ring-[3px] ring-surface relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-tr from-accent/20 to-purple-500/20" />
<span className="relative z-10 text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-br from-white to-zinc-400 drop-shadow-md">{initials}</span>
<div className="w-[72px] h-[72px] rounded-full bg-linear-to-br from-primary/80 to-primary flex items-center justify-center ring-[3px] ring-surface relative overflow-hidden">
<span className="relative z-10 text-2xl font-black text-on-primary drop-shadow-md">{initials}</span>
</div>
)}
</div>
@@ -223,7 +222,7 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{item.subtitle && <p className="text-[11px] text-zinc-500 mt-0.5">{item.subtitle}</p>}
</div>
{'badge' in item && item.badge ? (
<span className="bg-gradient-to-r from-knot-500 to-purple-600 text-white text-[11px] font-bold min-w-[22px] h-[22px] px-1.5 rounded-full flex items-center justify-center flex-shrink-0 shadow-[0_0_12px_rgba(168,85,247,0.4)]">
<span className="bg-linear-to-r from-primary to-primary-container text-on-primary text-[11px] font-black min-w-[22px] h-[22px] px-1.5 rounded-full flex items-center justify-center flex-shrink-0 shadow-[0_0_12px_rgba(var(--color-primary),0.4)]">
{item.badge}
</span>
) : (
@@ -521,7 +520,7 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{u.avatar ? (
<img src={u.avatar} alt="" className="w-10 h-10 rounded-full object-cover" />
) : (
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-knot-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm">
<div className="w-10 h-10 rounded-full bg-linear-to-br from-primary/80 to-primary flex items-center justify-center text-on-primary font-black text-sm">
{(u.displayName || u.username || '?')[0].toUpperCase()}
</div>
)}
@@ -556,7 +555,7 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{req.user.avatar ? (
<img src={req.user.avatar} alt="" className="w-10 h-10 rounded-full object-cover" />
) : (
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-knot-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm">
<div className="w-10 h-10 rounded-full bg-linear-to-br from-primary/80 to-primary flex items-center justify-center text-on-primary font-black text-sm">
{(req.user.displayName || req.user.username || '?')[0].toUpperCase()}
</div>
)}
@@ -601,7 +600,7 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
{friend.avatar ? (
<img src={friend.avatar} alt="" className="w-10 h-10 rounded-full object-cover" />
) : (
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-knot-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm">
<div className="w-10 h-10 rounded-full bg-linear-to-br from-primary/80 to-primary flex items-center justify-center text-on-primary font-black text-sm">
{(friend.displayName || friend.username || '?')[0].toUpperCase()}
</div>
)}
+8 -8
View File
@@ -71,14 +71,14 @@ export function getInitials(name: string): string {
export function generateAvatarColor(name: string): string {
const colors = [
'from-violet-500 to-purple-600',
'from-blue-500 to-indigo-600',
'from-emerald-500 to-teal-600',
'from-rose-500 to-pink-600',
'from-amber-500 to-orange-600',
'from-cyan-500 to-blue-600',
'from-fuchsia-500 to-purple-600',
'from-lime-500 to-green-600',
'bg-linear-to-br from-blue-400 to-blue-600',
'bg-linear-to-br from-sky-400 to-sky-600',
'bg-linear-to-br from-cyan-400 to-blue-600',
'bg-linear-to-br from-blue-500 to-indigo-600',
'bg-linear-to-br from-emerald-400 to-blue-600',
'bg-linear-to-br from-blue-600 to-primary-container',
'bg-linear-to-br from-primary to-primary-container',
'bg-linear-to-br from-blue-400 to-cyan-500',
];
let hash = 0;