sveltekit-ui 1.1.19 → 1.1.21
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/Components/Audio/index.svelte +22 -16
- package/dist/Components/Audio/index.svelte.js +80 -0
- package/package.json +1 -1
- package/src/lib/Components/Audio/index.svelte +22 -16
- package/src/lib/Components/Audio/index.svelte.js +80 -0
- package/src/routes/components/[component]/Showcase/Audio/index.svelte +1 -0
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
let { manager } = $props()
|
|
9
9
|
|
|
10
10
|
onMount(() => {
|
|
11
|
-
if(typeof manager?.handle_mount == "function"){
|
|
11
|
+
if (typeof manager?.handle_mount == "function") {
|
|
12
12
|
manager?.handle_mount()
|
|
13
13
|
}
|
|
14
14
|
})
|
|
15
|
-
|
|
16
|
-
|
|
17
15
|
</script>
|
|
18
16
|
|
|
19
17
|
{#snippet settings()}
|
|
@@ -23,6 +21,9 @@
|
|
|
23
21
|
<div>
|
|
24
22
|
<Slider manager={manager?.volume_slider_manager} />
|
|
25
23
|
<Slider manager={manager?.rate_slider_manager} />
|
|
24
|
+
{#if manager?.is_show_download_button}
|
|
25
|
+
<Button manager={manager?.download_audio_button_manager} />
|
|
26
|
+
{/if}
|
|
26
27
|
</div>
|
|
27
28
|
{/snippet}
|
|
28
29
|
</Popover>
|
|
@@ -53,7 +54,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
53
54
|
src={manager?.src}
|
|
54
55
|
type={manager?.type}
|
|
55
56
|
></audio>
|
|
56
|
-
{#if manager?.ui_type ==
|
|
57
|
+
{#if manager?.ui_type == "square"}
|
|
57
58
|
<div
|
|
58
59
|
class="container_square"
|
|
59
60
|
style="margin-left: {manager?.ml}rem; margin-right: {manager?.mr}rem; margin-top: {manager?.mt}rem; margin-bottom: {manager?.mb}rem;"
|
|
@@ -81,8 +82,13 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
81
82
|
</div>
|
|
82
83
|
<div style="display: flex;">
|
|
83
84
|
<Button manager={manager?.play_pause_button_manager} />
|
|
84
|
-
<div class="slider_box" class:is_short={manager?.ui_type ==
|
|
85
|
-
<span
|
|
85
|
+
<div class="slider_box" class:is_short={manager?.ui_type == "short"}>
|
|
86
|
+
<span
|
|
87
|
+
>{manager?.formatted_current_time}{manager?.time_slider_manager?.max &&
|
|
88
|
+
manager?.time_slider_manager?.max != Infinity
|
|
89
|
+
? ` / ${manager?.formatted_duration}`
|
|
90
|
+
: ""}</span
|
|
91
|
+
>
|
|
86
92
|
</div>
|
|
87
93
|
{@render settings()}
|
|
88
94
|
</div>
|
|
@@ -91,7 +97,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
91
97
|
{:else}
|
|
92
98
|
<div
|
|
93
99
|
class="container_line"
|
|
94
|
-
class:is_short={manager?.ui_type ==
|
|
100
|
+
class:is_short={manager?.ui_type == "short"}
|
|
95
101
|
style="margin-left: {manager?.ml}rem; margin-right: {manager?.mr}rem; margin-top: {manager?.mt}rem; margin-bottom: {manager?.mb}rem;"
|
|
96
102
|
>
|
|
97
103
|
{#if manager?.image_src && !manager?.is_hide_image}
|
|
@@ -105,20 +111,20 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
105
111
|
/>
|
|
106
112
|
{/if}
|
|
107
113
|
{#if !manager?.src}
|
|
108
|
-
<p style="display: flex; flex: 1;" class:is_short={manager?.ui_type ==
|
|
114
|
+
<p style="display: flex; flex: 1;" class:is_short={manager?.ui_type == "short"}>Missing Audio Source</p>
|
|
109
115
|
{:else if manager?.is_loading && !manager?.time_slider_manager?.max}
|
|
110
|
-
<div style="display: flex; flex: 1; margin-left: 1rem;" class:is_short={manager?.ui_type ==
|
|
116
|
+
<div style="display: flex; flex: 1; margin-left: 1rem;" class:is_short={manager?.ui_type == "short"}>
|
|
111
117
|
<LoadingWheel size={2} />
|
|
112
|
-
{#if manager?.ui_type !=
|
|
113
|
-
<p style="margin-left: 1rem;" class:is_short={manager?.ui_type ==
|
|
118
|
+
{#if manager?.ui_type != "standard"}
|
|
119
|
+
<p style="margin-left: 1rem;" class:is_short={manager?.ui_type == "short"}>Loading...</p>
|
|
114
120
|
{/if}
|
|
115
121
|
</div>
|
|
116
122
|
{:else}
|
|
117
123
|
<Button manager={manager?.play_pause_button_manager} />
|
|
118
|
-
<div class="slider_box" class:is_short={manager?.ui_type ==
|
|
124
|
+
<div class="slider_box" class:is_short={manager?.ui_type == "short"}>
|
|
119
125
|
<span>{manager?.formatted_current_time}</span>
|
|
120
|
-
{#if manager?.ui_type ==
|
|
121
|
-
<div style="display: flex; flex: 1; flex-direction: column;" class:is_short={manager?.ui_type ==
|
|
126
|
+
{#if manager?.ui_type == "standard"}
|
|
127
|
+
<div style="display: flex; flex: 1; flex-direction: column;" class:is_short={manager?.ui_type == "short"}>
|
|
122
128
|
<Slider manager={manager?.time_slider_manager} />
|
|
123
129
|
</div>
|
|
124
130
|
{:else}
|
|
@@ -128,7 +134,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
128
134
|
<span>{manager?.formatted_duration}</span>
|
|
129
135
|
{/if}
|
|
130
136
|
</div>
|
|
131
|
-
{#if manager?.ui_type ==
|
|
137
|
+
{#if manager?.ui_type == "standard"}
|
|
132
138
|
{@render settings()}
|
|
133
139
|
{/if}
|
|
134
140
|
{/if}
|
|
@@ -157,7 +163,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
157
163
|
0 0.2rem 1rem var(--shadow2),
|
|
158
164
|
inset 0 0 0 1px var(--shadow7-t);
|
|
159
165
|
}
|
|
160
|
-
.container_square{
|
|
166
|
+
.container_square {
|
|
161
167
|
display: flex;
|
|
162
168
|
flex-direction: column;
|
|
163
169
|
flex: 0;
|
|
@@ -27,6 +27,10 @@ export function create_audio_manager(config) {
|
|
|
27
27
|
let settings_button_manager = $state(null)
|
|
28
28
|
let volume_slider_manager = $state(null)
|
|
29
29
|
let rate_slider_manager = $state(null)
|
|
30
|
+
let is_show_download_button = $derived(set_closurable(config?.is_show_download_button, false))
|
|
31
|
+
let download_audio_button_manager = $state(null)
|
|
32
|
+
let download_is_loading = $state(false)
|
|
33
|
+
let download_error_message = $state(null)
|
|
30
34
|
|
|
31
35
|
let time_loaded_until = $state(0)
|
|
32
36
|
let time_highlight_range_start_percent = $derived((100 * time_slider_manager?.val) / time_slider_manager?.max)
|
|
@@ -293,6 +297,68 @@ export function create_audio_manager(config) {
|
|
|
293
297
|
is_loading = false
|
|
294
298
|
}
|
|
295
299
|
|
|
300
|
+
function mime_to_ext(mime) {
|
|
301
|
+
const v = String(mime || "").toLowerCase()
|
|
302
|
+
if (v.includes("mpeg")) return "mp3"
|
|
303
|
+
if (v.includes("mp4")) return "mp4"
|
|
304
|
+
if (v.includes("webm")) return "webm"
|
|
305
|
+
if (v.includes("ogg")) return "ogg"
|
|
306
|
+
if (v.includes("wav")) return "wav"
|
|
307
|
+
if (v.includes("flac")) return "flac"
|
|
308
|
+
if (v.includes("aac")) return "aac"
|
|
309
|
+
return "audio"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function safe_file_base(input) {
|
|
313
|
+
const s = String(input || "").trim()
|
|
314
|
+
if (!s) return "audio"
|
|
315
|
+
return (
|
|
316
|
+
s
|
|
317
|
+
.replace(/\.[a-z0-9]+$/i, "")
|
|
318
|
+
.replace(/[^a-z0-9_\- ]/gi, "")
|
|
319
|
+
.trim()
|
|
320
|
+
.replace(/\s+/g, "_")
|
|
321
|
+
.slice(0, 80)
|
|
322
|
+
.toLowerCase() || "audio"
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function download_audio() {
|
|
327
|
+
if (!browser) return
|
|
328
|
+
download_error_message = null
|
|
329
|
+
if (!src) {
|
|
330
|
+
download_error_message = "missing src"
|
|
331
|
+
return
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
download_is_loading = true
|
|
335
|
+
const res = await fetch(src)
|
|
336
|
+
if (!res.ok) {
|
|
337
|
+
const t = await res.text().catch(() => null)
|
|
338
|
+
download_error_message = t || `download failed (${res.status})`
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
const content_type = res.headers.get("content-type") || type || "audio/mpeg"
|
|
342
|
+
const blob = await res.blob()
|
|
343
|
+
const ext = mime_to_ext(content_type || blob.type)
|
|
344
|
+
const base = safe_file_base(title || album || artist || "recording")
|
|
345
|
+
const file_name = `${base}.${ext}`
|
|
346
|
+
const object_url = URL.createObjectURL(blob)
|
|
347
|
+
const a = document.createElement("a")
|
|
348
|
+
a.href = object_url
|
|
349
|
+
a.download = file_name
|
|
350
|
+
a.rel = "noopener"
|
|
351
|
+
document.body.appendChild(a)
|
|
352
|
+
a.click()
|
|
353
|
+
a.remove()
|
|
354
|
+
setTimeout(() => URL.revokeObjectURL(object_url), 1000)
|
|
355
|
+
} catch (e) {
|
|
356
|
+
download_error_message = e?.message || "download failed"
|
|
357
|
+
} finally {
|
|
358
|
+
download_is_loading = false
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
296
362
|
function init(config) {
|
|
297
363
|
storage_path = config?.storage_path
|
|
298
364
|
src = get_src(config?.src, config?.storage_id)
|
|
@@ -364,6 +430,14 @@ export function create_audio_manager(config) {
|
|
|
364
430
|
val: 1,
|
|
365
431
|
on_change: (input) => handle_rate_change(input),
|
|
366
432
|
})
|
|
433
|
+
download_audio_button_manager = create_button_manager({
|
|
434
|
+
type: "outlined",
|
|
435
|
+
mt: 1,
|
|
436
|
+
text: "Download",
|
|
437
|
+
support_icon: "download",
|
|
438
|
+
is_loading: () => download_is_loading,
|
|
439
|
+
on_click: () => download_audio(),
|
|
440
|
+
})
|
|
367
441
|
}
|
|
368
442
|
|
|
369
443
|
init(config)
|
|
@@ -442,6 +516,12 @@ export function create_audio_manager(config) {
|
|
|
442
516
|
get is_loading() {
|
|
443
517
|
return is_loading
|
|
444
518
|
},
|
|
519
|
+
get download_audio_button_manager() {
|
|
520
|
+
return download_audio_button_manager
|
|
521
|
+
},
|
|
522
|
+
get is_show_download_button() {
|
|
523
|
+
return is_show_download_button
|
|
524
|
+
},
|
|
445
525
|
handle_mount,
|
|
446
526
|
handle_loaded_metadata,
|
|
447
527
|
handle_progress,
|
package/package.json
CHANGED
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
let { manager } = $props()
|
|
9
9
|
|
|
10
10
|
onMount(() => {
|
|
11
|
-
if(typeof manager?.handle_mount == "function"){
|
|
11
|
+
if (typeof manager?.handle_mount == "function") {
|
|
12
12
|
manager?.handle_mount()
|
|
13
13
|
}
|
|
14
14
|
})
|
|
15
|
-
|
|
16
|
-
|
|
17
15
|
</script>
|
|
18
16
|
|
|
19
17
|
{#snippet settings()}
|
|
@@ -23,6 +21,9 @@
|
|
|
23
21
|
<div>
|
|
24
22
|
<Slider manager={manager?.volume_slider_manager} />
|
|
25
23
|
<Slider manager={manager?.rate_slider_manager} />
|
|
24
|
+
{#if manager?.is_show_download_button}
|
|
25
|
+
<Button manager={manager?.download_audio_button_manager} />
|
|
26
|
+
{/if}
|
|
26
27
|
</div>
|
|
27
28
|
{/snippet}
|
|
28
29
|
</Popover>
|
|
@@ -53,7 +54,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
53
54
|
src={manager?.src}
|
|
54
55
|
type={manager?.type}
|
|
55
56
|
></audio>
|
|
56
|
-
{#if manager?.ui_type ==
|
|
57
|
+
{#if manager?.ui_type == "square"}
|
|
57
58
|
<div
|
|
58
59
|
class="container_square"
|
|
59
60
|
style="margin-left: {manager?.ml}rem; margin-right: {manager?.mr}rem; margin-top: {manager?.mt}rem; margin-bottom: {manager?.mb}rem;"
|
|
@@ -81,8 +82,13 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
81
82
|
</div>
|
|
82
83
|
<div style="display: flex;">
|
|
83
84
|
<Button manager={manager?.play_pause_button_manager} />
|
|
84
|
-
<div class="slider_box" class:is_short={manager?.ui_type ==
|
|
85
|
-
<span
|
|
85
|
+
<div class="slider_box" class:is_short={manager?.ui_type == "short"}>
|
|
86
|
+
<span
|
|
87
|
+
>{manager?.formatted_current_time}{manager?.time_slider_manager?.max &&
|
|
88
|
+
manager?.time_slider_manager?.max != Infinity
|
|
89
|
+
? ` / ${manager?.formatted_duration}`
|
|
90
|
+
: ""}</span
|
|
91
|
+
>
|
|
86
92
|
</div>
|
|
87
93
|
{@render settings()}
|
|
88
94
|
</div>
|
|
@@ -91,7 +97,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
91
97
|
{:else}
|
|
92
98
|
<div
|
|
93
99
|
class="container_line"
|
|
94
|
-
class:is_short={manager?.ui_type ==
|
|
100
|
+
class:is_short={manager?.ui_type == "short"}
|
|
95
101
|
style="margin-left: {manager?.ml}rem; margin-right: {manager?.mr}rem; margin-top: {manager?.mt}rem; margin-bottom: {manager?.mb}rem;"
|
|
96
102
|
>
|
|
97
103
|
{#if manager?.image_src && !manager?.is_hide_image}
|
|
@@ -105,20 +111,20 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
105
111
|
/>
|
|
106
112
|
{/if}
|
|
107
113
|
{#if !manager?.src}
|
|
108
|
-
<p style="display: flex; flex: 1;" class:is_short={manager?.ui_type ==
|
|
114
|
+
<p style="display: flex; flex: 1;" class:is_short={manager?.ui_type == "short"}>Missing Audio Source</p>
|
|
109
115
|
{:else if manager?.is_loading && !manager?.time_slider_manager?.max}
|
|
110
|
-
<div style="display: flex; flex: 1; margin-left: 1rem;" class:is_short={manager?.ui_type ==
|
|
116
|
+
<div style="display: flex; flex: 1; margin-left: 1rem;" class:is_short={manager?.ui_type == "short"}>
|
|
111
117
|
<LoadingWheel size={2} />
|
|
112
|
-
{#if manager?.ui_type !=
|
|
113
|
-
<p style="margin-left: 1rem;" class:is_short={manager?.ui_type ==
|
|
118
|
+
{#if manager?.ui_type != "standard"}
|
|
119
|
+
<p style="margin-left: 1rem;" class:is_short={manager?.ui_type == "short"}>Loading...</p>
|
|
114
120
|
{/if}
|
|
115
121
|
</div>
|
|
116
122
|
{:else}
|
|
117
123
|
<Button manager={manager?.play_pause_button_manager} />
|
|
118
|
-
<div class="slider_box" class:is_short={manager?.ui_type ==
|
|
124
|
+
<div class="slider_box" class:is_short={manager?.ui_type == "short"}>
|
|
119
125
|
<span>{manager?.formatted_current_time}</span>
|
|
120
|
-
{#if manager?.ui_type ==
|
|
121
|
-
<div style="display: flex; flex: 1; flex-direction: column;" class:is_short={manager?.ui_type ==
|
|
126
|
+
{#if manager?.ui_type == "standard"}
|
|
127
|
+
<div style="display: flex; flex: 1; flex-direction: column;" class:is_short={manager?.ui_type == "short"}>
|
|
122
128
|
<Slider manager={manager?.time_slider_manager} />
|
|
123
129
|
</div>
|
|
124
130
|
{:else}
|
|
@@ -128,7 +134,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
128
134
|
<span>{manager?.formatted_duration}</span>
|
|
129
135
|
{/if}
|
|
130
136
|
</div>
|
|
131
|
-
{#if manager?.ui_type ==
|
|
137
|
+
{#if manager?.ui_type == "standard"}
|
|
132
138
|
{@render settings()}
|
|
133
139
|
{/if}
|
|
134
140
|
{/if}
|
|
@@ -157,7 +163,7 @@ onabort={(e) => console.log('abort',e)} -->
|
|
|
157
163
|
0 0.2rem 1rem var(--shadow2),
|
|
158
164
|
inset 0 0 0 1px var(--shadow7-t);
|
|
159
165
|
}
|
|
160
|
-
.container_square{
|
|
166
|
+
.container_square {
|
|
161
167
|
display: flex;
|
|
162
168
|
flex-direction: column;
|
|
163
169
|
flex: 0;
|
|
@@ -27,6 +27,10 @@ export function create_audio_manager(config) {
|
|
|
27
27
|
let settings_button_manager = $state(null)
|
|
28
28
|
let volume_slider_manager = $state(null)
|
|
29
29
|
let rate_slider_manager = $state(null)
|
|
30
|
+
let is_show_download_button = $derived(set_closurable(config?.is_show_download_button, false))
|
|
31
|
+
let download_audio_button_manager = $state(null)
|
|
32
|
+
let download_is_loading = $state(false)
|
|
33
|
+
let download_error_message = $state(null)
|
|
30
34
|
|
|
31
35
|
let time_loaded_until = $state(0)
|
|
32
36
|
let time_highlight_range_start_percent = $derived((100 * time_slider_manager?.val) / time_slider_manager?.max)
|
|
@@ -293,6 +297,68 @@ export function create_audio_manager(config) {
|
|
|
293
297
|
is_loading = false
|
|
294
298
|
}
|
|
295
299
|
|
|
300
|
+
function mime_to_ext(mime) {
|
|
301
|
+
const v = String(mime || "").toLowerCase()
|
|
302
|
+
if (v.includes("mpeg")) return "mp3"
|
|
303
|
+
if (v.includes("mp4")) return "mp4"
|
|
304
|
+
if (v.includes("webm")) return "webm"
|
|
305
|
+
if (v.includes("ogg")) return "ogg"
|
|
306
|
+
if (v.includes("wav")) return "wav"
|
|
307
|
+
if (v.includes("flac")) return "flac"
|
|
308
|
+
if (v.includes("aac")) return "aac"
|
|
309
|
+
return "audio"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function safe_file_base(input) {
|
|
313
|
+
const s = String(input || "").trim()
|
|
314
|
+
if (!s) return "audio"
|
|
315
|
+
return (
|
|
316
|
+
s
|
|
317
|
+
.replace(/\.[a-z0-9]+$/i, "")
|
|
318
|
+
.replace(/[^a-z0-9_\- ]/gi, "")
|
|
319
|
+
.trim()
|
|
320
|
+
.replace(/\s+/g, "_")
|
|
321
|
+
.slice(0, 80)
|
|
322
|
+
.toLowerCase() || "audio"
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function download_audio() {
|
|
327
|
+
if (!browser) return
|
|
328
|
+
download_error_message = null
|
|
329
|
+
if (!src) {
|
|
330
|
+
download_error_message = "missing src"
|
|
331
|
+
return
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
download_is_loading = true
|
|
335
|
+
const res = await fetch(src)
|
|
336
|
+
if (!res.ok) {
|
|
337
|
+
const t = await res.text().catch(() => null)
|
|
338
|
+
download_error_message = t || `download failed (${res.status})`
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
const content_type = res.headers.get("content-type") || type || "audio/mpeg"
|
|
342
|
+
const blob = await res.blob()
|
|
343
|
+
const ext = mime_to_ext(content_type || blob.type)
|
|
344
|
+
const base = safe_file_base(title || album || artist || "recording")
|
|
345
|
+
const file_name = `${base}.${ext}`
|
|
346
|
+
const object_url = URL.createObjectURL(blob)
|
|
347
|
+
const a = document.createElement("a")
|
|
348
|
+
a.href = object_url
|
|
349
|
+
a.download = file_name
|
|
350
|
+
a.rel = "noopener"
|
|
351
|
+
document.body.appendChild(a)
|
|
352
|
+
a.click()
|
|
353
|
+
a.remove()
|
|
354
|
+
setTimeout(() => URL.revokeObjectURL(object_url), 1000)
|
|
355
|
+
} catch (e) {
|
|
356
|
+
download_error_message = e?.message || "download failed"
|
|
357
|
+
} finally {
|
|
358
|
+
download_is_loading = false
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
296
362
|
function init(config) {
|
|
297
363
|
storage_path = config?.storage_path
|
|
298
364
|
src = get_src(config?.src, config?.storage_id)
|
|
@@ -364,6 +430,14 @@ export function create_audio_manager(config) {
|
|
|
364
430
|
val: 1,
|
|
365
431
|
on_change: (input) => handle_rate_change(input),
|
|
366
432
|
})
|
|
433
|
+
download_audio_button_manager = create_button_manager({
|
|
434
|
+
type: "outlined",
|
|
435
|
+
mt: 1,
|
|
436
|
+
text: "Download",
|
|
437
|
+
support_icon: "download",
|
|
438
|
+
is_loading: () => download_is_loading,
|
|
439
|
+
on_click: () => download_audio(),
|
|
440
|
+
})
|
|
367
441
|
}
|
|
368
442
|
|
|
369
443
|
init(config)
|
|
@@ -442,6 +516,12 @@ export function create_audio_manager(config) {
|
|
|
442
516
|
get is_loading() {
|
|
443
517
|
return is_loading
|
|
444
518
|
},
|
|
519
|
+
get download_audio_button_manager() {
|
|
520
|
+
return download_audio_button_manager
|
|
521
|
+
},
|
|
522
|
+
get is_show_download_button() {
|
|
523
|
+
return is_show_download_button
|
|
524
|
+
},
|
|
445
525
|
handle_mount,
|
|
446
526
|
handle_loaded_metadata,
|
|
447
527
|
handle_progress,
|