diff --git a/src/App.tsx b/src/App.tsx index 684b53f..ca7f9e2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,7 @@ import { import { customDataProvider } from "./providers/data"; import CssBaseline from "@mui/material/CssBaseline"; import GlobalStyles from "@mui/material/GlobalStyles"; -import { BrowserRouter, Route, Routes, Outlet, HashRouter } from "react-router"; +import { BrowserRouter, Route, Routes, Outlet } from "react-router"; import routerBindings, { NavigateToResource, CatchAllNavigate, @@ -76,11 +76,10 @@ import { import SidebarTitle from "./components/ui/SidebarTitle"; import { AdminOnly } from "./components/AdminOnly"; -import { LoadingProvider } from "@mt/utils"; +//import { LoadingProvider } from "@mt/utils"; import { KBarProvider, RefineKbar } from "@refinedev/kbar"; function App() { return ( - @@ -440,7 +439,6 @@ function App() { - ); } diff --git a/src/pages/route-preview/Constants.ts b/src/pages/route-preview/Constants.ts index 83ba76e..0a0cf7d 100644 --- a/src/pages/route-preview/Constants.ts +++ b/src/pages/route-preview/Constants.ts @@ -3,6 +3,7 @@ export const PATH_WIDTH = 15; export const STATION_RADIUS = 20; export const STATION_OUTLINE_WIDTH = 10; export const SIGHT_SIZE = 60; +export const SCALE_FACTOR = 40; export const BACKGROUND_COLOR = 0x111111; export const PATH_COLOR = 0xff4d4d; \ No newline at end of file diff --git a/src/pages/route-preview/InfiniteCanvas.tsx b/src/pages/route-preview/InfiniteCanvas.tsx index c65209d..6df05c5 100644 --- a/src/pages/route-preview/InfiniteCanvas.tsx +++ b/src/pages/route-preview/InfiniteCanvas.tsx @@ -2,6 +2,7 @@ import { FederatedMouseEvent, FederatedWheelEvent } from "pixi.js"; import { Component, ReactNode, useEffect, useState } from "react"; import { useTransform } from "./TransformContext"; import { useMapData } from "./MapDataContext"; +import { SCALE_FACTOR } from "./Constants"; class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean }> { state = { hasError: false }; @@ -71,6 +72,7 @@ export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) { }); } else { + setRotation(startRotation); setPosition({ x: startPosition.x - startMousePosition.x + e.globalX, y: startPosition.y - startMousePosition.y + e.globalY @@ -93,8 +95,8 @@ export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) { const mouseY = e.globalY - position.y; // Calculate new scale - const scaleMin = (routeData?.scale_min ?? 10)/20; - const scaleMax = (routeData?.scale_max ?? 20)/20; + const scaleMin = (routeData?.scale_min ?? 10)/SCALE_FACTOR; + const scaleMax = (routeData?.scale_max ?? 20)/SCALE_FACTOR; let zoomFactor = e.deltaY > 0 ? 0.9 : 1.1; // Zoom out/in //const newScale = scale * zoomFactor; diff --git a/src/pages/route-preview/RightSidebar.tsx b/src/pages/route-preview/RightSidebar.tsx index e4b7334..38f589a 100644 --- a/src/pages/route-preview/RightSidebar.tsx +++ b/src/pages/route-preview/RightSidebar.tsx @@ -2,10 +2,11 @@ import { Button, Stack, TextField, Typography } from "@mui/material"; import { useMapData } from "./MapDataContext"; import { useEffect, useState } from "react"; import { useTransform } from "./TransformContext"; +import { localToCoordinates } from "./utils"; export function RightSidebar() { const { routeData, setScaleRange, saveChanges, originalRouteData, setMapRotation, setMapCenter } = useMapData(); - const { rotation, setRotation, position, screenToLocal, getCenter, localToScreen, rotateToAngle, panToCoordinates } = useTransform(); + const { rotation, position, screenToLocal, getCenter, rotateToAngle, setTransform } = useTransform(); const [minScale, setMinScale] = useState(1); const [maxScale, setMaxScale] = useState(10); const [localCenter, setLocalCenter] = useState<{x: number, y: number}>({x: 0, y: 0}); @@ -37,7 +38,8 @@ export function RightSidebar() { useEffect(() => { const center = getCenter(); const localCenter = screenToLocal(center.x, center.y); - setLocalCenter(localCenter); + const coordinates = localToCoordinates(localCenter.x, localCenter.y); + setLocalCenter({x: coordinates.latitude, y: coordinates.longitude}); }, [position]); @@ -50,7 +52,7 @@ export function RightSidebar() { } function pan({x, y}: {x: number, y: number}) { - panToCoordinates(x, y, rotation); + setTransform(x, y); } if(!routeData) { diff --git a/src/pages/route-preview/Sight.tsx b/src/pages/route-preview/Sight.tsx index d873cb0..340ae9b 100644 --- a/src/pages/route-preview/Sight.tsx +++ b/src/pages/route-preview/Sight.tsx @@ -4,7 +4,7 @@ import { SightData } from "./types"; import { Assets, FederatedMouseEvent, Graphics, Texture } from "pixi.js"; import { COLORS } from "../../contexts/color-mode/theme"; import { SIGHT_SIZE, UP_SCALE } from "./Constants"; - +import { coordinatesToLocal } from "./utils"; interface SightProps { sight: SightData; @@ -75,6 +75,7 @@ export function Sight({ return null; } + const coordinates = coordinatesToLocal(sight.latitude, sight.longitude); return ( ) { const draw = useCallback((g: Graphics) => { g.clear(); - g.circle(station.latitude * UP_SCALE, station.longitude * UP_SCALE, STATION_RADIUS); + const coordinates = coordinatesToLocal(station.latitude, station.longitude); + g.circle(coordinates.x * UP_SCALE, coordinates.y * UP_SCALE, STATION_RADIUS); g.fill({color: PATH_COLOR}); g.stroke({color: BACKGROUND_COLOR, width: STATION_OUTLINE_WIDTH}); }, []); @@ -38,6 +40,10 @@ export function StationLabel({ const [startPosition, setStartPosition] = useState({ x: 0, y: 0 }); const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 }); + useEffect(() => { + console.log(position); + }, [position]); + if(!station) { console.error("station is null"); return null; @@ -75,6 +81,7 @@ export function StationLabel({ setIsDragging(false); e.stopPropagation(); }; + const coordinates = coordinatesToLocal(station.latitude, station.longitude); return ( { x: number, y: number }, getCenter: () => { x: number, y: number }, rotateToAngle: (to: number, fromPosition?: {x: number, y: number}) => void, - panToCoordinates: (latitude: number, longitude: number, rotation?: number) => void + setTransform: (latitude: number, longitude: number, rotationDegrees?: number, scale?: number) => void }>({ position: { x: 0, y: 0 }, scale: 1, @@ -32,7 +32,7 @@ const TransformContext = createContext<{ localToScreen: () => ({ x: 0, y: 0 }), getCenter: () => ({ x: 0, y: 0 }), rotateToAngle: () => {}, - panToCoordinates: () => {} + setTransform: () => {} }); // Provider component @@ -84,7 +84,6 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => { const canvasRect = canvas?.getBoundingClientRect(); const canvasLeft = canvasRect?.left ?? 0; const canvasTop = canvasRect?.top ?? 0; - const centerX = window.innerWidth / 2 - canvasLeft; const centerY = window.innerHeight / 2 - canvasTop; return {x: centerX, y: centerY}; @@ -92,9 +91,7 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => { function rotateToAngle(to: number, fromPosition?: {x: number, y: number}) { setRotation(to); - console.log(to, fromPosition); - const rotationDiff = to - rotation; - console.log("rotationDiff", rotationDiff); + const rotationDiff = to - rotation; const center = getCenter(); const cosDelta = Math.cos(rotationDiff); @@ -108,25 +105,29 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => { }); } - function panToCoordinates(latitude: number, longitude: number, rotation?: number) { + function setTransform(latitude: number, longitude: number, rotationDegrees?: number, useScale ?: number) { + const selectedRotation = rotationDegrees ? (rotationDegrees * Math.PI / 180) : rotation; + const selectedScale = useScale ? useScale/SCALE_FACTOR : scale; const center = getCenter(); + console.log("center", center.x, center.y); const newPosition = { - x: -latitude * UP_SCALE, - y: -longitude * UP_SCALE + x: -latitude * UP_SCALE * selectedScale, + y: -longitude * UP_SCALE * selectedScale }; - rotation ??= 0; - const cos = Math.cos(rotation); - const sin = Math.sin(rotation); + const cos = Math.cos(selectedRotation); + const sin = Math.sin(selectedRotation); // Translate point relative to center, rotate, then translate back const dx = newPosition.x; const dy = newPosition.y; - newPosition.x = (dx * cos - dy * sin) + center.x; - newPosition.y = (dx * sin + dy * cos) + center.y; + newPosition.x = (dx * cos - dy * sin) + center.x; + newPosition.y = (dx * sin + dy * cos) + center.y; setPosition(newPosition); + setRotation(selectedRotation); + setScale(selectedScale); } const value = useMemo(() => ({ @@ -139,9 +140,9 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => { setScale, setRotation, rotateToAngle, - panToCoordinates, screenToLocal, - localToScreen + localToScreen, + setTransform }), [position, scale, rotation, applicationRef]); return ( diff --git a/src/pages/route-preview/TravelPath.tsx b/src/pages/route-preview/TravelPath.tsx index 2213e11..6f3c003 100644 --- a/src/pages/route-preview/TravelPath.tsx +++ b/src/pages/route-preview/TravelPath.tsx @@ -1,6 +1,7 @@ import { Graphics } from "pixi.js"; import { useCallback } from "react"; import { PATH_COLOR, PATH_WIDTH } from "./Constants"; +import { coordinatesToLocal } from "./utils"; interface TravelPathProps { @@ -13,9 +14,11 @@ export function TravelPath({ const draw = useCallback((g: Graphics) => { g.clear(); - g.moveTo(points[0].x, points[0].y); + const coordStart = coordinatesToLocal(points[0].x, points[0].y); + g.moveTo(coordStart.x, coordStart.y); for (let i = 1; i < points.length - 1; i++) { - g.lineTo(points[i].x, points[i].y); + const coordinates = coordinatesToLocal(points[i].x, points[i].y); + g.lineTo(coordinates.x, coordinates.y); } g.stroke({ color: PATH_COLOR, diff --git a/src/pages/route-preview/index.tsx b/src/pages/route-preview/index.tsx index 29f7c60..df5fd00 100644 --- a/src/pages/route-preview/index.tsx +++ b/src/pages/route-preview/index.tsx @@ -23,6 +23,7 @@ import { TravelPath } from "./TravelPath"; import { LeftSidebar } from "./LeftSidebar"; import { RightSidebar } from "./RightSidebar"; import { Widgets } from "./Widgets"; +import { coordinatesToLocal } from "./utils"; extend({ Container, @@ -53,11 +54,12 @@ export const RoutePreview = () => { export function RouteMap() { - const { applicationRef, setPosition, screenToLocal, panToCoordinates } = useTransform(); + const { applicationRef, setPosition, screenToLocal, setTransform } = useTransform(); const { routeData, stationData, sightData, originalRouteData } = useMapData(); const [points, setPoints] = useState<{x: number, y: number}[]>([]); + const [isSetup, setIsSetup] = useState(false); const parentRef = useRef(null); @@ -70,7 +72,14 @@ export function RouteMap() { }, [originalRouteData]); useEffect(() => { - if (originalRouteData?.center_latitude === originalRouteData?.center_longitude && originalRouteData?.center_latitude === 0) { + if(!applicationRef?.current || isSetup) { + return; + } + + if ( + originalRouteData?.center_latitude === originalRouteData?.center_longitude && + originalRouteData?.center_latitude === 0 + ) { if (points.length > 0) { let boundingBox = { from: {x: Infinity, y: Infinity}, @@ -87,18 +96,22 @@ export function RouteMap() { y: -(boundingBox.from.y + boundingBox.to.y) / 2 }; setPosition(newCenter); + setIsSetup(true); } } else if ( originalRouteData?.center_latitude && originalRouteData?.center_longitude ) { - panToCoordinates( - originalRouteData?.center_latitude, - originalRouteData?.center_longitude, - originalRouteData?.rotate * Math.PI / 180 + const coordinates = coordinatesToLocal(originalRouteData?.center_latitude, originalRouteData?.center_longitude); + setTransform( + coordinates.x, + coordinates.y, + originalRouteData?.rotate, + originalRouteData?.scale_min ); + setIsSetup(true); } - }, [points, originalRouteData?.center_latitude, originalRouteData?.center_longitude, originalRouteData?.rotate]); + }, [points, originalRouteData?.center_latitude, originalRouteData?.center_longitude, originalRouteData?.rotate, applicationRef?.current, isSetup]); if (!routeData || !stationData || !sightData) { console.error("routeData, stationData or sightData is null"); diff --git a/src/pages/route-preview/utils.ts b/src/pages/route-preview/utils.ts new file mode 100644 index 0000000..b7f8caa --- /dev/null +++ b/src/pages/route-preview/utils.ts @@ -0,0 +1,16 @@ +export function coordinatesToLocal(longitude: number, latitude: number) { + + return { + x: latitude, + y: -longitude*2 + } + //return {x: longitude, y: latitude} +} + +export function localToCoordinates(x: number, y: number) { + return { + latitude: x, + longitude: -y/2 + } + // return {latitude: x, longitude: y} +} \ No newline at end of file diff --git a/src/preview/assets/.gitkeep b/src/preview/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/preview/assets/icons/company-logo.svg b/src/preview/assets/icons/company-logo.svg deleted file mode 100644 index 488da6c..0000000 --- a/src/preview/assets/icons/company-logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/preview/assets/images/loader.gif b/src/preview/assets/images/loader.gif deleted file mode 100644 index 0d951ad..0000000 Binary files a/src/preview/assets/images/loader.gif and /dev/null differ diff --git a/src/preview/components/AttractionShortPreview/AttractionShortPreview.css b/src/preview/components/AttractionShortPreview/AttractionShortPreview.css deleted file mode 100644 index 7b68896..0000000 --- a/src/preview/components/AttractionShortPreview/AttractionShortPreview.css +++ /dev/null @@ -1,39 +0,0 @@ -.attraction-card { - height: 415px; - width: 315px; - background: linear-gradient( - 113.51deg, - rgba(255, 255, 255, 0) 8.71%, - rgba(255, 255, 255, 0.16) 69.69% - ), - #806c59; - border-radius: 10px; - - overflow: hidden; - color: #ffffff; -} - -.attraction-card__content { - padding: 12px; -} - -.attraction-card__title { - margin: 8px 0 0 0; -} - -.attraction-card__text { - margin: 30px 0 0 0; - white-space: pre-wrap; -} - -.attraction-card__subtitle { - margin: 8px 0 0 0; - font-weight: 400; -} - -.attraction-card__image { - min-width: 100%; - max-height: 50%; - padding: 2px; - border-radius: 10px 10px 0 0; -} diff --git a/src/preview/components/AttractionShortPreview/AttractionShortPreview.tsx b/src/preview/components/AttractionShortPreview/AttractionShortPreview.tsx deleted file mode 100644 index a22537a..0000000 --- a/src/preview/components/AttractionShortPreview/AttractionShortPreview.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import "./AttractionShortPreview.css"; - -import { LocalizedString, useServerLocalization } from "@mt/i18n"; -import classNames from "classnames"; -import { TouchScrollWrapper } from "../TouchScrollWrapper/TouchScrollWrapper"; -import { HTMLAttributes } from "react"; - -export interface AttractionShortPreviewProps - extends Omit, "title" | "content"> { - img: string; - title: LocalizedString; - subtitle: LocalizedString; - content: LocalizedString; -} - -export function AttractionShortPreview({ - img, - title, - subtitle, - content, - className, - ...props -}: AttractionShortPreviewProps) { - const localizeText = useServerLocalization(); - - return ( -
- {img && ( - {localizeText(title)} - )} - - -
-

{localizeText(title)}

- -
- {localizeText(subtitle)} -
- -

-

-
-
- ); -} diff --git a/src/preview/components/AttractionWidget/AttractionWidget.css b/src/preview/components/AttractionWidget/AttractionWidget.css deleted file mode 100644 index 3ae3c4e..0000000 --- a/src/preview/components/AttractionWidget/AttractionWidget.css +++ /dev/null @@ -1,126 +0,0 @@ -.widget-container { - width: 545px; - height: var(--attraction-widget-container-height, 100%); - max-height: calc(100% - 90px); - color: #ffffff; - background: #806c59; - border: 2px solid #806c59; - border-radius: 10px; -} - -.widget-content { - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 100%; - overflow: hidden; -} - -.widget-slide { - position: relative; - display: none; - top: 0; - left: 0; - flex-direction: column; - justify-content: flex-start; - align-items: center; - width: 100%; -} - -.widget-slide.active, -.widget-slide.preview { - display: flex; - flex: 1; - overflow: auto; -} - -.widget-media { - width: 100%; - height: auto; - max-height: 644px; -} - -.view-container { - border-radius: 8px 8px 0 0; -} - -.widget-header { - background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%), - rgba(179, 165, 152, 0.4); - box-shadow: inset 4px 4px 12px rgba(255, 255, 255, 0.12); - width: 100%; - padding: 9px 16px; - font-weight: 700; - font-size: 24px; - line-height: 120%; -} - -.widget-text { - width: 100%; - align-self: self-start; - padding: 16px; - font-weight: 400; - font-size: 18px; - line-height: 150%; /* or 27px */ - opacity: 0; - transition: opacity 0.5s ease-in-out; - user-select: none; - word-break: break-word; - white-space: pre-wrap; -} - -.widget-text p { - margin: 0; -} - -.widget-text.preview { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-weight: 700; - font-size: 48px; - line-height: 120%; - text-align: center; -} - -.widget-text.active { - opacity: 1; -} - -.widget-titles { - display: flex; - height: 50px; - justify-content: space-evenly; - align-items: center; - width: 100%; - margin: 5px 0 0 0; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%), - rgba(179, 165, 152, 0.4); - box-shadow: inset 4px 4px 12px rgba(255, 255, 255, 0.12); - border-radius: 0 0 10px 10px; - padding: 12px 0; -} - -.widget-title { - font-weight: 400; - font-size: 18px; - line-height: 21px; - cursor: pointer; - user-select: none; - width: 100px; - text-align: center; -} - -.widget-title.active { - font-weight: bold; - text-decoration: underline; - text-underline-offset: 5px; -} - -.widget-title.preview { - display: none; -} diff --git a/src/preview/components/AttractionWidget/AttractionWidget.tsx b/src/preview/components/AttractionWidget/AttractionWidget.tsx deleted file mode 100644 index b682909..0000000 --- a/src/preview/components/AttractionWidget/AttractionWidget.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React, { HTMLAttributes, useEffect, useState } from "react"; -import { useServerLocalization } from "@mt/i18n"; -import cn from "classnames"; -import { useSwipeable } from "react-swipeable"; -import { ArticleBase } from "@mt/common-types"; -import "./AttractionWidget.css"; -import { usePrevious } from "@mt/utils"; -import { AttractionMedia } from "./media/AttractionMedia"; -import { TouchScrollWrapper } from "../TouchScrollWrapper/TouchScrollWrapper"; - -export interface AttractionsWidgetProps extends HTMLAttributes { - articles: ArticleBase[]; - isIdleMode: boolean; - isPreviewOnly?: boolean; -} - -export function AttractionWidget({ - articles, - isIdleMode, - isPreviewOnly = false, - ...props -}: AttractionsWidgetProps) { - const [activeIndex, setActiveIndex] = useState(0); - const prevArticles = usePrevious(articles) || []; - const localizeText = useServerLocalization(); - - const swipeHandlers = useSwipeable({ - onSwipedLeft: ({ event }) => { - event.preventDefault(); - setActiveIndex((activeIndex) => (activeIndex + 1) % articles.length); - }, - onSwipedRight: ({ event }) => { - event.preventDefault(); - setActiveIndex( - (activeIndex) => (activeIndex - 1 + articles.length) % articles.length - ); - }, - swipeDuration: 500, - preventScrollOnSwipe: true, - trackMouse: true, - }); - - const handleClick = (index: number) => { - setActiveIndex(index); - document.querySelector(".widget-text.active")!.scrollTop = 0; - }; - - useEffect(() => setActiveIndex(activeIndex), [activeIndex]); - - useEffect(() => { - if ( - !isPreviewOnly && - (isIdleMode || JSON.stringify(prevArticles) !== JSON.stringify(articles)) - ) { - setActiveIndex(0); - } - - // admin specific case: during edit we removed active article - if (prevArticles?.length > articles?.length) { - setActiveIndex(0); - } - }, [isPreviewOnly, isIdleMode, articles]); - - return ( -
-
- {articles?.map((article, index) => ( -
handleClick(index)} - > -
- -
- - {index !== 0 && ( -
- {localizeText(articles[0].text)} -
- )} - - -
- -
- ))} - -
- {articles?.map((article, index) => ( -
handleClick(index)} - > - {localizeText(article.name)} -
- ))} -
-
-
- ); -} diff --git a/src/preview/components/AttractionWidget/media/AttractionMedia.css b/src/preview/components/AttractionWidget/media/AttractionMedia.css deleted file mode 100644 index 34774e4..0000000 --- a/src/preview/components/AttractionWidget/media/AttractionMedia.css +++ /dev/null @@ -1,52 +0,0 @@ -.widget-image, -.widget-video, -.widget-3d-model { - max-width: 100%; - max-height: 100%; - width: 100%; - height: 100%; - display: block; - border-radius: 8px 8px 0 0; -} - -.widget-3d-model { - height: 350px; -} - -.widget-media__wrapper { - position: relative; - /*TODO: it worth to investigate it further... quite weird behavior of */ - box-sizing: content-box !important; -} - -.fullscreen-photo-sphere-btn, -.fullscreen-3d-btn { - width: 20px; - height: 20px; - position: absolute; - right: 10px; - bottom: 10px; - cursor: pointer; - z-index: 100; - opacity: 0.7; -} - -.media-with-watermark { - position: relative; -} - -.watermark { - position: absolute; - top: 10px; - left: 10px; - width: 50px; - height: auto; -} - -.psv-autorotate-button { - display: block !important; -} - -.psv-menu-button { - display: none !important; -} diff --git a/src/preview/components/AttractionWidget/media/AttractionMedia.tsx b/src/preview/components/AttractionWidget/media/AttractionMedia.tsx deleted file mode 100644 index a0f9b32..0000000 --- a/src/preview/components/AttractionWidget/media/AttractionMedia.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Media } from "@mt/common-types"; -import { ImageMedia } from "./ImageMedia"; -import { VideoMedia } from "./VideoMedia"; -import { PhotoSphereMedia } from "./PhotoSphereMedia"; -import { Object3DMedia } from "./Object3DMedia"; -import { memo } from "react"; - -export const AttractionMedia = memo( - ({ media }: { media: Media }) => { - const { type, url, watermarkUrl } = media; - - if (!url) return null; - - switch (type) { - case "IMAGE": - return ( - - ); - case "VIDEO": - return ; - case "PHOTO_SPHERE": - return ; - case "OBJECT_3D": - return ; - default: - return null; - } - }, - ({ media }, { media: newMedia }) => { - return ( - media.url === newMedia.url && - media.watermarkUrl === newMedia.watermarkUrl && - media.type === newMedia.type - ); - } -); diff --git a/src/preview/components/AttractionWidget/media/ImageMedia.tsx b/src/preview/components/AttractionWidget/media/ImageMedia.tsx deleted file mode 100644 index 94f4934..0000000 --- a/src/preview/components/AttractionWidget/media/ImageMedia.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import cn from 'classnames'; -import React from 'react'; - -import './AttractionMedia.css'; - -interface ImageMediaProps { - url: string; - alt: string; - watermarkUrl?: string; -} - -export const ImageMedia = ({ url, alt, watermarkUrl }: ImageMediaProps) => ( - <> - {alt} - {watermarkUrl && ( - Watermark - )} - -); diff --git a/src/preview/components/AttractionWidget/media/Object3DMedia.tsx b/src/preview/components/AttractionWidget/media/Object3DMedia.tsx deleted file mode 100644 index 853600a..0000000 --- a/src/preview/components/AttractionWidget/media/Object3DMedia.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import cn from "classnames"; -import React, { useEffect, useState } from "react"; - -import "./AttractionMedia.css"; -import ModelViewer from "../../model-viewer/ModelViewer"; -import { Icons, useLightboxContext } from "@mt/components"; -import { Object3DLightboxData } from "@mt/common-types"; - -interface Object3DMediaProps { - url: string; - watermarkUrl?: string; -} - -export const Object3DMedia = ({ url, watermarkUrl }: Object3DMediaProps) => { - // prettier-ignore - const { setData, openLightbox } = useLightboxContext(); - const [autoRotate, setAutoRotate] = useState(true); - - const handle3DFullscreenOpen = () => { - setAutoRotate(false); - setData({ - type: "OBJECT_3D", - modelUrl: url, - watermarkUrl, - }); - openLightbox(); - }; - - useEffect(() => { - setAutoRotate(true); - }, [url]); - - return ( -
-
- - {watermarkUrl && ( - Watermark - )} -
- - handle3DFullscreenOpen()} - /> -
- ); -}; diff --git a/src/preview/components/AttractionWidget/media/PhotoSphereMedia.tsx b/src/preview/components/AttractionWidget/media/PhotoSphereMedia.tsx deleted file mode 100644 index 15c9ed6..0000000 --- a/src/preview/components/AttractionWidget/media/PhotoSphereMedia.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import cn from "classnames"; -import React, { useRef } from "react"; -import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer"; - -import { PhotoSphereLightboxData } from "@mt/common-types"; - -import "./AttractionMedia.css"; -import { useLightboxContext } from "../../lightbox"; -import { Icons } from "@mt/components"; - -interface PhotoSphereMediaProps { - url: string; - watermarkUrl?: string; -} - -export const PhotoSphereMedia = ({ - url, - watermarkUrl, -}: PhotoSphereMediaProps) => { - // prettier-ignore - const { setData, openLightbox } = useLightboxContext(); - // react-photo-sphere-viewer doesn't have exported types, so here's a bit of a hardcoded piece - const photoSphereRef = useRef(null); - - const handlePhotoSphereFullscreenOpen = () => { - photoSphereRef.current?.stopAutoRotate(); - setData({ - type: "PHOTO_SPHERE", - imageUrl: url, - watermarkUrl, - }); - openLightbox(); - }; - - return ( -
- - {watermarkUrl && ( - Watermark - )} - {/* the following is a workaround to open lightbox-like preview in the middle of the screen instead of the real fullscreen */} - handlePhotoSphereFullscreenOpen()} - /> -
- ); -}; diff --git a/src/preview/components/AttractionWidget/media/VideoMedia.tsx b/src/preview/components/AttractionWidget/media/VideoMedia.tsx deleted file mode 100644 index c8af0f6..0000000 --- a/src/preview/components/AttractionWidget/media/VideoMedia.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import cn from "classnames"; -import React from "react"; - -import "./AttractionMedia.css"; - -interface VideoMediaProps { - url: string; - watermarkUrl?: string; -} - -export const VideoMedia = ({ url, watermarkUrl }: VideoMediaProps) => ( - <> -