Work on sidebar redesign
This commit is contained in:
parent
9d8af5bfa4
commit
4d02be1623
|
@ -4,7 +4,7 @@ import React from 'react'
|
|||
import { Helmet } from 'react-helmet'
|
||||
import Header from '../header/Header'
|
||||
import { Authorized } from '../routes/AuthorizedRoute'
|
||||
import { SidebarProvider } from '../sidebar/Sidebar'
|
||||
import { Sidebar, SidebarProvider } from '../sidebar/Sidebar'
|
||||
import MainMenu from './MainMenu'
|
||||
|
||||
export const ADMIN_QUERY = gql`
|
||||
|
@ -40,7 +40,7 @@ const Layout = ({ children, title, ...otherProps }: LayoutProps) => {
|
|||
<div className="h-6"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <Sidebar /> */}
|
||||
<Sidebar />
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
)
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
} from './__generated__/sidebarPhoto'
|
||||
|
||||
import { sidebarDownloadQuery_media_downloads } from './__generated__/sidebarDownloadQuery'
|
||||
import SidebarHeader from './SidebarHeader'
|
||||
|
||||
const SIDEBAR_MEDIA_QUERY = gql`
|
||||
query sidebarPhoto($id: ID!) {
|
||||
|
@ -87,13 +88,6 @@ const SIDEBAR_MEDIA_QUERY = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const PreviewImageWrapper = styled.div<{ imageAspect: number }>`
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-top: ${({ imageAspect }) => Math.min(imageAspect, 0.75) * 100}%;
|
||||
position: relative;
|
||||
`
|
||||
|
||||
const PreviewImage = styled(ProtectedImage)`
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
@ -134,12 +128,6 @@ const PreviewMedia = ({ media, previewImage }: PreviewMediaProps) => {
|
|||
return <div>ERROR: Unknown media type: {media.type}</div>
|
||||
}
|
||||
|
||||
const Name = styled.div`
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
margin: 0.75rem 0 1rem;
|
||||
`
|
||||
|
||||
const MetadataInfoContainer = styled.div`
|
||||
margin-bottom: 1.5rem;
|
||||
`
|
||||
|
@ -155,7 +143,7 @@ export const MetadataInfo = ({ media }: MediaInfoProps) => {
|
|||
const exifName = exifNameLookup(t)
|
||||
|
||||
if (media?.exif) {
|
||||
const mediaExif = (media?.exif as unknown) as {
|
||||
const mediaExif = media?.exif as unknown as {
|
||||
[key: string]: string | number | null
|
||||
}
|
||||
|
||||
|
@ -212,7 +200,7 @@ export const MetadataInfo = ({ media }: MediaInfoProps) => {
|
|||
|
||||
let videoMetadataItems: JSX.Element[] = []
|
||||
if (media?.videoMetadata) {
|
||||
const videoMetadata = (media.videoMetadata as unknown) as {
|
||||
const videoMetadata = media.videoMetadata as unknown as {
|
||||
[key: string]: string | number | null
|
||||
}
|
||||
|
||||
|
@ -371,16 +359,21 @@ const SidebarContent = ({ media, hidePreview }: SidebarContentProps) => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<SidebarHeader title={media.title ?? 'Loading...'} />
|
||||
<div className="lg:mx-4">
|
||||
{!hidePreview && (
|
||||
<PreviewImageWrapper imageAspect={imageAspect}>
|
||||
<div
|
||||
className="w-full h-0 relative"
|
||||
style={{ paddingTop: `${Math.min(imageAspect, 0.75) * 100}%` }}
|
||||
>
|
||||
<PreviewMedia
|
||||
previewImage={previewImage || undefined}
|
||||
media={media}
|
||||
/>
|
||||
<SidebarFacesOverlay media={media} />
|
||||
</PreviewImageWrapper>
|
||||
</div>
|
||||
)}
|
||||
<Name>{media.title}</Name>
|
||||
</div>
|
||||
<MetadataInfo media={media} />
|
||||
<SidebarDownload media={media} />
|
||||
<SidebarPhotoShare id={media.id} />
|
||||
|
@ -418,10 +411,8 @@ type MediaSidebarType = {
|
|||
}
|
||||
|
||||
const MediaSidebar = ({ media, hidePreview }: MediaSidebarType) => {
|
||||
const [loadMedia, { loading, error, data }] = useLazyQuery<
|
||||
sidebarPhoto,
|
||||
sidebarPhotoVariables
|
||||
>(SIDEBAR_MEDIA_QUERY)
|
||||
const [loadMedia, { loading, error, data }] =
|
||||
useLazyQuery<sidebarPhoto, sidebarPhotoVariables>(SIDEBAR_MEDIA_QUERY)
|
||||
|
||||
useEffect(() => {
|
||||
if (media != null && authToken()) {
|
||||
|
|
|
@ -1,41 +1,4 @@
|
|||
import React, { createContext, useContext, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { Icon } from 'semantic-ui-react'
|
||||
|
||||
const SidebarContainer = styled.div<{ highlighted: boolean }>`
|
||||
width: 28vw;
|
||||
max-width: 500px;
|
||||
min-width: 300px;
|
||||
flex-shrink: 0;
|
||||
overflow-y: scroll;
|
||||
right: 0;
|
||||
margin-top: 60px;
|
||||
background-color: white;
|
||||
padding: 12px;
|
||||
border-left: 1px solid #eee;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
/* full height - header - tabbar */
|
||||
height: calc(100% - 60px - 80px);
|
||||
max-width: min(calc(100vw - 85px), 400px);
|
||||
${({ highlighted }) => `right: ${highlighted ? 0 : -100}%;`}
|
||||
padding-top: 45px;
|
||||
}
|
||||
|
||||
transition: right 200ms ease-in-out;
|
||||
`
|
||||
|
||||
const SidebarDismissButton = styled(Icon)`
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
|
||||
@media (min-width: 700px) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react'
|
||||
|
||||
export type UpdateSidebarFn = (content: React.ReactNode) => void
|
||||
|
||||
|
@ -78,18 +41,33 @@ export const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||
}
|
||||
|
||||
export const Sidebar = () => {
|
||||
const { updateSidebar, content } = useContext(SidebarContext)
|
||||
const { content } = useContext(SidebarContext)
|
||||
|
||||
useEffect(() => {
|
||||
const body = document.body
|
||||
|
||||
if (content == null) {
|
||||
body.classList.remove('overflow-y-hidden')
|
||||
body.classList.remove('lg:overflow-y-auto')
|
||||
} else {
|
||||
body.classList.add('overflow-y-hidden')
|
||||
body.classList.add('lg:overflow-y-auto')
|
||||
}
|
||||
|
||||
return () => {
|
||||
body.classList.remove('overflow-y-hidden')
|
||||
body.classList.remove('lg:overflow-y-auto')
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<SidebarContainer highlighted={content != null}>
|
||||
<div
|
||||
className={`fixed top-[72px] bg-white bottom-0 w-full overflow-y-scroll transform transition-transform motion-reduce:transition-none ${
|
||||
content == null ? 'translate-x-full' : 'translate-x-0'
|
||||
} lg:w-[420px] lg:right-0 lg:shadow-separator lg:top-0 lg:z-40`}
|
||||
>
|
||||
{content}
|
||||
<SidebarDismissButton
|
||||
name="angle double right"
|
||||
size="big"
|
||||
link
|
||||
onClick={() => updateSidebar(null)}
|
||||
/>
|
||||
<div style={{ height: 100 }}></div>
|
||||
</SidebarContainer>
|
||||
<div className="h-24"></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import React, { useContext } from 'react'
|
||||
|
||||
import { ReactComponent as CloseIcon } from './icons/closeSidebarIcon.svg'
|
||||
import { ReactComponent as PinIcon } from './icons/pinSidebarIcon.svg'
|
||||
import { SidebarContext } from './Sidebar'
|
||||
|
||||
type SidebarHeaderProps = {
|
||||
title: string
|
||||
}
|
||||
|
||||
const SidebarHeader = ({ title }: SidebarHeaderProps) => {
|
||||
const { updateSidebar } = useContext(SidebarContext)
|
||||
|
||||
return (
|
||||
<div className="m-2 flex items-center gap-2">
|
||||
<button title="Close sidebar" onClick={() => updateSidebar(null)}>
|
||||
<CloseIcon className="m-2" />
|
||||
</button>
|
||||
<span className="flex-grow -mt-1">{title}</span>
|
||||
<button title="Pin sidebar">
|
||||
<PinIcon className="m-2" />
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SidebarHeader
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path stroke="none" stroke-width="1" fill="none" d="M1,11 L11,1 M11,11 L1,1" stroke="#1F2021" stroke-width="2"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 311 B |
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="17px" viewBox="0 0 16 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(8, 8.5) rotate(-330) translate(-8, -8.5) translate(4, 2)" stroke="#1F2021">
|
||||
<path d="M6.76850191,0.434840963 C6.04896114,1.86467297 5.79279384,3.20120746 6,4.44444444 C6.17989677,5.52382504 6.63266329,6.48919052 7.35829958,7.34054088 C7.50158762,7.50867286 7.48146228,7.76112984 7.31333862,7.90442763 C7.24096223,7.96611661 7.14897427,8 7.053875,8 L0.922873286,8 C0.701919553,8.00007212 0.522801161,7.82095373 0.522801161,7.59999999 C0.522801161,7.50599929 0.555900634,7.41500023 0.616293108,7.34296634 C1.36567981,6.44912577 1.82691544,5.48295181 2,4.44444444 C2.19754347,3.25918364 1.93688287,1.92116674 1.21801821,0.430393743 C1.14595115,0.281147735 1.2086138,0.10177184 1.35789863,0.0297852978 C1.39855358,0.0101811032 1.44310701,8.29112604e-18 1.4882418,0 L6.50055336,0 C6.666219,3.58349532e-05 6.80051754,0.134334371 6.80051754,0.300000012 C6.80051754,0.346829895 6.78955305,0.393009303 6.76850191,0.434840963 Z" stroke-linejoin="round"></path>
|
||||
<line x1="4" y1="8" x2="4" y2="13" stroke-linecap="round"></line>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -163,7 +163,7 @@ const TimelineGallery = () => {
|
|||
))
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="overflow-x-hidden">
|
||||
<div className="mb-2">
|
||||
<FavoritesCheckbox
|
||||
onlyFavorites={onlyFavorites}
|
||||
|
@ -183,7 +183,7 @@ const TimelineGallery = () => {
|
|||
dispatchMedia={dispatchMedia}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue