starting desktop + apartment
This commit is contained in:
@@ -1,8 +1,19 @@
|
||||
<linker>
|
||||
<assembly fullname="Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="ColorPicker" preserve="all" />
|
||||
<type fullname="FloorButton" preserve="all" />
|
||||
<type fullname="IndoorButton" preserve="all" />
|
||||
<type fullname="IndoorCameraHandler" preserve="all" />
|
||||
<type fullname="MobileDisableAutoSwitchControls" preserve="all" />
|
||||
<type fullname="OutdoorCameraHandler" preserve="all" />
|
||||
<type fullname="OutdoorCameraSwitcher" preserve="all" />
|
||||
<type fullname="OutdoorInstaller" preserve="all" />
|
||||
<type fullname="Player" preserve="all" />
|
||||
<type fullname="StarterAssets.StarterAssetsInputs" preserve="all" />
|
||||
<type fullname="StarterAssets.ThirdPersonController" preserve="all" />
|
||||
<type fullname="StarterAssets.UICanvasControllerInput" preserve="all" />
|
||||
<type fullname="UIVirtualTouchZone" preserve="all" />
|
||||
<type fullname=".UIVirtualTouchZone/Event" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="BakeryRuntimeAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="BakeryDirectLight" preserve="all" />
|
||||
@@ -15,18 +26,21 @@
|
||||
<type fullname=".ftLightmapsStorage/SectorData" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="Cinemachine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="Cinemachine.CinemachineBasicMultiChannelPerlin" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineBrain" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineHardLockToTarget" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineHardLookAt" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachinePipeline" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineSameAsFollowTarget" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineTransposer" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineVirtualCamera" preserve="all" />
|
||||
<type fullname="Cinemachine.NoiseSettings" preserve="all" />
|
||||
<type fullname="Cinemachine.CinemachineBlendDefinition" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.CinemachineBrain/BrainEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.CinemachineBrain/VcamActivatedEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.CinemachineVirtualCameraBase/TransitionParams" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.LensSettings" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.NoiseSettings/NoiseParams" preserve="nothing" serialized="true" />
|
||||
<type fullname="Cinemachine.NoiseSettings/TransformNoiseParams" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all">
|
||||
<type fullname="UnityEngine.AddressableAssets.Addressables" preserve="all" />
|
||||
@@ -34,12 +48,17 @@
|
||||
<assembly fullname="Unity.InputSystem, Version=1.7.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.InputSystem.InputActionAsset" preserve="all" />
|
||||
<type fullname="UnityEngine.InputSystem.InputActionReference" preserve="all" />
|
||||
<type fullname="UnityEngine.InputSystem.PlayerInput" preserve="all" />
|
||||
<type fullname="UnityEngine.InputSystem.UI.InputSystemUIInputModule" preserve="all" />
|
||||
<type fullname="UnityEngine.InputSystem.InputAction" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.InputActionMap" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.InputBinding" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.InputControlScheme" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.InputControlScheme/DeviceRequirement" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.PlayerInput/ActionEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.PlayerInput/ControlsChangedEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.PlayerInput/DeviceLostEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.InputSystem.PlayerInput/DeviceRegainedEvent" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.Rendering.Volume" preserve="all" />
|
||||
@@ -71,6 +90,17 @@
|
||||
<type fullname="UnityEngine.ResourceManagement.ResourceProviders.LegacyResourcesProvider" preserve="all" />
|
||||
<type fullname="UnityEngine.ResourceManagement.ResourceProviders.SceneProvider" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="Unity.TextMeshPro, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="TMPro.TextMeshProUGUI" preserve="all" />
|
||||
<type fullname="TMPro.TMP_FontAsset" preserve="all" />
|
||||
<type fullname="TMPro.FaceInfo_Legacy" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.FontAssetCreationSettings" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.KerningTable" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.TMP_Character" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.TMP_FontFeatureTable" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.TMP_FontWeightPair" preserve="nothing" serialized="true" />
|
||||
<type fullname="TMPro.VertexGradient" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.AudioModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.AudioListener" preserve="all" />
|
||||
</assembly>
|
||||
@@ -83,7 +113,6 @@
|
||||
<type fullname="UnityEngine.LightmapSettings" preserve="all" />
|
||||
<type fullname="UnityEngine.LightProbeGroup" preserve="all" />
|
||||
<type fullname="UnityEngine.LightProbes" preserve="all" />
|
||||
<type fullname="UnityEngine.LODGroup" preserve="all" />
|
||||
<type fullname="UnityEngine.Material" preserve="all" />
|
||||
<type fullname="UnityEngine.Mesh" preserve="all" />
|
||||
<type fullname="UnityEngine.MeshFilter" preserve="all" />
|
||||
@@ -93,18 +122,26 @@
|
||||
<type fullname="UnityEngine.ReflectionProbe" preserve="all" />
|
||||
<type fullname="UnityEngine.RenderSettings" preserve="all" />
|
||||
<type fullname="UnityEngine.Shader" preserve="all" />
|
||||
<type fullname="UnityEngine.Sprite" preserve="all" />
|
||||
<type fullname="UnityEngine.Texture2D" preserve="all" />
|
||||
<type fullname="UnityEngine.Transform" preserve="all" />
|
||||
<type fullname="UnityEngine.Events.ArgumentCache" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.Events.PersistentCallGroup" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.Events.PersistentListenerMode" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.Events.UnityEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.RectOffset" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.BoxCollider" preserve="all" />
|
||||
<type fullname="UnityEngine.CharacterController" preserve="all" />
|
||||
<type fullname="UnityEngine.MeshCollider" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.TextRenderingModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.Font" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="UnityEngine.EventSystems.EventSystem" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.Button" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.CanvasScaler" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.ContentSizeFitter" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.GraphicRaycaster" preserve="all" />
|
||||
@@ -113,6 +150,7 @@
|
||||
<type fullname="UnityEngine.UI.Toggle" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.ToggleGroup" preserve="all" />
|
||||
<type fullname="UnityEngine.UI.AnimationTriggers" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.UI.Button/ButtonClickedEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.UI.ColorBlock" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.UI.MaskableGraphic/CullStateChangedEvent" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.UI.Navigation" preserve="nothing" serialized="true" />
|
||||
@@ -126,4 +164,13 @@
|
||||
<assembly fullname="Zenject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<type fullname="Zenject.SceneContext" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.TextCoreFontEngineModule">
|
||||
<type fullname="UnityEngine.TextCore.FaceInfo" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.Glyph" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.GlyphMetrics" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.GlyphRect" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.LowLevel.GlyphAdjustmentRecord" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.LowLevel.GlyphPairAdjustmentRecord" preserve="nothing" serialized="true" />
|
||||
<type fullname="UnityEngine.TextCore.LowLevel.GlyphValueRecord" preserve="nothing" serialized="true" />
|
||||
</assembly>
|
||||
</linker>
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"m_buildTarget":"WebGL","m_SettingsHash":"254e8cd717ac24c4e28f4ae82d967d4b","m_CatalogLocations":[{"m_Keys":["AddressablesMainContentCatalog"],"m_InternalId":"{UnityEngine.AddressableAssets.Addressables.RuntimePath}/catalog.json","m_Provider":"UnityEngine.AddressableAssets.ResourceProviders.ContentCatalogProvider","m_Dependencies":[],"m_ResourceType":{"m_AssemblyName":"Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","m_ClassName":"UnityEngine.AddressableAssets.ResourceLocators.ContentCatalogData"},"SerializedData":[7,76,85,110,105,116,121,46,82,101,115,111,117,114,99,101,77,97,110,97,103,101,114,44,32,86,101,114,115,105,111,110,61,48,46,48,46,48,46,48,44,32,67,117,108,116,117,114,101,61,110,101,117,116,114,97,108,44,32,80,117,98,108,105,99,75,101,121,84,111,107,101,110,61,110,117,108,108,75,85,110,105,116,121,69,110,103,105,110,101,46,82,101,115,111,117,114,99,101,77,97,110,97,103,101,109,101,110,116,46,82,101,115,111,117,114,99,101,80,114,111,118,105,100,101,114,115,46,80,114,111,118,105,100,101,114,76,111,97,100,82,101,113,117,101,115,116,79,112,116,105,111,110,115,50,0,0,0,123,0,34,0,109,0,95,0,73,0,103,0,110,0,111,0,114,0,101,0,70,0,97,0,105,0,108,0,117,0,114,0,101,0,115,0,34,0,58,0,116,0,114,0,117,0,101,0,125,0]}],"m_ProfileEvents":false,"m_LogResourceManagerExceptions":true,"m_ExtraInitializationData":[],"m_DisableCatalogUpdateOnStart":false,"m_IsLocalCatalogInBundle":false,"m_CertificateHandlerType":{"m_AssemblyName":"","m_ClassName":""},"m_AddressablesVersion":"1.21.19","m_maxConcurrentWebRequests":3,"m_CatalogRequestsTimeout":0}
|
||||
{"m_buildTarget":"WebGL","m_SettingsHash":"67222d59d8da2748b0fb420b725d3303","m_CatalogLocations":[{"m_Keys":["AddressablesMainContentCatalog"],"m_InternalId":"{UnityEngine.AddressableAssets.Addressables.RuntimePath}/catalog.json","m_Provider":"UnityEngine.AddressableAssets.ResourceProviders.ContentCatalogProvider","m_Dependencies":[],"m_ResourceType":{"m_AssemblyName":"Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","m_ClassName":"UnityEngine.AddressableAssets.ResourceLocators.ContentCatalogData"},"SerializedData":[7,76,85,110,105,116,121,46,82,101,115,111,117,114,99,101,77,97,110,97,103,101,114,44,32,86,101,114,115,105,111,110,61,48,46,48,46,48,46,48,44,32,67,117,108,116,117,114,101,61,110,101,117,116,114,97,108,44,32,80,117,98,108,105,99,75,101,121,84,111,107,101,110,61,110,117,108,108,75,85,110,105,116,121,69,110,103,105,110,101,46,82,101,115,111,117,114,99,101,77,97,110,97,103,101,109,101,110,116,46,82,101,115,111,117,114,99,101,80,114,111,118,105,100,101,114,115,46,80,114,111,118,105,100,101,114,76,111,97,100,82,101,113,117,101,115,116,79,112,116,105,111,110,115,50,0,0,0,123,0,34,0,109,0,95,0,73,0,103,0,110,0,111,0,114,0,101,0,70,0,97,0,105,0,108,0,117,0,114,0,101,0,115,0,34,0,58,0,116,0,114,0,117,0,101,0,125,0]}],"m_ProfileEvents":false,"m_LogResourceManagerExceptions":true,"m_ExtraInitializationData":[],"m_DisableCatalogUpdateOnStart":false,"m_IsLocalCatalogInBundle":false,"m_CertificateHandlerType":{"m_AssemblyName":"","m_ClassName":""},"m_AddressablesVersion":"1.21.19","m_maxConcurrentWebRequests":3,"m_CatalogRequestsTimeout":0}
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
+4
-3
@@ -1,9 +1,10 @@
|
||||
import "./App.css";
|
||||
import Main from "./pages/Main";
|
||||
import Apartment from "./pages/Apartment";
|
||||
import Desktop from "./pages/Desktop/Desktop";
|
||||
import Apartment from "./pages/Mobile/Apartment";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
function App() {
|
||||
return <Apartment />;
|
||||
return <>{isMobile ? <Apartment /> : <Desktop />}</>;
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Outlet } from "react-router-dom";
|
||||
import BackIcon from "../icons/BackIcon";
|
||||
|
||||
const Header = () => {
|
||||
return (
|
||||
<>
|
||||
<header className="fixed left-0 top-0 px-2 w-full bg-[#ddd8d5] z-40 h-11 flex items-center justify-between">
|
||||
<BackIcon />
|
||||
<div className="items-center font-medium text-lg">A1M</div>
|
||||
<div></div>
|
||||
</header>
|
||||
{<Outlet />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,13 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import LoadingIcon from "../icons/LoadingIcon";
|
||||
|
||||
const loadingMessages = [
|
||||
{ id: 1, value: "looking for a villa" },
|
||||
{ id: 2, value: "building the walls" },
|
||||
{ id: 3, value: "installing the roof" },
|
||||
{ id: 4, value: "arranging the furniture" },
|
||||
{ id: 5, value: "preparing the villa for showing" },
|
||||
];
|
||||
import { loadingMessages } from "../consts/loading";
|
||||
|
||||
const LoaderModal = () => {
|
||||
const [offset, setOffset] = useState(0);
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import ButtonSwipperIcon from "../icons/ButtonSwipperIcon";
|
||||
import { Parameters as ParametersType } from "../types/appartment";
|
||||
import Parameters from "./Parameters";
|
||||
import Slider from "./Slider";
|
||||
import { SwipeEventData, useSwipeable } from "react-swipeable";
|
||||
|
||||
type ViewControllerProps = {
|
||||
parameters: ParametersType;
|
||||
};
|
||||
|
||||
const apartmentViews = [
|
||||
{ id: 1, title: "General View" },
|
||||
{ id: 2, title: "Ground Floor" },
|
||||
{ id: 3, title: "First Floor" },
|
||||
];
|
||||
|
||||
const ViewController = ({ parameters }: ViewControllerProps) => {
|
||||
const { sliders } = parameters;
|
||||
const [offset, setOffset] = useState(1);
|
||||
const [selectedViewId, setSelectedViewId] = useState(apartmentViews[0].id);
|
||||
// const [animationFrame, setAnimationFrame] = useState(0)
|
||||
|
||||
const handleOnSwiped = (eventData: SwipeEventData) => {
|
||||
if (eventData.dir === "Down") {
|
||||
setOffset(1);
|
||||
}
|
||||
if (eventData.dir === "Up") {
|
||||
// setTimeout(() => {
|
||||
setOffset(0);
|
||||
// }, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnBackClick = () => {
|
||||
setOffset(1);
|
||||
};
|
||||
|
||||
const handleOnViewClick = (viewId: number) => {
|
||||
return () => setSelectedViewId(viewId);
|
||||
};
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwiped: handleOnSwiped,
|
||||
// onSwiping:()=>
|
||||
// onSwipeStart: () => setIsScroll(true),
|
||||
// onSwiped: () => setIsScroll(false),
|
||||
|
||||
// onSwiped: () => console.log("first"),
|
||||
// onTouchEndOrOnMouseUp: handleOnTouchEnd,
|
||||
// swipeDuration: 300,
|
||||
// preventScrollOnSwipe: true,
|
||||
// onSwipedDown: (e) => e.preventDefault(),
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="bg-white flex flex-col transition-all duration-1000 fixed left-0 bottom-28">
|
||||
<div
|
||||
className={`${
|
||||
offset === 1 ? "rounded-ss-2xl rounded-se-2xl" : ""
|
||||
} bg-white w-full h-[calc(100vh)] border flex flex-col transition-all duration-1000 fixed left-0 top-11`}
|
||||
style={{
|
||||
transform: `translateY(calc(${offset * 80}vh))`,
|
||||
}}
|
||||
>
|
||||
<div className="absolute top-[-51px] w-full h-9 px-6 bg">
|
||||
<div
|
||||
className={`even bg-white rounded-[32px] flex text-sm justify-center w-fit border-2 transition-all duration-500 mx-auto`}
|
||||
style={{
|
||||
opacity: offset,
|
||||
pointerEvents: `${offset === 0 ? "none" : "auto"}`,
|
||||
}}
|
||||
>
|
||||
{apartmentViews.map((view) => (
|
||||
<div
|
||||
onClick={handleOnViewClick(view.id)}
|
||||
key={view.id}
|
||||
className={`${
|
||||
selectedViewId === view.id ? "bg-black text-white" : ""
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
>
|
||||
{" "}
|
||||
{view.title}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto flex justify-center self-start w-full">
|
||||
<ButtonSwipperIcon />
|
||||
</div>
|
||||
<div className="h-[calc(100vh-110px)] overflow-y-scroll relative">
|
||||
<div
|
||||
className="absolute bg-black z-30 h-[30%] w-full opacity-0"
|
||||
{...handlers}
|
||||
></div>
|
||||
<Slider sliders={sliders} />
|
||||
<Parameters parameters={parameters} />
|
||||
<div className="flex p-6 gap-2 overflow-x-scroll">
|
||||
{parameters.perspectiveWorkings.map((working) => (
|
||||
<img className="rounded-lg" src={working} alt="" key={working} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-6 pt-4 pb-14 mt-auto border">
|
||||
<button
|
||||
className="border flex w-full py-3 justify-center rounded-full"
|
||||
onClick={handleOnBackClick}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
// </div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewController;
|
||||
@@ -0,0 +1,37 @@
|
||||
import BackIcon from "../../../icons/BackIcon";
|
||||
import HelpIcon from "../../../icons/HelpIcon";
|
||||
import useStore from "../../../store/store";
|
||||
import PopupModal from "./PopupModal";
|
||||
import HelpPanel from "./HelpPanel";
|
||||
|
||||
const ButtonPanel = () => {
|
||||
const { setModal, setPanel } = useStore();
|
||||
|
||||
const handleOnHelpClick = () => {
|
||||
setModal(<PopupModal />);
|
||||
setPanel(<HelpPanel />);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
<div className="flex w-full absolute p-4 justify-between top-0 left-0">
|
||||
<button className="flex w-fit items-center gap-1 py-[6px] pl-2 pr-4 bg-white rounded-full text-sm font-medium border border-[#C7BDBA]">
|
||||
<div className="w-5 h-5 flex items-center justify-center">
|
||||
<BackIcon className="w-[5px] h-[10px]" />
|
||||
</div>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
className="bg-white border-[#C7BDBA] p-[6px] rounded-full"
|
||||
onClick={handleOnHelpClick}
|
||||
>
|
||||
<HelpIcon />
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ButtonPanel;
|
||||
@@ -0,0 +1,28 @@
|
||||
import { A1MViewParams } from "../../../consts/viewParams";
|
||||
import CrossIcon from "../../../icons/CrossIcon";
|
||||
import useStore from "../../../store/store";
|
||||
import ButtonPanel from "./ButtonPanel";
|
||||
import ViewControllerModal from "./ViewControllerModal";
|
||||
|
||||
const HelpPanel = () => {
|
||||
const { setPanel, setModal } = useStore();
|
||||
|
||||
const handleOnClose = () => {
|
||||
setModal(<ViewControllerModal parameters={A1MViewParams} />);
|
||||
setPanel(<ButtonPanel />);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex bg-[#F3F2F0] w-full absolute px-1 py-2 justify-between h-14 items-center">
|
||||
<div></div>
|
||||
<div className="font-medium text-lg">Control Help</div>
|
||||
<div className="flex p-2 cursor-pointer">
|
||||
<div className="flex p-2 cursor-pointer" onClick={handleOnClose}>
|
||||
<CrossIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpPanel;
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Parameters as ParametersType } from "../../../types/appartment";
|
||||
|
||||
type ImageSliderProps = {
|
||||
parameters: ParametersType;
|
||||
};
|
||||
|
||||
const ImageSlider = ({ parameters }: ImageSliderProps) => {
|
||||
return (
|
||||
<div className="flex p-6 gap-2 overflow-x-scroll">
|
||||
{parameters.perspectiveWorkings.map((working) => (
|
||||
<img className="rounded-lg" src={working} alt="" key={working} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageSlider;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Parameters } from "../types/appartment";
|
||||
import { Parameters } from "../../../types/appartment";
|
||||
|
||||
type ParametersProps = {
|
||||
parameters: Parameters;
|
||||
@@ -0,0 +1,59 @@
|
||||
import { useState } from "react";
|
||||
import useStore from "../../../store/store";
|
||||
import ViewControllerModal from "./ViewControllerModal";
|
||||
import { A1MViewParams } from "../../../consts/viewParams";
|
||||
import ButtonPanel from "./ButtonPanel";
|
||||
import { popups } from "../../../consts/popups";
|
||||
|
||||
const PopupModal = () => {
|
||||
const [currentPopupId, setCurrentPopupId] = useState(1);
|
||||
const { setModal, setPanel } = useStore();
|
||||
|
||||
const handleOnNextClick = (popup: number) => {
|
||||
return () => setCurrentPopupId(popup + 1);
|
||||
};
|
||||
|
||||
const handleOnComplete = () => {
|
||||
setModal(<ViewControllerModal parameters={A1MViewParams} />);
|
||||
setPanel(<ButtonPanel />);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{popups.map((popup, index) => (
|
||||
<div
|
||||
key={popup.id}
|
||||
className={`absolute bottom-0 w-full p-4 transition-all duration-300 z-20 ${
|
||||
currentPopupId !== popup.id ? "hidden opacity-0" : "opacity-1"
|
||||
}`}
|
||||
>
|
||||
<div className="bg-white p-4 border rounded-2xl">
|
||||
<div className="flex gap-4">
|
||||
<div className="h-full w-10">{popup.icon}</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="text-sm pr-12">{popup.title}</div>
|
||||
{popups.length === index + 1 ? (
|
||||
<button
|
||||
onClick={handleOnComplete}
|
||||
className="text-white bg-black rounded-full px-5 py-[6px] w-fit"
|
||||
>
|
||||
Complete
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
onClick={handleOnNextClick(popup.id)}
|
||||
className="text-white bg-black rounded-full px-5 py-[6px] w-fit"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PopupModal;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import { SliderType } from "../types/appartment";
|
||||
import { SliderType } from "../../../types/appartment";
|
||||
|
||||
type SliderProps = {
|
||||
sliders: SliderType[];
|
||||
@@ -0,0 +1,87 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { SwipeEventData, useSwipeable } from "react-swipeable";
|
||||
import ButtonSwipperIcon from "../../../icons/ButtonSwipperIcon";
|
||||
import { Parameters as ParametersType } from "../../../types/appartment";
|
||||
import Parameters from "./Parameters";
|
||||
import Slider from "./Slider";
|
||||
import ImageSlider from "./ImageSlider";
|
||||
import ViewToggle from "./ViewToggle";
|
||||
|
||||
type ViewControllerModalProps = {
|
||||
parameters: ParametersType;
|
||||
};
|
||||
|
||||
const ViewControllerModal = ({ parameters }: ViewControllerModalProps) => {
|
||||
const { sliders } = parameters;
|
||||
const [offset, setOffset] = useState(1);
|
||||
const [isTouchable, setIsTouchable] = useState(true);
|
||||
const [scrollY, setScrollY] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (offset === 1 || scrollY === 0) {
|
||||
setIsTouchable(true);
|
||||
} else {
|
||||
setIsTouchable(false);
|
||||
}
|
||||
}, [scrollY, offset]);
|
||||
|
||||
const handleOnSwiped = (eventData: SwipeEventData) => {
|
||||
if (eventData.dir === "Down") {
|
||||
setOffset(1);
|
||||
}
|
||||
if (eventData.dir === "Up") {
|
||||
setOffset(0);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnBackClick = () => {
|
||||
setOffset(1);
|
||||
};
|
||||
|
||||
const handleOnScroll = (event: React.UIEvent<HTMLDivElement, UIEvent>) => {
|
||||
setScrollY(event.currentTarget.scrollTop);
|
||||
};
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwiped: handleOnSwiped,
|
||||
preventScrollOnSwipe: offset === 1,
|
||||
trackTouch: isTouchable,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className=" flex flex-col fixed left-0 top-0 z-20 bg-black">
|
||||
<div
|
||||
{...handlers}
|
||||
className={`${
|
||||
offset === 1 ? "rounded-ss-2xl rounded-se-2xl" : ""
|
||||
} bg-white w-full h-[calc(100vh)] border flex flex-col transition-all duration-500 fixed left-0 top-0 ease-in-out`}
|
||||
style={{
|
||||
transform: `translateY(calc(${offset * 80}vh))`,
|
||||
}}
|
||||
>
|
||||
<ViewToggle offset={offset} />
|
||||
<div className="mx-auto flex justify-center self-start w-full">
|
||||
<ButtonSwipperIcon />
|
||||
</div>
|
||||
<div
|
||||
className="h-[calc(100vh-110px)] overflow-y-scroll relative"
|
||||
onScroll={handleOnScroll}
|
||||
>
|
||||
<Slider sliders={sliders} />
|
||||
<Parameters parameters={parameters} />
|
||||
<ImageSlider parameters={parameters} />
|
||||
</div>
|
||||
<div className="px-6 py-4 mt-auto border">
|
||||
<button
|
||||
className="border flex w-full py-3 justify-center rounded-full"
|
||||
onClick={handleOnBackClick}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewControllerModal;
|
||||
@@ -0,0 +1,79 @@
|
||||
import { useState } from "react";
|
||||
import useStore from "../../../store/store";
|
||||
|
||||
type ViewSwitcherProps = {
|
||||
offset?: number;
|
||||
isDesktop?: boolean;
|
||||
};
|
||||
|
||||
const ViewToggle = ({ offset, isDesktop }: ViewSwitcherProps) => {
|
||||
const [selectedViewId, setSelectedViewId] = useState(1);
|
||||
const { sendMessageToUnity } = useStore();
|
||||
|
||||
const handleOnFirstClick = () => {
|
||||
setSelectedViewId(1);
|
||||
if (sendMessageToUnity) {
|
||||
sendMessageToUnity("LevelSwitcher", "LoadSceneSingle", "Outdoor/A1");
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnSecondClick = () => {
|
||||
setSelectedViewId(2);
|
||||
if (sendMessageToUnity) {
|
||||
sendMessageToUnity("LevelSwitcher", "LoadSceneSingle", "Indoor/A1F1");
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnThirdClick = () => {
|
||||
setSelectedViewId(3);
|
||||
if (sendMessageToUnity) {
|
||||
sendMessageToUnity("LevelSwitcher", "LoadSceneSingle", "Indoor/A1F2");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${
|
||||
isDesktop ? "" : "absolute top-[-51px]"
|
||||
} w-full h-9 px-6 bg`}
|
||||
>
|
||||
<div
|
||||
className={`even bg-white rounded-[32px] flex text-sm justify-center w-fit border-2 transition-all duration-300 ease-in-out mx-auto select-none cursor-pointer`}
|
||||
style={{
|
||||
opacity: offset ? offset : 1,
|
||||
pointerEvents: `${offset === 0 ? "none" : "auto"}`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onClick={handleOnFirstClick}
|
||||
className={`${
|
||||
selectedViewId === 1 ? "bg-black text-white" : ""
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
>
|
||||
{" "}
|
||||
General View
|
||||
</div>
|
||||
<div
|
||||
onClick={handleOnSecondClick}
|
||||
className={`${
|
||||
selectedViewId === 2 ? "bg-black text-white" : ""
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
>
|
||||
{" "}
|
||||
Ground Floor
|
||||
</div>
|
||||
<div
|
||||
onClick={handleOnThirdClick}
|
||||
className={`${
|
||||
selectedViewId === 3 ? "bg-black text-white" : ""
|
||||
} py-2 px-4 w-fit rounded-[32px] `}
|
||||
>
|
||||
{" "}
|
||||
First Floor
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewToggle;
|
||||
@@ -0,0 +1,9 @@
|
||||
const loadingMessages = [
|
||||
{ id: 1, value: "looking for a villa" },
|
||||
{ id: 2, value: "building the walls" },
|
||||
{ id: 3, value: "installing the roof" },
|
||||
{ id: 4, value: "arranging the furniture" },
|
||||
{ id: 5, value: "preparing the villa for showing" },
|
||||
];
|
||||
|
||||
export {loadingMessages}
|
||||
@@ -0,0 +1,24 @@
|
||||
import ChangeToastIcon from "../icons/ChangeToastIcon";
|
||||
import RotateToastIcon from "../icons/RotateToastIcon";
|
||||
import TapToastIcon from "../icons/TapToastIcon";
|
||||
import { PopupType } from "../types/popup";
|
||||
|
||||
const popups: PopupType[] = [
|
||||
{
|
||||
id: 1,
|
||||
icon: <TapToastIcon />,
|
||||
title: "Tap on the floor to move in 3D space.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: <RotateToastIcon />,
|
||||
title: "Rotate the camera by swiping the screen.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: <ChangeToastIcon />,
|
||||
title: "Change the angle of view with a pinch.",
|
||||
},
|
||||
];
|
||||
|
||||
export { popups };
|
||||
@@ -0,0 +1,29 @@
|
||||
import Parameters from "../components/mobile/Appartment/Parameters";
|
||||
|
||||
const A1MViewParams: Parameters = {
|
||||
type: "A1M",
|
||||
plotArea: "1080 Sq.m",
|
||||
totalBuildUpArea: "472 Sq.m",
|
||||
TotalCountBedroms: 5,
|
||||
villaTheme: "Modern",
|
||||
sliders: [
|
||||
{
|
||||
title: "Ground Floor",
|
||||
image: "/images/apartment/A1M/A1M_GF.png",
|
||||
},
|
||||
{
|
||||
title: "First Floor",
|
||||
image: "/images/apartment/A1M/A1M_1F.png",
|
||||
},
|
||||
{
|
||||
title: "Parking",
|
||||
image: "/images/apartment/A1M/A1M_P.png",
|
||||
},
|
||||
],
|
||||
perspectiveWorkings: [
|
||||
"/images/apartment/A1M/perspectiveWorking/009_Villa_A1MO_CAM_01_R05.jpg",
|
||||
"/images/apartment/A1M/perspectiveWorking/009_Villa_A1MO_CAM_02_R05.jpg",
|
||||
],
|
||||
};
|
||||
|
||||
export { A1MViewParams };
|
||||
@@ -1,6 +1,9 @@
|
||||
const BackIcon = () => {
|
||||
import { IconProps } from "../types/icon";
|
||||
|
||||
const BackIcon = ({ className }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
className={`${className ? className : ""}`}
|
||||
width="12"
|
||||
height="20"
|
||||
viewBox="0 0 12 20"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
const ChangeToastIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M23.9184 18.1572L23.9181 18.1558M23.9181 18.1558C23.7403 17.4911 23.8337 16.7829 24.1778 16.187C24.5221 15.5906 25.0892 15.1555 25.7544 14.9773C26.4195 14.799 27.1282 14.8923 27.7246 15.2366C28.3209 15.5809 28.7561 16.148 28.9343 16.8132L30.2783 21.8291C30.6078 23.059 30.7082 24.3382 30.5753 25.6029M23.9181 18.1558L23.5157 16.6526C23.3375 15.9874 22.9023 15.4203 22.3059 15.076C21.7096 14.7317 21.0009 14.6384 20.3357 14.8166C19.6706 14.9948 19.1035 15.43 18.7592 16.0263C18.4149 16.6227 18.3216 17.3314 18.4998 17.9966L18.6337 18.498L16.3489 9.97102C16.1707 9.30587 15.7355 8.73877 15.1392 8.39446C14.5428 8.05015 13.8341 7.95685 13.169 8.13508C12.5038 8.3133 11.9367 8.74846 11.5924 9.34481C11.2481 9.94117 11.1548 10.6499 11.333 11.315L14.7864 24.2032C14.7864 24.2032 12.6392 23.2903 11.3818 22.4957C11.0472 22.2842 10.8546 22.0627 10.5395 21.9319C10.2244 21.8012 9.88659 21.7338 9.54544 21.7337C9.20429 21.7335 8.86646 21.8006 8.55125 21.9311C8.23605 22.0616 7.94964 22.2529 7.70841 22.4941C7.46719 22.7354 7.27586 23.0218 7.14538 23.337C7.01489 23.6522 6.9478 23.99 6.94794 24.3312C6.94809 24.6723 7.01546 25.0101 7.14621 25.3252C7.27696 25.6403 7.46852 25.9265 7.70995 26.1676C9.21579 27.9394 10.5495 29.424 11.7811 30.6388"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5.23052 3.99995L5.22882 9.65851M2.40039 6.83008L5.2305 9.65683L8.05895 6.82838"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5.23042 19.8392L5.23212 14.1806M8.06055 17.009L5.23044 14.1823L2.40199 17.0107"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChangeToastIcon;
|
||||
@@ -0,0 +1,21 @@
|
||||
const CrossIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M12 12L17 7M12 12L17 17M12 12L7 7M12 12L7 17"
|
||||
stroke="#050409"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default CrossIcon;
|
||||
@@ -0,0 +1,30 @@
|
||||
import { IconProps } from "../types/icon";
|
||||
|
||||
const HelpIcon = ({ className }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
className={className ? className : ""}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<circle cx="10" cy="10" r="8" stroke="#050409" strokeWidth="1.5" />
|
||||
<path
|
||||
d="M7.5 8.42592C7.5 6.99408 8.61929 5.83333 10 5.83333C11.3807 5.83333 12.5 6.99408 12.5 8.42592C12.5 9.79152 10.7893 10.7426 10 11.6667"
|
||||
stroke="#050409"
|
||||
strokeWidth="1.5"
|
||||
/>
|
||||
<ellipse
|
||||
cx="10.0003"
|
||||
cy="14.5833"
|
||||
rx="0.833333"
|
||||
ry="0.833333"
|
||||
fill="#050409"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpIcon;
|
||||
@@ -0,0 +1,28 @@
|
||||
const RotateToastIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M22.0783 20.6849V20.6836M22.0783 20.6836C22.0787 19.9954 22.3522 19.3356 22.8388 18.849C23.3257 18.3621 23.9861 18.0885 24.6748 18.0885C25.3634 18.0885 26.0238 18.3621 26.5107 18.849C26.9976 19.3359 27.2712 19.9963 27.2712 20.6849V25.8778C27.2712 27.151 27.037 28.4127 26.5813 29.5999M22.0783 20.6836L22.0788 19.1273C22.0788 18.4387 21.8052 17.7783 21.3183 17.2914C20.8314 16.8045 20.171 16.5309 19.4824 16.5309C18.7937 16.5309 18.1333 16.8045 17.6464 17.2914C17.1595 17.7783 16.8859 18.4387 16.8859 19.1273L16.8855 19.6464V10.8186C16.8855 10.13 16.612 9.46956 16.1251 8.98264C15.6381 8.49572 14.9777 8.22217 14.2891 8.22217C13.6005 8.22217 12.9401 8.49572 12.4532 8.98264C11.9662 9.46956 11.6927 10.13 11.6927 10.8186V24.1614C11.6927 24.1614 9.85497 22.7238 8.84606 21.6309C8.57756 21.34 8.44882 21.0762 8.1783 20.8683C7.90778 20.6605 7.59895 20.508 7.26946 20.4196C6.93997 20.3311 6.59629 20.3085 6.25805 20.3529C5.91981 20.3974 5.59365 20.5081 5.29821 20.6787C5.00276 20.8492 4.74383 21.0764 4.53621 21.347C4.32859 21.6177 4.17635 21.9267 4.08819 22.2563C4.00003 22.5858 3.97768 22.9295 4.02243 23.2677C4.06717 23.6059 4.17812 23.932 4.34894 24.2273C5.34487 26.3285 6.24895 28.1077 7.12416 29.5999"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M23.7145 4.87856L21.636 3.67856C20.2713 2.89063 18.7647 2.37922 17.2023 2.17353C15.64 1.96783 14.0524 2.07189 12.5302 2.47975C11.008 2.88762 9.58111 3.5913 8.3309 4.55063C7.08068 5.50995 6.03166 6.70613 5.24373 8.07087L4.06333 10.1154M23.7145 4.87856L22.836 1.6001M23.7145 4.87856L20.436 5.75702M4.06333 10.1154L7.28824 9.25127M4.06333 10.1154L3.19922 6.89047"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default RotateToastIcon;
|
||||
@@ -0,0 +1,27 @@
|
||||
const TapToastIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M22.0783 20.6849V20.6836M22.0783 20.6836C22.0787 19.9954 22.3522 19.3356 22.8388 18.849C23.3257 18.3621 23.9861 18.0885 24.6748 18.0885C25.3634 18.0885 26.0238 18.3621 26.5107 18.849C26.9976 19.3359 27.2712 19.9963 27.2712 20.6849V25.8778C27.2712 27.151 27.037 28.4127 26.5813 29.5999M22.0783 20.6836L22.0788 19.1273C22.0788 18.4387 21.8052 17.7783 21.3183 17.2914C20.8314 16.8045 20.171 16.5309 19.4824 16.5309C18.7937 16.5309 18.1333 16.8045 17.6464 17.2914C17.1595 17.7783 16.8859 18.4387 16.8859 19.1273L16.8855 19.6464V10.8186C16.8855 10.13 16.612 9.46956 16.1251 8.98264C15.6381 8.49572 14.9777 8.22217 14.2891 8.22217C13.6005 8.22217 12.9401 8.49572 12.4532 8.98264C11.9662 9.46956 11.6927 10.13 11.6927 10.8186V24.1614C11.6927 24.1614 9.85497 22.7238 8.84606 21.6309C8.57756 21.34 8.44882 21.0762 8.1783 20.8683C7.90778 20.6605 7.59895 20.508 7.26946 20.4196C6.93997 20.3311 6.59629 20.3085 6.25805 20.3529C5.91981 20.3974 5.59365 20.5081 5.29821 20.6787C5.00276 20.8492 4.74383 21.0764 4.53621 21.347C4.32859 21.6177 4.17635 21.9267 4.08819 22.2563C4.00003 22.5858 3.97768 22.9295 4.02243 23.2677C4.06717 23.6059 4.17812 23.932 4.34894 24.2273C5.34487 26.3285 6.24895 28.1077 7.12416 29.5999"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5.3203 12.8329C4.94712 11.4402 4.89933 9.98029 5.18062 8.56615C5.46191 7.15201 6.06474 5.82153 6.94248 4.67764C7.82022 3.53375 8.94934 2.60711 10.2425 1.9694C11.5356 1.33169 12.9582 1 14.4 1C15.8418 1 17.2644 1.33168 18.5575 1.9694C19.8507 2.60711 20.9798 3.53375 21.8575 4.67764C22.7353 5.82153 23.3381 7.15201 23.6194 8.56615C23.9007 9.98029 23.8529 11.4402 23.4797 12.8329"
|
||||
stroke="#B07A5C"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default TapToastIcon;
|
||||
+2
-8
@@ -2,17 +2,11 @@ import ReactDOM from "react-dom/client";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import Header from "./components/Header.tsx";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
element: <Header />,
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
element: <App />,
|
||||
},
|
||||
],
|
||||
path: "/",
|
||||
element: <App />,
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
import ViewController from "../components/ViewController";
|
||||
import useStore from "../store/store";
|
||||
import { Parameters } from "../types/appartment";
|
||||
import { Unity, useUnityContext } from "react-unity-webgl";
|
||||
import LoaderModal from "../components/LoaderModal";
|
||||
|
||||
const mainViewParams: Parameters = {
|
||||
type: "A1M",
|
||||
plotArea: "1080 Sq.m",
|
||||
totalBuildUpArea: "472 Sq.m",
|
||||
TotalCountBedroms: 5,
|
||||
villaTheme: "Modern",
|
||||
sliders: [
|
||||
{
|
||||
title: "General View",
|
||||
image: "/images/apartment/A1M/A1M_P.png",
|
||||
},
|
||||
{
|
||||
title: "Ground Floor",
|
||||
image: "/images/apartment/A1M/A1M_GF.png",
|
||||
},
|
||||
{
|
||||
title: "First Floor",
|
||||
image: "/images/apartment/A1M/A1M_1F.png",
|
||||
},
|
||||
],
|
||||
perspectiveWorkings: [
|
||||
"/images/apartment/A1M/perspectiveWorking/009_Villa_A1MO_CAM_01_R05.jpg",
|
||||
"/images/apartment/A1M/perspectiveWorking/009_Villa_A1MO_CAM_02_R05.jpg",
|
||||
],
|
||||
};
|
||||
|
||||
const Apartment = () => {
|
||||
const { modal, setModal } = useStore();
|
||||
const { unityProvider, isLoaded } = useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl-stable.loader.js",
|
||||
dataUrl: "builds/estate-webgl-stable.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl-stable.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl-stable.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
setModal(<LoaderModal />);
|
||||
} else {
|
||||
setModal(null);
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}, [isLoaded, setModal]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{modal}
|
||||
|
||||
<div className="h-screen overflow-hidden relative">
|
||||
<Unity
|
||||
unityProvider={unityProvider}
|
||||
style={{ width: "100vw", height: "100vh" }}
|
||||
/>
|
||||
<ViewController parameters={mainViewParams} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Apartment;
|
||||
@@ -0,0 +1,69 @@
|
||||
import { Unity, useUnityContext } from "react-unity-webgl";
|
||||
import useStore from "../../store/store";
|
||||
import { useEffect } from "react";
|
||||
import LoaderModal from "../../components/LoaderModal";
|
||||
import ViewToggle from "../../components/mobile/Appartment/ViewToggle";
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
|
||||
const Apartment = () => {
|
||||
const { loader, setLoader, setSendMessageToUnity } = useStore();
|
||||
|
||||
const {
|
||||
unityProvider,
|
||||
isLoaded,
|
||||
sendMessage,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
} = useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl.loader.js",
|
||||
dataUrl: "builds/estate-webgl.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
|
||||
const handleSetLoaded = (isSceneLoaded: ReactUnityEventParameter) => {
|
||||
if (isSceneLoaded === 0) {
|
||||
setLoader(<LoaderModal />);
|
||||
} else {
|
||||
setLoader(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
addEventListener("SetLoaded", handleSetLoaded);
|
||||
|
||||
return () => {
|
||||
removeEventListener("SetLoaded", handleSetLoaded);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
setLoader(<LoaderModal />);
|
||||
} else {
|
||||
setLoader(null);
|
||||
setSendMessageToUnity(sendMessage);
|
||||
sendMessage("LevelSwitcher", "LoadSceneSingle", "Outdoor/A1");
|
||||
}
|
||||
}, [isLoaded]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{loader}
|
||||
<div className="pt-[101px] pb-[63px] px-[215px] relative">
|
||||
<div className="relative">
|
||||
<div className="absolute top-0 w-full p-4">
|
||||
<ViewToggle isDesktop />
|
||||
</div>
|
||||
<Unity
|
||||
unityProvider={unityProvider}
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Apartment;
|
||||
@@ -0,0 +1,7 @@
|
||||
import Apartment from "./Apartment";
|
||||
|
||||
const Desktop = () => {
|
||||
return <Apartment />;
|
||||
};
|
||||
|
||||
export default Desktop;
|
||||
@@ -1,23 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
import useStore from "../store/store";
|
||||
// import { isMobile } from "react-device-detect";
|
||||
import ViewController from "../components/ViewController";
|
||||
import { Parameters } from "../types/appartment";
|
||||
import LoaderModal from "../components/LoaderModal";
|
||||
|
||||
const Main = () => {
|
||||
const { modal, setModal } = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
// setModal(<LoaderModal />);
|
||||
}, [setModal]);
|
||||
|
||||
return (
|
||||
<div className="h-screen overflow-hidden">
|
||||
{modal}
|
||||
{/* <ViewController parameters={mainViewParams} /> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Main;
|
||||
@@ -0,0 +1,79 @@
|
||||
import { useEffect } from "react";
|
||||
import useStore from "../../store/store";
|
||||
import { Unity, useUnityContext } from "react-unity-webgl";
|
||||
import LoaderModal from "../../components/LoaderModal";
|
||||
import ButtonPanel from "../../components/mobile/Appartment/ButtonPanel";
|
||||
import ViewControllerModal from "../../components/mobile/Appartment/ViewControllerModal";
|
||||
import { A1MViewParams } from "../../consts/viewParams";
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
|
||||
const Apartment = () => {
|
||||
const {
|
||||
modal,
|
||||
loader,
|
||||
panel,
|
||||
setModal,
|
||||
setPanel,
|
||||
setSendMessageToUnity,
|
||||
setLoader,
|
||||
} = useStore();
|
||||
const {
|
||||
unityProvider,
|
||||
isLoaded,
|
||||
sendMessage,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
} = useUnityContext({
|
||||
loaderUrl: "builds/estate-webgl.loader.js",
|
||||
dataUrl: "builds/estate-webgl.data.unityweb",
|
||||
frameworkUrl: "builds/estate-webgl.framework.js.unityweb",
|
||||
codeUrl: "builds/estate-webgl.wasm.unityweb",
|
||||
streamingAssetsUrl: "StreamingAssets",
|
||||
});
|
||||
|
||||
const handleSetLoaded = (isSceneLoaded: ReactUnityEventParameter) => {
|
||||
if (isSceneLoaded === 0) {
|
||||
setLoader(<LoaderModal />);
|
||||
} else {
|
||||
setModal(<ViewControllerModal parameters={A1MViewParams} />);
|
||||
setLoader(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
addEventListener("SetLoaded", handleSetLoaded);
|
||||
|
||||
return () => {
|
||||
removeEventListener("SetLoaded", handleSetLoaded);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
setLoader(<LoaderModal />);
|
||||
} else {
|
||||
setLoader(null);
|
||||
sendMessage("LevelSwitcher", "LoadSceneSingle", "Outdoor/A1");
|
||||
setSendMessageToUnity(sendMessage);
|
||||
setModal(<ViewControllerModal parameters={A1MViewParams} />);
|
||||
setPanel(<ButtonPanel />);
|
||||
}
|
||||
}, [isLoaded]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{modal}
|
||||
{loader}
|
||||
|
||||
<div className="h-screen overflow-hidden relative">
|
||||
{panel}
|
||||
<Unity
|
||||
unityProvider={unityProvider}
|
||||
style={{ width: "100vw", height: "100vh" }}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Apartment;
|
||||
@@ -0,0 +1,7 @@
|
||||
import Apartment from "./Apartment";
|
||||
|
||||
const Mobile = () => {
|
||||
return <Apartment />;
|
||||
};
|
||||
|
||||
export default Mobile;
|
||||
@@ -1,13 +1,27 @@
|
||||
import { ReactUnityEventParameter } from "react-unity-webgl/distribution/types/react-unity-event-parameters";
|
||||
import { create } from "zustand";
|
||||
|
||||
interface StoreType {
|
||||
|
||||
loader: React.ReactNode | null;
|
||||
panel: React.ReactNode | null;
|
||||
modal: React.ReactNode | null;
|
||||
sendMessageToUnity: ((gameObjectName: string, methodName: string, parameter?: ReactUnityEventParameter) => void) | null;
|
||||
setModal: (modal: React.ReactNode | null) => void;
|
||||
setPanel: (panel: React.ReactNode | null) => void;
|
||||
setLoader: (loader: React.ReactNode | null) => void;
|
||||
setSendMessageToUnity: (sendMessageToUnity :(gameObjectName: string, methodName: string, parameter?: ReactUnityEventParameter) => void | null) => void;
|
||||
}
|
||||
|
||||
const useStore = create<StoreType>((set) => ({
|
||||
modal: null,
|
||||
panel: null,
|
||||
sendMessageToUnity: null,
|
||||
loader: null,
|
||||
setModal: (modal) => set(() => ({ modal: modal })),
|
||||
setPanel: (panel) => set(() => ({ panel: panel })),
|
||||
setSendMessageToUnity: (sendMessageToUnity) => set(() => ({ sendMessageToUnity: sendMessageToUnity })),
|
||||
setLoader: (loader) => set(() => ({loader: loader}))
|
||||
}));
|
||||
|
||||
export default useStore;
|
||||
@@ -13,4 +13,10 @@ type Parameters = {
|
||||
perspectiveWorkings: string[]
|
||||
};
|
||||
|
||||
export type {Slider as SliderType, Parameters}
|
||||
type ViewSwitcher ={
|
||||
id: number,
|
||||
title: string,
|
||||
unityHandler: string,
|
||||
}
|
||||
|
||||
export type {Slider as SliderType, Parameters, ViewSwitcher}
|
||||
@@ -0,0 +1,5 @@
|
||||
type IconProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
export type {IconProps}
|
||||
@@ -0,0 +1,7 @@
|
||||
type PopupType = {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type {PopupType}
|
||||
Reference in New Issue
Block a user