Add mapbox to sidebar
This commit is contained in:
parent
57d408cb52
commit
c357532613
|
@ -6,7 +6,7 @@ import {
|
||||||
ProtectedVideo,
|
ProtectedVideo,
|
||||||
} from '../../components/photoGallery/ProtectedMedia'
|
} from '../../components/photoGallery/ProtectedMedia'
|
||||||
import { SidebarContext } from '../../components/sidebar/Sidebar'
|
import { SidebarContext } from '../../components/sidebar/Sidebar'
|
||||||
import MediaSidebar from '../../components/sidebar/MediaSidebar'
|
import MediaSidebar from '../../components/sidebar/MediaSidebar/MediaSidebar'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { SharePageToken_shareToken_media } from './__generated__/SharePageToken'
|
import { SharePageToken_shareToken_media } from './__generated__/SharePageToken'
|
||||||
import { MediaType } from '../../__generated__/globalTypes'
|
import { MediaType } from '../../__generated__/globalTypes'
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { MediaType } from '../../__generated__/globalTypes'
|
import { MediaType } from '../../__generated__/globalTypes'
|
||||||
import { MediaSidebarMedia } from '../sidebar/MediaSidebar'
|
import { MediaSidebarMedia } from '../sidebar/MediaSidebar/MediaSidebar'
|
||||||
import { sidebarPhoto_media_faces } from '../sidebar/__generated__/sidebarPhoto'
|
import { sidebarPhoto_media_faces } from '../sidebar/__generated__/sidebarPhoto'
|
||||||
|
|
||||||
interface FaceBoxStyleProps {
|
interface FaceBoxStyleProps {
|
||||||
|
|
|
@ -20,10 +20,13 @@ const MapContainer = styled.div`
|
||||||
|
|
||||||
type MapboxMapProps = {
|
type MapboxMapProps = {
|
||||||
configureMapbox(map: mapboxgl.Map, mapboxLibrary: typeof mapboxgl): void
|
configureMapbox(map: mapboxgl.Map, mapboxLibrary: typeof mapboxgl): void
|
||||||
readonly initialZoom?: number
|
mapboxOptions?: Partial<mapboxgl.MapboxOptions>
|
||||||
}
|
}
|
||||||
|
|
||||||
const useMapboxMap = ({ configureMapbox, initialZoom = 1 }: MapboxMapProps) => {
|
const useMapboxMap = ({
|
||||||
|
configureMapbox,
|
||||||
|
mapboxOptions = undefined,
|
||||||
|
}: MapboxMapProps) => {
|
||||||
const [mapboxLibrary, setMapboxLibrary] = useState<typeof mapboxgl>()
|
const [mapboxLibrary, setMapboxLibrary] = useState<typeof mapboxgl>()
|
||||||
const mapContainer = useRef<HTMLDivElement | null>(null)
|
const mapContainer = useRef<HTMLDivElement | null>(null)
|
||||||
const map = useRef<mapboxgl.Map | null>(null)
|
const map = useRef<mapboxgl.Map | null>(null)
|
||||||
|
@ -57,12 +60,15 @@ const useMapboxMap = ({ configureMapbox, initialZoom = 1 }: MapboxMapProps) => {
|
||||||
map.current = new mapboxLibrary.Map({
|
map.current = new mapboxLibrary.Map({
|
||||||
container: mapContainer.current,
|
container: mapContainer.current,
|
||||||
style: 'mapbox://styles/mapbox/streets-v11',
|
style: 'mapbox://styles/mapbox/streets-v11',
|
||||||
zoom: initialZoom,
|
...mapboxOptions,
|
||||||
})
|
})
|
||||||
|
|
||||||
configureMapbox(map.current, mapboxLibrary)
|
configureMapbox(map.current, mapboxLibrary)
|
||||||
|
map.current?.resize()
|
||||||
}, [mapContainer, mapboxLibrary, mapboxData])
|
}, [mapContainer, mapboxLibrary, mapboxData])
|
||||||
|
|
||||||
|
map.current?.resize()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mapContainer: <MapContainer ref={mapContainer}></MapContainer>,
|
mapContainer: <MapContainer ref={mapContainer}></MapContainer>,
|
||||||
mapboxMap: map.current,
|
mapboxMap: map.current,
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
toggleFavoriteAction,
|
toggleFavoriteAction,
|
||||||
useMarkFavoriteMutation,
|
useMarkFavoriteMutation,
|
||||||
} from './photoGalleryMutations'
|
} from './photoGalleryMutations'
|
||||||
import MediaSidebar from '../sidebar/MediaSidebar'
|
import MediaSidebar from '../sidebar/MediaSidebar/MediaSidebar'
|
||||||
import { SidebarContext } from '../sidebar/Sidebar'
|
import { SidebarContext } from '../sidebar/Sidebar'
|
||||||
|
|
||||||
const Gallery = styled.div`
|
const Gallery = styled.div`
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
import { gql, useLazyQuery } from '@apollo/client'
|
||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
import { authToken } from '../../../helpers/authentication'
|
||||||
|
import { MediaType } from '../../../__generated__/globalTypes'
|
||||||
|
import { SidebarFacesOverlay } from '../../facesOverlay/FacesOverlay'
|
||||||
|
import {
|
||||||
|
ProtectedImage,
|
||||||
|
ProtectedVideo,
|
||||||
|
ProtectedVideoProps_Media,
|
||||||
|
} from '../../photoGallery/ProtectedMedia'
|
||||||
|
import { SidebarPhotoCover } from '../AlbumCovers'
|
||||||
|
import { SidebarPhotoShare } from '../Sharing'
|
||||||
|
import SidebarMediaDownload from '../SidebarDownloadMedia'
|
||||||
|
import SidebarHeader from '../SidebarHeader'
|
||||||
|
import { sidebarDownloadQuery_media_downloads } from '../__generated__/sidebarDownloadQuery'
|
||||||
|
import {
|
||||||
|
sidebarPhoto,
|
||||||
|
sidebarPhotoVariables,
|
||||||
|
sidebarPhoto_media_exif,
|
||||||
|
sidebarPhoto_media_faces,
|
||||||
|
sidebarPhoto_media_thumbnail,
|
||||||
|
sidebarPhoto_media_videoMetadata,
|
||||||
|
} from '../__generated__/sidebarPhoto'
|
||||||
|
import ExifDetails from './MediaSidebarExif'
|
||||||
|
import MediaSidebarMap from './MediaSidebarMap'
|
||||||
|
|
||||||
|
const SIDEBAR_MEDIA_QUERY = gql`
|
||||||
|
query sidebarPhoto($id: ID!) {
|
||||||
|
media(id: $id) {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
type
|
||||||
|
highRes {
|
||||||
|
url
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
thumbnail {
|
||||||
|
url
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
videoWeb {
|
||||||
|
url
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
videoMetadata {
|
||||||
|
id
|
||||||
|
width
|
||||||
|
height
|
||||||
|
duration
|
||||||
|
codec
|
||||||
|
framerate
|
||||||
|
bitrate
|
||||||
|
colorProfile
|
||||||
|
audio
|
||||||
|
}
|
||||||
|
exif {
|
||||||
|
id
|
||||||
|
camera
|
||||||
|
maker
|
||||||
|
lens
|
||||||
|
dateShot
|
||||||
|
exposure
|
||||||
|
aperture
|
||||||
|
iso
|
||||||
|
focalLength
|
||||||
|
flash
|
||||||
|
exposureProgram
|
||||||
|
coordinates {
|
||||||
|
latitude
|
||||||
|
longitude
|
||||||
|
}
|
||||||
|
}
|
||||||
|
faces {
|
||||||
|
id
|
||||||
|
rectangle {
|
||||||
|
minX
|
||||||
|
maxX
|
||||||
|
minY
|
||||||
|
maxY
|
||||||
|
}
|
||||||
|
faceGroup {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const PreviewImage = styled(ProtectedImage)`
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
object-fit: contain;
|
||||||
|
`
|
||||||
|
|
||||||
|
const PreviewVideo = styled(ProtectedVideo)`
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
`
|
||||||
|
|
||||||
|
interface PreviewMediaPropsMedia extends ProtectedVideoProps_Media {
|
||||||
|
type: MediaType
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreviewMediaProps = {
|
||||||
|
media: PreviewMediaPropsMedia
|
||||||
|
previewImage?: {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PreviewMedia = ({ media, previewImage }: PreviewMediaProps) => {
|
||||||
|
if (media.type === MediaType.Photo) {
|
||||||
|
return <PreviewImage src={previewImage?.url} />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (media.type === MediaType.Video) {
|
||||||
|
return <PreviewVideo media={media} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div>ERROR: Unknown media type: {media.type}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
type SidebarContentProps = {
|
||||||
|
media: MediaSidebarMedia
|
||||||
|
hidePreview?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const SidebarContent = ({ media, hidePreview }: SidebarContentProps) => {
|
||||||
|
let previewImage = null
|
||||||
|
if (media.highRes) previewImage = media.highRes
|
||||||
|
else if (media.thumbnail) previewImage = media.thumbnail
|
||||||
|
|
||||||
|
const imageAspect =
|
||||||
|
previewImage?.width && previewImage?.height
|
||||||
|
? previewImage.height / previewImage.width
|
||||||
|
: 3 / 2
|
||||||
|
|
||||||
|
let sidebarMap = null
|
||||||
|
const mediaCoordinates = media.exif?.coordinates
|
||||||
|
if (mediaCoordinates) {
|
||||||
|
sidebarMap = <MediaSidebarMap coordinates={mediaCoordinates} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SidebarHeader title={media.title ?? 'Loading...'} />
|
||||||
|
<div className="lg:mx-4">
|
||||||
|
{!hidePreview && (
|
||||||
|
<div
|
||||||
|
className="w-full h-0 relative"
|
||||||
|
style={{ paddingTop: `${Math.min(imageAspect, 0.75) * 100}%` }}
|
||||||
|
>
|
||||||
|
<PreviewMedia
|
||||||
|
previewImage={previewImage || undefined}
|
||||||
|
media={media}
|
||||||
|
/>
|
||||||
|
<SidebarFacesOverlay media={media} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<ExifDetails media={media} />
|
||||||
|
{sidebarMap}
|
||||||
|
<SidebarMediaDownload media={media} />
|
||||||
|
<SidebarPhotoShare id={media.id} />
|
||||||
|
<div className="mt-8">
|
||||||
|
<SidebarPhotoCover cover_id={media.id} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MediaSidebarMedia {
|
||||||
|
__typename: 'Media'
|
||||||
|
id: string
|
||||||
|
title?: string
|
||||||
|
type: MediaType
|
||||||
|
highRes?: null | {
|
||||||
|
__typename: 'MediaURL'
|
||||||
|
url: string
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
}
|
||||||
|
thumbnail?: sidebarPhoto_media_thumbnail | null
|
||||||
|
videoWeb?: null | {
|
||||||
|
__typename: 'MediaURL'
|
||||||
|
url: string
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
}
|
||||||
|
videoMetadata?: sidebarPhoto_media_videoMetadata | null
|
||||||
|
exif?: sidebarPhoto_media_exif | null
|
||||||
|
faces?: sidebarPhoto_media_faces[]
|
||||||
|
downloads?: sidebarDownloadQuery_media_downloads[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaSidebarType = {
|
||||||
|
media: MediaSidebarMedia
|
||||||
|
hidePreview?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const MediaSidebar = ({ media, hidePreview }: MediaSidebarType) => {
|
||||||
|
const [loadMedia, { loading, error, data }] = useLazyQuery<
|
||||||
|
sidebarPhoto,
|
||||||
|
sidebarPhotoVariables
|
||||||
|
>(SIDEBAR_MEDIA_QUERY)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (media != null && authToken()) {
|
||||||
|
loadMedia({
|
||||||
|
variables: {
|
||||||
|
id: media.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [media])
|
||||||
|
|
||||||
|
if (!media) return null
|
||||||
|
|
||||||
|
if (!authToken()) {
|
||||||
|
return <SidebarContent media={media} hidePreview={hidePreview} />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) return <div>{error.message}</div>
|
||||||
|
|
||||||
|
if (loading || data == null) {
|
||||||
|
return <SidebarContent media={media} hidePreview={hidePreview} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return <SidebarContent media={data.media} hidePreview={hidePreview} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MediaSidebar
|
|
@ -1,147 +1,20 @@
|
||||||
import React, { useEffect } from 'react'
|
import React from 'react'
|
||||||
import { useLazyQuery, gql } from '@apollo/client'
|
|
||||||
import styled from 'styled-components'
|
|
||||||
import { authToken } from '../../helpers/authentication'
|
|
||||||
import {
|
|
||||||
ProtectedImage,
|
|
||||||
ProtectedVideo,
|
|
||||||
ProtectedVideoProps_Media,
|
|
||||||
} from '../photoGallery/ProtectedMedia'
|
|
||||||
import { SidebarPhotoShare } from './Sharing'
|
|
||||||
import SidebarMediaDownload from './SidebarDownloadMedia'
|
|
||||||
import SidebarItem from './SidebarItem'
|
|
||||||
import { SidebarFacesOverlay } from '../facesOverlay/FacesOverlay'
|
|
||||||
import { isNil } from '../../helpers/utils'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { MediaType } from '../../__generated__/globalTypes'
|
import styled from 'styled-components'
|
||||||
import { TranslationFn } from '../../localization'
|
import { isNil } from '../../../helpers/utils'
|
||||||
import {
|
import { TranslationFn } from '../../../localization'
|
||||||
sidebarPhoto,
|
import SidebarItem from '../SidebarItem'
|
||||||
sidebarPhotoVariables,
|
import { MediaSidebarMedia } from './MediaSidebar'
|
||||||
sidebarPhoto_media_exif,
|
|
||||||
sidebarPhoto_media_faces,
|
|
||||||
sidebarPhoto_media_thumbnail,
|
|
||||||
sidebarPhoto_media_videoMetadata,
|
|
||||||
} from './__generated__/sidebarPhoto'
|
|
||||||
|
|
||||||
import { sidebarDownloadQuery_media_downloads } from './__generated__/sidebarDownloadQuery'
|
|
||||||
import SidebarHeader from './SidebarHeader'
|
|
||||||
import { SidebarPhotoCover } from './AlbumCovers'
|
|
||||||
|
|
||||||
const SIDEBAR_MEDIA_QUERY = gql`
|
|
||||||
query sidebarPhoto($id: ID!) {
|
|
||||||
media(id: $id) {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
type
|
|
||||||
highRes {
|
|
||||||
url
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
thumbnail {
|
|
||||||
url
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
videoWeb {
|
|
||||||
url
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
videoMetadata {
|
|
||||||
id
|
|
||||||
width
|
|
||||||
height
|
|
||||||
duration
|
|
||||||
codec
|
|
||||||
framerate
|
|
||||||
bitrate
|
|
||||||
colorProfile
|
|
||||||
audio
|
|
||||||
}
|
|
||||||
exif {
|
|
||||||
id
|
|
||||||
camera
|
|
||||||
maker
|
|
||||||
lens
|
|
||||||
dateShot
|
|
||||||
exposure
|
|
||||||
aperture
|
|
||||||
iso
|
|
||||||
focalLength
|
|
||||||
flash
|
|
||||||
exposureProgram
|
|
||||||
coordinates {
|
|
||||||
latitude
|
|
||||||
longitude
|
|
||||||
}
|
|
||||||
}
|
|
||||||
faces {
|
|
||||||
id
|
|
||||||
rectangle {
|
|
||||||
minX
|
|
||||||
maxX
|
|
||||||
minY
|
|
||||||
maxY
|
|
||||||
}
|
|
||||||
faceGroup {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const PreviewImage = styled(ProtectedImage)`
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
object-fit: contain;
|
|
||||||
`
|
|
||||||
|
|
||||||
const PreviewVideo = styled(ProtectedVideo)`
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
`
|
|
||||||
|
|
||||||
interface PreviewMediaPropsMedia extends ProtectedVideoProps_Media {
|
|
||||||
type: MediaType
|
|
||||||
}
|
|
||||||
|
|
||||||
type PreviewMediaProps = {
|
|
||||||
media: PreviewMediaPropsMedia
|
|
||||||
previewImage?: {
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const PreviewMedia = ({ media, previewImage }: PreviewMediaProps) => {
|
|
||||||
if (media.type === MediaType.Photo) {
|
|
||||||
return <PreviewImage src={previewImage?.url} />
|
|
||||||
}
|
|
||||||
|
|
||||||
if (media.type === MediaType.Video) {
|
|
||||||
return <PreviewVideo media={media} />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div>ERROR: Unknown media type: {media.type}</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
const MetadataInfoContainer = styled.div`
|
const MetadataInfoContainer = styled.div`
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
`
|
`
|
||||||
|
|
||||||
type MediaInfoProps = {
|
type ExifDetailsProps = {
|
||||||
media?: MediaSidebarMedia
|
media?: MediaSidebarMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MetadataInfo = ({ media }: MediaInfoProps) => {
|
const ExifDetails = ({ media }: ExifDetailsProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
let exifItems: JSX.Element[] = []
|
let exifItems: JSX.Element[] = []
|
||||||
|
|
||||||
|
@ -343,106 +216,4 @@ const flashLookup = (t: TranslationFn): { [key: number]: string } => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SidebarContentProps = {
|
export default ExifDetails
|
||||||
media: MediaSidebarMedia
|
|
||||||
hidePreview?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const SidebarContent = ({ media, hidePreview }: SidebarContentProps) => {
|
|
||||||
let previewImage = null
|
|
||||||
if (media.highRes) previewImage = media.highRes
|
|
||||||
else if (media.thumbnail) previewImage = media.thumbnail
|
|
||||||
|
|
||||||
const imageAspect =
|
|
||||||
previewImage?.width && previewImage?.height
|
|
||||||
? previewImage.height / previewImage.width
|
|
||||||
: 3 / 2
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<SidebarHeader title={media.title ?? 'Loading...'} />
|
|
||||||
<div className="lg:mx-4">
|
|
||||||
{!hidePreview && (
|
|
||||||
<div
|
|
||||||
className="w-full h-0 relative"
|
|
||||||
style={{ paddingTop: `${Math.min(imageAspect, 0.75) * 100}%` }}
|
|
||||||
>
|
|
||||||
<PreviewMedia
|
|
||||||
previewImage={previewImage || undefined}
|
|
||||||
media={media}
|
|
||||||
/>
|
|
||||||
<SidebarFacesOverlay media={media} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<MetadataInfo media={media} />
|
|
||||||
<SidebarMediaDownload media={media} />
|
|
||||||
<SidebarPhotoShare id={media.id} />
|
|
||||||
<div className="mt-8">
|
|
||||||
<SidebarPhotoCover cover_id={media.id} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MediaSidebarMedia {
|
|
||||||
__typename: 'Media'
|
|
||||||
id: string
|
|
||||||
title?: string
|
|
||||||
type: MediaType
|
|
||||||
highRes?: null | {
|
|
||||||
__typename: 'MediaURL'
|
|
||||||
url: string
|
|
||||||
width?: number
|
|
||||||
height?: number
|
|
||||||
}
|
|
||||||
thumbnail?: sidebarPhoto_media_thumbnail | null
|
|
||||||
videoWeb?: null | {
|
|
||||||
__typename: 'MediaURL'
|
|
||||||
url: string
|
|
||||||
width?: number
|
|
||||||
height?: number
|
|
||||||
}
|
|
||||||
videoMetadata?: sidebarPhoto_media_videoMetadata | null
|
|
||||||
exif?: sidebarPhoto_media_exif | null
|
|
||||||
faces?: sidebarPhoto_media_faces[]
|
|
||||||
downloads?: sidebarDownloadQuery_media_downloads[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaSidebarType = {
|
|
||||||
media: MediaSidebarMedia
|
|
||||||
hidePreview?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const MediaSidebar = ({ media, hidePreview }: MediaSidebarType) => {
|
|
||||||
const [loadMedia, { loading, error, data }] = useLazyQuery<
|
|
||||||
sidebarPhoto,
|
|
||||||
sidebarPhotoVariables
|
|
||||||
>(SIDEBAR_MEDIA_QUERY)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (media != null && authToken()) {
|
|
||||||
loadMedia({
|
|
||||||
variables: {
|
|
||||||
id: media.id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [media])
|
|
||||||
|
|
||||||
if (!media) return null
|
|
||||||
|
|
||||||
if (!authToken()) {
|
|
||||||
return <SidebarContent media={media} hidePreview={hidePreview} />
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) return <div>{error.message}</div>
|
|
||||||
|
|
||||||
if (loading || data == null) {
|
|
||||||
return <SidebarContent media={media} hidePreview={hidePreview} />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <SidebarContent media={data.media} hidePreview={hidePreview} />
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MediaSidebar
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { isNil } from '../../../helpers/utils'
|
||||||
|
import useMapboxMap from '../../mapbox/MapboxMap'
|
||||||
|
import { SidebarSection, SidebarSectionTitle } from '../SidebarComponents'
|
||||||
|
import { sidebarPhoto_media_exif_coordinates } from '../__generated__/sidebarPhoto'
|
||||||
|
|
||||||
|
type MediaSidebarMapProps = {
|
||||||
|
coordinates: sidebarPhoto_media_exif_coordinates
|
||||||
|
}
|
||||||
|
|
||||||
|
const MediaSidebarMap = ({ coordinates }: MediaSidebarMapProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const { mapContainer, mapboxToken } = useMapboxMap({
|
||||||
|
mapboxOptions: {
|
||||||
|
interactive: false,
|
||||||
|
zoom: 12,
|
||||||
|
center: {
|
||||||
|
lat: coordinates.latitude,
|
||||||
|
lng: coordinates.longitude,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
configureMapbox: (map, mapboxLibrary) => {
|
||||||
|
// todo
|
||||||
|
map.addControl(
|
||||||
|
new mapboxLibrary.NavigationControl({ showCompass: false })
|
||||||
|
)
|
||||||
|
|
||||||
|
const centerMarker = new mapboxLibrary.Marker({
|
||||||
|
color: 'red',
|
||||||
|
scale: 0.8,
|
||||||
|
})
|
||||||
|
centerMarker.setLngLat({
|
||||||
|
lat: coordinates.latitude,
|
||||||
|
lng: coordinates.longitude,
|
||||||
|
})
|
||||||
|
centerMarker.addTo(map)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isNil(mapboxToken)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarSection>
|
||||||
|
<SidebarSectionTitle>
|
||||||
|
{t('sidebar.location.title', 'Location')}
|
||||||
|
</SidebarSectionTitle>
|
||||||
|
<div className="w-full h-64">{mapContainer}</div>
|
||||||
|
</SidebarSection>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MediaSidebarMap
|
|
@ -4,7 +4,7 @@ import { useLazyQuery, gql } from '@apollo/client'
|
||||||
import { authToken } from '../../helpers/authentication'
|
import { authToken } from '../../helpers/authentication'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { TranslationFn } from '../../localization'
|
import { TranslationFn } from '../../localization'
|
||||||
import { MediaSidebarMedia } from './MediaSidebar'
|
import { MediaSidebarMedia } from './MediaSidebar/MediaSidebar'
|
||||||
import {
|
import {
|
||||||
sidebarDownloadQuery,
|
sidebarDownloadQuery,
|
||||||
sidebarDownloadQueryVariables,
|
sidebarDownloadQueryVariables,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
toggleFavoriteAction,
|
toggleFavoriteAction,
|
||||||
useMarkFavoriteMutation,
|
useMarkFavoriteMutation,
|
||||||
} from '../photoGallery/photoGalleryMutations'
|
} from '../photoGallery/photoGalleryMutations'
|
||||||
import MediaSidebar from '../sidebar/MediaSidebar'
|
import MediaSidebar from '../sidebar/MediaSidebar/MediaSidebar'
|
||||||
import { SidebarContext } from '../sidebar/Sidebar'
|
import { SidebarContext } from '../sidebar/Sidebar'
|
||||||
import {
|
import {
|
||||||
getActiveTimelineImage,
|
getActiveTimelineImage,
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Download"
|
"title": "Download"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": "Lokation"
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Download"
|
"title": "Download"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Download"
|
"title": "Download"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": "Location"
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Descargar"
|
"title": "Descargar"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Télécharger"
|
"title": "Télécharger"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Download"
|
"title": "Download"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -264,6 +264,9 @@
|
||||||
},
|
},
|
||||||
"title": "Pobierz"
|
"title": "Pobierz"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -264,6 +264,9 @@
|
||||||
},
|
},
|
||||||
"title": "Скачать"
|
"title": "Скачать"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
},
|
},
|
||||||
"title": "Ladda ner"
|
"title": "Ladda ner"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"title": ""
|
||||||
|
},
|
||||||
"media": {
|
"media": {
|
||||||
"exif": {
|
"exif": {
|
||||||
"exposure_program": {
|
"exposure_program": {
|
||||||
|
|
Loading…
Reference in New Issue