Skip to content

Commit

Permalink
Added regeneration date
Browse files Browse the repository at this point in the history
  • Loading branch information
Neo-Ciber94 committed Jul 17, 2023
1 parent ebb1ee5 commit 151a1f1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 28 deletions.
40 changes: 40 additions & 0 deletions src/hooks/useNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useEffect, useState } from "react";
import { delay } from "~/utils/delay";

interface UseNumberOptions {
speed: number
}

export function useNumber(n: number, { speed }: UseNumberOptions = { speed: 50 }) {
if (n < 0) {
throw new Error("number must positive")
}

const [value, setValue] = useState(0);

useEffect(() => {
let unmounted = false;

const run = async () => {
for (let i = 0; i < n; i++) {
if (unmounted) {
return;
}

if (i > 1) {
await delay(speed);
}

setValue(i + 1);
}
}

void run();

return () => {
unmounted = true;
}
}, [n, speed])

return value;
}
89 changes: 61 additions & 28 deletions src/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import DarkModeToggle from "~/components/DarkModeToggle";
import { ForEachCharacter } from "~/components/ForEachCharacter";
import LoadingIndicator from "~/components/LoadingIndicator";
import ImageWithFallback from "~/components/ImageWithFallback";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { Menu } from "@headlessui/react";
import { MdOutlineGeneratingTokens } from "react-icons/md";
import { MdOutlineGeneratingTokens, MdCalendarToday } from "react-icons/md";
import { api } from "~/utils/api";
import { AnimatePresence, motion } from "framer-motion";
import dayjs from "dayjs";
import LocalizedFormat from "dayjs/plugin/localizedFormat";
import { useNumber } from "~/hooks/useNumber";
dayjs.extend(LocalizedFormat);

const font = Lato({
weight: ["700"],
Expand Down Expand Up @@ -65,18 +69,30 @@ interface UserAvatarProps {

function UserAvatar({ user }: UserAvatarProps) {
const name = user.username || user.firstName || "User";
const [showCount, setShowCount] = useState(false);
const fallbackImg = useMemo(
() => `https://placehold.co/64x64/9333ea/FFF?text=${name.slice(0, 2)}`,
[name]
);

const userTokensQuery = api.users.getTokenCount.useQuery();
const tokenCount = userTokensQuery.data?.tokenCount;
const nextRegeneration = userTokensQuery.data?.nextRegeneration;
const num = useNumber(
typeof tokenCount === "number" && showCount ? tokenCount : 0
);

return (
<Menu>
{({ open }) => (
<>
<Menu.Button>
<Menu.Button
onClick={() => {
if (!showCount) {
setShowCount(true);
}
}}
>
<div className="overflow-hidden rounded-full shadow">
<ImageWithFallback
alt={name}
Expand All @@ -98,32 +114,49 @@ function UserAvatar({ user }: UserAvatarProps) {
animate={{ opacity: 1, translateX: 0 }}
exit={{ opacity: 0, translateX: -60 }}
className="absolute right-14 top-14 z-40 flex flex-col gap-2 overflow-hidden rounded-lg border border-gray-200
bg-white p-1 shadow-md dark:border-violet-900/50 dark:bg-slate-900 dark:shadow-sm dark:shadow-violet-400/10"
bg-white p-1 text-xs shadow-md dark:border-violet-900/50 dark:bg-slate-900 dark:shadow-sm dark:shadow-violet-400/10"
>
<Menu.Item
as="li"
className="flex cursor-pointer flex-row items-center gap-4 rounded-lg px-5 py-2 hover:bg-violet-500 hover:text-white"
>
<MdOutlineGeneratingTokens className="text-2xl" />
{userTokensQuery.isLoading && (
<div className="px-10">
<LoadingIndicator size={25} />
</div>
)}
<span className="font-medium">
{userTokensQuery.data != null && (
<>
{userTokensQuery.data.tokenCount === "unlimited"
? "Unlimited tokens"
: `${userTokensQuery.data.tokenCount} ${
userTokensQuery.data.tokenCount === 1
? "token"
: "tokens"
} left`}
</>
)}
</span>
</Menu.Item>
{userTokensQuery.isLoading && (
<div className="px-10">
<LoadingIndicator size={25} />
</div>
)}
{!userTokensQuery.isLoading && (
<>
<Menu.Item
as="li"
className="flex cursor-pointer flex-row items-center gap-2 rounded-lg px-5 py-2 hover:bg-violet-500 hover:text-white"
>
<MdOutlineGeneratingTokens className="text-xl" />
<span className="font-medium">
{tokenCount != null && (
<>
{tokenCount === "unlimited"
? "Unlimited tokens"
: `${num} ${
tokenCount === 1 ? "token" : "tokens"
} left`}
</>
)}
</span>
</Menu.Item>

{nextRegeneration != null &&
typeof tokenCount === "number" && (
<Menu.Item
as="li"
className="flex cursor-pointer flex-row items-center gap-2 rounded-lg px-5 py-2 hover:bg-violet-500 hover:text-white"
>
<MdCalendarToday className="text-xl" />
<span className="font-medium">
<>{`Recharge ${dayjs(nextRegeneration).format(
"L"
)}`}</>
</span>
</Menu.Item>
)}
</>
)}
</Menu.Items>
)}
</AnimatePresence>
Expand Down

0 comments on commit 151a1f1

Please sign in to comment.