@blocklet/discuss-kit 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,199 +0,0 @@
1
- "use strict";
2
- const PropTypes = require("prop-types");
3
- const Theme = require("@arcblock/ux/lib/Theme");
4
- const Box = require("@mui/material/Box");
5
- const clsx = require("clsx");
6
- const React = require("react");
7
- const Rating = require("./rating");
8
- const jsxRuntime = require("react/jsx-runtime");
9
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
10
- function _interopNamespace(e) {
11
- if (e && e.__esModule)
12
- return e;
13
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
14
- if (e) {
15
- for (const k in e) {
16
- if (k !== "default") {
17
- const d = Object.getOwnPropertyDescriptor(e, k);
18
- Object.defineProperty(n, k, d.get ? d : {
19
- enumerable: true,
20
- get: () => e[k]
21
- });
22
- }
23
- }
24
- }
25
- n.default = e;
26
- return Object.freeze(n);
27
- }
28
- const PropTypes__default = /* @__PURE__ */ _interopDefaultLegacy(PropTypes);
29
- const Box__default = /* @__PURE__ */ _interopDefaultLegacy(Box);
30
- const clsx__default = /* @__PURE__ */ _interopDefaultLegacy(clsx);
31
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
32
- const Rating__default = /* @__PURE__ */ _interopDefaultLegacy(Rating);
33
- const SvgThumbUp = (props) => /* @__PURE__ */ React__namespace.createElement("svg", {
34
- width: 32,
35
- height: 32,
36
- viewBox: "0 0 24 24",
37
- ...props
38
- }, /* @__PURE__ */ React__namespace.createElement("g", {
39
- fill: "none",
40
- stroke: "currentColor",
41
- strokeLinecap: "round",
42
- strokeWidth: 1.5
43
- }, /* @__PURE__ */ React__namespace.createElement("path", {
44
- d: "M16.472 20H4.1a.6.6 0 0 1-.6-.6V9.6a.6.6 0 0 1 .6-.6h2.768a2 2 0 0 0 1.715-.971l2.71-4.517a1.631 1.631 0 0 1 2.961 1.308l-1.022 3.408a.6.6 0 0 0 .574.772h4.575a2 2 0 0 1 1.93 2.526l-1.91 7A2 2 0 0 1 16.473 20Z"
45
- }), /* @__PURE__ */ React__namespace.createElement("path", {
46
- strokeLinejoin: "round",
47
- d: "M7 20V9"
48
- })));
49
- function BinaryThumb({
50
- variant,
51
- size,
52
- ...rest
53
- }) {
54
- const renderer = ({
55
- options,
56
- toggleRate
57
- }) => {
58
- return /* @__PURE__ */ jsxRuntime.jsx(Root, {
59
- children: options.map((option) => {
60
- const icon = option.value === -1 ? /* @__PURE__ */ jsxRuntime.jsx(SvgThumbUp, {
61
- style: {
62
- transform: "rotate(180deg)"
63
- }
64
- }) : /* @__PURE__ */ jsxRuntime.jsx(SvgThumbUp, {});
65
- return /* @__PURE__ */ jsxRuntime.jsx("div", {
66
- className: "reaction-item",
67
- children: /* @__PURE__ */ jsxRuntime.jsx(IconButton, {
68
- className: "reaction-item-btn",
69
- icon,
70
- text: option.count,
71
- selected: option.selected,
72
- onClick: () => toggleRate(option.value),
73
- variant,
74
- size
75
- })
76
- }, option.value);
77
- })
78
- });
79
- };
80
- return /* @__PURE__ */ jsxRuntime.jsx(Rating__default.default, {
81
- ratingType: "binary-thumb",
82
- values: [1, -1],
83
- ...rest,
84
- render: renderer
85
- });
86
- }
87
- BinaryThumb.propTypes = {
88
- variant: PropTypes__default.default.oneOf(["default", "inverse"]),
89
- size: PropTypes__default.default.oneOf(["sm", "lg"])
90
- };
91
- BinaryThumb.defaultProps = {
92
- variant: "default",
93
- size: "sm"
94
- };
95
- const Root = Theme.styled(Box__default.default)`
96
- display: flex;
97
- .reaction-item {
98
- display: flex;
99
- align-items: center;
100
- }
101
- `;
102
- function IconButton({
103
- icon,
104
- text,
105
- onClick,
106
- selected,
107
- variant,
108
- size,
109
- ...rest
110
- }) {
111
- const classes = clsx__default.default(rest.className, `reaction-btn-${size} reaction-btn-${variant}`, {
112
- "reaction-btn-selected": selected
113
- });
114
- return /* @__PURE__ */ jsxRuntime.jsxs(IconButtonRoot, {
115
- ...rest,
116
- className: classes,
117
- children: [/* @__PURE__ */ jsxRuntime.jsx("span", {
118
- className: "reaction-btn-icon",
119
- onClick,
120
- children: icon
121
- }), !!text && /* @__PURE__ */ jsxRuntime.jsx("span", {
122
- className: "reaction-btn-text",
123
- children: text
124
- })]
125
- });
126
- }
127
- IconButton.propTypes = {
128
- icon: PropTypes__default.default.node.isRequired,
129
- text: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]).isRequired,
130
- onClick: PropTypes__default.default.func.isRequired,
131
- selected: PropTypes__default.default.bool,
132
- variant: PropTypes__default.default.oneOf(["default", "inverse"]),
133
- size: PropTypes__default.default.oneOf(["sm", "lg"])
134
- };
135
- IconButton.defaultProps = {
136
- selected: false,
137
- variant: "default",
138
- size: "sm"
139
- };
140
- const IconButtonRoot = Theme.styled("div")`
141
- display: flex;
142
- align-items: center;
143
- &.reaction-btn-selected {
144
- color: ${(props) => props.theme.palette.primary.main};
145
- }
146
- .reaction-btn-icon {
147
- display: flex;
148
- line-height: 1;
149
- &:hover {
150
- cursor: pointer;
151
- }
152
- }
153
- svg {
154
- width: auto;
155
- }
156
- .reaction-btn-text {
157
- display: inline-block;
158
- }
159
- &.reaction-btn-sm {
160
- min-width: 64px;
161
- height: 18px;
162
- font-size: 12px;
163
- svg {
164
- height: 16px;
165
- }
166
- .reaction-btn-text {
167
- margin-left: 8px;
168
- }
169
- }
170
- &.reaction-btn-lg {
171
- min-width: 100px;
172
- font-size: 14px;
173
- .reaction-btn-icon {
174
- justify-content: center;
175
- align-items: center;
176
- width: 44px;
177
- height: 44px;
178
- border-radius: 8px;
179
- }
180
- svg {
181
- height: 20px;
182
- }
183
- .reaction-btn-text {
184
- margin-left: 12px;
185
- }
186
- }
187
- &.reaction-btn-inverse {
188
- .reaction-btn-icon {
189
- background-color: ${(props) => props.theme.palette.grey[200]};
190
- }
191
- &.reaction-btn-selected {
192
- .reaction-btn-icon {
193
- color: #fff;
194
- background-color: ${(props) => props.theme.palette.primary.main};
195
- }
196
- }
197
- }
198
- `;
199
- module.exports = BinaryThumb;
@@ -1,39 +0,0 @@
1
- "use strict";
2
- const PropTypes = require("prop-types");
3
- const Rating = require("./rating");
4
- const jsxRuntime = require("react/jsx-runtime");
5
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
6
- const PropTypes__default = /* @__PURE__ */ _interopDefaultLegacy(PropTypes);
7
- const Rating__default = /* @__PURE__ */ _interopDefaultLegacy(Rating);
8
- function EmojiBased({
9
- emojiValues
10
- }) {
11
- return /* @__PURE__ */ jsxRuntime.jsx(Rating__default.default, {
12
- ratingType: "emoji-based",
13
- children: /* @__PURE__ */ jsxRuntime.jsx("span", {
14
- children: emojiValues
15
- })
16
- });
17
- }
18
- EmojiBased.propTypes = {
19
- emojiValues: PropTypes__default.default.array
20
- };
21
- EmojiBased.defaultProps = {
22
- emojiValues: [{
23
- value: 5,
24
- emojicon: "\u{1F601}"
25
- }, {
26
- value: 4,
27
- emojicon: "\u{1F600}"
28
- }, {
29
- value: 3,
30
- emojicon: "\u{1F610}"
31
- }, {
32
- value: 2,
33
- emojicon: "\u{1F615}"
34
- }, {
35
- value: 1,
36
- emojicon: "\u{1F61E}"
37
- }]
38
- };
39
- module.exports = EmojiBased;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const binaryThumb = require("./binary-thumb");
4
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
5
- const binaryThumb__default = /* @__PURE__ */ _interopDefaultLegacy(binaryThumb);
6
- Object.defineProperty(exports, "BinaryThumb", {
7
- enumerable: true,
8
- get: () => binaryThumb__default.default
9
- });
@@ -1,93 +0,0 @@
1
- "use strict";
2
- const react = require("react");
3
- const PropTypes = require("prop-types");
4
- const useSetState = require("react-use/lib/useSetState");
5
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
6
- const PropTypes__default = /* @__PURE__ */ _interopDefaultLegacy(PropTypes);
7
- const useSetState__default = /* @__PURE__ */ _interopDefaultLegacy(useSetState);
8
- function Rating({
9
- ratingType,
10
- values,
11
- countPerValue,
12
- selected,
13
- render,
14
- onRate,
15
- onUnrate
16
- }) {
17
- const [state, setState] = useSetState__default.default({
18
- selected,
19
- countPerValue
20
- });
21
- const hasSelected = !!state.selected || state.selected === 0;
22
- const increaseCount = (value, inc) => {
23
- setState((prevState) => ({
24
- countPerValue: {
25
- ...prevState.countPerValue,
26
- [value]: (prevState.countPerValue[value] || 0) + inc
27
- }
28
- }));
29
- };
30
- react.useEffect(() => {
31
- setState({
32
- countPerValue,
33
- selected
34
- });
35
- }, [countPerValue, selected]);
36
- if (!render) {
37
- return null;
38
- }
39
- const options = values.map((value) => {
40
- var _a;
41
- return {
42
- value,
43
- count: ((_a = state.countPerValue) == null ? void 0 : _a[value]) || 0,
44
- selected: state.selected === value
45
- };
46
- });
47
- const toggleRate = async (value) => {
48
- try {
49
- if (state.selected === value) {
50
- await onUnrate({
51
- ratingType,
52
- value
53
- });
54
- increaseCount(value, -1);
55
- setState({
56
- selected: null
57
- });
58
- } else {
59
- await onRate({
60
- ratingType,
61
- value
62
- });
63
- if (hasSelected) {
64
- increaseCount(state.selected, -1);
65
- }
66
- increaseCount(value, 1);
67
- setState({
68
- selected: value
69
- });
70
- }
71
- } catch (e) {
72
- console.error("Failed to rate.", e);
73
- }
74
- };
75
- return render({
76
- options,
77
- toggleRate
78
- });
79
- }
80
- Rating.propTypes = {
81
- ratingType: PropTypes__default.default.oneOf(["binary-thumb", "five-star", "emoji-based"]).isRequired,
82
- values: PropTypes__default.default.arrayOf(PropTypes__default.default.number).isRequired,
83
- countPerValue: PropTypes__default.default.object,
84
- selected: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]),
85
- render: PropTypes__default.default.func.isRequired,
86
- onRate: PropTypes__default.default.func.isRequired,
87
- onUnrate: PropTypes__default.default.func.isRequired
88
- };
89
- Rating.defaultProps = {
90
- countPerValue: {},
91
- selected: void 0
92
- };
93
- module.exports = Rating;
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const react = require("react");
4
- const PropTypes = require("prop-types");
5
- const Session = require("@arcblock/did-connect/lib/Session");
6
- const hooks = require("./hooks");
7
- const getWsClient = require("./ws");
8
- const jsxRuntime = require("react/jsx-runtime");
9
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
10
- const PropTypes__default = /* @__PURE__ */ _interopDefaultLegacy(PropTypes);
11
- const getWsClient__default = /* @__PURE__ */ _interopDefaultLegacy(getWsClient);
12
- const CommentsContext = react.createContext();
13
- function CommentsProvider({
14
- prefix,
15
- session,
16
- object,
17
- manageMode,
18
- flatMode,
19
- children
20
- }) {
21
- var _a;
22
- const sessionCtx = react.useContext(Session.SessionContext);
23
- const _session = session || (sessionCtx == null ? void 0 : sessionCtx.session);
24
- const wsClient = getWsClient__default.default(prefix);
25
- const commentsState = hooks.useComments({
26
- objectId: object.id,
27
- flatMode
28
- }, [(_a = _session == null ? void 0 : _session.user) == null ? void 0 : _a.did]);
29
- react.useEffect(() => {
30
- wsClient.connect();
31
- return () => {
32
- if (wsClient.isConnected()) {
33
- wsClient.disconnect();
34
- }
35
- };
36
- }, []);
37
- const value = react.useMemo(
38
- () => ({
39
- session: _session,
40
- object,
41
- prefix,
42
- manageMode,
43
- flatMode,
44
- ...commentsState
45
- }),
46
- [_session, object, prefix, commentsState]
47
- );
48
- return /* @__PURE__ */ jsxRuntime.jsx(CommentsContext.Provider, {
49
- value,
50
- children
51
- });
52
- }
53
- CommentsProvider.propTypes = {
54
- prefix: PropTypes__default.default.string,
55
- session: PropTypes__default.default.object,
56
- object: PropTypes__default.default.PropTypes.shape({
57
- id: PropTypes__default.default.string.isRequired,
58
- title: PropTypes__default.default.string,
59
- desc: PropTypes__default.default.string,
60
- owner: PropTypes__default.default.string
61
- }).isRequired,
62
- manageMode: PropTypes__default.default.bool,
63
- flatMode: PropTypes__default.default.bool,
64
- children: PropTypes__default.default.any.isRequired
65
- };
66
- CommentsProvider.defaultProps = {
67
- prefix: "",
68
- session: void 0,
69
- manageMode: false,
70
- flatMode: false
71
- };
72
- const useCommentsContext = () => {
73
- return react.useContext(CommentsContext);
74
- };
75
- exports.CommentsContext = CommentsContext;
76
- exports.CommentsProvider = CommentsProvider;
77
- exports.useCommentsContext = useCommentsContext;
package/lib/cjs/hooks.js DELETED
@@ -1,202 +0,0 @@
1
- "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const react = require("react");
4
- const useSetState = require("react-use/lib/useSetState");
5
- const uniqBy = require("lodash/uniqBy");
6
- const orderBy = require("lodash/orderBy");
7
- const Toast = require("@arcblock/ux/lib/Toast");
8
- const api = require("./api");
9
- const ws = require("./ws");
10
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
11
- const useSetState__default = /* @__PURE__ */ _interopDefaultLegacy(useSetState);
12
- const uniqBy__default = /* @__PURE__ */ _interopDefaultLegacy(uniqBy);
13
- const orderBy__default = /* @__PURE__ */ _interopDefaultLegacy(orderBy);
14
- const Toast__default = /* @__PURE__ */ _interopDefaultLegacy(Toast);
15
- const lastItem = (arr) => (arr == null ? void 0 : arr.length) ? arr[arr.length - 1] : null;
16
- const getInitialState = () => ({
17
- comments: [],
18
- cursor: null,
19
- total: 0,
20
- initialized: false,
21
- loading: true,
22
- error: null,
23
- rating: {},
24
- sortType: localStorage.getItem("sortType") || "asc"
25
- });
26
- const useComments = ({ objectId, flatMode }, deps = []) => {
27
- const [state, setState] = useSetState__default.default(getInitialState());
28
- const commentsKeyById = react.useMemo(() => {
29
- return state.comments.reduce((acc, cur) => {
30
- var _a;
31
- acc[cur.id] = cur;
32
- if ((_a = cur.replies) == null ? void 0 : _a.length) {
33
- cur.replies.forEach((item) => {
34
- acc[item.id] = item;
35
- });
36
- }
37
- return acc;
38
- }, {});
39
- }, [state]);
40
- const hasMore = react.useMemo(() => !!state.cursor, [state]);
41
- const fetchParamsRef = react.useRef({
42
- objectId,
43
- size: 12,
44
- embed: "replies,rating",
45
- ...flatMode && { includeReplies: 1 }
46
- });
47
- const updateCommentList = () => {
48
- setState({ comments: [...state.comments] });
49
- };
50
- const updateComment = (commentId, mapper) => {
51
- const commentOrReply = commentsKeyById[commentId];
52
- if (commentOrReply) {
53
- const rootComment = commentsKeyById[commentOrReply.commentId];
54
- if (!rootComment || flatMode) {
55
- const index = state.comments.findIndex((item) => item.id === commentId);
56
- if (index !== -1) {
57
- state.comments[index] = mapper(state.comments[index]);
58
- updateCommentList();
59
- }
60
- } else {
61
- const index = rootComment.replies.findIndex((item) => item.id === commentId);
62
- if (index !== -1) {
63
- rootComment.replies[index] = mapper(rootComment.replies[index]);
64
- updateComment(rootComment.id, (current) => ({
65
- ...current,
66
- replies: [...rootComment.replies]
67
- }));
68
- }
69
- }
70
- }
71
- };
72
- const addComment = (commentOrReply) => {
73
- if (commentsKeyById[commentOrReply.id]) {
74
- return;
75
- }
76
- const rootComment = commentsKeyById[commentOrReply.commentId];
77
- if (!rootComment || flatMode) {
78
- const comments = uniqBy__default.default([...state.comments, commentOrReply], "id");
79
- setState({ comments: orderBy__default.default(comments, ["createdAt"], [state.sortType]), total: state.total + 1 });
80
- } else {
81
- updateComment(rootComment.id, (current) => {
82
- var _a;
83
- const replies = uniqBy__default.default([...rootComment.replies || [], commentOrReply], "id");
84
- const newComment = {
85
- ...current,
86
- replies: orderBy__default.default(replies, ["createdAt"], ["asc"]),
87
- totalReplies: (current.totalReplies || 0) + 1
88
- };
89
- if (!current.repliesCursor) {
90
- newComment.repliesCursor = (_a = lastItem(current.replies)) == null ? void 0 : _a.createdAt;
91
- }
92
- return newComment;
93
- });
94
- }
95
- };
96
- const removeComment = (comment) => {
97
- const isReply = comment.commentId;
98
- if (isReply && !flatMode) {
99
- updateComment(comment.commentId, (current) => {
100
- return {
101
- ...current,
102
- replies: (current.replies || []).map((item) => {
103
- if (item.id === comment.id) {
104
- return { ...item, deletedAt: new Date() };
105
- }
106
- return item;
107
- })
108
- };
109
- });
110
- } else {
111
- updateComment(comment.id, (current) => {
112
- return { ...current, deletedAt: new Date() };
113
- });
114
- }
115
- };
116
- const handlers = {
117
- ADD_COMMENT: (data) => addComment(data),
118
- RATING: async () => {
119
- const rating = await api.fetchRatingStats(objectId);
120
- setState({ rating });
121
- },
122
- RATING_COMMENT: async ({ commentId }) => {
123
- const rating = await api.fetchRatingStats(commentId);
124
- updateComment(commentId, (current) => ({
125
- ...current,
126
- rating
127
- }));
128
- }
129
- };
130
- ws.useSubscription(
131
- objectId,
132
- ({ event, data }) => {
133
- var _a;
134
- (_a = handlers[event]) == null ? void 0 : _a.call(handlers, data);
135
- },
136
- [objectId, state]
137
- );
138
- const fetch = async () => {
139
- try {
140
- setState({ loading: true });
141
- return api.fetchComments({ ...fetchParamsRef.current, order: state.sortType, cursor: state.cursor });
142
- } catch (e) {
143
- Toast__default.default.warning("Failed to load comments data.");
144
- setState({ error: e });
145
- return { comments: [], total: 0, cursor: null };
146
- } finally {
147
- setState({ loading: false });
148
- }
149
- };
150
- const loadMore = async () => {
151
- if (hasMore) {
152
- const { data: comments, total, nextCursor } = await fetch();
153
- const sorted = orderBy__default.default([...state.comments, ...comments], ["createdAt"], [state.sortType]);
154
- setState({ comments: sorted, total, cursor: nextCursor });
155
- }
156
- };
157
- const loadMoreReplies = async (commentId) => {
158
- var _a;
159
- const rootComment = commentsKeyById[commentId];
160
- const cursor = rootComment.repliesCursor || ((_a = lastItem(rootComment.replies)) == null ? void 0 : _a.createdAt);
161
- const data = await api.fetchMoreReplies({
162
- commentId,
163
- cursor,
164
- embed: "rating"
165
- });
166
- const loadedReplies = data.data;
167
- let replies = uniqBy__default.default([...rootComment.replies || [], ...loadedReplies || []], "id");
168
- replies = orderBy__default.default(replies, ["createdAt"], ["asc"]);
169
- updateComment(commentId, (current) => {
170
- var _a2;
171
- return {
172
- ...current,
173
- replies,
174
- totalReplies: data.total,
175
- repliesCursor: (_a2 = lastItem(loadedReplies)) == null ? void 0 : _a2.createdAt
176
- };
177
- });
178
- };
179
- const sort = (sortType) => {
180
- setState({ sortType, cursor: null });
181
- localStorage.setItem("sortType", sortType);
182
- };
183
- react.useEffect(() => {
184
- const init = async () => {
185
- setState({ ...getInitialState(), initialized: false });
186
- const [{ data: comments, total, nextCursor }, rating] = await Promise.all([fetch(), api.fetchRatingStats(objectId)]);
187
- setState({ comments, total, cursor: nextCursor, rating, initialized: true });
188
- };
189
- init();
190
- }, [objectId, state.sortType, ...deps || []]);
191
- return {
192
- ...state,
193
- hasMore,
194
- loadMore,
195
- sort,
196
- addComment,
197
- updateComment,
198
- loadMoreReplies,
199
- removeComment
200
- };
201
- };
202
- exports.useComments = useComments;