diff --git a/api/src/resolvers/photos.js b/api/src/resolvers/photos.js
index 45fff484..0a9e2e16 100644
--- a/api/src/resolvers/photos.js
+++ b/api/src/resolvers/photos.js
@@ -39,6 +39,27 @@ const myAlbumQuery = function(args, ctx, info) {
return query
}
+const myPhotoQuery = function(args, ctx, info) {
+ const query = cypherQuery(args, ctx, info)
+
+ const whereSplit = query[0].indexOf('RETURN')
+
+ query[0] = injectAt(
+ query[0],
+ whereSplit,
+ `MATCH (u:User { id: {userid} }) WHERE (u)-[:OWNS]->(:Album)-[:CONTAINS]->(photo) `
+ )
+ query[1].userid = ctx.user.id
+
+ query[0] = injectAt(
+ query[0],
+ query[0].indexOf('RETURN `photo` {') + 16,
+ query[0].indexOf('RETURN `photo` {}') == -1 ? ` .id, ` : ` .id `
+ )
+
+ return query
+}
+
const Query = {
async myAlbums(root, args, ctx, info) {
let query = myAlbumQuery(args, ctx, info)
@@ -73,6 +94,39 @@ const Query = {
return result.records[0].get('album')
},
+ async myPhotos(root, args, ctx, info) {
+ let query = myPhotoQuery(args, ctx, info)
+ console.log(query)
+
+ const session = ctx.driver.session()
+
+ const result = await session.run(...query)
+
+ session.close()
+
+ return result.records.map(record => record.get('photo'))
+ },
+ async photo(root, args, ctx, info) {
+ const session = ctx.driver.session()
+
+ let query = myPhotoQuery(args, ctx, info)
+
+ const whereSplit = query[0].indexOf('RETURN')
+
+ query[0] = injectAt(query[0], whereSplit, ` AND photo.id = {id} `)
+ query[1].id = args.id
+ console.log(query)
+
+ const result = await session.run(...query)
+
+ session.close()
+
+ if (result.records.length == 0) {
+ throw new Error('Album was not found')
+ }
+
+ return result.records[0].get('photo')
+ },
}
function photoResolver(image) {
diff --git a/api/src/schema.graphql b/api/src/schema.graphql
index e549fad6..b1a4a35d 100644
--- a/api/src/schema.graphql
+++ b/api/src/schema.graphql
@@ -75,4 +75,7 @@ type Query {
myAlbums: [Album] @isAuthenticated
album(id: ID): Album @isAuthenticated
+
+ myPhotos: [Photo] @isAuthenticated
+ photo(id: ID): Photo @isAuthenticated
}
diff --git a/ui/src/AuthorizedRoute.js b/ui/src/AuthorizedRoute.js
new file mode 100644
index 00000000..05556d14
--- /dev/null
+++ b/ui/src/AuthorizedRoute.js
@@ -0,0 +1,25 @@
+import React from 'react'
+import { Route, Redirect } from 'react-router-dom'
+
+const AuthorizedRoute = ({ component: Component, ...props }) => {
+ const token = localStorage.getItem('token')
+
+ let unauthorizedRedirect = null
+ if (!token) {
+ unauthorizedRedirect =
+ }
+
+ return (
+ (
+ <>
+ {unauthorizedRedirect}
+
+ >
+ )}
+ >
+ )
+}
+
+export default AuthorizedRoute
diff --git a/ui/src/Layout.js b/ui/src/Layout.js
index 9a44d4da..9eba734c 100644
--- a/ui/src/Layout.js
+++ b/ui/src/Layout.js
@@ -1,9 +1,11 @@
import React, { Component } from 'react'
import styled from 'styled-components'
-import { Link } from 'react-router-dom'
+import { NavLink } from 'react-router-dom'
+import { Icon } from 'semantic-ui-react'
const Container = styled.div`
height: 100%;
+ margin-right: 500px;
/* display: grid;
grid-template-columns: 80px 1fr 500px; */
`
@@ -17,31 +19,42 @@ const LeftSidebar = styled.div`
padding-top: 10px;
`
-const RightSidebar = styled.div`
- height: 100%;
- width: 500px;
- position: fixed;
- right: 0;
- top: 60px;
- background-color: white;
-`
-
const Content = styled.div`
margin-top: 60px;
margin-left: 80px;
- margin-right: 500px;
padding: 12px 8px 0;
`
-const SideButton = styled(Link)`
- border: 1px solid #eee;
- text-align: center;
- padding-top: 17px;
- border-radius: 50%;
- display: block;
- width: 60px;
- height: 60px;
- margin: 10px;
+const SideButton = props => {
+ const StyledLink = styled(NavLink)`
+ text-align: center;
+ padding-top: 8px;
+ padding-left: 2px;
+ display: block;
+ width: 60px;
+ height: 60px;
+ margin: 10px;
+
+ font-size: 28px;
+
+ color: #888;
+
+ transition: transform 200ms, box-shadow 200ms;
+
+ :hover {
+ transform: scale(1.02);
+ }
+ `
+
+ return (
+
+ {props.children}
+
+ )
+}
+
+const SideButtonLabel = styled.div`
+ font-size: 16px;
`
const Header = styled.div`
@@ -64,10 +77,12 @@ class Layout extends Component {
return (
- Albums
+
+
+ Albums
+
{this.props.children}
- Right
diff --git a/ui/src/Pages/AlbumPage/AlbumPage.js b/ui/src/Pages/AlbumPage/AlbumPage.js
index 45bc0254..b0956994 100644
--- a/ui/src/Pages/AlbumPage/AlbumPage.js
+++ b/ui/src/Pages/AlbumPage/AlbumPage.js
@@ -1,8 +1,16 @@
import React, { Component } from 'react'
import gql from 'graphql-tag'
import { Query } from 'react-apollo'
-import { Gallery, Photo, PhotoFiller } from './styledElements'
+import {
+ Gallery,
+ Photo,
+ PhotoFiller,
+ PhotoContainer,
+ PhotoOverlay,
+} from './styledElements'
import Layout from '../../Layout'
+import { Loader } from 'semantic-ui-react'
+import AlbumSidebar from './AlbumSidebar'
const albumQuery = gql`
query albumQuery($id: ID) {
@@ -33,7 +41,7 @@ class AlbumPage extends Component {
this.photoAmount = 1
this.previousActive = false
- this.keyUpEvent = e => {
+ this.keyDownEvent = e => {
const activeImage = this.state.activeImage
if (activeImage != -1) {
if (e.key == 'ArrowRight') {
@@ -52,11 +60,11 @@ class AlbumPage extends Component {
}
componentDidMount() {
- document.addEventListener('keyup', this.keyUpEvent)
+ document.addEventListener('keydown', this.keyDownEvent)
}
componentWillUnmount() {
- document.removeEventListener('keyup', this.keyUpEvent)
+ document.removeEventListener('keydown', this.keyDownEvent)
}
setActiveImage(index) {
@@ -80,23 +88,45 @@ class AlbumPage extends Component {
{({ loading, error, data }) => {
if (error) return Error
- if (loading) return Loading
- this.photoAmount = data.album.photos.length
+ let photos = null
+ if (data.album) {
+ this.photoAmount = data.album.photos.length
- const { activeImage } = this.state
+ const { activeImage } = this.state
- const photos = data.album.photos.map((photo, index) => {
- return
- })
+ photos = data.album.photos.map((photo, index) => {
+ const active = activeImage == index
+
+ return (
+ {
+ this.setActiveImage(index)
+ }}
+ >
+
+
+
+ )
+ })
+ }
return (
-
{data.album.title}
+
{data.album ? data.album.title : ''}
+ Loading images
{photos}
+
)
}}
diff --git a/ui/src/Pages/AlbumPage/AlbumSidebar.js b/ui/src/Pages/AlbumPage/AlbumSidebar.js
new file mode 100644
index 00000000..65a2a5fb
--- /dev/null
+++ b/ui/src/Pages/AlbumPage/AlbumSidebar.js
@@ -0,0 +1,71 @@
+import React, { Component } from 'react'
+import styled from 'styled-components'
+import { Query } from 'react-apollo'
+import gql from 'graphql-tag'
+
+const photoQuery = gql`
+ query sidebarPhoto($id: ID) {
+ photo(id: $id) {
+ title
+ original {
+ path
+ width
+ height
+ }
+ }
+ }
+`
+
+const RightSidebar = styled.div`
+ height: 100%;
+ width: 500px;
+ position: fixed;
+ right: 0;
+ top: 60px;
+ background-color: white;
+ padding: 12px;
+ border-left: 1px solid #eee;
+`
+
+const PreviewImage = styled.img`
+ width: 100%;
+ height: 333px;
+ object-fit: contain;
+`
+
+const Name = styled.div`
+ text-align: center;
+ font-size: 16px;
+`
+
+class AlbumSidebar extends Component {
+ render() {
+ const { imageId } = this.props
+
+ if (!imageId) {
+ return
+ }
+
+ return (
+
+
+ {({ loading, error, data }) => {
+ if (loading) return 'Loading...'
+ if (error) return error
+
+ const { photo } = data
+
+ return (
+
+ )
+ }}
+
+
+ )
+ }
+}
+
+export default AlbumSidebar
diff --git a/ui/src/Pages/AlbumPage/styledElements.js b/ui/src/Pages/AlbumPage/styledElements.js
index e729bcc8..d5d9ab98 100644
--- a/ui/src/Pages/AlbumPage/styledElements.js
+++ b/ui/src/Pages/AlbumPage/styledElements.js
@@ -6,19 +6,32 @@ export const Gallery = styled.div`
align-items: center;
`
-export const Photo = styled.img`
+export const PhotoContainer = styled.div`
+ flex-grow: 1;
+ height: 200px;
margin: 4px;
background-color: #eee;
+ position: relative;
+`
+
+export const Photo = styled.img`
height: 200px;
- flex-grow: 1;
+ min-width: 100%;
+ position: relative;
object-fit: cover;
+`
+
+export const PhotoOverlay = styled.div`
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
${props =>
props.active &&
`
- will-change: transform;
- position: relative;
- z-index: 999;
+ border: 4px solid rgba(65, 131, 196, 0.6);
`}
`
diff --git a/ui/src/Pages/HomePage/Albums.js b/ui/src/Pages/HomePage/Albums.js
index bf647a1d..be866b59 100644
--- a/ui/src/Pages/HomePage/Albums.js
+++ b/ui/src/Pages/HomePage/Albums.js
@@ -3,7 +3,7 @@ import gql from 'graphql-tag'
import { Query } from 'react-apollo'
import styled from 'styled-components'
import { Link } from 'react-router-dom'
-import { Dimmer, Loader } from 'semantic-ui-react'
+import { Loader } from 'semantic-ui-react'
const getAlbumsQuery = gql`
query getMyAlbums {
diff --git a/ui/src/Routes.js b/ui/src/Routes.js
index 78cb17e2..94fd2d9c 100644
--- a/ui/src/Routes.js
+++ b/ui/src/Routes.js
@@ -4,22 +4,15 @@ import { Route, Switch } from 'react-router-dom'
import LoginPage from './Pages/LoginPage'
import HomePage from './Pages/HomePage/HomePage'
import AlbumPage from './Pages/AlbumPage/AlbumPage'
+import AuthorizedRoute from './AuthorizedRoute'
class Routes extends Component {
render() {
- const token = localStorage.getItem('token')
-
- let unauthorizedRedirect = null
- if (!token) {
- unauthorizedRedirect =
- }
-
return (
- {unauthorizedRedirect}
-
-
+
+
)
}