@blocklet/discuss-kit-ux-lite 2.6.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.
- package/LICENSE +13 -0
- package/dist/axios.d.ts +8 -0
- package/dist/blocklets.d.ts +13 -0
- package/dist/blocklets.mjs +17 -0
- package/dist/components/api-error-handler/api-error-handler.d.ts +13 -0
- package/dist/components/api-error-handler/api-error-handler.mjs +25 -0
- package/dist/components/api-error-handler/default-handler.d.ts +8 -0
- package/dist/components/api-error-handler/default-handler.mjs +69 -0
- package/dist/components/api-error-handler/index.d.ts +2 -0
- package/dist/components/api-error-handler/index.mjs +2 -0
- package/dist/components/api-error-handler/json-validation-interceptor.d.ts +2 -0
- package/dist/components/api-error-handler/json-validation-interceptor.mjs +9 -0
- package/dist/components/arcsphere/index.d.ts +16 -0
- package/dist/components/arcsphere/index.mjs +52 -0
- package/dist/components/authz/access-control.d.ts +24 -0
- package/dist/components/authz/access-control.mjs +15 -0
- package/dist/components/authz/context.d.ts +13 -0
- package/dist/components/authz/context.mjs +30 -0
- package/dist/components/authz/index.d.ts +2 -0
- package/dist/components/authz/index.mjs +2 -0
- package/dist/components/auto-translate/api.d.ts +14 -0
- package/dist/components/auto-translate/api.mjs +23 -0
- package/dist/components/auto-translate/auto-translate-button.d.ts +5 -0
- package/dist/components/auto-translate/auto-translate-button.mjs +48 -0
- package/dist/components/auto-translate/editor-store-adaptor.d.ts +1 -0
- package/dist/components/auto-translate/editor-store-adaptor.mjs +14 -0
- package/dist/components/auto-translate/index.d.ts +6 -0
- package/dist/components/auto-translate/index.mjs +6 -0
- package/dist/components/auto-translate/languages.d.ts +13 -0
- package/dist/components/auto-translate/languages.mjs +61 -0
- package/dist/components/auto-translate/post-auto-translate-plugin.d.ts +14 -0
- package/dist/components/auto-translate/post-auto-translate-plugin.mjs +32 -0
- package/dist/components/auto-translate/store.d.ts +21 -0
- package/dist/components/auto-translate/store.mjs +23 -0
- package/dist/components/auto-translate/translate.d.ts +17 -0
- package/dist/components/auto-translate/translate.mjs +103 -0
- package/dist/components/auto-translate/utils.d.ts +4 -0
- package/dist/components/auto-translate/utils.mjs +14 -0
- package/dist/components/auto-translate/with-availibility-check.d.ts +2 -0
- package/dist/components/auto-translate/with-availibility-check.mjs +10 -0
- package/dist/components/avatars/author-info.d.ts +23 -0
- package/dist/components/avatars/author-info.mjs +178 -0
- package/dist/components/avatars/avatar.d.ts +7 -0
- package/dist/components/avatars/avatar.mjs +9 -0
- package/dist/components/avatars/avatars.d.ts +10 -0
- package/dist/components/avatars/avatars.mjs +49 -0
- package/dist/components/avatars/badge.d.ts +14 -0
- package/dist/components/avatars/badge.mjs +178 -0
- package/dist/components/avatars/index.d.ts +5 -0
- package/dist/components/avatars/index.mjs +5 -0
- package/dist/components/avatars/system-user.d.ts +10 -0
- package/dist/components/avatars/system-user.mjs +58 -0
- package/dist/components/button-group/button-group.d.ts +18 -0
- package/dist/components/button-group/button-group.mjs +195 -0
- package/dist/components/button-group/index.d.ts +1 -0
- package/dist/components/button-group/index.mjs +1 -0
- package/dist/components/confirm.d.ts +29 -0
- package/dist/components/confirm.mjs +103 -0
- package/dist/components/dayjs.d.ts +3 -0
- package/dist/components/dayjs.mjs +5 -0
- package/dist/components/default-editor-config-provider.d.ts +8 -0
- package/dist/components/default-editor-config-provider.mjs +108 -0
- package/dist/components/dirty-prompt.d.ts +8 -0
- package/dist/components/dirty-prompt.mjs +117 -0
- package/dist/components/editor/blocklet-editor.d.ts +1 -0
- package/dist/components/editor/blocklet-editor.mjs +1 -0
- package/dist/components/editor/editor.d.ts +17 -0
- package/dist/components/editor/editor.mjs +35 -0
- package/dist/components/editor/index.d.ts +4 -0
- package/dist/components/editor/index.mjs +3 -0
- package/dist/components/editor/lazy-editor.d.ts +3 -0
- package/dist/components/editor/lazy-editor.mjs +14 -0
- package/dist/components/editor/viewer.d.ts +10 -0
- package/dist/components/editor/viewer.mjs +18 -0
- package/dist/components/emoji-icon.d.ts +11 -0
- package/dist/components/emoji-icon.mjs +62 -0
- package/dist/components/empty-status/empty-status.d.ts +7 -0
- package/dist/components/empty-status/empty-status.mjs +24 -0
- package/dist/components/empty-status/index.d.ts +1 -0
- package/dist/components/empty-status/index.mjs +1 -0
- package/dist/components/hooks/changed.d.ts +10 -0
- package/dist/components/hooks/changed.mjs +34 -0
- package/dist/components/hooks/index.d.ts +6 -0
- package/dist/components/hooks/index.mjs +6 -0
- package/dist/components/hooks/interval.d.ts +6 -0
- package/dist/components/hooks/interval.mjs +16 -0
- package/dist/components/hooks/locale-context.d.ts +10 -0
- package/dist/components/hooks/locale-context.mjs +12 -0
- package/dist/components/hooks/measure.d.ts +5 -0
- package/dist/components/hooks/measure.mjs +8 -0
- package/dist/components/hooks/now.d.ts +1 -0
- package/dist/components/hooks/now.mjs +10 -0
- package/dist/components/hooks/responsive.d.ts +17 -0
- package/dist/components/hooks/responsive.mjs +25 -0
- package/dist/components/hooks/session.d.ts +12 -0
- package/dist/components/hooks/session.mjs +48 -0
- package/dist/components/hooks/use-event-callback.d.ts +1 -0
- package/dist/components/hooks/use-event-callback.mjs +14 -0
- package/dist/components/icon-button.d.ts +6 -0
- package/dist/components/icon-button.mjs +37 -0
- package/dist/components/input/auto-clear-plugin.d.ts +3 -0
- package/dist/components/input/auto-clear-plugin.mjs +20 -0
- package/dist/components/input/comment-input.d.ts +11 -0
- package/dist/components/input/comment-input.mjs +108 -0
- package/dist/components/input/index.d.ts +4 -0
- package/dist/components/input/index.mjs +4 -0
- package/dist/components/input/input.d.ts +29 -0
- package/dist/components/input/input.mjs +149 -0
- package/dist/components/input/post-edit.d.ts +10 -0
- package/dist/components/input/post-edit.mjs +49 -0
- package/dist/components/input/scrollable-editor-wrapper.d.ts +9 -0
- package/dist/components/input/scrollable-editor-wrapper.mjs +18 -0
- package/dist/components/input/shortcut-plugin.d.ts +7 -0
- package/dist/components/input/shortcut-plugin.mjs +28 -0
- package/dist/components/lexical.d.ts +10 -0
- package/dist/components/lexical.mjs +56 -0
- package/dist/components/locale/en.d.ts +117 -0
- package/dist/components/locale/en.mjs +116 -0
- package/dist/components/locale/index.d.ts +236 -0
- package/dist/components/locale/index.mjs +3 -0
- package/dist/components/locale/zh.d.ts +119 -0
- package/dist/components/locale/zh.mjs +118 -0
- package/dist/components/pagination.d.ts +12 -0
- package/dist/components/pagination.mjs +44 -0
- package/dist/components/posts/comment-list/comment-list.d.ts +5 -0
- package/dist/components/posts/comment-list/comment-list.mjs +163 -0
- package/dist/components/posts/comment-list/context.d.ts +76 -0
- package/dist/components/posts/comment-list/context.mjs +318 -0
- package/dist/components/posts/comment.d.ts +16 -0
- package/dist/components/posts/comment.mjs +184 -0
- package/dist/components/posts/index.d.ts +6 -0
- package/dist/components/posts/index.mjs +6 -0
- package/dist/components/posts/menu.d.ts +14 -0
- package/dist/components/posts/menu.mjs +83 -0
- package/dist/components/posts/post-content.d.ts +16 -0
- package/dist/components/posts/post-content.mjs +63 -0
- package/dist/components/posts/post.d.ts +26 -0
- package/dist/components/posts/post.mjs +198 -0
- package/dist/components/profile-card/index.d.ts +1 -0
- package/dist/components/profile-card/index.mjs +1 -0
- package/dist/components/profile-card/profile-card.d.ts +15 -0
- package/dist/components/profile-card/profile-card.mjs +140 -0
- package/dist/components/rating/binary-thumb.d.ts +9 -0
- package/dist/components/rating/binary-thumb.mjs +162 -0
- package/dist/components/rating/github-reaction-container.d.ts +9 -0
- package/dist/components/rating/github-reaction-container.mjs +46 -0
- package/dist/components/rating/github-reaction.d.ts +18 -0
- package/dist/components/rating/github-reaction.mjs +174 -0
- package/dist/components/rating/index.d.ts +3 -0
- package/dist/components/rating/index.mjs +3 -0
- package/dist/components/rating/rater-list.d.ts +10 -0
- package/dist/components/rating/rater-list.mjs +33 -0
- package/dist/components/rating/rating.d.ts +27 -0
- package/dist/components/rating/rating.mjs +50 -0
- package/dist/components/segmented-control.d.ts +14 -0
- package/dist/components/segmented-control.mjs +55 -0
- package/dist/components/shared/relative-time.d.ts +8 -0
- package/dist/components/shared/relative-time.mjs +21 -0
- package/dist/components/toast.d.ts +8 -0
- package/dist/components/toast.mjs +44 -0
- package/dist/components/uploader/index.d.ts +13 -0
- package/dist/components/uploader/index.mjs +70 -0
- package/dist/components/uploader/utils.d.ts +1 -0
- package/dist/components/uploader/utils.mjs +16 -0
- package/dist/components/utils.d.ts +22 -0
- package/dist/components/utils.mjs +103 -0
- package/dist/components/view-more.d.ts +4 -0
- package/dist/components/view-more.mjs +50 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.mjs +14 -0
- package/dist/global.d.ts +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.mjs +29 -0
- package/dist/preferences.d.ts +2 -0
- package/dist/preferences.mjs +9 -0
- package/dist/theme/index.d.ts +8 -0
- package/dist/theme/index.mjs +96 -0
- package/dist/theme/typography.d.ts +2 -0
- package/dist/theme/typography.mjs +66 -0
- package/dist/type-override.d.ts +7 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.mjs +0 -0
- package/dist/vite-env.d.ts +1 -0
- package/dist/ws.d.ts +3 -0
- package/dist/ws.mjs +39 -0
- package/package.json +81 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
2
|
+
import { create } from "zustand";
|
|
3
|
+
import { persist } from "zustand/middleware";
|
|
4
|
+
import { useSessionContext } from "../hooks/session.mjs";
|
|
5
|
+
export const useAutoTranslateStore = create()(
|
|
6
|
+
persist(
|
|
7
|
+
(set, get) => ({
|
|
8
|
+
autoTranslate: false,
|
|
9
|
+
enableAutoTranslate: () => set({ autoTranslate: true }),
|
|
10
|
+
disableAutoTranslate: () => set({ autoTranslate: false }),
|
|
11
|
+
toggleAutoTranslate: (value) => set({ autoTranslate: value ?? !get().autoTranslate })
|
|
12
|
+
}),
|
|
13
|
+
{
|
|
14
|
+
name: "auto-translate"
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
);
|
|
18
|
+
export const useTargetLanguage = () => {
|
|
19
|
+
const { locale, languages } = useLocaleContext();
|
|
20
|
+
const { session } = useSessionContext();
|
|
21
|
+
const preferredLanguage = languages.find((x) => x.code === session?.user?.locale);
|
|
22
|
+
return preferredLanguage?.code ?? locale;
|
|
23
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { TypographyProps } from '@mui/material';
|
|
3
|
+
export declare const useTranslate: ({ text, enabled }: {
|
|
4
|
+
text: string;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
}) => {
|
|
7
|
+
translation: any;
|
|
8
|
+
key: any;
|
|
9
|
+
loading: boolean;
|
|
10
|
+
};
|
|
11
|
+
type Props<C extends React.ElementType> = {
|
|
12
|
+
text: string;
|
|
13
|
+
} & TypographyProps<C, {
|
|
14
|
+
component?: C;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function Translate<C extends React.ElementType>({ text, children, sx, ...rest }: Props<C>): import("react").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Typography } from "@mui/material";
|
|
3
|
+
import { useInViewport, useRequest } from "ahooks";
|
|
4
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
5
|
+
import { detectLanguageIso6391, hashText, isInlineTranslationAvailable } from "./utils.mjs";
|
|
6
|
+
import { useAutoTranslateStore, useTargetLanguage } from "./store.mjs";
|
|
7
|
+
import { api } from "./api.mjs";
|
|
8
|
+
import { useLocaleContext } from "../hooks/locale-context.mjs";
|
|
9
|
+
import { minDelay } from "../utils.mjs";
|
|
10
|
+
export const useTranslate = ({ text, enabled }) => {
|
|
11
|
+
const { getLanguageName } = useLocaleContext();
|
|
12
|
+
const targetLanguage = useTargetLanguage();
|
|
13
|
+
const targetLanguageName = getLanguageName(targetLanguage);
|
|
14
|
+
const key = useMemo(() => hashText(text), [text]);
|
|
15
|
+
const isTranslatedRef = useRef({});
|
|
16
|
+
const { data, loading, run } = useRequest(
|
|
17
|
+
async () => {
|
|
18
|
+
if (!text || !enabled) {
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
if (detectLanguageIso6391(text) === targetLanguage) {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const { data: translations } = await minDelay(
|
|
26
|
+
api.post("/translate", {
|
|
27
|
+
pieces: [{ key, text }],
|
|
28
|
+
targetLanguage,
|
|
29
|
+
targetLanguageName
|
|
30
|
+
}),
|
|
31
|
+
500
|
|
32
|
+
);
|
|
33
|
+
return translations[0]?.translation || text;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
return text;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
refreshDeps: [text, targetLanguage, key, enabled],
|
|
40
|
+
manual: true
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (enabled && !isTranslatedRef.current[`${targetLanguage}-${key}`]) {
|
|
45
|
+
isTranslatedRef.current[`${targetLanguage}-${key}`] = true;
|
|
46
|
+
run();
|
|
47
|
+
}
|
|
48
|
+
}, [enabled, run, targetLanguage, key]);
|
|
49
|
+
return {
|
|
50
|
+
translation: data,
|
|
51
|
+
key,
|
|
52
|
+
loading
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export function Translate({ text, children, sx, ...rest }) {
|
|
56
|
+
if (typeof children === "string" && !text) {
|
|
57
|
+
text = children;
|
|
58
|
+
}
|
|
59
|
+
text = text || "";
|
|
60
|
+
const ref = useRef(null);
|
|
61
|
+
const [inViewport] = useInViewport(ref);
|
|
62
|
+
const autoTranslate = useAutoTranslateStore((s) => s.autoTranslate);
|
|
63
|
+
const enabled = !!inViewport && autoTranslate && isInlineTranslationAvailable;
|
|
64
|
+
const { translation, loading } = useTranslate({ text, enabled });
|
|
65
|
+
const mergedSx = [
|
|
66
|
+
{
|
|
67
|
+
"& .translate-loader": {
|
|
68
|
+
boxSizing: "border-box",
|
|
69
|
+
display: "inline-block",
|
|
70
|
+
width: 13,
|
|
71
|
+
height: 13,
|
|
72
|
+
ml: 0.5,
|
|
73
|
+
border: (theme) => `2px solid ${theme.palette.divider}`,
|
|
74
|
+
borderBottomColor: "transparent",
|
|
75
|
+
verticalAlign: "middle",
|
|
76
|
+
borderRadius: "50%",
|
|
77
|
+
animation: "rotation 1s linear infinite"
|
|
78
|
+
},
|
|
79
|
+
"@keyframes rotation": {
|
|
80
|
+
"0%": {
|
|
81
|
+
transform: "rotate(0deg)"
|
|
82
|
+
},
|
|
83
|
+
"100%": {
|
|
84
|
+
transform: "rotate(360deg)"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
...Array.isArray(sx) ? sx : [sx]
|
|
89
|
+
];
|
|
90
|
+
const render = () => {
|
|
91
|
+
if (!enabled) {
|
|
92
|
+
return text;
|
|
93
|
+
}
|
|
94
|
+
if (loading) {
|
|
95
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
96
|
+
text,
|
|
97
|
+
/* @__PURE__ */ jsx(Box, { component: "span", className: "translate-loader" })
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
return translation;
|
|
101
|
+
};
|
|
102
|
+
return /* @__PURE__ */ jsx(Typography, { ref, sx: mergedSx, component: "span", ...rest, children: render() });
|
|
103
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import murmurhash from "murmurhash";
|
|
2
|
+
import { AIGNE_RUNTIME_DID, AIGNE_STUDIO_DID, DISCUSS_KIT_DID } from "../../constants.mjs";
|
|
3
|
+
import { blockletExists } from "../../blocklets.mjs";
|
|
4
|
+
export function hashText(text = "") {
|
|
5
|
+
return murmurhash.v3(text).toString(16);
|
|
6
|
+
}
|
|
7
|
+
const autoTranslationAID = window.blocklet.preferences.inlineTranslatorAgentAid || window.blocklet.AUTO_TRANSLATION_AID;
|
|
8
|
+
export const isInlineTranslationAvailable = blockletExists([AIGNE_RUNTIME_DID, AIGNE_STUDIO_DID, DISCUSS_KIT_DID]) && !!autoTranslationAID;
|
|
9
|
+
export function detectLanguage(src) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
export function detectLanguageIso6391(src) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { isInlineTranslationAvailable } from "./utils.mjs";
|
|
3
|
+
export function withAiAvailabilityCheck(Component) {
|
|
4
|
+
return (props) => {
|
|
5
|
+
if (!isInlineTranslationAvailable) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
return /* @__PURE__ */ jsx(Component, { ...props });
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { SxProps } from '@mui/material';
|
|
3
|
+
import type { User } from '../../types';
|
|
4
|
+
interface Props {
|
|
5
|
+
user: User;
|
|
6
|
+
newTitle?: string;
|
|
7
|
+
createdAt?: Date | string | React.ReactElement<any>;
|
|
8
|
+
append?: React.ReactNode;
|
|
9
|
+
size?: 'sm' | 'normal';
|
|
10
|
+
responsive?: boolean;
|
|
11
|
+
showProfileCard?: boolean;
|
|
12
|
+
showBadge?: boolean;
|
|
13
|
+
showDID?: boolean;
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
linkToProfile?: boolean;
|
|
16
|
+
onAvatarClick?: (defaultAction: Function) => void;
|
|
17
|
+
avatarSize?: number;
|
|
18
|
+
fontSize?: number;
|
|
19
|
+
copyable?: boolean;
|
|
20
|
+
sx?: SxProps;
|
|
21
|
+
}
|
|
22
|
+
export default function AuthorInfo({ user, createdAt, append, size, responsive, showProfileCard, showBadge, showDID, newTitle, children, linkToProfile, onAvatarClick, avatarSize, fontSize, copyable, sx, ...rest }: Props): import("react").JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { isValidElement } from "react";
|
|
3
|
+
import Box from "@mui/material/Box";
|
|
4
|
+
import { useTheme } from "@mui/material/styles";
|
|
5
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
6
|
+
import DID from "@arcblock/ux/lib/DID";
|
|
7
|
+
import { useNavigate } from "react-router-dom";
|
|
8
|
+
import UserCard from "@arcblock/ux/lib/UserCard";
|
|
9
|
+
import { CardType, InfoType } from "@arcblock/ux/lib/UserCard/types";
|
|
10
|
+
import { useBrowser } from "@arcblock/react-hooks";
|
|
11
|
+
import RelativeTime from "../shared/relative-time.mjs";
|
|
12
|
+
import Badge from "./badge.mjs";
|
|
13
|
+
import { ProfileCard } from "../profile-card/index.mjs";
|
|
14
|
+
import { isInDiscussKitApp, mergeSx, openProfile } from "../utils.mjs";
|
|
15
|
+
import { getUsername } from "../../blocklets.mjs";
|
|
16
|
+
export default function AuthorInfo({
|
|
17
|
+
user,
|
|
18
|
+
createdAt,
|
|
19
|
+
append,
|
|
20
|
+
size = "normal",
|
|
21
|
+
responsive = false,
|
|
22
|
+
showProfileCard,
|
|
23
|
+
showBadge = true,
|
|
24
|
+
showDID = true,
|
|
25
|
+
newTitle = void 0,
|
|
26
|
+
children,
|
|
27
|
+
linkToProfile = true,
|
|
28
|
+
onAvatarClick,
|
|
29
|
+
avatarSize,
|
|
30
|
+
fontSize,
|
|
31
|
+
copyable,
|
|
32
|
+
sx,
|
|
33
|
+
...rest
|
|
34
|
+
}) {
|
|
35
|
+
const theme = useTheme();
|
|
36
|
+
const downMd = useMediaQuery(theme.breakpoints.down("md"));
|
|
37
|
+
const navigate = useNavigate();
|
|
38
|
+
const { mobile } = useBrowser();
|
|
39
|
+
const sm = size === "sm";
|
|
40
|
+
const getMergedFontSize = () => {
|
|
41
|
+
if (fontSize) return fontSize;
|
|
42
|
+
if (sm) return 12;
|
|
43
|
+
if (showDID) return 14;
|
|
44
|
+
return 16;
|
|
45
|
+
};
|
|
46
|
+
let mergedFontSize = getMergedFontSize();
|
|
47
|
+
let mergedAvatarSize = avatarSize ?? (sm ? 40 : 48);
|
|
48
|
+
if (responsive && downMd) {
|
|
49
|
+
mergedFontSize = fontSize ?? 12;
|
|
50
|
+
mergedAvatarSize = avatarSize ?? 24;
|
|
51
|
+
}
|
|
52
|
+
const renderTime = () => {
|
|
53
|
+
if (!createdAt) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (isValidElement(createdAt)) {
|
|
57
|
+
return createdAt;
|
|
58
|
+
}
|
|
59
|
+
createdAt = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
|
|
60
|
+
return /* @__PURE__ */ jsx(Box, { component: RelativeTime, sx: { color: "text.secondary" }, value: createdAt });
|
|
61
|
+
};
|
|
62
|
+
const canClick = linkToProfile && user?.did && user?.did !== window.blocklet.appId;
|
|
63
|
+
const click = (e) => {
|
|
64
|
+
const defaultAction = () => {
|
|
65
|
+
if (!canClick) return;
|
|
66
|
+
e?.stopPropagation?.();
|
|
67
|
+
e?.preventDefault?.();
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
if (isInDiscussKitApp) {
|
|
70
|
+
navigate(`/profile?did=${user?.did}`);
|
|
71
|
+
} else {
|
|
72
|
+
openProfile(user?.did);
|
|
73
|
+
}
|
|
74
|
+
}, 100);
|
|
75
|
+
};
|
|
76
|
+
if (onAvatarClick) {
|
|
77
|
+
onAvatarClick(defaultAction);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
defaultAction();
|
|
81
|
+
};
|
|
82
|
+
const BadgeRender = /* @__PURE__ */ jsx(
|
|
83
|
+
Badge,
|
|
84
|
+
{
|
|
85
|
+
startComponent: !downMd && /* @__PURE__ */ jsx(
|
|
86
|
+
Box,
|
|
87
|
+
{
|
|
88
|
+
component: "span",
|
|
89
|
+
sx: {
|
|
90
|
+
display: "inline-block",
|
|
91
|
+
mx: 0.5
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"dot"
|
|
95
|
+
),
|
|
96
|
+
passports: user?.passports || [],
|
|
97
|
+
pointInfo: user?.pointInfo || {},
|
|
98
|
+
did: user?.did
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
return /* @__PURE__ */ jsxs(Box, { sx: mergeSx({ display: "flex", alignItems: "center", gap: 1.5, fontSize: mergedFontSize }, sx), ...rest, children: [
|
|
102
|
+
/* @__PURE__ */ jsx(
|
|
103
|
+
UserCard,
|
|
104
|
+
{
|
|
105
|
+
user,
|
|
106
|
+
cardType: CardType.AvatarOnly,
|
|
107
|
+
infoType: InfoType.Minimal,
|
|
108
|
+
avatarSize: mergedAvatarSize,
|
|
109
|
+
onAvatarClick: (_, e) => click(e),
|
|
110
|
+
tooltipProps: {
|
|
111
|
+
leaveDelay: 100,
|
|
112
|
+
title: /* @__PURE__ */ jsx(ProfileCard, { user, click })
|
|
113
|
+
},
|
|
114
|
+
popupSx: {
|
|
115
|
+
borderColor: "#d0d7de",
|
|
116
|
+
borderRadius: 1,
|
|
117
|
+
p: 2,
|
|
118
|
+
width: 340
|
|
119
|
+
},
|
|
120
|
+
showDid: true,
|
|
121
|
+
showHoverCard: showProfileCard && !mobile.any
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", flex: 1, overflow: "hidden" }, children: [
|
|
125
|
+
/* @__PURE__ */ jsxs(
|
|
126
|
+
Box,
|
|
127
|
+
{
|
|
128
|
+
className: "author-info-title",
|
|
129
|
+
sx: {
|
|
130
|
+
display: "flex",
|
|
131
|
+
alignItems: "center",
|
|
132
|
+
minHeight: 20,
|
|
133
|
+
flexWrap: "wrap",
|
|
134
|
+
lineHeight: 1.5
|
|
135
|
+
},
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ jsx(Box, { component: "span", children: newTitle || getUsername(user) }),
|
|
138
|
+
createdAt && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
Box,
|
|
141
|
+
{
|
|
142
|
+
component: "span",
|
|
143
|
+
sx: {
|
|
144
|
+
display: "inline-block",
|
|
145
|
+
mx: 0.5
|
|
146
|
+
},
|
|
147
|
+
children: "\xB7"
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
renderTime()
|
|
151
|
+
] }),
|
|
152
|
+
append,
|
|
153
|
+
showBadge && !downMd && BadgeRender
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
),
|
|
157
|
+
showBadge && downMd && /* @__PURE__ */ jsx(
|
|
158
|
+
Box,
|
|
159
|
+
{
|
|
160
|
+
sx: {
|
|
161
|
+
mt: 0.5
|
|
162
|
+
},
|
|
163
|
+
children: BadgeRender
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
showDID && !(responsive && downMd) && /* @__PURE__ */ jsx(
|
|
167
|
+
DID,
|
|
168
|
+
{
|
|
169
|
+
style: { lineHeight: 1.5, minHeight: 20, maxWidth: 250 },
|
|
170
|
+
size: mergedFontSize,
|
|
171
|
+
did: user?.did,
|
|
172
|
+
copyable
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
children && /* @__PURE__ */ jsx(Box, { children })
|
|
176
|
+
] })
|
|
177
|
+
] });
|
|
178
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import DidAvatar from "@arcblock/did-connect-react/lib/Avatar";
|
|
3
|
+
import { getResizedAvatar } from "../utils.mjs";
|
|
4
|
+
export default function Avatar({ src, ...rest }) {
|
|
5
|
+
if (src && src.startsWith("data:")) {
|
|
6
|
+
src = src.replace(/\s/g, encodeURIComponent(" "));
|
|
7
|
+
}
|
|
8
|
+
return /* @__PURE__ */ jsx(DidAvatar, { src: src ? getResizedAvatar(src) : src, ...rest });
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { AvatarGroupProps } from '@mui/material/AvatarGroup';
|
|
3
|
+
import type { User } from '../../types';
|
|
4
|
+
interface AvatarsProps extends Omit<AvatarGroupProps, 'variant'> {
|
|
5
|
+
users: User[];
|
|
6
|
+
variant?: 'circle' | 'rounded';
|
|
7
|
+
size?: number;
|
|
8
|
+
}
|
|
9
|
+
export default function Avatars({ users, variant, size, ...restProps }: AvatarsProps): import("react").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import Box from "@mui/material/Box";
|
|
3
|
+
import { styled } from "@arcblock/ux/lib/Theme";
|
|
4
|
+
import AvatarGroup from "@mui/material/AvatarGroup";
|
|
5
|
+
import { grey } from "@mui/material/colors";
|
|
6
|
+
import Avatar from "./avatar.mjs";
|
|
7
|
+
const Root = styled(AvatarGroup)`
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
position: relative;
|
|
11
|
+
z-index: 0;
|
|
12
|
+
line-height: 1;
|
|
13
|
+
.avatars-item {
|
|
14
|
+
width: 16px;
|
|
15
|
+
transition: width 0.1s ease-in-out;
|
|
16
|
+
& .image {
|
|
17
|
+
box-shadow: 0 0 0 2px ${({ theme }) => theme.palette.background.default} !important;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// use avatarGroup first is last
|
|
22
|
+
.avatars-item:first-of-type {
|
|
23
|
+
width: 24px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.MuiAvatar-root {
|
|
27
|
+
width: 24px;
|
|
28
|
+
height: 24px;
|
|
29
|
+
z-index: 100;
|
|
30
|
+
margin-left: 0px;
|
|
31
|
+
font-size: 12px;
|
|
32
|
+
background-color: ${grey[400]};
|
|
33
|
+
font-weight: 500;
|
|
34
|
+
border: none;
|
|
35
|
+
box-shadow: 0 0 0 2px ${({ theme }) => theme.palette.background.default} !important;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* &:hover {
|
|
39
|
+
gap: 4px;
|
|
40
|
+
.avatars-item {
|
|
41
|
+
width: 24px;
|
|
42
|
+
}
|
|
43
|
+
} */
|
|
44
|
+
`;
|
|
45
|
+
export default function Avatars({ users, variant = "circle", size = 24, ...restProps }) {
|
|
46
|
+
return /* @__PURE__ */ jsx(Root, { sx: { ".avatars-item + .avatars-item .image": { boxShadow: "0 0 0 2px #fff" } }, max: 999, ...restProps, children: users.map((user, index) => {
|
|
47
|
+
return /* @__PURE__ */ jsx(Box, { className: "avatars-item", sx: { position: "relative", zIndex: index + 1 }, children: /* @__PURE__ */ jsx(Avatar, { did: user.did, src: user.avatar, size, shape: "circle", variant }) }, index);
|
|
48
|
+
}) });
|
|
49
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface Props {
|
|
3
|
+
passports?: string[];
|
|
4
|
+
pointInfo?: any;
|
|
5
|
+
did?: string;
|
|
6
|
+
spacing?: number;
|
|
7
|
+
startComponent?: any;
|
|
8
|
+
inProfile?: boolean;
|
|
9
|
+
emptyProps?: Record<string, any>;
|
|
10
|
+
showIconOnly?: boolean;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
export default function Badge({ startComponent, passports, pointInfo, did, spacing, inProfile, emptyProps, showIconOnly, ...restProps }: Props): import("react").JSX.Element | null;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Chip from "@mui/material/Chip";
|
|
3
|
+
import Stack from "@mui/material/Stack";
|
|
4
|
+
import groupBy from "lodash/groupBy";
|
|
5
|
+
import flatMap from "lodash/flatMap";
|
|
6
|
+
import uniqBy from "lodash/uniqBy";
|
|
7
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
8
|
+
import trim from "lodash/trim";
|
|
9
|
+
import Avatar from "@mui/material/Avatar";
|
|
10
|
+
import BrokenImageIcon from "@mui/icons-material/BrokenImage";
|
|
11
|
+
import { Icon } from "@iconify/react";
|
|
12
|
+
import EmptyStatus from "../empty-status/empty-status.mjs";
|
|
13
|
+
const iconStyle = {
|
|
14
|
+
width: 20,
|
|
15
|
+
height: 20
|
|
16
|
+
};
|
|
17
|
+
const iconOnlyStyle = {
|
|
18
|
+
width: 16,
|
|
19
|
+
height: 16,
|
|
20
|
+
padding: 2,
|
|
21
|
+
m: 0,
|
|
22
|
+
cursor: "pointer"
|
|
23
|
+
};
|
|
24
|
+
const animationHeight = 8;
|
|
25
|
+
const getExtraAnimation = (value) => "";
|
|
26
|
+
const formatKey = (key) => {
|
|
27
|
+
if (typeof key === "string") {
|
|
28
|
+
return trim(key.toLowerCase());
|
|
29
|
+
}
|
|
30
|
+
return "";
|
|
31
|
+
};
|
|
32
|
+
const badgeList = flatMap(
|
|
33
|
+
(window?.blocklet?.preferences?.badgeList || []).filter((item) => [true, "true"].includes(item.enabled)).map((item) => {
|
|
34
|
+
return {
|
|
35
|
+
...item,
|
|
36
|
+
keyList: formatKey(item?.key)?.split(",")
|
|
37
|
+
};
|
|
38
|
+
}),
|
|
39
|
+
// split keyList to multiple items
|
|
40
|
+
(item) => {
|
|
41
|
+
return item?.keyList?.map((key) => {
|
|
42
|
+
return {
|
|
43
|
+
...item,
|
|
44
|
+
key: formatKey(key)
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
const badgeMap = groupBy(badgeList, "key");
|
|
50
|
+
export default function Badge({
|
|
51
|
+
startComponent,
|
|
52
|
+
passports,
|
|
53
|
+
pointInfo,
|
|
54
|
+
did,
|
|
55
|
+
spacing = 0.5,
|
|
56
|
+
inProfile = false,
|
|
57
|
+
emptyProps,
|
|
58
|
+
showIconOnly = false,
|
|
59
|
+
...restProps
|
|
60
|
+
}) {
|
|
61
|
+
const allBadges = [];
|
|
62
|
+
if (pointInfo?.grade) {
|
|
63
|
+
const { grade } = pointInfo;
|
|
64
|
+
const pointRuleBadge = badgeMap["point-rule-badge"]?.[0];
|
|
65
|
+
if (!grade.isDisabled && pointRuleBadge) {
|
|
66
|
+
allBadges.push({
|
|
67
|
+
...pointRuleBadge,
|
|
68
|
+
badgeIcon: grade.icon,
|
|
69
|
+
badgeName: grade.name
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
passports?.forEach((passport) => {
|
|
74
|
+
allBadges.push(...badgeMap[formatKey(passport)] || []);
|
|
75
|
+
});
|
|
76
|
+
if (did) {
|
|
77
|
+
allBadges.push(...badgeMap[formatKey(did)] || []);
|
|
78
|
+
}
|
|
79
|
+
if (badgeMap["*"]) {
|
|
80
|
+
allBadges.push(...badgeMap["*"] || []);
|
|
81
|
+
}
|
|
82
|
+
const uniqBadges = uniqBy(allBadges, (item) => {
|
|
83
|
+
delete item.key;
|
|
84
|
+
return JSON.stringify(item);
|
|
85
|
+
});
|
|
86
|
+
if (inProfile && uniqBadges?.length <= 0) {
|
|
87
|
+
return /* @__PURE__ */ jsx(EmptyStatus, { ...emptyProps });
|
|
88
|
+
}
|
|
89
|
+
return uniqBadges.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
90
|
+
startComponent,
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
Stack,
|
|
93
|
+
{
|
|
94
|
+
direction: "row",
|
|
95
|
+
sx: {
|
|
96
|
+
flexWrap: "wrap",
|
|
97
|
+
marginTop: inProfile ? "24px" : ""
|
|
98
|
+
},
|
|
99
|
+
children: uniqBadges.map((item) => {
|
|
100
|
+
const { badgeName, badgeIcon, badgeColor, badgeBackground } = item;
|
|
101
|
+
let icon;
|
|
102
|
+
if (badgeIcon) {
|
|
103
|
+
const isHttpIcon = ["http", "/", "data"].some((prefix) => badgeIcon.startsWith(prefix));
|
|
104
|
+
const badgeIconStyle = showIconOnly ? iconOnlyStyle : iconStyle;
|
|
105
|
+
if (!isHttpIcon) {
|
|
106
|
+
icon = /* @__PURE__ */ jsx(Icon, { className: "badge-icon", icon: badgeIcon, color: badgeColor, style: { ...badgeIconStyle } });
|
|
107
|
+
} else {
|
|
108
|
+
icon = /* @__PURE__ */ jsx(
|
|
109
|
+
Avatar,
|
|
110
|
+
{
|
|
111
|
+
className: "badge-icon",
|
|
112
|
+
sx: {
|
|
113
|
+
img: {
|
|
114
|
+
userSelect: "none !important",
|
|
115
|
+
WebkitUserSelect: "none !important",
|
|
116
|
+
WebkitUserDrag: "none !important"
|
|
117
|
+
},
|
|
118
|
+
background: "transparent",
|
|
119
|
+
...badgeIconStyle
|
|
120
|
+
},
|
|
121
|
+
src: badgeIcon,
|
|
122
|
+
children: /* @__PURE__ */ jsx(BrokenImageIcon, { sx: { ...badgeIconStyle, color: badgeColor } })
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const onlyIcon = showIconOnly && icon;
|
|
128
|
+
return /* @__PURE__ */ jsx(
|
|
129
|
+
Chip,
|
|
130
|
+
{
|
|
131
|
+
label: onlyIcon ? null : badgeName,
|
|
132
|
+
size: "small",
|
|
133
|
+
icon: onlyIcon && !!icon ? /* @__PURE__ */ jsx(Tooltip, { title: badgeName, placement: "top", children: icon }) : icon,
|
|
134
|
+
sx: {
|
|
135
|
+
color: badgeColor,
|
|
136
|
+
background: badgeBackground,
|
|
137
|
+
userSelect: "none",
|
|
138
|
+
fontSize: 12,
|
|
139
|
+
px: 0.25,
|
|
140
|
+
mr: spacing,
|
|
141
|
+
...!onlyIcon ? { my: "2px !important" } : { width: 20, height: 20 },
|
|
142
|
+
"@keyframes jump": {
|
|
143
|
+
"0%": {
|
|
144
|
+
transform: `translateY(0) ${getExtraAnimation()}`
|
|
145
|
+
},
|
|
146
|
+
"25%": {
|
|
147
|
+
transform: `translateY(-${animationHeight}px) ${getExtraAnimation()}`
|
|
148
|
+
},
|
|
149
|
+
"50%": {
|
|
150
|
+
transform: `translateY(0px) ${getExtraAnimation()}`
|
|
151
|
+
},
|
|
152
|
+
"75%": {
|
|
153
|
+
transform: `translateY(-${animationHeight}px) ${getExtraAnimation()}`
|
|
154
|
+
},
|
|
155
|
+
"100%": {
|
|
156
|
+
transform: `translateY(0) ${getExtraAnimation()}`
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"*": {
|
|
160
|
+
transition: "all 0.2s ease-in-out"
|
|
161
|
+
},
|
|
162
|
+
":hover": {
|
|
163
|
+
".badge-icon": {
|
|
164
|
+
// animation: 'jump 2s infinite',
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
...onlyIcon ? { "& .MuiChip-label": { display: "none" }, "& .MuiChip-icon": { m: 0 } } : {}
|
|
168
|
+
},
|
|
169
|
+
...restProps
|
|
170
|
+
},
|
|
171
|
+
badgeName
|
|
172
|
+
);
|
|
173
|
+
})
|
|
174
|
+
},
|
|
175
|
+
"badges"
|
|
176
|
+
)
|
|
177
|
+
] }) : null;
|
|
178
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Avatar } from "./avatar.mjs";
|
|
2
|
+
export { default as Avatars } from "./avatars.mjs";
|
|
3
|
+
export { default as AuthorInfo } from "./author-info.mjs";
|
|
4
|
+
export { default as SystemUser } from "./system-user.mjs";
|
|
5
|
+
export { default as Badge } from "./badge.mjs";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface Props {
|
|
3
|
+
name: string;
|
|
4
|
+
showDidAddress?: boolean;
|
|
5
|
+
showIcon?: boolean;
|
|
6
|
+
size?: 'sm' | 'normal';
|
|
7
|
+
icon?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export default function SystemUser({ name, showDidAddress, showIcon, size, icon, ...rest }: Props): import("react").JSX.Element;
|
|
10
|
+
export {};
|