Start on present view
This commit is contained in:
parent
53415714c2
commit
3cc8b4b5cb
|
@ -3,7 +3,7 @@ import gql from 'graphql-tag'
|
||||||
import { Query } from 'react-apollo'
|
import { Query } from 'react-apollo'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../Layout'
|
||||||
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
|
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
|
||||||
import PhotoGallery from '../../PhotoGallery'
|
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
|
||||||
import AlbumGallery from '../AllAlbumsPage/AlbumGallery'
|
import AlbumGallery from '../AllAlbumsPage/AlbumGallery'
|
||||||
|
|
||||||
const albumQuery = gql`
|
const albumQuery = gql`
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { Component } from 'react'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../Layout'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { Query } from 'react-apollo'
|
import { Query } from 'react-apollo'
|
||||||
import PhotoGallery from '../../PhotoGallery'
|
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
|
||||||
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
|
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
|
||||||
|
|
||||||
const photoQuery = gql`
|
const photoQuery = gql`
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
import React from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
import { useSpring, animated } from 'react-spring'
|
||||||
|
import LazyLoad from 'react-lazyload'
|
||||||
|
import { Icon } from 'semantic-ui-react'
|
||||||
|
|
||||||
|
const PhotoContainer = styled.div`
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 200px;
|
||||||
|
margin: 4px;
|
||||||
|
background-color: #eee;
|
||||||
|
position: relative;
|
||||||
|
`
|
||||||
|
|
||||||
|
const PhotoImg = photoProps => {
|
||||||
|
const StyledPhoto = styled(animated.img)`
|
||||||
|
height: 200px;
|
||||||
|
min-width: 100%;
|
||||||
|
position: relative;
|
||||||
|
object-fit: cover;
|
||||||
|
`
|
||||||
|
|
||||||
|
const [props, set, stop] = useSpring(() => ({ opacity: 0 }))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledPhoto
|
||||||
|
{...photoProps}
|
||||||
|
style={props}
|
||||||
|
onLoad={() => {
|
||||||
|
set({ opacity: 1 })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyPhoto extends React.Component {
|
||||||
|
shouldComponentUpdate(nextProps) {
|
||||||
|
return nextProps.src != this.props.src
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<LazyLoad>
|
||||||
|
<PhotoImg {...this.props} />
|
||||||
|
</LazyLoad>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PhotoOverlay = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
${props =>
|
||||||
|
props.active &&
|
||||||
|
`
|
||||||
|
border: 4px solid rgba(65, 131, 196, 0.6);
|
||||||
|
`}
|
||||||
|
`
|
||||||
|
|
||||||
|
const HoverIcon = styled(Icon)`
|
||||||
|
font-size: 1.5em !important;
|
||||||
|
margin: 160px 0 0 10px !important;
|
||||||
|
color: white !important;
|
||||||
|
text-shadow: 0 0 4px black;
|
||||||
|
opacity: 0 !important;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 34px !important;
|
||||||
|
height: 34px !important;
|
||||||
|
padding-top: 8px;
|
||||||
|
|
||||||
|
${PhotoContainer}:hover & {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
transition: opacity 100ms, background-color 100ms;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Photo = ({ photo, onSelectImage, minWidth, index, active }) => (
|
||||||
|
<PhotoContainer
|
||||||
|
key={photo.id}
|
||||||
|
style={{
|
||||||
|
cursor: onSelectImage ? 'pointer' : null,
|
||||||
|
minWidth: `${minWidth}px`,
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
onSelectImage && onSelectImage(index)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LazyPhoto src={photo.thumbnail && photo.thumbnail.url} />
|
||||||
|
<PhotoOverlay active={active}>
|
||||||
|
<HoverIcon
|
||||||
|
name="expand"
|
||||||
|
onClick={() => {
|
||||||
|
window.location.hash = `present=${photo.id}`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<HoverIcon name="heart outline" />
|
||||||
|
</PhotoOverlay>
|
||||||
|
</PhotoContainer>
|
||||||
|
)
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { Loader } from 'semantic-ui-react'
|
import { Loader } from 'semantic-ui-react'
|
||||||
import { useSpring, animated } from 'react-spring'
|
import { Photo } from './Photo'
|
||||||
import LazyLoad from 'react-lazyload'
|
import PresentView from './PresentView'
|
||||||
|
|
||||||
const Gallery = styled.div`
|
const Gallery = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -10,68 +10,16 @@ const Gallery = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
`
|
`
|
||||||
|
|
||||||
const PhotoContainer = styled.div`
|
|
||||||
flex-grow: 1;
|
|
||||||
height: 200px;
|
|
||||||
margin: 4px;
|
|
||||||
background-color: #eee;
|
|
||||||
position: relative;
|
|
||||||
`
|
|
||||||
|
|
||||||
const PhotoImg = photoProps => {
|
|
||||||
const StyledPhoto = styled(animated.img)`
|
|
||||||
height: 200px;
|
|
||||||
min-width: 100%;
|
|
||||||
position: relative;
|
|
||||||
object-fit: cover;
|
|
||||||
`
|
|
||||||
|
|
||||||
const [props, set, stop] = useSpring(() => ({ opacity: 0 }))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledPhoto
|
|
||||||
{...photoProps}
|
|
||||||
style={props}
|
|
||||||
onLoad={() => {
|
|
||||||
set({ opacity: 1 })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class Photo extends React.Component {
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
return nextProps.src != this.props.src
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<LazyLoad>
|
|
||||||
<PhotoImg {...this.props} />
|
|
||||||
</LazyLoad>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const PhotoOverlay = styled.div`
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
${props =>
|
|
||||||
props.active &&
|
|
||||||
`
|
|
||||||
border: 4px solid rgba(65, 131, 196, 0.6);
|
|
||||||
`}
|
|
||||||
`
|
|
||||||
|
|
||||||
const PhotoFiller = styled.div`
|
const PhotoFiller = styled.div`
|
||||||
height: 200px;
|
height: 200px;
|
||||||
flex-grow: 999999;
|
flex-grow: 999999;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const presentIdFromHash = hash => {
|
||||||
|
let match = hash.match(/present=([a-z0-9\-]+)/)
|
||||||
|
return match && match[1]
|
||||||
|
}
|
||||||
|
|
||||||
class PhotoGallery extends React.Component {
|
class PhotoGallery extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
@ -121,23 +69,20 @@ class PhotoGallery extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PhotoContainer
|
<Photo
|
||||||
key={photo.id}
|
key={photo.id}
|
||||||
style={{
|
photo={photo}
|
||||||
cursor: onSelectImage ? 'pointer' : null,
|
onSelectImage={onSelectImage}
|
||||||
minWidth: `${minWidth}px`,
|
minWidth={minWidth}
|
||||||
}}
|
index={index}
|
||||||
onClick={() => {
|
active={active}
|
||||||
onSelectImage && onSelectImage(index)
|
/>
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Photo src={photo.thumbnail && photo.thumbnail.url} />
|
|
||||||
<PhotoOverlay active={active} />
|
|
||||||
</PhotoContainer>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(presentIdFromHash(location.hash))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Gallery>
|
<Gallery>
|
||||||
|
@ -145,6 +90,7 @@ class PhotoGallery extends React.Component {
|
||||||
{photoElements}
|
{photoElements}
|
||||||
<PhotoFiller />
|
<PhotoFiller />
|
||||||
</Gallery>
|
</Gallery>
|
||||||
|
<PresentView image={presentIdFromHash(location.hash)} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import React from 'react'
|
||||||
|
import styled, { createGlobalStyle } from 'styled-components'
|
||||||
|
import { Query } from 'react-apollo'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
const PresentContainer = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 100;
|
||||||
|
`
|
||||||
|
|
||||||
|
const PreventScroll = createGlobalStyle`
|
||||||
|
body {
|
||||||
|
/* height: 100vh !important; */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const imageQuery = gql`
|
||||||
|
query presentImage($id: ID) {
|
||||||
|
photo(id: $id) {
|
||||||
|
title
|
||||||
|
original {
|
||||||
|
width
|
||||||
|
height
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const PresentImage = styled.img`
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: contain;
|
||||||
|
object-position: center;
|
||||||
|
`
|
||||||
|
|
||||||
|
export default class PresentView extends React.Component {
|
||||||
|
render() {
|
||||||
|
const { image } = this.props
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PresentContainer>
|
||||||
|
<PreventScroll />
|
||||||
|
<Query query={imageQuery} variables={{ id: image }}>
|
||||||
|
{({ loading, error, data }) => {
|
||||||
|
if (loading) return 'Loading...'
|
||||||
|
if (error) return error
|
||||||
|
|
||||||
|
const { photo } = data
|
||||||
|
|
||||||
|
console.log(photo)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PresentImage src={photo && photo.original.url} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Query>
|
||||||
|
</PresentContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import styled from 'styled-components'
|
||||||
import { Query } from 'react-apollo'
|
import { Query } from 'react-apollo'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { SidebarItem } from './SidebarItem'
|
import { SidebarItem } from './SidebarItem'
|
||||||
|
import { Loader } from 'semantic-ui-react'
|
||||||
|
|
||||||
const photoQuery = gql`
|
const photoQuery = gql`
|
||||||
query sidebarPhoto($id: ID) {
|
query sidebarPhoto($id: ID) {
|
||||||
|
@ -79,41 +80,44 @@ class AlbumSidebar extends Component {
|
||||||
<RightSidebar>
|
<RightSidebar>
|
||||||
<Query query={photoQuery} variables={{ id: imageId }}>
|
<Query query={photoQuery} variables={{ id: imageId }}>
|
||||||
{({ loading, error, data }) => {
|
{({ loading, error, data }) => {
|
||||||
if (loading) return 'Loading...'
|
|
||||||
if (error) return error
|
if (error) return error
|
||||||
|
|
||||||
const { photo } = data
|
const { photo } = data
|
||||||
|
|
||||||
let exifItems = []
|
let exifItems = []
|
||||||
|
|
||||||
if (photo.exif) {
|
if (data.photo) {
|
||||||
let exifKeys = Object.keys(photo.exif).filter(
|
if (photo.exif) {
|
||||||
x => !!photo.exif[x] && x != '__typename'
|
let exifKeys = Object.keys(photo.exif).filter(
|
||||||
)
|
x => !!photo.exif[x] && x != '__typename'
|
||||||
|
)
|
||||||
|
|
||||||
let exif = exifKeys.reduce(
|
let exif = exifKeys.reduce(
|
||||||
(prev, curr) => ({
|
(prev, curr) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[curr]: photo.exif[curr],
|
[curr]: photo.exif[curr],
|
||||||
}),
|
}),
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
|
||||||
exif.dateShot = exif.dateShot.formatted
|
exif.dateShot = exif.dateShot.formatted
|
||||||
|
|
||||||
exifItems = exifKeys.map(key => (
|
exifItems = exifKeys.map(key => (
|
||||||
<SidebarItem
|
<SidebarItem
|
||||||
key={key}
|
key={key}
|
||||||
name={exifNameLookup[key]}
|
name={exifNameLookup[key]}
|
||||||
value={exif[key]}
|
value={exif[key]}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PreviewImage src={photo.original && photo.original.url} />
|
<Loader active={loading} />
|
||||||
<Name>{photo.title}</Name>
|
<PreviewImage
|
||||||
|
src={photo && photo.original && photo.original.url}
|
||||||
|
/>
|
||||||
|
<Name>{photo && photo.title}</Name>
|
||||||
<div>{exifItems}</div>
|
<div>{exifItems}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue