Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
.text {
font-size: 0.9em;
padding: 1em 0;
overflow: hidden;
}

.by {
Expand Down
52 changes: 5 additions & 47 deletions examples/hackernews/src/components/comment/index.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,21 @@
import React, { useEffect, useState } from 'react';
import { Link } from '@umijs/tnf/router';
import { fetchItem } from '../../services';
import { pluralize, timeAgo } from '../../utils';
import React, { Link } from '@umijs/tnf/router';
import type { CommentType } from '../../types';
import { timeAgo } from '../../utils';
import styles from './index.module.less';

interface CommentProps {
id: number;
}

interface CommentType {
by: string;
time: number;
text: string;
kids?: number[];
}
export default function Comment({ id }: CommentProps) {
const [open, setOpen] = useState(true);
const [comment, setComment] = useState<CommentType | null>(null);

useEffect(() => {
async function fetchComments() {
setComment(await fetchItem(id));
}

fetchComments();
}, []);

export default function Comment({ comment }: { comment: CommentType }) {
if (!comment) return null;

return (
<div className={styles.normal}>
<div className={styles.by}>
<Link to={`/user/${comment.by}`}>{comment.by}</Link>
<span>{` ${timeAgo(comment.time)} ago`}</span>
{comment.kids ? (
<span>
{' '}
|{' '}
<a
href=""
className={styles.expand}
onClick={(e) => {
e.preventDefault();
setOpen(!open);
}}
>
{`${open ? 'collapse' : 'expand'} ${pluralize(comment.kids.length)}`}
</a>
</span>
) : null}
</div>
<div
className={styles.text}
dangerouslySetInnerHTML={{ __html: comment.text }}
/>
<div className={styles.commentChildren}>
{comment.kids && open
? comment.kids.map((id) => <Comment key={id} id={id} />)
: null}
</div>
</div>
);
}
4 changes: 2 additions & 2 deletions examples/hackernews/src/components/item-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styles from './index.module.less';

interface ItemListProps {
type: keyof Lists;
page: number;
page?: number;
maxPage: number;
items: ItemProps[];
}
Expand All @@ -21,7 +21,7 @@ interface Lists {
export default function ItemList({
type,
items,
page,
page = 1,
maxPage,
}: ItemListProps) {
return (
Expand Down
16 changes: 12 additions & 4 deletions examples/hackernews/src/components/item-page/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import React, { Link } from '@umijs/tnf/router';
import type { ItemProps } from '../../types';
import type { CommentType, ItemProps } from '../../types';
import { host, timeAgo } from '../../utils';
import Comment from '../comment';
import styles from './index.module.less';

export default function ItemPage({ item }: { item: ItemProps }) {
export default function ItemPage({
item,
comments,
}: {
item: ItemProps;
comments: CommentType[];
}) {
if (!item) return null;
return (
<>
Expand All @@ -26,8 +32,10 @@ export default function ItemPage({ item }: { item: ItemProps }) {
{item.kids ? `${item.descendants} comments` : 'No comments yet.'}
</p>
<div className={styles.commentChildren}>
{item.kids
? item.kids.map((id) => <Comment key={id} id={id} />)
{comments
? comments.map((item: CommentType) => (
<Comment key={item.id} comment={item} />
))
: null}
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions examples/hackernews/src/components/item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function Item({ item }: ItemProps) {
<span className={styles.host}> ({host(url)})</span>
</span>
) : (
<Link to={`/item/$id`} params={{ id }}>
<Link to={`/item/$itemId`} params={{ itemId: id }}>
{title}
</Link>
)}
Expand All @@ -49,7 +49,7 @@ export default function Item({ item }: ItemProps) {
{type !== 'job' ? (
<span className={styles.commentsLink}>
<span>{' | '}</span>
<Link to={`/item/$id`} params={{ id }}>
<Link to={`/item/$itemId`} params={{ itemId: id }}>
{descendants} comments
</Link>
</span>
Expand Down
55 changes: 19 additions & 36 deletions examples/hackernews/src/pages/__root.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Fragment } from 'react';
import React, { Link, Outlet, createRootRoute } from '@umijs/tnf/router';
import '../global.less';
import styles from './index.module.less';
Expand All @@ -15,43 +16,25 @@ export const Route = createRootRoute({
src="https://zos.alipayobjects.com/rmsportal/AsASAiphPWWUJWG.png"
/>
</Link>
<Link
activeProps={{ className: styles['active'] }}
to="/top/$page"
params={{ page: 1 }}
>
Top
</Link>
<Link
activeProps={{ className: styles['active'] }}
to="/new/$page"
params={{ page: 1 }}
>
New
</Link>
<Link
activeProps={{ className: styles['active'] }}
to="/show/$page"
params={{ page: 1 }}
>
Show
</Link>
<Link
activeProps={{ className: styles['active'] }}
to="/ask/$page"
params={{ page: 1 }}
>
Ask
</Link>
<Link
activeProps={{ className: styles['active'] }}
to="/job/$page"
params={{ page: 1 }}
>
Jobs
</Link>
{(
[
['/top/$page', 'Top'],
['/new/$page', 'New'],
['/show/$page', 'Show'],
['/ask/$page', 'Ask'],
['/job/$page', 'Jobs'],
] as const
).map(([to, label]) => {
return (
<Fragment key={to}>
<Link to={to} preload="intent" params={{ page: 1 }}>
{label}
</Link>
</Fragment>
);
})}
<span className={styles.github}>
Built with{' '}
Built with
<a
rel="noopener noreferrer"
href="https://github.com/umijs/tnf"
Expand Down
12 changes: 8 additions & 4 deletions examples/hackernews/src/pages/item.$itemId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { fetchItem } from '../services';

export const Route = createFileRoute('/item/$itemId')({
component: Item,
loader: async ({ params }: { params: { itemId: string } }) =>
await fetchItem(params.itemId),
loader: async ({ params }: { params: { itemId: string } }) => {
const item = await fetchItem(params.itemId);
const commentPromises = item.kids.map(async (id) => await fetchItem(id));
const comments = await Promise.all(commentPromises);
return { item, comments };
},
});

function Item() {
const item = Route.useLoaderData();
return <ItemPage item={item} />;
const { item, comments } = Route.useLoaderData();
return <ItemPage item={item} comments={comments} />;
}
8 changes: 8 additions & 0 deletions examples/hackernews/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ export interface ItemProps {
kids?: number[];
}

export interface CommentType {
id: number;
by: string;
time: number;
text: string;
kids?: number[];
}

export interface FetchListResult {
items: ItemProps[];
maxPage: number;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"pathe": "^1.1.2",
"picocolors": "^1.1.1",
"random-color": "^1.0.1",
"react": "19.0.0-rc-02c0e824-20241028",
"react-dom": "19.0.0-rc-02c0e824-20241028",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sirv": "^3.0.0",
"spdy": "^4.0.2",
"yargs-parser": "^21.1.1",
Expand Down
Loading
Loading