Skip to content

Commit

Permalink
Puffin update
Browse files Browse the repository at this point in the history
  • Loading branch information
jameszhang-a committed Feb 26, 2024
1 parent 049593e commit ab4a90e
Show file tree
Hide file tree
Showing 29 changed files with 317 additions and 16 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-query": "^4.20.0",
"@tanstack/react-query-devtools": "^4.32.0",
"@trpc/client": "^10.9.0",
Expand Down
Binary file added public/cats/cat05_gifs/cat05_attack_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_crouch_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_dash_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_die_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_fall_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_fright_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_hurt_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_idle_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_idle_blink_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_jump_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_land_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_ledgeclimb_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_ledgegrab_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_ledgeidle_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_liedown_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_run_12fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_sit_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_sneak_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_walk_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_wallclimb_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cats/cat05_gifs/cat05_wallgrab_8fps.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
180 changes: 180 additions & 0 deletions src/components/Pets/Cat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { useCallback, useEffect, useRef, useState } from "react";

import type { Action, CatType } from "./Cats";
import { cat1, cat5, CatTalk } from "./Cats";

import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";

import Image from "next/image";

// Pixels per second
const DEFAULT_SPEED = 30;
const RUNNING_SPEED = 60;

type CatProps = {
id: string;
name: string;
onClick: () => void;
};

function Cat({ name }: CatProps) {
let currPet: CatType;
switch (name) {
case "cat1":
currPet = cat1;
break;
case "cat5":
currPet = cat5;
break;
default:
currPet = cat1;
}
const petRef = useRef<HTMLDivElement>(null);
const actionRef = useRef<Action>("idle");

const [position, setPosition] = useState({ x: 90, y: -4 });
const [moveDuration, setMoveDuration] = useState(0);
const [faceRight, setFaceRight] = useState(true);
const [currAction, setCurrAction] = useState<Action>("laying");
const [catSpeech, setCatSpeech] = useState("");

const getRelativePosition = useCallback(() => {
if (!petRef.current) return { x: 0, y: 0 };

const petRect = petRef.current.getBoundingClientRect();
const container = petRef.current.parentNode as HTMLElement;
const containerRect = container.getBoundingClientRect();

return {
x: petRect.left - containerRect.left,
y: petRect.top - containerRect.top,
};
}, []);

const rest = useCallback(() => {
actionRef.current = "idle";
setCurrAction("idle");
setMoveDuration(0);
}, []);

const move = useCallback(() => {
if (actionRef.current === "walking") {
return;
}

actionRef.current = "walking";

// First determine the direction
let direction = Math.random() > 0.5 ? 1 : -1;
// Then determine the distance without running into the bounding box
const currentPosition = getRelativePosition();
const distance = Math.floor(Math.random() * 200 + 50);
const futureX = currentPosition.x + direction * distance;

// Collision detection with container boundaries
const container = petRef.current?.parentNode as HTMLElement;
if (container) {
const containerWidth = container.offsetWidth;

if (futureX < 0 || futureX > containerWidth - 40) {
direction *= -1; // Reverse the direction
}
}
// set new direction
setFaceRight(direction === 1);

const gottaRun = distance > 150;
setCurrAction(gottaRun ? "running" : "walking");

// Calculate duration
const moveDuration = gottaRun
? distance / RUNNING_SPEED
: distance / DEFAULT_SPEED;
setMoveDuration(moveDuration);

// Update position with possibly reversed direction
setPosition((prev) => {
return { x: prev.x + direction * distance, y: prev.y };
});

// Set a timeout to stop walking after the calculated duration
setTimeout(() => {
rest();
}, moveDuration * 1000);
}, [getRelativePosition, rest]);

// Simulate some autonomous behavior
useEffect(() => {
// Interval to change the cat's behavior periodically

const interval = setInterval(() => {
if (actionRef.current === "walking" || actionRef.current === "running") {
return;
}
const shouldMove = Math.random() > 0.5;
if (shouldMove) {
move();
} else {
rest();
}
}, 7000);

return () => clearInterval(interval);
}, [move, rest]);

const generateMessage = useCallback(() => {
const randomIndex = Math.floor(Math.random() * CatTalk.length);
setCatSpeech(CatTalk[randomIndex] as string);
}, []);

return (
<div
className="absolute bottom-3 h-10 w-10 border-yellow-500"
style={{
left: position.x,
bottom: position.y,
transition: `all ${moveDuration}s linear`,
}}
ref={petRef}
>
<Image
alt="cat"
className="absolute inset-0 scale-150"
style={{
transform: `
${faceRight ? "scaleX(1)" : "scaleX(-1)"}
scaleX(1.25)
scaleY(1.25)
`,
}}
src={currPet[currAction]}
/>
<TooltipProvider delayDuration={50}>
<Tooltip
onOpenChange={(open) => {
if (open) {
generateMessage();
}
}}
>
<TooltipTrigger>
<div
className="absolute bottom-0 left-1 right-2 top-3 m-auto cursor-pointer border-green-800"
onClick={move}
/>
</TooltipTrigger>
<TooltipContent sideOffset={7} align="start">
<p className="text-xs">{catSpeech}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
);
}

export default Cat;
43 changes: 43 additions & 0 deletions src/components/Pets/Cats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import cat1Walking from "public/cats/cat01_gifs/cat01_walk_8fps.gif";
import cat1Idle from "public/cats/cat01_gifs/cat01_idle_blink_8fps.gif";
import cat1Laying from "public/cats/cat01_gifs/cat01_liedown_8fps.gif";
import cat1Running from "public/cats/cat01_gifs/cat01_run_12fps.gif";

import cat5Walking from "public/cats/cat05_gifs/cat05_walk_8fps.gif";
import cat5Idle from "public/cats/cat05_gifs/cat05_idle_blink_8fps.gif";
import cat5Laying from "public/cats/cat05_gifs/cat05_liedown_8fps.gif";
import cat5Running from "public/cats/cat05_gifs/cat05_run_12fps.gif";

import type { StaticImageData } from "next/image";

export type Action = "idle" | "walking" | "laying" | "running";

export type CatType = {
[K in Action]: StaticImageData;
};

const cat1: CatType = {
walking: cat1Walking,
idle: cat1Idle,
laying: cat1Laying,
running: cat1Running,
};

const cat5: CatType = {
walking: cat5Walking,
idle: cat5Idle,
laying: cat5Laying,
running: cat5Running,
};

// TODO: make very dramatic reminders to complete habits
const CatTalk = [
"Meow",
"Purrrrr",
"Hi, I'm Puffin!",
"I love you!",
"Feed me!",
"I'm hungry~",
];

export { cat1, cat5, CatTalk };
27 changes: 24 additions & 3 deletions src/components/Pets/PetsContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import { Pets } from "./Pets";
import { useState } from "react";
import Cat from "./Cat";

function PetsContainer() {
const [pets] = useState([
// {
// name: "cat1",
// id: "1",
// onClick: () => console.log("pet clicked"),
// },
{
name: "cat5",
id: "2",
onClick: () => console.log("pet clicked"),
},
]);

return (
<div>
<Pets />
<div className="absolute bottom-0 right-0 -z-50 h-[100%] w-[100%]">
{pets.map((pet) => (
<Cat
key={pet.id}
id={`${pet.id}`}
name={pet.name}
onClick={pet.onClick}
/>
))}
</div>
);
}
Expand Down
28 changes: 28 additions & 0 deletions src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";

import { cn } from "@/lib/utils";

const TooltipProvider = TooltipPrimitive.Provider;

const Tooltip = TooltipPrimitive.Root;

const TooltipTrigger = TooltipPrimitive.Trigger;

const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-100 overflow-hidden rounded-md border bg-popover px-1 py-0.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
27 changes: 14 additions & 13 deletions src/pages/tracker/[uid].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import HabitLoading from "@/components/HabitLoading";
import Refresh from "@/components/Refresh";
import TrackerBackground from "@/components/TrackerBackground";
import { DatePicker2 } from "@/components/ui/datepicker";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { PetsContainer } from "@/components/Pets/PetsContainer";

import {
ClipboardDocumentCheckIcon,
ClipboardDocumentIcon,
Expand All @@ -27,16 +34,6 @@ import { type NextPage } from "next";

import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { useTime } from "@/hooks/useTime";
import { Button } from "@/components/ui/button";
import Image from "next/image";

import cat1 from "public/cats/cat01_gifs/cat01_walk_8fps.gif";
import { Pets } from "@/components/Pets/Pets";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";

const habitAPI = api.habit;

Expand Down Expand Up @@ -182,6 +179,7 @@ SN_End: ${!!serverTime ? serverTime.newDayEnd.toISOString() : "undefined"}
{slides}
</Carousel>
<Refresh />
{/* Debug info popover */}
<Popover>
<PopoverTrigger asChild>
<button className="align-center absolute bottom-3 right-11 flex grow justify-center rounded-md border border-input bg-background/[.2] p-1 align-middle hover:bg-accent hover:text-accent-foreground">
Expand Down Expand Up @@ -215,9 +213,12 @@ SN_End: ${!!serverTime ? serverTime.newDayEnd.toISOString() : "undefined"}
</CopyButton>
</PopoverContent>
</Popover>
<div className="absolute bottom-0 right-0 -z-50 h-[100%] w-[100%]">
<Pets />
</div>

<PetsContainer />
{/* <div className="">
<Pets name="cat5" />
<Cat name="cat1" id="1" onClick={() => console.log("onClick")} />
</div> */}
{/* <EllipsisHorizontalIcon className="h-6 w-6 cursor-pointer rounded-l text-gray-500 hover:border hover:border-slate-200 hover:bg-[#f4f5f6]/60 hover:shadow-inner" /> */}
</TrackerBackground>
</TrackerContextProvider>
Expand Down
27 changes: 27 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,25 @@
"@radix-ui/react-roving-focus" "1.0.4"
"@radix-ui/react-use-controllable-state" "1.0.1"

"@radix-ui/react-tooltip@^1.0.7":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e"
integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-dismissable-layer" "1.0.5"
"@radix-ui/react-id" "1.0.1"
"@radix-ui/react-popper" "1.1.3"
"@radix-ui/react-portal" "1.0.4"
"@radix-ui/react-presence" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.1"
"@radix-ui/react-visually-hidden" "1.0.3"

"@radix-ui/[email protected]":
version "1.0.0"
resolved "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz"
Expand Down Expand Up @@ -2057,6 +2076,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.1"

"@radix-ui/[email protected]":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac"
integrity sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"

"@radix-ui/[email protected]":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f"
Expand Down

0 comments on commit ab4a90e

Please sign in to comment.