always smooth image opening

This commit is contained in:
2020-12-13 19:22:45 +03:00
committed by Stepan Usatiuk
parent 08c83e7284
commit 019a206e05
5 changed files with 49 additions and 10 deletions

View File

@@ -26,6 +26,7 @@
object-fit: contain;
max-height: 100%;
max-width: 100%;
min-height: 100%;
width: auto;
height: auto;
box-shadow: $pt-elevation-shadow-4;

View File

@@ -1,7 +1,5 @@
@import "~@blueprintjs/core/lib/scss/variables";
.bp3-dark {
#photoView {}
}

View File

@@ -4,10 +4,15 @@ import { connect } from "react-redux";
import { Dispatch } from "redux";
import { IPhotoReqJSON } from "~../../src/entity/Photo";
import { LoadingStub } from "~LoadingStub";
import { getPhotoImgPath, getPhotoThumbPath } from "~redux/api/photos";
import {
fetchPhoto,
getPhotoImgPath,
getPhotoThumbPath,
} from "~redux/api/photos";
import { photoLoadStart } from "~redux/photos/actions";
import { IPhotoState } from "~redux/photos/reducer";
import { IAppState } from "~redux/reducers";
import { LargeSize, PreviewSize } from "./helper";
export interface IPhotoComponentProps {
id: number;
@@ -20,7 +25,36 @@ export interface IPhotoComponentProps {
export const PhotoComponent: React.FunctionComponent<IPhotoComponentProps> = (
props,
) => {
const [loaded, setLoaded] = React.useState<boolean>(false);
const [smallPreview, setSmallPreview] = React.useState<string | null>(null);
const [largePreview, setLargePreview] = React.useState<string | null>(null);
const [original, setOriginal] = React.useState<string | null>(null);
const imgRef = React.useRef<HTMLImageElement>(null);
React.useEffect(() => {
async function fetchSizes() {
if (props.photo && !smallPreview) {
const smallPreviewFetch = await fetch(
getPhotoThumbPath(props.photo, PreviewSize),
);
setSmallPreview(
URL.createObjectURL(await smallPreviewFetch.blob()),
);
}
if (props.photo && !largePreview) {
const largePreviewFetch = await fetch(
getPhotoThumbPath(props.photo, LargeSize),
);
setLargePreview(
URL.createObjectURL(await largePreviewFetch.blob()),
);
}
if (props.photo && !original) {
const originalFetch = await fetch(getPhotoImgPath(props.photo));
setOriginal(URL.createObjectURL(await originalFetch.blob()));
}
}
void fetchSizes();
});
if (!props.photo && !props.photoState?.fetching) {
props.fetchPhoto(props.id);
@@ -28,7 +62,6 @@ export const PhotoComponent: React.FunctionComponent<IPhotoComponentProps> = (
if (!props.photo) {
return <LoadingStub spinner={false} />;
}
const fileExists = props.photo.uploaded;
return (
@@ -36,10 +69,14 @@ export const PhotoComponent: React.FunctionComponent<IPhotoComponentProps> = (
{fileExists ? (
<div id="photoView">
<img
ref={imgRef}
id="photoImg"
className={loaded ? "loaded" : "notLoaded"}
onLoad={() => setLoaded(true)}
src={getPhotoThumbPath(props.photo, 2048)}
src={
original ||
largePreview ||
smallPreview ||
getPhotoThumbPath(props.photo, PreviewSize)
}
/>
</div>
) : (

View File

@@ -16,6 +16,7 @@ import { photoDeleteCancel, photoDeleteStart } from "~redux/photos/actions";
import { connect } from "react-redux";
import { LoadingStub } from "~LoadingStub";
import { RouteComponentProps, withRouter } from "react-router";
import { LargeSize, PreviewSize } from "./helper";
export interface IPhotoCardComponentProps extends RouteComponentProps {
photo: IPhotoReqJSON;
@@ -76,12 +77,12 @@ export class PhotoCardComponent extends React.PureComponent<
>
{fileExists ? (
<img
src={getPhotoThumbPath(this.props.photo, 512)}
src={getPhotoThumbPath(this.props.photo, PreviewSize)}
className={this.state.loaded ? "loaded" : "notLoaded"}
onLoad={() => this.setLoaded(true)}
onMouseEnter={() =>
preloadImage(
getPhotoThumbPath(this.props.photo, 2048),
getPhotoThumbPath(this.props.photo, LargeSize),
)
}
></img>

View File

@@ -0,0 +1,2 @@
export const PreviewSize = 512;
export const LargeSize = 2048;