Skip to content

Commit

Permalink
feat: implement 'Previsualizar' button
Browse files Browse the repository at this point in the history
  • Loading branch information
paoloose committed Nov 18, 2024
1 parent e2f003d commit 8fc8677
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 42 deletions.
9 changes: 9 additions & 0 deletions app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@
- `dev` - start development server
- `build` - build production version of the app
- `preview` - locally preview production build

## Resources

- 3D Gallery: <https://www.cgtrader.com/items/5155429/download-page>
- 3D scenes: <https://sketchfab.com/search?q=gallery&type=models>
- FPV example: <https://github.com/jgcarrillo/react-fp-movement>
- Virtual museum: <https://github.com/r23/Virtual-Reality-Museum>
- <https://github.com/r23/Virtual-Reality-Museum/blob/a37c16ce8cf00addeab8600c728ad04b925961e7/index.html#L132>
- <https://github.com/r23/Virtual-Reality-Museum/blob/master/models/good_samaritan.mtl>
3 changes: 2 additions & 1 deletion app/src/hooks/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,9 @@ const mockedGalleryBlocks = ([
] satisfies Array<GenericGalleryBlock>).toSorted((a, b) => b.props.size - a.props.size);

// const fetcher = (...args: ArgsType<typeof fetch>) => fetch(...args).then(res => res.json());
const fetcher = (...args: ArgsType<typeof fetch>) => {
const fetcher = async (...args: ArgsType<typeof fetch>) => {
const [path] = args;
await new Promise(resolve => setTimeout(resolve, 200));

if (typeof path !== 'string') {
throw new Error('Invalid path');
Expand Down
2 changes: 1 addition & 1 deletion app/src/pages/Editor/components/GalleryCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { setCursor } from '@/utils';
import { useApi } from '@/hooks/useApi';
import { GenericGalleryBlock, isDoorBlock, isModel3DBlock, isWallBlock, PictureSlotProps } from '@/types';

export const GalleryCanvas = ({ gallery }: { gallery: string }) => {
export const GalleryCanvas2D = ({ gallery }: { gallery: string }) => {
const [viewport, setViewport] = useState({ x: 0, y: 0 });
const stageRef = useRef<Konva.Stage>(null);
const draggingElem = useEditorStore((state) => state.draggingFile);
Expand Down
38 changes: 29 additions & 9 deletions app/src/pages/Editor/components/MainButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import {
import {
IconShare,
IconPlayerPlay,
IconPlayerStop,
} from '@tabler/icons-react';

import { primaryIconProps } from '@/constants';

export const MainButtons = () => (
type Props = { onPreviewButton: () => void, closePreviewButton: () => void, isPreviewing: boolean };

export const MainButtons = ({ onPreviewButton, closePreviewButton, isPreviewing }: Props) => (
<Group gap="xs" wrap="nowrap">
<Button
leftSection={(
Expand All @@ -19,13 +22,30 @@ export const MainButtons = () => (
>
Compartir
</Button>
<Button
variant="primary"
leftSection={(
<IconPlayerPlay {...primaryIconProps} />
)}
>
Visualizar
</Button>
{
isPreviewing ? (
<Button
variant="light"
color="red"
onClick={closePreviewButton}
leftSection={(
<IconPlayerStop {...primaryIconProps} />
)}
>
Cerrar Previsualización
</Button>
) :
(
<Button
variant="primary"
onClick={onPreviewButton}
leftSection={(
<IconPlayerPlay {...primaryIconProps} />
)}
>
Visualizar
</Button>
)
}
</Group>
);
58 changes: 41 additions & 17 deletions app/src/pages/Editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,56 @@
import { useState } from 'react';
import { Suspense, useState } from 'react';
import { UserButton } from '@/components/UserButton';
import { DynamicText } from '@/components/DynamicText';
import { GalleryCanvas } from './components/GalleryCanvas';
import { GalleryCanvas2D } from './components/GalleryCanvas';
import { MenuBurger } from './components/MenuBurger';
import { MainButtons } from './components/MainButtons';
import { EditorSidebar } from './components/ContentSidebar';
import { DRAG_PORTAL_ID } from './components/constants';
import { useLocation } from 'wouter';
import { Modal } from '@mantine/core';
import { Gallery3D } from '../Gallery3D';

export const Editor = ({ gallery }: { gallery: string }) => {
const [projectName, setProjectName] = useState('Nueva galería');
const [location, setLocation] = useLocation();
const [previewOpened, setPreviewOpened] = useState(false);

return (
<section style={{ paddingLeft: '16px', paddingRight: '16px', minWidth: '420px', position: 'relative', overflow: 'hidden' }}>
<div id={DRAG_PORTAL_ID} style={{ position: 'absolute' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', minHeight: '70px', maxHeight: '70px' }}>
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '8px', flexWrap: 'nowrap' }}>
<MenuBurger />
<DynamicText value={projectName} setValue={setProjectName} />
<>
<section style={{ minWidth: '420px', position: 'relative', overflow: 'hidden' }}>
<div id={DRAG_PORTAL_ID} style={{ position: 'absolute' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', minHeight: '70px', maxHeight: '70px' }}>
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '8px', flexWrap: 'nowrap', paddingLeft: '16px' }}>
<MenuBurger />
<DynamicText value={projectName} setValue={setProjectName} />
</div>
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '12px', paddingRight: '16px', }}>
<MainButtons
isPreviewing={previewOpened}
onPreviewButton={() => {
setPreviewOpened(true);
}}
closePreviewButton={() => {
setPreviewOpened(false);
}}
/>
<UserButton />
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '12px' }}>
<MainButtons />
<UserButton />
<div style={{ display: previewOpened ? 'none' : 'flex', flexDirection: 'row', gap: '16px', minHeight: 'calc(100vh - 70px)', maxHeight: 'calc(100vh - 70px)', paddingLeft: '16px', paddingRight: '16px' }}>
<EditorSidebar />
<GalleryCanvas2D gallery={gallery} />
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'row', gap: '16px', minHeight: 'calc(100vh - 70px)', maxHeight: 'calc(100vh - 70px)' }}>
<EditorSidebar />
<GalleryCanvas gallery={gallery} />
</div>
</section>
{
previewOpened && (
<div style={{ display: 'flex', flexDirection: 'row', minHeight: 'calc(100vh - 70px)', maxHeight: 'calc(100vh - 70px)' }}>
<div style={{ height: 'calc(100vh - 70px)', width: '100%' }}>
<Gallery3D gallery={gallery} />
</div>
</div>
)
}
</section>
</>
);
};
41 changes: 27 additions & 14 deletions app/src/pages/Gallery3D/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Text } from '@mantine/core';
import { Sky } from '@react-three/drei';
import { Canvas } from '@react-three/fiber';
import { Physics } from '@react-three/cannon';
Expand All @@ -6,24 +7,36 @@ import { UserContentFileElement } from '@/types';
import { Ground } from './components/gallery/Ground';
import { FPV } from './components/gallery/FPV';
import { Scene } from './components/gallery/Scene';
import { Loader } from '@mantine/core';

export const Gallery3D = ({ gallery }: { gallery: string }) => {
const { data } = useApi<Array<UserContentFileElement>>(`gallery/${gallery}`);
const { data, isLoading } = useApi<Array<UserContentFileElement>>(`gallery/${gallery}`);
console.log('🐢🐢🐢🐢', data);

if (isLoading) {
return <Loader color="rgba(0, 0, 0, 1)" />;
}

return (
<Canvas>
<ambientLight intensity={2.5} />
<spotLight
penumbra={0.5}
position={[10, 10, 5]}
castShadow />
<Physics>
<FPV />
<Ground />
<Scene />
</Physics>
<Sky />
</Canvas>
<>
<div style={{ position: 'absolute', width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none', flexDirection: 'column', gap: '12px' }}>
<Loader color="rgba(0, 0, 0, 1)" />
<Text ta="center" size="xl">Cargando previsualización...</Text>
<div style={{ height: '100px' }} />
</div>
<Canvas>
<ambientLight intensity={2.5} />
<spotLight
penumbra={0.5}
position={[10, 10, 5]}
castShadow />
<Physics>
<FPV />
<Ground />
<Scene />
</Physics>
<Sky />
</Canvas>
</>
);
};

0 comments on commit 8fc8677

Please sign in to comment.