| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- import { useEffect, useState } from "react";
- import { Divider, message, Result, Tag } from "antd";
- import { get, post } from "../../request";
- import store from "../../store";
- import { IArticleDataResponse, IArticleResponse } from "../api/Article";
- import ArticleView from "./ArticleView";
- import { ICourseCurrUserResponse } from "../api/Course";
- import { ICourseUser, signIn } from "../../reducers/course-user";
- import { ITextbook, refresh } from "../../reducers/current-course";
- import ExerciseList from "./ExerciseList";
- import ExerciseAnswer from "../course/ExerciseAnswer";
- import "./article.css";
- import CommentListCard from "../comment/CommentListCard";
- import TocTree from "./TocTree";
- import PaliText from "../template/Wbw/PaliText";
- import ArticleSkeleton from "./ArticleSkeleton";
- import {
- IViewRequest,
- IViewStoreResponse,
- } from "../../pages/studio/recent/list";
- import { modeChange } from "../../reducers/article-mode";
- export type ArticleMode = "read" | "edit" | "wbw";
- export type ArticleType =
- | "article"
- | "chapter"
- | "para"
- | "cs-para"
- | "sent"
- | "sim"
- | "page"
- | "textbook"
- | "exercise"
- | "exercise-list"
- | "sent-original"
- | "sent-commentary"
- | "sent-nissaya"
- | "sent-translation"
- | "term";
- /**
- * 每种article type 对应的路由参数
- * article/id?anthology=id&channel=id1,id2&mode=ArticleMode
- * chapter/book-para?channel=id1,id2&mode=ArticleMode
- * para/book?par=para1,para2&channel=id1,id2&mode=ArticleMode
- * cs-para/book-para?channel=id1,id2&mode=ArticleMode
- * sent/id?channel=id1,id2&mode=ArticleMode
- * sim/id?channel=id1,id2&mode=ArticleMode
- * textbook/articleId?course=id&mode=ArticleMode
- * exercise/articleId?course=id&exercise=id&username=name&mode=ArticleMode
- * exercise-list/articleId?course=id&exercise=id&mode=ArticleMode
- * sent-original/id
- */
- interface IWidgetArticle {
- type?: ArticleType;
- id?: string;
- book?: string | null;
- para?: string | null;
- channelId?: string | null;
- articleId?: string;
- anthologyId?: string;
- courseId?: string;
- exerciseId?: string;
- userName?: string;
- mode?: ArticleMode | null;
- active?: boolean;
- onArticleChange?: Function;
- onFinal?: Function;
- }
- const ArticleWidget = ({
- type,
- id,
- book,
- para,
- channelId,
- articleId,
- anthologyId,
- courseId,
- exerciseId,
- userName,
- mode = "read",
- active = false,
- onArticleChange,
- onFinal,
- }: IWidgetArticle) => {
- const [articleData, setArticleData] = useState<IArticleDataResponse>();
- const [articleMode, setArticleMode] = useState<ArticleMode>();
- const [extra, setExtra] = useState(<></>);
- const [showSkeleton, setShowSkeleton] = useState(true);
- const [unauthorized, setUnauthorized] = useState(false);
- const channels = channelId?.split("_");
- useEffect(() => {
- /**
- * 由课本进入查询当前用户的权限和channel
- */
- if (
- type === "textbook" ||
- type === "exercise" ||
- type === "exercise-list"
- ) {
- if (typeof articleId !== "undefined") {
- const id = articleId.split("_");
- get<ICourseCurrUserResponse>(`/v2/course-curr?course_id=${id[0]}`).then(
- (response) => {
- console.log("course user", response);
- if (response.ok) {
- const it: ICourseUser = {
- channelId: response.data.channel_id,
- role: response.data.role,
- };
- store.dispatch(signIn(it));
- /**
- * redux发布课程信息
- */
- const ic: ITextbook = {
- courseId: id[0],
- articleId: id[1],
- };
- store.dispatch(refresh(ic));
- }
- }
- );
- }
- }
- }, [articleId, type]);
- useEffect(() => {
- setArticleMode(mode ? mode : "read");
- //发布mode变更
- console.log("发布mode变更", mode);
- store.dispatch(modeChange(mode as ArticleMode));
- }, [mode]);
- useEffect(() => {
- console.log("mode", mode, articleMode);
- if (!active) {
- return;
- }
- if (mode === articleMode) {
- return;
- }
- //发布mode变更
- //store.dispatch(modeChange(mode));
- if (
- (mode === "edit" && articleMode === "wbw") ||
- (mode === "wbw" && articleMode === "edit")
- ) {
- console.log("set mode", mode, articleMode);
- setArticleMode(mode ? mode : "read");
- return;
- }
- setArticleMode(mode ? mode : "read");
- if (typeof type !== "undefined") {
- let url = "";
- switch (type) {
- case "chapter":
- if (typeof articleId !== "undefined") {
- url = `/v2/corpus-chapter/${articleId}?mode=${mode}`;
- url += channelId ? `&channels=${channelId}` : "";
- }
- break;
- case "para":
- url = `/v2/corpus?view=para&book=${book}&par=${para}&mode=${mode}`;
- url += channelId ? `&channels=${channelId}` : "";
- break;
- case "article":
- if (typeof articleId !== "undefined") {
- url = `/v2/article/${articleId}?mode=${mode}`;
- url += channelId ? `&channel=${channelId}` : "";
- url += anthologyId ? `&anthology=${anthologyId}` : "";
- }
- break;
- case "textbook":
- if (typeof articleId !== "undefined") {
- url = `/v2/article/${articleId}?view=textbook&course=${courseId}&mode=${mode}`;
- }
- break;
- case "exercise":
- if (typeof articleId !== "undefined") {
- url = `/v2/article/${articleId}?mode=${mode}&course=${courseId}&exercise=${exerciseId}&user=${userName}`;
- setExtra(
- <ExerciseAnswer
- courseId={courseId}
- articleId={articleId}
- exerciseId={exerciseId}
- />
- );
- }
- break;
- case "exercise-list":
- if (typeof articleId !== "undefined") {
- url = `/v2/article/${articleId}?mode=${mode}&course=${courseId}&exercise=${exerciseId}`;
- setExtra(
- <ExerciseList
- courseId={courseId}
- articleId={articleId}
- exerciseId={exerciseId}
- />
- );
- }
- break;
- default:
- if (typeof articleId !== "undefined") {
- url = `/v2/corpus/${type}/${articleId}/${mode}?mode=${mode}`;
- url += channelId ? `&channel=${channelId}` : "";
- }
- break;
- }
- console.log("article url", url);
- setShowSkeleton(true);
- get<IArticleResponse>(url)
- .then((json) => {
- console.log("article", json);
- if (json.ok) {
- setArticleData(json.data);
- setShowSkeleton(false);
- setExtra(
- <TocTree
- treeData={json.data.toc?.map((item) => {
- const strTitle = item.title ? item.title : item.pali_title;
- const progress = item.progress?.map((item, id) => (
- <Tag key={id}>{Math.round(item * 100)}</Tag>
- ));
- return {
- key: `${item.book}-${item.paragraph}`,
- title: (
- <>
- <PaliText text={strTitle} />
- {progress}
- </>
- ),
- level: item.level,
- };
- })}
- onSelect={(keys: string[]) => {
- console.log(keys);
- if (
- typeof onArticleChange !== "undefined" &&
- keys.length > 0
- ) {
- onArticleChange(keys[0]);
- }
- }}
- />
- );
- switch (type) {
- case "chapter":
- if (typeof articleId === "string" && channelId) {
- const [book, para] = articleId?.split("-");
- post<IViewRequest, IViewStoreResponse>("/v2/view", {
- target_type: type,
- book: parseInt(book),
- para: parseInt(para),
- channel: channelId,
- mode: mode ? mode : "read",
- }).then((json) => {
- console.log("view", json.data);
- });
- }
- break;
- default:
- break;
- }
- } else {
- setShowSkeleton(false);
- setUnauthorized(true);
- message.error(json.message);
- }
- })
- .catch((e) => {
- console.error(e);
- });
- }
- }, [
- active,
- type,
- articleId,
- mode,
- articleMode,
- book,
- para,
- channelId,
- anthologyId,
- courseId,
- exerciseId,
- userName,
- ]);
- return (
- <div>
- {showSkeleton ? (
- <ArticleSkeleton />
- ) : unauthorized ? (
- <Result
- status="403"
- title="无权访问"
- subTitle="您无权访问该内容。您可能没有登录,或者内容的所有者没有给您所需的权限。"
- extra={<></>}
- />
- ) : (
- <ArticleView
- id={articleData?.uid}
- title={articleData?.title}
- subTitle={articleData?.subtitle}
- summary={articleData?.summary}
- content={articleData ? articleData.content : ""}
- html={articleData?.html}
- path={articleData?.path}
- created_at={articleData?.created_at}
- updated_at={articleData?.updated_at}
- channels={channels}
- type={type}
- articleId={articleId}
- />
- )}
- {extra}
- <Divider />
- <CommentListCard resId={articleData?.uid} resType="article" />
- </div>
- );
- };
- export default ArticleWidget;
|