-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Trim21 <[email protected]>
- Loading branch information
Showing
6 changed files
with
160 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { ok } from 'oazapfts'; | ||
import type { KeyedMutator } from 'swr'; | ||
import useSWR from 'swr'; | ||
|
||
import { ozaClient } from '@bangumi/client'; | ||
|
||
export interface UseGroupPostRet { | ||
data: ozaClient.GroupReply; | ||
mutate: KeyedMutator<ozaClient.GroupReply>; | ||
} | ||
|
||
function useGroupPost(id: number): UseGroupPostRet { | ||
const { data, mutate } = useSWR(`/group/post/${id}`, async () => ok(ozaClient.getGroupPost(id)), { | ||
suspense: true, | ||
}); | ||
return { data, mutate }; | ||
} | ||
|
||
export default useGroupPost; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
import { Outlet } from 'react-router-dom'; | ||
|
||
import ErrorBoundary from '@bangumi/website/components/ErrorBoundary'; | ||
|
||
const GroupReplyPage = () => ( | ||
<ErrorBoundary fallback={{ 404: <>数据库中没有查询到指定话题,话题可能正在审核或已被删除。</> }}> | ||
<Outlet /> | ||
</ErrorBoundary> | ||
); | ||
|
||
export default GroupReplyPage; |
14 changes: 14 additions & 0 deletions
14
packages/website/src/pages/index/group/reply/[id]/edit.module.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.form { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1rem; | ||
} | ||
|
||
.tipText { | ||
display: block; | ||
margin-bottom: 10px; | ||
} | ||
|
||
.topicLink { | ||
padding: 0 10px; | ||
} |
96 changes: 96 additions & 0 deletions
96
packages/website/src/pages/index/group/reply/[id]/edit.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import type { TopicDetail } from 'packages/client/client'; | ||
import React, { useState } from 'react'; | ||
import { useNavigate, useParams } from 'react-router-dom'; | ||
import { useSWRConfig } from 'swr'; | ||
|
||
import { ozaClient } from '@bangumi/client'; | ||
import { EditorForm, toast, Typography } from '@bangumi/design'; | ||
import useGroupPost from '@bangumi/website/hooks/use-group-post'; | ||
import { useUser } from '@bangumi/website/hooks/use-user'; | ||
|
||
import styles from './edit.module.less'; | ||
|
||
const EditReplyPage = () => { | ||
const { id } = useParams(); | ||
if (!id || Number.isNaN(parseInt(id))) { | ||
throw new Error('参数错误:post ID'); | ||
} | ||
const postId = parseInt(id); | ||
|
||
const { user } = useUser(); | ||
if (!user) { | ||
throw new Error('抱歉,当前操作需要登录后才能继续进行'); | ||
} | ||
|
||
const { data, mutate } = useGroupPost(postId); | ||
if (data.creator.id !== user.id) { | ||
throw new Error('抱歉,你只能修改自己发表的帖子。'); | ||
} | ||
|
||
const { mutate: mutateTopic } = useSWRConfig(); | ||
const navigate = useNavigate(); | ||
|
||
const [sending, setSending] = useState(false); | ||
const [content, setContent] = useState(data.text); | ||
|
||
const handleSubmit = async (text: string) => { | ||
if (!text) { | ||
toast('请填写回复内容', { type: 'error' }); | ||
return; | ||
} | ||
setSending(true); | ||
const response = await ozaClient.editGroupPost(postId, { text }); | ||
if (response.status === 200) { | ||
const topicPath = `/group/topic/${data.topicID}`; | ||
// 确保再次回到此页面时内容是最新的,不需要向后端请求数据,因此将 revalidate 设置为 false | ||
mutate({ ...data, text }, { revalidate: false }); | ||
// 乐观更新回复内容 | ||
await mutateTopic(topicPath, (topic?: TopicDetail) => { | ||
if (!topic) { | ||
return topic; | ||
} | ||
const reply = topic.replies.find((reply) => reply.id === postId); | ||
if (reply) { | ||
reply.text = text; | ||
} | ||
return topic; | ||
}); | ||
navigate(topicPath); | ||
} else { | ||
console.error(response); | ||
toast(response.data.message, { type: 'error' }); | ||
} | ||
setSending(false); | ||
}; | ||
|
||
return ( | ||
<> | ||
<Typography.Text type='secondary' className={styles.tipText}> | ||
修改主题 | ||
<Typography.Link | ||
to={`/group/topic/${data.topicID}`} | ||
fontWeight='bold' | ||
className={styles.topicLink} | ||
> | ||
{data.topicTitle} | ||
</Typography.Link> | ||
的回复 | ||
</Typography.Text> | ||
<div className={styles.form}> | ||
<EditorForm | ||
placeholder='回复内容…' | ||
hideCancel | ||
value={content} | ||
onChange={setContent} | ||
onConfirm={handleSubmit} | ||
// TODO: use loading state | ||
confirmText={sending ? '...' : undefined} | ||
rows={15} | ||
/> | ||
</div> | ||
{/* TODO: add right column */} | ||
</> | ||
); | ||
}; | ||
|
||
export default EditReplyPage; |