Skip to content

use loading state #485

Open
Open
@github-actions

Description

https://api.github.com/bangumi/frontend/blob/facb65f43ffc838c01204b888227d84aae49cdb1/packages/website/src/pages/index/group/reply/[id]/edit.tsx#L86

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;

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions