@useupup/preact 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/AudioUploader-2WITC5YR-4WGBUCEB.js +298 -0
- package/dist/AudioUploader-2WITC5YR-4WGBUCEB.js.map +1 -0
- package/dist/AudioUploader-2WITC5YR-GCKVRJAT.cjs +298 -0
- package/dist/AudioUploader-2WITC5YR-GCKVRJAT.cjs.map +1 -0
- package/dist/BoxUploader-VE5LRJ7M-CWGNYYJV.js +170 -0
- package/dist/BoxUploader-VE5LRJ7M-CWGNYYJV.js.map +1 -0
- package/dist/BoxUploader-VE5LRJ7M-IE7LYW5P.cjs +170 -0
- package/dist/BoxUploader-VE5LRJ7M-IE7LYW5P.cjs.map +1 -0
- package/dist/CameraUploader-WF5A6UIS-3KBW647M.cjs +628 -0
- package/dist/CameraUploader-WF5A6UIS-3KBW647M.cjs.map +1 -0
- package/dist/CameraUploader-WF5A6UIS-DONVXSEZ.js +628 -0
- package/dist/CameraUploader-WF5A6UIS-DONVXSEZ.js.map +1 -0
- package/dist/DropboxUploader-VMUYG3OP-7FKTLIIL.cjs +172 -0
- package/dist/DropboxUploader-VMUYG3OP-7FKTLIIL.cjs.map +1 -0
- package/dist/DropboxUploader-VMUYG3OP-DBUPHIG7.js +172 -0
- package/dist/DropboxUploader-VMUYG3OP-DBUPHIG7.js.map +1 -0
- package/dist/GoogleDriveUploader-YA56X3QR-FMS6MTYU.js +175 -0
- package/dist/GoogleDriveUploader-YA56X3QR-FMS6MTYU.js.map +1 -0
- package/dist/GoogleDriveUploader-YA56X3QR-OR3CQLX2.cjs +175 -0
- package/dist/GoogleDriveUploader-YA56X3QR-OR3CQLX2.cjs.map +1 -0
- package/dist/ImageEditorInline-N2NSAODR-QWXPP3ON.js +184 -0
- package/dist/ImageEditorInline-N2NSAODR-QWXPP3ON.js.map +1 -0
- package/dist/ImageEditorInline-N2NSAODR-ZVAM6EOA.cjs +184 -0
- package/dist/ImageEditorInline-N2NSAODR-ZVAM6EOA.cjs.map +1 -0
- package/dist/ImageEditorModal-CWKMDVPY-PRD43JPH.cjs +236 -0
- package/dist/ImageEditorModal-CWKMDVPY-PRD43JPH.cjs.map +1 -0
- package/dist/ImageEditorModal-CWKMDVPY-ZRPTYHYN.js +236 -0
- package/dist/ImageEditorModal-CWKMDVPY-ZRPTYHYN.js.map +1 -0
- package/dist/OneDriveUploader-I25Y6AJP-FVXK6RGT.js +173 -0
- package/dist/OneDriveUploader-I25Y6AJP-FVXK6RGT.js.map +1 -0
- package/dist/OneDriveUploader-I25Y6AJP-GBOBEJQR.cjs +173 -0
- package/dist/OneDriveUploader-I25Y6AJP-GBOBEJQR.cjs.map +1 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-3TT6GNEN.js +286 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-3TT6GNEN.js.map +1 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-G7ADH264.cjs +286 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-G7ADH264.cjs.map +1 -0
- package/dist/chunk-2XFVSPFN.cjs +293 -0
- package/dist/chunk-2XFVSPFN.cjs.map +1 -0
- package/dist/chunk-7JLN2HMZ.cjs +4296 -0
- package/dist/chunk-7JLN2HMZ.cjs.map +1 -0
- package/dist/chunk-BVMKSTAE.js +4296 -0
- package/dist/chunk-BVMKSTAE.js.map +1 -0
- package/dist/chunk-C7QBCXAH.js +39 -0
- package/dist/chunk-C7QBCXAH.js.map +1 -0
- package/dist/chunk-CR6CXFRP.js +195 -0
- package/dist/chunk-CR6CXFRP.js.map +1 -0
- package/dist/chunk-ETIJATY7.cjs +39 -0
- package/dist/chunk-ETIJATY7.cjs.map +1 -0
- package/dist/chunk-FH3LYESR.js +411 -0
- package/dist/chunk-FH3LYESR.js.map +1 -0
- package/dist/chunk-GKMTOOTQ.cjs +411 -0
- package/dist/chunk-GKMTOOTQ.cjs.map +1 -0
- package/dist/chunk-KHH3WHWU.js +74 -0
- package/dist/chunk-KHH3WHWU.js.map +1 -0
- package/dist/chunk-V2O5HRJV.cjs +74 -0
- package/dist/chunk-V2O5HRJV.cjs.map +1 -0
- package/dist/chunk-WCI3AGJV.js +831 -0
- package/dist/chunk-WCI3AGJV.js.map +1 -0
- package/dist/chunk-YWJHE7U4.cjs +195 -0
- package/dist/chunk-YWJHE7U4.cjs.map +1 -0
- package/dist/chunk-ZGWETRKI.js +293 -0
- package/dist/chunk-ZGWETRKI.js.map +1 -0
- package/dist/chunk-ZKZJ5PPP.cjs +831 -0
- package/dist/chunk-ZKZJ5PPP.cjs.map +1 -0
- package/dist/filerobot-bridge-52YH7W2M.cjs +92 -0
- package/dist/filerobot-bridge-52YH7W2M.cjs.map +1 -0
- package/dist/filerobot-bridge-ED4XMHX4.js +92 -0
- package/dist/filerobot-bridge-ED4XMHX4.js.map +1 -0
- package/dist/filerobot-island.css +97 -0
- package/dist/filerobot-island.css.map +1 -0
- package/dist/filerobot-island.js +77951 -0
- package/dist/filerobot-island.js.map +1 -0
- package/dist/index.cjs +5600 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5600 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.d.ts +4 -0
- package/dist/tailwind-prefixed.css +2529 -0
- package/package.json +130 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Devino
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @useupup/preact
|
|
2
|
+
|
|
3
|
+
Preact file uploader with cloud-drive sources (Google Drive, OneDrive, Dropbox,
|
|
4
|
+
Box), resumable uploads, theming, and ICU i18n. It is a **`preact/compat`
|
|
5
|
+
re-export of [`@useupup/react`](https://www.npmjs.com/package/@useupup/react)** — the
|
|
6
|
+
same UI and API, resolved against Preact.
|
|
7
|
+
|
|
8
|
+
Requires Preact 10.13+ (`preact` is a peer dependency; the image editor has
|
|
9
|
+
additional optional peers — see below).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm i @useupup/preact
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage (Client Mode)
|
|
18
|
+
|
|
19
|
+
Client Mode uploads directly from the browser to your storage; your server only
|
|
20
|
+
issues short-lived upload credentials at `uploadEndpoint`.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { UpupUploader } from '@useupup/preact'
|
|
24
|
+
import '@useupup/preact/styles'
|
|
25
|
+
|
|
26
|
+
export function App() {
|
|
27
|
+
return (
|
|
28
|
+
<UpupUploader
|
|
29
|
+
provider="aws"
|
|
30
|
+
uploadEndpoint="/api/upload-token"
|
|
31
|
+
onFileUploadComplete={(file, key) =>
|
|
32
|
+
console.log('Uploaded', file.name, 'to', key)
|
|
33
|
+
}
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`uploadEndpoint` is your own route returning a presigned upload URL — see the
|
|
40
|
+
quickstart for a ready-made handler.
|
|
41
|
+
|
|
42
|
+
Use it in a Preact project that has the standard `preact/compat` aliases
|
|
43
|
+
(`react` / `react-dom` → `preact/compat`) configured in its bundler, as with any
|
|
44
|
+
React-compatible library.
|
|
45
|
+
|
|
46
|
+
## Server Mode
|
|
47
|
+
|
|
48
|
+
For credential isolation and server-proxied cloud drives, add
|
|
49
|
+
[`@useupup/server`](https://www.npmjs.com/package/@useupup/server) and point the
|
|
50
|
+
uploader at it — server mode works identically through the `preact/compat`
|
|
51
|
+
re-export:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<UpupUploader mode="server" serverUrl="/api/upup" provider="aws" />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Image editor
|
|
58
|
+
|
|
59
|
+
The optional image editor runs as an **isolated real-React island**: it lazily
|
|
60
|
+
loads actual `react` / `react-dom` on demand to render Filerobot, so React never
|
|
61
|
+
enters your main Preact bundle. If you enable the editor, install its peers
|
|
62
|
+
(`react`, `react-dom`, `react-filerobot-image-editor`, and the `konva` /
|
|
63
|
+
`react-konva` / `styled-components` dependencies it needs — see this package's
|
|
64
|
+
`peerDependencies`).
|
|
65
|
+
|
|
66
|
+
## Also exported
|
|
67
|
+
|
|
68
|
+
Because it re-exports `@useupup/react`, the public surface matches `@useupup/react`
|
|
69
|
+
exactly (`UpupUploader`, `UpupThemeProvider`, the brand icons, and the `use*`
|
|
70
|
+
hooks).
|
|
71
|
+
|
|
72
|
+
## Links
|
|
73
|
+
|
|
74
|
+
- [Preact quickstart](https://useupup.com/docs/quickstarts/preact)
|
|
75
|
+
- [Documentation](https://useupup.com/docs/)
|
|
76
|
+
- [Source & monorepo](https://github.com/DevinoSolutions/upup)
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SourceViewContainer
|
|
3
|
+
} from "./chunk-C7QBCXAH.js";
|
|
4
|
+
import {
|
|
5
|
+
Fragment,
|
|
6
|
+
u,
|
|
7
|
+
useUploaderFiles,
|
|
8
|
+
useUploaderSource,
|
|
9
|
+
useUploaderTheme
|
|
10
|
+
} from "./chunk-ZGWETRKI.js";
|
|
11
|
+
import {
|
|
12
|
+
compat_module_exports,
|
|
13
|
+
init_compat_module
|
|
14
|
+
} from "./chunk-FH3LYESR.js";
|
|
15
|
+
|
|
16
|
+
// ../react/dist/AudioUploader-2WITC5YR.js
|
|
17
|
+
init_compat_module();
|
|
18
|
+
init_compat_module();
|
|
19
|
+
import { cn } from "@useupup/core/internal";
|
|
20
|
+
var BAR_COUNT = 28;
|
|
21
|
+
function AudioWaveform({
|
|
22
|
+
stream
|
|
23
|
+
}) {
|
|
24
|
+
const barsRef = (0, compat_module_exports.useRef)([]);
|
|
25
|
+
(0, compat_module_exports.useEffect)(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
const AudioCtor = (_a = window.AudioContext) != null ? _a : window.webkitAudioContext;
|
|
28
|
+
if (!AudioCtor) return;
|
|
29
|
+
const ctx = new AudioCtor();
|
|
30
|
+
void ctx.resume();
|
|
31
|
+
const source = ctx.createMediaStreamSource(stream);
|
|
32
|
+
const analyser = ctx.createAnalyser();
|
|
33
|
+
analyser.fftSize = 64;
|
|
34
|
+
source.connect(analyser);
|
|
35
|
+
const data = new Uint8Array(analyser.frequencyBinCount);
|
|
36
|
+
let raf = 0;
|
|
37
|
+
const tick = () => {
|
|
38
|
+
var _a2;
|
|
39
|
+
analyser.getByteFrequencyData(data);
|
|
40
|
+
const bars = barsRef.current;
|
|
41
|
+
for (let i = 0; i < bars.length; i++) {
|
|
42
|
+
const v = (_a2 = data[i % data.length]) != null ? _a2 : 0;
|
|
43
|
+
const el = bars[i];
|
|
44
|
+
if (el) el.style.height = `${6 + v / 255 * 34}px`;
|
|
45
|
+
}
|
|
46
|
+
raf = requestAnimationFrame(tick);
|
|
47
|
+
};
|
|
48
|
+
raf = requestAnimationFrame(tick);
|
|
49
|
+
return () => {
|
|
50
|
+
cancelAnimationFrame(raf);
|
|
51
|
+
source.disconnect();
|
|
52
|
+
void ctx.close();
|
|
53
|
+
};
|
|
54
|
+
}, [stream]);
|
|
55
|
+
return /* @__PURE__ */ u(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
"data-upup-slot": "audio-waveform",
|
|
59
|
+
"aria-hidden": "true",
|
|
60
|
+
className: "upup-flex upup-h-11 upup-items-center upup-justify-center upup-gap-[3px]",
|
|
61
|
+
children: Array.from({ length: BAR_COUNT }).map((_, i) => /* @__PURE__ */ u(
|
|
62
|
+
"span",
|
|
63
|
+
{
|
|
64
|
+
ref: (el) => {
|
|
65
|
+
barsRef.current[i] = el;
|
|
66
|
+
},
|
|
67
|
+
className: "upup-w-[3px] upup-flex-none upup-rounded-full upup-bg-[#38bdf8]",
|
|
68
|
+
style: { height: "6px" }
|
|
69
|
+
},
|
|
70
|
+
i
|
|
71
|
+
))
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function AudioUploader() {
|
|
76
|
+
const { setFiles } = useUploaderFiles();
|
|
77
|
+
const { setActiveSource } = useUploaderSource();
|
|
78
|
+
const { isDark: dark } = useUploaderTheme();
|
|
79
|
+
const [state, setState] = (0, compat_module_exports.useState)("idle");
|
|
80
|
+
const [duration, setDuration] = (0, compat_module_exports.useState)(0);
|
|
81
|
+
const [audioUrl, setAudioUrl] = (0, compat_module_exports.useState)(null);
|
|
82
|
+
const [error, setError] = (0, compat_module_exports.useState)(null);
|
|
83
|
+
const mediaRecorder = (0, compat_module_exports.useRef)(null);
|
|
84
|
+
const chunks = (0, compat_module_exports.useRef)([]);
|
|
85
|
+
const timerRef = (0, compat_module_exports.useRef)(null);
|
|
86
|
+
const streamRef = (0, compat_module_exports.useRef)(null);
|
|
87
|
+
(0, compat_module_exports.useEffect)(() => {
|
|
88
|
+
return () => {
|
|
89
|
+
var _a;
|
|
90
|
+
if (timerRef.current) clearInterval(timerRef.current);
|
|
91
|
+
if (audioUrl) URL.revokeObjectURL(audioUrl);
|
|
92
|
+
(_a = streamRef.current) == null ? void 0 : _a.getTracks().forEach((t) => {
|
|
93
|
+
t.stop();
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
}, [audioUrl]);
|
|
97
|
+
const startRecording = (0, compat_module_exports.useCallback)(async () => {
|
|
98
|
+
try {
|
|
99
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
100
|
+
audio: true
|
|
101
|
+
});
|
|
102
|
+
streamRef.current = stream;
|
|
103
|
+
chunks.current = [];
|
|
104
|
+
const recorder = new MediaRecorder(stream);
|
|
105
|
+
mediaRecorder.current = recorder;
|
|
106
|
+
recorder.ondataavailable = (e) => {
|
|
107
|
+
if (e.data.size > 0) chunks.current.push(e.data);
|
|
108
|
+
};
|
|
109
|
+
recorder.onstop = () => {
|
|
110
|
+
const blob = new Blob(chunks.current, {
|
|
111
|
+
type: recorder.mimeType || "audio/webm"
|
|
112
|
+
});
|
|
113
|
+
setAudioUrl(URL.createObjectURL(blob));
|
|
114
|
+
stream.getTracks().forEach((t) => {
|
|
115
|
+
t.stop();
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
recorder.start();
|
|
119
|
+
setState("recording");
|
|
120
|
+
setDuration(0);
|
|
121
|
+
timerRef.current = setInterval(() => {
|
|
122
|
+
setDuration((d) => d + 1);
|
|
123
|
+
}, 1e3);
|
|
124
|
+
} catch {
|
|
125
|
+
setError(
|
|
126
|
+
"Microphone access denied. Please allow microphone access and try again."
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}, []);
|
|
130
|
+
const stopRecording = (0, compat_module_exports.useCallback)(() => {
|
|
131
|
+
var _a;
|
|
132
|
+
(_a = mediaRecorder.current) == null ? void 0 : _a.stop();
|
|
133
|
+
if (timerRef.current) clearInterval(timerRef.current);
|
|
134
|
+
setState("recorded");
|
|
135
|
+
}, []);
|
|
136
|
+
const discardRecording = (0, compat_module_exports.useCallback)(() => {
|
|
137
|
+
if (audioUrl) URL.revokeObjectURL(audioUrl);
|
|
138
|
+
setAudioUrl(null);
|
|
139
|
+
setDuration(0);
|
|
140
|
+
setState("idle");
|
|
141
|
+
}, [audioUrl]);
|
|
142
|
+
const addRecording = (0, compat_module_exports.useCallback)(() => {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
if (!audioUrl) return;
|
|
145
|
+
const ext = ((_b = (_a = mediaRecorder.current) == null ? void 0 : _a.mimeType) == null ? void 0 : _b.includes("webm")) ? "webm" : "ogg";
|
|
146
|
+
void fetch(audioUrl).then((r) => r.blob()).then((blob) => {
|
|
147
|
+
const file = new File(
|
|
148
|
+
[blob],
|
|
149
|
+
`recording-${Date.now()}.${ext}`,
|
|
150
|
+
{ type: blob.type }
|
|
151
|
+
);
|
|
152
|
+
setFiles([file]);
|
|
153
|
+
setActiveSource(void 0);
|
|
154
|
+
}).catch(() => {
|
|
155
|
+
});
|
|
156
|
+
}, [audioUrl, setFiles, setActiveSource]);
|
|
157
|
+
const formatTime = (s) => {
|
|
158
|
+
const m = Math.floor(s / 60);
|
|
159
|
+
const sec = s % 60;
|
|
160
|
+
return `${m}:${sec.toString().padStart(2, "0")}`;
|
|
161
|
+
};
|
|
162
|
+
if (error) {
|
|
163
|
+
return /* @__PURE__ */ u(SourceViewContainer, { "data-upup-slot": "audio-uploader", children: /* @__PURE__ */ u("div", { className: "upup-flex upup-flex-col upup-items-center upup-gap-3 upup-p-6 upup-text-center", children: /* @__PURE__ */ u(
|
|
164
|
+
"p",
|
|
165
|
+
{
|
|
166
|
+
className: cn("upup-text-sm upup-text-red-500", {
|
|
167
|
+
"upup-text-red-400": dark
|
|
168
|
+
}),
|
|
169
|
+
children: error
|
|
170
|
+
}
|
|
171
|
+
) }) });
|
|
172
|
+
}
|
|
173
|
+
return /* @__PURE__ */ u(SourceViewContainer, { "data-upup-slot": "audio-uploader", children: /* @__PURE__ */ u("div", { className: "upup-flex upup-h-full upup-w-full upup-flex-col upup-items-center upup-justify-center upup-gap-6 upup-p-6", children: [
|
|
174
|
+
/* @__PURE__ */ u(
|
|
175
|
+
"div",
|
|
176
|
+
{
|
|
177
|
+
className: cn(
|
|
178
|
+
"upup-flex upup-h-24 upup-w-24 upup-items-center upup-justify-center upup-rounded-full",
|
|
179
|
+
{
|
|
180
|
+
"upup-bg-red-500/20": state === "recording",
|
|
181
|
+
"upup-bg-[#0ea5e9]/20": state === "idle" || state === "recorded"
|
|
182
|
+
}
|
|
183
|
+
),
|
|
184
|
+
children: /* @__PURE__ */ u(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
className: cn(
|
|
188
|
+
"upup-flex upup-h-16 upup-w-16 upup-items-center upup-justify-center upup-rounded-full upup-transition-all",
|
|
189
|
+
{
|
|
190
|
+
"upup-animate-pulse upup-bg-red-500": state === "recording",
|
|
191
|
+
"upup-bg-[#0ea5e9]": state === "idle" || state === "recorded"
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
children: /* @__PURE__ */ u(
|
|
195
|
+
"svg",
|
|
196
|
+
{
|
|
197
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
198
|
+
width: "28",
|
|
199
|
+
height: "28",
|
|
200
|
+
viewBox: "0 0 24 24",
|
|
201
|
+
fill: "none",
|
|
202
|
+
stroke: "white",
|
|
203
|
+
strokeWidth: "2",
|
|
204
|
+
strokeLinecap: "round",
|
|
205
|
+
strokeLinejoin: "round",
|
|
206
|
+
children: [
|
|
207
|
+
/* @__PURE__ */ u("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
|
|
208
|
+
/* @__PURE__ */ u("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
209
|
+
/* @__PURE__ */ u("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
),
|
|
217
|
+
state === "recording" && streamRef.current && /* @__PURE__ */ u(AudioWaveform, { stream: streamRef.current }),
|
|
218
|
+
/* @__PURE__ */ u(
|
|
219
|
+
"span",
|
|
220
|
+
{
|
|
221
|
+
className: cn(
|
|
222
|
+
"upup-text-2xl upup-font-mono upup-tabular-nums",
|
|
223
|
+
{
|
|
224
|
+
"upup-text-[#1b1b1b]": !dark,
|
|
225
|
+
"upup-text-white": dark
|
|
226
|
+
}
|
|
227
|
+
),
|
|
228
|
+
children: formatTime(duration)
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
state === "recorded" && audioUrl && /* @__PURE__ */ u(
|
|
232
|
+
"audio",
|
|
233
|
+
{
|
|
234
|
+
controls: true,
|
|
235
|
+
src: audioUrl,
|
|
236
|
+
className: "upup-w-full upup-max-w-xs"
|
|
237
|
+
}
|
|
238
|
+
),
|
|
239
|
+
/* @__PURE__ */ u("div", { className: "upup-flex upup-gap-3", children: [
|
|
240
|
+
state === "idle" && /* @__PURE__ */ u(
|
|
241
|
+
"button",
|
|
242
|
+
{
|
|
243
|
+
type: "button",
|
|
244
|
+
className: cn(
|
|
245
|
+
"upup-rounded-lg upup-bg-[#0ea5e9] upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]",
|
|
246
|
+
{
|
|
247
|
+
"upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]": dark
|
|
248
|
+
}
|
|
249
|
+
),
|
|
250
|
+
onClick: () => {
|
|
251
|
+
void startRecording();
|
|
252
|
+
},
|
|
253
|
+
children: "Start Recording"
|
|
254
|
+
}
|
|
255
|
+
),
|
|
256
|
+
state === "recording" && /* @__PURE__ */ u(
|
|
257
|
+
"button",
|
|
258
|
+
{
|
|
259
|
+
type: "button",
|
|
260
|
+
className: "upup-rounded-lg upup-bg-red-500 upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-red-600",
|
|
261
|
+
onClick: stopRecording,
|
|
262
|
+
children: "Stop Recording"
|
|
263
|
+
}
|
|
264
|
+
),
|
|
265
|
+
state === "recorded" && /* @__PURE__ */ u(Fragment, { children: [
|
|
266
|
+
/* @__PURE__ */ u(
|
|
267
|
+
"button",
|
|
268
|
+
{
|
|
269
|
+
type: "button",
|
|
270
|
+
className: cn(
|
|
271
|
+
"upup-rounded-lg upup-bg-gray-500 upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-gray-600"
|
|
272
|
+
),
|
|
273
|
+
onClick: discardRecording,
|
|
274
|
+
children: "Discard"
|
|
275
|
+
}
|
|
276
|
+
),
|
|
277
|
+
/* @__PURE__ */ u(
|
|
278
|
+
"button",
|
|
279
|
+
{
|
|
280
|
+
type: "button",
|
|
281
|
+
className: cn(
|
|
282
|
+
"upup-rounded-lg upup-bg-[#0ea5e9] upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]",
|
|
283
|
+
{
|
|
284
|
+
"upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]": dark
|
|
285
|
+
}
|
|
286
|
+
),
|
|
287
|
+
onClick: addRecording,
|
|
288
|
+
children: "Add Recording"
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
] })
|
|
292
|
+
] })
|
|
293
|
+
] }) });
|
|
294
|
+
}
|
|
295
|
+
export {
|
|
296
|
+
AudioUploader as default
|
|
297
|
+
};
|
|
298
|
+
//# sourceMappingURL=AudioUploader-2WITC5YR-4WGBUCEB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../react/src/components/AudioUploader.tsx","../../react/src/components/AudioWaveform.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderSource,\r\n useUploaderTheme,\r\n} from '../context/UploaderContext'\r\nimport { cn } from '@useupup/core/internal'\r\nimport SourceViewContainer from './shared/SourceViewContainer'\r\nimport AudioWaveform from './AudioWaveform'\r\n\r\ntype RecordingState = 'idle' | 'recording' | 'recorded'\r\n\r\nexport default function AudioUploader(): React.ReactElement | null {\r\n const { setFiles } = useUploaderFiles()\r\n const { setActiveSource } = useUploaderSource()\r\n const { isDark: dark } = useUploaderTheme()\r\n\r\n const [state, setState] = useState<RecordingState>('idle')\r\n const [duration, setDuration] = useState(0)\r\n const [audioUrl, setAudioUrl] = useState<string | null>(null)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const mediaRecorder = useRef<MediaRecorder | null>(null)\r\n const chunks = useRef<Blob[]>([])\r\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)\r\n const streamRef = useRef<MediaStream | null>(null)\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (timerRef.current) clearInterval(timerRef.current)\r\n if (audioUrl) URL.revokeObjectURL(audioUrl)\r\n streamRef.current?.getTracks().forEach(t => {\r\n t.stop()\r\n })\r\n }\r\n }, [audioUrl])\r\n\r\n const startRecording = useCallback(async () => {\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({\r\n audio: true,\r\n })\r\n streamRef.current = stream\r\n chunks.current = []\r\n const recorder = new MediaRecorder(stream)\r\n mediaRecorder.current = recorder\r\n\r\n recorder.ondataavailable = e => {\r\n if (e.data.size > 0) chunks.current.push(e.data)\r\n }\r\n\r\n recorder.onstop = () => {\r\n const blob = new Blob(chunks.current, {\r\n type: recorder.mimeType || 'audio/webm',\r\n })\r\n setAudioUrl(URL.createObjectURL(blob))\r\n stream.getTracks().forEach(t => {\r\n t.stop()\r\n })\r\n }\r\n\r\n recorder.start()\r\n setState('recording')\r\n setDuration(0)\r\n timerRef.current = setInterval(() => {\r\n setDuration(d => d + 1)\r\n }, 1000)\r\n } catch {\r\n // upup-catch: getUserMedia rejection (permission denied / no device) is surfaced to the user via setError, not a system fault\r\n setError(\r\n 'Microphone access denied. Please allow microphone access and try again.',\r\n )\r\n }\r\n }, [])\r\n\r\n const stopRecording = useCallback(() => {\r\n mediaRecorder.current?.stop()\r\n if (timerRef.current) clearInterval(timerRef.current)\r\n setState('recorded')\r\n }, [])\r\n\r\n const discardRecording = useCallback(() => {\r\n if (audioUrl) URL.revokeObjectURL(audioUrl)\r\n setAudioUrl(null)\r\n setDuration(0)\r\n setState('idle')\r\n }, [audioUrl])\r\n\r\n const addRecording = useCallback(() => {\r\n if (!audioUrl) return\r\n const ext = mediaRecorder.current?.mimeType?.includes('webm')\r\n ? 'webm'\r\n : 'ogg'\r\n void fetch(audioUrl)\r\n .then(r => r.blob())\r\n .then(blob => {\r\n const file = new File(\r\n [blob],\r\n `recording-${Date.now()}.${ext}`,\r\n { type: blob.type },\r\n )\r\n setFiles([file])\r\n setActiveSource(undefined)\r\n })\r\n .catch(() => {\r\n // upup-catch: replaying an in-memory object URL cannot fail in practice; ignore\r\n })\r\n }, [audioUrl, setFiles, setActiveSource])\r\n\r\n const formatTime = (s: number) => {\r\n const m = Math.floor(s / 60)\r\n const sec = s % 60\r\n return `${m}:${sec.toString().padStart(2, '0')}`\r\n }\r\n\r\n if (error) {\r\n return (\r\n <SourceViewContainer data-upup-slot=\"audio-uploader\">\r\n <div className=\"upup-flex upup-flex-col upup-items-center upup-gap-3 upup-p-6 upup-text-center\">\r\n <p\r\n className={cn('upup-text-sm upup-text-red-500', {\r\n 'upup-text-red-400': dark,\r\n })}\r\n >\r\n {error}\r\n </p>\r\n </div>\r\n </SourceViewContainer>\r\n )\r\n }\r\n\r\n return (\r\n <SourceViewContainer data-upup-slot=\"audio-uploader\">\r\n <div className=\"upup-flex upup-h-full upup-w-full upup-flex-col upup-items-center upup-justify-center upup-gap-6 upup-p-6\">\r\n <div\r\n className={cn(\r\n 'upup-flex upup-h-24 upup-w-24 upup-items-center upup-justify-center upup-rounded-full',\r\n {\r\n 'upup-bg-red-500/20': state === 'recording',\r\n 'upup-bg-[#0ea5e9]/20':\r\n state === 'idle' || state === 'recorded',\r\n },\r\n )}\r\n >\r\n <div\r\n className={cn(\r\n 'upup-flex upup-h-16 upup-w-16 upup-items-center upup-justify-center upup-rounded-full upup-transition-all',\r\n {\r\n 'upup-animate-pulse upup-bg-red-500':\r\n state === 'recording',\r\n 'upup-bg-[#0ea5e9]':\r\n state === 'idle' || state === 'recorded',\r\n },\r\n )}\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"28\"\r\n height=\"28\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"white\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\" />\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\r\n <line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\" />\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n {state === 'recording' && streamRef.current && (\r\n <AudioWaveform stream={streamRef.current} />\r\n )}\r\n\r\n <span\r\n className={cn(\r\n 'upup-text-2xl upup-font-mono upup-tabular-nums',\r\n {\r\n 'upup-text-[#1b1b1b]': !dark,\r\n 'upup-text-white': dark,\r\n },\r\n )}\r\n >\r\n {formatTime(duration)}\r\n </span>\r\n\r\n {state === 'recorded' && audioUrl && (\r\n <audio\r\n controls\r\n src={audioUrl}\r\n className=\"upup-w-full upup-max-w-xs\"\r\n />\r\n )}\r\n\r\n <div className=\"upup-flex upup-gap-3\">\r\n {state === 'idle' && (\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'upup-rounded-lg upup-bg-[#0ea5e9] upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]',\r\n {\r\n 'upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]':\r\n dark,\r\n },\r\n )}\r\n onClick={() => {\r\n void startRecording()\r\n }}\r\n >\r\n Start Recording\r\n </button>\r\n )}\r\n {state === 'recording' && (\r\n <button\r\n type=\"button\"\r\n className=\"upup-rounded-lg upup-bg-red-500 upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-red-600\"\r\n onClick={stopRecording}\r\n >\r\n Stop Recording\r\n </button>\r\n )}\r\n {state === 'recorded' && (\r\n <>\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'upup-rounded-lg upup-bg-gray-500 upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-gray-600',\r\n )}\r\n onClick={discardRecording}\r\n >\r\n Discard\r\n </button>\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'upup-rounded-lg upup-bg-[#0ea5e9] upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]',\r\n {\r\n 'upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]':\r\n dark,\r\n },\r\n )}\r\n onClick={addRecording}\r\n >\r\n Add Recording\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n </SourceViewContainer>\r\n )\r\n}\r\n","import React, { useEffect, useRef } from 'react'\r\n\r\nconst BAR_COUNT = 28\r\n\r\n/**\r\n * Live recording waveform (states-tour-3 state D): sky bars whose heights track\r\n * the microphone's live frequency data via a Web Audio AnalyserNode.\r\n *\r\n * This is the ONE place JS-driven visuals are sanctioned — the bars render REAL\r\n * audio data, not fx decoration, so (a) they are NOT classed `upup-fx-*` (the\r\n * motion gate must not freeze live data) and (b) the rAF read loop is\r\n * legitimate. Heights are written straight to the DOM (no per-frame React\r\n * render). The AnalyserNode + AudioContext are torn down on unmount/stop.\r\n */\r\nexport default function AudioWaveform({\r\n stream,\r\n}: Readonly<{ stream: MediaStream }>): React.ReactElement {\r\n const barsRef = useRef<Array<HTMLSpanElement | null>>([])\r\n\r\n useEffect(() => {\r\n const AudioCtor =\r\n window.AudioContext ??\r\n (window as unknown as { webkitAudioContext?: typeof AudioContext })\r\n .webkitAudioContext\r\n if (!AudioCtor) return\r\n const ctx = new AudioCtor()\r\n // Autoplay policy may create the context suspended; without resuming,\r\n // getByteFrequencyData returns all-zeros and the bars silently flatline.\r\n void ctx.resume()\r\n const source = ctx.createMediaStreamSource(stream)\r\n const analyser = ctx.createAnalyser()\r\n analyser.fftSize = 64\r\n source.connect(analyser)\r\n const data = new Uint8Array(analyser.frequencyBinCount)\r\n let raf = 0\r\n const tick = () => {\r\n analyser.getByteFrequencyData(data)\r\n const bars = barsRef.current\r\n for (let i = 0; i < bars.length; i++) {\r\n const v = data[i % data.length] ?? 0\r\n const el = bars[i]\r\n if (el) el.style.height = `${6 + (v / 255) * 34}px`\r\n }\r\n raf = requestAnimationFrame(tick)\r\n }\r\n raf = requestAnimationFrame(tick)\r\n return () => {\r\n cancelAnimationFrame(raf)\r\n source.disconnect()\r\n void ctx.close()\r\n }\r\n }, [stream])\r\n\r\n return (\r\n <div\r\n data-upup-slot=\"audio-waveform\"\r\n aria-hidden=\"true\"\r\n className=\"upup-flex upup-h-11 upup-items-center upup-justify-center upup-gap-[3px]\"\r\n >\r\n {Array.from({ length: BAR_COUNT }).map((_, i) => (\r\n <span\r\n key={i}\r\n ref={el => {\r\n barsRef.current[i] = el\r\n }}\r\n className=\"upup-w-[3px] upup-flex-none upup-rounded-full upup-bg-[#38bdf8]\"\r\n style={{ height: '6px' }}\r\n />\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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","names":["_a","useRef","useEffect","jsx"]}
|