Skip to content

Commit

Permalink
Suspenseを細かく入れた
Browse files Browse the repository at this point in the history
  • Loading branch information
kgtkr committed Jan 24, 2024
1 parent 92b0ff2 commit 3c24c50
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 90 deletions.
89 changes: 44 additions & 45 deletions packages/client/src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ export function App(): JSX.Element {
}
setInitUserData(
await createUserData(
res.data.token as GA.TokenMasterFragment, // TODO: ここのキャストおかしい
),
res.data.token as GA.TokenMasterFragment // TODO: ここのキャストおかしい
)
);
} catch {
setInitUserData(null);
Expand Down Expand Up @@ -340,50 +340,49 @@ export function App(): JSX.Element {
/>
<Route component={pages.NotFoundPage} />
</Switch>

{location.state?.background ? (
<Route
path={routes.res.matcher()}
component={pages.ResModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.resReply.matcher()}
component={pages.ResReplyModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.profile.matcher()}
component={pages.ProfileModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicData.matcher()}
component={pages.TopicDataModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicFork.matcher()}
component={pages.TopicForkModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicEdit.matcher()}
component={pages.TopicEditModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.hash.matcher()}
component={pages.ResHashModal}
/>
) : null}
</React.Suspense>
{location.state?.background ? (
<Route
path={routes.res.matcher()}
component={pages.ResModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.resReply.matcher()}
component={pages.ResReplyModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.profile.matcher()}
component={pages.ProfileModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicData.matcher()}
component={pages.TopicDataModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicFork.matcher()}
component={pages.TopicForkModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.topicEdit.matcher()}
component={pages.TopicEditModal}
/>
) : null}
{location.state?.background ? (
<Route
path={routes.hash.matcher()}
component={pages.ResHashModal}
/>
) : null}
</div>
</div>
);
Expand Down
12 changes: 9 additions & 3 deletions packages/client/src/components/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Icon, IconButton } from "@mui/material";
import { CircularProgress, Icon, IconButton } from "@mui/material";
import React, { useState } from "react";
import * as style from "./page.module.scss";

Expand Down Expand Up @@ -33,7 +33,11 @@ export const Page: React.FC<PageProps> = ({
<IconButton onClick={() => setIsLeft(!isLeft)}>
<Icon>{isLeft ? "chevron_left" : "chevron_right"}</Icon>
</IconButton>
{isLeft ? sidebar : null}
{isLeft ? (
<React.Suspense fallback={<CircularProgress />}>
{sidebar}
</React.Suspense>
) : null}
</aside>
) : null}
<main
Expand All @@ -42,7 +46,9 @@ export const Page: React.FC<PageProps> = ({
}}
className={!disableScroll ? style.mainScroll : undefined}
>
{children}
<React.Suspense fallback={<CircularProgress />}>
{children}
</React.Suspense>
</main>
</div>
);
Expand Down
28 changes: 13 additions & 15 deletions packages/client/src/components/res.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import { Snack } from "./snack";
import { isNullish } from "../utils/isNullish";
import { useBackground } from "../hooks/useBackground";
import { NG, NGs, TextMatcher } from "../domains/entities/storage/NGs";
import {
useSetStorage,
usePrefixedStorageCollection,
} from "../domains/entities/storage/StorageCollectionHooks";
import { useSetStorage } from "../domains/entities/storage/StorageCollectionHooks";

function textMatcher(matcher: TextMatcher, text: string): boolean {
if (matcher.text.length === 0) {
Expand All @@ -26,7 +23,7 @@ function textMatcher(matcher: TextMatcher, text: string): boolean {
try {
return new RegExp(
matcher.text,
[matcher.ignoreCase ? "i" : ""].join(""),
[matcher.ignoreCase ? "i" : ""].join("")
).test(text);
} catch {
return false;
Expand Down Expand Up @@ -105,6 +102,7 @@ function isNG(ng: NG, res: GA.ResFragment): boolean {
interface ResProps {
res: GA.ResFragment;
update?: (res: GA.ResFragment) => void;
ngs: NG[];
}

export const Res = React.memo(function Res(props: ResProps) {
Expand All @@ -129,13 +127,13 @@ export const Res = React.memo(function Res(props: ResProps) {
};

const [submitVote] = GA.useVoteResMutation();
const ngs = usePrefixedStorageCollection(NGs);
const [addNG] = useSetStorage(NGs);
const ng = React.useMemo(
() => props.ngs.some((ng) => isNG(ng, props.res)),
[props.ngs, props.res]
);

return user.value !== null &&
!props.res.self &&
!disableNG &&
ngs.some((ng) => isNG(ng, props.res)) ? (
return user.value !== null && !props.res.self && !disableNG && ng ? (
<Paper>
あぼーん<a onClick={() => setDisableNG(true)}>[見る]</a>
</Paper>
Expand Down Expand Up @@ -246,7 +244,7 @@ export const Res = React.memo(function Res(props: ResProps) {
state: {
background,
},
},
}
)}
>
@{props.res.profile.sn}
Expand All @@ -256,7 +254,7 @@ export const Res = React.memo(function Res(props: ResProps) {
<Link
to={routes.res.to(
{ id: props.res.id, topic: props.res.topic.id },
{ state: { background } },
{ state: { background } }
)}
>
{dateFormat.format(props.res.date)}
Expand All @@ -269,7 +267,7 @@ export const Res = React.memo(function Res(props: ResProps) {
state: {
background,
},
},
}
)}
>
#{props.res.hash.substr(0, 6)}
Expand Down Expand Up @@ -357,7 +355,7 @@ export const Res = React.memo(function Res(props: ResProps) {
component={Link}
to={routes.res.to(
{ id: props.res.reply.id, topic: props.res.topic.id },
{ state: { background } },
{ state: { background } }
)}
style={small}
size="small"
Expand All @@ -371,7 +369,7 @@ export const Res = React.memo(function Res(props: ResProps) {
component={Link}
to={routes.resReply.to(
{ id: props.res.id, topic: props.res.topic.id },
{ state: { background } },
{ state: { background } }
)}
style={small}
size="small"
Expand Down
14 changes: 5 additions & 9 deletions packages/client/src/components/tags-input.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Chip, TextField, Autocomplete, Icon } from "@mui/material";
import * as React from "react";
import * as GA from "../generated/graphql-apollo";
import { Snack } from "./snack";
import {
useDeleteStorage,
useSetStorage,
Expand All @@ -16,29 +15,26 @@ export interface TagsInputProps {
}

export function TagsInput({ value, onChange, fullWidth }: TagsInputProps) {
// TODO: Suspenseが起きる範囲を狭くする
const favoTags = usePrefixedStorageCollection(FavoriteTags);
const tagsSet = React.useMemo(() => {
return new Set<string>([...favoTags.map((t) => t.tag)]);
}, [favoTags]);
const [deleteTag] = useDeleteStorage(FavoriteTags);
const [setTag] = useSetStorage(FavoriteTags);
const { data, loading, error } = GA.useFindTopicTagsQuery();
const { data, loading } = GA.useFindTopicTagsQuery();

if (loading) {
return <span>Loading...</span>;
}
if (error || !data) {
return <Snack msg="タグ候補取得に失敗しました" />;
}
// TODO: `useFindTopicTagsQuery` error handling

return (
<Autocomplete<string, true, undefined, true>
fullWidth={fullWidth}
placeholder="タグ"
freeSolo
multiple
options={data.topicTags.map((t) => t.name)}
options={data?.topicTags.map((t) => t.name) ?? []}
renderInput={(params) => <TextField {...params} placeholder="tag" />}
loading={loading}
renderTags={(value: string[], getTagProps) =>
value.map((option: string, index: number) => (
<Chip
Expand Down
8 changes: 5 additions & 3 deletions packages/client/src/pages/home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as routes from "@anontown-frontend/routes";
import { Tab, Tabs, Paper } from "@mui/material";
import { Tab, Tabs, Paper, CircularProgress } from "@mui/material";
import * as React from "react";
import { Helmet } from "react-helmet-async";
import { Link } from "react-router-dom";
Expand All @@ -20,8 +20,10 @@ export const HomePage = (_props: HomePageProps) => {
<Tab label="トピック" />
<Tab label="タグ" />
</Tabs>
{tabIndex === 0 ? <TopicFavo detail={true} /> : null}
{tabIndex === 1 ? <TagFavo /> : null}
<React.Suspense fallback={<CircularProgress />}>
{tabIndex === 0 ? <TopicFavo detail={true} /> : null}
{tabIndex === 1 ? <TagFavo /> : null}
</React.Suspense>
</div>
) : (
<Paper sx={{ p: 1 }}>
Expand Down
9 changes: 7 additions & 2 deletions packages/client/src/pages/notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import { RA, O } from "../prelude";
import { useRegisterSW } from "virtual:pwa-register/react";
import { Env } from "../env";
import { Snack } from "../components/snack";
import { usePrefixedStorageCollection } from "../domains/entities/storage/StorageCollectionHooks";
import { NGs } from "../domains/entities/storage/NGs";

type NotificationsPageProps = RouteComponentProps<{}> & UserSwitchProps;

export const NotificationsPage = userSwitch(
(_props: NotificationsPageProps) => {
const ngs = usePrefixedStorageCollection(NGs);
const [registration, setRegistration] = React.useState<
ServiceWorkerRegistration | undefined
>(undefined);
Expand Down Expand Up @@ -130,7 +133,9 @@ export const NotificationsPage = userSwitch(
</div>
<div>
{reses.data !== undefined
? reses.data.reses.map((r) => <Res res={r} key={r.id} />)
? reses.data.reses.map((r) => (
<Res res={r} key={r.id} ngs={ngs} />
))
: null}
</div>
<div>
Expand Down Expand Up @@ -173,5 +178,5 @@ export const NotificationsPage = userSwitch(
</div>
</Page>
);
},
}
);
7 changes: 6 additions & 1 deletion packages/client/src/pages/res-hash.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import { useTitle } from "react-use";
import { Page, Res, Snack } from "../components";
import * as GA from "../generated/graphql-apollo";
import { withModal } from "../utils";
import { usePrefixedStorageCollection } from "../domains/entities/storage/StorageCollectionHooks";
import { NGs } from "../domains/entities/storage/NGs";

function ResHashBase(_props: {}) {
const params = useParams<{ hash: string }>();
const hash = decodeURIComponent(params.hash);
const resesResult = GA.useFindResesQuery({ variables: { query: { hash } } });
const ngs = usePrefixedStorageCollection(NGs);
useTitle(`HASH:${hash}`);

return (
Expand All @@ -17,7 +20,9 @@ function ResHashBase(_props: {}) {
<Snack msg="レス取得に失敗しました" />
) : null}
{resesResult.data !== undefined
? resesResult.data.reses.map((res) => <Res res={res} key={res.id} />)
? resesResult.data.reses.map((res) => (
<Res res={res} key={res.id} ngs={ngs} />
))
: undefined}
</div>
);
Expand Down
5 changes: 4 additions & 1 deletion packages/client/src/pages/res-reply.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { useParams } from "react-router-dom";
import { Page, Res, Snack } from "../components";
import * as GA from "../generated/graphql-apollo";
import { withModal } from "../utils";
import { usePrefixedStorageCollection } from "../domains/entities/storage/StorageCollectionHooks";
import { NGs } from "../domains/entities/storage/NGs";

function ResReplyBase() {
const { id } = useParams<{ id: string }>();
const { loading, error, data } = GA.useFindResesQuery({
variables: { query: { reply: id } },
});
const ngs = usePrefixedStorageCollection(NGs);

return (
<div>
Expand All @@ -19,7 +22,7 @@ function ResReplyBase() {
) : (
<>
{data.reses.map((res) => (
<Res res={res} key={res.id} />
<Res res={res} key={res.id} ngs={ngs} />
))}
</>
)}
Expand Down
5 changes: 4 additions & 1 deletion packages/client/src/pages/res.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useParams } from "react-router-dom";
import { Page, Res, Snack } from "../components";
import * as GA from "../generated/graphql-apollo";
import { withModal } from "../utils";
import { usePrefixedStorageCollection } from "../domains/entities/storage/StorageCollectionHooks";
import { NGs } from "../domains/entities/storage/NGs";

interface ResBaseProps {
zDepth?: number;
Expand All @@ -14,6 +16,7 @@ function ResBase({ zDepth: _zDepth }: ResBaseProps) {
const { loading, error, data } = GA.useFindResesQuery({
variables: { query: { id: [id] } },
});
const ngs = usePrefixedStorageCollection(NGs);

return (
<div>
Expand All @@ -22,7 +25,7 @@ function ResBase({ zDepth: _zDepth }: ResBaseProps) {
{error || !data || data.reses.length === 0 ? (
<Snack msg="レス取得に失敗しました" />
) : (
<Res res={data.reses[0]} />
<Res res={data.reses[0]} ngs={ngs} />
)}
</div>
);
Expand Down
Loading

0 comments on commit 3c24c50

Please sign in to comment.