manually manage filter and sort storage
This commit is contained in:
parent
8e62eca18a
commit
8ac3dd27dd
2
TODO.md
2
TODO.md
@ -3,5 +3,5 @@
|
|||||||
- [ ] tags
|
- [ ] tags
|
||||||
- [ ] photo stories/collection pages
|
- [ ] photo stories/collection pages
|
||||||
- [ ] typescript (w/ graphql codegen)
|
- [ ] typescript (w/ graphql codegen)
|
||||||
- [ ] gallery sort and filter preserved in url (use-query or whatever?)
|
- [x] gallery sort and filter preserved in url (use-query or whatever?)
|
||||||
- [ ] nav next/prev buttons use saved gallery sort and filter
|
- [ ] nav next/prev buttons use saved gallery sort and filter
|
||||||
|
@ -61,7 +61,6 @@
|
|||||||
"react-div-100vh": "^0.7.0",
|
"react-div-100vh": "^0.7.0",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-use-query-param-string": "^2.0.3",
|
|
||||||
"sass": "^1.34.0",
|
"sass": "^1.34.0",
|
||||||
"tailwindcss": "^2.1.2",
|
"tailwindcss": "^2.1.2",
|
||||||
"use-breakpoint": "^2.0.1"
|
"use-breakpoint": "^2.0.1"
|
||||||
|
@ -21,26 +21,6 @@ const MasonryGallery = ({
|
|||||||
|
|
||||||
const { breakpoint } = useBreakpoint(breakpoints, "sm");
|
const { breakpoint } = useBreakpoint(breakpoints, "sm");
|
||||||
|
|
||||||
const scrollIntoView = React.useCallback(() => {
|
|
||||||
if (!window.location.hash) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const el = document.getElementById(window.location.hash.split("#")[1]);
|
|
||||||
if (!el) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.scrollIntoView({
|
|
||||||
block: "center",
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
// hacky but it works for now
|
|
||||||
setTimeout(() => {
|
|
||||||
scrollIntoView();
|
|
||||||
}, 100);
|
|
||||||
}, [scrollIntoView]);
|
|
||||||
|
|
||||||
const aspectRatios = React.useMemo(
|
const aspectRatios = React.useMemo(
|
||||||
() => R.map(getAspectRatio, images),
|
() => R.map(getAspectRatio, images),
|
||||||
[images]
|
[images]
|
||||||
|
@ -7,8 +7,6 @@ import { Picker, Item } from "@adobe/react-spectrum";
|
|||||||
|
|
||||||
import MasonryGallery from "../../components/MasonryGallery";
|
import MasonryGallery from "../../components/MasonryGallery";
|
||||||
import KeywordsPicker from "../../components/KeywordsPicker";
|
import KeywordsPicker from "../../components/KeywordsPicker";
|
||||||
import { useQueryParamString } from "react-use-query-param-string";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
const SORT_KEYS = {
|
const SORT_KEYS = {
|
||||||
hue: ["fields", "imageMeta", "vibrantHue"],
|
hue: ["fields", "imageMeta", "vibrantHue"],
|
||||||
@ -17,46 +15,100 @@ const SORT_KEYS = {
|
|||||||
date: [],
|
date: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getUrl = ({ keyword, sortKey }) => {
|
||||||
|
const url = new URL(window.location.toString());
|
||||||
|
if (keyword !== undefined) {
|
||||||
|
if (keyword === null) {
|
||||||
|
url.searchParams.delete("filter");
|
||||||
|
} else {
|
||||||
|
url.searchParams.set("filter", keyword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortKey !== undefined) {
|
||||||
|
if (sortKey === "rating") {
|
||||||
|
url.searchParams.delete("sort");
|
||||||
|
} else {
|
||||||
|
url.searchParams.set("sort", sortKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url.toString();
|
||||||
|
};
|
||||||
|
|
||||||
const GalleryPage = ({ data }) => {
|
const GalleryPage = ({ data }) => {
|
||||||
const [keyword, _setKeyword] = useQueryParamString("filter", null);
|
const [keyword, _setKeyword] = React.useState(null);
|
||||||
const [showDebug, _setShowDebug] = useQueryParamString("debug", false);
|
const [sortKey, _setSortKey] = React.useState("rating");
|
||||||
const [sortKey, _setSortKey] = useState("rating");
|
const showDebug =
|
||||||
|
typeof window !== "undefined" &&
|
||||||
|
window.location.search.includes("debug=true");
|
||||||
|
|
||||||
const setKeyword = React.useCallback(
|
const setKeyword = React.useCallback(
|
||||||
(keyword) => {
|
(newKeyword) => {
|
||||||
try {
|
try {
|
||||||
window.plausible("Filter Keyword", {
|
window.plausible("Filter Keyword", {
|
||||||
props: { keyword },
|
props: { keyword: newKeyword },
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
_setKeyword(keyword);
|
_setKeyword(newKeyword);
|
||||||
|
localStorage?.setItem("photogallery.keyword", newKeyword);
|
||||||
|
window.history.replaceState(null, "", getUrl({ keyword: newKeyword }));
|
||||||
},
|
},
|
||||||
[_setKeyword]
|
[_setKeyword]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSortKey = React.useCallback(
|
const setSortKey = React.useCallback(
|
||||||
(key) => {
|
(newSortKey) => {
|
||||||
try {
|
try {
|
||||||
window.plausible("Sort Gallery", {
|
window.plausible("Sort Gallery", {
|
||||||
props: { key },
|
props: { key: newSortKey },
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
localStorage?.setItem("photogallery.sortkey2", key);
|
_setSortKey(newSortKey);
|
||||||
_setSortKey(key);
|
localStorage?.setItem("photogallery.sortkey2", newSortKey);
|
||||||
|
window.history.replaceState(null, "", getUrl({ sortKey: newSortKey }));
|
||||||
},
|
},
|
||||||
[_setSortKey]
|
[_setSortKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const _sortKey = localStorage.getItem("photogallery.sortkey2");
|
const url = new URL(window.location.toString());
|
||||||
if (_sortKey) {
|
|
||||||
setSortKey(_sortKey);
|
const sortKeyFromUrl = url.searchParams.get("sort");
|
||||||
|
const sortKeyFromStorage = localStorage.getItem("photogallery.sortkey2");
|
||||||
|
if (sortKeyFromUrl || sortKeyFromStorage) {
|
||||||
|
setSortKey(sortKeyFromUrl || sortKeyFromStorage);
|
||||||
}
|
}
|
||||||
}, [setSortKey]);
|
|
||||||
|
const filterKeyFromUrl = url.searchParams.get("filter");
|
||||||
|
const filterKeyFromStorage = localStorage.getItem("photogallery.keyword");
|
||||||
|
if (filterKeyFromUrl || filterKeyFromStorage !== "null") {
|
||||||
|
setKeyword(filterKeyFromUrl || filterKeyFromStorage);
|
||||||
|
}
|
||||||
|
}, [setSortKey, setKeyword]);
|
||||||
|
|
||||||
|
const scrollIntoView = React.useCallback(() => {
|
||||||
|
if (!window.location.hash) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = document.getElementById(window.location.hash.split("#")[1]);
|
||||||
|
if (!el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.scrollIntoView({
|
||||||
|
block: "center",
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
// hacky but it works for now
|
||||||
|
setTimeout(() => {
|
||||||
|
// don't scroll into view if user got here with back button
|
||||||
|
scrollIntoView();
|
||||||
|
}, 100);
|
||||||
|
}, [scrollIntoView]);
|
||||||
|
|
||||||
const images = React.useMemo(
|
const images = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
17
yarn.lock
17
yarn.lock
@ -12282,16 +12282,6 @@ query-string@^6.13.8, query-string@^6.14.1:
|
|||||||
split-on-first "^1.0.0"
|
split-on-first "^1.0.0"
|
||||||
strict-uri-encode "^2.0.0"
|
strict-uri-encode "^2.0.0"
|
||||||
|
|
||||||
query-string@^7.1.1:
|
|
||||||
version "7.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1"
|
|
||||||
integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==
|
|
||||||
dependencies:
|
|
||||||
decode-uri-component "^0.2.0"
|
|
||||||
filter-obj "^1.1.0"
|
|
||||||
split-on-first "^1.0.0"
|
|
||||||
strict-uri-encode "^2.0.0"
|
|
||||||
|
|
||||||
querystring@0.2.0:
|
querystring@0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||||
@ -12481,13 +12471,6 @@ react-transition-group@^4.4.2:
|
|||||||
loose-envify "^1.4.0"
|
loose-envify "^1.4.0"
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
|
|
||||||
react-use-query-param-string@^2.0.3:
|
|
||||||
version "2.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-use-query-param-string/-/react-use-query-param-string-2.0.3.tgz#e1b986f9c49c5b9caad7a6a1c3c5a8f0bb841483"
|
|
||||||
integrity sha512-6rAimAH+IL0Ghq9EDs0Ywg0E51eeT1Uo6wY+JbwUEQvLiKfMKY8lsHlEqLtEj6udnVFUA4kEspGf2LBxpiknVw==
|
|
||||||
dependencies:
|
|
||||||
query-string "^7.1.1"
|
|
||||||
|
|
||||||
react@^17.0.1:
|
react@^17.0.1:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user