some roblox stuff again

This commit is contained in:
2025-07-24 04:25:18 +03:00
parent e0217cbbcb
commit d1f925f298
35 changed files with 866 additions and 282 deletions

View File

@@ -0,0 +1,61 @@
"use client";
import {
getLoggedInUser,
getUserByUserId,
UserProfileDetails
} from "@/lib/profile";
import { loadThumbnails } from "@/lib/thumbnailLoader";
import { useEffect, useState } from "react";
let isFetching = false;
let cachedData: any = null;
export function useCurrentAccount() {
const [profileDetails, setProfileDetails] = useState<
UserProfileDetails | null | false
>(cachedData);
useEffect(() => {
let cancelled = false;
if (profileDetails !== null) return;
if (isFetching) {
const IN = setInterval(() => {
if (cachedData !== null) {
if (!cancelled) setProfileDetails(cachedData);
clearInterval(IN);
}
}, 50);
return () => {
clearInterval(IN);
cancelled = true;
};
}
isFetching = true;
(async () => {
const authed = await getLoggedInUser();
if (authed) {
const user = await getUserByUserId(authed.id.toString());
if (!cancelled) setProfileDetails(user);
cachedData = user;
loadThumbnails([
{
type: "AvatarHeadShot",
targetId: authed.id,
format: "webp",
size: "720x720"
}
]).catch(() => {});
} else {
if (!cancelled) setProfileDetails(false);
cachedData = false;
}
isFetching = false;
})();
return () => {
cancelled = true;
};
}, [profileDetails]);
return profileDetails;
}

View File

@@ -0,0 +1,94 @@
"use client";
// https://friends.roblox.com/v1/users/1083030325/friends/find?userSort=1
import { useEffect, useState } from "react";
import { useCurrentAccount } from "./useCurrentAccount";
import { proxyFetch } from "@/lib/utils";
import { loadThumbnails } from "@/lib/thumbnailLoader";
let isFetching = false;
let cachedData: any = null;
export function useFriendsHome() {
const acct = useCurrentAccount();
const [friends, setFriends] = useState<
| {
hasVerifiedBadge: boolean;
id: number;
name: string;
displayName: string;
}[]
| null
| false
>(cachedData);
useEffect(() => {
let cancelled = false;
if (!acct) return;
if (isFetching) {
const IN = setInterval(() => {
if (cachedData !== null) {
if (!cancelled) setFriends(cachedData);
clearInterval(IN);
}
}, 50);
return () => {
clearInterval(IN);
cancelled = true;
};
}
isFetching = true;
(async () => {
const friendsAPICall = await proxyFetch(
`https://friends.roblox.com/v1/users/${acct.id}/friends/find?userSort=1`
);
const J = (await friendsAPICall.json()) as {
PageItems: { id: number }[];
};
const friendsAPICall2 = await proxyFetch(
`https://users.roblox.com/v1/users`,
{
method: "POST",
body: JSON.stringify({
userIds: J.PageItems.map((a) => a.id),
excludeBannedUsers: false
})
}
);
const J2 = (await friendsAPICall2.json()) as {
data: {
hasVerifiedBadge: boolean;
id: number;
name: string;
displayName: string;
}[];
};
loadThumbnails(
J2.data.map((a) => ({
type: "AvatarHeadShot",
size: "420x420",
targetId: a.id,
format: "webp"
}))
).catch(() => {});
const friendsList = J.PageItems.map((a) => {
const x = J2.data.find((b) => b.id === a.id);
return {
id: a.id,
hasVerifiedBadge: x?.hasVerifiedBadge || false,
name: x?.name || "?",
displayName: x?.displayName || "?"
};
});
if (!cancelled) setFriends(friendsList);
cachedData = friendsList;
isFetching = false;
})();
return () => {
cancelled = true;
};
}, [acct]);
return friends;
}

View File

@@ -0,0 +1,55 @@
"use client";
import { useEffect, useState } from "react";
import { useCurrentAccount } from "./useCurrentAccount";
import { proxyFetch } from "@/lib/utils";
let isFetching = false;
let cachedData: number | false | null = null;
export function useRobuxBalance() {
const acct = useCurrentAccount();
const [robux, setRobux] = useState<number | false | null>(cachedData);
useEffect(() => {
let cancelled = false;
if (!acct) return;
async function fetchBalance() {
if (isFetching) return;
if (!acct) return;
isFetching = true;
try {
const res = await proxyFetch(
`https://economy.roblox.com/v1/users/${acct.id}/currency`
);
const data = await res.json();
if (!cancelled) setRobux(data.robux);
cachedData = data.robux;
} catch {
if (!cancelled) setRobux(false);
cachedData = false;
} finally {
isFetching = false;
}
}
fetchBalance();
function handleTransaction() {
fetchBalance();
}
window.addEventListener("transactionCompletedEvent", handleTransaction);
return () => {
cancelled = true;
window.removeEventListener(
"transactionCompletedEvent",
handleTransaction
);
};
}, [acct]);
return robux;
}