smart smart method by google gemini

This commit is contained in:
2025-07-24 06:25:14 +03:00
parent d1f925f298
commit 980b27bf84
14 changed files with 294 additions and 60 deletions

View File

@@ -3,6 +3,8 @@ import { useFriendsHome } from "@/hooks/roblox/useFriendsHome";
import LazyLoadedImage from "./lazyLoadedImage";
import React from "react";
import { VerifiedIcon } from "./RobloxIcons";
import { useFriendsPresence } from "@/hooks/roblox/usePresence";
import { StupidHoverThing } from "./MiscStuff";
export function FriendsHomeSect(
props: React.DetailedHTMLProps<
@@ -12,6 +14,9 @@ export function FriendsHomeSect(
) {
const friends = useFriendsHome();
const acct = useCurrentAccount();
const presence = useFriendsPresence(
(!!friends ? friends : []).map((f) => f.id)
);
if (!friends) {
return <></>;
@@ -19,35 +24,93 @@ export function FriendsHomeSect(
return (
<div {...props}>
{/* <button onClick={()=>console.log(acct,presence,friends)}>debug</button> */}
<h1 className="text-2xl pb-2 pl-4">Friends</h1>
<div className="bg-base p-4 rounded-xl flex flex-col gap-2 px-4">
<div className="bg-base p-4 rounded-xl flex flex-col gap-2 px-4 no-scrollbar">
<div
className="flex items-center gap-4 overflow-x-auto pb-2 -mx-4 w-screen scrollbar-thin scrollbar-thumb-surface2 scrollbar-track-surface0"
className="flex items-center gap-4 overflow-x-auto overflow-y-visible no-scrollbar pb-2 -mx-4 w-screen scrollbar-thin scrollbar-thumb-surface2 scrollbar-track-surface0"
style={{
scrollSnapType: "x mandatory",
WebkitOverflowScrolling: "touch"
WebkitOverflowScrolling: "touch",
scrollbarWidth: "none"
}}
>
<div className="w-8" />
{friends.map((a) => (
<div
key={a.id}
className="flex flex-col items-center min-w-[6.5rem]"
// style={{ scrollSnapAlign: "start" }}
>
<LazyLoadedImage
imgId={`AvatarHeadShot_${a.id}`}
alt={a.name}
className="w-24 h-24 rounded-full border-2 border-surface2 object-cover shadow"
/>
<span className="truncate text-xs text-text mt-1 text-center flex items-center justify-center gap-1">
{a.displayName || a.name}
{a.hasVerifiedBadge ? null : (
<VerifiedIcon className="text-base fill-blue w-3 h-3" />
)}
</span>
</div>
))}
{friends.map((a) => {
const userStatus = presence.find(
(b) => b.userId === a.id
);
const userPresence = userStatus?.userPresenceType || 0;
const borderColor =
userPresence === 1
? "border-blue bg-blue/50"
: userPresence === 2
? "border-green bg-green/50"
: userPresence === 3
? "border-yellow bg-yellow/50"
: userPresence === 0
? "border-surface2 bg-surface2/50"
: "border-red bg-red/50";
const textColor =
userPresence === 1
? "text-blue"
: userPresence === 2
? "text-green"
: userPresence === 3
? "text-yellow"
: userPresence === 0
? "text-surface2"
: "text-red";
const fillColor =
userPresence === 1
? "fill-blue"
: userPresence === 2
? "fill-green"
: userPresence === 3
? "fill-yellow"
: userPresence === 0
? "fill-surface2"
: "fill-red";
return (
<div
key={a.id}
className="flex flex-col min-w-[6.5rem]"
>
<LazyLoadedImage
imgId={`AvatarHeadShot_${a.id}`}
alt={a.name}
className={`w-24 h-24 rounded-full border-2 ${borderColor} object-cover shadow-xl`}
/>
<span
className={`text-xs ${textColor} mt-1 text-center flex items-center justify-center gap-1 max-w-[6.5rem] overflow-hidden line-clamp-2`}
>
<StupidHoverThing
text={
<span className="space-x-1 flex items-center">
<p>{a.displayName || a.name}</p>
{!a.hasVerifiedBadge ? (
<VerifiedIcon
useDefault
className={`w-4 h-4 shrink-0`}
/>
) : null}
</span>
}
>
<span className="line-clamp-1 overflow-hidden text-ellipsis">
{a.displayName || a.name}
</span>
</StupidHoverThing>
{!a.hasVerifiedBadge ? (
<VerifiedIcon
className={`text-base ${fillColor} w-3 h-3 shrink-0`}
/>
) : null}
</span>
</div>
);
})}
<div className="w-8" />
</div>
</div>

15
components/MiscStuff.tsx Normal file
View File

@@ -0,0 +1,15 @@
import { VerifiedIcon } from "./RobloxIcons";
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
export function StupidHoverThing({ children, text }: React.PropsWithChildren & { text: string | React.ReactNode }) {
return (
<Tooltip>
<TooltipTrigger asChild>
{children}
</TooltipTrigger>
<TooltipContent className="bg-surface0 text-text m-2">
<p className="text-sm flex items-center">{text}</p>
</TooltipContent>
</Tooltip>
)
}

View File

@@ -2,18 +2,27 @@
import { useRobuxBalance } from "@/hooks/roblox/useRobuxBalance";
import { RobuxIcon } from "./RobloxIcons";
import React from "react";
export function QuickTopUI() {
export const QuickTopUI = React.memo(function () {
const robux = useRobuxBalance();
return (
<span className="z-50 absolute top-4 right-4 p-4 flex gap-4 items-center">
<img src="/icon-128.webp" className="-m-1 w-8 h-8" alt="" />
<span className="rounded-full bg-crust/50 flex items-center p-2">
<span className="px-2 font-sans text-blue text-xl flex items-center">
<div className="z-50 absolute top-4 right-4 p-4 flex gap-4 items-center">
<div className="rounded-full bg-crust/50 flex items-center p-2">
<div className="px-2 font-sans text-blue text-xl flex items-center">
<RobuxIcon className="w-6 h-6" />
<p className="pl-1">{robux}</p>
</span>
</span>
</span>
<p className="pl-1">{robux || "???"}</p>
</div>
</div>
</div>
);
}
});
export const QuickTopUILogoPart = React.memo(function () {
return (
<div className="z-50 relative top-4 left-4 p-4 flex gap-4 items-center text-blue">
<img src="/icon-128.webp" className="-m-1 w-8 h-8" alt="" />
<p className="mt-2">{"ocbwoy3-chan-blox"}</p>
</div>
);
});

View File

@@ -28,7 +28,7 @@ export function RobloxVerifiedSmall(
<VerifiedIcon {...props} />
</TooltipTrigger>
<TooltipContent className="bg-surface0 text-text m-2">
<p className="text-sm">Verified user</p>
<p className="text-sm">Verified</p>
</TooltipContent>
</Tooltip>
);

View File

@@ -1,12 +1,13 @@
"use client";
import React from "react";
import React, { useEffect } from "react";
import LazyLoadedImage from "./lazyLoadedImage";
import { Alert, AlertDescription, AlertTitle } from "./ui/alert";
import { OctagonXIcon } from "lucide-react";
import { RobloxPremiumSmall, RobloxVerifiedSmall } from "./RobloxTooltipStuff";
import { useCurrentAccount } from "@/hooks/roblox/useCurrentAccount";
import { Skeleton } from "./ui/skeleton";
import { useFriendsPresence } from "@/hooks/roblox/usePresence";
export function HomeLoggedInHeader() {
const profile = useCurrentAccount();
@@ -26,8 +27,24 @@ export function HomeLoggedInHeader() {
);
}
const presence = useFriendsPresence(profile ? [profile.id] : []);
const userActivity = presence.find((b) => b.userId === profile?.id)
const userPresence = userActivity?.userPresenceType;
const borderColor =
userPresence === 1
? "border-blue bg-blue/50"
: userPresence === 2
? "border-green bg-green/50"
: userPresence === 3
? "border-yellow bg-yellow/50"
: userPresence === 0
? "border-surface2 bg-surface2/50"
: "border-red bg-red/50";
return (
<>
{/* <button onClick={()=>console.log(userPresence)}>debug this</button> */}
<div className="flex items-center gap-6 bg-base rounded-xl px-8 py-6 w-fit mt-8 ml-0">
{!profile ? (
<Skeleton className="w-28 h-28 rounded-full" />
@@ -35,7 +52,7 @@ export function HomeLoggedInHeader() {
<LazyLoadedImage
imgId={`AvatarHeadShot_${profile.id}`}
alt=""
className="w-28 h-28 rounded-full shadow-crust"
className={`w-28 h-28 rounded-full shadow-crust border-2 ${borderColor}`}
/>
)}
<div className="flex flex-col justify-center">
@@ -53,7 +70,10 @@ export function HomeLoggedInHeader() {
</span>
<span className="text-base font-mono text-subtext0 mt-1">
{profile ? (
<>@{profile.name}</>
<>
@{profile.name}
{(!!userActivity && userPresence === 2) ? <> - {userActivity.lastLocation}</> : <></> }
</>
) : (
<Skeleton className="w-64 h-6 rounded-lg" />
)}