1
Fork 0

Start on present view

This commit is contained in:
viktorstrate 2019-07-25 00:53:50 +02:00
parent 53415714c2
commit 3cc8b4b5cb
6 changed files with 229 additions and 96 deletions

View File

@ -3,7 +3,7 @@ import gql from 'graphql-tag'
import { Query } from 'react-apollo'
import Layout from '../../Layout'
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
import PhotoGallery from '../../PhotoGallery'
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
import AlbumGallery from '../AllAlbumsPage/AlbumGallery'
const albumQuery = gql`

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react'
import Layout from '../../Layout'
import gql from 'graphql-tag'
import { Query } from 'react-apollo'
import PhotoGallery from '../../PhotoGallery'
import PhotoGallery from '../../components/photoGallery/PhotoGallery'
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
const photoQuery = gql`

View File

@ -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>
)

View File

@ -1,8 +1,8 @@
import React from 'react'
import styled from 'styled-components'
import { Loader } from 'semantic-ui-react'
import { useSpring, animated } from 'react-spring'
import LazyLoad from 'react-lazyload'
import { Photo } from './Photo'
import PresentView from './PresentView'
const Gallery = styled.div`
display: flex;
@ -10,68 +10,16 @@ const Gallery = styled.div`
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`
height: 200px;
flex-grow: 999999;
`
const presentIdFromHash = hash => {
let match = hash.match(/present=([a-z0-9\-]+)/)
return match && match[1]
}
class PhotoGallery extends React.Component {
constructor(props) {
super(props)
@ -121,23 +69,20 @@ class PhotoGallery extends React.Component {
}
return (
<PhotoContainer
<Photo
key={photo.id}
style={{
cursor: onSelectImage ? 'pointer' : null,
minWidth: `${minWidth}px`,
}}
onClick={() => {
onSelectImage && onSelectImage(index)
}}
>
<Photo src={photo.thumbnail && photo.thumbnail.url} />
<PhotoOverlay active={active} />
</PhotoContainer>
photo={photo}
onSelectImage={onSelectImage}
minWidth={minWidth}
index={index}
active={active}
/>
)
})
}
console.log(presentIdFromHash(location.hash))
return (
<div>
<Gallery>
@ -145,6 +90,7 @@ class PhotoGallery extends React.Component {
{photoElements}
<PhotoFiller />
</Gallery>
<PresentView image={presentIdFromHash(location.hash)} />
</div>
)
}

View File

@ -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>
)
}
}

View File

@ -3,6 +3,7 @@ import styled from 'styled-components'
import { Query } from 'react-apollo'
import gql from 'graphql-tag'
import { SidebarItem } from './SidebarItem'
import { Loader } from 'semantic-ui-react'
const photoQuery = gql`
query sidebarPhoto($id: ID) {
@ -79,41 +80,44 @@ class AlbumSidebar extends Component {
<RightSidebar>
<Query query={photoQuery} variables={{ id: imageId }}>
{({ loading, error, data }) => {
if (loading) return 'Loading...'
if (error) return error
const { photo } = data
let exifItems = []
if (photo.exif) {
let exifKeys = Object.keys(photo.exif).filter(
x => !!photo.exif[x] && x != '__typename'
)
if (data.photo) {
if (photo.exif) {
let exifKeys = Object.keys(photo.exif).filter(
x => !!photo.exif[x] && x != '__typename'
)
let exif = exifKeys.reduce(
(prev, curr) => ({
...prev,
[curr]: photo.exif[curr],
}),
{}
)
let exif = exifKeys.reduce(
(prev, curr) => ({
...prev,
[curr]: photo.exif[curr],
}),
{}
)
exif.dateShot = exif.dateShot.formatted
exif.dateShot = exif.dateShot.formatted
exifItems = exifKeys.map(key => (
<SidebarItem
key={key}
name={exifNameLookup[key]}
value={exif[key]}
/>
))
exifItems = exifKeys.map(key => (
<SidebarItem
key={key}
name={exifNameLookup[key]}
value={exif[key]}
/>
))
}
}
return (
<div>
<PreviewImage src={photo.original && photo.original.url} />
<Name>{photo.title}</Name>
<Loader active={loading} />
<PreviewImage
src={photo && photo.original && photo.original.url}
/>
<Name>{photo && photo.title}</Name>
<div>{exifItems}</div>
</div>
)