visuddhinanda 2 سال پیش
والد
کامیت
e76db476fb

+ 82 - 0
dashboard/src/components/discussion/DiscussionButton.tsx

@@ -0,0 +1,82 @@
+import { Space, Tooltip } from "antd";
+import store from "../../store";
+import { IShowDiscussion, show } from "../../reducers/discussion";
+import { openPanel } from "../../reducers/right-panel";
+import { CommentFillIcon, CommentOutlinedIcon } from "../../assets/icon";
+import { TResType } from "./DiscussionListCard";
+import { useAppSelector } from "../../hooks";
+import { currentUser } from "../../reducers/current-user";
+import { discussionList } from "../../reducers/discussion-count";
+
+interface IWidget {
+  initCount?: number;
+  resId?: string;
+  resType?: TResType;
+  hideCount?: boolean;
+  hideInZero?: boolean;
+  onlyMe?: boolean;
+}
+const DiscussionButton = ({
+  initCount = 0,
+  resId,
+  resType = "sentence",
+  hideCount = false,
+  hideInZero = false,
+  onlyMe = false,
+}: IWidget) => {
+  const user = useAppSelector(currentUser);
+  const discussions = useAppSelector(discussionList);
+
+  console.debug("discussions", discussions);
+
+  const all = discussions?.filter((value) => value.res_id === resId);
+  const my = all?.filter((value) => value.editor_uid === user?.id);
+  let currCount = initCount;
+  if (onlyMe) {
+    if (my) {
+      currCount = my.length;
+    } else {
+      currCount = 0;
+    }
+  } else {
+    if (all) {
+      currCount = all.length;
+    } else {
+      currCount = 0;
+    }
+  }
+
+  let myCount = false;
+  if (my && my.length > 0) {
+    myCount = true;
+  }
+
+  return hideInZero && currCount === 0 ? (
+    <></>
+  ) : (
+    <Tooltip title="讨论">
+      <Space
+        size={"small"}
+        style={{
+          cursor: "pointer",
+          color: currCount && currCount > 0 ? "#1890ff" : "unset",
+        }}
+        onClick={(event) => {
+          const data: IShowDiscussion = {
+            type: "discussion",
+            resId: resId,
+            resType: resType,
+          };
+          console.debug("discussion show", data);
+          store.dispatch(show(data));
+          store.dispatch(openPanel("discussion"));
+        }}
+      >
+        {myCount ? <CommentFillIcon /> : <CommentOutlinedIcon />}
+        {hideCount ? <></> : currCount}
+      </Space>
+    </Tooltip>
+  );
+};
+
+export default DiscussionButton;

+ 62 - 0
dashboard/src/components/discussion/DiscussionCount.tsx

@@ -0,0 +1,62 @@
+import { useEffect } from "react";
+import { useAppSelector } from "../../hooks";
+import { publish, upgrade } from "../../reducers/discussion-count";
+import { sentenceList } from "../../reducers/sentence";
+import {
+  IDiscussionCountRequest,
+  IDiscussionCountResponse,
+} from "../api/Comment";
+import { get, post } from "../../request";
+import store from "../../store";
+
+export const discussionCountUpgrade = (resId?: string) => {
+  if (typeof resId === "undefined") {
+    return;
+  }
+  const url = `/v2/discussion-count/${resId}`;
+  console.info("discussion-count api request", url);
+  get<IDiscussionCountResponse>(url).then((json) => {
+    console.debug("discussion-count api response", json);
+    if (json.ok) {
+      store.dispatch(upgrade({ resId: resId, data: json.data }));
+    } else {
+      console.error(json.message);
+    }
+  });
+};
+
+interface IWidget {
+  courseId?: string | null;
+}
+
+const DiscussionCount = ({ courseId }: IWidget) => {
+  const sentences = useAppSelector(sentenceList);
+
+  console.debug("sentences", sentences);
+
+  useEffect(() => {
+    const sentId: string[] = sentences
+      .filter((value) => typeof value.id != "undefined")
+      .map((item) => item.id);
+    if (sentId.length === 0) {
+      return;
+    }
+    const url = "/v2/discussion-count";
+    const data: IDiscussionCountRequest = {
+      course_id: courseId ?? undefined,
+      sentences: sentId.map((item) => item.split("-")),
+    };
+    console.info("discussion-count api request", url, data);
+    post<IDiscussionCountRequest, IDiscussionCountResponse>(url, data).then(
+      (json) => {
+        console.debug("discussion-count api response", json);
+        if (json.ok) {
+          store.dispatch(publish(json.data));
+        }
+      }
+    );
+  }, [courseId, sentences]);
+  return <></>;
+};
+
+export default DiscussionCount;

+ 41 - 0
dashboard/src/components/template/Wbw/WbwPaliDiscussionIcon.tsx

@@ -0,0 +1,41 @@
+import { useAppSelector } from "../../../hooks";
+import { courseUser } from "../../../reducers/course-user";
+import { currentUser } from "../../../reducers/current-user";
+import { IStudio } from "../../auth/Studio";
+import DiscussionButton from "../../discussion/DiscussionButton";
+import { IWbw } from "./WbwWord";
+
+interface IWidget {
+  data: IWbw;
+  studio?: IStudio;
+}
+const WbwPaliDiscussionIcon = ({ data, studio }: IWidget) => {
+  const userInCourse = useAppSelector(courseUser);
+  const currUser = useAppSelector(currentUser);
+
+  let onlyMe = false;
+  if (userInCourse) {
+    if (userInCourse.role === "student") {
+      if (studio?.id === currUser?.id) {
+        //我自己的wbw channel 显示全部
+        onlyMe = false;
+      } else {
+        //其他channel 只显示自己的
+        onlyMe = true;
+      }
+    }
+  }
+  console.debug("WbwPaliDiscussionIcon render", studio, data, onlyMe);
+  return (
+    <DiscussionButton
+      initCount={data.hasComment ? 1 : 0}
+      hideCount
+      hideInZero
+      onlyMe={onlyMe}
+      resId={data.uid}
+      resType="wbw"
+    />
+  );
+};
+
+export default WbwPaliDiscussionIcon;

+ 44 - 0
dashboard/src/reducers/discussion-count.ts

@@ -0,0 +1,44 @@
+/**
+ *
+ */
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+
+import type { RootState } from "../store";
+import { IDiscussionCountData } from "../components/api/Comment";
+
+export interface IUpgrade {
+  resId: string;
+  data: IDiscussionCountData[];
+}
+
+interface IState {
+  list: IDiscussionCountData[];
+}
+
+const initialState: IState = { list: [] };
+
+export const slice = createSlice({
+  name: "discussion-count",
+  initialState,
+  reducers: {
+    publish: (state, action: PayloadAction<IDiscussionCountData[]>) => {
+      console.debug("discussion-count publish", action.payload);
+      state.list = action.payload;
+    },
+    upgrade: (state, action: PayloadAction<IUpgrade>) => {
+      console.debug("discussion-count publish", action.payload);
+      const old = state.list.filter(
+        (value) => value.res_id !== action.payload.resId
+      );
+      state.list = [...old, ...action.payload.data];
+    },
+  },
+});
+
+export const { publish, upgrade } = slice.actions;
+
+export const discussionList = (
+  state: RootState
+): IDiscussionCountData[] | undefined => state.discussionCount.list;
+
+export default slice.reducer;