From 3c1fcca98665e374ac0a66c4ea4565bbe9ce9d61 Mon Sep 17 00:00:00 2001 From: Matchu Date: Thu, 10 Aug 2023 17:15:07 -0700 Subject: [PATCH] Remove next/router references Once again, not really tested, but we don't have the same errors as before so! --- app/javascript/wardrobe-2020/ItemPage.js | 17 ++--- .../ItemPage/SpeciesFacesPicker.js | 6 +- .../wardrobe-2020/WardrobePage/ItemsPanel.js | 4 +- .../wardrobe-2020/WardrobePage/index.js | 52 +--------------- .../AppearanceLayerSupportUploadModal.js | 7 +-- .../WardrobePage/useOutfitSaving.js | 9 +-- .../WardrobePage/useOutfitState.js | 62 ++++--------------- .../components/PaginationToolbar.js | 17 ++--- .../components/SquareItemCard.js | 1 - config/routes.rb | 3 +- 10 files changed, 44 insertions(+), 134 deletions(-) diff --git a/app/javascript/wardrobe-2020/ItemPage.js b/app/javascript/wardrobe-2020/ItemPage.js index dd80b2e6..0d655421 100644 --- a/app/javascript/wardrobe-2020/ItemPage.js +++ b/app/javascript/wardrobe-2020/ItemPage.js @@ -56,13 +56,13 @@ import useCurrentUser from "./components/useCurrentUser"; import SpeciesFacesPicker, { colorIsBasic, } from "./ItemPage/SpeciesFacesPicker"; -import { useRouter } from "next/router"; -import Head from "next/head"; -function ItemPage() { - const { query } = useRouter(); - return ; -} +// Removed for the wardrobe-2020 case. +// TODO: Refactor this stuff, do we even need ItemPageContent really? +// function ItemPage() { +// const { query } = useRouter(); +// return ; +// } /** * ItemPageContent is the content of ItemPage, but we also use it as the @@ -102,11 +102,6 @@ export function ItemPageContent({ itemId, isEmbedded = false }) { return ( <> - {!isEmbedded && item?.name && ( - - {item?.name} | Dress to Impress - - )} - {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */} + {/* eslint-disable-next-line jsx-a11y/alt-text */} )} @@ -416,7 +416,7 @@ function CrossFadeImage(incomingImageProps) { opacity: 1; `} > - {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */} + {/* eslint-disable-next-line jsx-a11y/alt-text */} - {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */} + {/* eslint-disable-next-line jsx-a11y/alt-text */} sendDeleteOutfitMutation({ variables: { id } }) .then(() => { - pushHistory(`/your-outfits`); + window.location = "/your-outfits"; }) .catch((e) => { /* handled in error UI */ diff --git a/app/javascript/wardrobe-2020/WardrobePage/index.js b/app/javascript/wardrobe-2020/WardrobePage/index.js index 4798bf8f..4ace189c 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/index.js +++ b/app/javascript/wardrobe-2020/WardrobePage/index.js @@ -1,6 +1,5 @@ import React from "react"; import { useToast } from "@chakra-ui/react"; -import { useRouter } from "next/router"; import { emptySearchQuery } from "./SearchToolbar"; import ItemsAndSearchPanels from "./ItemsAndSearchPanels"; @@ -30,8 +29,9 @@ function WardrobePage() { // We manage outfit saving up here, rather than at the point of the UI where // "Saving" indicators appear. That way, auto-saving still happens even when - // the indicator isn't on the page, e.g. when searching. We also mount a - // in this component to prevent navigating away before saving. + // the indicator isn't on the page, e.g. when searching. + // NOTE: This only applies to navigations leaving the wardrobe-2020 app, not + // within! const outfitSaving = useOutfitSaving(outfitState, dispatchToOutfit); // TODO: I haven't found a great place for this error UI yet, and this case @@ -86,20 +86,6 @@ function WardrobePage() { - {/* - * TODO: This might unnecessarily block navigations that we don't - * necessarily need to, e.g., navigating back to Your Outfits while the - * save request is in flight. We could instead submit the save mutation - * immediately on client-side nav, and have each outfit save mutation - * install a `beforeunload` handler that ensures that you don't close - * the page altogether while it's in flight. But let's start simple and - * see how annoying it actually is in practice lol - */} - - { - const handleWindowClose = (e) => { - if (!when) return; - e.preventDefault(); - return (e.returnValue = message); - }; - const handleBrowseAway = () => { - if (!when) return; - if (window.confirm(message)) return; - router.events.emit("routeChangeError"); - throw "routeChange aborted by ."; - }; - window.addEventListener("beforeunload", handleWindowClose); - router.events.on("routeChangeStart", handleBrowseAway); - return () => { - window.removeEventListener("beforeunload", handleWindowClose); - router.events.off("routeChangeStart", handleBrowseAway); - }; - }, [when, message, router]); - - return null; -} - export default WardrobePage; diff --git a/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js b/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js index 8e730562..fe0f8cb2 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js +++ b/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js @@ -292,7 +292,6 @@ function AppearanceLayerSupportReviewStep({ marginTop="2" > {imageWithAlphaUrl && ( - // eslint-disable-next-line @next/next/no-img-element { @@ -175,7 +176,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) { // It's important that this callback _doesn't_ change when the outfit // changes, so that the auto-save effect is only responding to the // debounced state! - [sendSaveOutfitMutation, pathname, pushHistory, toast] + [sendSaveOutfitMutation, pathname, navigate, toast] ); const saveOutfit = React.useCallback( diff --git a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js index c137763a..5d26c4f9 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js +++ b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js @@ -4,7 +4,6 @@ import produce, { enableMapSet } from "immer"; import { useQuery, useApolloClient } from "@apollo/client"; import { itemAppearanceFragment } from "../components/useOutfitAppearance"; -import { useRouter } from "next/router"; enableMapSet(); @@ -382,25 +381,26 @@ const EMPTY_CUSTOMIZATION_STATE = { }; function useParseOutfitUrl() { - const { query } = useRouter(); + const [searchParams] = useSearchParams(); // We memoize this to make `outfitStateWithoutExtras` an even more reliable // stable object! const memoizedOutfitState = React.useMemo( - () => readOutfitStateFromQuery(query), + () => readOutfitStateFromSearchParams(searchParams), [query] ); return memoizedOutfitState; } -export function readOutfitStateFromQuery(query) { +function readOutfitStateFromSearchParams(searchParams) { // For the /outfits/:id page, ignore the query string, and just wait for the // outfit data to load in! - if (query.outfitId != null) { + const outfitId = searchParams.get("outfitId"); + if (outfitId != null) { return { ...EMPTY_CUSTOMIZATION_STATE, - id: query.outfitId, + id: outfitId, }; } @@ -408,52 +408,16 @@ export function readOutfitStateFromQuery(query) { // not specified. return { id: null, - name: getValueFromQuery(query.name), - speciesId: getValueFromQuery(query.species) || "1", - colorId: getValueFromQuery(query.color) || "8", - pose: getValueFromQuery(query.pose) || "HAPPY_FEM", - appearanceId: getValueFromQuery(query.state) || null, - wornItemIds: new Set(getListFromQuery(query["objects[]"])), - closetedItemIds: new Set(getListFromQuery(query["closet[]"])), + name: searchParams.get("name"), + speciesId: searchParams.get("species") || "1", + colorId: searchParams.get("color") || "8", + pose: searchParams.get("pose") || "HAPPY_FEM", + appearanceId: searchParams.get("state") || null, + wornItemIds: new Set(searchParams.getAll("objects[]")), + closetedItemIds: new Set(searchParams.getAll("closet[]")), }; } -/** - * getValueFromQuery reads the given value from Next's `router.query` as a - * single value. For example: - * - * ?foo=bar -> "bar" -> "bar" - * ?foo=bar&foo=baz -> ["bar", "baz"] -> "bar" - * ?lol=huh -> undefined -> null - */ -function getValueFromQuery(value) { - if (Array.isArray(value)) { - return value[0]; - } else if (value != null) { - return value; - } else { - return null; - } -} - -/** - * getListFromQuery reads the given value from Next's `router.query` as a list - * of values. For example: - * - * ?foo=bar -> "bar" -> ["bar"] - * ?foo=bar&foo=baz -> ["bar", "baz"] -> ["bar", "baz"] - * ?lol=huh -> undefined -> [] - */ -function getListFromQuery(value) { - if (Array.isArray(value)) { - return value; - } else if (value != null) { - return [value]; - } else { - return []; - } -} - function getOutfitStateFromOutfitData(outfit) { if (!outfit) { return EMPTY_CUSTOMIZATION_STATE; diff --git a/app/javascript/wardrobe-2020/components/PaginationToolbar.js b/app/javascript/wardrobe-2020/components/PaginationToolbar.js index bf600b45..4c7d45c1 100644 --- a/app/javascript/wardrobe-2020/components/PaginationToolbar.js +++ b/app/javascript/wardrobe-2020/components/PaginationToolbar.js @@ -1,6 +1,6 @@ import React from "react"; import { Box, Button, Flex, Select } from "@chakra-ui/react"; -import { useRouter } from "next/router"; +import { useSearchParams } from "react-router-dom"; function PaginationToolbar({ isLoading, @@ -72,9 +72,9 @@ function PaginationToolbar({ } export function useRouterPagination(totalCount, numPerPage) { - const { query, push: pushHistory } = useRouter(); + const [searchParams, setSearchParams] = useSearchParams(); - const currentOffset = parseInt(query.offset) || 0; + const currentOffset = parseInt(searchParams.get("offset")) || 0; const currentPageIndex = Math.floor(currentOffset / numPerPage); const currentPageNumber = currentPageIndex + 1; @@ -82,11 +82,12 @@ export function useRouterPagination(totalCount, numPerPage) { const buildPageUrl = React.useCallback( (newPageNumber) => { - const newParams = new URLSearchParams(query); - const newPageIndex = newPageNumber - 1; - const newOffset = newPageIndex * numPerPage; - newParams.set("offset", newOffset); - return "?" + newParams.toString(); + setSearchParams((newParams) => { + const newPageIndex = newPageNumber - 1; + const newOffset = newPageIndex * numPerPage; + newParams.set("offset", newOffset); + return newParams; + }); }, [query, numPerPage] ); diff --git a/app/javascript/wardrobe-2020/components/SquareItemCard.js b/app/javascript/wardrobe-2020/components/SquareItemCard.js index f4caf56b..f0530041 100644 --- a/app/javascript/wardrobe-2020/components/SquareItemCard.js +++ b/app/javascript/wardrobe-2020/components/SquareItemCard.js @@ -225,7 +225,6 @@ function ItemThumbnail({ item, tradeMatchingMode }) { position: relative; `} > - {/* eslint-disable-next-line @next/next/no-img-element */} {`Thumbnail [:new, :create], :path => 'neopets-users' end - get '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits + get '/your-outfits', to: 'outfits#index', as: :current_user_outfits + get '/users/current-user/outfits', to: redirect('/your-outfits') post '/pets/load' => 'pets#load', :as => :load_pet post '/pets/submit' => 'pets#submit', :method => :post