selectable photos

This commit is contained in:
2022-04-30 21:59:08 +02:00
committed by Stepan Usatiuk
parent dfe14eac39
commit 5b64a420bd
4 changed files with 52 additions and 21 deletions

View File

@@ -31,15 +31,33 @@ export interface IOverviewComponentProps {
fetchPhotos: () => void; fetchPhotos: () => void;
} }
const PhotoCardM = React.memo(PhotoCard);
export const OverviewComponent: React.FunctionComponent< export const OverviewComponent: React.FunctionComponent<
IOverviewComponentProps IOverviewComponentProps
> = (props) => { > = (props) => {
const [selectedPhoto, setSelectedPhoto] = React.useState<number>(0); const [selectedPhoto, setSelectedPhoto] = React.useState<number>(0);
const [isOverlayOpened, setOverlayOpen] = React.useState<boolean>(false); const [isOverlayOpened, setOverlayOpen] = React.useState<boolean>(false);
const [selectedPhotos, setSelectedPhotos] = React.useState<Set<number>>(
const onCardClick = (id: number) => { new Set(),
setSelectedPhoto(id); );
setOverlayOpen(true); const selectedPhotosRef = React.useRef<Set<number>>(selectedPhotos);
selectedPhotosRef.current = selectedPhotos;
const onCardClick = (e: React.MouseEvent<HTMLElement>, id: number) => {
if (e.ctrlKey) {
const newSelectedPhotos = new Set<number>([
...selectedPhotosRef.current,
]);
if (newSelectedPhotos.has(id)) {
newSelectedPhotos.delete(id);
} else {
newSelectedPhotos.add(id);
}
setSelectedPhotos(newSelectedPhotos);
} else {
setSelectedPhoto(id);
setOverlayOpen(true);
}
}; };
if ( if (
@@ -73,6 +91,10 @@ export const OverviewComponent: React.FunctionComponent<
{}, {},
); );
const onClick = React.useCallback((e: React.MouseEvent<HTMLElement>) => {
onCardClick(e, Number(e.currentTarget.id));
}, []);
const photos = Object.keys(dates).reduce( const photos = Object.keys(dates).reduce(
(acc: JSX.Element[], year): JSX.Element[] => { (acc: JSX.Element[], year): JSX.Element[] => {
const els = Object.keys(dates[year]).reduce( const els = Object.keys(dates[year]).reduce(
@@ -85,10 +107,12 @@ export const OverviewComponent: React.FunctionComponent<
); );
const photosEls = photos.map((photo) => { const photosEls = photos.map((photo) => {
return ( return (
<PhotoCard <PhotoCardM
key={photo.id} selected={selectedPhotos.has(photo.id)}
key={"p" + photo.id}
id={String(photo.id)}
photo={photo} photo={photo}
onClick={() => onCardClick(photo.id)} onClick={onClick}
/> />
); );
}); });

View File

@@ -2,6 +2,10 @@
img { img {
transition: all 0.3s; transition: all 0.3s;
} }
.selected {
padding: 1rem;
border-radius: 1.5rem;
}
.notLoaded { .notLoaded {
opacity: 0; opacity: 0;
@@ -10,4 +14,5 @@
.loaded { .loaded {
opacity: 1; opacity: 1;
} }
} }

View File

@@ -20,10 +20,12 @@ import { LargeSize, PreviewSize } from "./helper";
export interface IPhotoCardComponentProps extends RouteComponentProps { export interface IPhotoCardComponentProps extends RouteComponentProps {
photo: IPhotoReqJSON; photo: IPhotoReqJSON;
selected: boolean;
id: string;
deletePhoto: (photo: IPhotoReqJSON) => void; deletePhoto: (photo: IPhotoReqJSON) => void;
cancelDelete: (photo: IPhotoReqJSON) => void; cancelDelete: (photo: IPhotoReqJSON) => void;
onClick: () => void; onClick: (e: React.MouseEvent<HTMLElement>) => void;
} }
export interface IPhotoCardComponentState { export interface IPhotoCardComponentState {
@@ -73,12 +75,18 @@ export class PhotoCardComponent extends React.PureComponent<
<Card <Card
className="photoCard" className="photoCard"
interactive={true} interactive={true}
onClick={() => this.props.onClick()} id={this.props.id}
onClick={(e: React.MouseEvent<HTMLElement>) =>
this.props.onClick(e)
}
> >
{fileExists ? ( {fileExists ? (
<img <img
src={getPhotoThumbPath(this.props.photo, PreviewSize)} src={getPhotoThumbPath(this.props.photo, PreviewSize)}
className={this.state.loaded ? "loaded" : "notLoaded"} className={
(this.state.loaded ? "loaded " : "notLoaded ") +
(this.props.selected ? "selected " : " ")
}
onLoad={() => this.setLoaded(true)} onLoad={() => this.setLoaded(true)}
/* /*
onMouseEnter={() => onMouseEnter={() =>

View File

@@ -1,9 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"lib": [ "lib": ["es2017", "dom"],
"es2017",
"dom"
],
"jsx": "react", "jsx": "react",
"target": "es5", "target": "es5",
"module": "commonjs", "module": "commonjs",
@@ -17,11 +14,8 @@
"strictFunctionTypes": true, "strictFunctionTypes": true,
"strictNullChecks": true, "strictNullChecks": true,
"skipLibCheck": true, "skipLibCheck": true,
"isolatedModules": true "isolatedModules": true,
"downlevelIteration": true
}, },
"include": [ "include": ["./src/**/*.ts", "./src/**/*.tsx", "./jest.config.js"]
"./src/**/*.ts", }
"./src/**/*.tsx",
"./jest.config.js"
]
}