Skip to content

Commit

Permalink
Merge pull request #1360 from hotate29/swr
Browse files Browse the repository at this point in the history
`UserProblemListPage`の`react-refetch`を置き換える
  • Loading branch information
kenkoooo authored Oct 15, 2023
2 parents 7eaec11 + 0e606b0 commit dd95540
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 64 deletions.
1 change: 0 additions & 1 deletion atcoder-problems-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"react-helmet": "6.1.0",
"react-icons": "4.2.0",
"react-measure": "2.5.2",
"react-refetch": "4.0.0-0",
"react-router-dom": "5.1.2",
"react-scripts": "4.0.1",
"reactstrap": "8.2.0",
Expand Down
6 changes: 6 additions & 0 deletions atcoder-problems-frontend/src/api/InternalAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ export const useRecentContests = () => {
typeCastFetcher<VirtualContestInfo[]>(url)
);
};

export const useMyList = () => {
return useSWRData(`${BASE_URL}/list/my`, (url) =>
typeCastFetcher<ProblemList[]>(url)
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { connect, PromiseState } from "react-refetch";
import React, { useState } from "react";
import {
Alert,
Expand All @@ -16,62 +15,54 @@ import {
Row,
Spinner,
} from "reactstrap";
import { Link, Redirect } from "react-router-dom";
import { LIST_CREATE, LIST_DELETE, LIST_MY } from "./ApiUrl";
import { ProblemList } from "./types";
import { Link, useHistory } from "react-router-dom";
import { useMyList } from "../../api/InternalAPIClient";
import { LIST_CREATE, LIST_DELETE } from "./ApiUrl";

interface Props {
myListFetch: PromiseState<ProblemList[] | null>;
createListFetch: PromiseState<{ internal_list_id: string } | null>;
createNewList: () => void;
deleteList: (internalListId: string) => void;
deleteResponse: PromiseState<unknown | null>;
interface CreateListResponse {
internal_list_id: string;
}

export const UserProblemListPage = connect<unknown, Props>(() => ({
myListFetch: LIST_MY,
createListFetch: { value: null },
createNewList: () => ({
createListFetch: {
url: LIST_CREATE,
method: "POST",
body: JSON.stringify({ list_name: "New List" }),
},
}),
deleteList: (internalListId: string) => ({
deleteResponse: {
url: LIST_DELETE,
method: "POST",
body: JSON.stringify({ internal_list_id: internalListId }),
andThen: () => ({
myListFetch: {
url: LIST_MY,
refreshing: true,
force: true,
},
}),
},
}),
deleteResponse: { value: null },
}))((props) => {
const { createListFetch, myListFetch } = props;
if (createListFetch.fulfilled && createListFetch.value !== null) {
const listId = createListFetch.value.internal_list_id;
return <Redirect to={`/problemlist/${listId}`} />;
const createNewList = () =>
fetch(LIST_CREATE, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ list_name: "New List" }),
})
.then((response) => response.json())
.then((response) => response as CreateListResponse);

const deleteList = (internalListId: string) =>
fetch(LIST_DELETE, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ internal_list_id: internalListId }),
});

export const UserProblemListPage: React.FC = () => {
const history = useHistory();
const myListFetch = useMyList();

if (myListFetch.error) {
return <Alert color="danger">Failed to fetch list info.</Alert>;
}
if (myListFetch.pending) {
if (!myListFetch.data) {
return <Spinner style={{ width: "3rem", height: "3rem" }} />;
} else if (myListFetch.rejected || !myListFetch.value) {
return <Alert color="danger">Failed to fetch list info.</Alert>;
}

const myList = myListFetch.value;
const myList = myListFetch.data ?? [];

return (
<>
<Row className="my-2">
<Col sm="12">
<Button color="success" onClick={(): void => props.createNewList()}>
<Button
color="success"
onClick={async () => {
const internalListId = (await createNewList()).internal_list_id;
history.push({ pathname: `/problemlist/${internalListId}` });
}}
>
Create New List
</Button>
</Col>
Expand All @@ -86,15 +77,18 @@ export const UserProblemListPage = connect<unknown, Props>(() => ({
internalListId={internal_list_id}
internalListName={internal_list_name}
listItemCount={items.length}
deleteList={props.deleteList}
deleteList={async (internalListId) => {
await deleteList(internalListId);
await myListFetch.mutate();
}}
/>
))}
</ListGroup>
</Col>
</Row>
</>
);
});
};

interface SingleListEntryProps {
internalListId: string;
Expand Down
16 changes: 0 additions & 16 deletions atcoder-problems-frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6818,13 +6818,6 @@ internmap@^1.0.0:
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==

invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"

ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
Expand Down Expand Up @@ -10651,15 +10644,6 @@ react-redux@^7.2.0:
prop-types "^15.7.2"
react-is "^16.13.1"

[email protected]:
version "4.0.0-0"
resolved "https://registry.yarnpkg.com/react-refetch/-/react-refetch-4.0.0-0.tgz#4bdc6c69f36f84d49be7010deb54bc13c0455aff"
integrity sha512-xTzCklbbNURYgDiqK5xF1BeFQT54JCKYl8MP5q+cHqLSLAXjNTfy8P1+XTK4pbAneu+gmFhJ7IM9SZiZ27zPZw==
dependencies:
hoist-non-react-statics "^3.3.0"
invariant "^2.2.4"
warning "^4.0.3"

react-refresh@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
Expand Down

0 comments on commit dd95540

Please sign in to comment.