@streamscloud/kit 0.2.26 → 0.2.27-1775564173889
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/ui/color-picker/cmp.color-picker.svelte +1 -1
- package/dist/ui/cropper/img-cropper/cmp.img-cropper-toolbar.svelte +1 -1
- package/dist/ui/emoji-picker/cmp.emoji-picker.svelte +1 -1
- package/dist/ui/inputs/input-emoji-picker/cmp.input-emoji-picker.svelte +1 -1
- package/dist/ui/video/cmp.video.svelte +59 -53
- package/dist/ui/video/cmp.video.svelte.d.ts +0 -2
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@ const onColorPickerInput = ({ hex }) => {
|
|
|
46
46
|
</script>
|
|
47
47
|
|
|
48
48
|
<div class="color-picker">
|
|
49
|
-
<Dropdown position="bottom-start" keepDropdownOpen>
|
|
49
|
+
<Dropdown position="bottom-start" keepDropdownOpen panel={false}>
|
|
50
50
|
{#snippet trigger()}
|
|
51
51
|
<div class="color-picker__trigger">
|
|
52
52
|
{#if children}
|
|
@@ -50,7 +50,7 @@ const selectedRatioLabel = $derived.by(() => {
|
|
|
50
50
|
{#if cropper.ratioOptions}
|
|
51
51
|
<div class="img-cropper-toolbar__ratio">
|
|
52
52
|
<span class="img-cropper-toolbar__label">{loc.ratio}</span>
|
|
53
|
-
<Dropdown position="top">
|
|
53
|
+
<Dropdown position="top" panel={false}>
|
|
54
54
|
{#snippet trigger()}
|
|
55
55
|
<div class="img-cropper-toolbar__ratio-trigger">{selectedRatioLabel}</div>
|
|
56
56
|
{/snippet}
|
|
@@ -5,7 +5,7 @@ import IconEmoji from '@fluentui/svg-icons/icons/emoji_20_regular.svg?raw';
|
|
|
5
5
|
let { dropdownPosition = 'bottom-end', on, children } = $props();
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
|
-
<Dropdown position={dropdownPosition} keepDropdownOpen={true}>
|
|
8
|
+
<Dropdown position={dropdownPosition} keepDropdownOpen={true} panel={false}>
|
|
9
9
|
{#snippet trigger()}
|
|
10
10
|
<div class="emoji-picker__trigger">
|
|
11
11
|
{#if children}
|
|
@@ -11,7 +11,7 @@ let { on } = $props();
|
|
|
11
11
|
</button>
|
|
12
12
|
|
|
13
13
|
<div class="input-emoji-picker">
|
|
14
|
-
<Dropdown position="bottom-end" matchTriggerWidth on={{ mounted: (e) => (toggleDropdown = e.toggleOpen) }} keepDropdownOpen={true}>
|
|
14
|
+
<Dropdown position="bottom-end" matchTriggerWidth panel={false} on={{ mounted: (e) => (toggleDropdown = e.toggleOpen) }} keepDropdownOpen={true}>
|
|
15
15
|
{#snippet trigger()}
|
|
16
16
|
<div class="input-emoji-picker__trigger-stub"></div>
|
|
17
17
|
{/snippet}
|
|
@@ -8,7 +8,7 @@ import IconSpeaker from '@fluentui/svg-icons/icons/speaker_2_20_regular.svg?raw'
|
|
|
8
8
|
import IconSpeakerMute from '@fluentui/svg-icons/icons/speaker_mute_20_regular.svg?raw';
|
|
9
9
|
import { untrack } from 'svelte';
|
|
10
10
|
import { fade } from 'svelte/transition';
|
|
11
|
-
let { src, poster, id = randomNanoid(),
|
|
11
|
+
let { src, poster, id = randomNanoid(), autoplay = false, loop = false, inert = false, allowPreloading = false, hideSpeaker = false, hidePlayButton = false, intersectionContainer, scrubberPosition = 'bottom', on } = $props();
|
|
12
12
|
let video = $state(null);
|
|
13
13
|
let videoContainerRef = $state(null);
|
|
14
14
|
let showControlsOnHover = $state(false);
|
|
@@ -25,6 +25,15 @@ $effect(() => {
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
|
+
// Eagerly load video on mount when no poster — show first frame immediately
|
|
29
|
+
$effect(() => {
|
|
30
|
+
if (!poster && video && !video.src) {
|
|
31
|
+
untrack(() => {
|
|
32
|
+
video.src = src;
|
|
33
|
+
video.load();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
28
37
|
// Register player instance in global playback manager
|
|
29
38
|
$effect(() => untrack(() => {
|
|
30
39
|
PlaybackManager.registerMountedPlayer(id, {
|
|
@@ -111,7 +120,7 @@ $effect(() => {
|
|
|
111
120
|
}
|
|
112
121
|
}, {
|
|
113
122
|
root: intersectionContainer,
|
|
114
|
-
rootMargin: '0px',
|
|
123
|
+
rootMargin: poster ? '0px' : '200px',
|
|
115
124
|
threshold: [0.1, 0.4, 0.6]
|
|
116
125
|
});
|
|
117
126
|
observer.observe(container);
|
|
@@ -229,12 +238,11 @@ const handleSeek = (percent) => {
|
|
|
229
238
|
<div class="video" role="none" inert={inert} bind:this={videoContainerRef}>
|
|
230
239
|
<video
|
|
231
240
|
class="video__video"
|
|
232
|
-
class:video__video--not-activated={!everActivated}
|
|
241
|
+
class:video__video--not-activated={!everActivated && !!poster}
|
|
233
242
|
width="100%"
|
|
234
|
-
controls={controls && everActivated}
|
|
235
243
|
poster={poster}
|
|
236
244
|
loop={loop}
|
|
237
|
-
preload=
|
|
245
|
+
preload={poster ? 'metadata' : 'auto'}
|
|
238
246
|
onvolumechange={onVolumeChange}
|
|
239
247
|
ontimeupdate={onTimeUpdate}
|
|
240
248
|
onloadeddata={onLoaded}
|
|
@@ -248,56 +256,54 @@ const handleSeek = (percent) => {
|
|
|
248
256
|
{#if !everActivated && poster}
|
|
249
257
|
<img class="video__poster" src={poster} alt="" />
|
|
250
258
|
{/if}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
{
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
{/if}
|
|
259
|
+
<div
|
|
260
|
+
class="video__overlay"
|
|
261
|
+
onclick={togglePlay}
|
|
262
|
+
onkeydown={() => ({})}
|
|
263
|
+
onmouseenter={() => (showControlsOnHover = true)}
|
|
264
|
+
onmouseleave={() => (showControlsOnHover = false)}
|
|
265
|
+
role="none">
|
|
266
|
+
{#if isVideoPaused && !hidePlayButton}
|
|
267
|
+
<button type="button" aria-label="play" class="video__playback-button" onclick={togglePlay} onkeydown={() => ({})}>
|
|
268
|
+
<Icon src={IconPlay} color="white" />
|
|
269
|
+
</button>
|
|
270
|
+
{:else if showControlsOnHover && !hidePlayButton}
|
|
271
|
+
<button type="button" aria-label="pause" class="video__playback-button video__playback-button--pause" onclick={togglePlay} onkeydown={() => ({})}>
|
|
272
|
+
<Icon src={IconPause} color="white" />
|
|
273
|
+
</button>
|
|
274
|
+
{/if}
|
|
268
275
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
{#if (showControlsOnHover || MediaVolumeManager.isMuted) && !hideSpeaker}
|
|
277
|
+
<button type="button" aria-label={MediaVolumeManager.isMuted ? 'mute' : 'unmute'} class="video__mute-button" onclick={toggleMute}>
|
|
278
|
+
{#if MediaVolumeManager.isMuted}
|
|
279
|
+
<Icon src={IconSpeakerMute} color="white" />
|
|
280
|
+
{:else}
|
|
281
|
+
<Icon src={IconSpeaker} color="white" />
|
|
282
|
+
{/if}
|
|
283
|
+
</button>
|
|
284
|
+
{/if}
|
|
278
285
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
{/if}
|
|
286
|
+
{#if everActivated}
|
|
287
|
+
<div
|
|
288
|
+
class="video__progress-container"
|
|
289
|
+
class:video__progress-container--top={scrubberPosition === 'top'}
|
|
290
|
+
class:video__progress-container--bottom={scrubberPosition === 'bottom'}
|
|
291
|
+
onmouseenter={() => (showProgressOnHover = true)}
|
|
292
|
+
onmouseleave={() => (showProgressOnHover = false)}
|
|
293
|
+
role="none">
|
|
294
|
+
{#if showProgressOnHover || (!showProgressOnHover && isVideoPaused)}
|
|
295
|
+
<div
|
|
296
|
+
class="video__seek-bar"
|
|
297
|
+
transition:fade={{ duration: isVideoPaused ? 0 : 300 }}
|
|
298
|
+
onclick={(e) => e.stopPropagation()}
|
|
299
|
+
onkeydown={() => ({})}
|
|
300
|
+
role="none">
|
|
301
|
+
<SeekBar value={percentageCompleted} on={{ seek: handleSeek }} />
|
|
302
|
+
</div>
|
|
303
|
+
{/if}
|
|
304
|
+
</div>
|
|
305
|
+
{/if}
|
|
306
|
+
</div>
|
|
301
307
|
</div>
|
|
302
308
|
|
|
303
309
|
<!--
|
|
@@ -6,8 +6,6 @@ type Props = {
|
|
|
6
6
|
poster: string | null | undefined;
|
|
7
7
|
/** Unique player ID for the global PlaybackManager @default nanoid() */
|
|
8
8
|
id?: string;
|
|
9
|
-
/** Show native browser controls once playback starts */
|
|
10
|
-
controls?: boolean;
|
|
11
9
|
/** Autoplay strategy: `true` plays immediately, `'on-appearance'` plays when scrolled into view */
|
|
12
10
|
autoplay?: true | false | 'on-appearance';
|
|
13
11
|
loop?: boolean;
|