From 1aa9f112ab3ea88a354d8fd00a90a7c2ed0fc5ee Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Sat, 7 Oct 2023 12:27:41 +0300 Subject: [PATCH 01/20] agora integration initial setaup --- client/packages/lowcoder/package.json | 2 + .../src/comps/comps/containerBase/utils.tsx | 1 + .../lowcoder/src/comps/comps/imageComp.tsx | 47 +- .../comps/comps/videoComp/videoContolComp.tsx | 226 ++++++++ .../comps/videoComp/videoControlButton.tsx | 376 +++++++++++++ .../comps/videoComp/videoMeetingComp.tsx | 323 +++++++++++ .../videoComp/videobuttonCompConstants.tsx | 111 ++++ .../src/comps/hooks/agoraFunctions.tsx | 144 +++++ .../lowcoder/src/comps/hooks/hookComp.tsx | 27 +- .../src/comps/hooks/hookCompTypes.tsx | 7 +- .../src/comps/hooks/videoControllerComp.tsx | 526 ++++++++++++++++++ client/packages/lowcoder/src/comps/index.tsx | 56 +- .../lowcoder/src/comps/uiCompRegistry.ts | 15 +- .../src/comps/utils/propertyUtils.tsx | 1 + .../packages/lowcoder/src/constants/Layers.ts | 1 + .../packages/lowcoder/src/i18n/locales/en.ts | 308 ++++++---- .../src/pages/editor/editorConstants.tsx | 6 +- 17 files changed, 2052 insertions(+), 125 deletions(-) create mode 100644 client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx create mode 100644 client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx create mode 100644 client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx create mode 100644 client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx create mode 100644 client/packages/lowcoder/src/comps/hooks/agoraFunctions.tsx create mode 100644 client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json index 278628768..4d856faee 100644 --- a/client/packages/lowcoder/package.json +++ b/client/packages/lowcoder/package.json @@ -36,6 +36,8 @@ "@types/react-signature-canvas": "^1.0.2", "@types/react-test-renderer": "^18.0.0", "@types/react-virtualized": "^9.21.21", + "agora-access-token": "^2.0.4", + "agora-rtc-sdk-ng": "^4.19.0", "ali-oss": "^6.17.1", "antd": "5.7.2", "antd-img-crop": "^4.12.2", diff --git a/client/packages/lowcoder/src/comps/comps/containerBase/utils.tsx b/client/packages/lowcoder/src/comps/comps/containerBase/utils.tsx index 35cc13d10..ca7ecd14d 100644 --- a/client/packages/lowcoder/src/comps/comps/containerBase/utils.tsx +++ b/client/packages/lowcoder/src/comps/comps/containerBase/utils.tsx @@ -95,6 +95,7 @@ export function oldContainerParamsToNew(params: any): any { container: { layout: params.value.layout, items: params.value.items }, }; const newParams = { ...params, value: newValue }; + // console.log("tempParams", newParams); // log.debug("params: ", params, "newParams: ", newParams); return newParams; } diff --git a/client/packages/lowcoder/src/comps/comps/imageComp.tsx b/client/packages/lowcoder/src/comps/comps/imageComp.tsx index 871bfa9df..48a5f4784 100644 --- a/client/packages/lowcoder/src/comps/comps/imageComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/imageComp.tsx @@ -1,15 +1,27 @@ import styled, { css } from "styled-components"; import { Section, sectionNames } from "lowcoder-design"; -import { clickEvent, eventHandlerControl } from "../controls/eventHandlerControl"; +import { + clickEvent, + eventHandlerControl, +} from "../controls/eventHandlerControl"; import { StringStateControl } from "../controls/codeStateControl"; import { UICompBuilder, withDefault } from "../generators"; -import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators/withExposing"; +import { + NameConfig, + NameConfigHidden, + withExposingConfigs, +} from "../generators/withExposing"; import { RecordConstructorToView } from "lowcoder-core"; import { useEffect, useRef, useState } from "react"; import _ from "lodash"; import ReactResizeDetector from "react-resize-detector"; import { styleControl } from "comps/controls/styleControl"; -import { ImageStyle, ImageStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants"; +import { + ImageStyle, + ImageStyleType, + heightCalculator, + widthCalculator, +} from "comps/controls/styleControlConstants"; import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; @@ -42,9 +54,9 @@ const getStyle = (style: ImageStyleType) => { img { border: 1px solid ${style.border}; border-radius: ${style.radius}; - margin: ${style.margin}; - padding: ${style.padding}; - max-width: ${widthCalculator(style.margin)}; + margin: ${style.margin}; + padding: ${style.padding}; + max-width: ${widthCalculator(style.margin)}; max-height: ${heightCalculator(style.margin)}; } @@ -67,7 +79,7 @@ const ContainerImg = (props: RecordConstructorToView) => { setWidth(img.naturalWidth); setHeight(img.naturalHeight); }; - } + }; useEffect(() => { const newImage = new Image(0, 0); @@ -79,14 +91,16 @@ const ContainerImg = (props: RecordConstructorToView) => { }; }, [props.src.value]); - useEffect(() =>{ + useEffect(() => { if (height && width) { onResize(); } - }, [height, width]) + }, [height, width]); // on safari const setStyle = (height: string, width: string) => { + console.log(width, height); + const img = imgRef.current; const imgDiv = img?.getElementsByTagName("div")[0]; const imgCurrent = img?.getElementsByTagName("img")[0]; @@ -117,7 +131,12 @@ const ContainerImg = (props: RecordConstructorToView) => { return ( -
+
{ })} -
{children.onEvent.getPropertyView()}
+
+ {children.onEvent.getPropertyView()} +
{children.autoHeight.getPropertyView()} {hiddenPropertyView(children)}
-
{children.style.getPropertyView()}
+
+ {children.style.getPropertyView()} +
); }) diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx new file mode 100644 index 000000000..6e3bd8c96 --- /dev/null +++ b/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx @@ -0,0 +1,226 @@ +import styled, { css } from "styled-components"; +import { Section, sectionNames } from "lowcoder-design"; +import { + clickEvent, + eventHandlerControl, +} from "../../controls/eventHandlerControl"; +import { StringStateControl } from "../../controls/codeStateControl"; +import { UICompBuilder, withDefault } from "../../generators"; +import { + NameConfig, + NameConfigHidden, + withExposingConfigs, +} from "../../generators/withExposing"; +import { RecordConstructorToView } from "lowcoder-core"; +import { useEffect, useRef, useState } from "react"; +import _ from "lodash"; +import ReactResizeDetector from "react-resize-detector"; +import { styleControl } from "comps/controls/styleControl"; +import { + ImageStyle, + ImageStyleType, + heightCalculator, + widthCalculator, +} from "comps/controls/styleControlConstants"; +import { hiddenPropertyView } from "comps/utils/propertyUtils"; +import { trans } from "i18n"; +import { AutoHeightControl } from "comps/controls/autoHeightControl"; +import { BoolControl } from "comps/controls/boolControl"; +import { Image as AntImage } from "antd"; +import { DEFAULT_IMG_URL } from "util/stringUtils"; +import { + Button100, + ButtonCompWrapper, + ButtonStyleControl, +} from "./videobuttonCompConstants"; + +const Container = styled.div<{ $style: ImageStyleType | undefined }>` + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + .ant-image, + img { + width: 100%; + height: 100%; + } + + img { + object-fit: contain; + pointer-events: auto; + } + + ${(props) => props.$style && getStyle(props.$style)} +`; + +const getStyle = (style: ImageStyleType) => { + return css` + img { + border: 1px solid ${style.border}; + border-radius: ${style.radius}; + margin: ${style.margin}; + padding: ${style.padding}; + max-width: ${widthCalculator(style.margin)}; + max-height: ${heightCalculator(style.margin)}; + } + + .ant-image-mask { + border-radius: ${style.radius}; + } + `; +}; + +const EventOptions = [clickEvent] as const; + +const ContainerImg = (props: RecordConstructorToView) => { + const imgRef = useRef(null); + const conRef = useRef(null); + const [width, setWidth] = useState(0); + const [height, setHeight] = useState(0); + + const imgOnload = (img: HTMLImageElement) => { + img.onload = function () { + setWidth(img.naturalWidth); + setHeight(img.naturalHeight); + }; + }; + + useEffect(() => { + const newImage = new Image(0, 0); + newImage.src = props.src.value; + imgOnload(newImage); + newImage.onerror = function (e) { + newImage.src = DEFAULT_IMG_URL; + imgOnload(newImage); + }; + }, [props.src.value]); + + useEffect(() => { + if (height && width) { + onResize(); + } + }, [height, width]); + + // on safari + const setStyle = (height: string, width: string) => { + console.log(width, height); + + const img = imgRef.current; + console.log("img", img); + const imgDiv = img?.getElementsByTagName("button")[0]; + console.log("button", imgDiv); + + const imgCurrent = img?.getElementsByTagName("button")[0]; + img!.style.height = height; + img!.style.width = width; + imgDiv!.style.height = height; + imgDiv!.style.width = width; + // imgCurrent!.style.height = height; + // imgCurrent!.style.width = width; + }; + + const onResize = () => { + const img = imgRef.current; + const container = conRef.current; + console.log(container?.clientWidth, container?.clientHeight); + + if (!img?.clientWidth || !img?.clientHeight || props.autoHeight || !width) { + return; + } + // fixme border style bug on safari + setStyle(container?.clientHeight + "px", container?.clientWidth + "px"); + // if ( + // (_.divide(container?.clientWidth!, container?.clientHeight!) || 0) > + // (_.divide(Number(width), Number(height)) || 0) + // ) { + // setStyle("100%", "auto"); + // } else { + // setStyle("auto", "100%"); + // } + }; + return ( + + +
+ + // isDefault(props.type) + // ? props.onEvent("click") + // : submitForm(editorState, props.form) + // } + > + m + +
+
+
+ ); +}; + +const childrenMap = { + src: withDefault(StringStateControl, "https://temp.im/350x400"), + onEvent: eventHandlerControl(EventOptions), + style: styleControl(ImageStyle), + autoHeight: withDefault(AutoHeightControl, "fixed"), + supportPreview: BoolControl, +}; + +let ImageBasicComp = new UICompBuilder(childrenMap, (props) => { + return ; +}) + .setPropertyViewFn((children) => { + return ( + <> +
+ {children.src.propertyView({ + label: trans("image.src"), + })} + {children.supportPreview.propertyView({ + label: trans("image.supportPreview"), + tooltip: trans("image.supportPreviewTip"), + })} +
+ +
+ {children.onEvent.getPropertyView()} +
+ +
+ {children.autoHeight.getPropertyView()} + {hiddenPropertyView(children)} +
+ +
+ {children.style.getPropertyView()} +
+ + ); + }) + .build(); + +ImageBasicComp = class extends ImageBasicComp { + override autoHeight(): boolean { + return this.children.autoHeight.getView(); + } +}; + +export const VideoContolComp = withExposingConfigs(ImageBasicComp, [ + new NameConfig("src", trans("image.srcDesc")), + NameConfigHidden, +]); diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx new file mode 100644 index 000000000..217cb1bc6 --- /dev/null +++ b/client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx @@ -0,0 +1,376 @@ +import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; +import { dropdownControl } from "comps/controls/dropdownControl"; +import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; +import { IconControl } from "comps/controls/iconControl"; +import { CompNameContext, EditorContext, EditorState } from "comps/editorState"; +import { withDefault } from "comps/generators"; +import { UICompBuilder } from "comps/generators/uiCompBuilder"; +import _ from "lodash"; +import { + disabledPropertyView, + hiddenPropertyView, + loadingPropertyView, +} from "comps/utils/propertyUtils"; +import { + CommonBlueLabel, + controlItem, + Dropdown, + Section, + sectionNames, +} from "lowcoder-design"; +import { trans } from "i18n"; +import styled, { css } from "styled-components"; + +import { + CommonNameConfig, + NameConfig, + withExposingConfigs, +} from "../../generators/withExposing"; +import { IForm } from "../formComp/formDataConstants"; +import { SimpleNameComp } from "../simpleNameComp"; +import { + Button100, + ButtonCompWrapper, + ButtonStyleControl, +} from "./videobuttonCompConstants"; +import { RefControl } from "comps/controls/refControl"; +import { + AutoHeightControl, + ImageStyleType, + heightCalculator, + widthCalculator, +} from "@lowcoder-ee/index.sdk"; +import { useEffect, useRef, useState } from "react"; +import ReactResizeDetector from "react-resize-detector"; + +const Container = styled.div<{ $style: any }>` + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + ${(props) => props.$style && getStyle(props.$style)} +`; + +const getStyle = (style: any) => { + return css` + button { + border: 1px solid ${style.border}; + border-radius: ${style.radius}; + margin: ${style.margin}; + padding: ${style.padding}; + max-width: ${widthCalculator(style.margin)}; + max-height: ${heightCalculator(style.margin)}; + } + `; +}; + +const FormLabel = styled(CommonBlueLabel)` + font-size: 13px; + margin-right: 4px; +`; + +const IconWrapper = styled.div<{ $style: any }>` + display: flex; + + ${(props) => props.$style && getStyleIcon(props.$style)} +`; + +function getStyleIcon(style: any) { + return css` + svg { + width: ${style.size} !important; + height: ${style.size} !important; + } + `; +} + +// const IconWrapper = styled.div<{ $styled: any }>` +// display: flex; +// svg { +// width: ${styled.width}px !important; +// height: ${styled.height}30px !important; +// } +// `; + +function getFormOptions(editorState: EditorState) { + return editorState + .uiCompInfoList() + .filter((info) => info.type === "form") + .map((info) => ({ + label: info.name, + value: info.name, + })); +} + +function getForm(editorState: EditorState, formName: string) { + const comp = editorState?.getUICompByName(formName); + if (comp && comp.children.compType.getView() === "form") { + return comp.children.comp as unknown as IForm; + } +} + +function getFormEventHandlerPropertyView( + editorState: EditorState, + formName: string +) { + const form = getForm(editorState, formName); + if (!form) { + return undefined; + } + return ( + + {form.onEventPropertyView( + <> + + editorState.setSelectedCompNames( + new Set([formName]), + "rightPanel" + ) + } + > + {formName} + + {trans("button.formButtonEvent")} + + )} + + ); +} + +class SelectFormControl extends SimpleNameComp { + override getPropertyView() { + const label = trans("button.formToSubmit"); + return controlItem( + { filterText: label }, + + {(editorState) => ( + <> + this.dispatchChangeValueAction(value)} + allowClear={true} + /> + {getFormEventHandlerPropertyView(editorState, this.value)} + + )} + + ); + } +} + +const typeOptions = [ + { + label: trans("button.default"), + value: "", + }, + { + label: trans("button.submit"), + value: "submit", + }, +] as const; + +function isDefault(type?: string) { + return !type; +} + +function submitForm(editorState: EditorState, formName: string) { + const form = getForm(editorState, formName); + if (form) { + form.submit(); + } +} + +let ButtonTmpComp = (function () { + const childrenMap = { + text: withDefault(StringControl, trans("button.button")), + iconSize: withDefault(StringControl, "20px"), + type: dropdownControl(typeOptions, ""), + autoHeight: withDefault(AutoHeightControl, "fixed"), + onEvent: ButtonEventHandlerControl, + disabled: BoolCodeControl, + loading: BoolCodeControl, + form: SelectFormControl, + prefixIcon: IconControl, + suffixIcon: IconControl, + style: ButtonStyleControl, + viewRef: RefControl, + }; + + return new UICompBuilder(childrenMap, (props) => { + const [width, setWidth] = useState(120); + const [height, setHeight] = useState(0); + + const imgRef = useRef(null); + const conRef = useRef(null); + useEffect(() => { + if (height && width) { + onResize(); + console.log("props", props, height, width); + } + }, [height, width]); + + const setStyle = (height: string, width: string) => { + console.log(width, height); + + const img = imgRef.current; + + const imgDiv = img?.getElementsByTagName("button")[0]; + console.log("img 1", img); + const imgCurrent = img?.getElementsByTagName("button")[0]; + console.log("img 2", imgCurrent); + img!.style.height = height; + img!.style.width = width; + imgDiv!.style.height = height; + imgDiv!.style.width = width; + // imgCurrent!.style.height = height; + // imgCurrent!.style.width = width; + }; + + const onResize = () => { + const img = imgRef.current; + console.log("img", img); + const container = conRef.current; + // console.log("img", container); + console.log( + "img", + !img?.clientWidth, + !img?.clientHeight, + props.autoHeight, + !width + ); + if ( + !img?.clientWidth || + !img?.clientHeight || + props.autoHeight || + !width + ) { + return; + } + // fixme border style bug on safari + // if ( + // (_.divide(container?.clientWidth!, container?.clientHeight!) || 0) > + // (_.divide(Number(width), Number(height)) || 0) + // ) { + // setStyle("100%", "auto"); + // } else { + console.log( + container?.clientHeight + "px", + container?.clientWidth + "px" + ); + + setStyle(container?.clientHeight + "px", container?.clientWidth + "px"); + // } + }; + + return ( + + {(editorState) => ( + + +
+ + isDefault(props.type) + ? props.onEvent("click") + : submitForm(editorState, props.form) + } + > + {props.prefixIcon && ( + + {props.prefixIcon} + + )} + { + props.text || + (props.prefixIcon || props.suffixIcon ? undefined : " ") // Avoid button disappearing + } + {props.suffixIcon && ( + + {props.suffixIcon} + + )} + +
+
+
+ )} +
+ ); + }) + .setPropertyViewFn((children) => ( + <> +
+ {children.text.propertyView({ label: trans("text") })} + {children.autoHeight.getPropertyView()} +
+
+ {children.type.propertyView({ + label: trans("prop.type"), + radioButton: true, + })} + {isDefault(children.type.getView()) + ? [ + children.onEvent.getPropertyView(), + disabledPropertyView(children), + loadingPropertyView(children), + ] + : children.form.getPropertyView()} +
+ +
+ {children.prefixIcon.propertyView({ + label: trans("button.prefixIcon"), + })} + {children.suffixIcon.propertyView({ + label: trans("button.suffixIcon"), + })} + {children.iconSize.propertyView({ + label: trans("meeting.iconSize"), + })} + {hiddenPropertyView(children)} +
+
+ {children.style.getPropertyView()} +
+ + )) + .build(); +})(); +ButtonTmpComp = class extends ButtonTmpComp { + override autoHeight(): boolean { + return this.children.autoHeight.getView(); + } +}; +export const VideoControlButton = withExposingConfigs(ButtonTmpComp, [ + new NameConfig("text", trans("button.textDesc")), + new NameConfig("loading", trans("button.loadingDesc")), + ...CommonNameConfig, +]); diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx new file mode 100644 index 000000000..460bebd63 --- /dev/null +++ b/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx @@ -0,0 +1,323 @@ +import { + ArrayControl, + ArrayOrJSONObjectControl, + BoolCodeControl, + JSONObjectArrayControl, + NumberControl, + StringControl, +} from "comps/controls/codeControl"; +import { dropdownControl } from "comps/controls/dropdownControl"; +import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; +import { IconControl } from "comps/controls/iconControl"; +import { CompNameContext, EditorContext, EditorState } from "comps/editorState"; +import { withDefault } from "comps/generators"; +import { UICompBuilder } from "comps/generators/uiCompBuilder"; +import ReactResizeDetector from "react-resize-detector"; +import _ from "lodash"; +import { + CommonBlueLabel, + controlItem, + Dropdown, + Section, + sectionNames, +} from "lowcoder-design"; +import { trans } from "i18n"; + +import styled, { css } from "styled-components"; +import { + CommonNameConfig, + NameConfig, + withExposingConfigs, +} from "../../generators/withExposing"; +import { IForm } from "../formComp/formDataConstants"; +import { SimpleNameComp } from "../simpleNameComp"; +import { ButtonStyleControl } from "./videobuttonCompConstants"; +import { RefControl } from "comps/controls/refControl"; +import { useEffect, useRef, useState } from "react"; + +import { AutoHeightControl } from "comps/controls/autoHeightControl"; +import { + arrayStringExposingStateControl, + booleanExposingStateControl, + jsonObjectExposingStateControl, + stringExposingStateControl, + withMethodExposing, +} from "@lowcoder-ee/index.sdk"; +// import useAgora from "@lowcoder-ee/comps/hooks/agoraFunctions"; + +const FormLabel = styled(CommonBlueLabel)` + font-size: 13px; + margin-right: 4px; +`; + +const IconWrapper = styled.div` + display: flex; +`; + +function getFormOptions(editorState: EditorState) { + return editorState + .uiCompInfoList() + .filter((info) => info.type === "form") + .map((info) => ({ + label: info.name, + value: info.name, + })); +} +const Container = styled.div<{ $style: any }>` + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + ${(props) => props.$style && getStyle(props.$style)} +`; + +const getStyle = (style: any) => { + return css` + button { + border: 1px solid ${style.border}; + border-radius: ${style.radius}; + margin: ${style.margin}; + padding: ${style.padding}; + } + `; +}; +function getForm(editorState: EditorState, formName: string) { + const comp = editorState?.getUICompByName(formName); + if (comp && comp.children.compType.getView() === "form") { + return comp.children.comp as unknown as IForm; + } +} + +function getFormEventHandlerPropertyView( + editorState: EditorState, + formName: string +) { + const form = getForm(editorState, formName); + if (!form) { + return undefined; + } + + return ( + + {form.onEventPropertyView( + <> + + editorState.setSelectedCompNames( + new Set([formName]), + "rightPanel" + ) + } + > + {formName} + + {trans("button.formButtonEvent")} + + )} + + ); +} + +class SelectFormControl extends SimpleNameComp { + override getPropertyView() { + const label = trans("button.formToSubmit"); + return controlItem( + { filterText: label }, + + {(editorState) => ( + <> + this.dispatchChangeValueAction(value)} + allowClear={true} + /> + {getFormEventHandlerPropertyView(editorState, this.value)} + + )} + + ); + } +} + +const typeOptions = [ + { + label: trans("button.default"), + value: "", + }, + { + label: trans("button.submit"), + value: "submit", + }, +] as const; + +let VideoCompBuilder = (function (props) { + const childrenMap = { + autoHeight: withDefault(AutoHeightControl, "fixed"), + type: dropdownControl(typeOptions, ""), + onEvent: ButtonEventHandlerControl, + disabled: BoolCodeControl, + loading: BoolCodeControl, + form: SelectFormControl, + prefixIcon: IconControl, + suffixIcon: IconControl, + style: ButtonStyleControl, + viewRef: RefControl, + appId: withDefault(StringControl, trans("prop.appid")), /// + videokey: withDefault(StringControl, trans("prop.videokey")), + participants: arrayStringExposingStateControl("participants"), + userId: stringExposingStateControl( + "text", + trans("meeting.userId", { name: "{{currentUser.name}}" }) + ), + }; + // const { client, videoHeight, videoWidth, setHeight, setWidth } = useAgora(); + + return new UICompBuilder(childrenMap, (props) => { + console.log("userId", props.userId.value); + // "afd10eabe68a4de68a76461be92c693c" + const videoRef = useRef(null); + const conRef = useRef(null); + + useEffect(() => { + onResize(); + }, []); + + useEffect(() => { + if (props.participants.value.length > 0) { + console.log("bbb", props.participants.value); + } + }, [props.participants.value]); + + const onResize = async () => { + const container = conRef.current; + let videoCo = videoRef.current; + videoCo!.style.height = container?.clientHeight + "px"; + videoCo!.style.width = container?.clientWidth + "px"; + }; + + return ( + + {(editorState) => ( + + + + + + )} + + ); + }) + .setPropertyViewFn((children) => ( + <> +
+ {children.userId.propertyView({ + label: trans("meeting.userId"), + })} + {children.autoHeight.getPropertyView()} + {children.videokey.propertyView({ + label: trans("prop.videokey"), + })} +
+ {/*
+ {/* {hiddenPropertyView(children)} +
*/} + + {/*
+ {children.type.propertyView({ + label: trans("prop.type"), + radioButton: true, + })} */} + {/* {isDefault(children.type.getView()) + ? [ + children.onEvent.getPropertyView(), + disabledPropertyView(children), + loadingPropertyView(children), + ] + : children.form.getPropertyView()} */} + {/*
*/} + + {/*
+ {children.prefixIcon.propertyView({ + label: trans("button.prefixIcon"), + })} + {children.suffixIcon.propertyView({ + label: trans("button.suffixIcon"), + })} + {hiddenPropertyView(children)} +
+ +
+ {children.style.getPropertyView()} +
*/} + + )) + .build(); +})(); + +VideoCompBuilder = class extends VideoCompBuilder { + override autoHeight(): boolean { + return this.children.autoHeight.getView(); + } +}; + +VideoCompBuilder = withMethodExposing(VideoCompBuilder, [ + { + method: { + name: "audioControl", + description: trans("meeting.actionBtnDesc"), + params: [], + }, + execute: (comp, values) => { + // let value = !comp.children.audioControl.getView().value; + // turnOnMicrophone(value); + // comp.children.audioControl.change(value); + }, + }, + // { + // method: { + // name: "videoControl", + // description: trans("meeting.actionBtnDesc"), + // params: [], + // }, + // execute: (comp, values) => { + // let value = !comp.children.videoControl.getView().value; + // turnOnCamera(value); + // comp.children.videoControl.change(value); + // }, + // }, + // { + // method: { + // name: "startMeeting", + // description: trans("meeting.actionBtnDesc"), + // params: [], + // }, + // execute: (comp, values) => { + // publishVideo(comp.children.appId.getView(), "testsdaadasdsa"); + // }, + // }, + // { + // method: { + // name: "endCall", + // description: trans("meeting.actionBtnDesc"), + // params: [], + // }, + // execute: (comp, values) => { + // let value = !comp.children.endCall.getView().value; + // leaveChannel(); + // comp.children.endCall.change(value); + // }, + // }, +]); + +export const VideoMeetingComp = withExposingConfigs(VideoCompBuilder, [ + // new NameConfig("appId", trans("button.textDesc")), + new NameConfig("loading", trans("button.loadingDesc")), + ...CommonNameConfig, +]); diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx new file mode 100644 index 000000000..26da52f34 --- /dev/null +++ b/client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx @@ -0,0 +1,111 @@ +import { Button } from "antd"; +import { styleControl } from "comps/controls/styleControl"; +import { + ButtonStyleType, + ButtonStyle, +} from "comps/controls/styleControlConstants"; +import { migrateOldData } from "comps/generators/simpleGenerators"; +import styled, { css } from "styled-components"; +import { genActiveColor, genHoverColor } from "lowcoder-design"; +import { refMethods } from "comps/generators/withMethodExposing"; +import { + blurMethod, + clickMethod, + focusWithOptions, +} from "comps/utils/methodUtils"; + +export function getButtonStyle(buttonStyle: ButtonStyleType) { + const hoverColor = genHoverColor(buttonStyle.background); + const activeColor = genActiveColor(buttonStyle.background); + return css` + &&& { + border-radius: ${buttonStyle.radius}; + margin: ${buttonStyle.margin}; + padding: ${buttonStyle.padding}; + &:not(:disabled) { + // click animation color + --antd-wave-shadow-color: ${buttonStyle.border}; + border-color: ${buttonStyle.border}; + color: ${buttonStyle.text}; + background-color: ${buttonStyle.background}; + border-radius: ${buttonStyle.radius}; + margin: ${buttonStyle.margin}; + padding: ${buttonStyle.padding}; + + :hover, + :focus { + color: ${buttonStyle.text}; + background-color: ${hoverColor}; + border-color: ${buttonStyle.border === buttonStyle.background + ? hoverColor + : buttonStyle.border}; + } + + :active { + color: ${buttonStyle.text}; + background-color: ${activeColor}; + border-color: ${buttonStyle.border === buttonStyle.background + ? activeColor + : buttonStyle.border}; + } + } + } + `; +} + +export const Button100 = styled(Button)<{ $buttonStyle?: ButtonStyleType }>` + ${(props) => props.$buttonStyle && getButtonStyle(props.$buttonStyle)} + width: 100%; + height: auto; + display: inline-flex; + justify-content: center; + align-items: center; + overflow: hidden; + span { + overflow: hidden; + text-overflow: ellipsis; + } + gap: 6px; +`; + +export const ButtonCompWrapper = styled.div<{ disabled: boolean }>` + // The button component is disabled but can respond to drag & select events + ${(props) => + props.disabled && + ` + cursor: not-allowed; + button:disabled { + pointer-events: none; + } + `}; +`; + +/** + * Compatible with old data 2022-08-05 + */ +function fixOldData(oldData: any) { + if ( + oldData && + (oldData.hasOwnProperty("backgroundColor") || + oldData.hasOwnProperty("borderColor") || + oldData.hasOwnProperty("color")) + ) { + return { + background: oldData.backgroundColor, + border: oldData.borderColor, + text: oldData.color, + }; + } + return oldData; +} +const ButtonTmpStyleControl = styleControl(ButtonStyle); +export const ButtonStyleControl = migrateOldData( + ButtonTmpStyleControl, + fixOldData +); + +export const buttonRefMethods = refMethods([ + focusWithOptions, + blurMethod, + clickMethod, +]); diff --git a/client/packages/lowcoder/src/comps/hooks/agoraFunctions.tsx b/client/packages/lowcoder/src/comps/hooks/agoraFunctions.tsx new file mode 100644 index 000000000..c82de1180 --- /dev/null +++ b/client/packages/lowcoder/src/comps/hooks/agoraFunctions.tsx @@ -0,0 +1,144 @@ +import { useEffect, useState } from "react"; +import AgoraRTC, { + IAgoraRTCClient, + IAgoraRTCRemoteUser, + ICameraVideoTrack, + IMicrophoneAudioTrack, +} from "agora-rtc-sdk-ng"; // Update the import with correct types +import { v4 as uuidv4 } from "uuid"; + +const useAgora = () => { + const [client, setClient] = useState(null); + const [audioTrack, setAudioTrack] = useState( + null + ); + const [videoTrack, setVideoTrack] = useState(null); + const [isJoined, setIsJoined] = useState(false); + const [videoHeight, setHeight] = useState(200); + const [videoWidth, setWidth] = useState(200); + + const initializeAgora = () => { + const agoraClient = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" }); + setClient(agoraClient); + }; + + const turnOnCamera = async (flag: any) => { + if (videoTrack) { + return videoTrack.setEnabled(flag); + } + const newVideoTrack = await AgoraRTC.createCameraVideoTrack(); + newVideoTrack.play("camera-video"); + setVideoTrack(newVideoTrack); + }; + + const turnOnMicrophone = async (flag: any) => { + if (audioTrack) { + return audioTrack.setEnabled(flag); + } + const newAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); + newAudioTrack.play(); + setAudioTrack(newAudioTrack); + }; + + const leaveChannel = async () => { + if (isJoined) { + if (!client) { + console.error("Agora client is not initialized"); + return; + } + + if (!client.localTracks.length) { + console.error("No local tracks to unpublish"); + return; + } + + if (videoTrack) { + await turnOnCamera(false); + await client.unpublish(videoTrack); + videoTrack.stop(); + setVideoTrack(null); + } + + if (audioTrack) { + await turnOnMicrophone(false); + await client.unpublish(audioTrack); + audioTrack.stop(); + setAudioTrack(null); + } + + await client.leave(); + setIsJoined(false); + } + }; + + const joinChannel = async (appId: any, channel: any, token: any) => { + if (!channel) { + channel = "react-room"; + } + + if (isJoined) { + await leaveChannel(); + } + + client?.on("user-published", onUserPublish); + + await client?.join(appId, channel, token || null, uuidv4()); + setIsJoined(true); + }; + + const publishVideo = async (appId: any, channel: any) => { + await turnOnCamera(true); + + if (!isJoined) { + await joinChannel(appId, channel, null); + } + + await client?.publish(videoTrack!); + + const mediaStreamTrack = videoTrack?.getMediaStreamTrack(); + + if (mediaStreamTrack) { + const videoSettings = mediaStreamTrack.getSettings(); + const videoWidth = videoSettings.width; + const videoHeight = videoSettings.height; + setWidth(videoWidth!); + setHeight(videoHeight!); + console.log(`Video width: ${videoWidth}px, height: ${videoHeight}px`); + } else { + console.error("Media stream track not found"); + } + }; + + const onUserPublish = async ( + user: IAgoraRTCRemoteUser, + mediaType: string + ) => { + if (mediaType === "video") { + const remoteTrack = await client?.subscribe(user, mediaType); + remoteTrack?.play("remote-video"); + } + if (mediaType === "audio") { + const remoteTrack = await client?.subscribe(user, mediaType); + remoteTrack?.play(); + } + }; + + return { + client, + audioTrack, + videoTrack, + isJoined, + turnOnCamera, + turnOnMicrophone, + leaveChannel, + joinChannel, + publishVideo, + initializeAgora, + videoWidth, + videoHeight, + setHeight, + setWidth, + }; +}; + +export default useAgora; diff --git a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx index b71169493..e5fa4d598 100644 --- a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx +++ b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx @@ -13,7 +13,11 @@ import { import { hookToStateComp, simpleValueComp } from "comps/generators/hookToComp"; import { withSimpleExposing } from "comps/generators/withExposing"; import { DrawerComp } from "comps/hooks/drawerComp"; -import { HookCompConstructor, HookCompMapRawType, HookCompType } from "comps/hooks/hookCompTypes"; +import { + HookCompConstructor, + HookCompMapRawType, + HookCompType, +} from "comps/hooks/hookCompTypes"; import { ModalComp } from "comps/hooks/modalComp"; import { trans } from "i18n"; import _ from "lodash"; @@ -28,6 +32,7 @@ import { MessageComp } from "./messageComp"; import { ThemeComp } from "./themeComp"; import UrlParamsHookComp from "./UrlParamsHookComp"; import { UtilsComp } from "./utilsComp"; +import { VideoCOntrollerComp } from "./videoControllerComp"; window._ = _; window.dayjs = dayjs; @@ -85,11 +90,12 @@ const HookMap: HookCompMapRawType = { currentTime: CurrentTimeHookComp, lodashJsLib: LodashJsLib, dayJsLib: DayJsLib, - momentJsLib: DayJsLib, // old components use this hook + momentJsLib: DayJsLib, // old components use this hook utils: UtilsComp, message: MessageComp, localStorage: LocalStorageComp, modal: ModalComp, + meeting: VideoCOntrollerComp, currentUser: CurrentUserHookComp, urlParams: UrlParamsHookComp, drawer: DrawerComp, @@ -111,9 +117,12 @@ function SelectHookView(props: { // Select the modal and its subcomponents on the left to display the modal useEffect(() => { if ( - (props.compType !== "modal" && props.compType !== "drawer") || + (props.compType !== "modal" && + props.compType !== "drawer" && + props.compType !== "meeting") || !selectedComp || - (editorState.selectSource !== "addComp" && editorState.selectSource !== "leftPanel") + (editorState.selectSource !== "addComp" && + editorState.selectSource !== "leftPanel") ) { return; } else if ((selectedComp as any).children.comp === props.comp) { @@ -125,7 +134,9 @@ function SelectHookView(props: { } else { // all child components of modal const allChildComp = getAllCompItems((props.comp as any).getCompTree()); - const selectChildComp = Object.values(allChildComp).find((child) => child === selectedComp); + const selectChildComp = Object.values(allChildComp).find( + (child) => child === selectedComp + ); const visible = props.comp.children.visible.getView().value; if (selectChildComp && !visible) { props.comp.children.visible.dispatch( @@ -140,7 +151,11 @@ function SelectHookView(props: { }, [selectedComp, editorState.selectSource]); return ( -
editorState.setSelectedCompNames(new Set([props.compName]))}> +
+ editorState.setSelectedCompNames(new Set([props.compName])) + } + > {props.children}
); diff --git a/client/packages/lowcoder/src/comps/hooks/hookCompTypes.tsx b/client/packages/lowcoder/src/comps/hooks/hookCompTypes.tsx index 1db9875a0..86aece2a2 100644 --- a/client/packages/lowcoder/src/comps/hooks/hookCompTypes.tsx +++ b/client/packages/lowcoder/src/comps/hooks/hookCompTypes.tsx @@ -3,6 +3,7 @@ import { withExposingRaw } from "comps/generators/withExposing"; const AllHookComp = [ "modal", "drawer", + "meeting", "title", "windowSize", "currentTime", @@ -17,7 +18,7 @@ const AllHookComp = [ "theme", ] as const; -export type HookCompType = typeof AllHookComp[number]; +export type HookCompType = (typeof AllHookComp)[number]; const AllHookCompSet = new Set(AllHookComp); export const isHookComp = (compType: string) => { @@ -41,6 +42,10 @@ const HookCompConfig: Record< category: "ui", singleton: false, }, + meeting: { + category: "ui", + singleton: false, + }, lodashJsLib: { category: "hide", }, diff --git a/client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx b/client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx new file mode 100644 index 000000000..f5cb68aca --- /dev/null +++ b/client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx @@ -0,0 +1,526 @@ +import { CloseOutlined } from "@ant-design/icons"; +import { Button } from "antd"; +import { ContainerCompBuilder } from "comps/comps/containerBase/containerCompBuilder"; +import { + gridItemCompToGridItems, + InnerGrid, +} from "comps/comps/containerComp/containerView"; +import { AutoHeightControl } from "comps/controls/autoHeightControl"; +import { BoolControl } from "comps/controls/boolControl"; +import { + JSONObjectArrayControl, + NumberControl, + StringControl, +} from "comps/controls/codeControl"; +import { + arrayStringExposingStateControl, + booleanExposingStateControl, + jsonObjectExposingStateControl, + jsonValueExposingStateControl, + numberExposingStateControl, +} from "comps/controls/codeStateControl"; +import { PositionControl } from "comps/controls/dropdownControl"; +import { + closeEvent, + eventHandlerControl, +} from "comps/controls/eventHandlerControl"; +import { styleControl } from "comps/controls/styleControl"; +import { DrawerStyle } from "comps/controls/styleControlConstants"; +import { withDefault } from "comps/generators"; +import { withMethodExposing } from "comps/generators/withMethodExposing"; +import { BackgroundColorContext } from "comps/utils/backgroundColorContext"; +import { CanvasContainerID } from "constants/domLocators"; +import { Layers } from "constants/Layers"; +import { trans } from "i18n"; +import { changeChildAction } from "lowcoder-core"; +import { + Drawer, + HintPlaceHolder, + Section, + sectionNames, +} from "lowcoder-design"; +import { useCallback, useEffect, useState } from "react"; +import { ResizeHandle } from "react-resizable"; +import styled from "styled-components"; +import { useUserViewMode } from "util/hooks"; +import { isNumeric } from "util/stringUtils"; +import { NameConfig, withExposingConfigs } from "../generators/withExposing"; +import { v4 as uuidv4 } from "uuid"; + +import AgoraRTC, { + ICameraVideoTrack, + IMicrophoneAudioTrack, + IAgoraRTCClient, + IAgoraRTCRemoteUser, + IRemoteVideoTrack, +} from "agora-rtc-sdk-ng"; +import { JSONObject } from "@lowcoder-ee/index.sdk"; + +const EventOptions = [closeEvent] as const; + +const DEFAULT_SIZE = 378; +const DEFAULT_PADDING = 16; + +const DrawerWrapper = styled.div` + // Shield the mouse events of the lower layer, the mask can be closed in the edit mode to prevent the lower layer from sliding + pointer-events: auto; +`; + +const ButtonStyle = styled(Button)` + position: absolute; + left: 0; + top: 0; + z-index: 10; + font-weight: 700; + box-shadow: none; + color: rgba(0, 0, 0, 0.45); + height: 54px; + width: 54px; + + svg { + width: 16px; + height: 16px; + } + + &, + :hover, + :focus { + background-color: transparent; + border: none; + } + + :hover, + :focus { + color: rgba(0, 0, 0, 0.75); + } +`; + +// If it is a number, use the px unit by default +function transToPxSize(size: string | number) { + return isNumeric(size) ? size + "px" : (size as string); +} + +const PlacementOptions = [ + { + label: trans("drawer.top"), + value: "top", + }, + { + label: trans("drawer.right"), + value: "right", + }, + { + label: trans("drawer.bottom"), + value: "bottom", + }, + { + label: trans("drawer.left"), + value: "left", + }, +] as const; + +let client: IAgoraRTCClient = AgoraRTC.createClient({ + mode: "rtc", + codec: "vp8", +}); + +let audioTrack: IMicrophoneAudioTrack; +let videoTrack: ICameraVideoTrack; + +const turnOnCamera = async (flag?: boolean) => { + if (videoTrack) { + return videoTrack.setEnabled(flag!); + } + videoTrack = await AgoraRTC.createCameraVideoTrack(); + videoTrack.play("camera-video"); +}; + +const turnOnMicrophone = async (flag?: boolean) => { + if (audioTrack) { + return audioTrack.setEnabled(flag!); + } + audioTrack = await AgoraRTC.createMicrophoneAudioTrack(); + audioTrack.play(); +}; + +const leaveChannel = async () => { + console.log("isJoined", isJoined); + + if (!client) { + console.error("Agora client is not initialized"); + return; + } + + if (!client.localTracks.length) { + console.error("No local tracks to unpublish"); + return; + } + if (videoTrack) { + // await turnOnCamera(false); + await client.unpublish(videoTrack); + videoTrack.stop(); + } + + if (audioTrack) { + // await turnOnMicrophone(false); + await client.unpublish(audioTrack); + audioTrack.stop(); + } + + await client.leave(); + isJoined = false; // Update the flag to indicate that you have left the channel +}; +let isJoined = false; + +const joinChannel = async (appId: any, channel: any, token: any) => { + if (!channel) { + channel = "react-room"; + } + + if (isJoined) { + await leaveChannel(); + } + + // client.on("user-published", onUserPublish); + + await client.join( + appId, + channel, + token || null, + Math.floor(100000 + Math.random() * 900000) + ); + + isJoined = true; +}; + +const publishVideo = async (appId: any, channel: any, height: any) => { + console.log("publishVideo", appId, channel, isJoined); + await turnOnCamera(true); + console.log(appId, channel); + + if (!isJoined) { + await joinChannel(appId, channel, null); + } + + console.log("publish videoTrack ", videoTrack); + + await client.publish(videoTrack); + + // turnOnCamera(true); + const mediaStreamTrack = videoTrack.getMediaStreamTrack(); + + if (mediaStreamTrack) { + const videoSettings = mediaStreamTrack.getSettings(); + const videoWidth = videoSettings.width; + const videoHeight = videoSettings.height; + console.log("videoHeight ", videoHeight); + + height.videoWidth.change(videoWidth); + height.videoHeight.change(videoHeight); + console.log(`Video width: ${videoWidth}px, height: ${videoHeight}px`); + } else { + console.error("Media stream track not found"); + } +}; + +const onUserPublish = async ( + user: IAgoraRTCRemoteUser, + mediaType: "video" | "audio" +) => { + if (mediaType === "video") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play("remote-video"); + } + if (mediaType === "audio") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play(); + } +}; + +let MTComp = (function () { + const childrenMap = { + visible: booleanExposingStateControl("visible"), + onEvent: eventHandlerControl(EventOptions), + width: StringControl, + height: StringControl, + autoHeight: AutoHeightControl, + style: styleControl(DrawerStyle), + placement: PositionControl, + maskClosable: withDefault(BoolControl, true), + showMask: withDefault(BoolControl, true), + audioControl: booleanExposingStateControl("false"), + videoControl: booleanExposingStateControl("true"), + endCall: booleanExposingStateControl("false"), + videoSettings: jsonObjectExposingStateControl(""), + videoWidth: numberExposingStateControl("videoWidth", 200), + videoHeight: numberExposingStateControl("videoHeight", 200), + appId: withDefault(StringControl, trans("prop.appid")), + participants: jsonValueExposingStateControl("participants"), + }; + return new ContainerCompBuilder(childrenMap, (props, dispatch) => { + const isTopBom = ["top", "bottom"].includes(props.placement); + const { items, ...otherContainerProps } = props.container; + const userViewMode = useUserViewMode(); + const resizable = !userViewMode && (!isTopBom || !props.autoHeight); + const onResizeStop = useCallback( + ( + e: React.SyntheticEvent, + node: HTMLElement, + size: { width: number; height: number }, + handle: ResizeHandle + ) => { + isTopBom + ? dispatch(changeChildAction("height", size.height, true)) + : dispatch(changeChildAction("width", size.width, true)); + }, + [dispatch, isTopBom] + ); + + const usersWithVideoTracks: any = {}; + + useEffect(() => { + console.log("nnnn ", props.participants); + }, [props.participants.value]); + + useEffect(() => { + if (client) { + console.log("REGISTERING LISTNERS"); + + client.on( + "user-published", + async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { + if (mediaType === "video") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play("remote-video"); + } + if (mediaType === "audio") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play(); + } + const remoteVideoTrack = user.videoTrack; + if (remoteVideoTrack) { + props.participants.onChange([JSON.stringify(user.uid)]); + console.log("usersWithVideoTracks", props.participants); + } + } + ); + + client.on("user-joined", (user: IAgoraRTCRemoteUser) => { + // usersWithVideoTracks[user.uid] = { user, videoTracks: [] }; + // props.participants.onChange(usersWithVideoTracks); + // console.log( + // "userJoined", + // user.uid, + // props.participants.value, + // usersWithVideoTracks + // ); + // const uid = user.uid; + // usersWithVideoTracks[uid] = { user, videoTracks: [] }; + }); + client.on("user-offline", (uid: any, reason: any) => { + console.log(`User ${uid} left the channel.`); + }); + client.on("user-published", (user, mediaType) => { + console.log(`User ${user.uid} published ${user.videoTrack} stream.`); + }); + client.on("stream-removed", (user: IAgoraRTCRemoteUser) => { + console.log(`Stream from user ${user.uid} removed.`); + }); + client.on("stream-added", (user: IAgoraRTCRemoteUser) => { + console.log("stream-added"); + + if (user.hasVideo) { + console.log(`Stream from user ${user.videoTrack} added.`); + } + }); + } + // turnOnCamera(true); + }, [client]); + + return ( + + + + document.querySelector(`#${CanvasContainerID}`) || document.body + } + footer={null} + width={transToPxSize(props.width || DEFAULT_SIZE)} + height={ + !props.autoHeight + ? transToPxSize(props.height || DEFAULT_SIZE) + : "" + } + onClose={(e) => { + props.visible.onChange(false); + }} + afterOpenChange={(visible) => { + if (!visible) { + props.onEvent("close"); + } + }} + zIndex={Layers.drawer} + maskClosable={props.maskClosable} + mask={props.showMask} + > + { + props.visible.onChange(false); + }} + > + + + + + + + ); + }) + .setPropertyViewFn((children) => ( + <> +
+ {children.appId.propertyView({ label: trans("prop.appid") })} + {children.placement.propertyView({ + label: trans("drawer.placement"), + radioButton: true, + })} + {["top", "bottom"].includes(children.placement.getView()) + ? children.autoHeight.getPropertyView() + : children.width.propertyView({ + label: trans("drawer.width"), + tooltip: trans("drawer.widthTooltip"), + placeholder: DEFAULT_SIZE + "", + })} + {!children.autoHeight.getView() && + ["top", "bottom"].includes(children.placement.getView()) && + children.height.propertyView({ + label: trans("drawer.height"), + tooltip: trans("drawer.heightTooltip"), + placeholder: DEFAULT_SIZE + "", + })} + {children.maskClosable.propertyView({ + label: trans("prop.maskClosable"), + })} + {children.showMask.propertyView({ + label: trans("prop.showMask"), + })} +
+
+ {children.onEvent.getPropertyView()} +
+
+ {children.style.getPropertyView()} +
+ + )) + .build(); +})(); + +MTComp = class extends MTComp { + override autoHeight(): boolean { + return false; + } +}; + +MTComp = withMethodExposing(MTComp, [ + { + method: { + name: "openDrawer", + description: trans("drawer.openDrawerDesc"), + params: [], + }, + execute: (comp, values) => { + comp.children.visible.getView().onChange(true); + }, + }, + { + method: { + name: "audioControl", + description: trans("meeting.actionBtnDesc"), + params: [], + }, + execute: (comp, values) => { + let value = !comp.children.audioControl.getView().value; + turnOnMicrophone(value); + comp.children.audioControl.change(value); + }, + }, + { + method: { + name: "videoControl", + description: trans("meeting.actionBtnDesc"), + params: [], + }, + execute: (comp, values) => { + let value = !comp.children.videoControl.getView().value; + turnOnCamera(value); + comp.children.videoControl.change(value); + }, + }, + { + method: { + name: "startMeeting", + description: trans("meeting.actionBtnDesc"), + params: [], + }, + execute: async (comp, values) => { + await publishVideo( + comp.children.appId.getView(), + "testsdaadasdsa", + comp.children + ); + }, + }, + { + method: { + name: "endCall", + description: trans("meeting.actionBtnDesc"), + params: [], + }, + execute: async (comp, values) => { + let value = !comp.children.endCall.getView().value; + await leaveChannel(); + comp.children.endCall.change(value); + }, + }, + { + method: { + name: "closeDrawer", + description: trans("drawer.closeDrawerDesc"), + params: [], + }, + execute: (comp, values) => { + comp.children.visible.getView().onChange(false); + }, + }, +]); + +export const VideoCOntrollerComp = withExposingConfigs(MTComp, [ + new NameConfig("visible", trans("export.visibleDesc")), + new NameConfig("appId", trans("prop.appid")), + new NameConfig("participants", trans("prop.participants")), +]); diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx index 16668379d..e48516ac3 100644 --- a/client/packages/lowcoder/src/comps/index.tsx +++ b/client/packages/lowcoder/src/comps/index.tsx @@ -5,7 +5,10 @@ import { ModalComp } from "comps/hooks/modalComp"; import { ButtonComp } from "./comps/buttonComp/buttonComp"; import { DropdownComp } from "./comps/buttonComp/dropdownComp"; import { LinkComp } from "./comps/buttonComp/linkComp"; -import { ContainerComp, defaultContainerData } from "./comps/containerComp/containerComp"; +import { + ContainerComp, + defaultContainerData, +} from "./comps/containerComp/containerComp"; import { CustomComp } from "./comps/customComp/customComp"; import { DatePickerComp, DateRangeComp } from "./comps/dateComp/dateComp"; import { DividerComp } from "./comps/dividerComp"; @@ -101,7 +104,12 @@ import { import { defaultFormData, FormComp } from "./comps/formComp/formComp"; import { IFrameComp } from "./comps/iframeComp"; -import { defaultGridData, defaultListViewData, GridComp, ListViewComp } from "./comps/listViewComp"; +import { + defaultGridData, + defaultListViewData, + GridComp, + ListViewComp, +} from "./comps/listViewComp"; import { ModuleComp } from "./comps/moduleComp/moduleComp"; import { NavComp } from "./comps/navComp/navComp"; import { TableComp } from "./comps/tableComp"; @@ -124,10 +132,13 @@ import { ScannerComp } from "./comps/buttonComp/scannerComp"; import { SignatureComp } from "./comps/signatureComp"; import { TimeLineComp } from "./comps/timelineComp/timelineComp"; import { MentionComp } from "./comps/textInputComp/mentionComp"; -import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp" +import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"; //Added by Aqib Mirza import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp"; import { ResponsiveLayoutComp } from "./comps/responsiveLayout"; +import { VideoMeetingComp } from "./comps/videoComp/videoMeetingComp"; +import { VideoControlButton } from "./comps/videoComp/videoControlButton"; +import { VideoCOntrollerComp } from "./hooks/videoControllerComp"; type Registry = { [key in UICompType]?: UICompManifest; @@ -373,7 +384,7 @@ const uiCompMap: Registry = { keywords: trans("uiComp.buttonCompKeywords"), comp: ButtonComp, layoutInfo: { - w: 3, + w: 2, h: 5, }, withoutLoading: true, @@ -546,6 +557,27 @@ const uiCompMap: Registry = { }, defaultDataFn: defaultContainerData, }, + + videocomponent: { + name: trans("meeting.videoCompName"), + enName: "Video", + description: trans("meeting.videoCompName"), + categories: ["meeting"], + icon: VideoCompIcon, + keywords: trans("meeting.meetingCompKeywords"), + comp: VideoMeetingComp, + withoutLoading: true, + }, + meetingcontrols: { + name: trans("meeting.meetingControlCompName"), + enName: "Controls", + description: trans("meeting.meetingCompDesc"), + categories: ["meeting"], + icon: ButtonCompIcon, + keywords: trans("meeting.meetingCompKeywords"), + comp: VideoControlButton, + withoutLoading: true, + }, tabbedContainer: { name: trans("uiComp.tabbedContainerCompName"), enName: "Tabbed Container", @@ -742,6 +774,16 @@ const uiCompMap: Registry = { comp: DrawerComp, withoutLoading: true, }, + meeting: { + name: trans("meeting.meetingCompName"), + enName: "Drawer", + description: trans("meeting.meetingCompDesc"), + categories: ["meeting"], + icon: DrawerCompIcon, + keywords: trans("meeting.meetingCompKeywords"), + comp: VideoCOntrollerComp, + withoutLoading: true, + }, carousel: { name: trans("uiComp.carouselCompName"), enName: "Carousel", @@ -876,12 +918,14 @@ const uiCompMap: Registry = { description: trans("uiComp.autoCompleteCompDesc"), categories: ["dataInputText"], icon: AutoCompleteCompIcon, - keywords: cnchar.spell(trans("uiComp.autoCompleteCompName"), "first", "low").toString(), + keywords: cnchar + .spell(trans("uiComp.autoCompleteCompName"), "first", "low") + .toString(), comp: AutoCompleteComp, layoutInfo: { w: 7, h: 5, - } + }, }, responsiveLayout: { name: trans("uiComp.responsiveLayoutCompName"), diff --git a/client/packages/lowcoder/src/comps/uiCompRegistry.ts b/client/packages/lowcoder/src/comps/uiCompRegistry.ts index 523409a01..1aa9778bb 100644 --- a/client/packages/lowcoder/src/comps/uiCompRegistry.ts +++ b/client/packages/lowcoder/src/comps/uiCompRegistry.ts @@ -5,7 +5,9 @@ import { JSONValue } from "util/jsonTypes"; import { EditorState } from "./editorState"; import { trans } from "i18n"; -export type ExposingMultiCompConstructor = ReturnType; +export type ExposingMultiCompConstructor = ReturnType< + typeof withExposingConfigs +>; // Required when the container generates default child comps type CompDefaultDataFunction = ( compName: string, @@ -22,6 +24,7 @@ export interface UICompLayoutInfo { export const uiCompCategoryNames = { common: trans("uiCompCategory.common"), + meeting: trans("uiCompCategory.meeting"), dataInputText: trans("uiCompCategory.dataInputText"), dataInputNumber: trans("uiCompCategory.dataInputNumber"), dataInputSelect: trans("uiCompCategory.dataInputSelect"), @@ -53,6 +56,9 @@ export type UICompType = | "moduleContainer" | "textArea" | "chart" + | "meeting" + | "videocomponent" + | "meetingcontrols" | "imageEditor" | "calendar" | "password" @@ -114,11 +120,14 @@ export type UICompType = | "timeline" | "mention" | "autocomplete" - | "responsiveLayout" + | "responsiveLayout"; export const uiCompRegistry = {} as Record; -export function registerComp(compType: UICompType | string, manifest: UICompManifest) { +export function registerComp( + compType: UICompType | string, + manifest: UICompManifest +) { uiCompRegistry[compType] = { ...manifest, keywords: [manifest.name, manifest.enName, manifest.keywords] diff --git a/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx b/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx index 3889982d3..76f458a68 100644 --- a/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx +++ b/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx @@ -30,6 +30,7 @@ export const placeholderPropertyView = (children: { placeholder: InstanceType; }) => children.placeholder.propertyView({ label: trans("prop.placeholder") }); + export const allowClearPropertyView = (children: { allowClear: InstanceType; }) => children.allowClear.propertyView({ label: trans("prop.showClear") }); diff --git a/client/packages/lowcoder/src/constants/Layers.ts b/client/packages/lowcoder/src/constants/Layers.ts index 04391ac4f..fcd2a361b 100644 --- a/client/packages/lowcoder/src/constants/Layers.ts +++ b/client/packages/lowcoder/src/constants/Layers.ts @@ -17,6 +17,7 @@ export const Layers = { modal: 950, // drawer: 950, + meeting: 950, tabBar: 800, // historySnapshotPanel: 555, diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index ddebe2166..67e118864 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -47,7 +47,8 @@ export const en = { api: { publishSuccess: "Published", recoverFailed: "Recover failed", - needUpdate: "Your current version is too old, please upgrade to the latest version.", + needUpdate: + "Your current version is too old, please upgrade to the latest version.", }, codeEditor: { notSupportAutoFormat: "Current code editor not supports auto formatting", @@ -64,16 +65,20 @@ export const en = { blur: "Remove focus", click: "Click", select: "Select all the text", - setSelectionRange: "Set the start and end positions of the current text selection", + setSelectionRange: + "Set the start and end positions of the current text selection", selectionStart: "The 0-based index of the first selected character.", - selectionEnd: "The 0-based index of the character after the last selected character.", + selectionEnd: + "The 0-based index of the character after the last selected character.", setRangeText: "Replace a range of text", replacement: "The string to insert.", replaceStart: "The 0-based index of the first character to replace.", - replaceEnd: "The 0-based index of the character after the last character to replace.", + replaceEnd: + "The 0-based index of the character after the last character to replace.", }, errorBoundary: { - encounterError: "Loading component failed. Please check your configuration. ", + encounterError: + "Loading component failed. Please check your configuration. ", clickToReload: "Click to reload", errorMsg: "Error: ", }, @@ -88,8 +93,10 @@ export const en = { noContainerSelected: "[bug] No selected container", deleteCompsSuccess: "Delete success. You can use {undoKey} to undo.", deleteCompsTitle: "Delete components", - deleteCompsBody: "Are you sure you want to delete {compNum} selected components?", - cutCompsSuccess: "Cut success. You can use {pasteKey} to paste, or use {undoKey} to undo.", + deleteCompsBody: + "Are you sure you want to delete {compNum} selected components?", + cutCompsSuccess: + "Cut success. You can use {pasteKey} to paste, or use {undoKey} to undo.", }, leftPanel: { queries: "Queries", @@ -135,6 +142,7 @@ export const en = { prop: { expand: "Expand", columns: "Columns", + videokey: "video key", rowSelection: "Row selection", toolbar: "Toolbar", pagination: "Pagination", @@ -149,6 +157,8 @@ export const en = { showClear: "Show clear button", showSearch: "Searchable", defaultValue: "Default value", + participants: "Participants", + appid: "Application Id", required: "Required field", readOnly: "Read only", readOnlyTooltip: @@ -234,10 +244,12 @@ export const en = { export: "Export data", exportNoFileType: "No select (optional)", fileName: "File name", - fileNameTooltip: "Support extension to specify the file type, like image.png.", + fileNameTooltip: + "Support extension to specify the file type, like image.png.", fileType: "File type", condition: "Only run when", - conditionTooltip: "Only run the event handler when this condition evaluates to 'true'", + conditionTooltip: + "Only run the event handler when this condition evaluates to 'true'", debounce: "Debounce", throttle: "Throttle", slowdownTooltip: @@ -275,7 +287,8 @@ export const en = { canvas: "Canvas color", canvasDesc: "The default background color of the app", primarySurface: "Container color", - primarySurfaceDesc: "The default background color for components such as tables", + primarySurfaceDesc: + "The default background color for components such as tables", borderRadius: "Border radius", borderRadiusDesc: "Most components use the default border radius", chart: "Chart style", @@ -286,14 +299,16 @@ export const en = { padding: "Padding", paddingDesc: "The default padding is typically used for most components", containerheaderpadding: "Header Padding", - containerheaderpaddingDesc: "The default headerpadding is typically used for most components", + containerheaderpaddingDesc: + "The default headerpadding is typically used for most components", //Added By Aqib Mirza gridColumns: "Grid Columns", gridColumnsDesc: "The default number of columns is typically used for most containers", }, style: { - resetTooltip: "Reset styles. Delete the input's value to reset an individual field.", + resetTooltip: + "Reset styles. Delete the input's value to reset an individual field.", contrastText: "Contrast text color", generated: "Generated", customize: "Customize", @@ -346,7 +361,8 @@ export const en = { }, export: { hiddenDesc: "If true, the component is hidden", - disabledDesc: "If true, the component will be greyed out and non-interactive", + disabledDesc: + "If true, the component will be greyed out and non-interactive", visibleDesc: "If true, the component is visible", inputValueDesc: "Current value of the input", invalidDesc: "Whether the value is invalid", @@ -365,22 +381,32 @@ export const en = { ratingValueDesc: "The currently selected score", ratingMaxDesc: "The maximum score currently set", datePickerValueDesc: "Currently selected date", - datePickerFormattedValueDesc: "Formatted selected date according to the specified format", + datePickerFormattedValueDesc: + "Formatted selected date according to the specified format", datePickerTimestampDesc: "The currently selected timestamp of the date (s)", dateRangeStartDesc: "Currently selected start date", dateRangeEndDesc: "Currently selected end date", - dateRangeStartTimestampDesc: "The currently selected timestamp of the start date (s)", - dateRangeEndTimestampDesc: "The currently selected timestamp of the end date (s)", - dateRangeFormattedValueDesc: "Formatted selected date according to the specified format", - dateRangeFormattedStartValueDesc: "Formatted start date according to the specified format", - dateRangeFormattedEndValueDesc: "Formatted end date according to the specified format", + dateRangeStartTimestampDesc: + "The currently selected timestamp of the start date (s)", + dateRangeEndTimestampDesc: + "The currently selected timestamp of the end date (s)", + dateRangeFormattedValueDesc: + "Formatted selected date according to the specified format", + dateRangeFormattedStartValueDesc: + "Formatted start date according to the specified format", + dateRangeFormattedEndValueDesc: + "Formatted end date according to the specified format", timePickerValueDesc: "Currently selected time", - timePickerFormattedValueDesc: "Formatted selected time according to the specified format", + timePickerFormattedValueDesc: + "Formatted selected time according to the specified format", timeRangeStartDesc: "Currently selected start time", timeRangeEndDesc: "Currently selected end time", - timeRangeFormattedValueDesc: "Formatted selected time according to the specified format", - timeRangeFormattedStartValueDesc: "Formatted start time according to the specified format", - timeRangeFormattedEndValueDesc: "Formatted end time according to the specified format", + timeRangeFormattedValueDesc: + "Formatted selected time according to the specified format", + timeRangeFormattedStartValueDesc: + "Formatted start time according to the specified format", + timeRangeFormattedEndValueDesc: + "Formatted end time according to the specified format", }, validationDesc: { email: "Please enter a valid email address", @@ -392,10 +418,14 @@ export const en = { "Insufficient number of characters, current length {length}, minimum length {minLength}", maxValue: "Greater than the maximum, current {value}, maximum {max}", minValue: "Less than the minimum, current {value}, minimum {min}", - maxTime: "Greater than the maximum time, current time {time}, the maximum time {maxTime}", - minTime: "Less than the minimum time, current time {time}, the minimum time {minTime}", - maxDate: "Greater than maximum date, current time {date}, maximum date {maxDate}", - minDate: "Less than minimum date, current time {date}, minimum date {minDate}", + maxTime: + "Greater than the maximum time, current time {time}, the maximum time {maxTime}", + minTime: + "Less than the minimum time, current time {time}, the minimum time {minTime}", + maxDate: + "Greater than maximum date, current time {date}, maximum date {maxDate}", + minDate: + "Less than minimum date, current time {date}, minimum date {minDate}", }, query: { noQueries: "No queries available. ", @@ -407,7 +437,8 @@ export const en = { advancedTab: "Advanced", showFailNotification: "Show notification on failure", failCondition: "Failure conditions", - failConditionTooltip1: "Customizes failure condition and corresponding notification.", + failConditionTooltip1: + "Customizes failure condition and corresponding notification.", failConditionTooltip2: "If any condition returns true, the query will be marked as failure and triggers corresponding notification.", showSuccessNotification: "Show notification on success", @@ -477,7 +508,8 @@ export const en = { execSuccess: "run success", execFail: "run failed", execIgnored: "The results of this query was ignored.", - deleteSuccessMessage: "Successfully deleted. You can use {undoKey} to undo.", + deleteSuccessMessage: + "Successfully deleted. You can use {undoKey} to undo.", dataExportDesc: "Data obtained by the current query", codeExportDesc: "Current query status code", successExportDesc: "Whether the current query was executed successfully", @@ -522,7 +554,8 @@ export const en = { sslCertVerificationTypeDisabled: "Disabled", selfSignedCert: "Self-signed Cert", selfSignedCertRequireMsg: "Please enter your Certificate", - enableTurnOffPreparedStatement: "Enable toggling prepared statements for queries", + enableTurnOffPreparedStatement: + "Enable toggling prepared statements for queries", enableTurnOffPreparedStatementTooltip: "You can enable or disable prepared statements in query Advanced tab", serviceName: "Service name", @@ -610,11 +643,13 @@ export const en = { publish: "Publish", historyVersion: "History version", deleteQueryLabel: "Delete query", - deleteQueryContent: "The query can't be recovered after being deleted. Delete the query?", + deleteQueryContent: + "The query can't be recovered after being deleted. Delete the query?", run: "Run", readOnly: "Read only", exit: "Exit", - recoverAppSnapshotContent: "Restore the current query to the version {version}", + recoverAppSnapshotContent: + "Restore the current query to the version {version}", searchPlaceholder: "Search query", allQuery: "All queries", deleteQueryTitle: "Delete query", @@ -648,8 +683,10 @@ export const en = { }, smtpQuery: { attachment: "Attachment", - attachmentTooltip: "Can use with file upload component, need convert data to: ", - MIMETypeUrl: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types", + attachmentTooltip: + "Can use with file upload component, need convert data to: ", + MIMETypeUrl: + "https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types", sender: "Sender", recipient: "Recipient", carbonCopy: "Carbon copy", @@ -660,6 +697,7 @@ export const en = { }, uiCompCategory: { common: "Commonly used", + meeting: "Meeting Settings", dataInputText: "Text inputs", dataInputNumber: "Number inputs", dataInputSelect: "Select inputs", @@ -863,13 +901,16 @@ export const en = { menuViewDocs: "View documentation", menuUpgradeToLatest: "Upgrade to latest version", nameNotEmpty: "Can not be empty", - nameRegex: "Must start with a letter and contain only letters, digits, and underscores (_)", + nameRegex: + "Must start with a letter and contain only letters, digits, and underscores (_)", nameJSKeyword: "Can not be a Javascript keyword", nameGlobalVariable: "Can not be global variable name", nameExists: "Name {name} already exist", - getLatestVersionMetaError: "Failed to fetch latest version, please try later.", + getLatestVersionMetaError: + "Failed to fetch latest version, please try later.", needNotUpgrade: "Current version is already latest.", - compNotFoundInLatestVersion: "Current component not found in the latest version.", + compNotFoundInLatestVersion: + "Current component not found in the latest version.", upgradeSuccess: "Successfully upgraded to latest version.", searchProp: "Search", }, @@ -990,9 +1031,11 @@ export const en = { radio: { options: "Options", horizontal: "Horizontal", - horizontalTooltip: "The horizontal layout wraps itself when it runs out of space", + horizontalTooltip: + "The horizontal layout wraps itself when it runs out of space", vertical: "Vertical", - verticalTooltip: "The vertical layout will always be displayed in a single column", + verticalTooltip: + "The vertical layout will always be displayed in a single column", autoColumns: "Auto column", autoColumnsTooltip: "The auto column layout automatically rearranges the order as space permits and displays as multiple columns", @@ -1002,11 +1045,13 @@ export const en = { }, selectInput: { valueDesc: "Currently selected value", - selectedIndexDesc: "The index of the currently selected value, or -1 if no value is selected", + selectedIndexDesc: + "The index of the currently selected value, or -1 if no value is selected", selectedLabelDesc: "The label of the currently selected value", }, file: { - typeErrorMsg: "Must be a number with a valid file size unit, or a unitless number of bytes.", + typeErrorMsg: + "Must be a number with a valid file size unit, or a unitless number of bytes.", fileEmptyErrorMsg: "upload failed. The file size is empty.", fileSizeExceedErrorMsg: "upload failed. The file size exceeds the limit.", minSize: "Min size", @@ -1025,7 +1070,8 @@ export const en = { uploadType: "Upload type", showUploadList: "Show upload list", maxFiles: "Max files", - filesValueDesc: "The contents of the currently uploaded file are Base64 encoded", + filesValueDesc: + "The contents of the currently uploaded file are Base64 encoded", filesDesc: "List of the current uploaded files. For details, refer to", clearValueDesc: "Clear all files", parseFiles: "Parse files", @@ -1068,13 +1114,15 @@ export const en = { default: "Default", submit: "Submit", textDesc: "Text currently displayed on button", - loadingDesc: "Is the button in loading state? If true the current button is loading", + loadingDesc: + "Is the button in loading state? If true the current button is loading", formButtonEvent: "event", }, link: { link: "Link", textDesc: "Text currently displayed on link", - loadingDesc: "Is the link in loading state? If true the current link is loading", + loadingDesc: + "Is the link in loading state? If true the current link is loading", }, scanner: { text: "Click scan", @@ -1174,7 +1222,8 @@ export const en = { optionList: "Operation list", option1: "Operation 1", status: "Status", - statusTooltip: "Optional values: success, error, default, warning, processing", + statusTooltip: + "Optional values: success, error, default, warning, processing", primaryButton: "Primary", defaultButton: "Default", type: "Type", @@ -1186,7 +1235,8 @@ export const en = { small: "S", middle: "M", large: "L", - refreshButtonTooltip: "The current data changes, click to regenerate the column.", + refreshButtonTooltip: + "The current data changes, click to regenerate the column.", changeSetDesc: "An object representing changes to an editable table, only contains the changed cell. Rows go first and columns go second.", selectedRowDesc: @@ -1228,7 +1278,8 @@ export const en = { showValue: "Show Value", expandable: "Expandable", configExpandedView: "Configure expanded view", - toUpdateRowsDesc: "An array of objects for rows to be updated in editable tables.", + toUpdateRowsDesc: + "An array of objects for rows to be updated in editable tables.", empty: "Empty", falseValues: "Text when false", allColumn: "All", @@ -1276,7 +1327,8 @@ export const en = { M: "M (Medium)", Q: "Q (Quartile)", H: "H (High)", - maxLength: "The content is too long. Set the length to less than 2953 characters", + maxLength: + "The content is too long. Set the length to less than 2953 characters", }, jsonExplorer: { indent: "Indent", @@ -1335,8 +1387,10 @@ export const en = { media: { playDesc: "Begins playback of the media.", pauseDesc: "Pauses the media playback.", - loadDesc: "Resets the media to the beginning and restart selecting the media resource.", - seekTo: "Seek to the given number of seconds, or fraction if amount is between 0 and 1", + loadDesc: + "Resets the media to the beginning and restart selecting the media resource.", + seekTo: + "Seek to the given number of seconds, or fraction if amount is between 0 and 1", seekToAmount: "Number of seconds, or fraction if it is between 0 and 1", showPreview: "Show preview", }, @@ -1353,8 +1407,10 @@ export const en = { insertImage: "Insert an image or ", }, millisecondsControl: { - timeoutTypeError: "Please enter the correct timeout period, the current input is: {value}", - timeoutLessThanMinError: "Input must greater than {left}, the current input is: {value}", + timeoutTypeError: + "Please enter the correct timeout period, the current input is: {value}", + timeoutLessThanMinError: + "Input must greater than {left}, the current input is: {value}", }, selectionControl: { single: "Single", @@ -1379,6 +1435,31 @@ export const en = { width: "Drawer width", height: "Drawer height", }, + meeting: { + placement: "Drawer placement", + size: "Size", + top: "Top", + right: "Right", + bottom: "Bottom", + left: "Left", + widthTooltip: "Number or percentage, e.g. 520, 60%", + heightTooltip: "Number, e.g. 378", + openDrawerDesc: "Open Drawer", + closeDrawerDesc: "Close Drawer", + width: "Drawer width", + height: "Drawer height", + actionBtnDesc: "Action Button", + title: "Meeting title", + meetingCompName: "Meeting Controller", + videoCompName: "Video Stream", + meetingControlCompName: "Controls Buttons", + meetingCompDesc: "Meeting component", + meetingCompControls: "Meeting control", + meetingCompKeywords: "", + iconSize: "Icon Size", + userId: "userId", + roomId: "roomId", + }, settings: { title: "Settings", member: "Members", @@ -1404,7 +1485,8 @@ export const en = { newGroupPrefix: "New group ", allMembers: "All members", deleteModalTitle: "Delete this group", - deleteModalContent: "The deleted group cannot be restored. Are you sure to delete the group?", + deleteModalContent: + "The deleted group cannot be restored. Are you sure to delete the group?", addMember: "Add members", nameColumn: "User name", joinTimeColumn: "Joining time", @@ -1416,9 +1498,12 @@ export const en = { exitOrg: "Leave", exitOrgDesc: "Are you sure you want to leave this workspace.", moveOutOrg: "Remove", - moveOutOrgDescSaasMode: "Are you sure you want to remove user {name} from this workspace?", - moveOutOrgDesc: "Are you sure you want to remove user {name}? This action cannot be recovered.", - devGroupTip: "Members of the developer group have privileges to create apps and data sources.", + moveOutOrgDescSaasMode: + "Are you sure you want to remove user {name} from this workspace?", + moveOutOrgDesc: + "Are you sure you want to remove user {name}? This action cannot be recovered.", + devGroupTip: + "Members of the developer group have privileges to create apps and data sources.", lastAdminQuit: "The last administrator cannot exit.", organizationNotExist: "The current workspace does not exist", inviteUserHelp: "You can copy the invitation link to send to the user", @@ -1431,7 +1516,8 @@ export const en = { manageBtn: "Manage", userDetail: "Detail", syncDeleteTip: "This group has been deleted from the address book source", - syncGroupTip: "This group is an address book synchronization group and cannot be edited", + syncGroupTip: + "This group is an address book synchronization group and cannot be edited", }, orgSettings: { newOrg: "New workspace", @@ -1442,7 +1528,8 @@ export const en = { "You are about to delete this workspace {permanentlyDelete}. Once deleted, the workspace {notRestored}.", permanentlyDelete: "permanently", notRestored: "cannot be restored", - deleteModalLabel: "Please enter workspace name{name}to confirm the operation:", + deleteModalLabel: + "Please enter workspace name{name}to confirm the operation:", deleteModalTip: "Please enter workspace name", deleteModalErr: "Workspace name is incorrect", deleteModalBtn: "Delete", @@ -1488,9 +1575,12 @@ export const en = { noTableSelected: "No table selected", noColumn: "No column", noColumnSelected: "No column selected", - noDataSourceFound: "No supported data source found. Create a new data source", - noTableFound: "No tables were found in this data source, please select another data source", - noColumnFound: "No supported column was found in this table. Please select another table", + noDataSourceFound: + "No supported data source found. Create a new data source", + noTableFound: + "No tables were found in this data source, please select another data source", + noColumnFound: + "No supported column was found in this table. Please select another table", formTitle: "Form title", name: "Name", nameTooltip: @@ -1522,9 +1612,11 @@ export const en = { "Number of rows in the list - This is usually set to a variable (for example, '{{query1.data.length}}') if you need to present the results of a query.", noOfColumns: "Column count", itemIndexName: "Item index name", - itemIndexNameDesc: "the variable name refer to the item's index, default as {default}", + itemIndexNameDesc: + "the variable name refer to the item's index, default as {default}", itemDataName: "Item data name", - itemDataNameDesc: "the variable name refer to the item's data object, default as {default}", + itemDataNameDesc: + "the variable name refer to the item's data object, default as {default}", itemsDesc: "Exposing data of Comps in list", dataDesc: "The raw data used in the current list", dataTooltip: @@ -1594,19 +1686,23 @@ export const en = { }, temporaryState: { value: "Init value", - valueTooltip: "The initial Value stored in the temporary state can be any valid JSON Value.", + valueTooltip: + "The initial Value stored in the temporary state can be any valid JSON Value.", docLink: "About temporary state", pathTypeError: "Path must be either a string or an array of values", unStructuredError: "Unstructured data {prev} can't be updated by {path}", valueDesc: "Temporary state value", - deleteMessage: "The temporary state is deleted successfully. You can use {undoKey} to undo.", + deleteMessage: + "The temporary state is deleted successfully. You can use {undoKey} to undo.", }, dataResponder: { data: "Data", dataDesc: "Data of current data responder", - dataTooltip: "When this data is changed, it will trigger subsequent actions.", + dataTooltip: + "When this data is changed, it will trigger subsequent actions.", docLink: "About the Data responder", - deleteMessage: "The data responder is deleted successfully. You can use {undoKey} to undo.", + deleteMessage: + "The data responder is deleted successfully. You can use {undoKey} to undo.", }, theme: { title: "Themes", @@ -1644,7 +1740,8 @@ export const en = { defaultTheme: "Default", yellow: "Yellow", green: "Green", - previewTitle: "Theme preview\nExample components that use your theme colors", + previewTitle: + "Theme preview\nExample components that use your theme colors", dateColumn: "Date", emailColumn: "Email", phoneColumn: "Phone", @@ -1682,7 +1779,8 @@ export const en = { pluginSetting: { title: "Plugins", npmPluginTitle: "npm plugins", - npmPluginDesc: "Set up npm plugins for all applications in the current workspace.", + npmPluginDesc: + "Set up npm plugins for all applications in the current workspace.", npmPluginEmpty: "No npm plugins were added.", npmPluginAddButton: "Add a npm plugin", saveSuccess: "Saved successfully", @@ -1695,9 +1793,11 @@ export const en = { defaultHomePlaceholder: "Select the default homepage", saveBtn: "Save", preloadJSTitle: "Preload JavaScript", - preloadJSHelp: "Set up preloaded JavaScript code for all apps in the current workspace.", + preloadJSHelp: + "Set up preloaded JavaScript code for all apps in the current workspace.", preloadCSSTitle: "Preload CSS", - preloadCSSHelp: " Set up preloaded CSS code for all apps in the current workspace.", + preloadCSSHelp: + " Set up preloaded CSS code for all apps in the current workspace.", preloadCSSApply: "Apply to the homepage of the workspace", preloadLibsTitle: "JavaScript library", preloadLibsHelp: @@ -1739,7 +1839,8 @@ export const en = { }, module: { emptyText: "No data", - circularReference: "Circular reference, current module/application cannot be used!", + circularReference: + "Circular reference, current module/application cannot be used!", emptyTestInput: "The current module has no input to test", emptyTestMethod: "The current module has no method to test", name: "Name", @@ -1762,7 +1863,8 @@ export const en = { output: "Output", nameExists: "Name {name} already exist", eventTriggered: "Event {name} is triggered", - globalPromptWhenEventTriggered: "Displays a global prompt when an event is triggered", + globalPromptWhenEventTriggered: + "Displays a global prompt when an event is triggered", emptyEventTest: "The current module has no events to test", emptyEvent: "No event has been added", event: "Event", @@ -1898,7 +2000,8 @@ export const en = { videoText: "Overview", onBtnText: "OK", // eslint-disable-next-line only-ascii/only-ascii - permissionDenyTitle: "💡 Unable to create a new application or data source?", + permissionDenyTitle: + "💡 Unable to create a new application or data source?", permissionDenyContent: "You don't have permission to create the application and data source. Please contact the administrator to join the developer group.", appName: "Tutorial application", @@ -1914,7 +2017,8 @@ export const en = { nameCheckMessage: "The name cannot be empty", viewOnly: "View only", recoverAppSnapshotTitle: "Restore this version?", - recoverAppSnapshotContent: "Restore current app to the version created at {time}.", + recoverAppSnapshotContent: + "Restore current app to the version created at {time}.", recoverAppSnapshotMessage: "Restore this version", returnEdit: "Return to editor", deploy: "Publish", @@ -1958,7 +2062,8 @@ export const en = { resetPasswordDesc: "Reset user {name}'s password. A new password will be generated after reset.", resetSuccess: "Reset succeeded", - resetSuccessDesc: "Password reset succeeded. The new password is: {password}", + resetSuccessDesc: + "Password reset succeeded. The new password is: {password}", copyPassword: "Copy password", }, preLoad: { @@ -2051,7 +2156,8 @@ export const en = { resCardSubTitle: "{time} by {creator}", trashEmpty: "Trash is empty.", projectEmpty: "Nothing here.", - projectEmptyCanAdd: "You don't have any apps yet. Click New to get started.", + projectEmptyCanAdd: + "You don't have any apps yet. Click New to get started.", name: "Name", type: "Type", creator: "Created by", @@ -2063,7 +2169,8 @@ export const en = { nameCheckMessage: "The name cannot be empty", deleteElementTitle: "Delete permanently", moveToTrashSubTitle: "{type} {name} will be moved to trash.", - deleteElementSubTitle: "Delete {type} {name} permanently, it cannot be recovered.", + deleteElementSubTitle: + "Delete {type} {name} permanently, it cannot be recovered.", deleteSuccessMsg: "Deleted successfully", deleteErrorMsg: "Deleted error", recoverSuccessMsg: "Recovered successfully", @@ -2136,12 +2243,15 @@ export const en = { aboutUs: "", changeLog: "", introVideo: "", - devNpmPlugin: "https://docs.lowcoder.cloud/lowcoder-extension/develop-data-source-plugins", + devNpmPlugin: + "https://docs.lowcoder.cloud/lowcoder-extension/develop-data-source-plugins", devNpmPluginText: "How to develop npm plugin", - useHost: "https://docs.lowcoder.cloud/setup-and-run/self-hosting/access-local-database-or-api", + useHost: + "https://docs.lowcoder.cloud/setup-and-run/self-hosting/access-local-database-or-api", eventHandlerSlowdown: "https://docs.lowcoder.cloud/build-applications/app-interaction/event-handlers", - thirdLib: "https://docs.lowcoder.cloud/lowcoder-extension/use-third-party-libraries-in-apps", + thirdLib: + "https://docs.lowcoder.cloud/lowcoder-extension/use-third-party-libraries-in-apps", thirdLibUrlText: "Use third-party libraries", }, datasourceTutorial: { @@ -2155,8 +2265,10 @@ export const en = { }, queryTutorial: { js: "", - transformer: "https://docs.lowcoder.cloud/business-logic-in-apps/write-javascript/transformers", - tempState: "https://docs.lowcoder.cloud/business-logic-in-apps/write-javascript/temporary-state", + transformer: + "https://docs.lowcoder.cloud/business-logic-in-apps/write-javascript/transformers", + tempState: + "https://docs.lowcoder.cloud/business-logic-in-apps/write-javascript/temporary-state", }, customComponent: { entryUrl: "https://sdk.lowcoder.cloud/custom_component.html", @@ -2226,7 +2338,8 @@ export const en = { defaultStartDateValue: "Default Start Date", defaultEndDateValue: "Default End Date", basicUsage: "Basic Usage", - basicDemoDescription: "The following examples show the basic usage of the component.", + basicDemoDescription: + "The following examples show the basic usage of the component.", noDefaultValue: "No Default Value", forbid: "Forbidden", placeholder: "Placeholder", @@ -2298,7 +2411,8 @@ export const en = { styleColor: "Font color", selectionMode: "Row selection mode", paginationSetting: "Pagination setting", - paginationShowSizeChanger: "Support users to modify the number of entries per page", + paginationShowSizeChanger: + "Support users to modify the number of entries per page", paginationShowSizeChangerButton: "Show size changer button", paginationShowQuickJumper: "Show quick jumper", paginationHideOnSinglePage: "Hide when there is only one page", @@ -2432,7 +2546,8 @@ export const en = { disableContent: "Disabling this ID provider may result in some users being unable to log in. Are you sure to proceed?", manualTip: "", - lockTip: "The content is locked. To make changes, please click the{icon}to unlock.", + lockTip: + "The content is locked. To make changes, please click the{icon}to unlock.", lockModalContent: "Changing the 'ID attribute' field can have significant impacts on user identification. Please confirm that you understand the implications of this change before proceeding.", payUserTag: "Premium", @@ -2450,7 +2565,7 @@ export const en = { animationStart: "Animation Start", valueDesc: "Current json Data", loop: "Loop", - auto: 'auto', + auto: "auto", onHover: "On hover", singlePlay: "Single Play", endlessLoop: "Endless Loop", @@ -2466,7 +2581,8 @@ export const en = { left: "Left", right: "Right", alternate: "alternate", - modeTooltip: "Set the content to appear left/right or alternately on both sides of the timeline", + modeTooltip: + "Set the content to appear left/right or alternately on both sides of the timeline", reverse: "reverse", pending: "pending", defaultPending: "continuous improvement", @@ -2485,7 +2601,7 @@ export const en = { clickedObjectDesc: "clicked item data", clickedIndexDesc: "clicked item index", }, - mention:{ + mention: { mentionList: "mention list", }, autoComplete: { @@ -2501,13 +2617,13 @@ export const en = { type: "type", antDesign: "AntDesign", normal: "Normal", - selectKey: 'key', - selectLable: 'label', - ComponentType: 'Component Type', - colorIcon: 'blue', - grewIcon: 'grew', - noneIcon: 'none', - small: 'small', + selectKey: "key", + selectLable: "label", + ComponentType: "Component Type", + colorIcon: "blue", + grewIcon: "grew", + noneIcon: "none", + small: "small", large: "large", componentSize: "component size", Introduction: "Introduction keys", diff --git a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx index 345baf396..c70e599c8 100644 --- a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx +++ b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx @@ -6,6 +6,7 @@ import { LeftCheckbox, LeftCommon, LeftContainer, + LeftMeeting, LeftDate, LeftDivider, LeftDrawer, @@ -83,6 +84,9 @@ export const CompStateIcon: { form: , jsonSchemaForm: , container: , + meeting: , + videocomponent: , + meetingcontrols: , tabbedContainer: , modal: , listView: , @@ -106,7 +110,7 @@ export const CompStateIcon: { signature: , jsonLottie: , //Added By Aqib Mirza timeline: , - mention: , + mention: , autocomplete: , responsiveLayout: , }; From cf0fac6e64b41b1ef7c1789408e4811a52da51f5 Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Sat, 7 Oct 2023 18:50:53 +0200 Subject: [PATCH 02/20] Small fixes to make it running locally --- .../src/components/Meeting.tsx | 93 +++++++++ .../lowcoder-design/src/icons/index.ts | 2 + client/packages/lowcoder-design/src/index.ts | 3 +- .../comps/videoComp/videoMeetingComp.tsx | 4 +- client/yarn.lock | 187 ++++++++++++++++++ 5 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 client/packages/lowcoder-design/src/components/Meeting.tsx diff --git a/client/packages/lowcoder-design/src/components/Meeting.tsx b/client/packages/lowcoder-design/src/components/Meeting.tsx new file mode 100644 index 000000000..a438f905b --- /dev/null +++ b/client/packages/lowcoder-design/src/components/Meeting.tsx @@ -0,0 +1,93 @@ +import { Drawer as AntdDrawer, DrawerProps as AntdDrawerProps } from "antd"; +import Handle from "./Modal/handler"; +import { useEffect, useMemo, useState } from "react"; +import { Resizable, ResizeHandle } from "react-resizable"; +import { useResizeDetector } from "react-resize-detector"; +import styled from "styled-components"; + +const StyledMeeting = styled(AntdDrawer)` + & .ant-drawer-content-wrapper { + transition-duration: 0s; + } +`; + +type Placement = "top" | "bottom" | "left" | "right"; +function getResizeHandle(placement?: Placement): ResizeHandle { + switch (placement) { + case "top": + return "s"; + case "bottom": + return "n"; + case "left": + return "e"; + } + return "w"; +} + +type MeetingProps = { + resizable?: boolean; + onResizeStart?: ( + e: React.SyntheticEvent, + node: HTMLElement, + size: { width: number; height: number }, + handle: ResizeHandle + ) => void; + onResize?: ( + e: React.SyntheticEvent, + node: HTMLElement, + size: { width: number; height: number }, + handle: ResizeHandle + ) => void; + onResizeStop?: ( + e: React.SyntheticEvent, + node: HTMLElement, + size: { width: number; height: number }, + handle: ResizeHandle + ) => void; +} & AntdDrawerProps; + +export function Meeting(props: MeetingProps) { + const { resizable, width: drawerWidth, height: drawerHeight, children, ...otherProps } = props; + const placement = useMemo(() => props.placement ?? "right", [props.placement]); + const resizeHandles = useMemo( + () => (resizable ? [getResizeHandle(placement)] : []), + [placement, resizable] + ); + const isTopBom = ["top", "bottom"].includes(placement); + const [width, setWidth] = useState(); + const [height, setHeight] = useState(); + useEffect(() => { + setWidth(undefined); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [drawerWidth]); + useEffect(() => { + setHeight(undefined); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [drawerHeight]); + const { width: detectWidth, height: detectHeight, ref } = useResizeDetector(); + // log.info("Drawer. drawerWidth: ", drawerWidth, " width: ", width, "detectWidth: ", detectWidth); + return ( + + + props.onResizeStart?.(event, node, size, handle) + } + onResize={(event, { node, size, handle }) => { + isTopBom ? setHeight(size.height) : setWidth(size.width); + props.onResize?.(event, node, size, handle); + }} + onResizeStop={(event, { node, size, handle }) => + props.onResizeStop?.(event, node, size, handle) + } + > +
+ {children} +
+
+
+ ); +} diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts index 6c9c2eb2b..0ea5ed45d 100644 --- a/client/packages/lowcoder-design/src/icons/index.ts +++ b/client/packages/lowcoder-design/src/icons/index.ts @@ -168,6 +168,7 @@ export { ReactComponent as AudioCompIcon } from "./icon-insert-audio.svg"; export { ReactComponent as VideoCompIcon } from "./icon-insert-video.svg"; export { ReactComponent as videoPlayTriangle } from "./icon-video-play-triangle.svg"; export { ReactComponent as DrawerCompIcon } from "./icon-drawer.svg"; +export { ReactComponent as LeftMeetingIcon } from "./icon-left-comp-video.svg"; export { ReactComponent as PlusIcon } from "./icon-plus.svg"; export { ReactComponent as HomeIcon } from "./icon-application-home.svg"; export { ReactComponent as HomeModuleIcon } from "./icon-application-module.svg"; @@ -236,6 +237,7 @@ export { ReactComponent as LeftContainer } from "./icon-left-comp-container.svg" export { ReactComponent as LeftDate } from "./icon-left-comp-date.svg"; export { ReactComponent as LeftDivider } from "./icon-left-comp-divider.svg"; export { ReactComponent as LeftDrawer } from "./icon-left-comp-drawer.svg"; +export { ReactComponent as LeftMeeting } from "./icon-left-comp-video.svg"; export { ReactComponent as LeftFile } from "./icon-left-comp-file.svg"; export { ReactComponent as LeftFileViewer } from "./icon-left-comp-fileViewer.svg"; export { ReactComponent as LeftForm } from "./icon-left-comp-form.svg"; diff --git a/client/packages/lowcoder-design/src/index.ts b/client/packages/lowcoder-design/src/index.ts index a2a7ca495..133417f7c 100644 --- a/client/packages/lowcoder-design/src/index.ts +++ b/client/packages/lowcoder-design/src/index.ts @@ -1,6 +1,7 @@ export * from "./components/Collapase"; export * from "./components/CustomModal"; -export * from "./components/Drawer"; +export * from "./components/Drawer"; +export * from "./components/Meeting"; export * from "./components/Dropdown"; export * from "./components/ExternalLink"; export * from "./components/GlobalInstances"; diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx index 460bebd63..9892499d0 100644 --- a/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx @@ -216,7 +216,7 @@ let VideoCompBuilder = (function (props) { }) .setPropertyViewFn((children) => ( <> -
+ {/*
{children.userId.propertyView({ label: trans("meeting.userId"), })} @@ -224,7 +224,7 @@ let VideoCompBuilder = (function (props) { {children.videokey.propertyView({ label: trans("prop.videokey"), })} -
+
*/} {/*
{/* {hiddenPropertyView(children)}
*/} diff --git a/client/yarn.lock b/client/yarn.lock index 4748d1eaf..0d2810fcf 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -12,6 +12,40 @@ __metadata: languageName: node linkType: hard +"@agora-js/media@npm:^4.19.0": + version: 4.19.0 + resolution: "@agora-js/media@npm:4.19.0" + dependencies: + "@agora-js/report": ^4.19.0 + "@agora-js/shared": ^4.19.0 + agora-rte-extension: ^1.2.3 + axios: ^0.27.2 + pako: ^2.1.0 + webrtc-adapter: 8.2.0 + checksum: c72485d9350376e8168dfcc205c2d5e19ea00c041a49404c4829cc520ab9216a842011467d23b542cff649447699852cb48563c675b2883c3a1ac3e68d27d78b + languageName: node + linkType: hard + +"@agora-js/report@npm:^4.19.0": + version: 4.19.0 + resolution: "@agora-js/report@npm:4.19.0" + dependencies: + "@agora-js/shared": ^4.19.0 + axios: ^0.27.2 + checksum: 2624fcad0aecb89ad38a420e7135bbeeb33c46c4e56797211a54b01c32fcf4b4add818bbf5af9497e27bdb0cc62eb95fe607c53071b21c03a2b2345cb37adb80 + languageName: node + linkType: hard + +"@agora-js/shared@npm:^4.19.0": + version: 4.19.0 + resolution: "@agora-js/shared@npm:4.19.0" + dependencies: + axios: ^0.27.2 + ua-parser-js: ^0.7.34 + checksum: 215164c8456a81c614809cb351b4ea31ed939324d99ce3e80bedd1e7737488c1486dd65320641077473339c25cf5520e4406d47003ac6e5a88ee889270bae378 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.2.1 resolution: "@ampproject/remapping@npm:2.2.1" @@ -4700,6 +4734,39 @@ __metadata: languageName: node linkType: hard +"agora-access-token@npm:^2.0.4": + version: 2.0.4 + resolution: "agora-access-token@npm:2.0.4" + dependencies: + crc-32: 1.2.0 + cuint: 0.2.2 + checksum: 7d91fa01c4ba085f70b8bdac9d296f8a5d29d2dc5a1c5cd995d4fe7bfb557cc3c5223bb0417065e89c584c0dbfaa7ddfdb4b689b0b8fc2459e77ad9d4ff0d52a + languageName: node + linkType: hard + +"agora-rtc-sdk-ng@npm:^4.19.0": + version: 4.19.0 + resolution: "agora-rtc-sdk-ng@npm:4.19.0" + dependencies: + "@agora-js/media": ^4.19.0 + "@agora-js/report": ^4.19.0 + "@agora-js/shared": ^4.19.0 + agora-rte-extension: ^1.2.3 + axios: ^0.27.2 + formdata-polyfill: ^4.0.7 + ua-parser-js: ^0.7.34 + webrtc-adapter: 8.2.0 + checksum: 495d16957dd7c12f0032dcc0a27d3d918ed20e4c869ea828e611dbc0130708231e483859cd51d64a7527e71078a7c7ed28d7924fb0dfe0be9a169b915ec1280a + languageName: node + linkType: hard + +"agora-rte-extension@npm:^1.2.3": + version: 1.2.3 + resolution: "agora-rte-extension@npm:1.2.3" + checksum: 5b53a2f08720a17e7dac5dc35c3d4c539a5eabe9e20a4da2bf08c666072dc11e90cac6b92e2b1ccbd4516c70cf4934ddfe13d9863553e1e36949a7b138cde96a + languageName: node + linkType: hard + "ahooks-v3-count@npm:^1.0.0": version: 1.0.0 resolution: "ahooks-v3-count@npm:1.0.0" @@ -5288,6 +5355,16 @@ __metadata: languageName: node linkType: hard +"axios@npm:^0.27.2": + version: 0.27.2 + resolution: "axios@npm:0.27.2" + dependencies: + follow-redirects: ^1.14.9 + form-data: ^4.0.0 + checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 + languageName: node + linkType: hard + "axobject-query@npm:^3.1.1": version: 3.1.1 resolution: "axobject-query@npm:3.1.1" @@ -6420,6 +6497,18 @@ __metadata: languageName: node linkType: hard +"crc-32@npm:1.2.0": + version: 1.2.0 + resolution: "crc-32@npm:1.2.0" + dependencies: + exit-on-epipe: ~1.0.1 + printj: ~1.1.0 + bin: + crc32: ./bin/crc32.njs + checksum: 7bcde8bea262f6629ac3c70e20bdfa3d058dc77091705ce8620513f76f19b41fc273ddd65a716eef9b4e33fbb61ff7f9b266653d214319aef27e4223789c6b9e + languageName: node + linkType: hard + "crc-32@npm:~1.2.0, crc-32@npm:~1.2.1": version: 1.2.2 resolution: "crc-32@npm:1.2.2" @@ -6678,6 +6767,13 @@ __metadata: languageName: node linkType: hard +"cuint@npm:0.2.2": + version: 0.2.2 + resolution: "cuint@npm:0.2.2" + checksum: b8127a93a7f16ce120ffcb22108014327c9808b258ee20e7dbb4c6740d7cb0f0c12d18a054eb716b0f2470090666abaae8a082d3cd5ef0e94fa447dd155842c4 + languageName: node + linkType: hard + "cytoscape-cose-bilkent@npm:^4.1.0": version: 4.1.0 resolution: "cytoscape-cose-bilkent@npm:4.1.0" @@ -8424,6 +8520,13 @@ __metadata: languageName: node linkType: hard +"exit-on-epipe@npm:~1.0.1": + version: 1.0.1 + resolution: "exit-on-epipe@npm:1.0.1" + checksum: e8ab4940416d19f311b3c9226e3725c6c4c6026fe682266ecc0ff33a455d585fe3e4ee757857c7bf1d0491b478cb232b8e395dfb438e65ac87317eda47304c32 + languageName: node + linkType: hard + "exit@npm:^0.1.2": version: 0.1.2 resolution: "exit@npm:0.1.2" @@ -8600,6 +8703,16 @@ __metadata: languageName: node linkType: hard +"fetch-blob@npm:^3.1.2": + version: 3.2.0 + resolution: "fetch-blob@npm:3.2.0" + dependencies: + node-domexception: ^1.0.0 + web-streams-polyfill: ^3.0.3 + checksum: f19bc28a2a0b9626e69fd7cf3a05798706db7f6c7548da657cbf5026a570945f5eeaedff52007ea35c8bcd3d237c58a20bf1543bc568ab2422411d762dd3d5bf + languageName: node + linkType: hard + "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -8700,6 +8813,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.14.9": + version: 1.15.3 + resolution: "follow-redirects@npm:1.15.3" + peerDependenciesMeta: + debug: + optional: true + checksum: 584da22ec5420c837bd096559ebfb8fe69d82512d5585004e36a3b4a6ef6d5905780e0c74508c7b72f907d1fa2b7bd339e613859e9c304d0dc96af2027fd0231 + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -8745,6 +8868,15 @@ __metadata: languageName: node linkType: hard +"formdata-polyfill@npm:^4.0.7": + version: 4.0.10 + resolution: "formdata-polyfill@npm:4.0.10" + dependencies: + fetch-blob: ^3.1.2 + checksum: 82a34df292afadd82b43d4a740ce387bc08541e0a534358425193017bf9fb3567875dc5f69564984b1da979979b70703aa73dee715a17b6c229752ae736dd9db + languageName: node + linkType: hard + "formstream@npm:^1.1.0": version: 1.2.0 resolution: "formstream@npm:1.2.0" @@ -11724,6 +11856,8 @@ __metadata: "@types/regenerator-runtime": ^0.13.1 "@types/uuid": ^8.3.4 "@vitejs/plugin-react": ^2.2.0 + agora-access-token: ^2.0.4 + agora-rtc-sdk-ng: ^4.19.0 ali-oss: ^6.17.1 antd: 5.7.2 antd-img-crop: ^4.12.2 @@ -12925,6 +13059,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:^1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f + languageName: node + linkType: hard + "node-fetch@npm:^2.6.11": version: 2.6.11 resolution: "node-fetch@npm:2.6.11" @@ -13371,6 +13512,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:^2.1.0": + version: 2.1.0 + resolution: "pako@npm:2.1.0" + checksum: 71666548644c9a4d056bcaba849ca6fd7242c6cf1af0646d3346f3079a1c7f4a66ffec6f7369ee0dc88f61926c10d6ab05da3e1fca44b83551839e89edd75a3e + languageName: node + linkType: hard + "papaparse@npm:^5.3.2": version: 5.4.1 resolution: "papaparse@npm:5.4.1" @@ -13693,6 +13841,15 @@ __metadata: languageName: node linkType: hard +"printj@npm:~1.1.0": + version: 1.1.2 + resolution: "printj@npm:1.1.2" + bin: + printj: ./bin/printj.njs + checksum: 1c0c66844545415e339356ad62009cdc467819817b1e0341aba428087a1414d46b84089edb4e77ef24705829f8aae6349724b9c7bd89d8690302b2de7a89b315 + languageName: node + linkType: hard + "process-es6@npm:^0.11.2, process-es6@npm:^0.11.6": version: 0.11.6 resolution: "process-es6@npm:0.11.6" @@ -16356,6 +16513,13 @@ __metadata: languageName: node linkType: hard +"sdp@npm:^3.0.2": + version: 3.2.0 + resolution: "sdp@npm:3.2.0" + checksum: 227885bddab9a5845e56ae184ff51e43ec7bc155e7f1ed2f17ca1b012e6767011d5bd01b6c4064ded8e3b6f6bf3c9b26b2cf754b9c8662285988ed27b54f37b1 + languageName: node + linkType: hard + "semver@npm:^5.0.1, semver@npm:^5.6.0": version: 5.7.1 resolution: "semver@npm:5.7.1" @@ -17799,6 +17963,13 @@ __metadata: languageName: node linkType: hard +"ua-parser-js@npm:^0.7.34": + version: 0.7.36 + resolution: "ua-parser-js@npm:0.7.36" + checksum: 04e18e7f6bf4964a10d74131ea9784c7f01d0c2d3b96f73340ac0a1f8e83d010b99fd7d425e7a2100fa40c58b72f6201408cbf4baa2df1103637f96fb59f2a30 + languageName: node + linkType: hard + "ua-parser-js@npm:^1.0.33": version: 1.0.35 resolution: "ua-parser-js@npm:1.0.35" @@ -18528,6 +18699,13 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:^3.0.3": + version: 3.2.1 + resolution: "web-streams-polyfill@npm:3.2.1" + checksum: b119c78574b6d65935e35098c2afdcd752b84268e18746606af149e3c424e15621b6f1ff0b42b2676dc012fc4f0d313f964b41a4b5031e525faa03997457da02 + languageName: node + linkType: hard + "web-vitals@npm:^2.1.0": version: 2.1.4 resolution: "web-vitals@npm:2.1.4" @@ -18563,6 +18741,15 @@ __metadata: languageName: node linkType: hard +"webrtc-adapter@npm:8.2.0": + version: 8.2.0 + resolution: "webrtc-adapter@npm:8.2.0" + dependencies: + sdp: ^3.0.2 + checksum: 67221eac0f01c35f32235b0b988ed27b7e850d03315050a4432f6dc2ff47b8e0535732dfbe5d9718f6a27d46eddc527ca1465e509ba628fdd4c968013fdacb86 + languageName: node + linkType: hard + "weixin-js-sdk@npm:^1.6.0": version: 1.6.0 resolution: "weixin-js-sdk@npm:1.6.0" From 6ca3d4dc96401470f808ff5e6d0c329fcfe6e36d Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 9 Oct 2023 10:17:47 +0300 Subject: [PATCH 03/20] v --- .../src/components/meeting.tsx | 43 ++ node_modules/.bin/uuid | 1 + node_modules/.yarn-integrity | 16 + node_modules/uuid/CHANGELOG.md | 274 ++++++++++ node_modules/uuid/CONTRIBUTING.md | 18 + node_modules/uuid/LICENSE.md | 9 + node_modules/uuid/README.md | 466 ++++++++++++++++++ node_modules/uuid/dist/bin/uuid | 2 + .../uuid/dist/commonjs-browser/index.js | 79 +++ .../uuid/dist/commonjs-browser/md5.js | 223 +++++++++ .../uuid/dist/commonjs-browser/native.js | 11 + .../uuid/dist/commonjs-browser/nil.js | 8 + .../uuid/dist/commonjs-browser/parse.js | 45 ++ .../uuid/dist/commonjs-browser/regex.js | 8 + .../uuid/dist/commonjs-browser/rng.js | 25 + .../uuid/dist/commonjs-browser/sha1.js | 104 ++++ .../uuid/dist/commonjs-browser/stringify.js | 44 ++ node_modules/uuid/dist/commonjs-browser/v1.js | 107 ++++ node_modules/uuid/dist/commonjs-browser/v3.js | 16 + .../uuid/dist/commonjs-browser/v35.js | 80 +++ node_modules/uuid/dist/commonjs-browser/v4.js | 43 ++ node_modules/uuid/dist/commonjs-browser/v5.js | 16 + .../uuid/dist/commonjs-browser/validate.js | 17 + .../uuid/dist/commonjs-browser/version.js | 21 + node_modules/uuid/dist/esm-browser/index.js | 9 + node_modules/uuid/dist/esm-browser/md5.js | 215 ++++++++ node_modules/uuid/dist/esm-browser/native.js | 4 + node_modules/uuid/dist/esm-browser/nil.js | 1 + node_modules/uuid/dist/esm-browser/parse.js | 35 ++ node_modules/uuid/dist/esm-browser/regex.js | 1 + node_modules/uuid/dist/esm-browser/rng.js | 18 + node_modules/uuid/dist/esm-browser/sha1.js | 96 ++++ .../uuid/dist/esm-browser/stringify.js | 33 ++ node_modules/uuid/dist/esm-browser/v1.js | 95 ++++ node_modules/uuid/dist/esm-browser/v3.js | 4 + node_modules/uuid/dist/esm-browser/v35.js | 66 +++ node_modules/uuid/dist/esm-browser/v4.js | 29 ++ node_modules/uuid/dist/esm-browser/v5.js | 4 + .../uuid/dist/esm-browser/validate.js | 7 + node_modules/uuid/dist/esm-browser/version.js | 11 + node_modules/uuid/dist/esm-node/index.js | 9 + node_modules/uuid/dist/esm-node/md5.js | 13 + node_modules/uuid/dist/esm-node/native.js | 4 + node_modules/uuid/dist/esm-node/nil.js | 1 + node_modules/uuid/dist/esm-node/parse.js | 35 ++ node_modules/uuid/dist/esm-node/regex.js | 1 + node_modules/uuid/dist/esm-node/rng.js | 12 + node_modules/uuid/dist/esm-node/sha1.js | 13 + node_modules/uuid/dist/esm-node/stringify.js | 33 ++ node_modules/uuid/dist/esm-node/v1.js | 95 ++++ node_modules/uuid/dist/esm-node/v3.js | 4 + node_modules/uuid/dist/esm-node/v35.js | 66 +++ node_modules/uuid/dist/esm-node/v4.js | 29 ++ node_modules/uuid/dist/esm-node/v5.js | 4 + node_modules/uuid/dist/esm-node/validate.js | 7 + node_modules/uuid/dist/esm-node/version.js | 11 + node_modules/uuid/dist/index.js | 79 +++ node_modules/uuid/dist/md5-browser.js | 223 +++++++++ node_modules/uuid/dist/md5.js | 23 + node_modules/uuid/dist/native-browser.js | 11 + node_modules/uuid/dist/native.js | 15 + node_modules/uuid/dist/nil.js | 8 + node_modules/uuid/dist/parse.js | 45 ++ node_modules/uuid/dist/regex.js | 8 + node_modules/uuid/dist/rng-browser.js | 25 + node_modules/uuid/dist/rng.js | 24 + node_modules/uuid/dist/sha1-browser.js | 104 ++++ node_modules/uuid/dist/sha1.js | 23 + node_modules/uuid/dist/stringify.js | 44 ++ node_modules/uuid/dist/uuid-bin.js | 85 ++++ node_modules/uuid/dist/v1.js | 107 ++++ node_modules/uuid/dist/v3.js | 16 + node_modules/uuid/dist/v35.js | 80 +++ node_modules/uuid/dist/v4.js | 43 ++ node_modules/uuid/dist/v5.js | 16 + node_modules/uuid/dist/validate.js | 17 + node_modules/uuid/dist/version.js | 21 + node_modules/uuid/package.json | 135 +++++ node_modules/uuid/wrapper.mjs | 10 + package.json | 5 + yarn.lock | 8 + 81 files changed, 3816 insertions(+) create mode 100644 client/packages/lowcoder-design/src/components/meeting.tsx create mode 120000 node_modules/.bin/uuid create mode 100644 node_modules/.yarn-integrity create mode 100644 node_modules/uuid/CHANGELOG.md create mode 100644 node_modules/uuid/CONTRIBUTING.md create mode 100644 node_modules/uuid/LICENSE.md create mode 100644 node_modules/uuid/README.md create mode 100755 node_modules/uuid/dist/bin/uuid create mode 100644 node_modules/uuid/dist/commonjs-browser/index.js create mode 100644 node_modules/uuid/dist/commonjs-browser/md5.js create mode 100644 node_modules/uuid/dist/commonjs-browser/native.js create mode 100644 node_modules/uuid/dist/commonjs-browser/nil.js create mode 100644 node_modules/uuid/dist/commonjs-browser/parse.js create mode 100644 node_modules/uuid/dist/commonjs-browser/regex.js create mode 100644 node_modules/uuid/dist/commonjs-browser/rng.js create mode 100644 node_modules/uuid/dist/commonjs-browser/sha1.js create mode 100644 node_modules/uuid/dist/commonjs-browser/stringify.js create mode 100644 node_modules/uuid/dist/commonjs-browser/v1.js create mode 100644 node_modules/uuid/dist/commonjs-browser/v3.js create mode 100644 node_modules/uuid/dist/commonjs-browser/v35.js create mode 100644 node_modules/uuid/dist/commonjs-browser/v4.js create mode 100644 node_modules/uuid/dist/commonjs-browser/v5.js create mode 100644 node_modules/uuid/dist/commonjs-browser/validate.js create mode 100644 node_modules/uuid/dist/commonjs-browser/version.js create mode 100644 node_modules/uuid/dist/esm-browser/index.js create mode 100644 node_modules/uuid/dist/esm-browser/md5.js create mode 100644 node_modules/uuid/dist/esm-browser/native.js create mode 100644 node_modules/uuid/dist/esm-browser/nil.js create mode 100644 node_modules/uuid/dist/esm-browser/parse.js create mode 100644 node_modules/uuid/dist/esm-browser/regex.js create mode 100644 node_modules/uuid/dist/esm-browser/rng.js create mode 100644 node_modules/uuid/dist/esm-browser/sha1.js create mode 100644 node_modules/uuid/dist/esm-browser/stringify.js create mode 100644 node_modules/uuid/dist/esm-browser/v1.js create mode 100644 node_modules/uuid/dist/esm-browser/v3.js create mode 100644 node_modules/uuid/dist/esm-browser/v35.js create mode 100644 node_modules/uuid/dist/esm-browser/v4.js create mode 100644 node_modules/uuid/dist/esm-browser/v5.js create mode 100644 node_modules/uuid/dist/esm-browser/validate.js create mode 100644 node_modules/uuid/dist/esm-browser/version.js create mode 100644 node_modules/uuid/dist/esm-node/index.js create mode 100644 node_modules/uuid/dist/esm-node/md5.js create mode 100644 node_modules/uuid/dist/esm-node/native.js create mode 100644 node_modules/uuid/dist/esm-node/nil.js create mode 100644 node_modules/uuid/dist/esm-node/parse.js create mode 100644 node_modules/uuid/dist/esm-node/regex.js create mode 100644 node_modules/uuid/dist/esm-node/rng.js create mode 100644 node_modules/uuid/dist/esm-node/sha1.js create mode 100644 node_modules/uuid/dist/esm-node/stringify.js create mode 100644 node_modules/uuid/dist/esm-node/v1.js create mode 100644 node_modules/uuid/dist/esm-node/v3.js create mode 100644 node_modules/uuid/dist/esm-node/v35.js create mode 100644 node_modules/uuid/dist/esm-node/v4.js create mode 100644 node_modules/uuid/dist/esm-node/v5.js create mode 100644 node_modules/uuid/dist/esm-node/validate.js create mode 100644 node_modules/uuid/dist/esm-node/version.js create mode 100644 node_modules/uuid/dist/index.js create mode 100644 node_modules/uuid/dist/md5-browser.js create mode 100644 node_modules/uuid/dist/md5.js create mode 100644 node_modules/uuid/dist/native-browser.js create mode 100644 node_modules/uuid/dist/native.js create mode 100644 node_modules/uuid/dist/nil.js create mode 100644 node_modules/uuid/dist/parse.js create mode 100644 node_modules/uuid/dist/regex.js create mode 100644 node_modules/uuid/dist/rng-browser.js create mode 100644 node_modules/uuid/dist/rng.js create mode 100644 node_modules/uuid/dist/sha1-browser.js create mode 100644 node_modules/uuid/dist/sha1.js create mode 100644 node_modules/uuid/dist/stringify.js create mode 100644 node_modules/uuid/dist/uuid-bin.js create mode 100644 node_modules/uuid/dist/v1.js create mode 100644 node_modules/uuid/dist/v3.js create mode 100644 node_modules/uuid/dist/v35.js create mode 100644 node_modules/uuid/dist/v4.js create mode 100644 node_modules/uuid/dist/v5.js create mode 100644 node_modules/uuid/dist/validate.js create mode 100644 node_modules/uuid/dist/version.js create mode 100644 node_modules/uuid/package.json create mode 100644 node_modules/uuid/wrapper.mjs create mode 100644 package.json create mode 100644 yarn.lock diff --git a/client/packages/lowcoder-design/src/components/meeting.tsx b/client/packages/lowcoder-design/src/components/meeting.tsx new file mode 100644 index 000000000..829044cf1 --- /dev/null +++ b/client/packages/lowcoder-design/src/components/meeting.tsx @@ -0,0 +1,43 @@ +import { trans } from "i18n/design"; +import { ReactNode } from "react"; +import styled from "styled-components"; +import { ReactComponent as MeetingContainerDrag } from "icons/icon-left-comp-video.svg"; + +type MeetingContainerPlaceholderProps = { + children?: ReactNode; +}; + +const HintText = styled.span` + font-size: 13px; + color: #b8b9bf; + text-align: center; +`; + +export function MeetingContainerPlaceholder( + props: MeetingContainerPlaceholderProps +) { + return ( +
+ + + {props.children} + +
+ ); +} + +export const MeetingHintPlaceHolder = ( + + {trans("container.hintPlaceHolder")} + +); diff --git a/node_modules/.bin/uuid b/node_modules/.bin/uuid new file mode 120000 index 000000000..588f70ecc --- /dev/null +++ b/node_modules/.bin/uuid @@ -0,0 +1 @@ +../uuid/dist/bin/uuid \ No newline at end of file diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity new file mode 100644 index 000000000..7799c779f --- /dev/null +++ b/node_modules/.yarn-integrity @@ -0,0 +1,16 @@ +{ + "systemParams": "darwin-x64-115", + "modulesFolders": [ + "node_modules" + ], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [ + "uuid@^9.0.1" + ], + "lockfileEntries": { + "uuid@^9.0.1": "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + }, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/node_modules/uuid/CHANGELOG.md b/node_modules/uuid/CHANGELOG.md new file mode 100644 index 000000000..0412ad8a6 --- /dev/null +++ b/node_modules/uuid/CHANGELOG.md @@ -0,0 +1,274 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [9.0.1](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1) (2023-09-12) + +### build + +- Fix CI to work with Node.js 20.x + +## [9.0.0](https://github.com/uuidjs/uuid/compare/v8.3.2...v9.0.0) (2022-09-05) + +### âš  BREAKING CHANGES + +- Drop Node.js 10.x support. This library always aims at supporting one EOLed LTS release which by this time now is 12.x which has reached EOL 30 Apr 2022. + +- Remove the minified UMD build from the package. + + Minified code is hard to audit and since this is a widely used library it seems more appropriate nowadays to optimize for auditability than to ship a legacy module format that, at best, serves educational purposes nowadays. + + For production browser use cases, users should be using a bundler. For educational purposes, today's online sandboxes like replit.com offer convenient ways to load npm modules, so the use case for UMD through repos like UNPKG or jsDelivr has largely vanished. + +- Drop IE 11 and Safari 10 support. Drop support for browsers that don't correctly implement const/let and default arguments, and no longer transpile the browser build to ES2015. + + This also removes the fallback on msCrypto instead of the crypto API. + + Browser tests are run in the first supported version of each supported browser and in the latest (as of this commit) version available on Browserstack. + +### Features + +- optimize uuid.v1 by 1.3x uuid.v4 by 4.3x (430%) ([#597](https://github.com/uuidjs/uuid/issues/597)) ([3a033f6](https://github.com/uuidjs/uuid/commit/3a033f6bab6bb3780ece6d645b902548043280bc)) +- remove UMD build ([#645](https://github.com/uuidjs/uuid/issues/645)) ([e948a0f](https://github.com/uuidjs/uuid/commit/e948a0f22bf22f4619b27bd913885e478e20fe6f)), closes [#620](https://github.com/uuidjs/uuid/issues/620) +- use native crypto.randomUUID when available ([#600](https://github.com/uuidjs/uuid/issues/600)) ([c9e076c](https://github.com/uuidjs/uuid/commit/c9e076c852edad7e9a06baaa1d148cf4eda6c6c4)) + +### Bug Fixes + +- add Jest/jsdom compatibility ([#642](https://github.com/uuidjs/uuid/issues/642)) ([16f9c46](https://github.com/uuidjs/uuid/commit/16f9c469edf46f0786164cdf4dc980743984a6fd)) +- change default export to named function ([#545](https://github.com/uuidjs/uuid/issues/545)) ([c57bc5a](https://github.com/uuidjs/uuid/commit/c57bc5a9a0653273aa639cda9177ce52efabe42a)) +- handle error when parameter is not set in v3 and v5 ([#622](https://github.com/uuidjs/uuid/issues/622)) ([fcd7388](https://github.com/uuidjs/uuid/commit/fcd73881692d9fabb63872576ba28e30ff852091)) +- run npm audit fix ([#644](https://github.com/uuidjs/uuid/issues/644)) ([04686f5](https://github.com/uuidjs/uuid/commit/04686f54c5fed2cfffc1b619f4970c4bb8532353)) +- upgrading from uuid3 broken link ([#568](https://github.com/uuidjs/uuid/issues/568)) ([1c849da](https://github.com/uuidjs/uuid/commit/1c849da6e164259e72e18636726345b13a7eddd6)) + +### build + +- drop Node.js 8.x from babel transpile target ([#603](https://github.com/uuidjs/uuid/issues/603)) ([aa11485](https://github.com/uuidjs/uuid/commit/aa114858260402107ec8a1e1a825dea0a259bcb5)) +- drop support for legacy browsers (IE11, Safari 10) ([#604](https://github.com/uuidjs/uuid/issues/604)) ([0f433e5](https://github.com/uuidjs/uuid/commit/0f433e5ec444edacd53016de67db021102f36148)) + +- drop node 10.x to upgrade dev dependencies ([#653](https://github.com/uuidjs/uuid/issues/653)) ([28a5712](https://github.com/uuidjs/uuid/commit/28a571283f8abda6b9d85e689f95b7d3ee9e282e)), closes [#643](https://github.com/uuidjs/uuid/issues/643) + +### [8.3.2](https://github.com/uuidjs/uuid/compare/v8.3.1...v8.3.2) (2020-12-08) + +### Bug Fixes + +- lazy load getRandomValues ([#537](https://github.com/uuidjs/uuid/issues/537)) ([16c8f6d](https://github.com/uuidjs/uuid/commit/16c8f6df2f6b09b4d6235602d6a591188320a82e)), closes [#536](https://github.com/uuidjs/uuid/issues/536) + +### [8.3.1](https://github.com/uuidjs/uuid/compare/v8.3.0...v8.3.1) (2020-10-04) + +### Bug Fixes + +- support expo>=39.0.0 ([#515](https://github.com/uuidjs/uuid/issues/515)) ([c65a0f3](https://github.com/uuidjs/uuid/commit/c65a0f3fa73b901959d638d1e3591dfacdbed867)), closes [#375](https://github.com/uuidjs/uuid/issues/375) + +## [8.3.0](https://github.com/uuidjs/uuid/compare/v8.2.0...v8.3.0) (2020-07-27) + +### Features + +- add parse/stringify/validate/version/NIL APIs ([#479](https://github.com/uuidjs/uuid/issues/479)) ([0e6c10b](https://github.com/uuidjs/uuid/commit/0e6c10ba1bf9517796ff23c052fc0468eedfd5f4)), closes [#475](https://github.com/uuidjs/uuid/issues/475) [#478](https://github.com/uuidjs/uuid/issues/478) [#480](https://github.com/uuidjs/uuid/issues/480) [#481](https://github.com/uuidjs/uuid/issues/481) [#180](https://github.com/uuidjs/uuid/issues/180) + +## [8.2.0](https://github.com/uuidjs/uuid/compare/v8.1.0...v8.2.0) (2020-06-23) + +### Features + +- improve performance of v1 string representation ([#453](https://github.com/uuidjs/uuid/issues/453)) ([0ee0b67](https://github.com/uuidjs/uuid/commit/0ee0b67c37846529c66089880414d29f3ae132d5)) +- remove deprecated v4 string parameter ([#454](https://github.com/uuidjs/uuid/issues/454)) ([88ce3ca](https://github.com/uuidjs/uuid/commit/88ce3ca0ba046f60856de62c7ce03f7ba98ba46c)), closes [#437](https://github.com/uuidjs/uuid/issues/437) +- support jspm ([#473](https://github.com/uuidjs/uuid/issues/473)) ([e9f2587](https://github.com/uuidjs/uuid/commit/e9f2587a92575cac31bc1d4ae944e17c09756659)) + +### Bug Fixes + +- prepare package exports for webpack 5 ([#468](https://github.com/uuidjs/uuid/issues/468)) ([8d6e6a5](https://github.com/uuidjs/uuid/commit/8d6e6a5f8965ca9575eb4d92e99a43435f4a58a8)) + +## [8.1.0](https://github.com/uuidjs/uuid/compare/v8.0.0...v8.1.0) (2020-05-20) + +### Features + +- improve v4 performance by reusing random number array ([#435](https://github.com/uuidjs/uuid/issues/435)) ([bf4af0d](https://github.com/uuidjs/uuid/commit/bf4af0d711b4d2ed03d1f74fd12ad0baa87dc79d)) +- optimize V8 performance of bytesToUuid ([#434](https://github.com/uuidjs/uuid/issues/434)) ([e156415](https://github.com/uuidjs/uuid/commit/e156415448ec1af2351fa0b6660cfb22581971f2)) + +### Bug Fixes + +- export package.json required by react-native and bundlers ([#449](https://github.com/uuidjs/uuid/issues/449)) ([be1c8fe](https://github.com/uuidjs/uuid/commit/be1c8fe9a3206c358e0059b52fafd7213aa48a52)), closes [ai/nanoevents#44](https://github.com/ai/nanoevents/issues/44#issuecomment-602010343) [#444](https://github.com/uuidjs/uuid/issues/444) + +## [8.0.0](https://github.com/uuidjs/uuid/compare/v7.0.3...v8.0.0) (2020-04-29) + +### âš  BREAKING CHANGES + +- For native ECMAScript Module (ESM) usage in Node.js only named exports are exposed, there is no more default export. + + ```diff + -import uuid from 'uuid'; + -console.log(uuid.v4()); // -> 'cd6c3b08-0adc-4f4b-a6ef-36087a1c9869' + +import { v4 as uuidv4 } from 'uuid'; + +uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' + ``` + +- Deep requiring specific algorithms of this library like `require('uuid/v4')`, which has been deprecated in `uuid@7`, is no longer supported. + + Instead use the named exports that this module exports. + + For ECMAScript Modules (ESM): + + ```diff + -import uuidv4 from 'uuid/v4'; + +import { v4 as uuidv4 } from 'uuid'; + uuidv4(); + ``` + + For CommonJS: + + ```diff + -const uuidv4 = require('uuid/v4'); + +const { v4: uuidv4 } = require('uuid'); + uuidv4(); + ``` + +### Features + +- native Node.js ES Modules (wrapper approach) ([#423](https://github.com/uuidjs/uuid/issues/423)) ([2d9f590](https://github.com/uuidjs/uuid/commit/2d9f590ad9701d692625c07ed62f0a0f91227991)), closes [#245](https://github.com/uuidjs/uuid/issues/245) [#419](https://github.com/uuidjs/uuid/issues/419) [#342](https://github.com/uuidjs/uuid/issues/342) +- remove deep requires ([#426](https://github.com/uuidjs/uuid/issues/426)) ([daf72b8](https://github.com/uuidjs/uuid/commit/daf72b84ceb20272a81bb5fbddb05dd95922cbba)) + +### Bug Fixes + +- add CommonJS syntax example to README quickstart section ([#417](https://github.com/uuidjs/uuid/issues/417)) ([e0ec840](https://github.com/uuidjs/uuid/commit/e0ec8402c7ad44b7ef0453036c612f5db513fda0)) + +### [7.0.3](https://github.com/uuidjs/uuid/compare/v7.0.2...v7.0.3) (2020-03-31) + +### Bug Fixes + +- make deep require deprecation warning work in browsers ([#409](https://github.com/uuidjs/uuid/issues/409)) ([4b71107](https://github.com/uuidjs/uuid/commit/4b71107d8c0d2ef56861ede6403fc9dc35a1e6bf)), closes [#408](https://github.com/uuidjs/uuid/issues/408) + +### [7.0.2](https://github.com/uuidjs/uuid/compare/v7.0.1...v7.0.2) (2020-03-04) + +### Bug Fixes + +- make access to msCrypto consistent ([#393](https://github.com/uuidjs/uuid/issues/393)) ([8bf2a20](https://github.com/uuidjs/uuid/commit/8bf2a20f3565df743da7215eebdbada9d2df118c)) +- simplify link in deprecation warning ([#391](https://github.com/uuidjs/uuid/issues/391)) ([bb2c8e4](https://github.com/uuidjs/uuid/commit/bb2c8e4e9f4c5f9c1eaaf3ea59710c633cd90cb7)) +- update links to match content in readme ([#386](https://github.com/uuidjs/uuid/issues/386)) ([44f2f86](https://github.com/uuidjs/uuid/commit/44f2f86e9d2bbf14ee5f0f00f72a3db1292666d4)) + +### [7.0.1](https://github.com/uuidjs/uuid/compare/v7.0.0...v7.0.1) (2020-02-25) + +### Bug Fixes + +- clean up esm builds for node and browser ([#383](https://github.com/uuidjs/uuid/issues/383)) ([59e6a49](https://github.com/uuidjs/uuid/commit/59e6a49e7ce7b3e8fb0f3ee52b9daae72af467dc)) +- provide browser versions independent from module system ([#380](https://github.com/uuidjs/uuid/issues/380)) ([4344a22](https://github.com/uuidjs/uuid/commit/4344a22e7aed33be8627eeaaf05360f256a21753)), closes [#378](https://github.com/uuidjs/uuid/issues/378) + +## [7.0.0](https://github.com/uuidjs/uuid/compare/v3.4.0...v7.0.0) (2020-02-24) + +### âš  BREAKING CHANGES + +- The default export, which used to be the v4() method but which was already discouraged in v3.x of this library, has been removed. +- Explicitly note that deep imports of the different uuid version functions are deprecated and no longer encouraged and that ECMAScript module named imports should be used instead. Emit a deprecation warning for people who deep-require the different algorithm variants. +- Remove builtin support for insecure random number generators in the browser. Users who want that will have to supply their own random number generator function. +- Remove support for generating v3 and v5 UUIDs in Node.js<4.x +- Convert code base to ECMAScript Modules (ESM) and release CommonJS build for node and ESM build for browser bundlers. + +### Features + +- add UMD build to npm package ([#357](https://github.com/uuidjs/uuid/issues/357)) ([4e75adf](https://github.com/uuidjs/uuid/commit/4e75adf435196f28e3fbbe0185d654b5ded7ca2c)), closes [#345](https://github.com/uuidjs/uuid/issues/345) +- add various es module and CommonJS examples ([b238510](https://github.com/uuidjs/uuid/commit/b238510bf352463521f74bab175a3af9b7a42555)) +- ensure that docs are up-to-date in CI ([ee5e77d](https://github.com/uuidjs/uuid/commit/ee5e77db547474f5a8f23d6c857a6d399209986b)) +- hybrid CommonJS & ECMAScript modules build ([a3f078f](https://github.com/uuidjs/uuid/commit/a3f078faa0baff69ab41aed08e041f8f9c8993d0)) +- remove insecure fallback random number generator ([3a5842b](https://github.com/uuidjs/uuid/commit/3a5842b141a6e5de0ae338f391661e6b84b167c9)), closes [#173](https://github.com/uuidjs/uuid/issues/173) +- remove support for pre Node.js v4 Buffer API ([#356](https://github.com/uuidjs/uuid/issues/356)) ([b59b5c5](https://github.com/uuidjs/uuid/commit/b59b5c5ecad271c5453f1a156f011671f6d35627)) +- rename repository to github:uuidjs/uuid ([#351](https://github.com/uuidjs/uuid/issues/351)) ([c37a518](https://github.com/uuidjs/uuid/commit/c37a518e367ac4b6d0aa62dba1bc6ce9e85020f7)), closes [#338](https://github.com/uuidjs/uuid/issues/338) + +### Bug Fixes + +- add deep-require proxies for local testing and adjust tests ([#365](https://github.com/uuidjs/uuid/issues/365)) ([7fedc79](https://github.com/uuidjs/uuid/commit/7fedc79ac8fda4bfd1c566c7f05ef4ac13b2db48)) +- add note about removal of default export ([#372](https://github.com/uuidjs/uuid/issues/372)) ([12749b7](https://github.com/uuidjs/uuid/commit/12749b700eb49db8a9759fd306d8be05dbfbd58c)), closes [#370](https://github.com/uuidjs/uuid/issues/370) +- deprecated deep requiring of the different algorithm versions ([#361](https://github.com/uuidjs/uuid/issues/361)) ([c0bdf15](https://github.com/uuidjs/uuid/commit/c0bdf15e417639b1aeb0b247b2fb11f7a0a26b23)) + +## [3.4.0](https://github.com/uuidjs/uuid/compare/v3.3.3...v3.4.0) (2020-01-16) + +### Features + +- rename repository to github:uuidjs/uuid ([#351](https://github.com/uuidjs/uuid/issues/351)) ([e2d7314](https://github.com/uuidjs/uuid/commit/e2d7314)), closes [#338](https://github.com/uuidjs/uuid/issues/338) + +## [3.3.3](https://github.com/uuidjs/uuid/compare/v3.3.2...v3.3.3) (2019-08-19) + +### Bug Fixes + +- no longer run ci tests on node v4 +- upgrade dependencies + +## [3.3.2](https://github.com/uuidjs/uuid/compare/v3.3.1...v3.3.2) (2018-06-28) + +### Bug Fixes + +- typo ([305d877](https://github.com/uuidjs/uuid/commit/305d877)) + +## [3.3.1](https://github.com/uuidjs/uuid/compare/v3.3.0...v3.3.1) (2018-06-28) + +### Bug Fixes + +- fix [#284](https://github.com/uuidjs/uuid/issues/284) by setting function name in try-catch ([f2a60f2](https://github.com/uuidjs/uuid/commit/f2a60f2)) + +# [3.3.0](https://github.com/uuidjs/uuid/compare/v3.2.1...v3.3.0) (2018-06-22) + +### Bug Fixes + +- assignment to readonly property to allow running in strict mode ([#270](https://github.com/uuidjs/uuid/issues/270)) ([d062fdc](https://github.com/uuidjs/uuid/commit/d062fdc)) +- fix [#229](https://github.com/uuidjs/uuid/issues/229) ([c9684d4](https://github.com/uuidjs/uuid/commit/c9684d4)) +- Get correct version of IE11 crypto ([#274](https://github.com/uuidjs/uuid/issues/274)) ([153d331](https://github.com/uuidjs/uuid/commit/153d331)) +- mem issue when generating uuid ([#267](https://github.com/uuidjs/uuid/issues/267)) ([c47702c](https://github.com/uuidjs/uuid/commit/c47702c)) + +### Features + +- enforce Conventional Commit style commit messages ([#282](https://github.com/uuidjs/uuid/issues/282)) ([cc9a182](https://github.com/uuidjs/uuid/commit/cc9a182)) + +## [3.2.1](https://github.com/uuidjs/uuid/compare/v3.2.0...v3.2.1) (2018-01-16) + +### Bug Fixes + +- use msCrypto if available. Fixes [#241](https://github.com/uuidjs/uuid/issues/241) ([#247](https://github.com/uuidjs/uuid/issues/247)) ([1fef18b](https://github.com/uuidjs/uuid/commit/1fef18b)) + +# [3.2.0](https://github.com/uuidjs/uuid/compare/v3.1.0...v3.2.0) (2018-01-16) + +### Bug Fixes + +- remove mistakenly added typescript dependency, rollback version (standard-version will auto-increment) ([09fa824](https://github.com/uuidjs/uuid/commit/09fa824)) +- use msCrypto if available. Fixes [#241](https://github.com/uuidjs/uuid/issues/241) ([#247](https://github.com/uuidjs/uuid/issues/247)) ([1fef18b](https://github.com/uuidjs/uuid/commit/1fef18b)) + +### Features + +- Add v3 Support ([#217](https://github.com/uuidjs/uuid/issues/217)) ([d94f726](https://github.com/uuidjs/uuid/commit/d94f726)) + +# [3.1.0](https://github.com/uuidjs/uuid/compare/v3.1.0...v3.0.1) (2017-06-17) + +### Bug Fixes + +- (fix) Add .npmignore file to exclude test/ and other non-essential files from packing. (#183) +- Fix typo (#178) +- Simple typo fix (#165) + +### Features + +- v5 support in CLI (#197) +- V5 support (#188) + +# 3.0.1 (2016-11-28) + +- split uuid versions into separate files + +# 3.0.0 (2016-11-17) + +- remove .parse and .unparse + +# 2.0.0 + +- Removed uuid.BufferClass + +# 1.4.0 + +- Improved module context detection +- Removed public RNG functions + +# 1.3.2 + +- Improve tests and handling of v1() options (Issue #24) +- Expose RNG option to allow for perf testing with different generators + +# 1.3.0 + +- Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)! +- Support for node.js crypto API +- De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code diff --git a/node_modules/uuid/CONTRIBUTING.md b/node_modules/uuid/CONTRIBUTING.md new file mode 100644 index 000000000..4a4503d02 --- /dev/null +++ b/node_modules/uuid/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing + +Please feel free to file GitHub Issues or propose Pull Requests. We're always happy to discuss improvements to this library! + +## Testing + +```shell +npm test +``` + +## Releasing + +Releases are supposed to be done from master, version bumping is automated through [`standard-version`](https://github.com/conventional-changelog/standard-version): + +```shell +npm run release -- --dry-run # verify output manually +npm run release # follow the instructions from the output of this command +``` diff --git a/node_modules/uuid/LICENSE.md b/node_modules/uuid/LICENSE.md new file mode 100644 index 000000000..393416836 --- /dev/null +++ b/node_modules/uuid/LICENSE.md @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2010-2020 Robert Kieffer and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/uuid/README.md b/node_modules/uuid/README.md new file mode 100644 index 000000000..4f51e0980 --- /dev/null +++ b/node_modules/uuid/README.md @@ -0,0 +1,466 @@ + + + +# uuid [![CI](https://github.com/uuidjs/uuid/workflows/CI/badge.svg)](https://github.com/uuidjs/uuid/actions?query=workflow%3ACI) [![Browser](https://github.com/uuidjs/uuid/workflows/Browser/badge.svg)](https://github.com/uuidjs/uuid/actions?query=workflow%3ABrowser) + +For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs + +- **Complete** - Support for RFC4122 version 1, 3, 4, and 5 UUIDs +- **Cross-platform** - Support for ... + - CommonJS, [ECMAScript Modules](#ecmascript-modules) and [CDN builds](#cdn-builds) + - NodeJS 12+ ([LTS releases](https://github.com/nodejs/Release)) + - Chrome, Safari, Firefox, Edge browsers + - Webpack and rollup.js module bundlers + - [React Native / Expo](#react-native--expo) +- **Secure** - Cryptographically-strong random values +- **Small** - Zero-dependency, small footprint, plays nice with "tree shaking" packagers +- **CLI** - Includes the [`uuid` command line](#command-line) utility + +> **Note** Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details. + +> **Note** Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library. + +## Quickstart + +To create a random UUID... + +**1. Install** + +```shell +npm install uuid +``` + +**2. Create a UUID** (ES6 module syntax) + +```javascript +import { v4 as uuidv4 } from 'uuid'; +uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' +``` + +... or using CommonJS syntax: + +```javascript +const { v4: uuidv4 } = require('uuid'); +uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed' +``` + +For timestamp UUIDs, namespace UUIDs, and other options read on ... + +## API Summary + +| | | | +| --- | --- | --- | +| [`uuid.NIL`](#uuidnil) | The nil UUID string (all zeros) | New in `uuid@8.3` | +| [`uuid.parse()`](#uuidparsestr) | Convert UUID string to array of bytes | New in `uuid@8.3` | +| [`uuid.stringify()`](#uuidstringifyarr-offset) | Convert array of bytes to UUID string | New in `uuid@8.3` | +| [`uuid.v1()`](#uuidv1options-buffer-offset) | Create a version 1 (timestamp) UUID | | +| [`uuid.v3()`](#uuidv3name-namespace-buffer-offset) | Create a version 3 (namespace w/ MD5) UUID | | +| [`uuid.v4()`](#uuidv4options-buffer-offset) | Create a version 4 (random) UUID | | +| [`uuid.v5()`](#uuidv5name-namespace-buffer-offset) | Create a version 5 (namespace w/ SHA-1) UUID | | +| [`uuid.validate()`](#uuidvalidatestr) | Test a string to see if it is a valid UUID | New in `uuid@8.3` | +| [`uuid.version()`](#uuidversionstr) | Detect RFC version of a UUID | New in `uuid@8.3` | + +## API + +### uuid.NIL + +The nil UUID string (all zeros). + +Example: + +```javascript +import { NIL as NIL_UUID } from 'uuid'; + +NIL_UUID; // ⇨ '00000000-0000-0000-0000-000000000000' +``` + +### uuid.parse(str) + +Convert UUID string to array of bytes + +| | | +| --------- | ---------------------------------------- | +| `str` | A valid UUID `String` | +| _returns_ | `Uint8Array[16]` | +| _throws_ | `TypeError` if `str` is not a valid UUID | + +Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left ↠ right order of hex-pairs in UUID strings. As shown in the example below. + +Example: + +```javascript +import { parse as uuidParse } from 'uuid'; + +// Parse a UUID +const bytes = uuidParse('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); + +// Convert to hex strings to show byte order (for documentation purposes) +[...bytes].map((v) => v.toString(16).padStart(2, '0')); // ⇨ + // [ + // '6e', 'c0', 'bd', '7f', + // '11', 'c0', '43', 'da', + // '97', '5e', '2a', '8a', + // 'd9', 'eb', 'ae', '0b' + // ] +``` + +### uuid.stringify(arr[, offset]) + +Convert array of bytes to UUID string + +| | | +| -------------- | ---------------------------------------------------------------------------- | +| `arr` | `Array`-like collection of 16 values (starting from `offset`) between 0-255. | +| [`offset` = 0] | `Number` Starting index in the Array | +| _returns_ | `String` | +| _throws_ | `TypeError` if a valid UUID string cannot be generated | + +Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left ↠ right order of hex-pairs in UUID strings. As shown in the example below. + +Example: + +```javascript +import { stringify as uuidStringify } from 'uuid'; + +const uuidBytes = [ + 0x6e, 0xc0, 0xbd, 0x7f, 0x11, 0xc0, 0x43, 0xda, 0x97, 0x5e, 0x2a, 0x8a, 0xd9, 0xeb, 0xae, 0x0b, +]; + +uuidStringify(uuidBytes); // ⇨ '6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b' +``` + +### uuid.v1([options[, buffer[, offset]]]) + +Create an RFC version 1 (timestamp) UUID + +| | | +| --- | --- | +| [`options`] | `Object` with one or more of the following properties: | +| [`options.node` ] | RFC "node" field as an `Array[6]` of byte values (per 4.1.6) | +| [`options.clockseq`] | RFC "clock sequence" as a `Number` between 0 - 0x3fff | +| [`options.msecs`] | RFC "timestamp" field (`Number` of milliseconds, unix epoch) | +| [`options.nsecs`] | RFC "timestamp" field (`Number` of nanoseconds to add to `msecs`, should be 0-10,000) | +| [`options.random`] | `Array` of 16 random bytes (0-255) | +| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) | +| [`buffer`] | `Array \| Buffer` If specified, uuid will be written here in byte-form, starting at `offset` | +| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` | +| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` | +| _throws_ | `Error` if more than 10M UUIDs/sec are requested | + +Note: The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process. + +Note: `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields. + +Example: + +```javascript +import { v1 as uuidv1 } from 'uuid'; + +uuidv1(); // ⇨ '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d' +``` + +Example using `options`: + +```javascript +import { v1 as uuidv1 } from 'uuid'; + +const v1options = { + node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab], + clockseq: 0x1234, + msecs: new Date('2011-11-01').getTime(), + nsecs: 5678, +}; +uuidv1(v1options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab' +``` + +### uuid.v3(name, namespace[, buffer[, offset]]) + +Create an RFC version 3 (namespace w/ MD5) UUID + +API is identical to `v5()`, but uses "v3" instead. + +⚠️ Note: Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_." + +### uuid.v4([options[, buffer[, offset]]]) + +Create an RFC version 4 (random) UUID + +| | | +| --- | --- | +| [`options`] | `Object` with one or more of the following properties: | +| [`options.random`] | `Array` of 16 random bytes (0-255) | +| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) | +| [`buffer`] | `Array \| Buffer` If specified, uuid will be written here in byte-form, starting at `offset` | +| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` | +| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` | + +Example: + +```javascript +import { v4 as uuidv4 } from 'uuid'; + +uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed' +``` + +Example using predefined `random` values: + +```javascript +import { v4 as uuidv4 } from 'uuid'; + +const v4options = { + random: [ + 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea, 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36, + ], +}; +uuidv4(v4options); // ⇨ '109156be-c4fb-41ea-b1b4-efe1671c5836' +``` + +### uuid.v5(name, namespace[, buffer[, offset]]) + +Create an RFC version 5 (namespace w/ SHA-1) UUID + +| | | +| --- | --- | +| `name` | `String \| Array` | +| `namespace` | `String \| Array[16]` Namespace UUID | +| [`buffer`] | `Array \| Buffer` If specified, uuid will be written here in byte-form, starting at `offset` | +| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` | +| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` | + +Note: The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`. + +Example with custom namespace: + +```javascript +import { v5 as uuidv5 } from 'uuid'; + +// Define a custom namespace. Readers, create your own using something like +// https://www.uuidgenerator.net/ +const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341'; + +uuidv5('Hello, World!', MY_NAMESPACE); // ⇨ '630eb68f-e0fa-5ecc-887a-7c7a62614681' +``` + +Example with RFC `URL` namespace: + +```javascript +import { v5 as uuidv5 } from 'uuid'; + +uuidv5('https://www.w3.org/', uuidv5.URL); // ⇨ 'c106a26a-21bb-5538-8bf2-57095d1976c1' +``` + +### uuid.validate(str) + +Test a string to see if it is a valid UUID + +| | | +| --------- | --------------------------------------------------- | +| `str` | `String` to validate | +| _returns_ | `true` if string is a valid UUID, `false` otherwise | + +Example: + +```javascript +import { validate as uuidValidate } from 'uuid'; + +uuidValidate('not a UUID'); // ⇨ false +uuidValidate('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ true +``` + +Using `validate` and `version` together it is possible to do per-version validation, e.g. validate for only v4 UUIds. + +```javascript +import { version as uuidVersion } from 'uuid'; +import { validate as uuidValidate } from 'uuid'; + +function uuidValidateV4(uuid) { + return uuidValidate(uuid) && uuidVersion(uuid) === 4; +} + +const v1Uuid = 'd9428888-122b-11e1-b85c-61cd3cbb3210'; +const v4Uuid = '109156be-c4fb-41ea-b1b4-efe1671c5836'; + +uuidValidateV4(v4Uuid); // ⇨ true +uuidValidateV4(v1Uuid); // ⇨ false +``` + +### uuid.version(str) + +Detect RFC version of a UUID + +| | | +| --------- | ---------------------------------------- | +| `str` | A valid UUID `String` | +| _returns_ | `Number` The RFC version of the UUID | +| _throws_ | `TypeError` if `str` is not a valid UUID | + +Example: + +```javascript +import { version as uuidVersion } from 'uuid'; + +uuidVersion('45637ec4-c85f-11ea-87d0-0242ac130003'); // ⇨ 1 +uuidVersion('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ 4 +``` + +## Command Line + +UUIDs can be generated from the command line using `uuid`. + +```shell +$ npx uuid +ddeb27fb-d9a0-4624-be4d-4615062daed4 +``` + +The default is to generate version 4 UUIDS, however the other versions are supported. Type `uuid --help` for details: + +```shell +$ npx uuid --help + +Usage: + uuid + uuid v1 + uuid v3 + uuid v4 + uuid v5 + uuid --help + +Note: may be "URL" or "DNS" to use the corresponding UUIDs +defined by RFC4122 +``` + +## ECMAScript Modules + +This library comes with [ECMAScript Modules](https://www.ecma-international.org/ecma-262/6.0/#sec-modules) (ESM) support for Node.js versions that support it ([example](./examples/node-esmodules/)) as well as bundlers like [rollup.js](https://rollupjs.org/guide/en/#tree-shaking) ([example](./examples/browser-rollup/)) and [webpack](https://webpack.js.org/guides/tree-shaking/) ([example](./examples/browser-webpack/)) (targeting both, Node.js and browser environments). + +```javascript +import { v4 as uuidv4 } from 'uuid'; +uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed' +``` + +To run the examples you must first create a dist build of this library in the module root: + +```shell +npm run build +``` + +## CDN Builds + +### ECMAScript Modules + +To load this module directly into modern browsers that [support loading ECMAScript Modules](https://caniuse.com/#feat=es6-module) you can make use of [jspm](https://jspm.org/): + +```html + +``` + +### UMD + +As of `uuid@9` [UMD (Universal Module Definition)](https://github.com/umdjs/umd) builds are no longer shipped with this library. + +If you need a UMD build of this library, use a bundler like Webpack or Rollup. Alternatively, refer to the documentation of [`uuid@8.3.2`](https://github.com/uuidjs/uuid/blob/v8.3.2/README.md#umd) which was the last version that shipped UMD builds. + +## Known issues + +### Duplicate UUIDs (Googlebot) + +This module may generate duplicate UUIDs when run in clients with _deterministic_ random number generators, such as [Googlebot crawlers](https://developers.google.com/search/docs/advanced/crawling/overview-google-crawlers). This can cause problems for apps that expect client-generated UUIDs to always be unique. Developers should be prepared for this and have a strategy for dealing with possible collisions, such as: + +- Check for duplicate UUIDs, fail gracefully +- Disable write operations for Googlebot clients + +### "getRandomValues() not supported" + +This error occurs in environments where the standard [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) API is not supported. This issue can be resolved by adding an appropriate polyfill: + +### React Native / Expo + +1. Install [`react-native-get-random-values`](https://github.com/LinusU/react-native-get-random-values#readme) +1. Import it _before_ `uuid`. Since `uuid` might also appear as a transitive dependency of some other imports it's safest to just import `react-native-get-random-values` as the very first thing in your entry point: + +```javascript +import 'react-native-get-random-values'; +import { v4 as uuidv4 } from 'uuid'; +``` + +Note: If you are using Expo, you must be using at least `react-native-get-random-values@1.5.0` and `expo@39.0.0`. + +### Web Workers / Service Workers (Edge <= 18) + +[In Edge <= 18, Web Crypto is not supported in Web Workers or Service Workers](https://caniuse.com/#feat=cryptography) and we are not aware of a polyfill (let us know if you find one, please). + +### IE 11 (Internet Explorer) + +Support for IE11 and other legacy browsers has been dropped as of `uuid@9`. If you need to support legacy browsers, you can always transpile the uuid module source yourself (e.g. using [Babel](https://babeljs.io/)). + +## Upgrading From `uuid@7` + +### Only Named Exports Supported When Using with Node.js ESM + +`uuid@7` did not come with native ECMAScript Module (ESM) support for Node.js. Importing it in Node.js ESM consequently imported the CommonJS source with a default export. This library now comes with true Node.js ESM support and only provides named exports. + +Instead of doing: + +```javascript +import uuid from 'uuid'; +uuid.v4(); +``` + +you will now have to use the named exports: + +```javascript +import { v4 as uuidv4 } from 'uuid'; +uuidv4(); +``` + +### Deep Requires No Longer Supported + +Deep requires like `require('uuid/v4')` [which have been deprecated in `uuid@7`](#deep-requires-now-deprecated) are no longer supported. + +## Upgrading From `uuid@3` + +"_Wait... what happened to `uuid@4` thru `uuid@6`?!?_" + +In order to avoid confusion with RFC [version 4](#uuidv4options-buffer-offset) and [version 5](#uuidv5name-namespace-buffer-offset) UUIDs, and a possible [version 6](http://gh.peabody.io/uuidv6/), releases 4 thru 6 of this module have been skipped. + +### Deep Requires Now Deprecated + +`uuid@3` encouraged the use of deep requires to minimize the bundle size of browser builds: + +```javascript +const uuidv4 = require('uuid/v4'); // <== NOW DEPRECATED! +uuidv4(); +``` + +As of `uuid@7` this library now provides ECMAScript modules builds, which allow packagers like Webpack and Rollup to do "tree-shaking" to remove dead code. Instead, use the `import` syntax: + +```javascript +import { v4 as uuidv4 } from 'uuid'; +uuidv4(); +``` + +... or for CommonJS: + +```javascript +const { v4: uuidv4 } = require('uuid'); +uuidv4(); +``` + +### Default Export Removed + +`uuid@3` was exporting the Version 4 UUID method as a default export: + +```javascript +const uuid = require('uuid'); // <== REMOVED! +``` + +This usage pattern was already discouraged in `uuid@3` and has been removed in `uuid@7`. + +--- + +Markdown generated from [README_js.md](README_js.md) by diff --git a/node_modules/uuid/dist/bin/uuid b/node_modules/uuid/dist/bin/uuid new file mode 100755 index 000000000..f38d2ee19 --- /dev/null +++ b/node_modules/uuid/dist/bin/uuid @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require('../uuid-bin'); diff --git a/node_modules/uuid/dist/commonjs-browser/index.js b/node_modules/uuid/dist/commonjs-browser/index.js new file mode 100644 index 000000000..5586dd3d0 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/index.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "NIL", { + enumerable: true, + get: function get() { + return _nil.default; + } +}); +Object.defineProperty(exports, "parse", { + enumerable: true, + get: function get() { + return _parse.default; + } +}); +Object.defineProperty(exports, "stringify", { + enumerable: true, + get: function get() { + return _stringify.default; + } +}); +Object.defineProperty(exports, "v1", { + enumerable: true, + get: function get() { + return _v.default; + } +}); +Object.defineProperty(exports, "v3", { + enumerable: true, + get: function get() { + return _v2.default; + } +}); +Object.defineProperty(exports, "v4", { + enumerable: true, + get: function get() { + return _v3.default; + } +}); +Object.defineProperty(exports, "v5", { + enumerable: true, + get: function get() { + return _v4.default; + } +}); +Object.defineProperty(exports, "validate", { + enumerable: true, + get: function get() { + return _validate.default; + } +}); +Object.defineProperty(exports, "version", { + enumerable: true, + get: function get() { + return _version.default; + } +}); + +var _v = _interopRequireDefault(require("./v1.js")); + +var _v2 = _interopRequireDefault(require("./v3.js")); + +var _v3 = _interopRequireDefault(require("./v4.js")); + +var _v4 = _interopRequireDefault(require("./v5.js")); + +var _nil = _interopRequireDefault(require("./nil.js")); + +var _version = _interopRequireDefault(require("./version.js")); + +var _validate = _interopRequireDefault(require("./validate.js")); + +var _stringify = _interopRequireDefault(require("./stringify.js")); + +var _parse = _interopRequireDefault(require("./parse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/md5.js b/node_modules/uuid/dist/commonjs-browser/md5.js new file mode 100644 index 000000000..7a4582ace --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/md5.js @@ -0,0 +1,223 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +/* + * Browser-compatible JavaScript MD5 + * + * Modification of JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ +function md5(bytes) { + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = new Uint8Array(msg.length); + + for (let i = 0; i < msg.length; ++i) { + bytes[i] = msg.charCodeAt(i); + } + } + + return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8)); +} +/* + * Convert an array of little-endian words to an array of bytes + */ + + +function md5ToHexEncodedArray(input) { + const output = []; + const length32 = input.length * 32; + const hexTab = '0123456789abcdef'; + + for (let i = 0; i < length32; i += 8) { + const x = input[i >> 5] >>> i % 32 & 0xff; + const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16); + output.push(hex); + } + + return output; +} +/** + * Calculate output length with padding and bit length + */ + + +function getOutputLength(inputLength8) { + return (inputLength8 + 64 >>> 9 << 4) + 14 + 1; +} +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + + +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[getOutputLength(len) - 1] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + + for (let i = 0; i < x.length; i += 16) { + const olda = a; + const oldb = b; + const oldc = c; + const oldd = d; + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + + return [a, b, c, d]; +} +/* + * Convert an array bytes to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + + +function bytesToWords(input) { + if (input.length === 0) { + return []; + } + + const length8 = input.length * 8; + const output = new Uint32Array(getOutputLength(length8)); + + for (let i = 0; i < length8; i += 8) { + output[i >> 5] |= (input[i / 8] & 0xff) << i % 32; + } + + return output; +} +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + + +function safeAdd(x, y) { + const lsw = (x & 0xffff) + (y & 0xffff); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xffff; +} +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +function bitRotateLeft(num, cnt) { + return num << cnt | num >>> 32 - cnt; +} +/* + * These functions implement the four basic operations the algorithm uses. + */ + + +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} + +function md5ff(a, b, c, d, x, s, t) { + return md5cmn(b & c | ~b & d, a, b, x, s, t); +} + +function md5gg(a, b, c, d, x, s, t) { + return md5cmn(b & d | c & ~d, a, b, x, s, t); +} + +function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); +} + +function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t); +} + +var _default = md5; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/native.js b/node_modules/uuid/dist/commonjs-browser/native.js new file mode 100644 index 000000000..c2eea59d0 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/native.js @@ -0,0 +1,11 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); +var _default = { + randomUUID +}; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/nil.js b/node_modules/uuid/dist/commonjs-browser/nil.js new file mode 100644 index 000000000..7ade577b2 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/nil.js @@ -0,0 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/parse.js b/node_modules/uuid/dist/commonjs-browser/parse.js new file mode 100644 index 000000000..4c69fc39e --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/parse.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +var _default = parse; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/regex.js b/node_modules/uuid/dist/commonjs-browser/regex.js new file mode 100644 index 000000000..1ef91d64c --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/regex.js @@ -0,0 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/rng.js b/node_modules/uuid/dist/commonjs-browser/rng.js new file mode 100644 index 000000000..d067cdb04 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/rng.js @@ -0,0 +1,25 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = rng; +// Unique ID creation requires a high quality random # generator. In the browser we therefore +// require the crypto API and do not support built-in fallback to lower quality random number +// generators (like Math.random()). +let getRandomValues; +const rnds8 = new Uint8Array(16); + +function rng() { + // lazy load so that environments that need to polyfill have a chance to do so + if (!getRandomValues) { + // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. + getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); + + if (!getRandomValues) { + throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); + } + } + + return getRandomValues(rnds8); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/sha1.js b/node_modules/uuid/dist/commonjs-browser/sha1.js new file mode 100644 index 000000000..24cbcedca --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/sha1.js @@ -0,0 +1,104 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +// Adapted from Chris Veness' SHA1 code at +// http://www.movable-type.co.uk/scripts/sha1.html +function f(s, x, y, z) { + switch (s) { + case 0: + return x & y ^ ~x & z; + + case 1: + return x ^ y ^ z; + + case 2: + return x & y ^ x & z ^ y & z; + + case 3: + return x ^ y ^ z; + } +} + +function ROTL(x, n) { + return x << n | x >>> 32 - n; +} + +function sha1(bytes) { + const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6]; + const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = []; + + for (let i = 0; i < msg.length; ++i) { + bytes.push(msg.charCodeAt(i)); + } + } else if (!Array.isArray(bytes)) { + // Convert Array-like to Array + bytes = Array.prototype.slice.call(bytes); + } + + bytes.push(0x80); + const l = bytes.length / 4 + 2; + const N = Math.ceil(l / 16); + const M = new Array(N); + + for (let i = 0; i < N; ++i) { + const arr = new Uint32Array(16); + + for (let j = 0; j < 16; ++j) { + arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3]; + } + + M[i] = arr; + } + + M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32); + M[N - 1][14] = Math.floor(M[N - 1][14]); + M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff; + + for (let i = 0; i < N; ++i) { + const W = new Uint32Array(80); + + for (let t = 0; t < 16; ++t) { + W[t] = M[i][t]; + } + + for (let t = 16; t < 80; ++t) { + W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } + + let a = H[0]; + let b = H[1]; + let c = H[2]; + let d = H[3]; + let e = H[4]; + + for (let t = 0; t < 80; ++t) { + const s = Math.floor(t / 20); + const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0; + e = d; + d = c; + c = ROTL(b, 30) >>> 0; + b = a; + a = T; + } + + H[0] = H[0] + a >>> 0; + H[1] = H[1] + b >>> 0; + H[2] = H[2] + c >>> 0; + H[3] = H[3] + d >>> 0; + H[4] = H[4] + e >>> 0; + } + + return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff]; +} + +var _default = sha1; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/stringify.js b/node_modules/uuid/dist/commonjs-browser/stringify.js new file mode 100644 index 000000000..390bf8918 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/stringify.js @@ -0,0 +1,44 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +exports.unsafeStringify = unsafeStringify; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +var _default = stringify; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/v1.js b/node_modules/uuid/dist/commonjs-browser/v1.js new file mode 100644 index 000000000..125bc58f7 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/v1.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _rng = _interopRequireDefault(require("./rng.js")); + +var _stringify = require("./stringify.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || (0, _stringify.unsafeStringify)(b); +} + +var _default = v1; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/v3.js b/node_modules/uuid/dist/commonjs-browser/v3.js new file mode 100644 index 000000000..6b47ff517 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/v3.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _v = _interopRequireDefault(require("./v35.js")); + +var _md = _interopRequireDefault(require("./md5.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/v35.js b/node_modules/uuid/dist/commonjs-browser/v35.js new file mode 100644 index 000000000..7c522d97a --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/v35.js @@ -0,0 +1,80 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.URL = exports.DNS = void 0; +exports.default = v35; + +var _stringify = require("./stringify.js"); + +var _parse = _interopRequireDefault(require("./parse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.unsafeStringify)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/v4.js b/node_modules/uuid/dist/commonjs-browser/v4.js new file mode 100644 index 000000000..959d69869 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/v4.js @@ -0,0 +1,43 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _native = _interopRequireDefault(require("./native.js")); + +var _rng = _interopRequireDefault(require("./rng.js")); + +var _stringify = require("./stringify.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + if (_native.default.randomUUID && !buf && !options) { + return _native.default.randomUUID(); + } + + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.unsafeStringify)(rnds); +} + +var _default = v4; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/v5.js b/node_modules/uuid/dist/commonjs-browser/v5.js new file mode 100644 index 000000000..99d615e09 --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/v5.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _v = _interopRequireDefault(require("./v35.js")); + +var _sha = _interopRequireDefault(require("./sha1.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/validate.js b/node_modules/uuid/dist/commonjs-browser/validate.js new file mode 100644 index 000000000..fd052157d --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/validate.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _regex = _interopRequireDefault(require("./regex.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/commonjs-browser/version.js b/node_modules/uuid/dist/commonjs-browser/version.js new file mode 100644 index 000000000..f63af01ad --- /dev/null +++ b/node_modules/uuid/dist/commonjs-browser/version.js @@ -0,0 +1,21 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.slice(14, 15), 16); +} + +var _default = version; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/index.js b/node_modules/uuid/dist/esm-browser/index.js new file mode 100644 index 000000000..1db6f6d25 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/index.js @@ -0,0 +1,9 @@ +export { default as v1 } from './v1.js'; +export { default as v3 } from './v3.js'; +export { default as v4 } from './v4.js'; +export { default as v5 } from './v5.js'; +export { default as NIL } from './nil.js'; +export { default as version } from './version.js'; +export { default as validate } from './validate.js'; +export { default as stringify } from './stringify.js'; +export { default as parse } from './parse.js'; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/md5.js b/node_modules/uuid/dist/esm-browser/md5.js new file mode 100644 index 000000000..f12212ea3 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/md5.js @@ -0,0 +1,215 @@ +/* + * Browser-compatible JavaScript MD5 + * + * Modification of JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ +function md5(bytes) { + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = new Uint8Array(msg.length); + + for (let i = 0; i < msg.length; ++i) { + bytes[i] = msg.charCodeAt(i); + } + } + + return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8)); +} +/* + * Convert an array of little-endian words to an array of bytes + */ + + +function md5ToHexEncodedArray(input) { + const output = []; + const length32 = input.length * 32; + const hexTab = '0123456789abcdef'; + + for (let i = 0; i < length32; i += 8) { + const x = input[i >> 5] >>> i % 32 & 0xff; + const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16); + output.push(hex); + } + + return output; +} +/** + * Calculate output length with padding and bit length + */ + + +function getOutputLength(inputLength8) { + return (inputLength8 + 64 >>> 9 << 4) + 14 + 1; +} +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + + +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[getOutputLength(len) - 1] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + + for (let i = 0; i < x.length; i += 16) { + const olda = a; + const oldb = b; + const oldc = c; + const oldd = d; + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + + return [a, b, c, d]; +} +/* + * Convert an array bytes to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + + +function bytesToWords(input) { + if (input.length === 0) { + return []; + } + + const length8 = input.length * 8; + const output = new Uint32Array(getOutputLength(length8)); + + for (let i = 0; i < length8; i += 8) { + output[i >> 5] |= (input[i / 8] & 0xff) << i % 32; + } + + return output; +} +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + + +function safeAdd(x, y) { + const lsw = (x & 0xffff) + (y & 0xffff); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xffff; +} +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +function bitRotateLeft(num, cnt) { + return num << cnt | num >>> 32 - cnt; +} +/* + * These functions implement the four basic operations the algorithm uses. + */ + + +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} + +function md5ff(a, b, c, d, x, s, t) { + return md5cmn(b & c | ~b & d, a, b, x, s, t); +} + +function md5gg(a, b, c, d, x, s, t) { + return md5cmn(b & d | c & ~d, a, b, x, s, t); +} + +function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); +} + +function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t); +} + +export default md5; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/native.js b/node_modules/uuid/dist/esm-browser/native.js new file mode 100644 index 000000000..b22292cd1 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/native.js @@ -0,0 +1,4 @@ +const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); +export default { + randomUUID +}; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/nil.js b/node_modules/uuid/dist/esm-browser/nil.js new file mode 100644 index 000000000..b36324c2a --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/nil.js @@ -0,0 +1 @@ +export default '00000000-0000-0000-0000-000000000000'; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/parse.js b/node_modules/uuid/dist/esm-browser/parse.js new file mode 100644 index 000000000..6421c5d5a --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/parse.js @@ -0,0 +1,35 @@ +import validate from './validate.js'; + +function parse(uuid) { + if (!validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +export default parse; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/regex.js b/node_modules/uuid/dist/esm-browser/regex.js new file mode 100644 index 000000000..3da8673a5 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/regex.js @@ -0,0 +1 @@ +export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/rng.js b/node_modules/uuid/dist/esm-browser/rng.js new file mode 100644 index 000000000..6e652346d --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/rng.js @@ -0,0 +1,18 @@ +// Unique ID creation requires a high quality random # generator. In the browser we therefore +// require the crypto API and do not support built-in fallback to lower quality random number +// generators (like Math.random()). +let getRandomValues; +const rnds8 = new Uint8Array(16); +export default function rng() { + // lazy load so that environments that need to polyfill have a chance to do so + if (!getRandomValues) { + // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. + getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); + + if (!getRandomValues) { + throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); + } + } + + return getRandomValues(rnds8); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/sha1.js b/node_modules/uuid/dist/esm-browser/sha1.js new file mode 100644 index 000000000..d3c25659a --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/sha1.js @@ -0,0 +1,96 @@ +// Adapted from Chris Veness' SHA1 code at +// http://www.movable-type.co.uk/scripts/sha1.html +function f(s, x, y, z) { + switch (s) { + case 0: + return x & y ^ ~x & z; + + case 1: + return x ^ y ^ z; + + case 2: + return x & y ^ x & z ^ y & z; + + case 3: + return x ^ y ^ z; + } +} + +function ROTL(x, n) { + return x << n | x >>> 32 - n; +} + +function sha1(bytes) { + const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6]; + const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = []; + + for (let i = 0; i < msg.length; ++i) { + bytes.push(msg.charCodeAt(i)); + } + } else if (!Array.isArray(bytes)) { + // Convert Array-like to Array + bytes = Array.prototype.slice.call(bytes); + } + + bytes.push(0x80); + const l = bytes.length / 4 + 2; + const N = Math.ceil(l / 16); + const M = new Array(N); + + for (let i = 0; i < N; ++i) { + const arr = new Uint32Array(16); + + for (let j = 0; j < 16; ++j) { + arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3]; + } + + M[i] = arr; + } + + M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32); + M[N - 1][14] = Math.floor(M[N - 1][14]); + M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff; + + for (let i = 0; i < N; ++i) { + const W = new Uint32Array(80); + + for (let t = 0; t < 16; ++t) { + W[t] = M[i][t]; + } + + for (let t = 16; t < 80; ++t) { + W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } + + let a = H[0]; + let b = H[1]; + let c = H[2]; + let d = H[3]; + let e = H[4]; + + for (let t = 0; t < 80; ++t) { + const s = Math.floor(t / 20); + const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0; + e = d; + d = c; + c = ROTL(b, 30) >>> 0; + b = a; + a = T; + } + + H[0] = H[0] + a >>> 0; + H[1] = H[1] + b >>> 0; + H[2] = H[2] + c >>> 0; + H[3] = H[3] + d >>> 0; + H[4] = H[4] + e >>> 0; + } + + return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff]; +} + +export default sha1; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/stringify.js b/node_modules/uuid/dist/esm-browser/stringify.js new file mode 100644 index 000000000..a6e4c8864 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/stringify.js @@ -0,0 +1,33 @@ +import validate from './validate.js'; +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +export function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!validate(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +export default stringify; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/v1.js b/node_modules/uuid/dist/esm-browser/v1.js new file mode 100644 index 000000000..382e5d795 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/v1.js @@ -0,0 +1,95 @@ +import rng from './rng.js'; +import { unsafeStringify } from './stringify.js'; // **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || unsafeStringify(b); +} + +export default v1; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/v3.js b/node_modules/uuid/dist/esm-browser/v3.js new file mode 100644 index 000000000..09063b860 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/v3.js @@ -0,0 +1,4 @@ +import v35 from './v35.js'; +import md5 from './md5.js'; +const v3 = v35('v3', 0x30, md5); +export default v3; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/v35.js b/node_modules/uuid/dist/esm-browser/v35.js new file mode 100644 index 000000000..3355e1f55 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/v35.js @@ -0,0 +1,66 @@ +import { unsafeStringify } from './stringify.js'; +import parse from './parse.js'; + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +export default function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = parse(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return unsafeStringify(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/v4.js b/node_modules/uuid/dist/esm-browser/v4.js new file mode 100644 index 000000000..95ea87991 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/v4.js @@ -0,0 +1,29 @@ +import native from './native.js'; +import rng from './rng.js'; +import { unsafeStringify } from './stringify.js'; + +function v4(options, buf, offset) { + if (native.randomUUID && !buf && !options) { + return native.randomUUID(); + } + + options = options || {}; + const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return unsafeStringify(rnds); +} + +export default v4; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/v5.js b/node_modules/uuid/dist/esm-browser/v5.js new file mode 100644 index 000000000..e87fe317d --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/v5.js @@ -0,0 +1,4 @@ +import v35 from './v35.js'; +import sha1 from './sha1.js'; +const v5 = v35('v5', 0x50, sha1); +export default v5; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/validate.js b/node_modules/uuid/dist/esm-browser/validate.js new file mode 100644 index 000000000..f1cdc7af4 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/validate.js @@ -0,0 +1,7 @@ +import REGEX from './regex.js'; + +function validate(uuid) { + return typeof uuid === 'string' && REGEX.test(uuid); +} + +export default validate; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-browser/version.js b/node_modules/uuid/dist/esm-browser/version.js new file mode 100644 index 000000000..936307630 --- /dev/null +++ b/node_modules/uuid/dist/esm-browser/version.js @@ -0,0 +1,11 @@ +import validate from './validate.js'; + +function version(uuid) { + if (!validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.slice(14, 15), 16); +} + +export default version; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/index.js b/node_modules/uuid/dist/esm-node/index.js new file mode 100644 index 000000000..1db6f6d25 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/index.js @@ -0,0 +1,9 @@ +export { default as v1 } from './v1.js'; +export { default as v3 } from './v3.js'; +export { default as v4 } from './v4.js'; +export { default as v5 } from './v5.js'; +export { default as NIL } from './nil.js'; +export { default as version } from './version.js'; +export { default as validate } from './validate.js'; +export { default as stringify } from './stringify.js'; +export { default as parse } from './parse.js'; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/md5.js b/node_modules/uuid/dist/esm-node/md5.js new file mode 100644 index 000000000..4d68b040f --- /dev/null +++ b/node_modules/uuid/dist/esm-node/md5.js @@ -0,0 +1,13 @@ +import crypto from 'crypto'; + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return crypto.createHash('md5').update(bytes).digest(); +} + +export default md5; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/native.js b/node_modules/uuid/dist/esm-node/native.js new file mode 100644 index 000000000..f0d199261 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/native.js @@ -0,0 +1,4 @@ +import crypto from 'crypto'; +export default { + randomUUID: crypto.randomUUID +}; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/nil.js b/node_modules/uuid/dist/esm-node/nil.js new file mode 100644 index 000000000..b36324c2a --- /dev/null +++ b/node_modules/uuid/dist/esm-node/nil.js @@ -0,0 +1 @@ +export default '00000000-0000-0000-0000-000000000000'; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/parse.js b/node_modules/uuid/dist/esm-node/parse.js new file mode 100644 index 000000000..6421c5d5a --- /dev/null +++ b/node_modules/uuid/dist/esm-node/parse.js @@ -0,0 +1,35 @@ +import validate from './validate.js'; + +function parse(uuid) { + if (!validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +export default parse; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/regex.js b/node_modules/uuid/dist/esm-node/regex.js new file mode 100644 index 000000000..3da8673a5 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/regex.js @@ -0,0 +1 @@ +export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/rng.js b/node_modules/uuid/dist/esm-node/rng.js new file mode 100644 index 000000000..80062449a --- /dev/null +++ b/node_modules/uuid/dist/esm-node/rng.js @@ -0,0 +1,12 @@ +import crypto from 'crypto'; +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; +export default function rng() { + if (poolPtr > rnds8Pool.length - 16) { + crypto.randomFillSync(rnds8Pool); + poolPtr = 0; + } + + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/sha1.js b/node_modules/uuid/dist/esm-node/sha1.js new file mode 100644 index 000000000..e23850b44 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/sha1.js @@ -0,0 +1,13 @@ +import crypto from 'crypto'; + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return crypto.createHash('sha1').update(bytes).digest(); +} + +export default sha1; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/stringify.js b/node_modules/uuid/dist/esm-node/stringify.js new file mode 100644 index 000000000..a6e4c8864 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/stringify.js @@ -0,0 +1,33 @@ +import validate from './validate.js'; +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +export function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!validate(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +export default stringify; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/v1.js b/node_modules/uuid/dist/esm-node/v1.js new file mode 100644 index 000000000..382e5d795 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/v1.js @@ -0,0 +1,95 @@ +import rng from './rng.js'; +import { unsafeStringify } from './stringify.js'; // **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || unsafeStringify(b); +} + +export default v1; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/v3.js b/node_modules/uuid/dist/esm-node/v3.js new file mode 100644 index 000000000..09063b860 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/v3.js @@ -0,0 +1,4 @@ +import v35 from './v35.js'; +import md5 from './md5.js'; +const v3 = v35('v3', 0x30, md5); +export default v3; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/v35.js b/node_modules/uuid/dist/esm-node/v35.js new file mode 100644 index 000000000..3355e1f55 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/v35.js @@ -0,0 +1,66 @@ +import { unsafeStringify } from './stringify.js'; +import parse from './parse.js'; + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +export default function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = parse(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return unsafeStringify(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/v4.js b/node_modules/uuid/dist/esm-node/v4.js new file mode 100644 index 000000000..95ea87991 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/v4.js @@ -0,0 +1,29 @@ +import native from './native.js'; +import rng from './rng.js'; +import { unsafeStringify } from './stringify.js'; + +function v4(options, buf, offset) { + if (native.randomUUID && !buf && !options) { + return native.randomUUID(); + } + + options = options || {}; + const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return unsafeStringify(rnds); +} + +export default v4; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/v5.js b/node_modules/uuid/dist/esm-node/v5.js new file mode 100644 index 000000000..e87fe317d --- /dev/null +++ b/node_modules/uuid/dist/esm-node/v5.js @@ -0,0 +1,4 @@ +import v35 from './v35.js'; +import sha1 from './sha1.js'; +const v5 = v35('v5', 0x50, sha1); +export default v5; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/validate.js b/node_modules/uuid/dist/esm-node/validate.js new file mode 100644 index 000000000..f1cdc7af4 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/validate.js @@ -0,0 +1,7 @@ +import REGEX from './regex.js'; + +function validate(uuid) { + return typeof uuid === 'string' && REGEX.test(uuid); +} + +export default validate; \ No newline at end of file diff --git a/node_modules/uuid/dist/esm-node/version.js b/node_modules/uuid/dist/esm-node/version.js new file mode 100644 index 000000000..936307630 --- /dev/null +++ b/node_modules/uuid/dist/esm-node/version.js @@ -0,0 +1,11 @@ +import validate from './validate.js'; + +function version(uuid) { + if (!validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.slice(14, 15), 16); +} + +export default version; \ No newline at end of file diff --git a/node_modules/uuid/dist/index.js b/node_modules/uuid/dist/index.js new file mode 100644 index 000000000..88d676a29 --- /dev/null +++ b/node_modules/uuid/dist/index.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "NIL", { + enumerable: true, + get: function () { + return _nil.default; + } +}); +Object.defineProperty(exports, "parse", { + enumerable: true, + get: function () { + return _parse.default; + } +}); +Object.defineProperty(exports, "stringify", { + enumerable: true, + get: function () { + return _stringify.default; + } +}); +Object.defineProperty(exports, "v1", { + enumerable: true, + get: function () { + return _v.default; + } +}); +Object.defineProperty(exports, "v3", { + enumerable: true, + get: function () { + return _v2.default; + } +}); +Object.defineProperty(exports, "v4", { + enumerable: true, + get: function () { + return _v3.default; + } +}); +Object.defineProperty(exports, "v5", { + enumerable: true, + get: function () { + return _v4.default; + } +}); +Object.defineProperty(exports, "validate", { + enumerable: true, + get: function () { + return _validate.default; + } +}); +Object.defineProperty(exports, "version", { + enumerable: true, + get: function () { + return _version.default; + } +}); + +var _v = _interopRequireDefault(require("./v1.js")); + +var _v2 = _interopRequireDefault(require("./v3.js")); + +var _v3 = _interopRequireDefault(require("./v4.js")); + +var _v4 = _interopRequireDefault(require("./v5.js")); + +var _nil = _interopRequireDefault(require("./nil.js")); + +var _version = _interopRequireDefault(require("./version.js")); + +var _validate = _interopRequireDefault(require("./validate.js")); + +var _stringify = _interopRequireDefault(require("./stringify.js")); + +var _parse = _interopRequireDefault(require("./parse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/node_modules/uuid/dist/md5-browser.js b/node_modules/uuid/dist/md5-browser.js new file mode 100644 index 000000000..7a4582ace --- /dev/null +++ b/node_modules/uuid/dist/md5-browser.js @@ -0,0 +1,223 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +/* + * Browser-compatible JavaScript MD5 + * + * Modification of JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ +function md5(bytes) { + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = new Uint8Array(msg.length); + + for (let i = 0; i < msg.length; ++i) { + bytes[i] = msg.charCodeAt(i); + } + } + + return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8)); +} +/* + * Convert an array of little-endian words to an array of bytes + */ + + +function md5ToHexEncodedArray(input) { + const output = []; + const length32 = input.length * 32; + const hexTab = '0123456789abcdef'; + + for (let i = 0; i < length32; i += 8) { + const x = input[i >> 5] >>> i % 32 & 0xff; + const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16); + output.push(hex); + } + + return output; +} +/** + * Calculate output length with padding and bit length + */ + + +function getOutputLength(inputLength8) { + return (inputLength8 + 64 >>> 9 << 4) + 14 + 1; +} +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + + +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[getOutputLength(len) - 1] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + + for (let i = 0; i < x.length; i += 16) { + const olda = a; + const oldb = b; + const oldc = c; + const oldd = d; + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + + return [a, b, c, d]; +} +/* + * Convert an array bytes to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + + +function bytesToWords(input) { + if (input.length === 0) { + return []; + } + + const length8 = input.length * 8; + const output = new Uint32Array(getOutputLength(length8)); + + for (let i = 0; i < length8; i += 8) { + output[i >> 5] |= (input[i / 8] & 0xff) << i % 32; + } + + return output; +} +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + + +function safeAdd(x, y) { + const lsw = (x & 0xffff) + (y & 0xffff); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xffff; +} +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +function bitRotateLeft(num, cnt) { + return num << cnt | num >>> 32 - cnt; +} +/* + * These functions implement the four basic operations the algorithm uses. + */ + + +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} + +function md5ff(a, b, c, d, x, s, t) { + return md5cmn(b & c | ~b & d, a, b, x, s, t); +} + +function md5gg(a, b, c, d, x, s, t) { + return md5cmn(b & d | c & ~d, a, b, x, s, t); +} + +function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); +} + +function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t); +} + +var _default = md5; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/md5.js b/node_modules/uuid/dist/md5.js new file mode 100644 index 000000000..824d48167 --- /dev/null +++ b/node_modules/uuid/dist/md5.js @@ -0,0 +1,23 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _crypto = _interopRequireDefault(require("crypto")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('md5').update(bytes).digest(); +} + +var _default = md5; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/native-browser.js b/node_modules/uuid/dist/native-browser.js new file mode 100644 index 000000000..c2eea59d0 --- /dev/null +++ b/node_modules/uuid/dist/native-browser.js @@ -0,0 +1,11 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); +var _default = { + randomUUID +}; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/native.js b/node_modules/uuid/dist/native.js new file mode 100644 index 000000000..de8046913 --- /dev/null +++ b/node_modules/uuid/dist/native.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _crypto = _interopRequireDefault(require("crypto")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = { + randomUUID: _crypto.default.randomUUID +}; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/nil.js b/node_modules/uuid/dist/nil.js new file mode 100644 index 000000000..7ade577b2 --- /dev/null +++ b/node_modules/uuid/dist/nil.js @@ -0,0 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/parse.js b/node_modules/uuid/dist/parse.js new file mode 100644 index 000000000..4c69fc39e --- /dev/null +++ b/node_modules/uuid/dist/parse.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +var _default = parse; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/regex.js b/node_modules/uuid/dist/regex.js new file mode 100644 index 000000000..1ef91d64c --- /dev/null +++ b/node_modules/uuid/dist/regex.js @@ -0,0 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/rng-browser.js b/node_modules/uuid/dist/rng-browser.js new file mode 100644 index 000000000..d067cdb04 --- /dev/null +++ b/node_modules/uuid/dist/rng-browser.js @@ -0,0 +1,25 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = rng; +// Unique ID creation requires a high quality random # generator. In the browser we therefore +// require the crypto API and do not support built-in fallback to lower quality random number +// generators (like Math.random()). +let getRandomValues; +const rnds8 = new Uint8Array(16); + +function rng() { + // lazy load so that environments that need to polyfill have a chance to do so + if (!getRandomValues) { + // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. + getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); + + if (!getRandomValues) { + throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); + } + } + + return getRandomValues(rnds8); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/rng.js b/node_modules/uuid/dist/rng.js new file mode 100644 index 000000000..3507f9377 --- /dev/null +++ b/node_modules/uuid/dist/rng.js @@ -0,0 +1,24 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = rng; + +var _crypto = _interopRequireDefault(require("crypto")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; + } + + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/sha1-browser.js b/node_modules/uuid/dist/sha1-browser.js new file mode 100644 index 000000000..24cbcedca --- /dev/null +++ b/node_modules/uuid/dist/sha1-browser.js @@ -0,0 +1,104 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +// Adapted from Chris Veness' SHA1 code at +// http://www.movable-type.co.uk/scripts/sha1.html +function f(s, x, y, z) { + switch (s) { + case 0: + return x & y ^ ~x & z; + + case 1: + return x ^ y ^ z; + + case 2: + return x & y ^ x & z ^ y & z; + + case 3: + return x ^ y ^ z; + } +} + +function ROTL(x, n) { + return x << n | x >>> 32 - n; +} + +function sha1(bytes) { + const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6]; + const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + if (typeof bytes === 'string') { + const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + + bytes = []; + + for (let i = 0; i < msg.length; ++i) { + bytes.push(msg.charCodeAt(i)); + } + } else if (!Array.isArray(bytes)) { + // Convert Array-like to Array + bytes = Array.prototype.slice.call(bytes); + } + + bytes.push(0x80); + const l = bytes.length / 4 + 2; + const N = Math.ceil(l / 16); + const M = new Array(N); + + for (let i = 0; i < N; ++i) { + const arr = new Uint32Array(16); + + for (let j = 0; j < 16; ++j) { + arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3]; + } + + M[i] = arr; + } + + M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32); + M[N - 1][14] = Math.floor(M[N - 1][14]); + M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff; + + for (let i = 0; i < N; ++i) { + const W = new Uint32Array(80); + + for (let t = 0; t < 16; ++t) { + W[t] = M[i][t]; + } + + for (let t = 16; t < 80; ++t) { + W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } + + let a = H[0]; + let b = H[1]; + let c = H[2]; + let d = H[3]; + let e = H[4]; + + for (let t = 0; t < 80; ++t) { + const s = Math.floor(t / 20); + const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0; + e = d; + d = c; + c = ROTL(b, 30) >>> 0; + b = a; + a = T; + } + + H[0] = H[0] + a >>> 0; + H[1] = H[1] + b >>> 0; + H[2] = H[2] + c >>> 0; + H[3] = H[3] + d >>> 0; + H[4] = H[4] + e >>> 0; + } + + return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff]; +} + +var _default = sha1; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/sha1.js b/node_modules/uuid/dist/sha1.js new file mode 100644 index 000000000..03bdd63ce --- /dev/null +++ b/node_modules/uuid/dist/sha1.js @@ -0,0 +1,23 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _crypto = _interopRequireDefault(require("crypto")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('sha1').update(bytes).digest(); +} + +var _default = sha1; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/stringify.js b/node_modules/uuid/dist/stringify.js new file mode 100644 index 000000000..390bf8918 --- /dev/null +++ b/node_modules/uuid/dist/stringify.js @@ -0,0 +1,44 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +exports.unsafeStringify = unsafeStringify; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +var _default = stringify; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/uuid-bin.js b/node_modules/uuid/dist/uuid-bin.js new file mode 100644 index 000000000..50a7a9f17 --- /dev/null +++ b/node_modules/uuid/dist/uuid-bin.js @@ -0,0 +1,85 @@ +"use strict"; + +var _assert = _interopRequireDefault(require("assert")); + +var _v = _interopRequireDefault(require("./v1.js")); + +var _v2 = _interopRequireDefault(require("./v3.js")); + +var _v3 = _interopRequireDefault(require("./v4.js")); + +var _v4 = _interopRequireDefault(require("./v5.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function usage() { + console.log('Usage:'); + console.log(' uuid'); + console.log(' uuid v1'); + console.log(' uuid v3 '); + console.log(' uuid v4'); + console.log(' uuid v5 '); + console.log(' uuid --help'); + console.log('\nNote: may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC4122'); +} + +const args = process.argv.slice(2); + +if (args.indexOf('--help') >= 0) { + usage(); + process.exit(0); +} + +const version = args.shift() || 'v4'; + +switch (version) { + case 'v1': + console.log((0, _v.default)()); + break; + + case 'v3': + { + const name = args.shift(); + let namespace = args.shift(); + (0, _assert.default)(name != null, 'v3 name not specified'); + (0, _assert.default)(namespace != null, 'v3 namespace not specified'); + + if (namespace === 'URL') { + namespace = _v2.default.URL; + } + + if (namespace === 'DNS') { + namespace = _v2.default.DNS; + } + + console.log((0, _v2.default)(name, namespace)); + break; + } + + case 'v4': + console.log((0, _v3.default)()); + break; + + case 'v5': + { + const name = args.shift(); + let namespace = args.shift(); + (0, _assert.default)(name != null, 'v5 name not specified'); + (0, _assert.default)(namespace != null, 'v5 namespace not specified'); + + if (namespace === 'URL') { + namespace = _v4.default.URL; + } + + if (namespace === 'DNS') { + namespace = _v4.default.DNS; + } + + console.log((0, _v4.default)(name, namespace)); + break; + } + + default: + usage(); + process.exit(1); +} \ No newline at end of file diff --git a/node_modules/uuid/dist/v1.js b/node_modules/uuid/dist/v1.js new file mode 100644 index 000000000..125bc58f7 --- /dev/null +++ b/node_modules/uuid/dist/v1.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _rng = _interopRequireDefault(require("./rng.js")); + +var _stringify = require("./stringify.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || (0, _stringify.unsafeStringify)(b); +} + +var _default = v1; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/v3.js b/node_modules/uuid/dist/v3.js new file mode 100644 index 000000000..6b47ff517 --- /dev/null +++ b/node_modules/uuid/dist/v3.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _v = _interopRequireDefault(require("./v35.js")); + +var _md = _interopRequireDefault(require("./md5.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/v35.js b/node_modules/uuid/dist/v35.js new file mode 100644 index 000000000..7c522d97a --- /dev/null +++ b/node_modules/uuid/dist/v35.js @@ -0,0 +1,80 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.URL = exports.DNS = void 0; +exports.default = v35; + +var _stringify = require("./stringify.js"); + +var _parse = _interopRequireDefault(require("./parse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.unsafeStringify)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} \ No newline at end of file diff --git a/node_modules/uuid/dist/v4.js b/node_modules/uuid/dist/v4.js new file mode 100644 index 000000000..959d69869 --- /dev/null +++ b/node_modules/uuid/dist/v4.js @@ -0,0 +1,43 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _native = _interopRequireDefault(require("./native.js")); + +var _rng = _interopRequireDefault(require("./rng.js")); + +var _stringify = require("./stringify.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + if (_native.default.randomUUID && !buf && !options) { + return _native.default.randomUUID(); + } + + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.unsafeStringify)(rnds); +} + +var _default = v4; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/v5.js b/node_modules/uuid/dist/v5.js new file mode 100644 index 000000000..99d615e09 --- /dev/null +++ b/node_modules/uuid/dist/v5.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _v = _interopRequireDefault(require("./v35.js")); + +var _sha = _interopRequireDefault(require("./sha1.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/validate.js b/node_modules/uuid/dist/validate.js new file mode 100644 index 000000000..fd052157d --- /dev/null +++ b/node_modules/uuid/dist/validate.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _regex = _interopRequireDefault(require("./regex.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/dist/version.js b/node_modules/uuid/dist/version.js new file mode 100644 index 000000000..f63af01ad --- /dev/null +++ b/node_modules/uuid/dist/version.js @@ -0,0 +1,21 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _validate = _interopRequireDefault(require("./validate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.slice(14, 15), 16); +} + +var _default = version; +exports.default = _default; \ No newline at end of file diff --git a/node_modules/uuid/package.json b/node_modules/uuid/package.json new file mode 100644 index 000000000..6cc33618c --- /dev/null +++ b/node_modules/uuid/package.json @@ -0,0 +1,135 @@ +{ + "name": "uuid", + "version": "9.0.1", + "description": "RFC4122 (v1, v4, and v5) UUIDs", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "keywords": [ + "uuid", + "guid", + "rfc4122" + ], + "license": "MIT", + "bin": { + "uuid": "./dist/bin/uuid" + }, + "sideEffects": false, + "main": "./dist/index.js", + "exports": { + ".": { + "node": { + "module": "./dist/esm-node/index.js", + "require": "./dist/index.js", + "import": "./wrapper.mjs" + }, + "browser": { + "import": "./dist/esm-browser/index.js", + "require": "./dist/commonjs-browser/index.js" + }, + "default": "./dist/esm-browser/index.js" + }, + "./package.json": "./package.json" + }, + "module": "./dist/esm-node/index.js", + "browser": { + "./dist/md5.js": "./dist/md5-browser.js", + "./dist/native.js": "./dist/native-browser.js", + "./dist/rng.js": "./dist/rng-browser.js", + "./dist/sha1.js": "./dist/sha1-browser.js", + "./dist/esm-node/index.js": "./dist/esm-browser/index.js" + }, + "files": [ + "CHANGELOG.md", + "CONTRIBUTING.md", + "LICENSE.md", + "README.md", + "dist", + "wrapper.mjs" + ], + "devDependencies": { + "@babel/cli": "7.18.10", + "@babel/core": "7.18.10", + "@babel/eslint-parser": "7.18.9", + "@babel/preset-env": "7.18.10", + "@commitlint/cli": "17.0.3", + "@commitlint/config-conventional": "17.0.3", + "bundlewatch": "0.3.3", + "eslint": "8.21.0", + "eslint-config-prettier": "8.5.0", + "eslint-config-standard": "17.0.0", + "eslint-plugin-import": "2.26.0", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-prettier": "4.2.1", + "eslint-plugin-promise": "6.0.0", + "husky": "8.0.1", + "jest": "28.1.3", + "lint-staged": "13.0.3", + "npm-run-all": "4.1.5", + "optional-dev-dependency": "2.0.1", + "prettier": "2.7.1", + "random-seed": "0.3.0", + "runmd": "1.3.9", + "standard-version": "9.5.0" + }, + "optionalDevDependencies": { + "@wdio/browserstack-service": "7.16.10", + "@wdio/cli": "7.16.10", + "@wdio/jasmine-framework": "7.16.6", + "@wdio/local-runner": "7.16.10", + "@wdio/spec-reporter": "7.16.9", + "@wdio/static-server-service": "7.16.6" + }, + "scripts": { + "examples:browser:webpack:build": "cd examples/browser-webpack && npm install && npm run build", + "examples:browser:rollup:build": "cd examples/browser-rollup && npm install && npm run build", + "examples:node:commonjs:test": "cd examples/node-commonjs && npm install && npm test", + "examples:node:esmodules:test": "cd examples/node-esmodules && npm install && npm test", + "examples:node:jest:test": "cd examples/node-jest && npm install && npm test", + "prepare": "cd $( git rev-parse --show-toplevel ) && husky install", + "lint": "npm run eslint:check && npm run prettier:check", + "eslint:check": "eslint src/ test/ examples/ *.js", + "eslint:fix": "eslint --fix src/ test/ examples/ *.js", + "pretest": "[ -n $CI ] || npm run build", + "test": "BABEL_ENV=commonjsNode node --throw-deprecation node_modules/.bin/jest test/unit/", + "pretest:browser": "optional-dev-dependency && npm run build && npm-run-all --parallel examples:browser:**", + "test:browser": "wdio run ./wdio.conf.js", + "pretest:node": "npm run build", + "test:node": "npm-run-all --parallel examples:node:**", + "test:pack": "./scripts/testpack.sh", + "pretest:benchmark": "npm run build", + "test:benchmark": "cd examples/benchmark && npm install && npm test", + "prettier:check": "prettier --check '**/*.{js,jsx,json,md}'", + "prettier:fix": "prettier --write '**/*.{js,jsx,json,md}'", + "bundlewatch": "npm run pretest:browser && bundlewatch --config bundlewatch.config.json", + "md": "runmd --watch --output=README.md README_js.md", + "docs": "( node --version | grep -q 'v18' ) && ( npm run build && npx runmd --output=README.md README_js.md )", + "docs:diff": "npm run docs && git diff --quiet README.md", + "build": "./scripts/build.sh", + "prepack": "npm run build", + "release": "standard-version --no-verify" + }, + "repository": { + "type": "git", + "url": "https://github.com/uuidjs/uuid.git" + }, + "lint-staged": { + "*.{js,jsx,json,md}": [ + "prettier --write" + ], + "*.{js,jsx}": [ + "eslint --fix" + ] + }, + "standard-version": { + "scripts": { + "postchangelog": "prettier --write CHANGELOG.md" + } + } +} diff --git a/node_modules/uuid/wrapper.mjs b/node_modules/uuid/wrapper.mjs new file mode 100644 index 000000000..c31e9cef4 --- /dev/null +++ b/node_modules/uuid/wrapper.mjs @@ -0,0 +1,10 @@ +import uuid from './dist/index.js'; +export const v1 = uuid.v1; +export const v3 = uuid.v3; +export const v4 = uuid.v4; +export const v5 = uuid.v5; +export const NIL = uuid.NIL; +export const version = uuid.version; +export const validate = uuid.validate; +export const stringify = uuid.stringify; +export const parse = uuid.parse; diff --git a/package.json b/package.json new file mode 100644 index 000000000..7c18dc8fa --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "uuid": "^9.0.1" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..7b075058f --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== From 5017338e4debf346eefc831b1de5310a56e7863c Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 9 Oct 2023 11:08:42 +0300 Subject: [PATCH 04/20] renaming refactoring of the components --- .../videoControlButton.tsx | 0 .../meetingComp}/videoControllerComp.tsx | 70 +----- .../videoStreamComp.tsx} | 102 -------- .../videobuttonCompConstants.tsx | 0 .../comps/comps/videoComp/videoContolComp.tsx | 226 ------------------ .../lowcoder/src/comps/hooks/hookComp.tsx | 2 +- client/packages/lowcoder/src/comps/index.tsx | 6 +- 7 files changed, 10 insertions(+), 396 deletions(-) rename client/packages/lowcoder/src/comps/comps/{videoComp => meetingComp}/videoControlButton.tsx (100%) rename client/packages/lowcoder/src/comps/{hooks => comps/meetingComp}/videoControllerComp.tsx (87%) rename client/packages/lowcoder/src/comps/comps/{videoComp/videoMeetingComp.tsx => meetingComp/videoStreamComp.tsx} (63%) rename client/packages/lowcoder/src/comps/comps/{videoComp => meetingComp}/videobuttonCompConstants.tsx (100%) delete mode 100644 client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoControlButton.tsx similarity index 100% rename from client/packages/lowcoder/src/comps/comps/videoComp/videoControlButton.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videoControlButton.tsx diff --git a/client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx similarity index 87% rename from client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx index f5cb68aca..74ba992ad 100644 --- a/client/packages/lowcoder/src/comps/hooks/videoControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx @@ -8,12 +8,9 @@ import { import { AutoHeightControl } from "comps/controls/autoHeightControl"; import { BoolControl } from "comps/controls/boolControl"; import { - JSONObjectArrayControl, - NumberControl, StringControl, } from "comps/controls/codeControl"; import { - arrayStringExposingStateControl, booleanExposingStateControl, jsonObjectExposingStateControl, jsonValueExposingStateControl, @@ -39,22 +36,19 @@ import { Section, sectionNames, } from "lowcoder-design"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect } from "react"; import { ResizeHandle } from "react-resizable"; import styled from "styled-components"; import { useUserViewMode } from "util/hooks"; import { isNumeric } from "util/stringUtils"; -import { NameConfig, withExposingConfigs } from "../generators/withExposing"; -import { v4 as uuidv4 } from "uuid"; +import { NameConfig, withExposingConfigs } from "../../generators/withExposing"; import AgoraRTC, { ICameraVideoTrack, IMicrophoneAudioTrack, IAgoraRTCClient, IAgoraRTCRemoteUser, - IRemoteVideoTrack, } from "agora-rtc-sdk-ng"; -import { JSONObject } from "@lowcoder-ee/index.sdk"; const EventOptions = [closeEvent] as const; @@ -100,24 +94,6 @@ function transToPxSize(size: string | number) { return isNumeric(size) ? size + "px" : (size as string); } -const PlacementOptions = [ - { - label: trans("drawer.top"), - value: "top", - }, - { - label: trans("drawer.right"), - value: "right", - }, - { - label: trans("drawer.bottom"), - value: "bottom", - }, - { - label: trans("drawer.left"), - value: "left", - }, -] as const; let client: IAgoraRTCClient = AgoraRTC.createClient({ mode: "rtc", @@ -144,8 +120,6 @@ const turnOnMicrophone = async (flag?: boolean) => { }; const leaveChannel = async () => { - console.log("isJoined", isJoined); - if (!client) { console.error("Agora client is not initialized"); return; @@ -156,19 +130,19 @@ const leaveChannel = async () => { return; } if (videoTrack) { - // await turnOnCamera(false); + await turnOnCamera(false); await client.unpublish(videoTrack); videoTrack.stop(); } if (audioTrack) { - // await turnOnMicrophone(false); + await turnOnMicrophone(false); await client.unpublish(audioTrack); audioTrack.stop(); } await client.leave(); - isJoined = false; // Update the flag to indicate that you have left the channel + isJoined = false; }; let isJoined = false; @@ -181,8 +155,6 @@ const joinChannel = async (appId: any, channel: any, token: any) => { await leaveChannel(); } - // client.on("user-published", onUserPublish); - await client.join( appId, channel, @@ -194,7 +166,6 @@ const joinChannel = async (appId: any, channel: any, token: any) => { }; const publishVideo = async (appId: any, channel: any, height: any) => { - console.log("publishVideo", appId, channel, isJoined); await turnOnCamera(true); console.log(appId, channel); @@ -202,11 +173,7 @@ const publishVideo = async (appId: any, channel: any, height: any) => { await joinChannel(appId, channel, null); } - console.log("publish videoTrack ", videoTrack); - await client.publish(videoTrack); - - // turnOnCamera(true); const mediaStreamTrack = videoTrack.getMediaStreamTrack(); if (mediaStreamTrack) { @@ -276,16 +243,12 @@ let MTComp = (function () { [dispatch, isTopBom] ); - const usersWithVideoTracks: any = {}; - useEffect(() => { console.log("nnnn ", props.participants); }, [props.participants.value]); useEffect(() => { if (client) { - console.log("REGISTERING LISTNERS"); - client.on( "user-published", async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { @@ -297,26 +260,10 @@ let MTComp = (function () { const remoteTrack = await client.subscribe(user, mediaType); remoteTrack.play(); } - const remoteVideoTrack = user.videoTrack; - if (remoteVideoTrack) { - props.participants.onChange([JSON.stringify(user.uid)]); - console.log("usersWithVideoTracks", props.participants); - } } ); - client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - // usersWithVideoTracks[user.uid] = { user, videoTracks: [] }; - // props.participants.onChange(usersWithVideoTracks); - // console.log( - // "userJoined", - // user.uid, - // props.participants.value, - // usersWithVideoTracks - // ); - // const uid = user.uid; - // usersWithVideoTracks[uid] = { user, videoTracks: [] }; - }); + client.on("user-joined", (user: IAgoraRTCRemoteUser) => {}); client.on("user-offline", (uid: any, reason: any) => { console.log(`User ${uid} left the channel.`); }); @@ -328,13 +275,8 @@ let MTComp = (function () { }); client.on("stream-added", (user: IAgoraRTCRemoteUser) => { console.log("stream-added"); - - if (user.hasVideo) { - console.log(`Stream from user ${user.videoTrack} added.`); - } }); } - // turnOnCamera(true); }, [client]); return ( diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx similarity index 63% rename from client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx index 9892499d0..67e687277 100644 --- a/client/packages/lowcoder/src/comps/comps/videoComp/videoMeetingComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx @@ -165,19 +165,12 @@ let VideoCompBuilder = (function (props) { suffixIcon: IconControl, style: ButtonStyleControl, viewRef: RefControl, - appId: withDefault(StringControl, trans("prop.appid")), /// - videokey: withDefault(StringControl, trans("prop.videokey")), - participants: arrayStringExposingStateControl("participants"), userId: stringExposingStateControl( "text", trans("meeting.userId", { name: "{{currentUser.name}}" }) ), }; - // const { client, videoHeight, videoWidth, setHeight, setWidth } = useAgora(); - return new UICompBuilder(childrenMap, (props) => { - console.log("userId", props.userId.value); - // "afd10eabe68a4de68a76461be92c693c" const videoRef = useRef(null); const conRef = useRef(null); @@ -185,11 +178,6 @@ let VideoCompBuilder = (function (props) { onResize(); }, []); - useEffect(() => { - if (props.participants.value.length > 0) { - console.log("bbb", props.participants.value); - } - }, [props.participants.value]); const onResize = async () => { const container = conRef.current; @@ -205,7 +193,6 @@ let VideoCompBuilder = (function (props) { @@ -216,46 +203,6 @@ let VideoCompBuilder = (function (props) { }) .setPropertyViewFn((children) => ( <> - {/*
- {children.userId.propertyView({ - label: trans("meeting.userId"), - })} - {children.autoHeight.getPropertyView()} - {children.videokey.propertyView({ - label: trans("prop.videokey"), - })} -
*/} - {/*
- {/* {hiddenPropertyView(children)} -
*/} - - {/*
- {children.type.propertyView({ - label: trans("prop.type"), - radioButton: true, - })} */} - {/* {isDefault(children.type.getView()) - ? [ - children.onEvent.getPropertyView(), - disabledPropertyView(children), - loadingPropertyView(children), - ] - : children.form.getPropertyView()} */} - {/*
*/} - - {/*
- {children.prefixIcon.propertyView({ - label: trans("button.prefixIcon"), - })} - {children.suffixIcon.propertyView({ - label: trans("button.suffixIcon"), - })} - {hiddenPropertyView(children)} -
- -
- {children.style.getPropertyView()} -
*/} )) .build(); @@ -267,57 +214,8 @@ VideoCompBuilder = class extends VideoCompBuilder { } }; -VideoCompBuilder = withMethodExposing(VideoCompBuilder, [ - { - method: { - name: "audioControl", - description: trans("meeting.actionBtnDesc"), - params: [], - }, - execute: (comp, values) => { - // let value = !comp.children.audioControl.getView().value; - // turnOnMicrophone(value); - // comp.children.audioControl.change(value); - }, - }, - // { - // method: { - // name: "videoControl", - // description: trans("meeting.actionBtnDesc"), - // params: [], - // }, - // execute: (comp, values) => { - // let value = !comp.children.videoControl.getView().value; - // turnOnCamera(value); - // comp.children.videoControl.change(value); - // }, - // }, - // { - // method: { - // name: "startMeeting", - // description: trans("meeting.actionBtnDesc"), - // params: [], - // }, - // execute: (comp, values) => { - // publishVideo(comp.children.appId.getView(), "testsdaadasdsa"); - // }, - // }, - // { - // method: { - // name: "endCall", - // description: trans("meeting.actionBtnDesc"), - // params: [], - // }, - // execute: (comp, values) => { - // let value = !comp.children.endCall.getView().value; - // leaveChannel(); - // comp.children.endCall.change(value); - // }, - // }, -]); export const VideoMeetingComp = withExposingConfigs(VideoCompBuilder, [ - // new NameConfig("appId", trans("button.textDesc")), new NameConfig("loading", trans("button.loadingDesc")), ...CommonNameConfig, ]); diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videobuttonCompConstants.tsx similarity index 100% rename from client/packages/lowcoder/src/comps/comps/videoComp/videobuttonCompConstants.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videobuttonCompConstants.tsx diff --git a/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx b/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx deleted file mode 100644 index 6e3bd8c96..000000000 --- a/client/packages/lowcoder/src/comps/comps/videoComp/videoContolComp.tsx +++ /dev/null @@ -1,226 +0,0 @@ -import styled, { css } from "styled-components"; -import { Section, sectionNames } from "lowcoder-design"; -import { - clickEvent, - eventHandlerControl, -} from "../../controls/eventHandlerControl"; -import { StringStateControl } from "../../controls/codeStateControl"; -import { UICompBuilder, withDefault } from "../../generators"; -import { - NameConfig, - NameConfigHidden, - withExposingConfigs, -} from "../../generators/withExposing"; -import { RecordConstructorToView } from "lowcoder-core"; -import { useEffect, useRef, useState } from "react"; -import _ from "lodash"; -import ReactResizeDetector from "react-resize-detector"; -import { styleControl } from "comps/controls/styleControl"; -import { - ImageStyle, - ImageStyleType, - heightCalculator, - widthCalculator, -} from "comps/controls/styleControlConstants"; -import { hiddenPropertyView } from "comps/utils/propertyUtils"; -import { trans } from "i18n"; -import { AutoHeightControl } from "comps/controls/autoHeightControl"; -import { BoolControl } from "comps/controls/boolControl"; -import { Image as AntImage } from "antd"; -import { DEFAULT_IMG_URL } from "util/stringUtils"; -import { - Button100, - ButtonCompWrapper, - ButtonStyleControl, -} from "./videobuttonCompConstants"; - -const Container = styled.div<{ $style: ImageStyleType | undefined }>` - height: 100%; - width: 100%; - display: flex; - align-items: center; - justify-content: center; - .ant-image, - img { - width: 100%; - height: 100%; - } - - img { - object-fit: contain; - pointer-events: auto; - } - - ${(props) => props.$style && getStyle(props.$style)} -`; - -const getStyle = (style: ImageStyleType) => { - return css` - img { - border: 1px solid ${style.border}; - border-radius: ${style.radius}; - margin: ${style.margin}; - padding: ${style.padding}; - max-width: ${widthCalculator(style.margin)}; - max-height: ${heightCalculator(style.margin)}; - } - - .ant-image-mask { - border-radius: ${style.radius}; - } - `; -}; - -const EventOptions = [clickEvent] as const; - -const ContainerImg = (props: RecordConstructorToView) => { - const imgRef = useRef(null); - const conRef = useRef(null); - const [width, setWidth] = useState(0); - const [height, setHeight] = useState(0); - - const imgOnload = (img: HTMLImageElement) => { - img.onload = function () { - setWidth(img.naturalWidth); - setHeight(img.naturalHeight); - }; - }; - - useEffect(() => { - const newImage = new Image(0, 0); - newImage.src = props.src.value; - imgOnload(newImage); - newImage.onerror = function (e) { - newImage.src = DEFAULT_IMG_URL; - imgOnload(newImage); - }; - }, [props.src.value]); - - useEffect(() => { - if (height && width) { - onResize(); - } - }, [height, width]); - - // on safari - const setStyle = (height: string, width: string) => { - console.log(width, height); - - const img = imgRef.current; - console.log("img", img); - const imgDiv = img?.getElementsByTagName("button")[0]; - console.log("button", imgDiv); - - const imgCurrent = img?.getElementsByTagName("button")[0]; - img!.style.height = height; - img!.style.width = width; - imgDiv!.style.height = height; - imgDiv!.style.width = width; - // imgCurrent!.style.height = height; - // imgCurrent!.style.width = width; - }; - - const onResize = () => { - const img = imgRef.current; - const container = conRef.current; - console.log(container?.clientWidth, container?.clientHeight); - - if (!img?.clientWidth || !img?.clientHeight || props.autoHeight || !width) { - return; - } - // fixme border style bug on safari - setStyle(container?.clientHeight + "px", container?.clientWidth + "px"); - // if ( - // (_.divide(container?.clientWidth!, container?.clientHeight!) || 0) > - // (_.divide(Number(width), Number(height)) || 0) - // ) { - // setStyle("100%", "auto"); - // } else { - // setStyle("auto", "100%"); - // } - }; - return ( - - -
- - // isDefault(props.type) - // ? props.onEvent("click") - // : submitForm(editorState, props.form) - // } - > - m - -
-
-
- ); -}; - -const childrenMap = { - src: withDefault(StringStateControl, "https://temp.im/350x400"), - onEvent: eventHandlerControl(EventOptions), - style: styleControl(ImageStyle), - autoHeight: withDefault(AutoHeightControl, "fixed"), - supportPreview: BoolControl, -}; - -let ImageBasicComp = new UICompBuilder(childrenMap, (props) => { - return ; -}) - .setPropertyViewFn((children) => { - return ( - <> -
- {children.src.propertyView({ - label: trans("image.src"), - })} - {children.supportPreview.propertyView({ - label: trans("image.supportPreview"), - tooltip: trans("image.supportPreviewTip"), - })} -
- -
- {children.onEvent.getPropertyView()} -
- -
- {children.autoHeight.getPropertyView()} - {hiddenPropertyView(children)} -
- -
- {children.style.getPropertyView()} -
- - ); - }) - .build(); - -ImageBasicComp = class extends ImageBasicComp { - override autoHeight(): boolean { - return this.children.autoHeight.getView(); - } -}; - -export const VideoContolComp = withExposingConfigs(ImageBasicComp, [ - new NameConfig("src", trans("image.srcDesc")), - NameConfigHidden, -]); diff --git a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx index e5fa4d598..7d6943c0c 100644 --- a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx +++ b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx @@ -32,7 +32,7 @@ import { MessageComp } from "./messageComp"; import { ThemeComp } from "./themeComp"; import UrlParamsHookComp from "./UrlParamsHookComp"; import { UtilsComp } from "./utilsComp"; -import { VideoCOntrollerComp } from "./videoControllerComp"; +import { VideoCOntrollerComp } from "../comps/meetingComp/videoControllerComp"; window._ = _; window.dayjs = dayjs; diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx index e48516ac3..faadc87bf 100644 --- a/client/packages/lowcoder/src/comps/index.tsx +++ b/client/packages/lowcoder/src/comps/index.tsx @@ -136,9 +136,9 @@ import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"; //Added by Aqib Mirza import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp"; import { ResponsiveLayoutComp } from "./comps/responsiveLayout"; -import { VideoMeetingComp } from "./comps/videoComp/videoMeetingComp"; -import { VideoControlButton } from "./comps/videoComp/videoControlButton"; -import { VideoCOntrollerComp } from "./hooks/videoControllerComp"; +import { VideoMeetingComp } from "./comps/meetingComp/videoStreamComp"; +import { VideoControlButton } from "./comps/meetingComp/videoControlButton"; +import { VideoCOntrollerComp } from "./comps/meetingComp/videoControllerComp"; type Registry = { [key in UICompType]?: UICompManifest; From d1050eb93a134705d793e82043c9cca3f6afece8 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 9 Oct 2023 12:39:11 +0300 Subject: [PATCH 05/20] more meeting components name refactoring fixes --- .../src/components/Meeting.tsx | 93 ------------------- .../src/components/meeting.tsx | 43 --------- client/packages/lowcoder-design/src/index.ts | 3 +- ...omp.tsx => videoMeetingControllerComp.tsx} | 7 +- ...eamComp.tsx => videoMeetingStreamComp.tsx} | 2 +- .../lowcoder/src/comps/hooks/hookComp.tsx | 4 +- client/packages/lowcoder/src/comps/index.tsx | 8 +- .../lowcoder/src/comps/uiCompRegistry.ts | 2 +- .../packages/lowcoder/src/i18n/locales/en.ts | 4 +- 9 files changed, 13 insertions(+), 153 deletions(-) delete mode 100644 client/packages/lowcoder-design/src/components/Meeting.tsx delete mode 100644 client/packages/lowcoder-design/src/components/meeting.tsx rename client/packages/lowcoder/src/comps/comps/meetingComp/{videoControllerComp.tsx => videoMeetingControllerComp.tsx} (99%) rename client/packages/lowcoder/src/comps/comps/meetingComp/{videoStreamComp.tsx => videoMeetingStreamComp.tsx} (98%) diff --git a/client/packages/lowcoder-design/src/components/Meeting.tsx b/client/packages/lowcoder-design/src/components/Meeting.tsx deleted file mode 100644 index a438f905b..000000000 --- a/client/packages/lowcoder-design/src/components/Meeting.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Drawer as AntdDrawer, DrawerProps as AntdDrawerProps } from "antd"; -import Handle from "./Modal/handler"; -import { useEffect, useMemo, useState } from "react"; -import { Resizable, ResizeHandle } from "react-resizable"; -import { useResizeDetector } from "react-resize-detector"; -import styled from "styled-components"; - -const StyledMeeting = styled(AntdDrawer)` - & .ant-drawer-content-wrapper { - transition-duration: 0s; - } -`; - -type Placement = "top" | "bottom" | "left" | "right"; -function getResizeHandle(placement?: Placement): ResizeHandle { - switch (placement) { - case "top": - return "s"; - case "bottom": - return "n"; - case "left": - return "e"; - } - return "w"; -} - -type MeetingProps = { - resizable?: boolean; - onResizeStart?: ( - e: React.SyntheticEvent, - node: HTMLElement, - size: { width: number; height: number }, - handle: ResizeHandle - ) => void; - onResize?: ( - e: React.SyntheticEvent, - node: HTMLElement, - size: { width: number; height: number }, - handle: ResizeHandle - ) => void; - onResizeStop?: ( - e: React.SyntheticEvent, - node: HTMLElement, - size: { width: number; height: number }, - handle: ResizeHandle - ) => void; -} & AntdDrawerProps; - -export function Meeting(props: MeetingProps) { - const { resizable, width: drawerWidth, height: drawerHeight, children, ...otherProps } = props; - const placement = useMemo(() => props.placement ?? "right", [props.placement]); - const resizeHandles = useMemo( - () => (resizable ? [getResizeHandle(placement)] : []), - [placement, resizable] - ); - const isTopBom = ["top", "bottom"].includes(placement); - const [width, setWidth] = useState(); - const [height, setHeight] = useState(); - useEffect(() => { - setWidth(undefined); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [drawerWidth]); - useEffect(() => { - setHeight(undefined); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [drawerHeight]); - const { width: detectWidth, height: detectHeight, ref } = useResizeDetector(); - // log.info("Drawer. drawerWidth: ", drawerWidth, " width: ", width, "detectWidth: ", detectWidth); - return ( - - - props.onResizeStart?.(event, node, size, handle) - } - onResize={(event, { node, size, handle }) => { - isTopBom ? setHeight(size.height) : setWidth(size.width); - props.onResize?.(event, node, size, handle); - }} - onResizeStop={(event, { node, size, handle }) => - props.onResizeStop?.(event, node, size, handle) - } - > -
- {children} -
-
-
- ); -} diff --git a/client/packages/lowcoder-design/src/components/meeting.tsx b/client/packages/lowcoder-design/src/components/meeting.tsx deleted file mode 100644 index 829044cf1..000000000 --- a/client/packages/lowcoder-design/src/components/meeting.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { trans } from "i18n/design"; -import { ReactNode } from "react"; -import styled from "styled-components"; -import { ReactComponent as MeetingContainerDrag } from "icons/icon-left-comp-video.svg"; - -type MeetingContainerPlaceholderProps = { - children?: ReactNode; -}; - -const HintText = styled.span` - font-size: 13px; - color: #b8b9bf; - text-align: center; -`; - -export function MeetingContainerPlaceholder( - props: MeetingContainerPlaceholderProps -) { - return ( -
- - - {props.children} - -
- ); -} - -export const MeetingHintPlaceHolder = ( - - {trans("container.hintPlaceHolder")} - -); diff --git a/client/packages/lowcoder-design/src/index.ts b/client/packages/lowcoder-design/src/index.ts index 133417f7c..a2a7ca495 100644 --- a/client/packages/lowcoder-design/src/index.ts +++ b/client/packages/lowcoder-design/src/index.ts @@ -1,7 +1,6 @@ export * from "./components/Collapase"; export * from "./components/CustomModal"; -export * from "./components/Drawer"; -export * from "./components/Meeting"; +export * from "./components/Drawer"; export * from "./components/Dropdown"; export * from "./components/ExternalLink"; export * from "./components/GlobalInstances"; diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx similarity index 99% rename from client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 74ba992ad..d068ace93 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -7,9 +7,7 @@ import { } from "comps/comps/containerComp/containerView"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; import { BoolControl } from "comps/controls/boolControl"; -import { - StringControl, -} from "comps/controls/codeControl"; +import { StringControl } from "comps/controls/codeControl"; import { booleanExposingStateControl, jsonObjectExposingStateControl, @@ -94,7 +92,6 @@ function transToPxSize(size: string | number) { return isNumeric(size) ? size + "px" : (size as string); } - let client: IAgoraRTCClient = AgoraRTC.createClient({ mode: "rtc", codec: "vp8", @@ -461,7 +458,7 @@ MTComp = withMethodExposing(MTComp, [ }, ]); -export const VideoCOntrollerComp = withExposingConfigs(MTComp, [ +export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [ new NameConfig("visible", trans("export.visibleDesc")), new NameConfig("appId", trans("prop.appid")), new NameConfig("participants", trans("prop.participants")), diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx similarity index 98% rename from client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 67e687277..d2963c4c3 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -215,7 +215,7 @@ VideoCompBuilder = class extends VideoCompBuilder { }; -export const VideoMeetingComp = withExposingConfigs(VideoCompBuilder, [ +export const VideoMeetingStreamComp = withExposingConfigs(VideoCompBuilder, [ new NameConfig("loading", trans("button.loadingDesc")), ...CommonNameConfig, ]); diff --git a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx index 7d6943c0c..43e44b7c7 100644 --- a/client/packages/lowcoder/src/comps/hooks/hookComp.tsx +++ b/client/packages/lowcoder/src/comps/hooks/hookComp.tsx @@ -32,7 +32,7 @@ import { MessageComp } from "./messageComp"; import { ThemeComp } from "./themeComp"; import UrlParamsHookComp from "./UrlParamsHookComp"; import { UtilsComp } from "./utilsComp"; -import { VideoCOntrollerComp } from "../comps/meetingComp/videoControllerComp"; +import { VideoMeetingControllerComp } from "../comps/meetingComp/videoMeetingControllerComp"; window._ = _; window.dayjs = dayjs; @@ -95,7 +95,7 @@ const HookMap: HookCompMapRawType = { message: MessageComp, localStorage: LocalStorageComp, modal: ModalComp, - meeting: VideoCOntrollerComp, + meeting: VideoMeetingControllerComp, currentUser: CurrentUserHookComp, urlParams: UrlParamsHookComp, drawer: DrawerComp, diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx index faadc87bf..c2ffb9951 100644 --- a/client/packages/lowcoder/src/comps/index.tsx +++ b/client/packages/lowcoder/src/comps/index.tsx @@ -136,9 +136,9 @@ import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"; //Added by Aqib Mirza import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp"; import { ResponsiveLayoutComp } from "./comps/responsiveLayout"; -import { VideoMeetingComp } from "./comps/meetingComp/videoStreamComp"; +import { VideoMeetingStreamComp } from "./comps/meetingComp/videoMeetingStreamComp"; import { VideoControlButton } from "./comps/meetingComp/videoControlButton"; -import { VideoCOntrollerComp } from "./comps/meetingComp/videoControllerComp"; +import { VideoMeetingControllerComp } from "./comps/meetingComp/videoMeetingControllerComp"; type Registry = { [key in UICompType]?: UICompManifest; @@ -565,7 +565,7 @@ const uiCompMap: Registry = { categories: ["meeting"], icon: VideoCompIcon, keywords: trans("meeting.meetingCompKeywords"), - comp: VideoMeetingComp, + comp: VideoMeetingStreamComp, withoutLoading: true, }, meetingcontrols: { @@ -781,7 +781,7 @@ const uiCompMap: Registry = { categories: ["meeting"], icon: DrawerCompIcon, keywords: trans("meeting.meetingCompKeywords"), - comp: VideoCOntrollerComp, + comp: VideoMeetingControllerComp, withoutLoading: true, }, carousel: { diff --git a/client/packages/lowcoder/src/comps/uiCompRegistry.ts b/client/packages/lowcoder/src/comps/uiCompRegistry.ts index 1aa9778bb..1dcf740bb 100644 --- a/client/packages/lowcoder/src/comps/uiCompRegistry.ts +++ b/client/packages/lowcoder/src/comps/uiCompRegistry.ts @@ -24,7 +24,7 @@ export interface UICompLayoutInfo { export const uiCompCategoryNames = { common: trans("uiCompCategory.common"), - meeting: trans("uiCompCategory.meeting"), + meeting: trans("meeting.meeting"), dataInputText: trans("uiCompCategory.dataInputText"), dataInputNumber: trans("uiCompCategory.dataInputNumber"), dataInputSelect: trans("uiCompCategory.dataInputSelect"), diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 67e118864..6eef4054d 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -697,7 +697,6 @@ export const en = { }, uiCompCategory: { common: "Commonly used", - meeting: "Meeting Settings", dataInputText: "Text inputs", dataInputNumber: "Number inputs", dataInputSelect: "Select inputs", @@ -1436,7 +1435,8 @@ export const en = { height: "Drawer height", }, meeting: { - placement: "Drawer placement", + placement: "Meeting placement", + meeting: "Meeting Settings", size: "Size", top: "Top", right: "Right", From db0753fc3df7bb97287ce194552ff8fc7c311cca Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Tue, 10 Oct 2023 17:37:23 +0300 Subject: [PATCH 06/20] initial-participants listview with videos --- .../videoMeetingControllerComp.tsx | 71 ++++++------------- .../meetingComp/videoMeetingStreamComp.tsx | 70 +++++++++++------- 2 files changed, 65 insertions(+), 76 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index d068ace93..cc9ccabb8 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -11,7 +11,6 @@ import { StringControl } from "comps/controls/codeControl"; import { booleanExposingStateControl, jsonObjectExposingStateControl, - jsonValueExposingStateControl, numberExposingStateControl, } from "comps/controls/codeStateControl"; import { PositionControl } from "comps/controls/dropdownControl"; @@ -21,7 +20,7 @@ import { } from "comps/controls/eventHandlerControl"; import { styleControl } from "comps/controls/styleControl"; import { DrawerStyle } from "comps/controls/styleControlConstants"; -import { withDefault } from "comps/generators"; +import { stateComp, withDefault } from "comps/generators"; import { withMethodExposing } from "comps/generators/withMethodExposing"; import { BackgroundColorContext } from "comps/utils/backgroundColorContext"; import { CanvasContainerID } from "constants/domLocators"; @@ -34,7 +33,7 @@ import { Section, sectionNames, } from "lowcoder-design"; -import { useCallback, useEffect } from "react"; +import { useCallback, useEffect, useState } from "react"; import { ResizeHandle } from "react-resizable"; import styled from "styled-components"; import { useUserViewMode } from "util/hooks"; @@ -47,6 +46,8 @@ import AgoraRTC, { IAgoraRTCClient, IAgoraRTCRemoteUser, } from "agora-rtc-sdk-ng"; +import { JSONValue } from "@lowcoder-ee/index.sdk"; +import { getData } from "../listViewComp/listViewUtils"; const EventOptions = [closeEvent] as const; @@ -92,11 +93,10 @@ function transToPxSize(size: string | number) { return isNumeric(size) ? size + "px" : (size as string); } -let client: IAgoraRTCClient = AgoraRTC.createClient({ +export const client: IAgoraRTCClient = AgoraRTC.createClient({ mode: "rtc", codec: "vp8", }); - let audioTrack: IMicrophoneAudioTrack; let videoTrack: ICameraVideoTrack; @@ -105,7 +105,7 @@ const turnOnCamera = async (flag?: boolean) => { return videoTrack.setEnabled(flag!); } videoTrack = await AgoraRTC.createCameraVideoTrack(); - videoTrack.play("camera-video"); + videoTrack.play("host-video"); }; const turnOnMicrophone = async (flag?: boolean) => { @@ -151,13 +151,9 @@ const joinChannel = async (appId: any, channel: any, token: any) => { if (isJoined) { await leaveChannel(); } - - await client.join( - appId, - channel, - token || null, - Math.floor(100000 + Math.random() * 900000) - ); + let userId = Math.floor(100000 + Math.random() * 900000); + console.log("me joining ", userId); + await client.join(appId, channel, token || null, userId); isJoined = true; }; @@ -177,30 +173,13 @@ const publishVideo = async (appId: any, channel: any, height: any) => { const videoSettings = mediaStreamTrack.getSettings(); const videoWidth = videoSettings.width; const videoHeight = videoSettings.height; - console.log("videoHeight ", videoHeight); - height.videoWidth.change(videoWidth); height.videoHeight.change(videoHeight); - console.log(`Video width: ${videoWidth}px, height: ${videoHeight}px`); } else { console.error("Media stream track not found"); } }; -const onUserPublish = async ( - user: IAgoraRTCRemoteUser, - mediaType: "video" | "audio" -) => { - if (mediaType === "video") { - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play("remote-video"); - } - if (mediaType === "audio") { - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play(); - } -}; - let MTComp = (function () { const childrenMap = { visible: booleanExposingStateControl("visible"), @@ -219,7 +198,7 @@ let MTComp = (function () { videoWidth: numberExposingStateControl("videoWidth", 200), videoHeight: numberExposingStateControl("videoHeight", 200), appId: withDefault(StringControl, trans("prop.appid")), - participants: jsonValueExposingStateControl("participants"), + participants: stateComp([]), }; return new ContainerCompBuilder(childrenMap, (props, dispatch) => { const isTopBom = ["top", "bottom"].includes(props.placement); @@ -239,34 +218,20 @@ let MTComp = (function () { }, [dispatch, isTopBom] ); + const [userIds, setUserIds] = useState([]); useEffect(() => { - console.log("nnnn ", props.participants); - }, [props.participants.value]); + dispatch(changeChildAction("participants", getData(userIds).data, false)); + }, [userIds]); useEffect(() => { if (client) { - client.on( - "user-published", - async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { - if (mediaType === "video") { - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play("remote-video"); - } - if (mediaType === "audio") { - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play(); - } - } - ); - - client.on("user-joined", (user: IAgoraRTCRemoteUser) => {}); + client.on("user-joined", (user: IAgoraRTCRemoteUser) => { + setUserIds((userIds: any) => [...userIds, { user: user.uid }]); + }); client.on("user-offline", (uid: any, reason: any) => { console.log(`User ${uid} left the channel.`); }); - client.on("user-published", (user, mediaType) => { - console.log(`User ${user.uid} published ${user.videoTrack} stream.`); - }); client.on("stream-removed", (user: IAgoraRTCRemoteUser) => { console.log(`Stream from user ${user.uid} removed.`); }); @@ -463,3 +428,7 @@ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [ new NameConfig("appId", trans("prop.appid")), new NameConfig("participants", trans("prop.participants")), ]); + +export function agoraClient() { + return client; +} diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index d2963c4c3..b880d2deb 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -1,11 +1,4 @@ -import { - ArrayControl, - ArrayOrJSONObjectControl, - BoolCodeControl, - JSONObjectArrayControl, - NumberControl, - StringControl, -} from "comps/controls/codeControl"; +import { BoolCodeControl } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; import { IconControl } from "comps/controls/iconControl"; @@ -36,13 +29,11 @@ import { RefControl } from "comps/controls/refControl"; import { useEffect, useRef, useState } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; -import { - arrayStringExposingStateControl, - booleanExposingStateControl, - jsonObjectExposingStateControl, - stringExposingStateControl, - withMethodExposing, -} from "@lowcoder-ee/index.sdk"; +import { client } from "./videoMeetingControllerComp"; + +import { IAgoraRTCRemoteUser, UID } from "agora-rtc-sdk-ng"; + +import { stringExposingStateControl } from "@lowcoder-ee/index.sdk"; // import useAgora from "@lowcoder-ee/comps/hooks/agoraFunctions"; const FormLabel = styled(CommonBlueLabel)` @@ -50,10 +41,6 @@ const FormLabel = styled(CommonBlueLabel)` margin-right: 4px; `; -const IconWrapper = styled.div` - display: flex; -`; - function getFormOptions(editorState: EditorState) { return editorState .uiCompInfoList() @@ -165,10 +152,7 @@ let VideoCompBuilder = (function (props) { suffixIcon: IconControl, style: ButtonStyleControl, viewRef: RefControl, - userId: stringExposingStateControl( - "text", - trans("meeting.userId", { name: "{{currentUser.name}}" }) - ), + userId: stringExposingStateControl("user id", trans("meeting.userId")), }; return new UICompBuilder(childrenMap, (props) => { const videoRef = useRef(null); @@ -178,7 +162,6 @@ let VideoCompBuilder = (function (props) { onResize(); }, []); - const onResize = async () => { const container = conRef.current; let videoCo = videoRef.current; @@ -186,6 +169,39 @@ let VideoCompBuilder = (function (props) { videoCo!.style.width = container?.clientWidth + "px"; }; + useEffect(() => { + client.on( + "user-published", + async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { + if (mediaType === "video") { + + // const videoElement = document.createElement("video"); + // videoElement.id = user.uid + ""; + // videoElement.width = 640; + // videoElement.height = 360; + + // if (conRef.current) { + // conRef.current.appendChild(videoElement); + // } + + // console.log("elementHtml", document.getElementById(user.uid + "")); + + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play(user.uid + "_v"); + console.log("user-published ", user.uid); + } + if (mediaType === "audio") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play(); + } + } + ); + + client.on("user-joined", (user: IAgoraRTCRemoteUser) => { + console.log("drawer joined", user.uid); + }); + }, [props.userId]); + return ( {(editorState) => ( @@ -193,6 +209,7 @@ let VideoCompBuilder = (function (props) { @@ -203,6 +220,10 @@ let VideoCompBuilder = (function (props) { }) .setPropertyViewFn((children) => ( <> +
+ {children.userId.propertyView({ label: trans("text") })} + {children.autoHeight.getPropertyView()} +
)) .build(); @@ -214,7 +235,6 @@ VideoCompBuilder = class extends VideoCompBuilder { } }; - export const VideoMeetingStreamComp = withExposingConfigs(VideoCompBuilder, [ new NameConfig("loading", trans("button.loadingDesc")), ...CommonNameConfig, From 26a980ab4cc03ecd249ab8d5d53d24f463e5e34e Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Thu, 12 Oct 2023 14:26:42 +0300 Subject: [PATCH 07/20] implemented user leaving the call and removing the user from the list of users to refresh all other users in the room to see one user has left --- .DS_Store | Bin 0 -> 6148 bytes client/packages/lowcoder/docker-compose.yaml | 99 ++++++++++++++++++ .../videoMeetingControllerComp.tsx | 36 +++---- .../meetingComp/videoMeetingStreamComp.tsx | 26 +---- 4 files changed, 115 insertions(+), 46 deletions(-) create mode 100644 .DS_Store create mode 100644 client/packages/lowcoder/docker-compose.yaml diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8cd8f4f0b42ebab53a9ee4a7866540c3f64ac38f GIT binary patch literal 6148 zcmeHKu}&L75Pj<$*oG8VB&48FoM@mjqNO^JQ${Heqy!sVn8cT}VvK~8C|4vYqtK^F z6-1XR;s??}OOZAu4J8#~W_NAR+8m-nDB6*B-`>vb%)58KTQ2~$(ycE7B>)9#jKKtT zHyHc5jabgk%n&Nh(b`^I-Ady2NTi?e3U~z`q5}Nx1}I}2JJ^-)Z}GVNP5R=bQmM6) z8qF1oN52nFUjJEk{qk<9Z5dqwkkIJ{+Ded@;Xe<{@GR&oC=S@|b!SF^{_%?b&RFNrS%k3U~#)0(}Me z`w&uNj4Y-G^{0b6eFPv3Xj&VMOFSS9Ek+hogXAGoW+|ars_YR%ndLMe+PKJKYS1i) zvWE|4D=T|KQMx+i4|O { }; const leaveChannel = async () => { - if (!client) { - console.error("Agora client is not initialized"); - return; - } - - if (!client.localTracks.length) { - console.error("No local tracks to unpublish"); - return; - } + console.log("user leaving 3"); if (videoTrack) { await turnOnCamera(false); await client.unpublish(videoTrack); videoTrack.stop(); } + console.log("user leaving 2"); if (audioTrack) { await turnOnMicrophone(false); await client.unpublish(audioTrack); audioTrack.stop(); } + console.log("user leaving"); await client.leave(); isJoined = false; @@ -225,20 +219,14 @@ let MTComp = (function () { }, [userIds]); useEffect(() => { - if (client) { - client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - setUserIds((userIds: any) => [...userIds, { user: user.uid }]); - }); - client.on("user-offline", (uid: any, reason: any) => { - console.log(`User ${uid} left the channel.`); - }); - client.on("stream-removed", (user: IAgoraRTCRemoteUser) => { - console.log(`Stream from user ${user.uid} removed.`); - }); - client.on("stream-added", (user: IAgoraRTCRemoteUser) => { - console.log("stream-added"); - }); - } + client.on("user-joined", (user: IAgoraRTCRemoteUser) => { + setUserIds((userIds: any) => [...userIds, { user: user.uid }]); + }); + client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => { + setUserIds((userIds: any) => + userIds.filter((item: any) => item.user !== user.uid) + ); + }); }, [client]); return ( @@ -407,6 +395,8 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { let value = !comp.children.endCall.getView().value; + console.log(""); + await leaveChannel(); comp.children.endCall.change(value); }, diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index b880d2deb..b5d07de62 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -34,7 +34,6 @@ import { client } from "./videoMeetingControllerComp"; import { IAgoraRTCRemoteUser, UID } from "agora-rtc-sdk-ng"; import { stringExposingStateControl } from "@lowcoder-ee/index.sdk"; -// import useAgora from "@lowcoder-ee/comps/hooks/agoraFunctions"; const FormLabel = styled(CommonBlueLabel)` font-size: 13px; @@ -168,27 +167,13 @@ let VideoCompBuilder = (function (props) { videoCo!.style.height = container?.clientHeight + "px"; videoCo!.style.width = container?.clientWidth + "px"; }; - useEffect(() => { client.on( "user-published", async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { if (mediaType === "video") { - - // const videoElement = document.createElement("video"); - // videoElement.id = user.uid + ""; - // videoElement.width = 640; - // videoElement.height = 360; - - // if (conRef.current) { - // conRef.current.appendChild(videoElement); - // } - - // console.log("elementHtml", document.getElementById(user.uid + "")); - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play(user.uid + "_v"); - console.log("user-published ", user.uid); + remoteTrack.play(user.uid + ""); } if (mediaType === "audio") { const remoteTrack = await client.subscribe(user, mediaType); @@ -196,12 +181,7 @@ let VideoCompBuilder = (function (props) { } } ); - - client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - console.log("drawer joined", user.uid); - }); - }, [props.userId]); - + }, [props.userId.value]); return ( {(editorState) => ( @@ -209,7 +189,7 @@ let VideoCompBuilder = (function (props) { From 36de39ca6f9bb494b11e76819a546b9cbba7ed91 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Thu, 12 Oct 2023 17:41:56 +0300 Subject: [PATCH 08/20] added sharing of screen --- .../videoMeetingControllerComp.tsx | 55 +++++++++++++++---- .../meetingComp/videoMeetingStreamComp.tsx | 10 +++- .../packages/lowcoder/src/i18n/locales/en.ts | 1 + 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 7d0b8fd12..4344565b8 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -12,6 +12,7 @@ import { booleanExposingStateControl, jsonObjectExposingStateControl, numberExposingStateControl, + stringExposingStateControl, } from "comps/controls/codeStateControl"; import { PositionControl } from "comps/controls/dropdownControl"; import { @@ -45,6 +46,8 @@ import AgoraRTC, { IMicrophoneAudioTrack, IAgoraRTCClient, IAgoraRTCRemoteUser, + UID, + ILocalVideoTrack, } from "agora-rtc-sdk-ng"; import { JSONValue } from "@lowcoder-ee/index.sdk"; import { getData } from "../listViewComp/listViewUtils"; @@ -99,13 +102,14 @@ export const client: IAgoraRTCClient = AgoraRTC.createClient({ }); let audioTrack: IMicrophoneAudioTrack; let videoTrack: ICameraVideoTrack; - +let screenShareStream: ILocalVideoTrack; +let userId: UID | null | undefined; const turnOnCamera = async (flag?: boolean) => { if (videoTrack) { return videoTrack.setEnabled(flag!); } videoTrack = await AgoraRTC.createCameraVideoTrack(); - videoTrack.play("host-video"); + videoTrack.play(userId + ""); }; const turnOnMicrophone = async (flag?: boolean) => { @@ -115,24 +119,42 @@ const turnOnMicrophone = async (flag?: boolean) => { audioTrack = await AgoraRTC.createMicrophoneAudioTrack(); audioTrack.play(); }; - +const shareScreen = async (sharing: boolean) => { + try { + if (sharing == false) { + await client.unpublish(screenShareStream); + await client.publish(videoTrack); + videoTrack.play(userId + ""); + } else { + screenShareStream = await AgoraRTC.createScreenVideoTrack( + { + screenSourceType: "screen", + }, + "disable" + ); + await client.unpublish(videoTrack); + screenShareStream.play(userId + ""); + await client.publish(screenShareStream); + } + } catch (error) { + console.error("Failed to create screen share stream:", error); + } +}; const leaveChannel = async () => { - console.log("user leaving 3"); if (videoTrack) { await turnOnCamera(false); await client.unpublish(videoTrack); videoTrack.stop(); } - console.log("user leaving 2"); if (audioTrack) { await turnOnMicrophone(false); await client.unpublish(audioTrack); audioTrack.stop(); } - console.log("user leaving"); await client.leave(); + window.location.reload(); //FixMe: this reloads the page when user leaves isJoined = false; }; let isJoined = false; @@ -145,7 +167,6 @@ const joinChannel = async (appId: any, channel: any, token: any) => { if (isJoined) { await leaveChannel(); } - let userId = Math.floor(100000 + Math.random() * 900000); console.log("me joining ", userId); await client.join(appId, channel, token || null, userId); @@ -154,8 +175,6 @@ const joinChannel = async (appId: any, channel: any, token: any) => { const publishVideo = async (appId: any, channel: any, height: any) => { await turnOnCamera(true); - console.log(appId, channel); - if (!isJoined) { await joinChannel(appId, channel, null); } @@ -188,11 +207,13 @@ let MTComp = (function () { audioControl: booleanExposingStateControl("false"), videoControl: booleanExposingStateControl("true"), endCall: booleanExposingStateControl("false"), + sharingScreen: booleanExposingStateControl("false"), videoSettings: jsonObjectExposingStateControl(""), videoWidth: numberExposingStateControl("videoWidth", 200), videoHeight: numberExposingStateControl("videoHeight", 200), appId: withDefault(StringControl, trans("prop.appid")), participants: stateComp([]), + host: stringExposingStateControl("host"), }; return new ContainerCompBuilder(childrenMap, (props, dispatch) => { const isTopBom = ["top", "bottom"].includes(props.placement); @@ -349,6 +370,18 @@ MTComp = withMethodExposing(MTComp, [ comp.children.visible.getView().onChange(true); }, }, + { + method: { + name: "startSharing", + description: trans("drawer.openDrawerDesc"), + params: [], + }, + execute: async (comp, values) => { + let sharing = !comp.children.sharingScreen.getView().value; + comp.children.sharingScreen.change(sharing); + await shareScreen(sharing); + }, + }, { method: { name: "audioControl", @@ -380,6 +413,8 @@ MTComp = withMethodExposing(MTComp, [ params: [], }, execute: async (comp, values) => { + userId = Math.floor(100000 + Math.random() * 900000); + comp.children.host.change(userId + ""); await publishVideo( comp.children.appId.getView(), "testsdaadasdsa", @@ -395,7 +430,6 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { let value = !comp.children.endCall.getView().value; - console.log(""); await leaveChannel(); comp.children.endCall.change(value); @@ -416,6 +450,7 @@ MTComp = withMethodExposing(MTComp, [ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [ new NameConfig("visible", trans("export.visibleDesc")), new NameConfig("appId", trans("prop.appid")), + new NameConfig("host", trans("prop.appid")), new NameConfig("participants", trans("prop.participants")), ]); diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index b5d07de62..8966e93ec 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -31,7 +31,7 @@ import { useEffect, useRef, useState } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; import { client } from "./videoMeetingControllerComp"; -import { IAgoraRTCRemoteUser, UID } from "agora-rtc-sdk-ng"; +import AgoraRTC, { IAgoraRTCRemoteUser, UID } from "agora-rtc-sdk-ng"; import { stringExposingStateControl } from "@lowcoder-ee/index.sdk"; @@ -168,12 +168,18 @@ let VideoCompBuilder = (function (props) { videoCo!.style.width = container?.clientWidth + "px"; }; useEffect(() => { + client.on( "user-published", async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { if (mediaType === "video") { const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play(user.uid + ""); + let userId = user.uid + ""; + const element = document.getElementById(userId); + if (element) { + console.log("userId", element); + remoteTrack.play(userId); + } } if (mediaType === "audio") { const remoteTrack = await client.subscribe(user, mediaType); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 6eef4054d..89aab914c 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1452,6 +1452,7 @@ export const en = { title: "Meeting title", meetingCompName: "Meeting Controller", videoCompName: "Video Stream", + videoSharingCompName: "Video Sharing", meetingControlCompName: "Controls Buttons", meetingCompDesc: "Meeting component", meetingCompControls: "Meeting control", From 834c8250815cf56a70b8d71c7adf4e59d63ba95e Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Thu, 12 Oct 2023 18:26:18 +0300 Subject: [PATCH 09/20] refactored control buttons --- .../{videoControlButton.tsx => controlButton.tsx} | 14 ++------------ client/packages/lowcoder/src/comps/index.tsx | 6 +++--- .../packages/lowcoder/src/comps/uiCompRegistry.ts | 2 +- .../lowcoder/src/pages/editor/editorConstants.tsx | 2 +- 4 files changed, 7 insertions(+), 17 deletions(-) rename client/packages/lowcoder/src/comps/comps/meetingComp/{videoControlButton.tsx => controlButton.tsx} (95%) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoControlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx similarity index 95% rename from client/packages/lowcoder/src/comps/comps/meetingComp/videoControlButton.tsx rename to client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx index 217cb1bc6..17fca3adb 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoControlButton.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx @@ -306,17 +306,7 @@ let ButtonTmpComp = (function () { {props.prefixIcon} )} - { - props.text || - (props.prefixIcon || props.suffixIcon ? undefined : " ") // Avoid button disappearing - } - {props.suffixIcon && ( - - {props.suffixIcon} - - )} +
@@ -369,7 +359,7 @@ ButtonTmpComp = class extends ButtonTmpComp { return this.children.autoHeight.getView(); } }; -export const VideoControlButton = withExposingConfigs(ButtonTmpComp, [ +export const ControlButton = withExposingConfigs(ButtonTmpComp, [ new NameConfig("text", trans("button.textDesc")), new NameConfig("loading", trans("button.loadingDesc")), ...CommonNameConfig, diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx index c2ffb9951..f2098742b 100644 --- a/client/packages/lowcoder/src/comps/index.tsx +++ b/client/packages/lowcoder/src/comps/index.tsx @@ -137,7 +137,7 @@ import { AutoCompleteComp } from "./comps/autoCompleteComp/autoCompleteComp"; import { JsonLottieComp } from "./comps/jsonComp/jsonLottieComp"; import { ResponsiveLayoutComp } from "./comps/responsiveLayout"; import { VideoMeetingStreamComp } from "./comps/meetingComp/videoMeetingStreamComp"; -import { VideoControlButton } from "./comps/meetingComp/videoControlButton"; +import { ControlButton } from "./comps/meetingComp/controlButton"; import { VideoMeetingControllerComp } from "./comps/meetingComp/videoMeetingControllerComp"; type Registry = { @@ -568,14 +568,14 @@ const uiCompMap: Registry = { comp: VideoMeetingStreamComp, withoutLoading: true, }, - meetingcontrols: { + controlButton: { name: trans("meeting.meetingControlCompName"), enName: "Controls", description: trans("meeting.meetingCompDesc"), categories: ["meeting"], icon: ButtonCompIcon, keywords: trans("meeting.meetingCompKeywords"), - comp: VideoControlButton, + comp: ControlButton, withoutLoading: true, }, tabbedContainer: { diff --git a/client/packages/lowcoder/src/comps/uiCompRegistry.ts b/client/packages/lowcoder/src/comps/uiCompRegistry.ts index 1dcf740bb..a43e5e9e2 100644 --- a/client/packages/lowcoder/src/comps/uiCompRegistry.ts +++ b/client/packages/lowcoder/src/comps/uiCompRegistry.ts @@ -58,7 +58,7 @@ export type UICompType = | "chart" | "meeting" | "videocomponent" - | "meetingcontrols" + | "controlButton" | "imageEditor" | "calendar" | "password" diff --git a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx index c70e599c8..9a437761c 100644 --- a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx +++ b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx @@ -86,7 +86,7 @@ export const CompStateIcon: { container: , meeting: , videocomponent: , - meetingcontrols: , + controlButton: , tabbedContainer: , modal: , listView: , From 5472d95244cf66de5cc19879774c436ed5b33a7b Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Fri, 13 Oct 2023 11:13:28 +0300 Subject: [PATCH 10/20] fixed button data fields --- .../comps/comps/meetingComp/controlButton.tsx | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx index 17fca3adb..a56355e94 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx @@ -30,13 +30,11 @@ import { IForm } from "../formComp/formDataConstants"; import { SimpleNameComp } from "../simpleNameComp"; import { Button100, - ButtonCompWrapper, ButtonStyleControl, } from "./videobuttonCompConstants"; import { RefControl } from "comps/controls/refControl"; import { AutoHeightControl, - ImageStyleType, heightCalculator, widthCalculator, } from "@lowcoder-ee/index.sdk"; @@ -85,14 +83,6 @@ function getStyleIcon(style: any) { `; } -// const IconWrapper = styled.div<{ $styled: any }>` -// display: flex; -// svg { -// width: ${styled.width}px !important; -// height: ${styled.height}30px !important; -// } -// `; - function getFormOptions(editorState: EditorState) { return editorState .uiCompInfoList() @@ -186,7 +176,6 @@ function submitForm(editorState: EditorState, formName: string) { let ButtonTmpComp = (function () { const childrenMap = { - text: withDefault(StringControl, trans("button.button")), iconSize: withDefault(StringControl, "20px"), type: dropdownControl(typeOptions, ""), autoHeight: withDefault(AutoHeightControl, "fixed"), @@ -195,7 +184,6 @@ let ButtonTmpComp = (function () { loading: BoolCodeControl, form: SelectFormControl, prefixIcon: IconControl, - suffixIcon: IconControl, style: ButtonStyleControl, viewRef: RefControl, }; @@ -209,39 +197,23 @@ let ButtonTmpComp = (function () { useEffect(() => { if (height && width) { onResize(); - console.log("props", props, height, width); } }, [height, width]); const setStyle = (height: string, width: string) => { - console.log(width, height); - const img = imgRef.current; const imgDiv = img?.getElementsByTagName("button")[0]; - console.log("img 1", img); const imgCurrent = img?.getElementsByTagName("button")[0]; - console.log("img 2", imgCurrent); img!.style.height = height; img!.style.width = width; imgDiv!.style.height = height; imgDiv!.style.width = width; - // imgCurrent!.style.height = height; - // imgCurrent!.style.width = width; }; const onResize = () => { const img = imgRef.current; - console.log("img", img); const container = conRef.current; - // console.log("img", container); - console.log( - "img", - !img?.clientWidth, - !img?.clientHeight, - props.autoHeight, - !width - ); if ( !img?.clientWidth || !img?.clientHeight || @@ -250,20 +222,12 @@ let ButtonTmpComp = (function () { ) { return; } - // fixme border style bug on safari - // if ( - // (_.divide(container?.clientWidth!, container?.clientHeight!) || 0) > - // (_.divide(Number(width), Number(height)) || 0) - // ) { - // setStyle("100%", "auto"); - // } else { console.log( container?.clientHeight + "px", container?.clientWidth + "px" ); setStyle(container?.clientHeight + "px", container?.clientWidth + "px"); - // } }; return ( @@ -318,7 +282,6 @@ let ButtonTmpComp = (function () { .setPropertyViewFn((children) => ( <>
- {children.text.propertyView({ label: trans("text") })} {children.autoHeight.getPropertyView()}
@@ -339,9 +302,6 @@ let ButtonTmpComp = (function () { {children.prefixIcon.propertyView({ label: trans("button.prefixIcon"), })} - {children.suffixIcon.propertyView({ - label: trans("button.suffixIcon"), - })} {children.iconSize.propertyView({ label: trans("meeting.iconSize"), })} @@ -360,7 +320,6 @@ ButtonTmpComp = class extends ButtonTmpComp { } }; export const ControlButton = withExposingConfigs(ButtonTmpComp, [ - new NameConfig("text", trans("button.textDesc")), new NameConfig("loading", trans("button.loadingDesc")), ...CommonNameConfig, ]); From b808ac9948f7a0191b071b38bee4a6ca1a6cad4a Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Fri, 13 Oct 2023 12:02:03 +0300 Subject: [PATCH 11/20] added styling of the video component --- .../comps/comps/meetingComp/controlButton.tsx | 5 --- .../meetingComp/videoMeetingStreamComp.tsx | 31 +++++++++++++++---- .../packages/lowcoder/src/i18n/locales/en.ts | 1 + 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx index a56355e94..d3ad399a5 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx @@ -204,7 +204,6 @@ let ButtonTmpComp = (function () { const img = imgRef.current; const imgDiv = img?.getElementsByTagName("button")[0]; - const imgCurrent = img?.getElementsByTagName("button")[0]; img!.style.height = height; img!.style.width = width; imgDiv!.style.height = height; @@ -222,10 +221,6 @@ let ButtonTmpComp = (function () { ) { return; } - console.log( - container?.clientHeight + "px", - container?.clientWidth + "px" - ); setStyle(container?.clientHeight + "px", container?.clientWidth + "px"); }; diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 8966e93ec..5ff3ff8da 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -26,14 +26,18 @@ import { IForm } from "../formComp/formDataConstants"; import { SimpleNameComp } from "../simpleNameComp"; import { ButtonStyleControl } from "./videobuttonCompConstants"; import { RefControl } from "comps/controls/refControl"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useRef } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; import { client } from "./videoMeetingControllerComp"; -import AgoraRTC, { IAgoraRTCRemoteUser, UID } from "agora-rtc-sdk-ng"; +import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; -import { stringExposingStateControl } from "@lowcoder-ee/index.sdk"; +import { + hiddenPropertyView, + stringExposingStateControl, +} from "@lowcoder-ee/index.sdk"; +import { BackgroundColorContext } from "@lowcoder-ee/comps/utils/backgroundColorContext"; const FormLabel = styled(CommonBlueLabel)` font-size: 13px; @@ -60,11 +64,12 @@ const Container = styled.div<{ $style: any }>` const getStyle = (style: any) => { return css` - button { + { border: 1px solid ${style.border}; border-radius: ${style.radius}; margin: ${style.margin}; padding: ${style.padding}; + background-color: ${style.background}; } `; }; @@ -138,6 +143,9 @@ const typeOptions = [ value: "submit", }, ] as const; +function isDefault(type?: string) { + return !type; +} let VideoCompBuilder = (function (props) { const childrenMap = { @@ -168,7 +176,6 @@ let VideoCompBuilder = (function (props) { videoCo!.style.width = container?.clientWidth + "px"; }; useEffect(() => { - client.on( "user-published", async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { @@ -188,6 +195,9 @@ let VideoCompBuilder = (function (props) { } ); }, [props.userId.value]); + + console.log(props); + return ( {(editorState) => ( @@ -207,9 +217,18 @@ let VideoCompBuilder = (function (props) { .setPropertyViewFn((children) => ( <>
- {children.userId.propertyView({ label: trans("text") })} + {children.userId.propertyView({ label: trans("meeting.videoId") })} {children.autoHeight.getPropertyView()}
+
+ {children.onEvent.getPropertyView()} +
+
+ {hiddenPropertyView(children)} +
+
+ {children.style.getPropertyView()} +
)) .build(); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 89aab914c..1ba24dc43 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1441,6 +1441,7 @@ export const en = { top: "Top", right: "Right", bottom: "Bottom", + videoId: "Video Id", left: "Left", widthTooltip: "Number or percentage, e.g. 520, 60%", heightTooltip: "Number, e.g. 378", From e62d64c85b58b30d62000158f1758381f791770a Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Fri, 13 Oct 2023 12:15:49 +0300 Subject: [PATCH 12/20] added meeting name to the meeting controller data field --- .../videoMeetingControllerComp.tsx | 19 +++++++++++++------ .../packages/lowcoder/src/i18n/locales/en.ts | 6 ++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 4344565b8..69237d0ff 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -211,9 +211,10 @@ let MTComp = (function () { videoSettings: jsonObjectExposingStateControl(""), videoWidth: numberExposingStateControl("videoWidth", 200), videoHeight: numberExposingStateControl("videoHeight", 200), - appId: withDefault(StringControl, trans("prop.appid")), + appId: withDefault(StringControl, trans("meeting.appid")), participants: stateComp([]), host: stringExposingStateControl("host"), + meetingName: stringExposingStateControl("meetingName"), }; return new ContainerCompBuilder(childrenMap, (props, dispatch) => { const isTopBom = ["top", "bottom"].includes(props.placement); @@ -316,7 +317,10 @@ let MTComp = (function () { .setPropertyViewFn((children) => ( <>
- {children.appId.propertyView({ label: trans("prop.appid") })} + {children.appId.propertyView({ label: trans("meeting.appid") })} + {children.meetingName.propertyView({ + label: trans("meeting.meetingName"), + })} {children.placement.propertyView({ label: trans("drawer.placement"), radioButton: true, @@ -417,7 +421,9 @@ MTComp = withMethodExposing(MTComp, [ comp.children.host.change(userId + ""); await publishVideo( comp.children.appId.getView(), - "testsdaadasdsa", + comp.children.meetingName.getView().value == "" + ? userId + "_meetingId" + : comp.children.meetingName.getView().value, comp.children ); }, @@ -449,9 +455,10 @@ MTComp = withMethodExposing(MTComp, [ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [ new NameConfig("visible", trans("export.visibleDesc")), - new NameConfig("appId", trans("prop.appid")), - new NameConfig("host", trans("prop.appid")), - new NameConfig("participants", trans("prop.participants")), + new NameConfig("appId", trans("meeting.appid")), + new NameConfig("host", trans("meeting.host")), + new NameConfig("participants", trans("meeting.participants")), + new NameConfig("meetingName", trans("meeting.meetingName")), ]); export function agoraClient() { diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 1ba24dc43..74cbb65ea 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -157,8 +157,6 @@ export const en = { showClear: "Show clear button", showSearch: "Searchable", defaultValue: "Default value", - participants: "Participants", - appid: "Application Id", required: "Required field", readOnly: "Read only", readOnlyTooltip: @@ -1439,6 +1437,10 @@ export const en = { meeting: "Meeting Settings", size: "Size", top: "Top", + host: "Host", + participants: "Participants", + appid: "Application Id", + meetingName: "Meeting Name", right: "Right", bottom: "Bottom", videoId: "Video Id", From 34a001eb228c8616972dd61beeeacbfb0a3fd3ff Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Fri, 13 Oct 2023 15:07:45 +0300 Subject: [PATCH 13/20] fixed video component styling --- .../comps/meetingComp/videoMeetingStreamComp.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 5ff3ff8da..170101822 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -62,6 +62,15 @@ const Container = styled.div<{ $style: any }>` ${(props) => props.$style && getStyle(props.$style)} `; +const VideoContainer = styled.video<{ $style: any }>` + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + ${(props) => props.$style && getStyle(props.$style)} +`; + const getStyle = (style: any) => { return css` { @@ -203,11 +212,12 @@ let VideoCompBuilder = (function (props) { {(editorState) => ( - + > + {/* */} )} From c78a54cdd08c8ec980c2af3be0d214c12dbccc80 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Sat, 14 Oct 2023 15:27:37 +0300 Subject: [PATCH 14/20] added video stream controller events --- .../videoMeetingControllerComp.tsx | 258 ++++++++++-------- .../meetingComp/videoMeetingStreamComp.tsx | 180 ++++++------ .../comps/controls/eventHandlerControl.tsx | 93 ++++++- .../packages/lowcoder/src/i18n/locales/en.ts | 5 + 4 files changed, 321 insertions(+), 215 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 69237d0ff..ca8836a73 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -49,8 +49,10 @@ import AgoraRTC, { UID, ILocalVideoTrack, } from "agora-rtc-sdk-ng"; + import { JSONValue } from "@lowcoder-ee/index.sdk"; import { getData } from "../listViewComp/listViewUtils"; +import { meetingStreamChildren } from "./videoMeetingStreamComp"; const EventOptions = [closeEvent] as const; @@ -104,6 +106,7 @@ let audioTrack: IMicrophoneAudioTrack; let videoTrack: ICameraVideoTrack; let screenShareStream: ILocalVideoTrack; let userId: UID | null | undefined; + const turnOnCamera = async (flag?: boolean) => { if (videoTrack) { return videoTrack.setEnabled(flag!); @@ -172,6 +175,9 @@ const joinChannel = async (appId: any, channel: any, token: any) => { isJoined = true; }; +const hostChanged = (users: any) => {}; + + const publishVideo = async (appId: any, channel: any, height: any) => { await turnOnCamera(true); @@ -193,127 +199,145 @@ const publishVideo = async (appId: any, channel: any, height: any) => { } }; +export const meetingControllerChildren = { + visible: booleanExposingStateControl("visible"), + onEvent: eventHandlerControl(EventOptions), + width: StringControl, + height: StringControl, + autoHeight: AutoHeightControl, + style: styleControl(DrawerStyle), + placement: PositionControl, + maskClosable: withDefault(BoolControl, true), + showMask: withDefault(BoolControl, true), + audioControl: booleanExposingStateControl("false"), + videoControl: booleanExposingStateControl("true"), + endCall: booleanExposingStateControl("false"), + sharingScreen: booleanExposingStateControl("false"), + videoSettings: jsonObjectExposingStateControl(""), + videoWidth: numberExposingStateControl("videoWidth", 200), + videoHeight: numberExposingStateControl("videoHeight", 200), + appId: withDefault(StringControl, trans("meeting.appid")), + participants: stateComp([]), + host: stringExposingStateControl("host"), + meetingName: stringExposingStateControl("meetingName"), +}; let MTComp = (function () { - const childrenMap = { - visible: booleanExposingStateControl("visible"), - onEvent: eventHandlerControl(EventOptions), - width: StringControl, - height: StringControl, - autoHeight: AutoHeightControl, - style: styleControl(DrawerStyle), - placement: PositionControl, - maskClosable: withDefault(BoolControl, true), - showMask: withDefault(BoolControl, true), - audioControl: booleanExposingStateControl("false"), - videoControl: booleanExposingStateControl("true"), - endCall: booleanExposingStateControl("false"), - sharingScreen: booleanExposingStateControl("false"), - videoSettings: jsonObjectExposingStateControl(""), - videoWidth: numberExposingStateControl("videoWidth", 200), - videoHeight: numberExposingStateControl("videoHeight", 200), - appId: withDefault(StringControl, trans("meeting.appid")), - participants: stateComp([]), - host: stringExposingStateControl("host"), - meetingName: stringExposingStateControl("meetingName"), - }; - return new ContainerCompBuilder(childrenMap, (props, dispatch) => { - const isTopBom = ["top", "bottom"].includes(props.placement); - const { items, ...otherContainerProps } = props.container; - const userViewMode = useUserViewMode(); - const resizable = !userViewMode && (!isTopBom || !props.autoHeight); - const onResizeStop = useCallback( - ( - e: React.SyntheticEvent, - node: HTMLElement, - size: { width: number; height: number }, - handle: ResizeHandle - ) => { - isTopBom - ? dispatch(changeChildAction("height", size.height, true)) - : dispatch(changeChildAction("width", size.width, true)); - }, - [dispatch, isTopBom] - ); - const [userIds, setUserIds] = useState([]); - - useEffect(() => { - dispatch(changeChildAction("participants", getData(userIds).data, false)); - }, [userIds]); - - useEffect(() => { - client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - setUserIds((userIds: any) => [...userIds, { user: user.uid }]); - }); - client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => { - setUserIds((userIds: any) => - userIds.filter((item: any) => item.user !== user.uid) + return new ContainerCompBuilder( + meetingControllerChildren, + (props, dispatch) => { + const isTopBom = ["top", "bottom"].includes(props.placement); + const { items, ...otherContainerProps } = props.container; + const userViewMode = useUserViewMode(); + const resizable = !userViewMode && (!isTopBom || !props.autoHeight); + const onResizeStop = useCallback( + ( + e: React.SyntheticEvent, + node: HTMLElement, + size: { width: number; height: number }, + handle: ResizeHandle + ) => { + isTopBom + ? dispatch(changeChildAction("height", size.height, true)) + : dispatch(changeChildAction("width", size.width, true)); + }, + [dispatch, isTopBom] + ); + const [userIds, setUserIds] = useState([]); + + useEffect(() => { + dispatch( + changeChildAction("participants", getData(userIds).data, false) ); - }); - }, [client]); - - return ( - - - - document.querySelector(`#${CanvasContainerID}`) || document.body - } - footer={null} - width={transToPxSize(props.width || DEFAULT_SIZE)} - height={ - !props.autoHeight - ? transToPxSize(props.height || DEFAULT_SIZE) - : "" - } - onClose={(e) => { - props.visible.onChange(false); - }} - afterOpenChange={(visible) => { - if (!visible) { - props.onEvent("close"); + }, [userIds]); + + useEffect(() => { + client.on("user-joined", (user: IAgoraRTCRemoteUser) => { + console.log("userData", user); + let userData = { user: user.uid, host: false }; + if (userIds.length == 0) { + userData.host = true; + } else { + userData.host = false; + } + console.log("userData", userData); + + setUserIds((userIds: any) => [...userIds, userData]); + }); + client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => { + let newUsers = userIds.filter((item: any) => item.user !== user.uid); + let hostExists = newUsers.filter((f: any) => f.host === true); + if (hostExists.length == 0 && newUsers.length > 0) { + newUsers[0].host = true; + hostChanged(newUsers); + } + setUserIds(newUsers); + }); + }, [client]); + + return ( + + + + document.querySelector(`#${CanvasContainerID}`) || document.body } - }} - zIndex={Layers.drawer} - maskClosable={props.maskClosable} - mask={props.showMask} - > - { + footer={null} + width={transToPxSize(props.width || DEFAULT_SIZE)} + height={ + !props.autoHeight + ? transToPxSize(props.height || DEFAULT_SIZE) + : "" + } + onClose={(e) => { props.visible.onChange(false); }} + afterOpenChange={(visible) => { + if (!visible) { + props.onEvent("close"); + } + }} + zIndex={Layers.drawer} + maskClosable={props.maskClosable} + mask={props.showMask} > - - - - - - - ); - }) + { + props.visible.onChange(false); + }} + > + + + + + + + ); + } + ) .setPropertyViewFn((children) => ( <>
@@ -422,7 +446,7 @@ MTComp = withMethodExposing(MTComp, [ await publishVideo( comp.children.appId.getView(), comp.children.meetingName.getView().value == "" - ? userId + "_meetingId" + ? "_meetingId" : comp.children.meetingName.getView().value, comp.children ); @@ -430,7 +454,7 @@ MTComp = withMethodExposing(MTComp, [ }, { method: { - name: "endCall", + name: "endMeeting", description: trans("meeting.actionBtnDesc"), params: [], }, diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 170101822..01d3f41cc 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -1,6 +1,5 @@ import { BoolCodeControl } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; -import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; import { IconControl } from "comps/controls/iconControl"; import { CompNameContext, EditorContext, EditorState } from "comps/editorState"; import { withDefault } from "comps/generators"; @@ -29,15 +28,20 @@ import { RefControl } from "comps/controls/refControl"; import { useEffect, useRef } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; -import { client } from "./videoMeetingControllerComp"; +import { + client, + meetingControllerChildren, +} from "./videoMeetingControllerComp"; import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; import { + ButtonEventHandlerControl, + MeetingEventHandlerControl, hiddenPropertyView, + refMethods, stringExposingStateControl, } from "@lowcoder-ee/index.sdk"; -import { BackgroundColorContext } from "@lowcoder-ee/comps/utils/backgroundColorContext"; const FormLabel = styled(CommonBlueLabel)` font-size: 13px; @@ -155,95 +159,105 @@ const typeOptions = [ function isDefault(type?: string) { return !type; } +export const videoShared = () => { + console.log("data"); + +} +export const meetingStreamChildren = { + autoHeight: withDefault(AutoHeightControl, "fixed"), + type: dropdownControl(typeOptions, ""), + // onEvent: ButtonEventHandlerControl, + onEvent: MeetingEventHandlerControl, + disabled: BoolCodeControl, + loading: BoolCodeControl, + form: SelectFormControl, + prefixIcon: IconControl, + suffixIcon: IconControl, + style: ButtonStyleControl, + viewRef: RefControl, + // viewRef: RefControl, + userId: stringExposingStateControl("user id", trans("meeting.userId")), +}; let VideoCompBuilder = (function (props) { - const childrenMap = { - autoHeight: withDefault(AutoHeightControl, "fixed"), - type: dropdownControl(typeOptions, ""), - onEvent: ButtonEventHandlerControl, - disabled: BoolCodeControl, - loading: BoolCodeControl, - form: SelectFormControl, - prefixIcon: IconControl, - suffixIcon: IconControl, - style: ButtonStyleControl, - viewRef: RefControl, - userId: stringExposingStateControl("user id", trans("meeting.userId")), - }; - return new UICompBuilder(childrenMap, (props) => { - const videoRef = useRef(null); - const conRef = useRef(null); + return ( + new UICompBuilder(meetingStreamChildren, (props) => { + const videoRef = useRef(null); + const conRef = useRef(null); + + useEffect(() => { + onResize(); + }, []); - useEffect(() => { - onResize(); - }, []); + const onResize = async () => { + const container = conRef.current; + let videoCo = videoRef.current; + videoCo!.style.height = container?.clientHeight + "px"; + videoCo!.style.width = container?.clientWidth + "px"; + }; + useEffect(() => { + client.on( + "user-published", + async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { + if (mediaType === "video") { + const remoteTrack = await client.subscribe(user, mediaType); + console.log("remoteTrack", remoteTrack); - const onResize = async () => { - const container = conRef.current; - let videoCo = videoRef.current; - videoCo!.style.height = container?.clientHeight + "px"; - videoCo!.style.width = container?.clientWidth + "px"; - }; - useEffect(() => { - client.on( - "user-published", - async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { - if (mediaType === "video") { - const remoteTrack = await client.subscribe(user, mediaType); - let userId = user.uid + ""; - const element = document.getElementById(userId); - if (element) { - console.log("userId", element); - remoteTrack.play(userId); + let userId = user.uid + ""; + const element = document.getElementById(userId); + if (element) { + remoteTrack.play(userId); + } + } + if (mediaType === "audio") { + const remoteTrack = await client.subscribe(user, mediaType); + remoteTrack.play(); } } - if (mediaType === "audio") { - const remoteTrack = await client.subscribe(user, mediaType); - remoteTrack.play(); - } - } - ); - }, [props.userId.value]); - - console.log(props); + ); + }, [props.userId.value]); - return ( - - {(editorState) => ( - - - - {/* */} - - - )} - - ); - }) - .setPropertyViewFn((children) => ( - <> -
- {children.userId.propertyView({ label: trans("meeting.videoId") })} - {children.autoHeight.getPropertyView()} -
-
- {children.onEvent.getPropertyView()} -
-
- {hiddenPropertyView(children)} -
-
- {children.style.getPropertyView()} -
- - )) - .build(); + return ( + + {(editorState) => ( + + + + + + )} + + ); + }) + .setPropertyViewFn((children) => ( + <> +
+ {children.userId.propertyView({ label: trans("meeting.videoId") })} + {children.autoHeight.getPropertyView()} +
+
+ {children.onEvent.getPropertyView()} +
+
+ {hiddenPropertyView(children)} +
+
+ {children.style.getPropertyView()} +
+ + )) + // .setExposeMethodConfigs(refMethods([shareMethod])) + .build() + ); })(); +// interface BaseStreamRef { +// shared: () => void; +// } VideoCompBuilder = class extends VideoCompBuilder { override autoHeight(): boolean { return this.children.autoHeight.getView(); diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx index 426357c92..2ea7e66b7 100644 --- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx @@ -47,7 +47,9 @@ const childrenMap = { handler: ActionSelectorControl, }; -class SingleEventHandlerControl extends simpleMultiComp(childrenMap) { +class SingleEventHandlerControl< + T extends EventConfigsType +> extends simpleMultiComp(childrenMap) { // view is function (eventName: ValueFromOption) => void, representing a named event getView() { const name = this.children.name.getView(); @@ -67,14 +69,18 @@ class SingleEventHandlerControl extends simpleMultiC const children = this.children; const { eventConfigs } = props; - const eventName = eventConfigs.find((x) => x.value === name)?.label?.toString(); + const eventName = eventConfigs + .find((x) => x.value === name) + ?.label?.toString(); let content: ReactNode = null; if (props.inline && eventConfigs.length === 1) { content = (
- {trans("eventHandler.inlineEventTitle", { eventName: eventName?.toLowerCase() ?? "" })} + {trans("eventHandler.inlineEventTitle", { + eventName: eventName?.toLowerCase() ?? "", + })}
{children.handler.propertyView({ label: trans("eventHandler.action"), @@ -124,15 +130,27 @@ class SingleEventHandlerControl extends simpleMultiC const EventHandlerControlPropertyView = (props: { dispatch: DispatchType; - pushAction: (value: any) => CustomListAction; - deleteAction: (index: number) => CustomListAction; + pushAction: ( + value: any + ) => CustomListAction; + deleteAction: ( + index: number + ) => CustomListAction; items: InstanceType[]; inline?: boolean; title?: ReactNode; type?: "query"; eventConfigs: EventConfigsType; }) => { - const { dispatch, pushAction, deleteAction, inline = false, items, eventConfigs, type } = props; + const { + dispatch, + pushAction, + deleteAction, + inline = false, + items, + eventConfigs, + type, + } = props; const editorState = useContext(EditorContext); const [showNewCreate, setShowNewCreate] = useState(false); @@ -149,7 +167,9 @@ const EventHandlerControlPropertyView = (props: { const queryExecHandler = { compType: "executeQuery", comp: { - queryName: editorState?.selectedOrFirstQueryComp()?.children.name.getView(), + queryName: editorState + ?.selectedOrFirstQueryComp() + ?.children.name.getView(), }, }; const messageHandler = { @@ -181,7 +201,9 @@ const EventHandlerControlPropertyView = (props: { ))}
) : ( - {trans("eventHandler.emptyEventHandlers")} + + {trans("eventHandler.emptyEventHandlers")} + ); if (props.inline) { return
{renderItems()}
; @@ -210,7 +232,9 @@ const EventHandlerControlPropertyView = (props: { ); }; -class EventHandlerControl extends list(SingleEventHandlerControl) { +class EventHandlerControl extends list( + SingleEventHandlerControl +) { @memo // @ts-ignore getView() { @@ -227,14 +251,21 @@ class EventHandlerControl extends list(SingleEventHa } isBind(eventName: ValueFromOption) { - return super.getView().some((child) => child.children.name.getView() === eventName); + return super + .getView() + .some((child) => child.children.name.getView() === eventName); } override getPropertyView() { return this.propertyView(); } - propertyView(options?: { inline?: boolean; title?: ReactNode; type?: "query"; eventConfigs: T }) { + propertyView(options?: { + inline?: boolean; + title?: ReactNode; + type?: "query"; + eventConfigs: T; + }) { const title = options?.title ?? trans("eventHandler.eventHandlers"); return controlItem( { filterText: title }, @@ -252,13 +283,20 @@ class EventHandlerControl extends list(SingleEventHa } } -export function eventHandlerControl(eventConfigs?: T, type?: "query") { +export function eventHandlerControl( + eventConfigs?: T, + type?: "query" +) { class EventHandlerTempControl extends EventHandlerControl { getEventNames() { return eventConfigs; } - propertyView(options?: { inline?: boolean; title?: ReactNode; eventConfigs?: T }) { + propertyView(options?: { + inline?: boolean; + title?: ReactNode; + eventConfigs?: T; + }) { return super.propertyView({ ...options, type, @@ -310,6 +348,21 @@ export const mentionEvent: EventConfigType = { value: "mention", description: trans("event.mentionDesc"), }; +export const screenShared: EventConfigType = { + label: trans("meeting.screenShared"), + value: "screenShared", + description: trans("meeting.screenSharedDesc"), +}; +export const cameraView: EventConfigType = { + label: trans("meeting.cameraView"), + value: "cameraView", + description: trans("meeting.cameraViewDesc"), +}; +export const audioMuteUnmute: EventConfigType = { + label: trans("meeting.audioMuteUnmute"), + value: "audioMuteUnmute", + description: trans("meeting.audioMuteUnmute"), +}; export const InputEventHandlerControl = eventHandlerControl([ changeEvent, @@ -318,9 +371,13 @@ export const InputEventHandlerControl = eventHandlerControl([ submitEvent, ] as const); -export const ButtonEventHandlerControl = eventHandlerControl([clickEvent] as const); +export const ButtonEventHandlerControl = eventHandlerControl([ + clickEvent, +] as const); -export const ChangeEventHandlerControl = eventHandlerControl([changeEvent] as const); +export const ChangeEventHandlerControl = eventHandlerControl([ + changeEvent, +] as const); export const SelectEventHandlerControl = eventHandlerControl([ changeEvent, @@ -333,3 +390,9 @@ export const ScannerEventHandlerControl = eventHandlerControl([ successEvent, closeEvent, ] as const); + +export const MeetingEventHandlerControl = eventHandlerControl([ + screenShared, + cameraView, + audioMuteUnmute, +] as const); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 74cbb65ea..eef64917d 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1435,6 +1435,11 @@ export const en = { meeting: { placement: "Meeting placement", meeting: "Meeting Settings", + cameraView: "Camera View", + cameraViewDesc: "Camera View", + screenShared: "Screen Shared", + screenSharedDesc: "Screen Shared", + audioMuteUnmute: "Audio Mute", size: "Size", top: "Top", host: "Host", From 84c9749bf1fe8a0f7d983d8c2d25822bc052d4be Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Sun, 15 Oct 2023 16:11:07 +0200 Subject: [PATCH 15/20] fixed styling for VideoStream Component --- .../src/comps/comps/meetingComp/videoMeetingStreamComp.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 01d3f41cc..f283011b6 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -63,8 +63,7 @@ const Container = styled.div<{ $style: any }>` display: flex; align-items: center; justify-content: center; - ${(props) => props.$style && getStyle(props.$style)} -`; +`; // ${(props) => props.$style && getStyle(props.$style)} - they should be applyed to VideoContainer only const VideoContainer = styled.video<{ $style: any }>` height: 100%; From c278c6dc40446eeecfca445fb5339da359390c3e Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 16 Oct 2023 12:27:53 +0300 Subject: [PATCH 16/20] finished audio/mute event on video stream component --- .../videoMeetingControllerComp.tsx | 39 ++++++------------- .../meetingComp/videoMeetingStreamComp.tsx | 37 +++++++++++------- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index ca8836a73..d7519e001 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -121,6 +121,12 @@ const turnOnMicrophone = async (flag?: boolean) => { } audioTrack = await AgoraRTC.createMicrophoneAudioTrack(); audioTrack.play(); + + if (!flag) { + await client.unpublish(audioTrack); + } else { + await client.publish(audioTrack); + } }; const shareScreen = async (sharing: boolean) => { try { @@ -162,40 +168,20 @@ const leaveChannel = async () => { }; let isJoined = false; -const joinChannel = async (appId: any, channel: any, token: any) => { - if (!channel) { - channel = "react-room"; - } - - if (isJoined) { - await leaveChannel(); - } - console.log("me joining ", userId); - await client.join(appId, channel, token || null, userId); - - isJoined = true; -}; const hostChanged = (users: any) => {}; - - const publishVideo = async (appId: any, channel: any, height: any) => { await turnOnCamera(true); - if (!isJoined) { - await joinChannel(appId, channel, null); - } - + await client.join(appId, channel, null, userId); await client.publish(videoTrack); - const mediaStreamTrack = videoTrack.getMediaStreamTrack(); + const mediaStreamTrack = videoTrack.getMediaStreamTrack(); if (mediaStreamTrack) { const videoSettings = mediaStreamTrack.getSettings(); const videoWidth = videoSettings.width; const videoHeight = videoSettings.height; height.videoWidth.change(videoWidth); height.videoHeight.change(videoHeight); - } else { - console.error("Media stream track not found"); } }; @@ -252,15 +238,12 @@ let MTComp = (function () { useEffect(() => { client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - console.log("userData", user); let userData = { user: user.uid, host: false }; if (userIds.length == 0) { userData.host = true; } else { userData.host = false; } - console.log("userData", userData); - setUserIds((userIds: any) => [...userIds, userData]); }); client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => { @@ -416,9 +399,11 @@ MTComp = withMethodExposing(MTComp, [ description: trans("meeting.actionBtnDesc"), params: [], }, - execute: (comp, values) => { + execute: async (comp, values) => { let value = !comp.children.audioControl.getView().value; - turnOnMicrophone(value); + console.log("turnOnMicrophone", value); + // await audioTrack.setEnabled(value); + await turnOnMicrophone(value); comp.children.audioControl.change(value); }, }, diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 01d3f41cc..043ebe81b 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -28,18 +28,13 @@ import { RefControl } from "comps/controls/refControl"; import { useEffect, useRef } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; -import { - client, - meetingControllerChildren, -} from "./videoMeetingControllerComp"; +import { client } from "./videoMeetingControllerComp"; import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; import { - ButtonEventHandlerControl, MeetingEventHandlerControl, hiddenPropertyView, - refMethods, stringExposingStateControl, } from "@lowcoder-ee/index.sdk"; @@ -156,13 +151,10 @@ const typeOptions = [ value: "submit", }, ] as const; -function isDefault(type?: string) { - return !type; -} + export const videoShared = () => { console.log("data"); - -} +}; export const meetingStreamChildren = { autoHeight: withDefault(AutoHeightControl, "fixed"), type: dropdownControl(typeOptions, ""), @@ -201,8 +193,6 @@ let VideoCompBuilder = (function (props) { async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { if (mediaType === "video") { const remoteTrack = await client.subscribe(user, mediaType); - console.log("remoteTrack", remoteTrack); - let userId = user.uid + ""; const element = document.getElementById(userId); if (element) { @@ -211,10 +201,31 @@ let VideoCompBuilder = (function (props) { } if (mediaType === "audio") { const remoteTrack = await client.subscribe(user, mediaType); + if ( + user.hasAudio && + user.uid + "" != props.userId.value && + props.userId.value != "" + ) { + props.onEvent("audioMuteUnmute"); + } remoteTrack.play(); } } ); + client.on( + "user-unpublished", + (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { + if (mediaType === "audio") { + if ( + !user.hasAudio && + user.uid + "" != props.userId.value && + props.userId.value != "" + ) { + props.onEvent("audioMuteUnmute"); + } + } + } + ); }, [props.userId.value]); return ( From d131b71f0f20ebd9be99bb0929ad9132d16707a5 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 16 Oct 2023 14:10:40 +0300 Subject: [PATCH 17/20] Feat: video toggle event --- .../videoMeetingControllerComp.tsx | 35 +++++++++++-------- .../meetingComp/videoMeetingStreamComp.tsx | 21 ++++++++++- .../comps/controls/eventHandlerControl.tsx | 7 +++- .../packages/lowcoder/src/i18n/locales/en.ts | 1 + 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index d7519e001..6991eb897 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -52,7 +52,6 @@ import AgoraRTC, { import { JSONValue } from "@lowcoder-ee/index.sdk"; import { getData } from "../listViewComp/listViewUtils"; -import { meetingStreamChildren } from "./videoMeetingStreamComp"; const EventOptions = [closeEvent] as const; @@ -151,22 +150,15 @@ const shareScreen = async (sharing: boolean) => { }; const leaveChannel = async () => { if (videoTrack) { - await turnOnCamera(false); await client.unpublish(videoTrack); - videoTrack.stop(); + await turnOnCamera(false); } if (audioTrack) { await turnOnMicrophone(false); - await client.unpublish(audioTrack); - audioTrack.stop(); } - await client.leave(); - window.location.reload(); //FixMe: this reloads the page when user leaves - isJoined = false; }; -let isJoined = false; const hostChanged = (users: any) => {}; @@ -236,6 +228,17 @@ let MTComp = (function () { ); }, [userIds]); + useEffect(() => { + if (props.endCall.value) { + let newUsers = userIds.filter((item: any) => item.user !== userId); + console.log("newUsers", newUsers, userId); + + dispatch( + changeChildAction("participants", getData(newUsers).data, false) + ); + } + }, [props.endCall.value]); + useEffect(() => { client.on("user-joined", (user: IAgoraRTCRemoteUser) => { let userData = { user: user.uid, host: false }; @@ -401,8 +404,6 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { let value = !comp.children.audioControl.getView().value; - console.log("turnOnMicrophone", value); - // await audioTrack.setEnabled(value); await turnOnMicrophone(value); comp.children.audioControl.change(value); }, @@ -413,9 +414,14 @@ MTComp = withMethodExposing(MTComp, [ description: trans("meeting.actionBtnDesc"), params: [], }, - execute: (comp, values) => { + execute: async (comp, values) => { let value = !comp.children.videoControl.getView().value; - turnOnCamera(value); + if (videoTrack) { + videoTrack.setEnabled(value); + } else { + await turnOnCamera(value); + } + comp.children.videoControl.change(value); }, }, @@ -445,9 +451,8 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { let value = !comp.children.endCall.getView().value; - - await leaveChannel(); comp.children.endCall.change(value); + await leaveChannel(); }, }, { diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 76fe5ba6c..7ac21b7b8 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -28,7 +28,10 @@ import { RefControl } from "comps/controls/refControl"; import { useEffect, useRef } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; -import { client } from "./videoMeetingControllerComp"; +import { + client, + meetingControllerChildren, +} from "./videoMeetingControllerComp"; import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; @@ -193,6 +196,13 @@ let VideoCompBuilder = (function (props) { if (mediaType === "video") { const remoteTrack = await client.subscribe(user, mediaType); let userId = user.uid + ""; + if ( + user.hasVideo && + user.uid + "" != props.userId.value && + props.userId.value != "" + ) { + props.onEvent("videoActiveInactive"); + } const element = document.getElementById(userId); if (element) { remoteTrack.play(userId); @@ -223,6 +233,15 @@ let VideoCompBuilder = (function (props) { props.onEvent("audioMuteUnmute"); } } + if (mediaType === "video") { + if ( + !user.hasVideo && + user.uid + "" != props.userId.value && + props.userId.value != "" + ) { + props.onEvent("videoActiveInactive"); + } + } } ); }, [props.userId.value]); diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx index 2ea7e66b7..6f0c3e389 100644 --- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx @@ -363,7 +363,11 @@ export const audioMuteUnmute: EventConfigType = { value: "audioMuteUnmute", description: trans("meeting.audioMuteUnmute"), }; - +export const videoActiveInactive: EventConfigType = { + label: trans("meeting.videoActiveInactive"), + value: "videoActiveInactive", + description: trans("meeting.videoActiveInactive"), +}; export const InputEventHandlerControl = eventHandlerControl([ changeEvent, focusEvent, @@ -395,4 +399,5 @@ export const MeetingEventHandlerControl = eventHandlerControl([ screenShared, cameraView, audioMuteUnmute, + videoActiveInactive, ] as const); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index eef64917d..654e4a29b 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1440,6 +1440,7 @@ export const en = { screenShared: "Screen Shared", screenSharedDesc: "Screen Shared", audioMuteUnmute: "Audio Mute", + videoActiveInactive: "Video Active Inactive", size: "Size", top: "Top", host: "Host", From 2dd01e53c6060afba91b896c5132301eaac0bdac Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Mon, 16 Oct 2023 14:17:21 +0300 Subject: [PATCH 18/20] Feat: video click event --- .../src/comps/comps/meetingComp/videoMeetingStreamComp.tsx | 1 + .../lowcoder/src/comps/controls/eventHandlerControl.tsx | 6 ++++++ client/packages/lowcoder/src/i18n/locales/en.ts | 1 + 3 files changed, 8 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index 7ac21b7b8..d3166145d 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -252,6 +252,7 @@ let VideoCompBuilder = (function (props) { props.onEvent("videoClicked")} ref={videoRef} $style={props.style} id={props.userId.value} diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx index 6f0c3e389..e7c216bb6 100644 --- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx @@ -368,6 +368,11 @@ export const videoActiveInactive: EventConfigType = { value: "videoActiveInactive", description: trans("meeting.videoActiveInactive"), }; +export const videoClicked: EventConfigType = { + label: trans("meeting.videoClicked"), + value: "videoClicked", + description: trans("meeting.videoClicked"), +}; export const InputEventHandlerControl = eventHandlerControl([ changeEvent, focusEvent, @@ -400,4 +405,5 @@ export const MeetingEventHandlerControl = eventHandlerControl([ cameraView, audioMuteUnmute, videoActiveInactive, + videoClicked, ] as const); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 654e4a29b..5e023827c 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1440,6 +1440,7 @@ export const en = { screenShared: "Screen Shared", screenSharedDesc: "Screen Shared", audioMuteUnmute: "Audio Mute", + videoClicked: "Video Clicked", videoActiveInactive: "Video Active Inactive", size: "Size", top: "Top", From 03b21f05fc147a4a5f61f45e9d296d87048a62f4 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Tue, 17 Oct 2023 16:44:16 +0300 Subject: [PATCH 19/20] refactored/cleaned the code --- .../videoMeetingControllerComp.tsx | 31 ++-- .../meetingComp/videoMeetingStreamComp.tsx | 151 +++++++++--------- .../comps/controls/eventHandlerControl.tsx | 40 ++--- .../packages/lowcoder/src/i18n/locales/en.ts | 7 +- 4 files changed, 120 insertions(+), 109 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 6991eb897..2c5809d43 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -190,13 +190,14 @@ export const meetingControllerChildren = { audioControl: booleanExposingStateControl("false"), videoControl: booleanExposingStateControl("true"), endCall: booleanExposingStateControl("false"), - sharingScreen: booleanExposingStateControl("false"), + sharing: booleanExposingStateControl("false"), videoSettings: jsonObjectExposingStateControl(""), videoWidth: numberExposingStateControl("videoWidth", 200), videoHeight: numberExposingStateControl("videoHeight", 200), appId: withDefault(StringControl, trans("meeting.appid")), participants: stateComp([]), - host: stringExposingStateControl("host"), + usersScreenShared: stateComp([]), + localUser: jsonObjectExposingStateControl(""), meetingName: stringExposingStateControl("meetingName"), }; let MTComp = (function () { @@ -231,8 +232,6 @@ let MTComp = (function () { useEffect(() => { if (props.endCall.value) { let newUsers = userIds.filter((item: any) => item.user !== userId); - console.log("newUsers", newUsers, userId); - dispatch( changeChildAction("participants", getData(newUsers).data, false) ); @@ -241,7 +240,11 @@ let MTComp = (function () { useEffect(() => { client.on("user-joined", (user: IAgoraRTCRemoteUser) => { - let userData = { user: user.uid, host: false }; + let userData = { + user: user.uid, + host: false, + audiostatus: user.hasVideo, + }; if (userIds.length == 0) { userData.host = true; } else { @@ -391,9 +394,9 @@ MTComp = withMethodExposing(MTComp, [ params: [], }, execute: async (comp, values) => { - let sharing = !comp.children.sharingScreen.getView().value; - comp.children.sharingScreen.change(sharing); + let sharing = !comp.children.sharing.getView().value; await shareScreen(sharing); + comp.children.sharing.change(sharing); }, }, { @@ -404,6 +407,11 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { let value = !comp.children.audioControl.getView().value; + let localUserData = comp.children.localUser.change({ + user: userId + "", + audiostatus: value, + }); + console.log(localUserData); await turnOnMicrophone(value); comp.children.audioControl.change(value); }, @@ -421,7 +429,7 @@ MTComp = withMethodExposing(MTComp, [ } else { await turnOnCamera(value); } - + comp.children.videoControl.change(value); }, }, @@ -433,7 +441,10 @@ MTComp = withMethodExposing(MTComp, [ }, execute: async (comp, values) => { userId = Math.floor(100000 + Math.random() * 900000); - comp.children.host.change(userId + ""); + comp.children.localUser.change({ + user: userId + "", + audiostatus: false, + }); await publishVideo( comp.children.appId.getView(), comp.children.meetingName.getView().value == "" @@ -470,7 +481,7 @@ MTComp = withMethodExposing(MTComp, [ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [ new NameConfig("visible", trans("export.visibleDesc")), new NameConfig("appId", trans("meeting.appid")), - new NameConfig("host", trans("meeting.host")), + new NameConfig("localUser", trans("meeting.host")), new NameConfig("participants", trans("meeting.participants")), new NameConfig("meetingName", trans("meeting.meetingName")), ]); diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx index d3166145d..d468b637d 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx @@ -25,12 +25,11 @@ import { IForm } from "../formComp/formDataConstants"; import { SimpleNameComp } from "../simpleNameComp"; import { ButtonStyleControl } from "./videobuttonCompConstants"; import { RefControl } from "comps/controls/refControl"; -import { useEffect, useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import { AutoHeightControl } from "comps/controls/autoHeightControl"; import { client, - meetingControllerChildren, } from "./videoMeetingControllerComp"; import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; @@ -61,8 +60,7 @@ const Container = styled.div<{ $style: any }>` display: flex; align-items: center; justify-content: center; -`; // ${(props) => props.$style && getStyle(props.$style)} - they should be applyed to VideoContainer only - +`; const VideoContainer = styled.video<{ $style: any }>` height: 100%; width: 100%; @@ -154,13 +152,9 @@ const typeOptions = [ }, ] as const; -export const videoShared = () => { - console.log("data"); -}; export const meetingStreamChildren = { autoHeight: withDefault(AutoHeightControl, "fixed"), type: dropdownControl(typeOptions, ""), - // onEvent: ButtonEventHandlerControl, onEvent: MeetingEventHandlerControl, disabled: BoolCodeControl, loading: BoolCodeControl, @@ -169,27 +163,28 @@ export const meetingStreamChildren = { suffixIcon: IconControl, style: ButtonStyleControl, viewRef: RefControl, - // viewRef: RefControl, - userId: stringExposingStateControl("user id", trans("meeting.userId")), + userId: stringExposingStateControl(""), }; let VideoCompBuilder = (function (props) { - return ( - new UICompBuilder(meetingStreamChildren, (props) => { - const videoRef = useRef(null); - const conRef = useRef(null); + return new UICompBuilder(meetingStreamChildren, (props) => { + const videoRef = useRef(null); + const conRef = useRef(null); + const [userId, setUserId] = useState(); - useEffect(() => { - onResize(); - }, []); + useEffect(() => { + onResize(); + }, []); - const onResize = async () => { - const container = conRef.current; - let videoCo = videoRef.current; - videoCo!.style.height = container?.clientHeight + "px"; - videoCo!.style.width = container?.clientWidth + "px"; - }; - useEffect(() => { + const onResize = async () => { + const container = conRef.current; + let videoCo = videoRef.current; + videoCo!.style.height = container?.clientHeight + "px"; + videoCo!.style.width = container?.clientWidth + "px"; + }; + useEffect(() => { + if (props.userId.value !== "") { + let userData = JSON.parse(props.userId?.value); client.on( "user-published", async (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => { @@ -198,10 +193,10 @@ let VideoCompBuilder = (function (props) { let userId = user.uid + ""; if ( user.hasVideo && - user.uid + "" != props.userId.value && - props.userId.value != "" + user.uid + "" != userData.user && + userData.user != "" ) { - props.onEvent("videoActiveInactive"); + props.onEvent("videoOn"); } const element = document.getElementById(userId); if (element) { @@ -212,10 +207,12 @@ let VideoCompBuilder = (function (props) { const remoteTrack = await client.subscribe(user, mediaType); if ( user.hasAudio && - user.uid + "" != props.userId.value && - props.userId.value != "" + user.uid + "" != userData.user && + userData.user != "" ) { - props.onEvent("audioMuteUnmute"); + userData.audiostatus = user.hasVideo; + + props.onEvent("audioUnmuted"); } remoteTrack.play(); } @@ -227,67 +224,67 @@ let VideoCompBuilder = (function (props) { if (mediaType === "audio") { if ( !user.hasAudio && - user.uid + "" != props.userId.value && - props.userId.value != "" + user.uid + "" != userData.user && + userData.user != "" ) { - props.onEvent("audioMuteUnmute"); + userData.audiostatus = user.hasVideo; + props.onEvent("audioMuted"); } } if (mediaType === "video") { if ( !user.hasVideo && - user.uid + "" != props.userId.value && - props.userId.value != "" + user.uid + "" != userData.user && + userData.user != "" ) { - props.onEvent("videoActiveInactive"); + props.onEvent("videoOff"); } } } ); - }, [props.userId.value]); + setUserId(userData.user); + } + }, [props.userId.value]); - return ( - - {(editorState) => ( - - - props.onEvent("videoClicked")} - ref={videoRef} - $style={props.style} - id={props.userId.value} - > - - - )} - - ); - }) - .setPropertyViewFn((children) => ( - <> -
- {children.userId.propertyView({ label: trans("meeting.videoId") })} - {children.autoHeight.getPropertyView()} -
-
- {children.onEvent.getPropertyView()} -
-
- {hiddenPropertyView(children)} -
-
- {children.style.getPropertyView()} -
- - )) - // .setExposeMethodConfigs(refMethods([shareMethod])) - .build() - ); + + + return ( + + {(editorState) => ( + + + props.onEvent("videoClicked")} + ref={videoRef} + $style={props.style} + id={userId} + > + + + )} + + ); + }) + .setPropertyViewFn((children) => ( + <> +
+ {children.userId.propertyView({ label: trans("meeting.videoId") })} + {children.autoHeight.getPropertyView()} +
+
+ {children.onEvent.getPropertyView()} +
+
+ {hiddenPropertyView(children)} +
+
+ {children.style.getPropertyView()} +
+ + )) + .build(); })(); -// interface BaseStreamRef { -// shared: () => void; -// } VideoCompBuilder = class extends VideoCompBuilder { override autoHeight(): boolean { return this.children.autoHeight.getView(); diff --git a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx index e7c216bb6..29b3093de 100644 --- a/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx @@ -348,25 +348,25 @@ export const mentionEvent: EventConfigType = { value: "mention", description: trans("event.mentionDesc"), }; -export const screenShared: EventConfigType = { - label: trans("meeting.screenShared"), - value: "screenShared", - description: trans("meeting.screenSharedDesc"), +export const audioUnmuted: EventConfigType = { + label: trans("meeting.audioUnmuted"), + value: "audioUnmuted", + description: trans("meeting.audioUnmuted"), }; -export const cameraView: EventConfigType = { - label: trans("meeting.cameraView"), - value: "cameraView", - description: trans("meeting.cameraViewDesc"), +export const audioMuted: EventConfigType = { + label: trans("meeting.audioMuted"), + value: "audioMuted", + description: trans("meeting.audioMuted"), }; -export const audioMuteUnmute: EventConfigType = { - label: trans("meeting.audioMuteUnmute"), - value: "audioMuteUnmute", - description: trans("meeting.audioMuteUnmute"), +export const videoOff: EventConfigType = { + label: trans("meeting.videoOff"), + value: "videoOff", + description: trans("meeting.videoOff"), }; -export const videoActiveInactive: EventConfigType = { - label: trans("meeting.videoActiveInactive"), - value: "videoActiveInactive", - description: trans("meeting.videoActiveInactive"), +export const videoOn: EventConfigType = { + label: trans("meeting.videoOn"), + value: "videoOn", + description: trans("meeting.videoOn"), }; export const videoClicked: EventConfigType = { label: trans("meeting.videoClicked"), @@ -401,9 +401,9 @@ export const ScannerEventHandlerControl = eventHandlerControl([ ] as const); export const MeetingEventHandlerControl = eventHandlerControl([ - screenShared, - cameraView, - audioMuteUnmute, - videoActiveInactive, + audioMuted, + audioUnmuted, + videoOff, + videoOn, videoClicked, ] as const); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 5e023827c..2869d3183 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1439,9 +1439,11 @@ export const en = { cameraViewDesc: "Camera View", screenShared: "Screen Shared", screenSharedDesc: "Screen Shared", - audioMuteUnmute: "Audio Mute", + audioUnmuted: "Audio Unmuted", + audioMuted: "Audio Muted", videoClicked: "Video Clicked", - videoActiveInactive: "Video Active Inactive", + videoOff: "Video Off", + videoOn: "Video On", size: "Size", top: "Top", host: "Host", @@ -1451,6 +1453,7 @@ export const en = { right: "Right", bottom: "Bottom", videoId: "Video Id", + audioStatus: "audio status", left: "Left", widthTooltip: "Number or percentage, e.g. 520, 60%", heightTooltip: "Number, e.g. 378", From 742009597b0bd085a3c837597cd481dae48e6023 Mon Sep 17 00:00:00 2001 From: freddysundowner Date: Wed, 18 Oct 2023 14:30:02 +0300 Subject: [PATCH 20/20] Fix: audio echo on the local user --- .../src/comps/comps/meetingComp/videoMeetingControllerComp.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx index 2c5809d43..11dc31d65 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx @@ -119,7 +119,7 @@ const turnOnMicrophone = async (flag?: boolean) => { return audioTrack.setEnabled(flag!); } audioTrack = await AgoraRTC.createMicrophoneAudioTrack(); - audioTrack.play(); + // audioTrack.play(); if (!flag) { await client.unpublish(audioTrack);