diff --git a/api/package.json b/api/package.json index 84565879..84906658 100644 --- a/api/package.json +++ b/api/package.json @@ -30,12 +30,14 @@ "fs-extra": "^8.1.0", "graphql-tag": "^2.10.1", "image-size": "^0.7.4", - "img-type": "^0.1.13", + "image-type": "^4.1.0", + "is-image": "^3.0.0", "jsonwebtoken": "^8.5.1", "lodash": "^4.17.14", "neo4j-driver": "^1.7.3", "neo4j-graphql-js": "^2.6.3", "node-fetch": "^2.3.0", + "read-chunk": "^3.2.0", "regenerator-runtime": "^0.13.2", "sharp": "^0.22.1", "uuid": "^3.3.2" diff --git a/api/src/Scanner.js b/api/src/Scanner.js index baa97e78..a6860d42 100644 --- a/api/src/Scanner.js +++ b/api/src/Scanner.js @@ -2,14 +2,31 @@ import fs from 'fs-extra' import path from 'path' import { resolve as pathResolve, basename as pathBasename } from 'path' import { PubSub } from 'apollo-server' -import imgType from 'img-type' import uuid from 'uuid' import { exiftool } from 'exiftool-vendored' import sharp from 'sharp' +import readChunk from 'read-chunk' +import imageType from 'image-type' import config from './config' export const EVENT_SCANNER_PROGRESS = 'SCANNER_PROGRESS' +const isImage = async path => { + const buffer = await readChunk(path, 0, 12) + const type = imageType(buffer) + + return type != null +} + +const isRawImage = async path => { + const buffer = await readChunk(path, 0, 12) + const { ext } = imageType(buffer) + + const rawTypes = ['cr2', 'arw', 'crw', 'dng'] + + return rawTypes.includes(ext) +} + class PhotoScanner { constructor(driver) { this.driver = driver @@ -146,7 +163,7 @@ class PhotoScanner { continue } - if (!foundImage && (await imgType.isImg(itemPath))) { + if (!foundImage && (await isImage(itemPath))) { foundImage = true } } @@ -167,7 +184,7 @@ class PhotoScanner { for (const item of list) { const itemPath = pathResolve(path, item) - if (await imgType.isImg(itemPath)) { + if (await isImage(itemPath)) { const session = this.driver.session() const photoResult = await session.run( @@ -217,13 +234,9 @@ class PhotoScanner { await fs.remove(imagePath) await fs.mkdirp(imagePath) - const type = await imgType.getType(photo.path) - let resizeBaseImg = photo.path - const rawTypes = ['cr2', 'arw', 'crw', 'dng'] - - if (rawTypes.includes(type)) { + if (await isRawImage(photo.path)) { console.log('Processing RAW image') const extractedPath = path.resolve(imagePath, 'extracted.jpg') diff --git a/ui/src/Layout.js b/ui/src/Layout.js index d3b8dba2..9a44d4da 100644 --- a/ui/src/Layout.js +++ b/ui/src/Layout.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import styled from 'styled-components' +import { Link } from 'react-router-dom' const Container = styled.div` height: 100%; @@ -11,9 +12,9 @@ const LeftSidebar = styled.div` height: 100%; width: 80px; position: fixed; - top: 0; + top: 60px; left: 0; - background-color: #eee; + padding-top: 10px; ` const RightSidebar = styled.div` @@ -21,23 +22,55 @@ const RightSidebar = styled.div` width: 500px; position: fixed; right: 0; - top: 0; - background-color: #eee; + top: 60px; + background-color: white; ` const Content = styled.div` + margin-top: 60px; margin-left: 80px; margin-right: 500px; - padding: 0 8px; + padding: 12px 8px 0; +` + +const SideButton = styled(Link)` + border: 1px solid #eee; + text-align: center; + padding-top: 17px; + border-radius: 50%; + display: block; + width: 60px; + height: 60px; + margin: 10px; +` + +const Header = styled.div` + height: 60px; + width: 100%; + position: fixed; + background: white; + top: 0; + /* border-bottom: 1px solid rgba(0, 0, 0, 0.1); */ + box-shadow: 0 0 2px rgba(0, 0, 0, 0.3); +` + +const Title = styled.h1` + font-size: 36px; + padding: 5px 12px; ` class Layout extends Component { render() { return ( - Left + + Albums + {this.props.children} Right +
+ Photoview +
) } diff --git a/ui/src/Pages/AlbumPage/AlbumPage.js b/ui/src/Pages/AlbumPage/AlbumPage.js index f54a7848..45bc0254 100644 --- a/ui/src/Pages/AlbumPage/AlbumPage.js +++ b/ui/src/Pages/AlbumPage/AlbumPage.js @@ -91,10 +91,13 @@ class AlbumPage extends Component { }) return ( - - {photos} - - +
+

{data.album.title}

+ + {photos} + + +
) }} diff --git a/ui/src/Pages/HomePage/Albums.js b/ui/src/Pages/HomePage/Albums.js index 418bcd9c..bf647a1d 100644 --- a/ui/src/Pages/HomePage/Albums.js +++ b/ui/src/Pages/HomePage/Albums.js @@ -19,6 +19,13 @@ const getAlbumsQuery = gql` } ` +const Container = styled.div` + margin: -10px; + margin-top: 20px; + position: relative; + min-height: 500px; +` + const AlbumBoxLink = styled(Link)` width: 240px; height: 240px; @@ -41,7 +48,7 @@ const AlbumBoxImage = styled.div` class Albums extends Component { render() { return ( -
+ {({ loading, error, data }) => { // if (loading) return @@ -52,7 +59,9 @@ class Albums extends Component { if (data && data.myAlbums) { albums = data.myAlbums.map(album => ( - +

{album.title}

)) @@ -76,7 +85,7 @@ class Albums extends Component { ) }}
-
+ ) } } diff --git a/ui/src/Pages/HomePage/HomePage.js b/ui/src/Pages/HomePage/HomePage.js index 33b3ff30..35848960 100644 --- a/ui/src/Pages/HomePage/HomePage.js +++ b/ui/src/Pages/HomePage/HomePage.js @@ -6,7 +6,7 @@ class HomePage extends Component { render() { return ( -

Home

+

Albums

)