manually manage filter and sort storage
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							@@ -3,5 +3,5 @@
 | 
			
		||||
- [ ] tags
 | 
			
		||||
- [ ] photo stories/collection pages
 | 
			
		||||
- [ ] 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
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,6 @@
 | 
			
		||||
    "react-div-100vh": "^0.7.0",
 | 
			
		||||
    "react-dom": "^17.0.1",
 | 
			
		||||
    "react-helmet": "^6.1.0",
 | 
			
		||||
    "react-use-query-param-string": "^2.0.3",
 | 
			
		||||
    "sass": "^1.34.0",
 | 
			
		||||
    "tailwindcss": "^2.1.2",
 | 
			
		||||
    "use-breakpoint": "^2.0.1"
 | 
			
		||||
 
 | 
			
		||||
@@ -21,26 +21,6 @@ const MasonryGallery = ({
 | 
			
		||||
 | 
			
		||||
  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(
 | 
			
		||||
    () => R.map(getAspectRatio, images),
 | 
			
		||||
    [images]
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,6 @@ import { Picker, Item } from "@adobe/react-spectrum";
 | 
			
		||||
 | 
			
		||||
import MasonryGallery from "../../components/MasonryGallery";
 | 
			
		||||
import KeywordsPicker from "../../components/KeywordsPicker";
 | 
			
		||||
import { useQueryParamString } from "react-use-query-param-string";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
 | 
			
		||||
const SORT_KEYS = {
 | 
			
		||||
  hue: ["fields", "imageMeta", "vibrantHue"],
 | 
			
		||||
@@ -17,46 +15,100 @@ const SORT_KEYS = {
 | 
			
		||||
  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 [keyword, _setKeyword] = useQueryParamString("filter", null);
 | 
			
		||||
  const [showDebug, _setShowDebug] = useQueryParamString("debug", false);
 | 
			
		||||
  const [sortKey, _setSortKey] = useState("rating");
 | 
			
		||||
  const [keyword, _setKeyword] = React.useState(null);
 | 
			
		||||
  const [sortKey, _setSortKey] = React.useState("rating");
 | 
			
		||||
  const showDebug =
 | 
			
		||||
    typeof window !== "undefined" &&
 | 
			
		||||
    window.location.search.includes("debug=true");
 | 
			
		||||
 | 
			
		||||
  const setKeyword = React.useCallback(
 | 
			
		||||
    (keyword) => {
 | 
			
		||||
    (newKeyword) => {
 | 
			
		||||
      try {
 | 
			
		||||
        window.plausible("Filter Keyword", {
 | 
			
		||||
          props: { keyword },
 | 
			
		||||
          props: { keyword: newKeyword },
 | 
			
		||||
        });
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        // do nothing
 | 
			
		||||
      }
 | 
			
		||||
      _setKeyword(keyword);
 | 
			
		||||
      _setKeyword(newKeyword);
 | 
			
		||||
      localStorage?.setItem("photogallery.keyword", newKeyword);
 | 
			
		||||
      window.history.replaceState(null, "", getUrl({ keyword: newKeyword }));
 | 
			
		||||
    },
 | 
			
		||||
    [_setKeyword]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const setSortKey = React.useCallback(
 | 
			
		||||
    (key) => {
 | 
			
		||||
    (newSortKey) => {
 | 
			
		||||
      try {
 | 
			
		||||
        window.plausible("Sort Gallery", {
 | 
			
		||||
          props: { key },
 | 
			
		||||
          props: { key: newSortKey },
 | 
			
		||||
        });
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        // do nothing
 | 
			
		||||
      }
 | 
			
		||||
      localStorage?.setItem("photogallery.sortkey2", key);
 | 
			
		||||
      _setSortKey(key);
 | 
			
		||||
      _setSortKey(newSortKey);
 | 
			
		||||
      localStorage?.setItem("photogallery.sortkey2", newSortKey);
 | 
			
		||||
      window.history.replaceState(null, "", getUrl({ sortKey: newSortKey }));
 | 
			
		||||
    },
 | 
			
		||||
    [_setSortKey]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  React.useEffect(() => {
 | 
			
		||||
    const _sortKey = localStorage.getItem("photogallery.sortkey2");
 | 
			
		||||
    if (_sortKey) {
 | 
			
		||||
      setSortKey(_sortKey);
 | 
			
		||||
    const url = new URL(window.location.toString());
 | 
			
		||||
 | 
			
		||||
    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(
 | 
			
		||||
    () =>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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"
 | 
			
		||||
    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:
 | 
			
		||||
  version "0.2.0"
 | 
			
		||||
  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"
 | 
			
		||||
    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:
 | 
			
		||||
  version "17.0.2"
 | 
			
		||||
  resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user