Inmemory caching with photoswipe on thumbnail.

This commit is contained in:
Pushkar Anand 2020-11-23 08:30:17 +05:30
parent a85ef0de9a
commit 6adc49cc2b
5 changed files with 79 additions and 19 deletions

View file

@ -9,7 +9,6 @@
"start": "next start"
},
"dependencies": {
"@types/localforage": "^0.0.34",
"axios": "^0.20.0",
"bootstrap": "^4.5.2",
"comlink": "^4.3.0",
@ -33,8 +32,10 @@
"devDependencies": {
"@next/bundle-analyzer": "^9.5.3",
"@types/libsodium-wrappers": "^0.7.8",
"@types/localforage": "^0.0.34",
"@types/node": "^14.6.4",
"@types/react": "^16.9.49",
"@types/react-photoswipe": "^1.3.0",
"@types/react-window": "^1.8.2",
"@types/react-window-infinite-loader": "^1.0.3",
"@types/styled-components": "^5.1.3",

View file

@ -1,20 +1,22 @@
import React, { useEffect, useState } from 'react';
import { file, getPreview } from 'services/fileService';
import { getActualKey } from 'utils/common/key';
import { getData, LS_KEYS } from 'utils/storage/localStorage';
import styled from 'styled-components';
interface IProps {
data: file,
updateUrl: (url: string) => void,
onClick: () => void,
}
const Cont = styled.div`
const Cont = styled.div<{ disabled: boolean }>`
background: #555 url(/image.svg) no-repeat center;
margin: 0 4px;
display: inline-block;
width: 192px;
height: 192px;
overflow: hidden;
cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
& > img {
object-fit: cover;
@ -25,22 +27,28 @@ const Cont = styled.div`
export default function PreviewCard(props: IProps) {
const [imgSrc, setImgSrc] = useState<string>();
const { data } = props;
const { data, onClick, updateUrl } = props;
useEffect(() => {
if (data) {
if (data && !data.src) {
const main = async () => {
const token = getData(LS_KEYS.USER).token;
const key = await getActualKey();
const url = await getPreview(token, data);
setImgSrc(url);
data.src = url;
updateUrl(url);
}
main();
}
}, [data]);
return <Cont>
<img src={imgSrc} />
const handleClick = () => {
if (data.src || imgSrc) {
onClick();
}
}
return <Cont onClick={handleClick} disabled={!data.src && !imgSrc}>
<img src={data.src || imgSrc} />
</Cont>;
}

View file

@ -7,7 +7,8 @@ import { getData, LS_KEYS } from 'utils/storage/localStorage';
import PreviewCard from './components/PreviewCard';
import { getActualKey } from 'utils/common/key';
import styled from 'styled-components';
import { PhotoSwipeGallery } from 'react-photoswipe';
import { PhotoSwipe } from 'react-photoswipe';
import { Options } from 'photoswipe';
import AutoSizer from 'react-virtualized-auto-sizer';
import { FixedSizeList as List } from 'react-window';
@ -36,7 +37,10 @@ export default function Gallery() {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [data, setData] = useState<file[]>();
const [total, setTotal] = useState(1);
const [open, setOpen] = useState(false);
const [options, setOptions] = useState<Options>({
history: false,
});
useEffect(() => {
const key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
@ -49,7 +53,11 @@ export default function Gallery() {
const encryptionKey = await getActualKey();
const resp = await getFiles("0", token, "100", encryptionKey);
setLoading(false);
setData(resp);
setData(resp.map(item => ({
...item,
w: window.innerWidth,
h: window.innerHeight,
})));
};
main();
}, []);
@ -60,8 +68,32 @@ export default function Gallery() {
</div>
}
const getThumbnail = (item) => (
<PreviewCard data={item} />
const updateUrl = (index: number) => (url: string) => {
data[index] = {
...data[index],
src: url,
}
setData(data);
}
const handleClose = () => {
setOpen(false);
}
const onThumbnailClick = (index: number) => () => {
setOptions({
...options,
index,
});
setOpen(true);
}
const getThumbnail = (data: file[], index: number) => (
<PreviewCard
data={data[index]}
updateUrl={updateUrl(index)}
onClick={onThumbnailClick(index)}
/>
)
return (<Container>
@ -75,14 +107,20 @@ export default function Gallery() {
>
{({ index, style }) => <ListItem style={style}>
{getThumbnail(data[index * 5])}
{getThumbnail(data[index * 5 + 1])}
{getThumbnail(data[index * 5 + 2])}
{getThumbnail(data[index * 5 + 3])}
{getThumbnail(data[index * 5 + 4])}
{getThumbnail(data, index * 5)}
{getThumbnail(data, index * 5 + 1)}
{getThumbnail(data, index * 5 + 2)}
{getThumbnail(data, index * 5 + 3)}
{getThumbnail(data, index * 5 + 4)}
</ListItem>}
</List>
)}
</AutoSizer>
<PhotoSwipe
isOpen={open}
items={data}
options={options}
onClose={handleClose}
/>
</Container>);
}

View file

@ -1,3 +1,3 @@
export const getEndpoint = () => {
return process.env.NEXT_PUBLIC_ENTE_ENDPOINT || "https://api.staging.ente.io";
return process.env.NEXT_PUBLIC_ENTE_ENDPOINT || "https://api.ente.io";
}

View file

@ -1149,6 +1149,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.4.tgz#a145cc0bb14ef9c4777361b7bbafa5cf8e3acb5a"
integrity sha512-Wk7nG1JSaMfMpoMJDKUsWYugliB2Vy55pdjLpmLixeyMi7HizW2I/9QoxsPCkXl3dO+ZOVqPumKaDUv5zJu2uQ==
"@types/photoswipe@*":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@types/photoswipe/-/photoswipe-4.1.0.tgz#212ad2b05d67828b24d424a01cb6fbb0735d37db"
integrity sha512-SWcWlJH8exQ/yijUNQn5pJdSrcsfPwyBmksBPa4NLNaUr4rhaC7YOGcrNSoIAC9LByoEbTIKWQpFVtHjomTTLA==
"@types/prop-types@*", "@types/prop-types@^15.7.3":
version "15.7.3"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
@ -1161,6 +1166,14 @@
dependencies:
"@types/react" "*"
"@types/react-photoswipe@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@types/react-photoswipe/-/react-photoswipe-1.3.0.tgz#c22948d540e7febe541f9a96742110b566105026"
integrity sha512-HqOyG+N1Ifjs3xd88bxGQbxv+ookIs94L/JPpYvcnkb1UMc7nBtEcCNvQ9QPB+eiFFG72z/uqA0poagRl0nopA==
dependencies:
"@types/photoswipe" "*"
"@types/react" "*"
"@types/react-transition-group@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"