Start on timeline frontend
This commit is contained in:
parent
214c4e8be4
commit
9c84336d34
|
@ -5,6 +5,11 @@ import Routes from './components/routes/Routes'
|
|||
import Messages from './components/messages/Messages'
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
* {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React from 'react'
|
||||
import Layout from '../../Layout'
|
||||
import PropTypes from 'prop-types'
|
||||
import GalleryGroups from '../../components/photoGallery/GalleryGroups'
|
||||
import TimelineGallery from '../../components/timelineGallery/TimelineGallery'
|
||||
|
||||
const PhotosPage = ({ match }) => {
|
||||
const PhotosPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Layout title="Photos">
|
||||
<GalleryGroups subPage={match.params.subPage} />
|
||||
<TimelineGallery />
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -122,7 +122,6 @@ const VideoThumbnailIcon = styled(Icon)`
|
|||
export const MediaThumbnail = ({
|
||||
media,
|
||||
onSelectImage,
|
||||
minWidth,
|
||||
index,
|
||||
active,
|
||||
setPresenting,
|
||||
|
@ -163,6 +162,13 @@ export const MediaThumbnail = ({
|
|||
videoIcon = <VideoThumbnailIcon name="play" size="big" />
|
||||
}
|
||||
|
||||
let minWidth = 100
|
||||
if (media.thumbnail) {
|
||||
minWidth = Math.floor(
|
||||
(media.thumbnail.width / media.thumbnail.height) * 200
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<MediaContainer
|
||||
key={media.id}
|
||||
|
@ -174,7 +180,14 @@ export const MediaThumbnail = ({
|
|||
onSelectImage && onSelectImage(index)
|
||||
}}
|
||||
>
|
||||
<LazyPhoto src={media.thumbnail && media.thumbnail.url} />
|
||||
<div
|
||||
style={{
|
||||
minWidth: `${minWidth}px`,
|
||||
height: `200px`,
|
||||
}}
|
||||
>
|
||||
<LazyPhoto src={media.thumbnail && media.thumbnail.url} />
|
||||
</div>
|
||||
<PhotoOverlay active={active}>
|
||||
{videoIcon}
|
||||
<HoverIcon
|
||||
|
|
|
@ -54,13 +54,6 @@ const PhotoGallery = ({
|
|||
photoElements = media.map((photo, index) => {
|
||||
const active = activeIndex == index
|
||||
|
||||
let minWidth = 100
|
||||
if (photo.thumbnail) {
|
||||
minWidth = Math.floor(
|
||||
(photo.thumbnail.width / photo.thumbnail.height) * 200
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<MediaThumbnail
|
||||
key={photo.id}
|
||||
|
@ -71,7 +64,6 @@ const PhotoGallery = ({
|
|||
}}
|
||||
onFavorite={onFavorite}
|
||||
setPresenting={setPresenting}
|
||||
minWidth={minWidth}
|
||||
index={index}
|
||||
active={active}
|
||||
/>
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import React from 'react'
|
||||
import { useQuery, gql } from '@apollo/client'
|
||||
import TimelineGroupDate from './TimelineGroupDate'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const MY_TIMELINE_QUERY = gql`
|
||||
query myTimeline {
|
||||
myTimeline {
|
||||
album {
|
||||
id
|
||||
title
|
||||
}
|
||||
media {
|
||||
id
|
||||
thumbnail {
|
||||
url
|
||||
width
|
||||
height
|
||||
}
|
||||
}
|
||||
mediaTotal
|
||||
date
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const GalleryWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
`
|
||||
|
||||
const TimelineGallery = () => {
|
||||
const { data, error } = useQuery(MY_TIMELINE_QUERY)
|
||||
|
||||
if (error) {
|
||||
return error
|
||||
}
|
||||
|
||||
let timelineGroups = null
|
||||
if (data?.myTimeline) {
|
||||
const dateGroupedAlbums = data.myTimeline.reduce((acc, val) => {
|
||||
if (acc.length == 0 || acc[acc.length - 1].date != val.date) {
|
||||
acc.push({
|
||||
date: val.date,
|
||||
groups: [val],
|
||||
})
|
||||
} else {
|
||||
acc[acc.length - 1].groups.push(val)
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
timelineGroups = dateGroupedAlbums.map(({ date, groups }) => (
|
||||
<TimelineGroupDate key={date} date={date} groups={groups} />
|
||||
))
|
||||
}
|
||||
|
||||
return <GalleryWrapper>{timelineGroups}</GalleryWrapper>
|
||||
}
|
||||
|
||||
export default TimelineGallery
|
|
@ -0,0 +1,61 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { MediaThumbnail } from '../photoGallery/MediaThumbnail'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const MediaWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
position: relative;
|
||||
margin: -4px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
/* Compensate for tab bar on mobile */
|
||||
margin-bottom: 76px;
|
||||
}
|
||||
`
|
||||
|
||||
const AlbumTitle = styled.h2`
|
||||
color: #212121;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 200;
|
||||
margin: 0 0 4px;
|
||||
`
|
||||
|
||||
const GroupAlbumWrapper = styled.div`
|
||||
margin-top: 12px;
|
||||
`
|
||||
|
||||
const TimelineGroupAlbum = ({ group: { album, media /* mediaTotal */ } }) => {
|
||||
const mediaElms = media.map(media => (
|
||||
<MediaThumbnail
|
||||
key={media.id}
|
||||
media={media}
|
||||
onSelectImage={() => {
|
||||
// todo
|
||||
}}
|
||||
setPresenting={() => {
|
||||
// todo
|
||||
}}
|
||||
index={0}
|
||||
active={false}
|
||||
/>
|
||||
))
|
||||
|
||||
return (
|
||||
<GroupAlbumWrapper>
|
||||
<AlbumTitle>{album.title}</AlbumTitle>
|
||||
<MediaWrapper>{mediaElms}</MediaWrapper>
|
||||
</GroupAlbumWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
TimelineGroupAlbum.propTypes = {
|
||||
group: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default TimelineGroupAlbum
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import TimelineGroupAlbum from './TimelineGroupAlbum'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const dateFormatter = new Intl.DateTimeFormat(navigator.language, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})
|
||||
|
||||
const GroupDateWrapper = styled.div`
|
||||
margin: 12px 12px;
|
||||
`
|
||||
|
||||
const DateTitle = styled.h1`
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 -12px;
|
||||
`
|
||||
|
||||
const TimelineGroupDate = ({ date, groups }) => {
|
||||
const groupElms = groups.map(group => (
|
||||
<TimelineGroupAlbum key={`${group.date}_${group.album.id}`} group={group} />
|
||||
))
|
||||
|
||||
const formattedDate = dateFormatter.format(new Date(date))
|
||||
|
||||
return (
|
||||
<GroupDateWrapper>
|
||||
<DateTitle>{formattedDate}</DateTitle>
|
||||
<div>{groupElms}</div>
|
||||
</GroupDateWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
TimelineGroupDate.propTypes = {
|
||||
date: PropTypes.string.isRequired,
|
||||
groups: PropTypes.array.isRequired,
|
||||
}
|
||||
|
||||
export default TimelineGroupDate
|
Loading…
Reference in New Issue