first person camera bug and new project loading screen stuck bug fixed
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
DocumentationIcon,
|
DocumentationIcon,
|
||||||
HelpIcon,
|
HelpIcon,
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
LogoutIcon,
|
LogoutIcon,
|
||||||
NotificationIcon,
|
NotificationIcon,
|
||||||
ProjectsIcon,
|
ProjectsIcon,
|
||||||
TutorialsIcon,
|
TutorialsIcon,
|
||||||
} from "../icons/DashboardIcon";
|
} from "../icons/DashboardIcon";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import darkThemeImage from "../../assets/image/darkThemeProject.png";
|
import darkThemeImage from "../../assets/image/darkThemeProject.png";
|
||||||
@@ -15,180 +15,174 @@ import { SettingsIcon, TrashIcon } from "../icons/ExportCommonIcons";
|
|||||||
import { getUserData } from "../../functions/getUserData";
|
import { getUserData } from "../../functions/getUserData";
|
||||||
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
||||||
|
|
||||||
|
// import { createProject } from "../../services/dashboard/createProject";
|
||||||
|
|
||||||
interface SidePannelProps {
|
interface SidePannelProps {
|
||||||
setActiveTab: React.Dispatch<React.SetStateAction<string>>;
|
setActiveTab: React.Dispatch<React.SetStateAction<string>>;
|
||||||
activeTab: string;
|
activeTab: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
||||||
const { email, userName, userId, organization } = getUserData();
|
const { email, userName, userId, organization } = getUserData();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
const { projectSocket } = useSocketStore();
|
const { projectSocket, initializeSocket } = useSocketStore();
|
||||||
const savedTheme = localStorage.getItem("theme") ?? "light";
|
const savedTheme = localStorage.getItem("theme") ?? "light";
|
||||||
|
|
||||||
function generateProjectId() {
|
function generateProjectId() {
|
||||||
const randomBytes = new Uint8Array(12);
|
const randomBytes = new Uint8Array(12);
|
||||||
crypto.getRandomValues(randomBytes);
|
crypto.getRandomValues(randomBytes);
|
||||||
return Array.from(randomBytes, (byte) =>
|
return Array.from(randomBytes, (byte) =>
|
||||||
byte.toString(16).padStart(2, "0")
|
byte.toString(16).padStart(2, "0")
|
||||||
).join("");
|
).join("");
|
||||||
}
|
|
||||||
|
|
||||||
const handleCreateNewProject = async () => {
|
|
||||||
const token = localStorage.getItem("token");
|
|
||||||
const refreshToken = localStorage.getItem("refreshToken");
|
|
||||||
if (!token || !refreshToken) {
|
|
||||||
console.error('token expired');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
const projectId = generateProjectId();
|
|
||||||
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
|
|
||||||
|
|
||||||
//API for creating new Project
|
const handleCreateNewProject = async () => {
|
||||||
// const project = await createProject(
|
const token = localStorage.getItem("token");
|
||||||
// projectId,
|
const refreshToken = localStorage.getItem("refreshToken");
|
||||||
// userId,
|
if (!token || !refreshToken) {
|
||||||
// savedTheme === "dark" ? darkThemeImage : lightThemeImage,
|
console.error('token expired');
|
||||||
// organization
|
return;
|
||||||
// );
|
}
|
||||||
|
|
||||||
const addProject = {
|
const projectId = generateProjectId();
|
||||||
userId,
|
initializeSocket(email, organization, token, refreshToken);
|
||||||
thumbnail: savedTheme === "dark" ? darkThemeImage : lightThemeImage,
|
|
||||||
organization: organization,
|
|
||||||
projectUuid: projectId,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (projectSocket) {
|
if (projectSocket?.connected) {
|
||||||
const handleResponse = (data: any) => {
|
// SOCKET
|
||||||
if (data.message === "Project created successfully") {
|
const addProject = {
|
||||||
setLoadingProgress(1);
|
userId,
|
||||||
navigate(`/projects/${data.data.projectId}`);
|
thumbnail: savedTheme === "dark" ? darkThemeImage : lightThemeImage,
|
||||||
}
|
organization: organization,
|
||||||
projectSocket.off("v1-project:response:add", handleResponse); // Clean up
|
projectUuid: projectId,
|
||||||
};
|
};
|
||||||
projectSocket.on("v1-project:response:add", handleResponse);
|
const handleResponse = (data: any) => {
|
||||||
|
if (data.message === "Project created successfully") {
|
||||||
|
setLoadingProgress(1);
|
||||||
|
navigate(`/projects/${data.data.projectId}`);
|
||||||
|
}
|
||||||
|
projectSocket.off("v1-project:response:add", handleResponse);
|
||||||
|
};
|
||||||
|
projectSocket.on("v1-project:response:add", handleResponse);
|
||||||
|
|
||||||
projectSocket.emit("v1:project:add", addProject);
|
projectSocket.emit("v1:project:add", addProject);
|
||||||
} else {
|
} else {
|
||||||
console.error("Socket is not connected.");
|
// API
|
||||||
}
|
// const project = await createProject(
|
||||||
} catch (error) {
|
// projectId,
|
||||||
console.error("Error creating project:", error);
|
// userId,
|
||||||
}
|
// savedTheme === "dark" ? darkThemeImage : lightThemeImage,
|
||||||
};
|
// organization
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="side-pannel-container">
|
<div className="side-pannel-container">
|
||||||
<div className="side-pannel-header">
|
<div className="side-pannel-header">
|
||||||
<div className="user-container">
|
<div className="user-container">
|
||||||
<div className="user-profile">
|
<div className="user-profile">
|
||||||
{userName?.charAt(0).toUpperCase()}
|
{userName?.charAt(0).toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
<div className="user-name">
|
<div className="user-name">
|
||||||
{userName
|
{userName ? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() : "Anonymous"}
|
||||||
? userName.charAt(0).toUpperCase() +
|
</div>
|
||||||
userName.slice(1).toLowerCase()
|
</div>
|
||||||
: "Anonymous"}
|
<div className="notifications-container">
|
||||||
</div>
|
<NotificationIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="new-project-button"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={handleCreateNewProject}
|
||||||
|
>
|
||||||
|
+ New project
|
||||||
|
</div>
|
||||||
|
<div className="side-bar-content-container">
|
||||||
|
<div className="side-bar-options-container">
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
activeTab === "Home" ? "option-list active" : "option-list"
|
||||||
|
}
|
||||||
|
onClick={() => setActiveTab("Home")}
|
||||||
|
>
|
||||||
|
<HomeIcon />
|
||||||
|
Home
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
activeTab === "Projects" ? "option-list active" : "option-list"
|
||||||
|
}
|
||||||
|
title="Projects"
|
||||||
|
onClick={() => setActiveTab("Projects")}
|
||||||
|
>
|
||||||
|
<ProjectsIcon />
|
||||||
|
Projects
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
activeTab === "Trash" ? "option-list active" : "option-list"
|
||||||
|
}
|
||||||
|
title="Trash"
|
||||||
|
onClick={() => setActiveTab("Trash")}
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
Trash
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
activeTab === "Tutorials" ? "option-list active" : "option-list"
|
||||||
|
}
|
||||||
|
title="coming soon"
|
||||||
|
onClick={() => {
|
||||||
|
// setActiveTab("Tutorials");
|
||||||
|
console.warn("Tutorials comming soon");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TutorialsIcon />
|
||||||
|
Tutorials
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
activeTab === "Documentation"
|
||||||
|
? "option-list active"
|
||||||
|
: "option-list"
|
||||||
|
}
|
||||||
|
title="coming soon"
|
||||||
|
onClick={() => {
|
||||||
|
// setActiveTab("Documentation");
|
||||||
|
console.warn("Documentation comming soon");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DocumentationIcon />
|
||||||
|
Documentation
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="side-bar-options-container">
|
||||||
|
<div className="option-list" title="coming soon">
|
||||||
|
<SettingsIcon />
|
||||||
|
Settings
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="option-list"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.clear();
|
||||||
|
navigate("/");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LogoutIcon />
|
||||||
|
Log out
|
||||||
|
</div>
|
||||||
|
<div className="option-list" title="coming soon">
|
||||||
|
<HelpIcon />
|
||||||
|
Help & Feedback
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="notifications-container">
|
);
|
||||||
<NotificationIcon />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="new-project-button"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={handleCreateNewProject}
|
|
||||||
>
|
|
||||||
+ New project
|
|
||||||
</div>
|
|
||||||
<div className="side-bar-content-container">
|
|
||||||
<div className="side-bar-options-container">
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
activeTab === "Home" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
onClick={() => setActiveTab("Home")}
|
|
||||||
>
|
|
||||||
<HomeIcon />
|
|
||||||
Home
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
activeTab === "Projects" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="Projects"
|
|
||||||
onClick={() => setActiveTab("Projects")}
|
|
||||||
>
|
|
||||||
<ProjectsIcon />
|
|
||||||
Projects
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
activeTab === "Trash" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="Trash"
|
|
||||||
onClick={() => setActiveTab("Trash")}
|
|
||||||
>
|
|
||||||
<TrashIcon />
|
|
||||||
Trash
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
activeTab === "Tutorials" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="coming soon"
|
|
||||||
onClick={() => {
|
|
||||||
// setActiveTab("Tutorials");
|
|
||||||
console.warn("Tutorials comming soon");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TutorialsIcon />
|
|
||||||
Tutorials
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
activeTab === "Documentation"
|
|
||||||
? "option-list active"
|
|
||||||
: "option-list"
|
|
||||||
}
|
|
||||||
title="coming soon"
|
|
||||||
onClick={() => {
|
|
||||||
// setActiveTab("Documentation");
|
|
||||||
console.warn("Documentation comming soon");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DocumentationIcon />
|
|
||||||
Documentation
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="side-bar-options-container">
|
|
||||||
<div className="option-list" title="coming soon">
|
|
||||||
<SettingsIcon />
|
|
||||||
Settings
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="option-list"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => {
|
|
||||||
localStorage.clear();
|
|
||||||
navigate("/");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<LogoutIcon />
|
|
||||||
Log out
|
|
||||||
</div>
|
|
||||||
<div className="option-list" title="coming soon">
|
|
||||||
<HelpIcon />
|
|
||||||
Help & Feedback
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SidePannel;
|
export default SidePannel;
|
||||||
|
|||||||
@@ -72,11 +72,13 @@ function MainScene() {
|
|||||||
if (versionHistory.length > 0 && organization && userId) {
|
if (versionHistory.length > 0 && organization && userId) {
|
||||||
recentlyViewed(organization, userId).then((projects) => {
|
recentlyViewed(organization, userId).then((projects) => {
|
||||||
const recent_opened_verisionID = (Object.values(projects?.RecentlyViewed || {})[0] as any)?.Present_version._id;
|
const recent_opened_verisionID = (Object.values(projects?.RecentlyViewed || {})[0] as any)?.Present_version._id;
|
||||||
if (recent_opened_verisionID) {
|
if (recent_opened_verisionID && projects.RecentlyViewed[0]._id === projectId) {
|
||||||
const version = versionHistory.find((ver) => ver.versionId === recent_opened_verisionID);
|
const version = versionHistory.find((ver) => ver.versionId === recent_opened_verisionID);
|
||||||
if (version) {
|
if (version) {
|
||||||
setSelectedVersion(version);
|
setSelectedVersion(version);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setSelectedVersion(versionHistory[0]);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { useCamMode, useToggleView } from "../../../store/builder/store";
|
|||||||
import switchToThirdPerson from "./functions/switchToThirdPerson";
|
import switchToThirdPerson from "./functions/switchToThirdPerson";
|
||||||
import switchToFirstPerson from "./functions/switchToFirstPerson";
|
import switchToFirstPerson from "./functions/switchToFirstPerson";
|
||||||
import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys";
|
import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys";
|
||||||
import { firstPersonCamera } from "./functions/firstPersonCamera";
|
|
||||||
|
|
||||||
const CamMode: React.FC = () => {
|
const CamMode: React.FC = () => {
|
||||||
const { camMode, setCamMode } = useCamMode();
|
const { camMode, setCamMode } = useCamMode();
|
||||||
@@ -41,14 +40,22 @@ const CamMode: React.FC = () => {
|
|||||||
const keyCombination = detectModifierKeys(event);
|
const keyCombination = detectModifierKeys(event);
|
||||||
|
|
||||||
if (keyCombination === "/" && !isTransitioning && !toggleView) {
|
if (keyCombination === "/" && !isTransitioning && !toggleView) {
|
||||||
firstPersonCamera({
|
setIsTransitioning && setIsTransitioning(true);
|
||||||
setIsTransitioning,
|
|
||||||
state,
|
state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
|
||||||
camMode,
|
state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
|
||||||
setCamMode,
|
state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse;
|
||||||
switchToFirstPerson,
|
state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
|
||||||
switchToThirdPerson,
|
|
||||||
});
|
if (camMode === "ThirdPerson") {
|
||||||
|
setCamMode("FirstPerson");
|
||||||
|
await switchToFirstPerson(state.controls, state.camera);
|
||||||
|
} else if (camMode === "FirstPerson") {
|
||||||
|
setCamMode("ThirdPerson");
|
||||||
|
await switchToThirdPerson(state.controls, state.camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsTransitioning && setIsTransitioning(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyCombination === 'Shift') {
|
if (keyCombination === 'Shift') {
|
||||||
@@ -77,7 +84,7 @@ const CamMode: React.FC = () => {
|
|||||||
if (!state.controls) return;
|
if (!state.controls) return;
|
||||||
if (camMode === "ThirdPerson" || !document.pointerLockElement) return;
|
if (camMode === "ThirdPerson" || !document.pointerLockElement) return;
|
||||||
|
|
||||||
const speedMultiplier = isShiftActive ? 4 : 1;
|
const speedMultiplier = isShiftActive ? CONSTANTS.firstPersonControls.sprintSpeed : CONSTANTS.firstPersonControls.walkSpeed;
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed * speedMultiplier, true);
|
state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed * speedMultiplier, true);
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
|
||||||
|
|
||||||
interface FirstPersonCameraProps {
|
|
||||||
setIsTransitioning?: (value: boolean) => void;
|
|
||||||
state: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FirstPersonCameraParams extends FirstPersonCameraProps {
|
|
||||||
camMode: string;
|
|
||||||
setCamMode: (mode: string) => void;
|
|
||||||
switchToFirstPerson: (controls: any, camera: any) => Promise<void>;
|
|
||||||
switchToThirdPerson: (controls: any, camera: any) => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function firstPersonCamera({
|
|
||||||
setIsTransitioning,
|
|
||||||
state,
|
|
||||||
camMode,
|
|
||||||
setCamMode,
|
|
||||||
switchToFirstPerson,
|
|
||||||
switchToThirdPerson
|
|
||||||
}: FirstPersonCameraParams): Promise<void> {
|
|
||||||
setIsTransitioning && setIsTransitioning(true);
|
|
||||||
|
|
||||||
state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
|
|
||||||
state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
|
|
||||||
state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse;
|
|
||||||
state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
|
|
||||||
|
|
||||||
if (camMode === "ThirdPerson") {
|
|
||||||
setCamMode("FirstPerson");
|
|
||||||
await switchToFirstPerson(state.controls, state.camera);
|
|
||||||
} else if (camMode === "FirstPerson") {
|
|
||||||
setCamMode("ThirdPerson");
|
|
||||||
await switchToThirdPerson(state.controls, state.camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsTransitioning && setIsTransitioning(false);
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,8 @@ export type Controls = {
|
|||||||
backwardSpeed: number;
|
backwardSpeed: number;
|
||||||
leftSpeed: number;
|
leftSpeed: number;
|
||||||
rightSpeed: number;
|
rightSpeed: number;
|
||||||
|
walkSpeed: number;
|
||||||
|
sprintSpeed: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ThirdPersonControls = {
|
export type ThirdPersonControls = {
|
||||||
@@ -199,6 +201,8 @@ export const firstPersonControls: Controls = {
|
|||||||
backwardSpeed: -0.1, // Speed of backward movement
|
backwardSpeed: -0.1, // Speed of backward movement
|
||||||
leftSpeed: -0.1, // Speed of left movement
|
leftSpeed: -0.1, // Speed of left movement
|
||||||
rightSpeed: 0.1, // Speed of right movement
|
rightSpeed: 0.1, // Speed of right movement
|
||||||
|
walkSpeed: 1, // Walk speed
|
||||||
|
sprintSpeed: 4 // Sprint Speed
|
||||||
};
|
};
|
||||||
|
|
||||||
export const thirdPersonControls: ThirdPersonControls = {
|
export const thirdPersonControls: ThirdPersonControls = {
|
||||||
|
|||||||
Reference in New Issue
Block a user