diff --git a/ui/src/Pages/AlbumPage/AlbumPage.js b/ui/src/Pages/AlbumPage/AlbumPage.js
index 71ae6d1..08d44bf 100644
--- a/ui/src/Pages/AlbumPage/AlbumPage.js
+++ b/ui/src/Pages/AlbumPage/AlbumPage.js
@@ -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`
diff --git a/ui/src/Pages/PhotosPage/PhotosPage.js b/ui/src/Pages/PhotosPage/PhotosPage.js
index 2363b76..8fc117c 100644
--- a/ui/src/Pages/PhotosPage/PhotosPage.js
+++ b/ui/src/Pages/PhotosPage/PhotosPage.js
@@ -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`
diff --git a/ui/src/components/photoGallery/Photo.js b/ui/src/components/photoGallery/Photo.js
new file mode 100644
index 0000000..a0f7c21
--- /dev/null
+++ b/ui/src/components/photoGallery/Photo.js
@@ -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>
+)
diff --git a/ui/src/PhotoGallery.js b/ui/src/components/photoGallery/PhotoGallery.js
similarity index 56%
rename from ui/src/PhotoGallery.js
rename to ui/src/components/photoGallery/PhotoGallery.js
index 9fa9667..96b1cc6 100644
--- a/ui/src/PhotoGallery.js
+++ b/ui/src/components/photoGallery/PhotoGallery.js
@@ -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>
     )
   }
diff --git a/ui/src/components/photoGallery/PresentView.js b/ui/src/components/photoGallery/PresentView.js
new file mode 100644
index 0000000..ef305d4
--- /dev/null
+++ b/ui/src/components/photoGallery/PresentView.js
@@ -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>
+    )
+  }
+}
diff --git a/ui/src/components/sidebar/PhotoSidebar.js b/ui/src/components/sidebar/PhotoSidebar.js
index 36e3eb7..e4e2dbb 100644
--- a/ui/src/components/sidebar/PhotoSidebar.js
+++ b/ui/src/components/sidebar/PhotoSidebar.js
@@ -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>
             )
