Skip to content

Commit

Permalink
useHydratedフックを追加し、コンテンツの読み込み中にスケルトンローディングを表示する機能を実装しました。また、不要なLoader…
Browse files Browse the repository at this point in the history
…2コンポーネントを削除しました。 (#541)
  • Loading branch information
ttizze authored Jan 28, 2025
2 parents 4019636 + 87c3a6a commit b6f0802
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 45 deletions.
15 changes: 15 additions & 0 deletions web/app/components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { cn } from "~/utils/cn";

function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("animate-pulse rounded-md bg-primary/10", className)}
{...props}
/>
);
}

export { Skeleton };
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useFetcher } from "@remix-run/react";
import { MoreVertical } from "lucide-react";
import { Loader2 } from "lucide-react";
import { useHydrated } from "remix-utils/use-hydrated";
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
import { Button } from "~/components/ui/button";
import {
Expand Down Expand Up @@ -33,7 +31,6 @@ export function PageCommentList({
locale,
}: CommentListProps) {
const fetcher = useFetcher();
const isHydrated = useHydrated();
return (
<div className="space-y-4">
{pageCommentsWithUser.map((pageComment) => (
Expand Down Expand Up @@ -87,26 +84,20 @@ export function PageCommentList({
</div>
</div>
<div className="mt-2 prose dark:prose-invert">
{!isHydrated ? (
<div className="w-full h-full flex items-center justify-center">
<Loader2 className="w-10 h-10 animate-spin" />
</div>
) : (
<MemoizedParsedContent
html={pageComment.content}
segmentWithTranslations={
pageComment.pageCommentSegmentsWithTranslations
}
currentHandle={currentHandle}
showOriginal={showOriginal}
showTranslation={showTranslation}
locale={locale}
voteIntent={VoteIntent.COMMENT_SEGMENT_TRANSLATION}
addTranslationFormIntent={
AddTranslationFormIntent.COMMENT_SEGMENT_TRANSLATION
}
/>
)}
<MemoizedParsedContent
html={pageComment.content}
segmentWithTranslations={
pageComment.pageCommentSegmentsWithTranslations
}
currentHandle={currentHandle}
showOriginal={showOriginal}
showTranslation={showTranslation}
locale={locale}
voteIntent={VoteIntent.COMMENT_SEGMENT_TRANSLATION}
addTranslationFormIntent={
AddTranslationFormIntent.COMMENT_SEGMENT_TRANSLATION
}
/>
</div>
</div>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import type { UserAITranslationInfo } from "@prisma/client";
import { Loader2 } from "lucide-react";
import { useHydrated } from "remix-utils/use-hydrated";
import { LocaleLink } from "~/components/LocaleLink";
import { TagList } from "~/components/TagList";
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
Expand Down Expand Up @@ -34,8 +32,6 @@ export function ContentWithTranslations({
showOriginal = true,
showTranslation = true,
}: ContentWithTranslationsProps) {
const isHydrated = useHydrated();

return (
<>
<h1 className="!mb-0 ">
Expand Down Expand Up @@ -92,24 +88,18 @@ export function ContentWithTranslations({
className="pt-3"
intent="translatePage"
/>
{!isHydrated ? (
<div className="w-full h-full flex items-center justify-center">
<Loader2 className="w-10 h-10 animate-spin" />
</div>
) : (
<MemoizedParsedContent
html={pageWithTranslations.page.content}
segmentWithTranslations={pageWithTranslations.segmentWithTranslations}
currentHandle={currentHandle}
showOriginal={showOriginal}
showTranslation={showTranslation}
locale={locale}
voteIntent={VoteIntent.PAGE_SEGMENT_TRANSLATION}
addTranslationFormIntent={
AddTranslationFormIntent.PAGE_SEGMENT_TRANSLATION
}
/>
)}
<MemoizedParsedContent
html={pageWithTranslations.page.content}
segmentWithTranslations={pageWithTranslations.segmentWithTranslations}
currentHandle={currentHandle}
showOriginal={showOriginal}
showTranslation={showTranslation}
locale={locale}
voteIntent={VoteIntent.PAGE_SEGMENT_TRANSLATION}
addTranslationFormIntent={
AddTranslationFormIntent.PAGE_SEGMENT_TRANSLATION
}
/>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import parse, {
type DOMNode,
} from "html-react-parser";
import { memo } from "react";
import { useHydrated } from "remix-utils/use-hydrated";
import { Skeleton } from "~/components/ui/skeleton";
import type { AddTranslationFormIntent } from "~/routes/resources+/add-translation-form/route";
import type { VoteIntent } from "~/routes/resources+/vote-buttons";
import type { SegmentWithTranslations } from "../types";
Expand Down Expand Up @@ -33,6 +35,20 @@ export function ParsedContent({
voteIntent,
addTranslationFormIntent,
}: ParsedContentProps) {
const isHydrated = useHydrated();
if (!isHydrated) {
return (
// Start of Selection
<div className="flex flex-col space-y-3 mt-5">
{Array.from({ length: 5 }).map(() => (
<Skeleton
key={Math.random().toString(36).substring(2, 9)}
className="w-full h-5"
/>
))}
</div>
);
}
const sanitizedContent = DOMPurify.sanitize(html);
const doc = new DOMParser().parseFromString(sanitizedContent, "text/html");

Expand Down

0 comments on commit b6f0802

Please sign in to comment.