@streamscloud/embeddable 13.2.0 → 13.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/dist/media-center/media-center/discover/community-features.svelte +2 -1
- package/dist/media-center/media-center/discover/discover-header.svelte +1 -0
- package/dist/media-center/media-center/discover/discover-view.svelte +1 -0
- package/dist/posts/post-viewer/attachments-horizontal.svelte +1 -0
- package/dist/posts/post-viewer/media/post-media.svelte +3 -3
- package/dist/ui/player/slider/cmp.player-slider.svelte +22 -15
- package/dist/ui/{slider → player/slider-horizontal}/cmp.slider.svelte +51 -28
- package/dist/ui/{slider → player/slider-horizontal}/cmp.slider.svelte.d.ts +1 -1
- package/dist/ui/player/slider-horizontal/index.d.ts +2 -0
- package/dist/ui/player/slider-horizontal/index.js +2 -0
- package/dist/ui/{slider → player/slider-horizontal}/slider-localization.d.ts +1 -1
- package/dist/ui/{slider → player/slider-horizontal}/slider-localization.js +1 -1
- package/dist/ui/player/utils/index.d.ts +1 -0
- package/dist/ui/player/utils/index.js +1 -0
- package/dist/ui/player/utils/touch-synchronizer.d.ts +7 -0
- package/dist/ui/player/utils/touch-synchronizer.js +21 -0
- package/package.json +1 -1
- package/dist/ui/slider/index.d.ts +0 -2
- package/dist/ui/slider/index.js +0 -2
- /package/dist/ui/{slider → player/slider-horizontal}/types.d.ts +0 -0
- /package/dist/ui/{slider → player/slider-horizontal}/types.js +0 -0
|
@@ -111,8 +111,9 @@ const onJoinMembershipClick = () => __awaiter(void 0, void 0, void 0, function*
|
|
|
111
111
|
display: flex;
|
|
112
112
|
flex-wrap: nowrap;
|
|
113
113
|
margin-top: 0.25rem;
|
|
114
|
-
gap: 8.125rem;
|
|
115
114
|
align-items: center;
|
|
115
|
+
max-width: 19.6875rem;
|
|
116
|
+
justify-content: space-between;
|
|
116
117
|
/* Set 'container-type: inline-size;' to reference container*/
|
|
117
118
|
}
|
|
118
119
|
@container (width < 576px) {
|
|
@@ -77,6 +77,7 @@ const localization = $derived(new DiscoverViewLocalization(context.locale));
|
|
|
77
77
|
flex: 1;
|
|
78
78
|
scrollbar-gutter: stable both-edges;
|
|
79
79
|
padding-inline: 1.875rem;
|
|
80
|
+
overflow-x: hidden;
|
|
80
81
|
overflow-y: auto;
|
|
81
82
|
--_cross-browser-scrollbar--thumb-color: transparent;
|
|
82
83
|
--_cross-browser-scrollbar--track-color: transparent;
|
|
@@ -168,6 +168,7 @@ const variables = $derived.by(() => {
|
|
|
168
168
|
overflow-x: auto;
|
|
169
169
|
padding-inline: var(--_post-viewer--attachments-horizontal--padding-inline);
|
|
170
170
|
scrollbar-width: none;
|
|
171
|
+
overscroll-behavior: none;
|
|
171
172
|
}
|
|
172
173
|
.attachments-horizontal__item {
|
|
173
174
|
position: relative;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { Image } from '../../../ui/image';
|
|
2
|
-
import {
|
|
2
|
+
import { SliderHorizontal } from '../../../ui/player/slider-horizontal';
|
|
3
3
|
import { Video } from '../../../ui/video';
|
|
4
4
|
let { id, media, locale, autoplay = 'on-appearance', on } = $props();
|
|
5
5
|
</script>
|
|
@@ -26,11 +26,11 @@ let { id, media, locale, autoplay = 'on-appearance', on } = $props();
|
|
|
26
26
|
{#if media.items.length === 1}
|
|
27
27
|
{@render mediaItem(media.items[0])}
|
|
28
28
|
{:else if media.items.length > 1}
|
|
29
|
-
<
|
|
29
|
+
<SliderHorizontal items={media.items} initialIndex={media.currentIndex} locale={locale} on={{ indexChanged: (index) => (media.currentIndex = index) }}>
|
|
30
30
|
{#snippet children(item)}
|
|
31
31
|
{@render mediaItem(item)}
|
|
32
32
|
{/snippet}
|
|
33
|
-
</
|
|
33
|
+
</SliderHorizontal>
|
|
34
34
|
{/if}
|
|
35
35
|
</div>
|
|
36
36
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { TouchSynchronizer } from '../utils';
|
|
2
|
+
import { createWheelAdapter } from './wheel-gestures-adapter';
|
|
2
3
|
import { onDestroy, onMount, untrack } from 'svelte';
|
|
3
4
|
let { buffer, on, children } = $props();
|
|
4
5
|
let slidesRef;
|
|
@@ -43,21 +44,27 @@ onMount(() => {
|
|
|
43
44
|
let touchStartY = 0;
|
|
44
45
|
let touchMoveY = 0;
|
|
45
46
|
let touchStartTime = 0;
|
|
46
|
-
let
|
|
47
|
+
let swipeState = 'not-initialized';
|
|
47
48
|
window.addEventListener(`keydown`, onKeyPress);
|
|
48
49
|
slidesRef.addEventListener('touchstart', (e) => {
|
|
50
|
+
TouchSynchronizer.touchStarted(slidesRef);
|
|
49
51
|
// The movement gets all janky if there's a transition on the elements.
|
|
50
52
|
slidesRef.classList.toggle('animate', false);
|
|
51
53
|
touchStartX = e.changedTouches[0].screenX;
|
|
52
54
|
touchStartY = e.changedTouches[0].screenY;
|
|
53
55
|
touchStartTime = Date.now();
|
|
54
|
-
|
|
56
|
+
swipeState = 'not-initialized';
|
|
55
57
|
}, { passive: true });
|
|
56
58
|
slidesRef.addEventListener('touchmove', (e) => {
|
|
57
|
-
if (
|
|
59
|
+
if (swipeState === 'vertical') {
|
|
58
60
|
// Already determined this is a vertical swipe
|
|
59
61
|
e.preventDefault();
|
|
60
62
|
e.stopPropagation();
|
|
63
|
+
TouchSynchronizer.touchMovePropagationBlocked(slidesRef);
|
|
64
|
+
}
|
|
65
|
+
else if (swipeState === 'horizontal') {
|
|
66
|
+
// Already determined this is a horizontal swipe
|
|
67
|
+
return;
|
|
61
68
|
}
|
|
62
69
|
const touchCurrentX = e.changedTouches[0].screenX;
|
|
63
70
|
const touchCurrentY = e.changedTouches[0].screenY;
|
|
@@ -67,9 +74,10 @@ onMount(() => {
|
|
|
67
74
|
if (diffX > 10 || diffY > 10) {
|
|
68
75
|
if (diffY > diffX) {
|
|
69
76
|
// Vertical swipe - handle it
|
|
70
|
-
|
|
77
|
+
swipeState = 'vertical';
|
|
71
78
|
e.preventDefault();
|
|
72
79
|
e.stopPropagation();
|
|
80
|
+
TouchSynchronizer.touchMovePropagationBlocked(slidesRef);
|
|
73
81
|
const newPosition = touchCurrentY;
|
|
74
82
|
const diff = newPosition - touchStartY;
|
|
75
83
|
if ((diff > 0 && buffer.canLoadPrevious) || (diff < 0 && buffer.canLoadNext)) {
|
|
@@ -79,28 +87,27 @@ onMount(() => {
|
|
|
79
87
|
}
|
|
80
88
|
else {
|
|
81
89
|
// Horizontal swipe - allow child to handle
|
|
82
|
-
|
|
90
|
+
swipeState = 'horizontal';
|
|
83
91
|
return;
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
94
|
}, { passive: false });
|
|
87
95
|
slidesRef.addEventListener('touchend', (e) => {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
const reset = () => {
|
|
97
|
+
swipeTransition = 0;
|
|
98
|
+
touchMoveY = 0;
|
|
99
|
+
};
|
|
92
100
|
// Check if this is a vertical swipe
|
|
93
|
-
if (
|
|
101
|
+
if (swipeState !== 'vertical') {
|
|
94
102
|
// Horizontal swipe - don't handle and don't block
|
|
103
|
+
reset();
|
|
95
104
|
return;
|
|
96
105
|
}
|
|
97
106
|
// This is a vertical swipe - block propagation
|
|
98
107
|
e.stopPropagation();
|
|
108
|
+
TouchSynchronizer.touchEndPropatationBlocked(slidesRef);
|
|
109
|
+
TouchSynchronizer.touchEnded(slidesRef);
|
|
99
110
|
slidesRef.classList.toggle('animate', true);
|
|
100
|
-
const reset = () => {
|
|
101
|
-
swipeTransition = 0;
|
|
102
|
-
touchMoveY = 0;
|
|
103
|
-
};
|
|
104
111
|
const isFastSwipe = Date.now() - touchStartTime < 300;
|
|
105
112
|
if (!touchMoveY || (!isFastSwipe && Math.abs(touchMoveY) < sliderHeight / 6)) {
|
|
106
113
|
return reset();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
<script lang="ts">import { runningInBrowser } from '
|
|
2
|
-
import { Utils } from '
|
|
3
|
-
import { HtmlHelper } from '
|
|
4
|
-
import { Icon } from '
|
|
1
|
+
<script lang="ts">import { runningInBrowser } from '../../../core/browser';
|
|
2
|
+
import { Utils } from '../../../core/utils';
|
|
3
|
+
import { HtmlHelper } from '../../../core/utils/html-helper';
|
|
4
|
+
import { Icon } from '../../icon';
|
|
5
|
+
import { TouchSynchronizer } from '../utils';
|
|
5
6
|
import { SliderLocalization } from './slider-localization';
|
|
6
7
|
import { SliderMode } from './types';
|
|
7
8
|
import IconChevronLeft from '@fluentui/svg-icons/icons/chevron_left_20_regular.svg?raw';
|
|
@@ -13,13 +14,14 @@ let { items, sliderMode = SliderMode.ArrowsWithCounts, dotsConfig = {
|
|
|
13
14
|
}, locale, initialIndex, autoSlideMs = 0, on, children } = $props();
|
|
14
15
|
const localization = $derived.by(() => new SliderLocalization(locale));
|
|
15
16
|
const itemIndices = $derived(items.map((_, index) => index));
|
|
16
|
-
const animationDuration =
|
|
17
|
+
const animationDuration = 300;
|
|
17
18
|
let previousItems = $state.raw(undefined);
|
|
18
19
|
let selectedIndex = $state(initialIndex);
|
|
19
20
|
let animationIndex = $state(null);
|
|
20
21
|
let interval;
|
|
21
22
|
let slidesRef;
|
|
22
23
|
let sliderWidth = $state(0);
|
|
24
|
+
let swipeTransition = $state(0);
|
|
23
25
|
let resizeObserver;
|
|
24
26
|
onMount(() => {
|
|
25
27
|
notifyIndexChanged();
|
|
@@ -28,19 +30,26 @@ onMount(() => {
|
|
|
28
30
|
});
|
|
29
31
|
let touchStartX = 0;
|
|
30
32
|
let touchStartY = 0;
|
|
33
|
+
let touchMoveX = 0;
|
|
31
34
|
let touchStartTime = 0;
|
|
32
|
-
let
|
|
35
|
+
let swipeState = 'not-initialized';
|
|
33
36
|
slidesRef.addEventListener('touchstart', (e) => {
|
|
37
|
+
TouchSynchronizer.touchStarted(slidesRef);
|
|
38
|
+
slidesRef.classList.toggle('animate', false);
|
|
34
39
|
touchStartX = e.changedTouches[0].screenX;
|
|
35
40
|
touchStartY = e.changedTouches[0].screenY;
|
|
36
41
|
touchStartTime = Date.now();
|
|
37
|
-
|
|
42
|
+
swipeState = 'not-initialized';
|
|
38
43
|
}, { passive: true });
|
|
39
44
|
slidesRef.addEventListener('touchmove', (e) => {
|
|
40
|
-
if (
|
|
45
|
+
if (swipeState === 'horizontal') {
|
|
41
46
|
// Already determined this is a horizontal swipe
|
|
42
47
|
e.preventDefault();
|
|
43
48
|
e.stopPropagation();
|
|
49
|
+
TouchSynchronizer.touchMovePropagationBlocked(slidesRef);
|
|
50
|
+
}
|
|
51
|
+
else if (swipeState === 'vertical') {
|
|
52
|
+
// Already determined this is a vertical swipe
|
|
44
53
|
return;
|
|
45
54
|
}
|
|
46
55
|
const touchCurrentX = e.changedTouches[0].screenX;
|
|
@@ -51,39 +60,49 @@ onMount(() => {
|
|
|
51
60
|
if (diffX > 10 || diffY > 10) {
|
|
52
61
|
if (diffX > diffY) {
|
|
53
62
|
// Horizontal swipe - block vertical scroll
|
|
54
|
-
|
|
63
|
+
swipeState = 'horizontal';
|
|
55
64
|
e.preventDefault();
|
|
56
65
|
e.stopPropagation();
|
|
66
|
+
TouchSynchronizer.touchMovePropagationBlocked(slidesRef);
|
|
67
|
+
touchMoveX = touchCurrentX - touchStartX;
|
|
68
|
+
const basePosition = -sliderWidth * (animationIndex === null ? selectedIndex + 1 : animationIndex);
|
|
69
|
+
swipeTransition = basePosition + touchMoveX;
|
|
57
70
|
}
|
|
58
71
|
else {
|
|
59
72
|
// Vertical swipe - allow parent to handle
|
|
60
|
-
|
|
73
|
+
swipeState = 'vertical';
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
|
-
});
|
|
76
|
+
}, { passive: false });
|
|
64
77
|
slidesRef.addEventListener('touchend', (e) => {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
const reset = () => {
|
|
79
|
+
swipeTransition = 0;
|
|
80
|
+
touchMoveX = 0;
|
|
81
|
+
};
|
|
69
82
|
// Check if this is a horizontal swipe
|
|
70
|
-
if (
|
|
83
|
+
if (swipeState !== 'horizontal') {
|
|
84
|
+
reset();
|
|
71
85
|
return;
|
|
72
86
|
}
|
|
73
87
|
// This is a horizontal swipe - block propagation
|
|
74
88
|
e.stopPropagation();
|
|
75
89
|
e.preventDefault();
|
|
90
|
+
slidesRef.classList.toggle('animate', true);
|
|
91
|
+
TouchSynchronizer.touchEndPropatationBlocked(slidesRef);
|
|
92
|
+
TouchSynchronizer.touchEnded(slidesRef);
|
|
76
93
|
const isFastSwipe = Date.now() - touchStartTime < 300;
|
|
77
|
-
if (!isFastSwipe &&
|
|
94
|
+
if (!isFastSwipe && Math.abs(touchMoveX) < sliderWidth / 6) {
|
|
95
|
+
reset();
|
|
78
96
|
return;
|
|
79
97
|
}
|
|
80
|
-
if (
|
|
98
|
+
if (touchMoveX < 0) {
|
|
81
99
|
loadNext();
|
|
82
100
|
}
|
|
83
|
-
|
|
101
|
+
else {
|
|
84
102
|
loadPrevious();
|
|
85
103
|
}
|
|
86
|
-
|
|
104
|
+
reset();
|
|
105
|
+
}, { passive: false });
|
|
87
106
|
slidesRef.addEventListener('transitionend', (e) => {
|
|
88
107
|
e.stopPropagation();
|
|
89
108
|
if (animationIndex !== null && animationIndex > items.length - 1) {
|
|
@@ -166,16 +185,23 @@ const setIndex = (index) => {
|
|
|
166
185
|
};
|
|
167
186
|
const loadPrevious = Utils.throttle(() => {
|
|
168
187
|
setIndex(--selectedIndex);
|
|
169
|
-
},
|
|
188
|
+
}, animationDuration);
|
|
170
189
|
const loadNext = Utils.throttle(() => {
|
|
171
190
|
setIndex(++selectedIndex);
|
|
172
|
-
},
|
|
191
|
+
}, animationDuration);
|
|
173
192
|
$effect(() => {
|
|
174
193
|
if (previousItems && items !== previousItems) {
|
|
175
194
|
setIndex(0);
|
|
176
195
|
}
|
|
177
196
|
previousItems = items;
|
|
178
197
|
});
|
|
198
|
+
const styles = $derived.by(() => {
|
|
199
|
+
const values = [
|
|
200
|
+
`transform: translateX(${swipeTransition || (items.length > 1 ? -sliderWidth * (animationIndex === null ? selectedIndex + 1 : animationIndex) : 0)}px)`,
|
|
201
|
+
`--_slider-horizontal--animation: ${animationDuration}ms ease-out transform`
|
|
202
|
+
];
|
|
203
|
+
return values.join(';');
|
|
204
|
+
});
|
|
179
205
|
const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.ArrowsOnly, SliderMode.DotsOnly, SliderMode.DotsOnlyBelow].includes(sliderMode));
|
|
180
206
|
</script>
|
|
181
207
|
|
|
@@ -186,12 +212,9 @@ const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.
|
|
|
186
212
|
class:slider--dots-only={sliderMode === SliderMode.DotsOnly}
|
|
187
213
|
class:slider--dots-only-below={sliderMode === SliderMode.DotsOnlyBelow}
|
|
188
214
|
class:slider--arrows-with-counts={sliderMode === SliderMode.ArrowsWithCounts}>
|
|
189
|
-
<div
|
|
190
|
-
class="slider__slides"
|
|
191
|
-
bind:this={slidesRef}
|
|
192
|
-
style={`transform: translateX(${items.length > 1 ? -sliderWidth * (animationIndex === null ? selectedIndex + 1 : animationIndex) : 0}px)`}>
|
|
215
|
+
<div class="slider__slides" bind:this={slidesRef} style={styles}>
|
|
193
216
|
{#if items.length > 1}
|
|
194
|
-
<div class="slider__slide"
|
|
217
|
+
<div class="slider__slide">
|
|
195
218
|
{#if children}
|
|
196
219
|
{@render children(items[items.length - 1])}
|
|
197
220
|
{/if}
|
|
@@ -268,7 +291,7 @@ const showClassicArrowsAndDots = $derived([SliderMode.ArrowsAndDots, SliderMode.
|
|
|
268
291
|
height: 100%;
|
|
269
292
|
}
|
|
270
293
|
.slider__slides:global(.animate) {
|
|
271
|
-
transition:
|
|
294
|
+
transition: var(--_slider-horizontal--animation);
|
|
272
295
|
}
|
|
273
296
|
.slider__slide {
|
|
274
297
|
display: flex;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TouchSynchronizer } from './touch-synchronizer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TouchSynchronizer } from './touch-synchronizer';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare class TouchSynchronizer {
|
|
2
|
+
private static listeners;
|
|
3
|
+
static touchStarted: (ref: HTMLElement) => void;
|
|
4
|
+
static touchMovePropagationBlocked: (ref: HTMLElement) => void;
|
|
5
|
+
static touchEndPropatationBlocked: (ref: HTMLElement) => void;
|
|
6
|
+
static touchEnded: (ref: HTMLElement) => void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class TouchSynchronizer {
|
|
2
|
+
static listeners = [];
|
|
3
|
+
static touchStarted = (ref) => {
|
|
4
|
+
TouchSynchronizer.listeners.push(ref);
|
|
5
|
+
};
|
|
6
|
+
static touchMovePropagationBlocked = (ref) => {
|
|
7
|
+
const otherListeners = TouchSynchronizer.listeners.filter((r) => r !== ref);
|
|
8
|
+
otherListeners.forEach((r) => {
|
|
9
|
+
r.dispatchEvent(new TouchEvent('touchend', { cancelable: false }));
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
static touchEndPropatationBlocked = (ref) => {
|
|
13
|
+
const otherListeners = TouchSynchronizer.listeners.filter((r) => r !== ref);
|
|
14
|
+
otherListeners.forEach((r) => {
|
|
15
|
+
r.dispatchEvent(new TouchEvent('touchend', { cancelable: false }));
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
static touchEnded = (ref) => {
|
|
19
|
+
TouchSynchronizer.listeners = TouchSynchronizer.listeners.filter((r) => r !== ref);
|
|
20
|
+
};
|
|
21
|
+
}
|
package/package.json
CHANGED
package/dist/ui/slider/index.js
DELETED
|
File without changes
|
|
File without changes
|