[#1] Remove office phone and add email app
All checks were successful
Publish Docker Image / Publish Docker Image (push) Successful in 1m1s
All checks were successful
Publish Docker Image / Publish Docker Image (push) Successful in 1m1s
This commit is contained in:
@@ -15,7 +15,6 @@ import {
|
||||
BackSide,
|
||||
} from "three";
|
||||
import { Billboard, Text } from "@react-three/drei";
|
||||
import { useConfig } from "../hooks/useConfig";
|
||||
|
||||
interface ButtonsProps {
|
||||
menuTraversal: Stack<View>;
|
||||
@@ -23,7 +22,6 @@ interface ButtonsProps {
|
||||
pendingView: View | null;
|
||||
setPendingView: Dispatch<SetStateAction<View | null>>;
|
||||
goPreviousView(): void;
|
||||
phoneHovered: boolean;
|
||||
currentView: View;
|
||||
}
|
||||
|
||||
@@ -35,11 +33,8 @@ export const Buttons = ({
|
||||
pendingView,
|
||||
setPendingView,
|
||||
goPreviousView,
|
||||
phoneHovered,
|
||||
currentView,
|
||||
}: ButtonsProps) => {
|
||||
const config = useConfig();
|
||||
|
||||
const [hovered, setHovered] = useState<View | null>(null);
|
||||
|
||||
const desktopRef = useDisableRaycast(currentView !== View.MainView);
|
||||
@@ -47,8 +42,6 @@ export const Buttons = ({
|
||||
const sideRef = useDisableRaycast(currentView !== View.MainView);
|
||||
const cellphoneRef = useDisableRaycast(currentView !== View.DesktopView);
|
||||
const pcRef = useDisableRaycast(currentView !== View.DesktopView);
|
||||
const resumeRef = useDisableRaycast(currentView !== View.SideView);
|
||||
const phoneRef = useDisableRaycast(currentView !== View.SideView);
|
||||
|
||||
const goToView = useCallback(
|
||||
(view: View) => {
|
||||
@@ -89,12 +82,12 @@ export const Buttons = ({
|
||||
}, [menuTraversal, pendingView, setPendingView]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hovered || phoneHovered) {
|
||||
if (hovered) {
|
||||
document.body.style.cursor = "pointer";
|
||||
} else {
|
||||
document.body.style.cursor = "auto";
|
||||
}
|
||||
}, [hovered, phoneHovered]);
|
||||
}, [hovered]);
|
||||
|
||||
const mainMenuSpring = useThreeSpring<MeshStandardMaterial>({
|
||||
opacity: currentView === View.MainView ? 1 : 0,
|
||||
@@ -116,14 +109,11 @@ export const Buttons = ({
|
||||
const printerMenuSpring = useThreeSpring<MeshStandardMaterial>({
|
||||
opacity: currentView === View.PrinterView ? 1 : 0,
|
||||
});
|
||||
const sideMenuSpring = useThreeSpring<MeshStandardMaterial>({
|
||||
opacity: currentView === View.SideView ? 1 : 0,
|
||||
});
|
||||
const desktopViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.DesktopView ? 1.25 : 1,
|
||||
});
|
||||
const sideViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.SideView ? 1.25 : 1,
|
||||
const resumeViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.ResumeView ? 1.25 : 1,
|
||||
});
|
||||
const cellphoneViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.CellphoneView ? 1.25 : 1,
|
||||
@@ -134,15 +124,9 @@ export const Buttons = ({
|
||||
const creditsViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.CreditsView ? 1.25 : 1,
|
||||
});
|
||||
const resumeViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.ResumeView ? 1.25 : 1,
|
||||
});
|
||||
const printerViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.PrinterView ? 1.25 : 1,
|
||||
});
|
||||
const phoneViewSpring = useThreeSpring<BufferGeometry>({
|
||||
scale: hovered === View.PhoneView ? 1.25 : 1,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -242,16 +226,16 @@ export const Buttons = ({
|
||||
position={[2.525, 6, 6.75]}
|
||||
onClick={
|
||||
currentView === View.MainView
|
||||
? () => goToView(View.SideView)
|
||||
? () => goToView(View.ResumeView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOver={
|
||||
currentView === View.MainView
|
||||
? () => setHovered(View.SideView)
|
||||
? () => setHovered(View.ResumeView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOut={() => setHovered(null)}
|
||||
scale={sideViewSpring.scale}
|
||||
scale={resumeViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.6, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
@@ -260,7 +244,10 @@ export const Buttons = ({
|
||||
opacity={mainMenuSpring.opacity}
|
||||
/>
|
||||
</animated.mesh>
|
||||
<animated.mesh position={[2.525, 6, 6.75]} scale={sideViewSpring.scale}>
|
||||
<animated.mesh
|
||||
position={[2.525, 6, 6.75]}
|
||||
scale={resumeViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.65, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
transparent
|
||||
@@ -277,7 +264,7 @@ export const Buttons = ({
|
||||
fillOpacity={mainMenuSpring.opacity}
|
||||
outlineOpacity={mainMenuSpring.opacity}
|
||||
>
|
||||
Resume & Contact
|
||||
Resume
|
||||
</AnimatedText>
|
||||
</Billboard>
|
||||
</group>
|
||||
@@ -450,105 +437,6 @@ export const Buttons = ({
|
||||
</AnimatedText>
|
||||
</Billboard>
|
||||
</group>
|
||||
{/* Side Menu */}
|
||||
<group>
|
||||
<animated.mesh
|
||||
ref={resumeRef}
|
||||
position={[2.845, 4.75, 6.454]}
|
||||
onClick={
|
||||
currentView === View.SideView
|
||||
? () => goToView(View.ResumeView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOver={
|
||||
currentView === View.SideView
|
||||
? () => setHovered(View.ResumeView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOut={() => setHovered(null)}
|
||||
scale={resumeViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.175, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
transparent
|
||||
color="white"
|
||||
opacity={sideMenuSpring.opacity}
|
||||
/>
|
||||
</animated.mesh>
|
||||
<animated.mesh
|
||||
position={[2.845, 4.75, 6.454]}
|
||||
scale={resumeViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.175 + 7 / 480, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
transparent
|
||||
color="black"
|
||||
opacity={sideMenuSpring.opacity}
|
||||
side={BackSide}
|
||||
/>
|
||||
</animated.mesh>
|
||||
<Billboard position={[2.845, 5.1875, 6.454]}>
|
||||
<AnimatedText
|
||||
font="/assets/inter.ttf"
|
||||
fontSize={0.21875}
|
||||
outlineWidth={7 / 480}
|
||||
fillOpacity={sideMenuSpring.opacity}
|
||||
outlineOpacity={sideMenuSpring.opacity}
|
||||
>
|
||||
Resume
|
||||
</AnimatedText>
|
||||
</Billboard>
|
||||
{config.phoneNumber && (
|
||||
<>
|
||||
<animated.mesh
|
||||
ref={phoneRef}
|
||||
position={[3.75, 5.125, 7]}
|
||||
onClick={
|
||||
currentView === View.SideView
|
||||
? () => goToView(View.PhoneView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOver={
|
||||
currentView === View.SideView
|
||||
? () => setHovered(View.PhoneView)
|
||||
: undefined
|
||||
}
|
||||
onPointerOut={() => setHovered(null)}
|
||||
scale={phoneViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.175, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
transparent
|
||||
color="white"
|
||||
opacity={sideMenuSpring.opacity}
|
||||
/>
|
||||
</animated.mesh>
|
||||
<animated.mesh
|
||||
position={[3.75, 5.125, 7]}
|
||||
scale={phoneViewSpring.scale}
|
||||
>
|
||||
<sphereGeometry args={[0.175 + 7 / 480, 32, 32]} />
|
||||
<animated.meshStandardMaterial
|
||||
transparent
|
||||
color="black"
|
||||
opacity={sideMenuSpring.opacity}
|
||||
side={BackSide}
|
||||
/>
|
||||
</animated.mesh>
|
||||
<Billboard position={[3.75, 5.515, 7]}>
|
||||
<AnimatedText
|
||||
font="/assets/inter.ttf"
|
||||
fontSize={0.21875}
|
||||
outlineWidth={7 / 480}
|
||||
fillOpacity={sideMenuSpring.opacity}
|
||||
outlineOpacity={sideMenuSpring.opacity}
|
||||
>
|
||||
Contact
|
||||
</AnimatedText>
|
||||
</Billboard>
|
||||
</>
|
||||
)}
|
||||
</group>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -56,7 +56,6 @@ export function Scene(props: JSX.IntrinsicElements["group"]) {
|
||||
|
||||
// States
|
||||
const [pendingView, setPendingView] = useState<View | null>(null);
|
||||
const [phoneHovered, setPhoneHovered] = useState(false);
|
||||
const [backHovered, setBackHovered] = useState(false);
|
||||
const [backClicked, setBackClicked] = useState(false);
|
||||
const [menuTraversal, setMenuTraversal] = useState<Stack<View>>(() => {
|
||||
@@ -182,7 +181,6 @@ export function Scene(props: JSX.IntrinsicElements["group"]) {
|
||||
pendingView={pendingView}
|
||||
setPendingView={setPendingView}
|
||||
goPreviousView={goPreviousView}
|
||||
phoneHovered={phoneHovered}
|
||||
currentView={currentView}
|
||||
/>
|
||||
<group>
|
||||
@@ -321,67 +319,6 @@ export function Scene(props: JSX.IntrinsicElements["group"]) {
|
||||
</Html>
|
||||
</mesh>
|
||||
</group>
|
||||
<group
|
||||
position={[4, 4.74056, 7.25]}
|
||||
rotation={[-Math.PI, -Math.PI / 4, -Math.PI]}
|
||||
scale={0.3}
|
||||
>
|
||||
<group
|
||||
position={[-0.45957, -1.57735, -0.97302]}
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
scale={100}
|
||||
onClick={
|
||||
config.phoneNumber && currentView === View.PhoneView
|
||||
? () => {
|
||||
window.open(
|
||||
`tel:${config.phoneNumber}`,
|
||||
"_blank",
|
||||
"noopener,noreferrer"
|
||||
);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onPointerOver={
|
||||
config.phoneNumber && currentView === View.PhoneView
|
||||
? () => setPhoneHovered(true)
|
||||
: undefined
|
||||
}
|
||||
onPointerOut={() => setPhoneHovered(false)}
|
||||
>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.Top.geometry}
|
||||
material={materials.TopMaterial}
|
||||
/>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.OfficePhoneBody.geometry}
|
||||
material={materials.OfficePhoneBodyMaterial}
|
||||
/>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.Screen.geometry}
|
||||
material={materials.ScreenMaterial}
|
||||
/>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.Buttons.geometry}
|
||||
material={materials.HandleAndButtonsMaterial}
|
||||
/>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.Handle.geometry}
|
||||
material={materials.HandleAndButtonsMaterial}
|
||||
position={[-0.01639, -0.0078, 0.02006]}
|
||||
rotation={[-0.37437, 0, Math.PI / 2]}
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<Text
|
||||
position={[-2.415, 12.5, -6]}
|
||||
font="/assets/inter-bold.ttf"
|
||||
|
||||
@@ -36,11 +36,6 @@ export const views: PerspectiveCameraProps[] = [
|
||||
position: [3.0143, 5.5, 6.0997],
|
||||
rotation: [-2.55743, -0.69621, -2.74104],
|
||||
},
|
||||
{
|
||||
// SideView
|
||||
position: [0.5, 7.75, 4.15],
|
||||
rotation: [-2.1005, -0.68155, -2.35619],
|
||||
},
|
||||
{
|
||||
// CreditsView
|
||||
position: [1.25, 5.9822, -2.075],
|
||||
@@ -56,8 +51,7 @@ export enum View {
|
||||
CellphoneView = 4,
|
||||
DesktopView = 5,
|
||||
PhoneView = 6,
|
||||
SideView = 7,
|
||||
CreditsView = 8,
|
||||
CreditsView = 7,
|
||||
}
|
||||
|
||||
export const hashtoView: Record<string, View> = {
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
mdiWifi,
|
||||
mdiBattery80,
|
||||
mdiHelp,
|
||||
mdiEmail,
|
||||
} from "@mdi/js";
|
||||
import Icon from "@mdi/react";
|
||||
import { useRef, useState } from "react";
|
||||
@@ -88,6 +89,17 @@ export const CellphoneUI = () => {
|
||||
<div className={`${appClass} ${fillerClass}`}>
|
||||
<Icon path={mdiCalculator} className="text-neutral-300" />
|
||||
</div>
|
||||
{config.email && (
|
||||
<a
|
||||
href={`mailto:${config.email}`}
|
||||
target="_blank"
|
||||
className={appClass}
|
||||
onMouseOver={handleEnter}
|
||||
onMouseOut={handleLeave}
|
||||
>
|
||||
<Icon path={mdiEmail} className="text-neutral-300" />
|
||||
</a>
|
||||
)}
|
||||
{config.socials?.matrix && (
|
||||
<a
|
||||
href={`https://matrix.to/#/${config.socials.matrix}`}
|
||||
|
||||
@@ -66,6 +66,11 @@ export async function register() {
|
||||
format: "phone",
|
||||
nullable: true,
|
||||
},
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email",
|
||||
nullable: true,
|
||||
},
|
||||
fallbackUrl: {
|
||||
type: "string",
|
||||
format: "uri",
|
||||
|
||||
1
src/types/config.d.ts
vendored
1
src/types/config.d.ts
vendored
@@ -16,6 +16,7 @@ export interface Config {
|
||||
tags?: string[];
|
||||
}[];
|
||||
phoneNumber?: string;
|
||||
email?: string;
|
||||
fallbackUrl?: string;
|
||||
name: [string, string];
|
||||
status?: string;
|
||||
|
||||
Reference in New Issue
Block a user