@blocklet/discuss-kit 1.0.0

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.
Files changed (45) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +15 -0
  3. package/lib/cjs/api.js +45 -0
  4. package/lib/cjs/comment-list.js +117 -0
  5. package/lib/cjs/components/comment.js +335 -0
  6. package/lib/cjs/components/error-fallback.js +26 -0
  7. package/lib/cjs/components/menu.js +84 -0
  8. package/lib/cjs/components/rating/binary-thumb.js +199 -0
  9. package/lib/cjs/components/rating/emoji-based.js +39 -0
  10. package/lib/cjs/components/rating/index.js +9 -0
  11. package/lib/cjs/components/rating/rating.js +93 -0
  12. package/lib/cjs/context.js +77 -0
  13. package/lib/cjs/did-comment-with-session.js +25 -0
  14. package/lib/cjs/did-comment.js +389 -0
  15. package/lib/cjs/hooks.js +202 -0
  16. package/lib/cjs/index.js +21 -0
  17. package/lib/cjs/lib/utils.js +17 -0
  18. package/lib/cjs/locales/en.js +27 -0
  19. package/lib/cjs/locales/index.js +10 -0
  20. package/lib/cjs/locales/zh.js +27 -0
  21. package/lib/cjs/session.js +14 -0
  22. package/lib/cjs/theme-provider.js +48 -0
  23. package/lib/cjs/ws.js +39 -0
  24. package/lib/es/api.js +43 -0
  25. package/lib/es/comment-list.js +112 -0
  26. package/lib/es/components/comment.js +309 -0
  27. package/lib/es/components/error-fallback.js +23 -0
  28. package/lib/es/components/menu.js +77 -0
  29. package/lib/es/components/rating/binary-thumb.js +176 -0
  30. package/lib/es/components/rating/emoji-based.js +37 -0
  31. package/lib/es/components/rating/index.js +4 -0
  32. package/lib/es/components/rating/rating.js +91 -0
  33. package/lib/es/context.js +74 -0
  34. package/lib/es/did-comment-with-session.js +24 -0
  35. package/lib/es/did-comment.js +377 -0
  36. package/lib/es/hooks.js +197 -0
  37. package/lib/es/index.js +8 -0
  38. package/lib/es/lib/utils.js +17 -0
  39. package/lib/es/locales/en.js +26 -0
  40. package/lib/es/locales/index.js +7 -0
  41. package/lib/es/locales/zh.js +26 -0
  42. package/lib/es/session.js +14 -0
  43. package/lib/es/theme-provider.js +46 -0
  44. package/lib/es/ws.js +37 -0
  45. package/package.json +79 -0
@@ -0,0 +1,176 @@
1
+ import PropTypes from "prop-types";
2
+ import { styled } from "@arcblock/ux/lib/Theme";
3
+ import Box from "@mui/material/Box";
4
+ import clsx from "clsx";
5
+ import * as React from "react";
6
+ import Rating from "./rating";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ const SvgThumbUp = (props) => /* @__PURE__ */ React.createElement("svg", {
9
+ width: 32,
10
+ height: 32,
11
+ viewBox: "0 0 24 24",
12
+ ...props
13
+ }, /* @__PURE__ */ React.createElement("g", {
14
+ fill: "none",
15
+ stroke: "currentColor",
16
+ strokeLinecap: "round",
17
+ strokeWidth: 1.5
18
+ }, /* @__PURE__ */ React.createElement("path", {
19
+ 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"
20
+ }), /* @__PURE__ */ React.createElement("path", {
21
+ strokeLinejoin: "round",
22
+ d: "M7 20V9"
23
+ })));
24
+ function BinaryThumb({
25
+ variant,
26
+ size,
27
+ ...rest
28
+ }) {
29
+ const renderer = ({
30
+ options,
31
+ toggleRate
32
+ }) => {
33
+ return /* @__PURE__ */ jsx(Root, {
34
+ children: options.map((option) => {
35
+ const icon = option.value === -1 ? /* @__PURE__ */ jsx(SvgThumbUp, {
36
+ style: {
37
+ transform: "rotate(180deg)"
38
+ }
39
+ }) : /* @__PURE__ */ jsx(SvgThumbUp, {});
40
+ return /* @__PURE__ */ jsx("div", {
41
+ className: "reaction-item",
42
+ children: /* @__PURE__ */ jsx(IconButton, {
43
+ className: "reaction-item-btn",
44
+ icon,
45
+ text: option.count,
46
+ selected: option.selected,
47
+ onClick: () => toggleRate(option.value),
48
+ variant,
49
+ size
50
+ })
51
+ }, option.value);
52
+ })
53
+ });
54
+ };
55
+ return /* @__PURE__ */ jsx(Rating, {
56
+ ratingType: "binary-thumb",
57
+ values: [1, -1],
58
+ ...rest,
59
+ render: renderer
60
+ });
61
+ }
62
+ BinaryThumb.propTypes = {
63
+ variant: PropTypes.oneOf(["default", "inverse"]),
64
+ size: PropTypes.oneOf(["sm", "lg"])
65
+ };
66
+ BinaryThumb.defaultProps = {
67
+ variant: "default",
68
+ size: "sm"
69
+ };
70
+ const Root = styled(Box)`
71
+ display: flex;
72
+ .reaction-item {
73
+ display: flex;
74
+ align-items: center;
75
+ }
76
+ `;
77
+ function IconButton({
78
+ icon,
79
+ text,
80
+ onClick,
81
+ selected,
82
+ variant,
83
+ size,
84
+ ...rest
85
+ }) {
86
+ const classes = clsx(rest.className, `reaction-btn-${size} reaction-btn-${variant}`, {
87
+ "reaction-btn-selected": selected
88
+ });
89
+ return /* @__PURE__ */ jsxs(IconButtonRoot, {
90
+ ...rest,
91
+ className: classes,
92
+ children: [/* @__PURE__ */ jsx("span", {
93
+ className: "reaction-btn-icon",
94
+ onClick,
95
+ children: icon
96
+ }), !!text && /* @__PURE__ */ jsx("span", {
97
+ className: "reaction-btn-text",
98
+ children: text
99
+ })]
100
+ });
101
+ }
102
+ IconButton.propTypes = {
103
+ icon: PropTypes.node.isRequired,
104
+ text: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
105
+ onClick: PropTypes.func.isRequired,
106
+ selected: PropTypes.bool,
107
+ variant: PropTypes.oneOf(["default", "inverse"]),
108
+ size: PropTypes.oneOf(["sm", "lg"])
109
+ };
110
+ IconButton.defaultProps = {
111
+ selected: false,
112
+ variant: "default",
113
+ size: "sm"
114
+ };
115
+ const IconButtonRoot = styled("div")`
116
+ display: flex;
117
+ align-items: center;
118
+ &.reaction-btn-selected {
119
+ color: ${(props) => props.theme.palette.primary.main};
120
+ }
121
+ .reaction-btn-icon {
122
+ display: flex;
123
+ line-height: 1;
124
+ &:hover {
125
+ cursor: pointer;
126
+ }
127
+ }
128
+ svg {
129
+ width: auto;
130
+ }
131
+ .reaction-btn-text {
132
+ display: inline-block;
133
+ }
134
+ &.reaction-btn-sm {
135
+ min-width: 64px;
136
+ height: 18px;
137
+ font-size: 12px;
138
+ svg {
139
+ height: 16px;
140
+ }
141
+ .reaction-btn-text {
142
+ margin-left: 8px;
143
+ }
144
+ }
145
+ &.reaction-btn-lg {
146
+ min-width: 100px;
147
+ font-size: 14px;
148
+ .reaction-btn-icon {
149
+ justify-content: center;
150
+ align-items: center;
151
+ width: 44px;
152
+ height: 44px;
153
+ border-radius: 8px;
154
+ }
155
+ svg {
156
+ height: 20px;
157
+ }
158
+ .reaction-btn-text {
159
+ margin-left: 12px;
160
+ }
161
+ }
162
+ &.reaction-btn-inverse {
163
+ .reaction-btn-icon {
164
+ background-color: ${(props) => props.theme.palette.grey[200]};
165
+ }
166
+ &.reaction-btn-selected {
167
+ .reaction-btn-icon {
168
+ color: #fff;
169
+ background-color: ${(props) => props.theme.palette.primary.main};
170
+ }
171
+ }
172
+ }
173
+ `;
174
+ export {
175
+ BinaryThumb as default
176
+ };
@@ -0,0 +1,37 @@
1
+ import PropTypes from "prop-types";
2
+ import Rating from "./rating";
3
+ import { jsx } from "react/jsx-runtime";
4
+ function EmojiBased({
5
+ emojiValues
6
+ }) {
7
+ return /* @__PURE__ */ jsx(Rating, {
8
+ ratingType: "emoji-based",
9
+ children: /* @__PURE__ */ jsx("span", {
10
+ children: emojiValues
11
+ })
12
+ });
13
+ }
14
+ EmojiBased.propTypes = {
15
+ emojiValues: PropTypes.array
16
+ };
17
+ EmojiBased.defaultProps = {
18
+ emojiValues: [{
19
+ value: 5,
20
+ emojicon: "\u{1F601}"
21
+ }, {
22
+ value: 4,
23
+ emojicon: "\u{1F600}"
24
+ }, {
25
+ value: 3,
26
+ emojicon: "\u{1F610}"
27
+ }, {
28
+ value: 2,
29
+ emojicon: "\u{1F615}"
30
+ }, {
31
+ value: 1,
32
+ emojicon: "\u{1F61E}"
33
+ }]
34
+ };
35
+ export {
36
+ EmojiBased as default
37
+ };
@@ -0,0 +1,4 @@
1
+ import { default as default2 } from "./binary-thumb";
2
+ export {
3
+ default2 as BinaryThumb
4
+ };
@@ -0,0 +1,91 @@
1
+ import { useEffect } from "react";
2
+ import PropTypes from "prop-types";
3
+ import useSetState from "react-use/lib/useSetState";
4
+ function Rating({
5
+ ratingType,
6
+ values,
7
+ countPerValue,
8
+ selected,
9
+ render,
10
+ onRate,
11
+ onUnrate
12
+ }) {
13
+ const [state, setState] = useSetState({
14
+ selected,
15
+ countPerValue
16
+ });
17
+ const hasSelected = !!state.selected || state.selected === 0;
18
+ const increaseCount = (value, inc) => {
19
+ setState((prevState) => ({
20
+ countPerValue: {
21
+ ...prevState.countPerValue,
22
+ [value]: (prevState.countPerValue[value] || 0) + inc
23
+ }
24
+ }));
25
+ };
26
+ useEffect(() => {
27
+ setState({
28
+ countPerValue,
29
+ selected
30
+ });
31
+ }, [countPerValue, selected]);
32
+ if (!render) {
33
+ return null;
34
+ }
35
+ const options = values.map((value) => {
36
+ var _a;
37
+ return {
38
+ value,
39
+ count: ((_a = state.countPerValue) == null ? void 0 : _a[value]) || 0,
40
+ selected: state.selected === value
41
+ };
42
+ });
43
+ const toggleRate = async (value) => {
44
+ try {
45
+ if (state.selected === value) {
46
+ await onUnrate({
47
+ ratingType,
48
+ value
49
+ });
50
+ increaseCount(value, -1);
51
+ setState({
52
+ selected: null
53
+ });
54
+ } else {
55
+ await onRate({
56
+ ratingType,
57
+ value
58
+ });
59
+ if (hasSelected) {
60
+ increaseCount(state.selected, -1);
61
+ }
62
+ increaseCount(value, 1);
63
+ setState({
64
+ selected: value
65
+ });
66
+ }
67
+ } catch (e) {
68
+ console.error("Failed to rate.", e);
69
+ }
70
+ };
71
+ return render({
72
+ options,
73
+ toggleRate
74
+ });
75
+ }
76
+ Rating.propTypes = {
77
+ ratingType: PropTypes.oneOf(["binary-thumb", "five-star", "emoji-based"]).isRequired,
78
+ values: PropTypes.arrayOf(PropTypes.number).isRequired,
79
+ countPerValue: PropTypes.object,
80
+ selected: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
81
+ render: PropTypes.func.isRequired,
82
+ onRate: PropTypes.func.isRequired,
83
+ onUnrate: PropTypes.func.isRequired
84
+ };
85
+ Rating.defaultProps = {
86
+ countPerValue: {},
87
+ selected: void 0
88
+ };
89
+ export {
90
+ Rating as default
91
+ };
@@ -0,0 +1,74 @@
1
+ import { createContext, useContext, useEffect, useMemo } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { SessionContext } from "@arcblock/did-connect/lib/Session";
4
+ import { useComments } from "./hooks";
5
+ import getWsClient from "./ws";
6
+ import { jsx } from "react/jsx-runtime";
7
+ const CommentsContext = createContext();
8
+ function CommentsProvider({
9
+ prefix,
10
+ session,
11
+ object,
12
+ manageMode,
13
+ flatMode,
14
+ children
15
+ }) {
16
+ var _a;
17
+ const sessionCtx = useContext(SessionContext);
18
+ const _session = session || (sessionCtx == null ? void 0 : sessionCtx.session);
19
+ const wsClient = getWsClient(prefix);
20
+ const commentsState = useComments({
21
+ objectId: object.id,
22
+ flatMode
23
+ }, [(_a = _session == null ? void 0 : _session.user) == null ? void 0 : _a.did]);
24
+ useEffect(() => {
25
+ wsClient.connect();
26
+ return () => {
27
+ if (wsClient.isConnected()) {
28
+ wsClient.disconnect();
29
+ }
30
+ };
31
+ }, []);
32
+ const value = useMemo(
33
+ () => ({
34
+ session: _session,
35
+ object,
36
+ prefix,
37
+ manageMode,
38
+ flatMode,
39
+ ...commentsState
40
+ }),
41
+ [_session, object, prefix, commentsState]
42
+ );
43
+ return /* @__PURE__ */ jsx(CommentsContext.Provider, {
44
+ value,
45
+ children
46
+ });
47
+ }
48
+ CommentsProvider.propTypes = {
49
+ prefix: PropTypes.string,
50
+ session: PropTypes.object,
51
+ object: PropTypes.PropTypes.shape({
52
+ id: PropTypes.string.isRequired,
53
+ title: PropTypes.string,
54
+ desc: PropTypes.string,
55
+ owner: PropTypes.string
56
+ }).isRequired,
57
+ manageMode: PropTypes.bool,
58
+ flatMode: PropTypes.bool,
59
+ children: PropTypes.any.isRequired
60
+ };
61
+ CommentsProvider.defaultProps = {
62
+ prefix: "",
63
+ session: void 0,
64
+ manageMode: false,
65
+ flatMode: false
66
+ };
67
+ const useCommentsContext = () => {
68
+ return useContext(CommentsContext);
69
+ };
70
+ export {
71
+ CommentsContext,
72
+ CommentsProvider,
73
+ useCommentsContext
74
+ };
@@ -0,0 +1,24 @@
1
+ import { getWebWalletUrl } from "@arcblock/did-connect/lib/utils";
2
+ import DIDComment from "./did-comment";
3
+ import { SessionProvider } from "./session";
4
+ import { jsx } from "react/jsx-runtime";
5
+ const DIDCommentHOC = (WrappedComponent) => {
6
+ const webWalletUrl = getWebWalletUrl();
7
+ return function(props) {
8
+ return /* @__PURE__ */ jsx(SessionProvider, {
9
+ serviceHost: "/",
10
+ webWalletUrl,
11
+ children: (session) => {
12
+ return /* @__PURE__ */ jsx(WrappedComponent, {
13
+ ...props,
14
+ session: session.session,
15
+ showConnectBtn: true
16
+ });
17
+ }
18
+ });
19
+ };
20
+ };
21
+ const didCommentWithSession = DIDCommentHOC(DIDComment);
22
+ export {
23
+ didCommentWithSession as default
24
+ };