From 7fb48aed5a9eb3073ec5088dde5190394087318d Mon Sep 17 00:00:00 2001 From: Lillifee Date: Thu, 30 Dec 2021 11:31:42 +0100 Subject: [PATCH] Gallery improvements and player alignment fix - Fix player alignment on resize - Sort files by date decending - Remove random thumbnail size - Fallback icon and filename for unsupported formats - Snap gallery header --- package.json | 2 +- src/server/watcher.ts | 2 +- src/shared/settings/types.ts | 2 +- src/site/components/gallery/Gallery.tsx | 80 +++++++++++++++++-------- src/site/components/main/Player.tsx | 4 +- src/site/components/theme/themes.ts | 2 +- 6 files changed, 60 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index adbaf78..314dcab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "raspicam", - "version": "1.0.1", + "version": "1.1.0", "main": "src/server/index.ts", "browser": "src/site/index.tsx", "author": "Patrick Matt", diff --git a/src/server/watcher.ts b/src/server/watcher.ts index db17b6a..ff5e6d0 100644 --- a/src/server/watcher.ts +++ b/src/server/watcher.ts @@ -39,7 +39,7 @@ export const fileWatcher = (): FileWatcher => { const addFile = (fileName: string) => { const { name, base, ext } = path.parse(fileName); const type = fileTypes[ext.substring(1)]; - const file: RaspiFile = { name, base, ext, type }; + const file: RaspiFile = { name, base, ext, type, date: 0 }; // Invalid type or thumbnail if (!type || isThumbnail(file)) return; diff --git a/src/shared/settings/types.ts b/src/shared/settings/types.ts index 4b81c69..34045ad 100644 --- a/src/shared/settings/types.ts +++ b/src/shared/settings/types.ts @@ -39,8 +39,8 @@ export interface RaspiFile { name: string; base: string; ext: string; + date: number; thumb?: string; - date?: number; } export interface RaspiControlStatus { diff --git a/src/site/components/gallery/Gallery.tsx b/src/site/components/gallery/Gallery.tsx index 2f19a0f..18f5d05 100644 --- a/src/site/components/gallery/Gallery.tsx +++ b/src/site/components/gallery/Gallery.tsx @@ -2,21 +2,22 @@ import * as React from 'react'; import styled from 'styled-components'; import { RaspiGallery, RaspiFile, photosPath } from '../../../shared/settings/types'; import { useFetch } from '../common/hooks/useFetch'; +import { Icon } from '../common/Icon'; import { Toolbar } from './Toolbar'; const GalleryContainer = styled.div` flex: 1; display: flex; + overflow-y: auto; flex-direction: column; color: ${(p) => p.theme.Foreground}; background: ${(p) => p.theme.Background}; - overflow-y: auto; `; -const ImageContainer = styled.div` +const GroupContainer = styled.div` display: grid; - margin: 0.2em; - grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + margin: 0.5em 0.2em; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); grid-auto-flow: dense; grid-gap: 0.2em; justify-items: stretch; @@ -27,11 +28,6 @@ const ImageContainer = styled.div` } `; -interface ThumbnailProps { - sizeCol: number; - sizeRow: number; -} - const Thumbnail = styled.img` max-width: 100%; height: auto; @@ -39,10 +35,30 @@ const Thumbnail = styled.img` flex: 1; `; -const PreviewLink = styled.a` +const PreviewContainer = styled.div` + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + min-height: 80px; + fill: ${(p) => p.theme.Foreground}; + background: ${(p) => p.theme.LayerBackground}; +`; + +const FallbackIcon = styled.div` + margin: 0.2em; +`; + +const FallbackText = styled.div` + margin: 0.2em; + color: ${({ theme }) => theme.Foreground}; + font-size: ${({ theme }) => theme.FontSize.s}; +`; + +const PreviewLink = styled.a` display: flex; - grid-row-start: span ${(p) => p.sizeRow}; - grid-column-start: span ${(p) => p.sizeCol}; + text-decoration: none; `; const Group = styled.div` @@ -54,7 +70,10 @@ const Group = styled.div` const Header = styled.div` font-size: ${(p) => p.theme.FontSize.l}; font-weight: 300; - margin: 1em 0.5em; + position: sticky; + top: 0px; + margin: 0 1.5em; + padding: 0.45em; `; const dateTimeFormat = new Intl.DateTimeFormat('en-GB', { @@ -64,12 +83,14 @@ const dateTimeFormat = new Intl.DateTimeFormat('en-GB', { export const Gallery: React.FC = () => { const [gallery] = useFetch('/api/gallery', { files: [] }); - const groupedFiles = gallery.data.files.reduce>((result, file) => { - const date = dateTimeFormat.format(new Date(file.date || 0)); - const images = (result[date] = result[date] || []); - images.push(file); - return result; - }, {}); + const groupedFiles = gallery.data.files + .sort((a, b) => b.date - a.date) + .reduce>((result, file) => { + const date = dateTimeFormat.format(new Date(file.date)); + const images = (result[date] = result[date] || []); + images.push(file); + return result; + }, {}); return ( @@ -78,20 +99,29 @@ export const Gallery: React.FC = () => { {Object.entries(groupedFiles).map(([date, files]) => (
{date}
- - {files.map((file, index) => ( + + {files.map((file) => ( - + + {file.thumb ? ( + + ) : ( + + + + + {file.base} + + )} + ))} - +
))}
diff --git a/src/site/components/main/Player.tsx b/src/site/components/main/Player.tsx index 0af9af5..cf69fc3 100644 --- a/src/site/components/main/Player.tsx +++ b/src/site/components/main/Player.tsx @@ -11,9 +11,7 @@ const Container = styled.div` `; const VideoContainer = styled.div` - display: flex; - align-items: center; - justify-content: center; + margin: 0 auto; `; const Video = styled.video` diff --git a/src/site/components/theme/themes.ts b/src/site/components/theme/themes.ts index 4f3ae51..b37898c 100644 --- a/src/site/components/theme/themes.ts +++ b/src/site/components/theme/themes.ts @@ -8,7 +8,7 @@ export const darkTheme: DefaultTheme = { LayerBackground: 'rgba(20, 20, 20, 0.8)', SubLayerBackground: 'rgba(20, 20, 20, 0.6)', - Background: '#3d3d3d', + Background: '#242424', Border: '#1d1d1d', Foreground: '#e2e2e2',