import Maid from "@rbxts/maid";
import React, { useEffect, useRef } from "@rbxts/react";
import { TweenService } from "@rbxts/services";
import { extractEntries } from "client/ui/lib/utils";
type ModifiedImageButtonProps = Omit<React.ComponentProps<"imagebutton">, "Image" | "BackgroundTransparency">;
interface MenuItemProps extends ModifiedImageButtonProps {
PreviewModel: Model;
OnClick: () => void;
}
export function MenuItem(props: MenuItemProps) {
const [{ PreviewModel, OnClick, Size = new UDim2(1, 0, 1, 0), Event }, rest] = extractEntries(props, [
"PreviewModel",
"OnClick",
"Size",
"Event",
]);
const viewportRef = useRef<ViewportFrame>(undefined);
const cameraRef = useRef<Camera>(undefined);
const maid = new Maid();
// Setup the preview model and camera in the viewport
useEffect(() => {
if (!viewportRef.current) return;
if (!cameraRef.current) return;
viewportRef.current.CurrentCamera = cameraRef.current;
const previewModelClone = PreviewModel.Clone();
previewModelClone.Parent = viewportRef.current;
previewModelClone.PivotTo(new CFrame(0, 0, 0));
cameraRef.current.CFrame = CFrame.lookAt(
cameraRef.current.CFrame.Position,
previewModelClone.WorldPivot.Position,
);
const primaryPart = previewModelClone.PrimaryPart;
if (!primaryPart) {
warn(`MenuItem -> Preview model ${PreviewModel.Name} does not have a PrimaryPart set.`);
return;
}
// Rotate the camera around the model
const tween = TweenService.Create(
primaryPart,
new TweenInfo(10, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true),
{
CFrame: primaryPart.CFrame.mul(CFrame.Angles(0, math.rad(180), 0)),
},
);
tween.Play();
maid.GiveTask(previewModelClone);
maid.GiveTask(tween);
return () => {
maid.DoCleaning();
};
}, []);
return (
<imagebutton
Size={Size}
Event={{
...Event,
MouseButton1Click: OnClick,
}}
BackgroundTransparency={0.75}
{...rest}
>
<viewportframe ref={viewportRef} Size={new UDim2(1, 0, 1, 0)} BackgroundTransparency={1}>
<sky
CelestialBodiesShown
MoonAngularSize={11}
MoonTextureId="rbxasset://sky/moon.jpg"
SkyboxBk="rbxassetid://591058823"
SkyboxDn="rbxassetid://591059876"
SkyboxFt="rbxassetid://591058104"
SkyboxLf="rbxassetid://591057861"
SkyboxRt="rbxassetid://591057625"
SkyboxUp="rbxassetid://591059642"
StarCount={3000}
SunAngularSize={11}
SunTextureId="rbxasset://sky/sun.jpg"
/>
<camera ref={cameraRef} FieldOfView={70} CFrame={new CFrame(0, 1, 4)} />
</viewportframe>
</imagebutton>
);
}