diff --git a/ui/src/components/photoGallery/MediaThumbnail.js b/ui/src/components/photoGallery/MediaThumbnail.js
index 7a41415..f2cb0cb 100644
--- a/ui/src/components/photoGallery/MediaThumbnail.js
+++ b/ui/src/components/photoGallery/MediaThumbnail.js
@@ -205,7 +205,6 @@ export const MediaThumbnail = ({
 MediaThumbnail.propTypes = {
   media: PropTypes.object.isRequired,
   onSelectImage: PropTypes.func,
-  minWidth: PropTypes.number.isRequired,
   index: PropTypes.number.isRequired,
   active: PropTypes.bool.isRequired,
   setPresenting: PropTypes.func.isRequired,
diff --git a/ui/src/components/timelineGallery/TimelineGallery.js b/ui/src/components/timelineGallery/TimelineGallery.js
index 6bc5111..e9cb5f0 100644
--- a/ui/src/components/timelineGallery/TimelineGallery.js
+++ b/ui/src/components/timelineGallery/TimelineGallery.js
@@ -1,7 +1,9 @@
-import React from 'react'
+import React, { useState } from 'react'
+import PropTypes from 'prop-types'
 import { useQuery, gql } from '@apollo/client'
 import TimelineGroupDate from './TimelineGroupDate'
 import styled from 'styled-components'
+import PresentView from '../photoGallery/presentView/PresentView'
 
 const MY_TIMELINE_QUERY = gql`
   query myTimeline {
@@ -12,11 +14,22 @@ const MY_TIMELINE_QUERY = gql`
       }
       media {
         id
+        title
+        type
         thumbnail {
           url
           width
           height
         }
+        highRes {
+          url
+          width
+          height
+        }
+        videoWeb {
+          url
+        }
+        favorite
       }
       mediaTotal
       date
@@ -30,6 +43,51 @@ const GalleryWrapper = styled.div`
 `
 
 const TimelineGallery = () => {
+  const [activeIndex, setActiveIndex] = useState({
+    dateGroup: -1,
+    albumGroup: -1,
+    media: -1,
+  })
+  const [presenting, setPresenting] = useState(false)
+
+  const nextMedia = () => {
+    setActiveIndex(activeIndex => {
+      const albumGroups = dateGroupedAlbums[activeIndex.dateGroup].groups
+      const albumMedia = albumGroups[activeIndex.albumGroup].media
+
+      if (activeIndex.media < albumMedia.length - 1) {
+        return {
+          ...activeIndex,
+          media: activeIndex.media + 1,
+        }
+      }
+
+      if (activeIndex.albumGroup < albumGroups.length - 1) {
+        return {
+          ...activeIndex,
+          albumGroup: activeIndex.albumGroup + 1,
+          media: 0,
+        }
+      }
+
+      if (activeIndex.dateGroup < dateGroupedAlbums.length - 1) {
+        return {
+          dateGroup: activeIndex.dateGroup + 1,
+          albumGroup: 0,
+          media: 0,
+        }
+      }
+
+      return {
+        dateGroup: 0,
+        albumGroup: 0,
+        media: 0,
+      }
+    })
+  }
+
+  const previousMedia = () => {}
+
   const { data, error } = useQuery(MY_TIMELINE_QUERY)
 
   if (error) {
@@ -37,8 +95,9 @@ const TimelineGallery = () => {
   }
 
   let timelineGroups = null
+  let dateGroupedAlbums = []
   if (data?.myTimeline) {
-    const dateGroupedAlbums = data.myTimeline.reduce((acc, val) => {
+    dateGroupedAlbums = data.myTimeline.reduce((acc, val) => {
       if (acc.length == 0 || acc[acc.length - 1].date != val.date) {
         acc.push({
           date: val.date,
@@ -51,12 +110,51 @@ const TimelineGallery = () => {
       return acc
     }, [])
 
-    timelineGroups = dateGroupedAlbums.map(({ date, groups }) => (
-      <TimelineGroupDate key={date} date={date} groups={groups} />
+    timelineGroups = dateGroupedAlbums.map(({ date, groups }, i) => (
+      <TimelineGroupDate
+        key={date}
+        date={date}
+        groups={groups}
+        activeIndex={
+          activeIndex.dateGroup == i
+            ? activeIndex
+            : { albumGroup: -1, media: -1 }
+        }
+        setPresenting={setPresenting}
+        onSelectDateGroup={({ media, albumGroup }) => {
+          setActiveIndex({
+            media,
+            albumGroup,
+            dateGroup: i,
+          })
+        }}
+      />
     ))
   }
 
-  return <GalleryWrapper>{timelineGroups}</GalleryWrapper>
+  return (
+    <GalleryWrapper>
+      {timelineGroups}
+      {presenting && (
+        <PresentView
+          media={
+            dateGroupedAlbums &&
+            dateGroupedAlbums[activeIndex.dateGroup].groups[
+              activeIndex.albumGroup
+            ].media[activeIndex.media]
+          }
+          nextImage={nextMedia}
+          previousImage={previousMedia}
+          setPresenting={setPresenting}
+        />
+      )}
+    </GalleryWrapper>
+  )
+}
+
+TimelineGallery.propTypes = {
+  favorites: PropTypes.bool,
+  setFavorites: PropTypes.func,
 }
 
 export default TimelineGallery
diff --git a/ui/src/components/timelineGallery/TimelineGroupAlbum.js b/ui/src/components/timelineGallery/TimelineGroupAlbum.js
index 3705cfc..15ee7c1 100644
--- a/ui/src/components/timelineGallery/TimelineGroupAlbum.js
+++ b/ui/src/components/timelineGallery/TimelineGroupAlbum.js
@@ -7,7 +7,7 @@ const MediaWrapper = styled.div`
   display: flex;
   flex-wrap: wrap;
   align-items: center;
-  height: 200px;
+  height: 210px;
   position: relative;
   margin: -4px;
 
@@ -30,19 +30,20 @@ const GroupAlbumWrapper = styled.div`
   margin-top: 12px;
 `
 
-const TimelineGroupAlbum = ({ group: { album, media /* mediaTotal */ } }) => {
-  const mediaElms = media.map(media => (
+const TimelineGroupAlbum = ({
+  group: { album, media /* mediaTotal */ },
+  onSelectMedia,
+  setPresenting,
+  activeIndex,
+}) => {
+  const mediaElms = media.map((media, i) => (
     <MediaThumbnail
       key={media.id}
       media={media}
-      onSelectImage={() => {
-        // todo
-      }}
-      setPresenting={() => {
-        // todo
-      }}
-      index={0}
-      active={false}
+      onSelectImage={onSelectMedia}
+      setPresenting={setPresenting}
+      index={i}
+      active={activeIndex == i}
     />
   ))
 
@@ -56,6 +57,9 @@ const TimelineGroupAlbum = ({ group: { album, media /* mediaTotal */ } }) => {
 
 TimelineGroupAlbum.propTypes = {
   group: PropTypes.object.isRequired,
+  onSelectMedia: PropTypes.func.isRequired,
+  setPresenting: PropTypes.func.isRequired,
+  activeIndex: PropTypes.number.isRequired,
 }
 
 export default TimelineGroupAlbum
diff --git a/ui/src/components/timelineGallery/TimelineGroupDate.js b/ui/src/components/timelineGallery/TimelineGroupDate.js
index ae1f88a..7a2de68 100644
--- a/ui/src/components/timelineGallery/TimelineGroupDate.js
+++ b/ui/src/components/timelineGallery/TimelineGroupDate.js
@@ -18,9 +18,26 @@ const DateTitle = styled.h1`
   margin: 0 0 -12px;
 `
 
-const TimelineGroupDate = ({ date, groups }) => {
-  const groupElms = groups.map(group => (
-    <TimelineGroupAlbum key={`${group.date}_${group.album.id}`} group={group} />
+const TimelineGroupDate = ({
+  date,
+  groups,
+  onSelectDateGroup,
+  activeIndex,
+  setPresenting,
+}) => {
+  const albumGroupElms = groups.map((group, i) => (
+    <TimelineGroupAlbum
+      key={`${group.date}_${group.album.id}`}
+      group={group}
+      onSelectMedia={mediaIndex => {
+        onSelectDateGroup({
+          media: mediaIndex,
+          albumGroup: i,
+        })
+      }}
+      activeIndex={activeIndex.albumGroup == i ? activeIndex.media : -1}
+      setPresenting={setPresenting}
+    />
   ))
 
   const formattedDate = dateFormatter.format(new Date(date))
@@ -28,7 +45,7 @@ const TimelineGroupDate = ({ date, groups }) => {
   return (
     <GroupDateWrapper>
       <DateTitle>{formattedDate}</DateTitle>
-      <div>{groupElms}</div>
+      <div>{albumGroupElms}</div>
     </GroupDateWrapper>
   )
 }
@@ -36,6 +53,9 @@ const TimelineGroupDate = ({ date, groups }) => {
 TimelineGroupDate.propTypes = {
   date: PropTypes.string.isRequired,
   groups: PropTypes.array.isRequired,
+  onSelectDateGroup: PropTypes.func.isRequired,
+  activeIndex: PropTypes.object.isRequired,
+  setPresenting: PropTypes.func.isRequired,
 }
 
 export default TimelineGroupDate
