@vunk/plus 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/components/SendOutlined.mjs +1319 -0
  2. package/components/avatar/index.d.ts +4 -0
  3. package/components/avatar/index.mjs +49 -0
  4. package/components/avatar/src/ctx.d.ts +18 -0
  5. package/components/avatar/src/index.vue.d.ts +180 -0
  6. package/components/avatar/src/types.d.ts +1 -0
  7. package/components/monaco-editor/index.mjs +9 -1
  8. package/components/recorder-button/index.css +72 -0
  9. package/components/recorder-button/index.d.ts +4 -0
  10. package/components/recorder-button/index.mjs +319 -0
  11. package/components/recorder-button/src/ctx.d.ts +19 -0
  12. package/components/recorder-button/src/index.vue.d.ts +309 -0
  13. package/components/recorder-button/src/speech-to-text.d.ts +1 -0
  14. package/components/recorder-button/src/types.d.ts +6 -0
  15. package/components/sender/index.css +29 -0
  16. package/components/sender/index.d.ts +4 -0
  17. package/components/sender/index.mjs +172 -0
  18. package/components/sender/src/ctx.d.ts +21 -0
  19. package/components/sender/src/index.vue.d.ts +484 -0
  20. package/components/sender/src/types.d.ts +1 -0
  21. package/components/speech-button/index.css +10 -0
  22. package/components/speech-button/index.d.ts +4 -0
  23. package/components/speech-button/index.mjs +131 -0
  24. package/components/speech-button/src/RecordingIcon.vue.d.ts +2 -0
  25. package/components/speech-button/src/ctx.d.ts +10 -0
  26. package/components/speech-button/src/index.vue.d.ts +22 -0
  27. package/components/speech-button/src/types.d.ts +1 -0
  28. package/components/table-columns/src/ctx.d.ts +4 -4
  29. package/components/table-columns/src/el-ctx.d.ts +5 -5
  30. package/components/table-columns/src/index.vue.d.ts +21 -21
  31. package/components/tables-v1/src/ctx.d.ts +24 -24
  32. package/components/tables-v1/src/el-ctx.d.ts +10 -10
  33. package/components/tables-v1/src/index.vue.d.ts +103 -103
  34. package/components/tables-v1-checkbox/src/ctx.d.ts +22 -22
  35. package/components/tables-v1-checkbox/src/index.vue.d.ts +182 -170
  36. package/components/vditor/src/index.vue.d.ts +5 -5
  37. package/composables/recorder/index.d.ts +15 -0
  38. package/composables/recorder/index.mjs +14478 -0
  39. package/index.css +114 -0
  40. package/package.json +30 -1
@@ -0,0 +1,4 @@
1
+ import VkAvatar from './src/index.vue';
2
+ export * as __VkAvatar from './src/types';
3
+ export { VkAvatar, };
4
+ export default VkAvatar;
@@ -0,0 +1,49 @@
1
+ import { ElAvatar } from 'element-plus';
2
+ import { defineComponent, resolveComponent, openBlock, createBlock, normalizeStyle, withCtx, renderSlot } from 'vue';
3
+ import { _ as _export_sfc } from '../_plugin-vue_export-helper.mjs';
4
+
5
+ const props = {
6
+ background: {
7
+ default: "transparent"
8
+ },
9
+ color: {
10
+ default: "currentColor"
11
+ }
12
+ };
13
+ const emits = {};
14
+
15
+ var _sfc_main = defineComponent({
16
+ name: "VkAvatar",
17
+ components: {
18
+ ElAvatar
19
+ },
20
+ props,
21
+ emits
22
+ });
23
+
24
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
25
+ const _component_ElAvatar = resolveComponent("ElAvatar");
26
+ return openBlock(), createBlock(_component_ElAvatar, {
27
+ style: normalizeStyle({
28
+ background: _ctx.background,
29
+ color: _ctx.color
30
+ })
31
+ }, {
32
+ default: withCtx(() => [
33
+ renderSlot(_ctx.$slots, "default")
34
+ ]),
35
+ _: 3
36
+ /* FORWARDED */
37
+ }, 8, ["style"]);
38
+ }
39
+ var VkAvatar = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "/home/runner/work/vunk-plus/vunk-plus/packages/components/avatar/src/index.vue"]]);
40
+
41
+ var types = /*#__PURE__*/Object.freeze({
42
+ __proto__: null
43
+ });
44
+
45
+ VkAvatar.install = (app) => {
46
+ app.component(VkAvatar.name || "VkAvatar", VkAvatar);
47
+ };
48
+
49
+ export { VkAvatar, types as __VkAvatar, VkAvatar as default };
@@ -0,0 +1,18 @@
1
+ export declare const props: {
2
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
3
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
4
+ readonly icon: {
5
+ readonly type: import("vue").PropType<unknown>;
6
+ readonly required: false;
7
+ readonly validator: (val: unknown) => boolean;
8
+ __epPropKey: true;
9
+ };
10
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
11
+ readonly alt: StringConstructor;
12
+ readonly srcSet: StringConstructor;
13
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => ObjectFitProperty) | ((new (...args: any[]) => any) | (() => ObjectFitProperty))[], unknown, unknown, "cover", boolean>;
14
+ } & {
15
+ background: never;
16
+ color: never;
17
+ };
18
+ export declare const emits: {};
@@ -0,0 +1,180 @@
1
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
3
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
4
+ readonly icon: {
5
+ readonly type: import("vue").PropType<unknown>;
6
+ readonly required: false;
7
+ readonly validator: (val: unknown) => boolean;
8
+ __epPropKey: true;
9
+ };
10
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
11
+ readonly alt: StringConstructor;
12
+ readonly srcSet: StringConstructor;
13
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => ObjectFitProperty) | ((new (...args: any[]) => any) | (() => ObjectFitProperty))[], unknown, unknown, "cover", boolean>;
14
+ } & {
15
+ background: never;
16
+ color: never;
17
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
18
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
19
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
20
+ readonly icon: {
21
+ readonly type: import("vue").PropType<unknown>;
22
+ readonly required: false;
23
+ readonly validator: (val: unknown) => boolean;
24
+ __epPropKey: true;
25
+ };
26
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
27
+ readonly alt: StringConstructor;
28
+ readonly srcSet: StringConstructor;
29
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => ObjectFitProperty) | ((new (...args: any[]) => any) | (() => ObjectFitProperty))[], unknown, unknown, "cover", boolean>;
30
+ } & {
31
+ background: never;
32
+ color: never;
33
+ }>> & Readonly<{}>, {
34
+ readonly size: import("element-plus").ButtonType<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number>;
35
+ readonly shape: import("element-plus").ButtonType<StringConstructor, "circle" | "square", unknown>;
36
+ readonly src: string;
37
+ readonly fit: any;
38
+ }, {}, {
39
+ ElAvatar: import("element-plus/es/utils").SFCWithInstall<import("vue").DefineComponent<{
40
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
41
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
42
+ readonly icon: {
43
+ readonly type: import("vue").PropType<unknown>;
44
+ readonly required: false;
45
+ readonly validator: (val: unknown) => boolean;
46
+ __epPropKey: true;
47
+ };
48
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
49
+ readonly alt: StringConstructor;
50
+ readonly srcSet: StringConstructor;
51
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => any) | ((new (...args: any[]) => any) | (() => any))[], unknown, unknown, "cover", boolean>;
52
+ }, {
53
+ props: Readonly<import("@vue/shared").LooseRequired<Readonly<import("vue").ExtractPropTypes<{
54
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
55
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
56
+ readonly icon: {
57
+ readonly type: import("vue").PropType<unknown>;
58
+ readonly required: false;
59
+ readonly validator: (val: unknown) => boolean;
60
+ __epPropKey: true;
61
+ };
62
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
63
+ readonly alt: StringConstructor;
64
+ readonly srcSet: StringConstructor;
65
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => any) | ((new (...args: any[]) => any) | (() => any))[], unknown, unknown, "cover", boolean>;
66
+ }>> & {
67
+ onError?: (evt: Event) => any;
68
+ }>>;
69
+ emit: (event: "error", evt: Event) => void;
70
+ ns: {
71
+ namespace: import("vue").ComputedRef<string>;
72
+ b: (blockSuffix?: string) => string;
73
+ e: (element?: string) => string;
74
+ m: (modifier?: string) => string;
75
+ be: (blockSuffix?: string, element?: string) => string;
76
+ em: (element?: string, modifier?: string) => string;
77
+ bm: (blockSuffix?: string, modifier?: string) => string;
78
+ bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
79
+ is: {
80
+ (name: string, state: boolean): string;
81
+ (name: string): string;
82
+ };
83
+ cssVar: (object: Record<string, string>) => Record<string, string>;
84
+ cssVarName: (name: string) => string;
85
+ cssVarBlock: (object: Record<string, string>) => Record<string, string>;
86
+ cssVarBlockName: (name: string) => string;
87
+ };
88
+ hasLoadError: import("vue").Ref<boolean, boolean>;
89
+ avatarClass: import("vue").ComputedRef<string[]>;
90
+ sizeStyle: import("vue").ComputedRef<import("vue").CSSProperties>;
91
+ fitStyle: import("vue").ComputedRef<import("vue").CSSProperties>;
92
+ handleError: (e: Event) => void;
93
+ ElIcon: import("element-plus/es/utils").SFCWithInstall<import("vue").DefineComponent<{
94
+ readonly size: {
95
+ readonly type: import("vue").PropType<import("element-plus").ButtonType<(new (...args: any[]) => string | number) | (() => string | number) | ((new (...args: any[]) => string | number) | (() => string | number))[], unknown, unknown>>;
96
+ readonly required: false;
97
+ readonly validator: (val: unknown) => boolean;
98
+ __epPropKey: true;
99
+ };
100
+ readonly color: {
101
+ readonly type: import("vue").PropType<string>;
102
+ readonly required: false;
103
+ readonly validator: (val: unknown) => boolean;
104
+ __epPropKey: true;
105
+ };
106
+ }, {
107
+ props: Readonly<import("@vue/shared").LooseRequired<Readonly<import("vue").ExtractPropTypes<{
108
+ readonly size: {
109
+ readonly type: import("vue").PropType<import("element-plus").ButtonType<(new (...args: any[]) => string | number) | (() => string | number) | ((new (...args: any[]) => string | number) | (() => string | number))[], unknown, unknown>>;
110
+ readonly required: false;
111
+ readonly validator: (val: unknown) => boolean;
112
+ __epPropKey: true;
113
+ };
114
+ readonly color: {
115
+ readonly type: import("vue").PropType<string>;
116
+ readonly required: false;
117
+ readonly validator: (val: unknown) => boolean;
118
+ __epPropKey: true;
119
+ };
120
+ }>> & {
121
+ [x: `on${string}`]: ((...args: any[]) => any) | ((...args: unknown[]) => any);
122
+ }>>;
123
+ ns: {
124
+ namespace: import("vue").ComputedRef<string>;
125
+ b: (blockSuffix?: string) => string;
126
+ e: (element?: string) => string;
127
+ m: (modifier?: string) => string;
128
+ be: (blockSuffix?: string, element?: string) => string;
129
+ em: (element?: string, modifier?: string) => string;
130
+ bm: (blockSuffix?: string, modifier?: string) => string;
131
+ bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
132
+ is: {
133
+ (name: string, state: boolean): string;
134
+ (name: string): string;
135
+ };
136
+ cssVar: (object: Record<string, string>) => Record<string, string>;
137
+ cssVarName: (name: string) => string;
138
+ cssVarBlock: (object: Record<string, string>) => Record<string, string>;
139
+ cssVarBlockName: (name: string) => string;
140
+ };
141
+ style: import("vue").ComputedRef<import("vue").CSSProperties>;
142
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
143
+ readonly size: {
144
+ readonly type: import("vue").PropType<import("element-plus").ButtonType<(new (...args: any[]) => string | number) | (() => string | number) | ((new (...args: any[]) => string | number) | (() => string | number))[], unknown, unknown>>;
145
+ readonly required: false;
146
+ readonly validator: (val: unknown) => boolean;
147
+ __epPropKey: true;
148
+ };
149
+ readonly color: {
150
+ readonly type: import("vue").PropType<string>;
151
+ readonly required: false;
152
+ readonly validator: (val: unknown) => boolean;
153
+ __epPropKey: true;
154
+ };
155
+ }>>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>> & Record<string, any>;
156
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
157
+ error: (evt: Event) => boolean;
158
+ }, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
159
+ readonly size: import("element-plus/es/utils").EpPropFinalized<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number, "", boolean>;
160
+ readonly shape: import("element-plus/es/utils").EpPropFinalized<StringConstructor, "circle" | "square", unknown, "circle", boolean>;
161
+ readonly icon: {
162
+ readonly type: import("vue").PropType<unknown>;
163
+ readonly required: false;
164
+ readonly validator: (val: unknown) => boolean;
165
+ __epPropKey: true;
166
+ };
167
+ readonly src: import("element-plus/es/utils").EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
168
+ readonly alt: StringConstructor;
169
+ readonly srcSet: StringConstructor;
170
+ readonly fit: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => any) | (() => any) | ((new (...args: any[]) => any) | (() => any))[], unknown, unknown, "cover", boolean>;
171
+ }>> & {
172
+ onError?: (evt: Event) => any;
173
+ }, {
174
+ readonly size: import("element-plus").ButtonType<readonly [NumberConstructor, StringConstructor], "" | "default" | "small" | "large", number>;
175
+ readonly shape: import("element-plus").ButtonType<StringConstructor, "circle" | "square", unknown>;
176
+ readonly src: string;
177
+ readonly fit: any;
178
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>> & Record<string, any>;
179
+ }, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
180
+ export default _default;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { watchPausable } from '@vueuse/core';
2
2
  import { editor } from 'monaco-editor';
3
- import { defineComponent, ref, onMounted, nextTick, watchEffect, openBlock, createElementBlock } from 'vue';
3
+ import { defineComponent, ref, onMounted, nextTick, watchEffect, onBeforeUnmount, openBlock, createElementBlock } from 'vue';
4
4
  import { bindPropsFactory, onEmitsFactory } from '@vunk/core/shared/utils-vue';
5
5
  import { _ as _export_sfc } from '../_plugin-vue_export-helper.mjs';
6
6
 
@@ -61,6 +61,14 @@ var _sfc_main = defineComponent({
61
61
  readOnly: props2.readOnly
62
62
  });
63
63
  });
64
+ const resizeObserver = new ResizeObserver(() => {
65
+ editor$1.layout();
66
+ });
67
+ resizeObserver.observe(editorNode.value);
68
+ onBeforeUnmount(() => {
69
+ resizeObserver.disconnect();
70
+ editor$1.dispose();
71
+ });
64
72
  });
65
73
  return {
66
74
  editorNode
@@ -0,0 +1,72 @@
1
+ .sk-recorder-container {
2
+ position: relative;
3
+ }
4
+ .sk-recorder-button {
5
+ position: relative;
6
+ width: 100%;
7
+ touch-action: none;
8
+ user-select: none;
9
+ }
10
+ .recording-mask {
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ right: 0;
15
+ bottom: 0;
16
+ background: rgba(0, 0, 0, 0.6);
17
+ z-index: 1000;
18
+ display: flex;
19
+ flex-direction: column;
20
+ justify-content: space-between;
21
+ pointer-events: none;
22
+ }
23
+ .action-buttons {
24
+ pointer-events: auto;
25
+ display: flex;
26
+ justify-content: space-between;
27
+ padding: 20px 40px;
28
+ margin-bottom: 100px;
29
+ }
30
+ .cancel-btn, .text-btn {
31
+ display: flex;
32
+ flex-direction: column;
33
+ align-items: center;
34
+ color: white;
35
+ }
36
+ .btn-icon {
37
+ width: 60px; /* 增大按钮尺寸 */
38
+ height: 60px;
39
+ background: rgba(0, 0, 0, 0.4);
40
+ border-radius: 50%;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ font-size: 28px;
45
+ margin-bottom: 8px;
46
+ }
47
+ .cancel-btn.active .btn-icon {
48
+ background: var(--el-color-danger);
49
+ }
50
+ .text-btn.active .btn-icon {
51
+ background: var(--el-color-primary);
52
+ }
53
+ .btn-text {
54
+ font-size: 14px;
55
+ }
56
+ .recording-tip {
57
+ flex: 1;
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: center;
61
+ justify-content: center;
62
+ padding-bottom: 100px; /* 向上移动一些 */
63
+ color: white;
64
+ }
65
+ .wave-container {
66
+ width: 160px; /* 增大波形显示区域 */
67
+ height: 100px;
68
+ margin-bottom: 20px;
69
+ }
70
+ .tip-text {
71
+ font-size: 14px;
72
+ }
@@ -0,0 +1,4 @@
1
+ import VkRecorderButton from './src/index.vue';
2
+ export * as __VkRecorderButton from './src/types';
3
+ export { VkRecorderButton, };
4
+ export default VkRecorderButton;
@@ -0,0 +1,319 @@
1
+ import { ElButton, ElMessage } from 'element-plus';
2
+ import Recorder from 'recorder-core';
3
+ import { defineComponent, ref, shallowRef, onUnmounted, resolveComponent, openBlock, createElementBlock, createCommentVNode, createElementVNode, toDisplayString, normalizeClass, createVNode, mergeProps, withCtx } from 'vue';
4
+ import 'recorder-core/src/engine/mp3';
5
+ import 'recorder-core/src/engine/wav';
6
+ import 'recorder-core/src/engine/mp3-engine';
7
+ import 'recorder-core/src/extensions/waveview';
8
+ import 'recorder-core/src/app-support/app';
9
+ import { _ as _export_sfc } from '../_plugin-vue_export-helper.mjs';
10
+
11
+ const props = {
12
+ speenchToTextUrl: {
13
+ type: String,
14
+ default: "http://localhost:3000/speech-to-text"
15
+ },
16
+ /**
17
+ * 自定义转为文本区域事件
18
+ */
19
+ onTextZone: {
20
+ type: Function,
21
+ default: void 0
22
+ }
23
+ };
24
+ const emits = {
25
+ submitText: (text) => typeof text === "string",
26
+ submit: (_) => true
27
+ };
28
+
29
+ async function speechToText(url, blob) {
30
+ const formData = new FormData();
31
+ formData.append("file", blob, "audio.wav");
32
+ const response = await fetch(url, {
33
+ method: "POST",
34
+ body: formData
35
+ });
36
+ if (!response.ok) {
37
+ throw new Error("Speech to text failed");
38
+ }
39
+ const result = await response.json();
40
+ return result.text;
41
+ }
42
+
43
+ const LONG_PRESS_DURATION = 100;
44
+ var _sfc_main = defineComponent({
45
+ name: "VkRecorderButton",
46
+ components: {
47
+ ElButton
48
+ },
49
+ props,
50
+ emits,
51
+ setup(props2, { emit }) {
52
+ const supported = ref(false);
53
+ const recording = ref(false);
54
+ const recordingNode = ref();
55
+ const wave = shallowRef();
56
+ const blobUrl = ref("");
57
+ let pressTimer = null;
58
+ const rec = new Recorder({
59
+ // mp3格式,指定采样率hz、比特率kbps
60
+ type: "wav",
61
+ sampleRate: 16e3,
62
+ bitRate: 16,
63
+ onProcess
64
+ });
65
+ const recOpen = () => {
66
+ return new Promise((resolve, reject) => {
67
+ rec.open(() => {
68
+ supported.value = true;
69
+ if (Recorder.WaveView) {
70
+ wave.value = Recorder.WaveView({
71
+ elem: recordingNode.value
72
+ });
73
+ }
74
+ resolve(true);
75
+ }, (msg, isUserNotAllow) => {
76
+ ElMessage.error(`${isUserNotAllow ? "\u7528\u6237\u672A\u6388\u6743, " : ""}\u65E0\u6CD5\u5F55\u97F3:${msg}`);
77
+ reject(new Error(msg));
78
+ });
79
+ });
80
+ };
81
+ const startRecording = async () => {
82
+ await recOpen();
83
+ if (!supported.value)
84
+ return;
85
+ rec.start();
86
+ recording.value = true;
87
+ };
88
+ const isDragging = ref(false);
89
+ const dragPosition = ref({ x: 0, y: 0 });
90
+ const cancelZone = ref(false);
91
+ const isTextZone = ref(false);
92
+ let isMouseDown = false;
93
+ const stopRecording = () => {
94
+ const theTextZone = isTextZone.value;
95
+ rec.stop(async (blob) => {
96
+ blobUrl.value = (window.URL || webkitURL).createObjectURL(blob);
97
+ rec.close();
98
+ recording.value = false;
99
+ emit("submit", {
100
+ blob,
101
+ url: blobUrl.value
102
+ });
103
+ if (theTextZone) {
104
+ if (props2.onTextZone) {
105
+ props2.onTextZone({
106
+ blob,
107
+ url: blobUrl.value
108
+ });
109
+ } else {
110
+ speechToText(props2.speenchToTextUrl, blob).then((text) => {
111
+ emit("submitText", text);
112
+ }).catch((err) => {
113
+ console.error("\u8BED\u97F3\u8BC6\u522B\u9519\u8BEF:", err);
114
+ ElMessage.error("\u8F6C\u6362\u6587\u5B57\u5931\u8D25");
115
+ });
116
+ }
117
+ }
118
+ });
119
+ };
120
+ const addDocumentListeners = () => {
121
+ document.addEventListener("mousemove", onmousemove);
122
+ document.addEventListener("mouseup", onmouseup);
123
+ };
124
+ const removeDocumentListeners = () => {
125
+ document.removeEventListener("mousemove", onmousemove);
126
+ document.removeEventListener("mouseup", onmouseup);
127
+ };
128
+ const onmousedown = (e) => {
129
+ e.preventDefault();
130
+ isMouseDown = true;
131
+ const touch = "touches" in e ? e.touches[0] : e;
132
+ dragPosition.value = { x: touch.clientX, y: touch.clientY };
133
+ if (e instanceof MouseEvent) {
134
+ addDocumentListeners();
135
+ }
136
+ pressTimer = setTimeout(() => {
137
+ if (isMouseDown) {
138
+ isDragging.value = true;
139
+ startRecording();
140
+ }
141
+ }, LONG_PRESS_DURATION);
142
+ };
143
+ function onmousemove(e) {
144
+ e.preventDefault();
145
+ if (!isDragging.value)
146
+ return;
147
+ const touch = "touches" in e ? e.touches[0] : e;
148
+ dragPosition.value = { x: touch.clientX, y: touch.clientY };
149
+ const cancelBtn = document.querySelector(".cancel-btn");
150
+ const textBtn = document.querySelector(".text-btn");
151
+ if (cancelBtn && textBtn) {
152
+ const cancelRect = cancelBtn.getBoundingClientRect();
153
+ const textRect = textBtn.getBoundingClientRect();
154
+ cancelZone.value = touch.clientX >= cancelRect.left && touch.clientX <= cancelRect.right && touch.clientY >= cancelRect.top && touch.clientY <= cancelRect.bottom;
155
+ isTextZone.value = touch.clientX >= textRect.left && touch.clientX <= textRect.right && touch.clientY >= textRect.top && touch.clientY <= textRect.bottom;
156
+ }
157
+ }
158
+ function onmouseup(e) {
159
+ isMouseDown = false;
160
+ clearTimeout(pressTimer);
161
+ if (isDragging.value) {
162
+ if (cancelZone.value) {
163
+ rec.close();
164
+ } else {
165
+ stopRecording();
166
+ }
167
+ isDragging.value = false;
168
+ cancelZone.value = false;
169
+ isTextZone.value = false;
170
+ }
171
+ if (e instanceof MouseEvent) {
172
+ removeDocumentListeners();
173
+ }
174
+ }
175
+ function onProcess(buffers, powerLevel, bufferDuration, bufferSampleRate) {
176
+ wave.value?.input(
177
+ buffers[buffers.length - 1],
178
+ powerLevel,
179
+ bufferSampleRate
180
+ );
181
+ }
182
+ onUnmounted(() => {
183
+ removeDocumentListeners();
184
+ });
185
+ return {
186
+ onmousedown,
187
+ onmousemove,
188
+ onmouseup,
189
+ recording,
190
+ recordingNode,
191
+ blobUrl,
192
+ isDragging,
193
+ cancelZone,
194
+ isTextZone
195
+ };
196
+ }
197
+ });
198
+
199
+ const _hoisted_1 = { class: "sk-recorder-container" };
200
+ const _hoisted_2 = {
201
+ key: 0,
202
+ class: "recording-mask"
203
+ };
204
+ const _hoisted_3 = { class: "recording-tip" };
205
+ const _hoisted_4 = {
206
+ ref: "recordingNode",
207
+ class: "wave-container"
208
+ };
209
+ const _hoisted_5 = { class: "tip-text" };
210
+ const _hoisted_6 = { class: "action-buttons" };
211
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
212
+ const _component_ElButton = resolveComponent("ElButton");
213
+ return openBlock(), createElementBlock("div", _hoisted_1, [
214
+ createCommentVNode(" \u906E\u7F69\u5C42 "),
215
+ _ctx.isDragging ? (openBlock(), createElementBlock("div", _hoisted_2, [
216
+ createCommentVNode(" \u5F55\u97F3\u63D0\u793A\u533A\u57DF\u79FB\u5230\u4E0A\u9762 "),
217
+ createElementVNode("div", _hoisted_3, [
218
+ createElementVNode(
219
+ "div",
220
+ _hoisted_4,
221
+ null,
222
+ 512
223
+ /* NEED_PATCH */
224
+ ),
225
+ createElementVNode(
226
+ "div",
227
+ _hoisted_5,
228
+ toDisplayString(_ctx.cancelZone ? "\u677E\u5F00\u624B\u6307\uFF0C\u53D6\u6D88\u53D1\u9001" : "\u677E\u5F00\u53D1\u9001\uFF0C\u4E0A\u6ED1\u53D6\u6D88"),
229
+ 1
230
+ /* TEXT */
231
+ )
232
+ ]),
233
+ createCommentVNode(" \u64CD\u4F5C\u6309\u94AE\u79FB\u5230\u5E95\u90E8 "),
234
+ createElementVNode("div", _hoisted_6, [
235
+ createElementVNode(
236
+ "div",
237
+ {
238
+ class: normalizeClass(["cancel-btn", { active: _ctx.cancelZone }])
239
+ },
240
+ _cache[0] || (_cache[0] = [
241
+ createElementVNode(
242
+ "div",
243
+ { class: "btn-icon" },
244
+ " \xD7 ",
245
+ -1
246
+ /* HOISTED */
247
+ ),
248
+ createElementVNode(
249
+ "div",
250
+ { class: "btn-text" },
251
+ " \u53D6\u6D88\u53D1\u9001 ",
252
+ -1
253
+ /* HOISTED */
254
+ )
255
+ ]),
256
+ 2
257
+ /* CLASS */
258
+ ),
259
+ createElementVNode(
260
+ "div",
261
+ {
262
+ class: normalizeClass(["text-btn", { active: _ctx.isTextZone }])
263
+ },
264
+ _cache[1] || (_cache[1] = [
265
+ createElementVNode(
266
+ "div",
267
+ { class: "btn-icon" },
268
+ " \u6587 ",
269
+ -1
270
+ /* HOISTED */
271
+ ),
272
+ createElementVNode(
273
+ "div",
274
+ { class: "btn-text" },
275
+ " \u8F6C\u4E3A\u6587\u5B57 ",
276
+ -1
277
+ /* HOISTED */
278
+ )
279
+ ]),
280
+ 2
281
+ /* CLASS */
282
+ )
283
+ ])
284
+ ])) : createCommentVNode("v-if", true),
285
+ createCommentVNode(" \u5F55\u97F3\u6309\u94AE "),
286
+ createVNode(_component_ElButton, mergeProps(_ctx.$attrs, {
287
+ class: ["sk-recorder-button", {
288
+ "is-recording": _ctx.recording
289
+ }],
290
+ onTouchstart: _ctx.onmousedown,
291
+ onTouchmove: _ctx.onmousemove,
292
+ onTouchend: _ctx.onmouseup,
293
+ onMousedown: _ctx.onmousedown
294
+ }), {
295
+ default: withCtx(() => _cache[2] || (_cache[2] = [
296
+ createElementVNode(
297
+ "span",
298
+ { class: "sk-recorder-button-text" },
299
+ "\u6309\u4F4F \u8BF4\u8BDD",
300
+ -1
301
+ /* HOISTED */
302
+ )
303
+ ])),
304
+ _: 1
305
+ /* STABLE */
306
+ }, 16, ["class", "onTouchstart", "onTouchmove", "onTouchend", "onMousedown"])
307
+ ]);
308
+ }
309
+ var VkRecorderButton = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "/home/runner/work/vunk-plus/vunk-plus/packages/components/recorder-button/src/index.vue"]]);
310
+
311
+ var types = /*#__PURE__*/Object.freeze({
312
+ __proto__: null
313
+ });
314
+
315
+ VkRecorderButton.install = (app) => {
316
+ app.component(VkRecorderButton.name || "VkRecorderButton", VkRecorderButton);
317
+ };
318
+
319
+ export { VkRecorderButton, types as __VkRecorderButton, VkRecorderButton as default };