@sdata/web-vue 3.19.0 → 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sd.css +11 -0
- package/dist/sd.min.css +1 -1
- package/es/basic-crud-table/basic-crud-table.vue_vue_type_script_setup_true_lang.js +6 -4
- package/es/basic-crud-table/types.d.ts +2 -0
- package/es/card/card.d.ts +22 -0
- package/es/card/card.js +11 -2
- package/es/card/index.d.ts +39 -0
- package/es/cascader/base-cascader-panel.d.ts +3 -0
- package/es/cascader/base-cascader-panel.js +2 -1
- package/es/cascader/cascader-search-panel.d.ts +3 -0
- package/es/cascader/cascader-search-panel.js +2 -1
- package/es/cascader/cascader.vue.d.ts +20 -8
- package/es/cascader/cascader.vue_vue_type_script_setup_true_lang.js +42 -4
- package/es/cascader/index.d.ts +1 -1
- package/es/cascader/types.d.ts +13 -0
- package/es/color-picker/color-picker.js +13 -1
- package/es/color-picker/index.d.ts +1 -1
- package/es/color-picker/interface.d.ts +10 -0
- package/es/config-provider/config-provider.vue.d.ts +67 -0
- package/es/config-provider/config-provider.vue_vue_type_script_setup_true_lang.js +67 -1
- package/es/config-provider/context.d.ts +12 -0
- package/es/config-provider/index.d.ts +99 -0
- package/es/date-picker/index.d.ts +12 -1
- package/es/date-picker/interface.d.ts +19 -0
- package/es/date-picker/picker.vue.d.ts +23 -13
- package/es/date-picker/picker.vue_vue_type_script_setup_true_lang.js +23 -2
- package/es/date-picker/range-picker.vue.d.ts +25 -14
- package/es/date-picker/range-picker.vue_vue_type_script_setup_true_lang.js +21 -2
- package/es/drawer/drawer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/es/index.css +11 -0
- package/es/index.d.ts +2 -2
- package/es/list/index.d.ts +9 -0
- package/es/list/list.d.ts +7 -0
- package/es/list/list.js +8 -2
- package/es/modal/modal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/es/qr-code/index.d.ts +18 -12
- package/es/qr-code/qr-code.vue.d.ts +5 -3
- package/es/qr-code/qr-code.vue_vue_type_script_setup_true_lang.js +5 -2
- package/es/select/index.d.ts +10 -1
- package/es/select/interface.d.ts +10 -0
- package/es/select/select-dropdown.vue.d.ts +3 -0
- package/es/select/select-dropdown.vue_vue_type_script_setup_true_lang.js +2 -4
- package/es/select/select.d.ts +7 -0
- package/es/select/select.js +30 -2
- package/es/sender/index.d.ts +1 -1
- package/es/sender/sender.vue_vue_type_script_setup_true_lang.js +117 -93
- package/es/sender/style/index.css +11 -0
- package/es/sender/style/index.scss +13 -0
- package/es/sender/types.d.ts +60 -3
- package/es/sender/use-speech.d.ts +12 -2
- package/es/sender/use-speech.js +293 -75
- package/es/spin/index.d.ts +15 -0
- package/es/spin/spin.d.ts +9 -0
- package/es/spin/spin.js +72 -10
- package/es/table/index.d.ts +51 -6
- package/es/table/interface.d.ts +3 -0
- package/es/table/table.d.ts +22 -3
- package/es/table/table.js +7 -2
- package/es/time-picker/index.d.ts +12 -1
- package/es/time-picker/interface.d.ts +10 -0
- package/es/time-picker/time-picker.vue.d.ts +15 -4
- package/es/time-picker/time-picker.vue_vue_type_script_setup_true_lang.js +22 -2
- package/es/timeline/index.d.ts +39 -0
- package/es/timeline/timeline.d.ts +22 -0
- package/es/timeline/timeline.js +11 -2
- package/es/toolbar/toolbar.vue_vue_type_script_setup_true_lang.js +9 -5
- package/es/toolbar/types.d.ts +2 -0
- package/es/tree-select/index.d.ts +1 -1
- package/es/tree-select/interface.d.ts +10 -0
- package/es/tree-select/tree-select.vue.d.ts +17 -1
- package/es/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js +27 -2
- package/json/vetur-attributes.json +63 -3
- package/json/vetur-tags.json +20 -0
- package/json/web-types.json +163 -3
- package/package.json +1 -1
package/es/sender/use-speech.js
CHANGED
|
@@ -1,113 +1,331 @@
|
|
|
1
|
+
import _objectSpread2 from "../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/objectSpread2.js";
|
|
1
2
|
import { useI18n } from "../locale/index.js";
|
|
2
3
|
import _asyncToGenerator from "../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/asyncToGenerator.js";
|
|
3
|
-
import { computed, shallowRef, toValue, watch } from "vue";
|
|
4
|
-
import { usePermission, useSpeechRecognition, useUserMedia } from "@vueuse/core";
|
|
4
|
+
import { computed, onBeforeUnmount, onMounted, shallowRef, toValue, watch } from "vue";
|
|
5
5
|
//#region components/sender/use-speech.ts
|
|
6
|
+
var DEFAULT_PROCESSOR_NAME = "sd-sender-audio-processor";
|
|
7
|
+
var DEFAULT_BUFFER_SIZE = 4096;
|
|
8
|
+
var resolveBufferSize = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(128, Math.floor(value)) : DEFAULT_BUFFER_SIZE;
|
|
9
|
+
var WORKLET_SOURCE = `
|
|
10
|
+
class SdSenderAudioProcessor extends AudioWorkletProcessor {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
super();
|
|
13
|
+
this.bufferSize = Math.max(128, options.processorOptions?.bufferSize || ${DEFAULT_BUFFER_SIZE});
|
|
14
|
+
this.buffer = new Float32Array(this.bufferSize);
|
|
15
|
+
this.offset = 0;
|
|
16
|
+
this.port.onmessage = (event) => {
|
|
17
|
+
if (event.data?.type !== 'flush') return;
|
|
18
|
+
if (this.offset > 0) {
|
|
19
|
+
const chunk = this.buffer.slice(0, this.offset);
|
|
20
|
+
this.port.postMessage(chunk.buffer, [chunk.buffer]);
|
|
21
|
+
this.offset = 0;
|
|
22
|
+
}
|
|
23
|
+
this.port.postMessage({ type: 'flushed' });
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
process(inputs) {
|
|
28
|
+
const channels = inputs[0];
|
|
29
|
+
if (!channels?.length) return true;
|
|
30
|
+
const frames = channels[0].length;
|
|
31
|
+
for (let frame = 0; frame < frames; frame += 1) {
|
|
32
|
+
let sample = 0;
|
|
33
|
+
for (let channel = 0; channel < channels.length; channel += 1) {
|
|
34
|
+
sample += channels[channel][frame] || 0;
|
|
35
|
+
}
|
|
36
|
+
this.buffer[this.offset] = sample / channels.length;
|
|
37
|
+
this.offset += 1;
|
|
38
|
+
if (this.offset === this.bufferSize) {
|
|
39
|
+
const chunk = this.buffer;
|
|
40
|
+
this.port.postMessage(chunk.buffer, [chunk.buffer]);
|
|
41
|
+
this.buffer = new Float32Array(this.bufferSize);
|
|
42
|
+
this.offset = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
registerProcessor('${DEFAULT_PROCESSOR_NAME}', SdSenderAudioProcessor);
|
|
49
|
+
`;
|
|
6
50
|
var isPermissionDeniedError = (error) => error instanceof DOMException ? error.name === "NotAllowedError" || error.name === "SecurityError" : error instanceof Error && (error.name === "NotAllowedError" || error.name === "SecurityError");
|
|
7
|
-
function useSpeech(allowSpeech,
|
|
51
|
+
function useSpeech(allowSpeech, options) {
|
|
8
52
|
const { t } = useI18n();
|
|
9
53
|
const config = computed(() => toValue(allowSpeech));
|
|
10
|
-
const controlled = computed(() => typeof config.value === "object" && typeof config.value.recording === "boolean");
|
|
11
|
-
const
|
|
54
|
+
const controlled = computed(() => typeof config.value === "object" && typeof config.value.recording === "boolean" && typeof config.value.onRecordingChange === "function");
|
|
55
|
+
const supported = shallowRef(false);
|
|
56
|
+
const internalRecording = shallowRef(false);
|
|
12
57
|
const requesting = shallowRef(false);
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
const recording = computed(() => controlled.value && typeof config.value === "object" ? Boolean(config.value.recording) : isListening.value);
|
|
28
|
-
const available = computed(() => Boolean(config.value) && (controlled.value || Boolean(isSpeechSupported.value && !permissionDenied.value)));
|
|
58
|
+
const captureError = shallowRef();
|
|
59
|
+
const stream = shallowRef();
|
|
60
|
+
const audioContext = shallowRef();
|
|
61
|
+
const sourceNode = shallowRef();
|
|
62
|
+
const workletNode = shallowRef();
|
|
63
|
+
const socket = shallowRef();
|
|
64
|
+
const startedAt = shallowRef(0);
|
|
65
|
+
const chunks = shallowRef(0);
|
|
66
|
+
const sequence = shallowRef(0);
|
|
67
|
+
let generatedWorkletUrl;
|
|
68
|
+
let resolveWorkletFlush;
|
|
69
|
+
let disposed = false;
|
|
70
|
+
const recording = computed(() => controlled.value && typeof config.value === "object" ? Boolean(config.value.recording) : internalRecording.value);
|
|
71
|
+
const available = computed(() => Boolean(config.value) && (controlled.value || supported.value) && !(captureError.value && isPermissionDeniedError(captureError.value.error)));
|
|
29
72
|
const statusText = computed(() => {
|
|
30
|
-
var
|
|
73
|
+
var _captureError$value;
|
|
31
74
|
if (requesting.value) return t("sender.speech.requestingPermission");
|
|
32
|
-
if (
|
|
33
|
-
if (!controlled.value && !
|
|
75
|
+
if (captureError.value && isPermissionDeniedError(captureError.value.error)) return t("sender.speech.permissionDenied");
|
|
76
|
+
if (!controlled.value && !supported.value) return t("sender.speech.unsupported");
|
|
34
77
|
if (recording.value) return t("sender.speech.stop");
|
|
35
|
-
if (((
|
|
36
|
-
if (
|
|
37
|
-
const recognitionErrorCode = recognitionError.value && "error" in recognitionError.value ? recognitionError.value.error : void 0;
|
|
38
|
-
if (recognitionErrorCode === "audio-capture") return t("sender.speech.noMicrophone");
|
|
39
|
-
if (recognitionErrorCode === "no-speech") return t("sender.speech.noSpeech");
|
|
40
|
-
if (recognitionError.value) return t("sender.speech.recognitionFailed");
|
|
78
|
+
if (((_captureError$value = captureError.value) === null || _captureError$value === void 0 ? void 0 : _captureError$value.error.name) === "NotFoundError") return t("sender.speech.noMicrophone");
|
|
79
|
+
if (captureError.value) return t("sender.speech.microphoneUnavailable");
|
|
41
80
|
return t("sender.speech.start");
|
|
42
81
|
});
|
|
43
|
-
const
|
|
82
|
+
const resolveAudioContext = () => {
|
|
83
|
+
var _window$AudioContext;
|
|
84
|
+
const AudioContextConstructor = (_window$AudioContext = window.AudioContext) !== null && _window$AudioContext !== void 0 ? _window$AudioContext : window.webkitAudioContext;
|
|
85
|
+
if (!AudioContextConstructor) throw new Error("AudioContext is not supported");
|
|
86
|
+
return new AudioContextConstructor();
|
|
87
|
+
};
|
|
88
|
+
const resolveWorkletUrl = () => {
|
|
89
|
+
var _generatedWorkletUrl;
|
|
90
|
+
if (typeof config.value === "object" && config.value.workletUrl) return config.value.workletUrl;
|
|
91
|
+
(_generatedWorkletUrl = generatedWorkletUrl) !== null && _generatedWorkletUrl !== void 0 || (generatedWorkletUrl = URL.createObjectURL(new Blob([WORKLET_SOURCE], { type: "text/javascript" })));
|
|
92
|
+
return generatedWorkletUrl;
|
|
93
|
+
};
|
|
94
|
+
const connectTransport = (url, protocols) => new Promise((resolve, reject) => {
|
|
95
|
+
const nextSocket = protocols ? new WebSocket(url, protocols) : new WebSocket(url);
|
|
96
|
+
let opened = false;
|
|
97
|
+
socket.value = nextSocket;
|
|
98
|
+
nextSocket.binaryType = "arraybuffer";
|
|
99
|
+
nextSocket.onopen = (event) => {
|
|
100
|
+
opened = true;
|
|
101
|
+
options.onTransportOpen({
|
|
102
|
+
event,
|
|
103
|
+
socket: nextSocket
|
|
104
|
+
});
|
|
105
|
+
resolve(nextSocket);
|
|
106
|
+
};
|
|
107
|
+
nextSocket.onmessage = (event) => options.onTransportMessage({
|
|
108
|
+
event,
|
|
109
|
+
socket: nextSocket
|
|
110
|
+
});
|
|
111
|
+
nextSocket.onclose = (event) => options.onTransportClose({
|
|
112
|
+
event,
|
|
113
|
+
socket: nextSocket
|
|
114
|
+
});
|
|
115
|
+
nextSocket.onerror = () => {
|
|
116
|
+
const errorEvent = {
|
|
117
|
+
error: /* @__PURE__ */ new Error(`Unable to connect to speech URL: ${url}`),
|
|
118
|
+
phase: "transport"
|
|
119
|
+
};
|
|
120
|
+
if (opened) options.onError(errorEvent);
|
|
121
|
+
else reject(errorEvent.error);
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
const flushWorklet = () => new Promise((resolve) => {
|
|
125
|
+
var _workletNode$value;
|
|
126
|
+
const port = (_workletNode$value = workletNode.value) === null || _workletNode$value === void 0 ? void 0 : _workletNode$value.port;
|
|
127
|
+
if (!port) {
|
|
128
|
+
resolve();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const timeout = window.setTimeout(resolve, 100);
|
|
132
|
+
resolveWorkletFlush = () => {
|
|
133
|
+
window.clearTimeout(timeout);
|
|
134
|
+
resolveWorkletFlush = void 0;
|
|
135
|
+
resolve();
|
|
136
|
+
};
|
|
137
|
+
port.postMessage({ type: "flush" });
|
|
138
|
+
});
|
|
139
|
+
const releaseResources = function() {
|
|
44
140
|
var _ref = _asyncToGenerator(function* () {
|
|
45
|
-
|
|
141
|
+
var _workletNode$value2, _sourceNode$value, _stream$value, _audioContext$value, _audioContext$value2;
|
|
142
|
+
(_workletNode$value2 = workletNode.value) === null || _workletNode$value2 === void 0 || _workletNode$value2.disconnect();
|
|
143
|
+
(_sourceNode$value = sourceNode.value) === null || _sourceNode$value === void 0 || _sourceNode$value.disconnect();
|
|
144
|
+
(_stream$value = stream.value) === null || _stream$value === void 0 || _stream$value.getTracks().forEach((track) => track.stop());
|
|
145
|
+
if (((_audioContext$value = audioContext.value) === null || _audioContext$value === void 0 ? void 0 : _audioContext$value.state) !== "closed") yield (_audioContext$value2 = audioContext.value) === null || _audioContext$value2 === void 0 ? void 0 : _audioContext$value2.close();
|
|
146
|
+
if (socket.value && (socket.value.readyState === WebSocket.OPEN || socket.value.readyState === WebSocket.CONNECTING)) socket.value.close(1e3, "speech-ended");
|
|
147
|
+
workletNode.value = void 0;
|
|
148
|
+
sourceNode.value = void 0;
|
|
149
|
+
stream.value = void 0;
|
|
150
|
+
audioContext.value = void 0;
|
|
151
|
+
socket.value = void 0;
|
|
152
|
+
});
|
|
153
|
+
return function releaseResources() {
|
|
154
|
+
return _ref.apply(this, arguments);
|
|
155
|
+
};
|
|
156
|
+
}();
|
|
157
|
+
const stopCapture = function() {
|
|
158
|
+
var _ref2 = _asyncToGenerator(function* (reason = "manual") {
|
|
159
|
+
var _socket$value, _config$value$onRecor, _config$value;
|
|
160
|
+
if (!internalRecording.value) return;
|
|
161
|
+
yield flushWorklet();
|
|
162
|
+
const endedAt = performance.now();
|
|
163
|
+
internalRecording.value = false;
|
|
164
|
+
if (((_socket$value = socket.value) === null || _socket$value === void 0 ? void 0 : _socket$value.readyState) === WebSocket.OPEN && typeof config.value === "object" && config.value.sendMetadata !== false) socket.value.send(JSON.stringify({
|
|
165
|
+
type: "end",
|
|
166
|
+
reason
|
|
167
|
+
}));
|
|
168
|
+
yield releaseResources();
|
|
169
|
+
if (typeof config.value === "object") (_config$value$onRecor = (_config$value = config.value).onRecordingChange) === null || _config$value$onRecor === void 0 || _config$value$onRecor.call(_config$value, false);
|
|
170
|
+
options.onEnd({
|
|
171
|
+
source: "capture",
|
|
172
|
+
reason,
|
|
173
|
+
startedAt: startedAt.value,
|
|
174
|
+
endedAt,
|
|
175
|
+
duration: endedAt - startedAt.value,
|
|
176
|
+
chunks: chunks.value
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
return function stopCapture() {
|
|
180
|
+
return _ref2.apply(this, arguments);
|
|
181
|
+
};
|
|
182
|
+
}();
|
|
183
|
+
const startCapture = function() {
|
|
184
|
+
var _ref3 = _asyncToGenerator(function* () {
|
|
185
|
+
if (requesting.value || internalRecording.value || !available.value) return;
|
|
46
186
|
requesting.value = true;
|
|
47
|
-
|
|
187
|
+
captureError.value = void 0;
|
|
188
|
+
let phase = "permission";
|
|
48
189
|
try {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
190
|
+
var _speechConfig$audioCo, _speechConfig$process, _socket$value3, _speechConfig$onRecor;
|
|
191
|
+
const speechConfig = typeof config.value === "object" ? config.value : void 0;
|
|
192
|
+
const bufferSize = resolveBufferSize(speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.bufferSize);
|
|
193
|
+
stream.value = yield navigator.mediaDevices.getUserMedia({
|
|
194
|
+
audio: (_speechConfig$audioCo = speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.audioConstraints) !== null && _speechConfig$audioCo !== void 0 ? _speechConfig$audioCo : true,
|
|
195
|
+
video: false
|
|
196
|
+
});
|
|
197
|
+
if (disposed) {
|
|
198
|
+
yield releaseResources();
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.url) {
|
|
202
|
+
phase = "transport";
|
|
203
|
+
yield connectTransport(speechConfig.url, speechConfig.protocols);
|
|
204
|
+
if (disposed) {
|
|
205
|
+
yield releaseResources();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
phase = "audioContext";
|
|
210
|
+
const nextAudioContext = resolveAudioContext();
|
|
211
|
+
audioContext.value = nextAudioContext;
|
|
212
|
+
phase = "audioWorklet";
|
|
213
|
+
yield nextAudioContext.audioWorklet.addModule(resolveWorkletUrl());
|
|
214
|
+
if (disposed) {
|
|
215
|
+
yield releaseResources();
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const processorName = (_speechConfig$process = speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.processorName) !== null && _speechConfig$process !== void 0 ? _speechConfig$process : DEFAULT_PROCESSOR_NAME;
|
|
219
|
+
const nextWorkletNode = new AudioWorkletNode(nextAudioContext, processorName, {
|
|
220
|
+
numberOfInputs: 1,
|
|
221
|
+
numberOfOutputs: 0,
|
|
222
|
+
channelCount: 1,
|
|
223
|
+
processorOptions: _objectSpread2(_objectSpread2({}, speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.processorOptions), {}, { bufferSize })
|
|
224
|
+
});
|
|
225
|
+
workletNode.value = nextWorkletNode;
|
|
226
|
+
sourceNode.value = nextAudioContext.createMediaStreamSource(stream.value);
|
|
227
|
+
nextWorkletNode.port.onmessage = (event) => {
|
|
228
|
+
var _socket$value2;
|
|
229
|
+
if (!(event.data instanceof ArrayBuffer) && "type" in event.data) {
|
|
230
|
+
if (event.data.type === "flushed") resolveWorkletFlush === null || resolveWorkletFlush === void 0 || resolveWorkletFlush();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (!internalRecording.value) return;
|
|
234
|
+
const buffer = event.data;
|
|
235
|
+
const dataEvent = {
|
|
236
|
+
buffer,
|
|
237
|
+
sampleRate: nextAudioContext.sampleRate,
|
|
238
|
+
sequence: sequence.value,
|
|
239
|
+
timestamp: performance.now()
|
|
240
|
+
};
|
|
241
|
+
sequence.value += 1;
|
|
242
|
+
chunks.value += 1;
|
|
243
|
+
options.onData(dataEvent);
|
|
244
|
+
if (((_socket$value2 = socket.value) === null || _socket$value2 === void 0 ? void 0 : _socket$value2.readyState) === WebSocket.OPEN) socket.value.send(buffer);
|
|
245
|
+
};
|
|
246
|
+
sourceNode.value.connect(nextWorkletNode);
|
|
247
|
+
startedAt.value = performance.now();
|
|
248
|
+
chunks.value = 0;
|
|
249
|
+
sequence.value = 0;
|
|
250
|
+
internalRecording.value = true;
|
|
251
|
+
if (((_socket$value3 = socket.value) === null || _socket$value3 === void 0 ? void 0 : _socket$value3.readyState) === WebSocket.OPEN && (speechConfig === null || speechConfig === void 0 ? void 0 : speechConfig.sendMetadata) !== false) socket.value.send(JSON.stringify({
|
|
252
|
+
type: "start",
|
|
253
|
+
format: "pcm-f32",
|
|
254
|
+
channels: 1,
|
|
255
|
+
sampleRate: nextAudioContext.sampleRate,
|
|
256
|
+
bufferSize
|
|
257
|
+
}));
|
|
258
|
+
speechConfig === null || speechConfig === void 0 || (_speechConfig$onRecor = speechConfig.onRecordingChange) === null || _speechConfig$onRecor === void 0 || _speechConfig$onRecor.call(speechConfig, true);
|
|
259
|
+
options.onStart({
|
|
260
|
+
source: "capture",
|
|
261
|
+
startedAt: startedAt.value,
|
|
262
|
+
stream: stream.value,
|
|
263
|
+
audioContext: nextAudioContext,
|
|
264
|
+
sampleRate: nextAudioContext.sampleRate
|
|
265
|
+
});
|
|
53
266
|
} catch (error) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
267
|
+
const errorEvent = {
|
|
268
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
269
|
+
phase
|
|
270
|
+
};
|
|
271
|
+
captureError.value = errorEvent;
|
|
272
|
+
options.onError(errorEvent);
|
|
273
|
+
yield releaseResources();
|
|
58
274
|
} finally {
|
|
59
|
-
stopMicrophone();
|
|
60
275
|
requesting.value = false;
|
|
61
276
|
}
|
|
62
277
|
});
|
|
63
|
-
return function
|
|
64
|
-
return
|
|
278
|
+
return function startCapture() {
|
|
279
|
+
return _ref3.apply(this, arguments);
|
|
65
280
|
};
|
|
66
281
|
}();
|
|
67
282
|
const trigger = function() {
|
|
68
|
-
var
|
|
283
|
+
var _ref4 = _asyncToGenerator(function* (breakRecording = false) {
|
|
69
284
|
if (breakRecording && !recording.value) return;
|
|
70
|
-
forceBreak.value = breakRecording;
|
|
71
285
|
if (controlled.value && typeof config.value === "object") {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
286
|
+
var _config$value$onRecor2, _config$value2;
|
|
287
|
+
const nextRecording = !recording.value;
|
|
288
|
+
(_config$value$onRecor2 = (_config$value2 = config.value).onRecordingChange) === null || _config$value$onRecor2 === void 0 || _config$value$onRecor2.call(_config$value2, nextRecording);
|
|
289
|
+
const now = performance.now();
|
|
290
|
+
if (nextRecording) {
|
|
291
|
+
startedAt.value = now;
|
|
292
|
+
options.onStart({
|
|
293
|
+
source: "controlled",
|
|
294
|
+
startedAt: now
|
|
295
|
+
});
|
|
296
|
+
} else options.onEnd({
|
|
297
|
+
source: "controlled",
|
|
298
|
+
reason: "controlled",
|
|
299
|
+
startedAt: startedAt.value,
|
|
300
|
+
endedAt: now,
|
|
301
|
+
duration: now - startedAt.value,
|
|
302
|
+
chunks: 0
|
|
303
|
+
});
|
|
78
304
|
return;
|
|
79
305
|
}
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
result.value = "";
|
|
83
|
-
recognitionError.value = void 0;
|
|
84
|
-
startRecognition();
|
|
85
|
-
if (typeof config.value === "object") config.value.onRecordingChange(true);
|
|
306
|
+
if (internalRecording.value) yield stopCapture();
|
|
307
|
+
else yield startCapture();
|
|
86
308
|
});
|
|
87
309
|
return function trigger() {
|
|
88
|
-
return
|
|
310
|
+
return _ref4.apply(this, arguments);
|
|
89
311
|
};
|
|
90
312
|
}();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
forceBreak.value = false;
|
|
95
|
-
});
|
|
96
|
-
watch(recognitionError, (nextError) => {
|
|
97
|
-
if (nextError && "error" in nextError && (nextError.error === "not-allowed" || nextError.error === "service-not-allowed")) permissionDeniedByRequest.value = true;
|
|
313
|
+
onMounted(() => {
|
|
314
|
+
var _navigator$mediaDevic;
|
|
315
|
+
supported.value = Boolean(typeof ((_navigator$mediaDevic = navigator.mediaDevices) === null || _navigator$mediaDevic === void 0 ? void 0 : _navigator$mediaDevic.getUserMedia) === "function" && typeof AudioContext !== "undefined" && typeof AudioWorkletNode !== "undefined");
|
|
98
316
|
});
|
|
99
|
-
watch(
|
|
100
|
-
if (
|
|
101
|
-
microphoneAuthorized.value = true;
|
|
102
|
-
permissionDeniedByRequest.value = false;
|
|
103
|
-
} else if (nextPermission === "denied") {
|
|
104
|
-
microphoneAuthorized.value = false;
|
|
105
|
-
if (isListening.value) stopRecognition();
|
|
106
|
-
}
|
|
317
|
+
watch(() => Boolean(config.value), (enabled) => {
|
|
318
|
+
if (!enabled) stopCapture();
|
|
107
319
|
});
|
|
108
320
|
watch(controlled, (nextControlled) => {
|
|
109
|
-
if (nextControlled
|
|
321
|
+
if (nextControlled) stopCapture();
|
|
110
322
|
});
|
|
323
|
+
onBeforeUnmount(_asyncToGenerator(function* () {
|
|
324
|
+
disposed = true;
|
|
325
|
+
if (internalRecording.value) yield stopCapture("unmount");
|
|
326
|
+
else yield releaseResources();
|
|
327
|
+
if (generatedWorkletUrl) URL.revokeObjectURL(generatedWorkletUrl);
|
|
328
|
+
}));
|
|
111
329
|
return {
|
|
112
330
|
available,
|
|
113
331
|
recording,
|
package/es/spin/index.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ declare const Spin: {
|
|
|
7
7
|
type: NumberConstructor;
|
|
8
8
|
};
|
|
9
9
|
loading: BooleanConstructor;
|
|
10
|
+
delay: {
|
|
11
|
+
type: (BooleanConstructor | NumberConstructor)[];
|
|
12
|
+
default: boolean;
|
|
13
|
+
};
|
|
10
14
|
dot: BooleanConstructor;
|
|
11
15
|
tip: StringConstructor;
|
|
12
16
|
hideIcon: {
|
|
@@ -16,6 +20,7 @@ declare const Spin: {
|
|
|
16
20
|
}>> & Readonly<{}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {
|
|
17
21
|
dot: boolean;
|
|
18
22
|
loading: boolean;
|
|
23
|
+
delay: number | boolean;
|
|
19
24
|
hideIcon: boolean;
|
|
20
25
|
}, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
|
|
21
26
|
P: {};
|
|
@@ -29,6 +34,10 @@ declare const Spin: {
|
|
|
29
34
|
type: NumberConstructor;
|
|
30
35
|
};
|
|
31
36
|
loading: BooleanConstructor;
|
|
37
|
+
delay: {
|
|
38
|
+
type: (BooleanConstructor | NumberConstructor)[];
|
|
39
|
+
default: boolean;
|
|
40
|
+
};
|
|
32
41
|
dot: BooleanConstructor;
|
|
33
42
|
tip: StringConstructor;
|
|
34
43
|
hideIcon: {
|
|
@@ -38,6 +47,7 @@ declare const Spin: {
|
|
|
38
47
|
}>> & Readonly<{}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, {
|
|
39
48
|
dot: boolean;
|
|
40
49
|
loading: boolean;
|
|
50
|
+
delay: number | boolean;
|
|
41
51
|
hideIcon: boolean;
|
|
42
52
|
}>;
|
|
43
53
|
__isFragment?: never;
|
|
@@ -48,6 +58,10 @@ declare const Spin: {
|
|
|
48
58
|
type: NumberConstructor;
|
|
49
59
|
};
|
|
50
60
|
loading: BooleanConstructor;
|
|
61
|
+
delay: {
|
|
62
|
+
type: (BooleanConstructor | NumberConstructor)[];
|
|
63
|
+
default: boolean;
|
|
64
|
+
};
|
|
51
65
|
dot: BooleanConstructor;
|
|
52
66
|
tip: StringConstructor;
|
|
53
67
|
hideIcon: {
|
|
@@ -57,6 +71,7 @@ declare const Spin: {
|
|
|
57
71
|
}>> & Readonly<{}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {
|
|
58
72
|
dot: boolean;
|
|
59
73
|
loading: boolean;
|
|
74
|
+
delay: number | boolean;
|
|
60
75
|
hideIcon: boolean;
|
|
61
76
|
}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & {
|
|
62
77
|
install: (app: App, options?: SDOptions) => void;
|
package/es/spin/spin.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
3
3
|
type: NumberConstructor;
|
|
4
4
|
};
|
|
5
5
|
loading: BooleanConstructor;
|
|
6
|
+
delay: {
|
|
7
|
+
type: (BooleanConstructor | NumberConstructor)[];
|
|
8
|
+
default: boolean;
|
|
9
|
+
};
|
|
6
10
|
dot: BooleanConstructor;
|
|
7
11
|
tip: StringConstructor;
|
|
8
12
|
hideIcon: {
|
|
@@ -14,6 +18,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
14
18
|
type: NumberConstructor;
|
|
15
19
|
};
|
|
16
20
|
loading: BooleanConstructor;
|
|
21
|
+
delay: {
|
|
22
|
+
type: (BooleanConstructor | NumberConstructor)[];
|
|
23
|
+
default: boolean;
|
|
24
|
+
};
|
|
17
25
|
dot: BooleanConstructor;
|
|
18
26
|
tip: StringConstructor;
|
|
19
27
|
hideIcon: {
|
|
@@ -23,6 +31,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
23
31
|
}>> & Readonly<{}>, {
|
|
24
32
|
dot: boolean;
|
|
25
33
|
loading: boolean;
|
|
34
|
+
delay: number | boolean;
|
|
26
35
|
hideIcon: boolean;
|
|
27
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
28
37
|
export default _default;
|
package/es/spin/spin.js
CHANGED
|
@@ -2,8 +2,10 @@ import { configProviderInjectionKey } from "../config-provider/context.js";
|
|
|
2
2
|
import { getPrefixCls } from "../_utils/global-config.js";
|
|
3
3
|
import { getFirstComponent } from "../_utils/vue-utils.js";
|
|
4
4
|
import IconLoading from "../icon/icon-loading/index.js";
|
|
5
|
+
import { useConfigProviderProp } from "../_hooks/use-config-provider-prop.js";
|
|
5
6
|
import dot_loading_default from "./dot-loading.js";
|
|
6
|
-
import { Fragment, cloneVNode, computed, createVNode, defineComponent, inject } from "vue";
|
|
7
|
+
import { Fragment, cloneVNode, computed, createVNode, defineComponent, inject, shallowRef, toRef } from "vue";
|
|
8
|
+
import { watchDebounced } from "@vueuse/core";
|
|
7
9
|
//#region components/spin/spin.tsx
|
|
8
10
|
var spin_default = /* @__PURE__ */ defineComponent({
|
|
9
11
|
name: "Spin",
|
|
@@ -19,6 +21,14 @@ var spin_default = /* @__PURE__ */ defineComponent({
|
|
|
19
21
|
*/
|
|
20
22
|
loading: Boolean,
|
|
21
23
|
/**
|
|
24
|
+
* @zh 加载指示器显示前的延迟时间。设置为 `true` 时延迟 400ms
|
|
25
|
+
* @en Delay before showing the loading indicator. Uses 400ms when set to `true`
|
|
26
|
+
*/
|
|
27
|
+
delay: {
|
|
28
|
+
type: [Boolean, Number],
|
|
29
|
+
default: false
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
22
32
|
* @zh 是否使用点类型的动画
|
|
23
33
|
* @en Whether to use dot type animation
|
|
24
34
|
*/
|
|
@@ -55,9 +65,61 @@ var spin_default = /* @__PURE__ */ defineComponent({
|
|
|
55
65
|
setup(props, { slots }) {
|
|
56
66
|
const prefixCls = getPrefixCls("spin");
|
|
57
67
|
const configCtx = inject(configProviderInjectionKey, void 0);
|
|
68
|
+
const { mergedValue: mergedLoading } = useConfigProviderProp(toRef(props, "loading"), {
|
|
69
|
+
propNames: ["loading"],
|
|
70
|
+
getGlobalValue: (ctx) => {
|
|
71
|
+
var _ctx$spinProps;
|
|
72
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps = ctx.spinProps) === null || _ctx$spinProps === void 0 ? void 0 : _ctx$spinProps.loading;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const { mergedValue: mergedDelay } = useConfigProviderProp(toRef(props, "delay"), {
|
|
76
|
+
propNames: ["delay"],
|
|
77
|
+
getGlobalValue: (ctx) => {
|
|
78
|
+
var _ctx$spinProps2;
|
|
79
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps2 = ctx.spinProps) === null || _ctx$spinProps2 === void 0 ? void 0 : _ctx$spinProps2.delay;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const { mergedValue: mergedSize } = useConfigProviderProp(toRef(props, "size"), {
|
|
83
|
+
propNames: ["size"],
|
|
84
|
+
getGlobalValue: (ctx) => {
|
|
85
|
+
var _ctx$spinProps3;
|
|
86
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps3 = ctx.spinProps) === null || _ctx$spinProps3 === void 0 ? void 0 : _ctx$spinProps3.size;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const { mergedValue: mergedDot } = useConfigProviderProp(toRef(props, "dot"), {
|
|
90
|
+
propNames: ["dot"],
|
|
91
|
+
getGlobalValue: (ctx) => {
|
|
92
|
+
var _ctx$spinProps4;
|
|
93
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps4 = ctx.spinProps) === null || _ctx$spinProps4 === void 0 ? void 0 : _ctx$spinProps4.dot;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const { mergedValue: mergedTip } = useConfigProviderProp(toRef(props, "tip"), {
|
|
97
|
+
propNames: ["tip"],
|
|
98
|
+
getGlobalValue: (ctx) => {
|
|
99
|
+
var _ctx$spinProps5;
|
|
100
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps5 = ctx.spinProps) === null || _ctx$spinProps5 === void 0 ? void 0 : _ctx$spinProps5.tip;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const { mergedValue: mergedHideIcon } = useConfigProviderProp(toRef(props, "hideIcon"), {
|
|
104
|
+
propNames: ["hideIcon", "hide-icon"],
|
|
105
|
+
getGlobalValue: (ctx) => {
|
|
106
|
+
var _ctx$spinProps6;
|
|
107
|
+
return ctx === null || ctx === void 0 || (_ctx$spinProps6 = ctx.spinProps) === null || _ctx$spinProps6 === void 0 ? void 0 : _ctx$spinProps6.hideIcon;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
const delayTime = computed(() => mergedDelay.value === true ? 400 : Math.max(0, Number(mergedDelay.value) || 0));
|
|
111
|
+
const requestedLoading = computed(() => slots.default ? Boolean(mergedLoading.value) : true);
|
|
112
|
+
const delayedLoading = shallowRef(false);
|
|
113
|
+
watchDebounced(requestedLoading, (loading) => {
|
|
114
|
+
delayedLoading.value = loading;
|
|
115
|
+
}, {
|
|
116
|
+
debounce: delayTime,
|
|
117
|
+
immediate: true
|
|
118
|
+
});
|
|
119
|
+
const activeLoading = computed(() => delayTime.value > 0 ? Boolean(requestedLoading.value && delayedLoading.value) : requestedLoading.value);
|
|
58
120
|
const cls = computed(() => [prefixCls, {
|
|
59
|
-
[`${prefixCls}-loading`]:
|
|
60
|
-
[`${prefixCls}-with-tip`]:
|
|
121
|
+
[`${prefixCls}-loading`]: slots.default ? activeLoading.value : Boolean(mergedLoading.value),
|
|
122
|
+
[`${prefixCls}-with-tip`]: mergedTip.value && !slots.default
|
|
61
123
|
}]);
|
|
62
124
|
const renderIcon = () => {
|
|
63
125
|
if (slots.icon) {
|
|
@@ -65,28 +127,28 @@ var spin_default = /* @__PURE__ */ defineComponent({
|
|
|
65
127
|
if (iconVNode) return cloneVNode(iconVNode, { spin: true });
|
|
66
128
|
}
|
|
67
129
|
if (slots.element) return slots.element();
|
|
68
|
-
if (
|
|
130
|
+
if (mergedDot.value) return createVNode(dot_loading_default, { "size": mergedSize.value }, null);
|
|
69
131
|
if (configCtx === null || configCtx === void 0 ? void 0 : configCtx.slots.loading) return configCtx.slots.loading();
|
|
70
132
|
return createVNode(IconLoading, {
|
|
71
133
|
"spin": true,
|
|
72
|
-
"size":
|
|
134
|
+
"size": mergedSize.value
|
|
73
135
|
}, null);
|
|
74
136
|
};
|
|
75
137
|
const renderSpinIcon = () => {
|
|
76
138
|
var _slots$tip, _slots$tip2, _slots$tip3;
|
|
77
|
-
const style =
|
|
78
|
-
const hasTip = Boolean((_slots$tip = slots.tip) !== null && _slots$tip !== void 0 ? _slots$tip :
|
|
79
|
-
return createVNode(Fragment, null, [!
|
|
139
|
+
const style = mergedSize.value ? { fontSize: `${mergedSize.value}px` } : void 0;
|
|
140
|
+
const hasTip = Boolean((_slots$tip = slots.tip) !== null && _slots$tip !== void 0 ? _slots$tip : mergedTip.value);
|
|
141
|
+
return createVNode(Fragment, null, [!mergedHideIcon.value && createVNode("div", {
|
|
80
142
|
"class": `${prefixCls}-icon`,
|
|
81
143
|
"style": style,
|
|
82
144
|
"aria-hidden": "true"
|
|
83
|
-
}, [renderIcon()]), hasTip && createVNode("div", { "class": `${prefixCls}-tip` }, [(_slots$tip2 = (_slots$tip3 = slots.tip) === null || _slots$tip3 === void 0 ? void 0 : _slots$tip3.call(slots)) !== null && _slots$tip2 !== void 0 ? _slots$tip2 :
|
|
145
|
+
}, [renderIcon()]), hasTip && createVNode("div", { "class": `${prefixCls}-tip` }, [(_slots$tip2 = (_slots$tip3 = slots.tip) === null || _slots$tip3 === void 0 ? void 0 : _slots$tip3.call(slots)) !== null && _slots$tip2 !== void 0 ? _slots$tip2 : mergedTip.value])]);
|
|
84
146
|
};
|
|
85
147
|
return () => createVNode("div", {
|
|
86
148
|
"role": "status",
|
|
87
149
|
"aria-live": "polite",
|
|
88
150
|
"class": cls.value
|
|
89
|
-
}, [slots.default ? createVNode(Fragment, null, [slots.default(),
|
|
151
|
+
}, [slots.default ? createVNode(Fragment, null, [slots.default(), activeLoading.value && createVNode("div", { "class": `${prefixCls}-mask` }, [createVNode("div", { "class": `${prefixCls}-mask-icon` }, [renderSpinIcon()])])]) : activeLoading.value ? renderSpinIcon() : null]);
|
|
90
152
|
}
|
|
91
153
|
});
|
|
92
154
|
//#endregion
|