Simple image viewing with custom code.

master
Sander Vocke 6 years ago
parent 28dbc5714c
commit 683f306193
  1. 3
      src/context/modal_gallery_context.js
  2. 82
      src/gallery/gallery.js
  3. 64
      src/gridgallery.js
  4. 37
      src/lib/modal.js
  5. 47
      src/main.js
  6. 8
      src/queries.js

@ -0,0 +1,3 @@
import { createContext } from 'react';
export const g_modal_gallery_context = createContext([{}, () => { }]);

@ -0,0 +1,82 @@
import React, { useState, useEffect } from 'react';
import Box from '@material-ui/core/Box';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => ({
background: {
width: "100%",
height: "100%",
overflow: "auto",
position: "absolute",
"background-color": "rgba(0,0,0,1)",
'overflow': 'hidden',
},
image_container: {
'width': '100%',
'height': '100%',
'overflow': 'hidden',
},
image: {
'object-fit': 'contain',
'width': '100%',
'height': '100%',
'overflow': 'hidden',
},
}));
export function GalleryImageRender(props) {
const { src } = props;
const classes = useStyles();
return (
<img src={src}
className={classes.image} />
);
}
export function GalleryImage(props) {
const { photo } = props;
// First show the fast (thumbnail) image.
const [src, setSrc] = useState(photo.state.thumbnailpath);
// Start a fetch of the full image, then show that.
useEffect(() => {
console.log("Fetching...");
fetch(photo.state.path)
.then(() => {
console.log("Fetch done. setting image.");
setSrc(photo.state.path);
})
}, []);
return (
<GalleryImageRender src={src}/>
);
}
export function Gallery(props) {
const { onClose, items, current_item } = props;
const classes = useStyles();
var maybe_photo = false;
if (items && items.length > 0 && current_item < items.length) {
maybe_photo = items[current_item];
}
return (
<>
<Box
className={classes.background}
onClick={onClose}>
<Box className={classes.image_container}>
{
maybe_photo &&
<GalleryImage photo={maybe_photo} />
}
</Box>
</Box>
</>
);
}

@ -1,8 +1,10 @@
import React from 'react';
import React, { useContext } from 'react';
import Box from '@material-ui/core/Box';
import { makeStyles } from '@material-ui/core/styles';
import { g_modal_gallery_context } from './context/modal_gallery_context.js';
const useStyles = makeStyles(theme => ({
gallery: {
width: "100%",
@ -12,6 +14,7 @@ const useStyles = makeStyles(theme => ({
},
imgitem: {
width: "100%",
cursor: 'pointer',
}
}));
@ -35,9 +38,8 @@ export function GridGalleryItem(props) {
}
export function PhotoItem(props) {
const { photo, row_height } = props;
const { photo, row_height, onClick } = props;
const classes = useStyles();
const photo_width = (photo.state.fullsize[0] / photo.state.fullsize[1]) * row_height;
return (
@ -45,7 +47,7 @@ export function PhotoItem(props) {
width={photo_width}
height={row_height}
>
<img src={photo.state.thumbnailpath} className={classes.imgitem} />
<img src={photo.state.thumbnailpath} className={classes.imgitem} onClick={onClick} />
</GridGalleryItem>
);
}
@ -66,43 +68,27 @@ export function ItemGridGallery(props) {
export function GridGallery(props) {
const { photos } = props;
return (
<ItemGridGallery>
{photos.map(photo => {
return <PhotoItem photo={photo} row_height={300} />
})}
</ItemGridGallery>
);
}
const [modalGalleryState, setModalGalleryState] = useContext(g_modal_gallery_context);
/*
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
},
}));
var _ = require('lodash');
const photo_to_gallery_photo = (photo) => {
if (!photo.state.fullsize) {
throw new Error("Photo for gallery does not have a size.");
const handleClick = (idx) => {
const state = _.cloneDeep(modalGalleryState);
state.active = true;
state.items = photos;
state.current_item = idx;
setModalGalleryState(state);
}
return {
src: photo.state.path,
thumbnail: photo.state.thumbnailpath,
thumbnailWidth: photo.state.fullsize[0],
thumbnailHeight: photo.state.fullsize[1],
caption: photo.state.name,
}
}
export function GridGallery(props) {
const classes = useStyles();
return (
<Gallery className={classes.root} enableImageSelection={false} images={props.photos.map(x => photo_to_gallery_photo(x))} />
)
}
*/
<ItemGridGallery>
{photos.map((photo, idx) => {
return <PhotoItem
photo={photo}
row_height={300}
onClick={() => {handleClick(idx);}}
/>
})}
</ItemGridGallery>
);
}

@ -0,0 +1,37 @@
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import { makeStyles } from '@material-ui/core/styles'
const useStyles = makeStyles(theme => ({
modal: {
position: "fixed",
top: '0px',
left: '0px',
width: '100%',
height: '100vh',
'z-index': '1300', //Material UI "modal" value
},
}));
export function Modal(props) {
const { children, active } = props;
const [el, setEl] = useState(null);
const classes = useStyles();
useEffect(() => {
const new_el = document.createElement('div');
new_el.className = classes.modal;
setEl(new_el);
document.getElementById('root').appendChild(new_el);
}, []);
if(!el) {
return <></>;
}
if(el) {
el.style.visibility = active ? 'visible' : 'hidden';
}
return ReactDOM.createPortal(children, el);
}

@ -12,6 +12,9 @@ import { UserQuery, user_query_from_search_string, maybe_image_query, do_image_q
import { Browser } from './browser.js';
import { UserQueryWidget } from './userquerywidget.js';
import { ResultsView } from './resultsview.js';
import { Modal } from './lib/modal.js';
import { Gallery } from './gallery/gallery.js';
import { g_modal_gallery_context } from './context/modal_gallery_context.js';
const useStyles = makeStyles(theme => ({
root: {
@ -46,6 +49,11 @@ export function LoadedMainPage(props) {
const [allTags, setAllTags] = React.useState([]);
const [albums, setAlbums] = React.useState([]);
const [tags, setTags] = React.useState([]);
const [modalGalleryState, setModalGalleryState] = React.useState({
active: false,
items: [],
current_item: 0,
});
const { database, photos_dir, thumbs_dir } = props;
var _ = require('lodash');
@ -110,7 +118,7 @@ export function LoadedMainPage(props) {
function onNewQuery(q) {
var do_update = !_.isEqual(q.filter, gallery_user_query.filter);
setGalleryUserQuery(q);
if (do_update) {
if (do_update) {
updatePhotos(q);
updateAlbums(q);
updateTags(q);
@ -122,18 +130,35 @@ export function LoadedMainPage(props) {
onNewQuery(query);
}
function handleGalleryClose() {
var state = _.cloneDeep(modalGalleryState);
state.active = false;
state.items = [];
state.current_item = 0;
setModalGalleryState(state);
}
return (
<>
<Box className={classes.root}>
<Box className={classes.navigator}>
<Box className={classes.margined}>{albums && <Browser albums={allAlbums} tags={allTags} onNewQuery={onNewQuery} />}</Box>
<g_modal_gallery_context.Provider value={[modalGalleryState, setModalGalleryState]}>
<Box className={classes.root}>
<Box className={classes.navigator}>
<Box className={classes.margined}>{albums && <Browser albums={allAlbums} tags={allTags} onNewQuery={onNewQuery} />}</Box>
</Box>
<Box className={classes.searchandview}>
<Box className={classes.margined}><SearchBar onSubmit={onSearch} /></Box>
<Box className={classes.margined}><UserQueryWidget userQuery={gallery_user_query} onChange={onNewQuery} /></Box>
<Box className={classes.margined}>{photos && <ResultsView photos={photos ? photos : []} albums={albums ? albums : []} tags={tags ? tags : []} />}</Box>
</Box>
</Box>
<Box className={classes.searchandview}>
<Box className={classes.margined}><SearchBar onSubmit={onSearch} /></Box>
<Box className={classes.margined}><UserQueryWidget userQuery={gallery_user_query} onChange={onNewQuery} /></Box>
<Box className={classes.margined}>{photos && <ResultsView photos={photos ? photos : []} albums={albums ? albums : []} tags={tags ? tags : []} />}</Box>
</Box>
</Box>
</g_modal_gallery_context.Provider>
<Modal active={modalGalleryState.active}>
<Gallery
onClose={handleGalleryClose}
items={modalGalleryState.items}
current_item={modalGalleryState.current_item}
/>
</Modal>
</>
);
}
@ -147,8 +172,8 @@ const theme = createMuiTheme({
},
});
export function MainPage() {
// TODO: ProvideDB should be put in a context like the modal gallery is.
return (
<ThemeProvider theme={theme}>
<ProvideDB

@ -89,14 +89,6 @@ export const MatchTypeEnum = {
MATCH_TAG_NAME_EQUALS: 10, // Match on the local tag name (excluding parents)
}
/*
export const ResultTypeEnum = {
IMAGE: 1,
ALBUM: 2,
TAG: 3,
}
*/
export class ResultFilter {
to_sql_where() { return "(1=1)"; }

Loading…
Cancel
Save