@shortkitsdk/web 0.3.0 → 0.3.2
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/shortkit.cjs +237 -52
- package/dist/shortkit.js +237 -52
- package/dist/shortkit.min.js +1 -1
- package/dist/shortkit.mjs +237 -52
- package/dist/shortkit.slim.cjs +237 -52
- package/dist/shortkit.slim.js +237 -52
- package/dist/shortkit.slim.min.js +1 -1
- package/dist/shortkit.slim.mjs +237 -52
- package/package.json +1 -1
package/dist/shortkit.slim.js
CHANGED
|
@@ -603,16 +603,35 @@
|
|
|
603
603
|
player._skCurrentUrl = streamingUrl;
|
|
604
604
|
}
|
|
605
605
|
/**
|
|
606
|
-
* Promote a preload player to active: raise buffer limits
|
|
607
|
-
*
|
|
606
|
+
* Promote a preload player to active: raise buffer limits, uncap ABR, and
|
|
607
|
+
* force an immediate quality upgrade.
|
|
608
|
+
*
|
|
609
|
+
* Preload streams start at level 0 (lowest rendition) to conserve bandwidth.
|
|
610
|
+
* When attachStream() is called again with isActive=true for the same URL it
|
|
611
|
+
* early-returns, so the HLS instance keeps its startLevel:0 config. The
|
|
612
|
+
* already-buffered low-quality segments play through before any higher-quality
|
|
613
|
+
* segments arrive — causing a visible low-res start even on fast connections.
|
|
614
|
+
*
|
|
615
|
+
* Fix: lock HLS to the highest level, then seek-in-place to flush the
|
|
616
|
+
* low-quality buffer so the player immediately re-fetches at high quality.
|
|
617
|
+
* Re-enable ABR after a few seconds so slow connections self-correct.
|
|
608
618
|
*/
|
|
609
619
|
promoteToActive(itemId) {
|
|
610
620
|
const hls = this.hlsInstances.get(itemId);
|
|
611
|
-
if (hls)
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
621
|
+
if (!hls) return;
|
|
622
|
+
hls.config.maxBufferLength = PlayerPool.ACTIVE_HLS_CONFIG.maxBufferLength;
|
|
623
|
+
hls.config.maxMaxBufferLength = PlayerPool.ACTIVE_HLS_CONFIG.maxMaxBufferLength;
|
|
624
|
+
hls.autoLevelCapping = -1;
|
|
625
|
+
const top = hls.levels ? hls.levels.length - 1 : -1;
|
|
626
|
+
if (top > 0 && hls.currentLevel < top) {
|
|
627
|
+
hls.currentLevel = top;
|
|
628
|
+
const player = this.assignments.get(itemId);
|
|
629
|
+
if (player) {
|
|
630
|
+
player.currentTime = player.currentTime;
|
|
631
|
+
}
|
|
632
|
+
setTimeout(() => {
|
|
633
|
+
if (!hls.destroyed) hls.currentLevel = -1;
|
|
634
|
+
}, 4e3);
|
|
616
635
|
}
|
|
617
636
|
}
|
|
618
637
|
/** Pause, destroy HLS, and remove player from DOM and pool tracking. */
|
|
@@ -908,7 +927,7 @@
|
|
|
908
927
|
}
|
|
909
928
|
setMuted(muted) {
|
|
910
929
|
this.isMuted = muted;
|
|
911
|
-
for (const [, player] of this.pool.
|
|
930
|
+
for (const [, player] of this.pool.assignments) {
|
|
912
931
|
player.muted = muted;
|
|
913
932
|
}
|
|
914
933
|
this._pushPlayerState({ isMuted: muted });
|
|
@@ -921,7 +940,7 @@
|
|
|
921
940
|
}
|
|
922
941
|
setPlaybackRate(rate) {
|
|
923
942
|
this.playbackRate = rate;
|
|
924
|
-
for (const [, player] of this.pool.
|
|
943
|
+
for (const [, player] of this.pool.assignments) {
|
|
925
944
|
player.playbackRate = rate;
|
|
926
945
|
}
|
|
927
946
|
this._pushPlayerState({ playbackRate: rate });
|
|
@@ -1398,11 +1417,10 @@
|
|
|
1398
1417
|
const player = this.pool.getPlayer(id);
|
|
1399
1418
|
if (player) {
|
|
1400
1419
|
player.pause();
|
|
1401
|
-
player.style.opacity = "0";
|
|
1402
1420
|
player._skRevealedFor = null;
|
|
1403
1421
|
}
|
|
1404
1422
|
this._stopTimeLoop(id);
|
|
1405
|
-
this.
|
|
1423
|
+
this._detachOverlay(id);
|
|
1406
1424
|
this._sk._tracker.deactivateContent();
|
|
1407
1425
|
}
|
|
1408
1426
|
// --- Time loop ---
|
|
@@ -1584,14 +1602,20 @@
|
|
|
1584
1602
|
}
|
|
1585
1603
|
}
|
|
1586
1604
|
/** Clear the overlay container's DOM and unsubscribe tracked listeners. */
|
|
1587
|
-
|
|
1605
|
+
/** Unsubscribe overlay event listeners without clearing DOM. */
|
|
1606
|
+
_detachOverlay(itemId) {
|
|
1588
1607
|
const entry = this._overlayContainers.get(itemId);
|
|
1589
1608
|
if (!entry) return;
|
|
1590
1609
|
if (entry.unsub) {
|
|
1591
1610
|
entry.unsub();
|
|
1592
1611
|
entry.unsub = null;
|
|
1593
1612
|
}
|
|
1594
|
-
|
|
1613
|
+
}
|
|
1614
|
+
/** Unsubscribe and clear overlay DOM (used on destroy). */
|
|
1615
|
+
_clearOverlay(itemId) {
|
|
1616
|
+
this._detachOverlay(itemId);
|
|
1617
|
+
const entry = this._overlayContainers.get(itemId);
|
|
1618
|
+
if (entry) entry.el.innerHTML = "";
|
|
1595
1619
|
}
|
|
1596
1620
|
}
|
|
1597
1621
|
class EmbeddedFeedManager {
|
|
@@ -1640,6 +1664,7 @@
|
|
|
1640
1664
|
this._setupScrollEnd();
|
|
1641
1665
|
this._setupVisibilityHandler();
|
|
1642
1666
|
this._setupCellHeightObserver();
|
|
1667
|
+
this._setupDebugPanel();
|
|
1643
1668
|
if (startIndex > 0 && startIndex < items.length) {
|
|
1644
1669
|
const targetEl = this.itemEls.get(items[startIndex].id);
|
|
1645
1670
|
if (targetEl) targetEl.scrollIntoView({ behavior: "instant", block: "start" });
|
|
@@ -1662,6 +1687,11 @@
|
|
|
1662
1687
|
this._resizeObserver = null;
|
|
1663
1688
|
}
|
|
1664
1689
|
if (this._visHandler) document.removeEventListener("visibilitychange", this._visHandler);
|
|
1690
|
+
if (this._debugKeyHandler) document.removeEventListener("keydown", this._debugKeyHandler);
|
|
1691
|
+
if (this._debugPanel) {
|
|
1692
|
+
this._debugPanel.remove();
|
|
1693
|
+
this._debugPanel = null;
|
|
1694
|
+
}
|
|
1665
1695
|
this.container.innerHTML = "";
|
|
1666
1696
|
this.itemEls.clear();
|
|
1667
1697
|
this.items = [];
|
|
@@ -1705,7 +1735,7 @@
|
|
|
1705
1735
|
}
|
|
1706
1736
|
setMuted(muted) {
|
|
1707
1737
|
this.isMuted = muted;
|
|
1708
|
-
for (const [, player] of this.pool.
|
|
1738
|
+
for (const [, player] of this.pool.assignments) {
|
|
1709
1739
|
player.muted = muted;
|
|
1710
1740
|
}
|
|
1711
1741
|
this._pushPlayerState({ isMuted: muted });
|
|
@@ -1718,7 +1748,7 @@
|
|
|
1718
1748
|
}
|
|
1719
1749
|
setPlaybackRate(rate) {
|
|
1720
1750
|
this.playbackRate = rate;
|
|
1721
|
-
for (const [, player] of this.pool.
|
|
1751
|
+
for (const [, player] of this.pool.assignments) {
|
|
1722
1752
|
player.playbackRate = rate;
|
|
1723
1753
|
}
|
|
1724
1754
|
this._pushPlayerState({ playbackRate: rate });
|
|
@@ -1990,11 +2020,52 @@
|
|
|
1990
2020
|
const p = this.pool.getPlayer(id);
|
|
1991
2021
|
if (p) {
|
|
1992
2022
|
p.pause();
|
|
1993
|
-
p.style.opacity = "0";
|
|
1994
2023
|
p._skRevealedFor = null;
|
|
1995
2024
|
}
|
|
1996
2025
|
this._stopTimeLoop(id);
|
|
1997
|
-
this.
|
|
2026
|
+
this._detachOverlay(id);
|
|
2027
|
+
}
|
|
2028
|
+
// --- Debug panel (toggle with 'D' key) ---
|
|
2029
|
+
_setupDebugPanel() {
|
|
2030
|
+
const panel = document.createElement("div");
|
|
2031
|
+
panel.id = "sk-debug-panel";
|
|
2032
|
+
panel.style.cssText = "position:fixed;top:12px;right:12px;z-index:99999;background:rgba(0,0,0,.85);color:#0f0;font:12px/1.5 monospace;padding:10px 14px;border-radius:8px;pointer-events:none;display:none;min-width:220px;";
|
|
2033
|
+
document.body.appendChild(panel);
|
|
2034
|
+
this._debugPanel = panel;
|
|
2035
|
+
this._debugVisible = false;
|
|
2036
|
+
this._debugKeyHandler = (e) => {
|
|
2037
|
+
if (e.key === "d" || e.key === "D") {
|
|
2038
|
+
this._debugVisible = !this._debugVisible;
|
|
2039
|
+
panel.style.display = this._debugVisible ? "block" : "none";
|
|
2040
|
+
}
|
|
2041
|
+
};
|
|
2042
|
+
document.addEventListener("keydown", this._debugKeyHandler);
|
|
2043
|
+
}
|
|
2044
|
+
_updateDebugPanel() {
|
|
2045
|
+
if (!this._debugVisible || !this._debugPanel) return;
|
|
2046
|
+
const hls = this.pool.hlsInstances.get(this.activeItemId);
|
|
2047
|
+
if (!hls || !hls.levels || !hls.levels.length) {
|
|
2048
|
+
this._debugPanel.innerHTML = "HLS: no levels loaded";
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
const level = hls.levels[hls.currentLevel] || {};
|
|
2052
|
+
const bw = hls.bandwidthEstimate ? (hls.bandwidthEstimate / 1e6).toFixed(2) : "?";
|
|
2053
|
+
const lines = [
|
|
2054
|
+
`<b style="color:#fff">HLS Debug</b>`,
|
|
2055
|
+
`Level: ${hls.currentLevel} / ${hls.levels.length - 1}`,
|
|
2056
|
+
`Resolution: ${level.width || "?"}x${level.height || "?"}`,
|
|
2057
|
+
`Bitrate: ${level.bitrate ? (level.bitrate / 1e3).toFixed(0) + " kbps" : "?"}`,
|
|
2058
|
+
`BW estimate: ${bw} Mbps`,
|
|
2059
|
+
`Auto cap: ${hls.autoLevelCapping}`,
|
|
2060
|
+
`Next level: ${hls.nextLevel}`,
|
|
2061
|
+
`<span style="color:#888">Levels:</span>`
|
|
2062
|
+
];
|
|
2063
|
+
for (let i = 0; i < hls.levels.length; i++) {
|
|
2064
|
+
const l = hls.levels[i];
|
|
2065
|
+
const marker = i === hls.currentLevel ? ' <b style="color:#0ff">◀</b>' : "";
|
|
2066
|
+
lines.push(` ${i}: ${l.width}x${l.height} @ ${(l.bitrate / 1e3).toFixed(0)}k${marker}`);
|
|
2067
|
+
}
|
|
2068
|
+
this._debugPanel.innerHTML = lines.join("<br>");
|
|
1998
2069
|
}
|
|
1999
2070
|
// --- Time loop (state emission only, no DOM updates) ---
|
|
2000
2071
|
_startTimeLoop(id, el, player) {
|
|
@@ -2002,6 +2073,7 @@
|
|
|
2002
2073
|
const tick = () => {
|
|
2003
2074
|
if (this._destroyed) return;
|
|
2004
2075
|
if (!player || player.paused) {
|
|
2076
|
+
this._updateDebugPanel();
|
|
2005
2077
|
this.rafIds.set(id, requestAnimationFrame(tick));
|
|
2006
2078
|
return;
|
|
2007
2079
|
}
|
|
@@ -2027,6 +2099,7 @@
|
|
|
2027
2099
|
player.play().catch(() => {
|
|
2028
2100
|
});
|
|
2029
2101
|
}
|
|
2102
|
+
this._updateDebugPanel();
|
|
2030
2103
|
this.rafIds.set(id, requestAnimationFrame(tick));
|
|
2031
2104
|
};
|
|
2032
2105
|
this.rafIds.set(id, requestAnimationFrame(tick));
|
|
@@ -2193,14 +2266,20 @@
|
|
|
2193
2266
|
} catch (e) {
|
|
2194
2267
|
}
|
|
2195
2268
|
}
|
|
2196
|
-
|
|
2269
|
+
/** Unsubscribe overlay event listeners without clearing DOM. */
|
|
2270
|
+
_detachOverlay(itemId) {
|
|
2197
2271
|
const entry = this._overlayContainers.get(itemId);
|
|
2198
2272
|
if (!entry) return;
|
|
2199
2273
|
if (entry.unsub) {
|
|
2200
2274
|
entry.unsub();
|
|
2201
2275
|
entry.unsub = null;
|
|
2202
2276
|
}
|
|
2203
|
-
|
|
2277
|
+
}
|
|
2278
|
+
/** Unsubscribe and clear overlay DOM (used on destroy). */
|
|
2279
|
+
_clearOverlay(itemId) {
|
|
2280
|
+
this._detachOverlay(itemId);
|
|
2281
|
+
const entry = this._overlayContainers.get(itemId);
|
|
2282
|
+
if (entry) entry.el.innerHTML = "";
|
|
2204
2283
|
}
|
|
2205
2284
|
}
|
|
2206
2285
|
const MuteOnSvg = '<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>';
|
|
@@ -2550,6 +2629,7 @@
|
|
|
2550
2629
|
this._isOpen = true;
|
|
2551
2630
|
this._onClose = onClose;
|
|
2552
2631
|
this._openItemId = item.id;
|
|
2632
|
+
this._openThumbnailUrl = item.thumbnailUrl || null;
|
|
2553
2633
|
const sourceRect = sourceEl.getBoundingClientRect();
|
|
2554
2634
|
const sourceRadius = parseFloat(getComputedStyle(sourceEl).borderRadius) || 12;
|
|
2555
2635
|
this.overlayEl.classList.add("skp-active");
|
|
@@ -2594,6 +2674,21 @@
|
|
|
2594
2674
|
feedEl.style.transform = "none";
|
|
2595
2675
|
feedEl.style.borderRadius = `${targetRadius}px`;
|
|
2596
2676
|
});
|
|
2677
|
+
this.feedManager.startObserver();
|
|
2678
|
+
this.feedManager._activateItem(item.id);
|
|
2679
|
+
this.overlayEl.classList.add("skp-feed-ready");
|
|
2680
|
+
const itemOverlay = feedItemEl?.querySelector('[data-ref="overlay"]');
|
|
2681
|
+
const chromeEls = [...this.overlayEl.querySelectorAll(".skp-feed-close, .sk-sidebar")];
|
|
2682
|
+
if (itemOverlay) chromeEls.push(itemOverlay);
|
|
2683
|
+
chromeEls.forEach((el) => {
|
|
2684
|
+
el.style.opacity = "0";
|
|
2685
|
+
el.style.transition = "none";
|
|
2686
|
+
});
|
|
2687
|
+
this.overlayEl.getBoundingClientRect();
|
|
2688
|
+
chromeEls.forEach((el) => {
|
|
2689
|
+
el.style.transition = "opacity .35s cubic-bezier(.32,.72,0,1)";
|
|
2690
|
+
el.style.opacity = "1";
|
|
2691
|
+
});
|
|
2597
2692
|
await this._waitForTransitionEnd(feedEl, 450);
|
|
2598
2693
|
feedEl.classList.remove("skp-flip-animating");
|
|
2599
2694
|
feedEl.style.transformOrigin = "";
|
|
@@ -2601,9 +2696,10 @@
|
|
|
2601
2696
|
feedEl.style.scrollSnapType = "";
|
|
2602
2697
|
feedEl.style.transform = "";
|
|
2603
2698
|
feedEl.style.borderRadius = "";
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2699
|
+
chromeEls.forEach((el) => {
|
|
2700
|
+
el.style.opacity = "";
|
|
2701
|
+
el.style.transition = "";
|
|
2702
|
+
});
|
|
2607
2703
|
this._escHandler = (e) => {
|
|
2608
2704
|
if (e.key === "Escape") this.close();
|
|
2609
2705
|
};
|
|
@@ -2616,33 +2712,44 @@
|
|
|
2616
2712
|
const feedWrapper = feedEl.parentNode;
|
|
2617
2713
|
const feedRect = feedEl.getBoundingClientRect();
|
|
2618
2714
|
const activeItemId = this.feedManager?.activeItemId;
|
|
2619
|
-
|
|
2620
|
-
if (activeItemId === this._openItemId) {
|
|
2621
|
-
const ejected = this.feedManager?.pool.ejectPlayer(activeItemId);
|
|
2622
|
-
if (ejected) {
|
|
2623
|
-
transferBack = true;
|
|
2624
|
-
transferVideo = ejected.video;
|
|
2625
|
-
transferHls = ejected.hls;
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2715
|
+
const canTransfer = activeItemId === this._openItemId;
|
|
2628
2716
|
let targetRect = null;
|
|
2629
2717
|
if (this._onClose) targetRect = this._onClose("getSourceRect");
|
|
2630
2718
|
if (feedRect && targetRect) {
|
|
2631
|
-
if (this.feedManager?.activeItemId && !
|
|
2719
|
+
if (this.feedManager?.activeItemId && !canTransfer) {
|
|
2632
2720
|
this.feedManager._deactivateItem(this.feedManager.activeItemId);
|
|
2633
2721
|
}
|
|
2722
|
+
const targetItemId = canTransfer ? this._openItemId : activeItemId;
|
|
2723
|
+
if (targetItemId && this.feedManager) {
|
|
2724
|
+
const targetEl = this.feedManager.itemEls.get(targetItemId);
|
|
2725
|
+
if (targetEl) targetEl.scrollIntoView({ behavior: "instant", block: "start" });
|
|
2726
|
+
}
|
|
2727
|
+
const savedScrollTop = feedEl.scrollTop;
|
|
2634
2728
|
feedEl.style.position = "fixed";
|
|
2635
2729
|
feedEl.style.left = `${feedRect.left}px`;
|
|
2636
2730
|
feedEl.style.top = `${feedRect.top}px`;
|
|
2637
2731
|
feedEl.style.width = `${feedRect.width}px`;
|
|
2638
2732
|
feedEl.style.height = `${feedRect.height}px`;
|
|
2639
|
-
feedEl.style.zIndex =
|
|
2733
|
+
feedEl.style.zIndex = String(getComputedStyle(this.overlayEl).zIndex || 9999);
|
|
2640
2734
|
feedEl.style.margin = "0";
|
|
2641
2735
|
feedEl.style.flex = "none";
|
|
2642
2736
|
feedEl.style.aspectRatio = "unset";
|
|
2643
2737
|
feedEl.style.maxHeight = "none";
|
|
2644
2738
|
document.body.appendChild(feedEl);
|
|
2739
|
+
feedEl.scrollTop = savedScrollTop;
|
|
2645
2740
|
this.overlayEl.classList.remove("skp-active", "skp-feed-ready");
|
|
2741
|
+
let thumbOverlay = null;
|
|
2742
|
+
if (this._openThumbnailUrl) {
|
|
2743
|
+
const crossfadeItemId = canTransfer ? this._openItemId : activeItemId;
|
|
2744
|
+
const crossfadeEl = crossfadeItemId && this.feedManager?.itemEls.get(crossfadeItemId);
|
|
2745
|
+
const videoContainer = crossfadeEl?.querySelector('[data-ref="videoContainer"]');
|
|
2746
|
+
if (videoContainer) {
|
|
2747
|
+
thumbOverlay = document.createElement("img");
|
|
2748
|
+
thumbOverlay.src = this._openThumbnailUrl;
|
|
2749
|
+
thumbOverlay.style.cssText = "position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .4s cubic-bezier(.32,.72,0,1);pointer-events:none;z-index:2;";
|
|
2750
|
+
videoContainer.appendChild(thumbOverlay);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2646
2753
|
const scaleX = targetRect.width / feedRect.width;
|
|
2647
2754
|
const scaleY = targetRect.height / feedRect.height;
|
|
2648
2755
|
const translateX = targetRect.left - feedRect.left;
|
|
@@ -2652,29 +2759,58 @@
|
|
|
2652
2759
|
feedEl.style.transformOrigin = "0 0";
|
|
2653
2760
|
feedEl.style.overflow = "hidden";
|
|
2654
2761
|
feedEl.style.scrollSnapType = "none";
|
|
2762
|
+
feedEl.style.pointerEvents = "none";
|
|
2655
2763
|
feedEl.getBoundingClientRect();
|
|
2656
2764
|
feedEl.classList.add("skp-flip-animating");
|
|
2657
2765
|
requestAnimationFrame(() => {
|
|
2658
2766
|
feedEl.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
2659
2767
|
feedEl.style.borderRadius = `${endRadius}px`;
|
|
2768
|
+
if (thumbOverlay) thumbOverlay.style.opacity = "1";
|
|
2660
2769
|
});
|
|
2661
2770
|
await this._waitForTransitionEnd(feedEl, 450);
|
|
2771
|
+
if (thumbOverlay) thumbOverlay.remove();
|
|
2772
|
+
let transferVideo = null;
|
|
2773
|
+
let transferHls = null;
|
|
2774
|
+
if (canTransfer) {
|
|
2775
|
+
const ejected = this.feedManager?.pool.ejectPlayer(this._openItemId);
|
|
2776
|
+
if (ejected) {
|
|
2777
|
+
transferVideo = ejected.video;
|
|
2778
|
+
transferHls = ejected.hls;
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2662
2781
|
feedEl.style.visibility = "hidden";
|
|
2663
2782
|
feedEl.classList.remove("skp-flip-animating");
|
|
2664
|
-
["position", "left", "top", "width", "height", "zIndex", "margin", "flex", "aspectRatio", "maxHeight", "transformOrigin", "overflow", "scrollSnapType", "transform", "borderRadius"].forEach((p) => feedEl.style[p] = "");
|
|
2783
|
+
["position", "left", "top", "width", "height", "zIndex", "margin", "flex", "aspectRatio", "maxHeight", "transformOrigin", "overflow", "scrollSnapType", "pointerEvents", "transform", "borderRadius"].forEach((p) => feedEl.style[p] = "");
|
|
2665
2784
|
const sidebarEl = feedWrapper.querySelector(".sk-sidebar");
|
|
2666
2785
|
feedWrapper.insertBefore(feedEl, sidebarEl);
|
|
2667
2786
|
feedEl.style.visibility = "";
|
|
2787
|
+
if (this._onClose) {
|
|
2788
|
+
this._onClose("closed", {
|
|
2789
|
+
transferVideo,
|
|
2790
|
+
transferHls,
|
|
2791
|
+
transferItemId: transferVideo ? this._openItemId : null
|
|
2792
|
+
});
|
|
2793
|
+
this._onClose = null;
|
|
2794
|
+
}
|
|
2668
2795
|
} else {
|
|
2669
2796
|
this.overlayEl.classList.remove("skp-active", "skp-feed-ready");
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2797
|
+
if (this._onClose) {
|
|
2798
|
+
let transferVideo = null;
|
|
2799
|
+
let transferHls = null;
|
|
2800
|
+
if (canTransfer) {
|
|
2801
|
+
const ejected = this.feedManager?.pool.ejectPlayer(this._openItemId);
|
|
2802
|
+
if (ejected) {
|
|
2803
|
+
transferVideo = ejected.video;
|
|
2804
|
+
transferHls = ejected.hls;
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
this._onClose("closed", {
|
|
2808
|
+
transferVideo,
|
|
2809
|
+
transferHls,
|
|
2810
|
+
transferItemId: transferVideo ? this._openItemId : null
|
|
2811
|
+
});
|
|
2812
|
+
this._onClose = null;
|
|
2813
|
+
}
|
|
2678
2814
|
}
|
|
2679
2815
|
if (this.feedManager) {
|
|
2680
2816
|
this.feedManager.destroy();
|
|
@@ -2726,6 +2862,7 @@
|
|
|
2726
2862
|
this._onClose = onClose;
|
|
2727
2863
|
this._openSlotIndex = startIndex;
|
|
2728
2864
|
this._openItemId = item.id;
|
|
2865
|
+
this._openThumbnailUrl = item.thumbnailUrl || null;
|
|
2729
2866
|
const slotRect = slotEl.getBoundingClientRect();
|
|
2730
2867
|
const slotRadius = parseFloat(getComputedStyle(slotEl).borderRadius) || 12;
|
|
2731
2868
|
if (_isPreview) {
|
|
@@ -2772,6 +2909,21 @@
|
|
|
2772
2909
|
feedEl.style.transform = "none";
|
|
2773
2910
|
feedEl.style.borderRadius = `${targetRadius}px`;
|
|
2774
2911
|
});
|
|
2912
|
+
this.feedManager.startObserver();
|
|
2913
|
+
this.feedManager._activateItem(item.id);
|
|
2914
|
+
this.overlayEl.classList.add("skw-feed-ready");
|
|
2915
|
+
const itemOverlay = feedItemEl?.querySelector('[data-ref="overlay"]');
|
|
2916
|
+
const chromeEls = [...this.overlayEl.querySelectorAll(".skw-feed-close, .sk-sidebar")];
|
|
2917
|
+
if (itemOverlay) chromeEls.push(itemOverlay);
|
|
2918
|
+
chromeEls.forEach((el) => {
|
|
2919
|
+
el.style.opacity = "0";
|
|
2920
|
+
el.style.transition = "none";
|
|
2921
|
+
});
|
|
2922
|
+
this.overlayEl.getBoundingClientRect();
|
|
2923
|
+
chromeEls.forEach((el) => {
|
|
2924
|
+
el.style.transition = "opacity .35s cubic-bezier(.32,.72,0,1)";
|
|
2925
|
+
el.style.opacity = "1";
|
|
2926
|
+
});
|
|
2775
2927
|
await this._waitForTransitionEnd(feedEl, 450);
|
|
2776
2928
|
feedEl.classList.remove("skw-flip-animating");
|
|
2777
2929
|
feedEl.style.transformOrigin = "";
|
|
@@ -2779,9 +2931,10 @@
|
|
|
2779
2931
|
feedEl.style.scrollSnapType = "";
|
|
2780
2932
|
feedEl.style.transform = "";
|
|
2781
2933
|
feedEl.style.borderRadius = "";
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2934
|
+
chromeEls.forEach((el) => {
|
|
2935
|
+
el.style.opacity = "";
|
|
2936
|
+
el.style.transition = "";
|
|
2937
|
+
});
|
|
2785
2938
|
this._escHandler = (e) => {
|
|
2786
2939
|
if (e.key === "Escape") this.close();
|
|
2787
2940
|
};
|
|
@@ -2808,6 +2961,12 @@
|
|
|
2808
2961
|
if (this.feedManager?.activeItemId && !canTransfer) {
|
|
2809
2962
|
this.feedManager._deactivateItem(this.feedManager.activeItemId);
|
|
2810
2963
|
}
|
|
2964
|
+
const targetItemId = canTransfer ? this._openItemId : activeItemId;
|
|
2965
|
+
if (targetItemId && this.feedManager) {
|
|
2966
|
+
const targetEl = this.feedManager.itemEls.get(targetItemId);
|
|
2967
|
+
if (targetEl) targetEl.scrollIntoView({ behavior: "instant", block: "start" });
|
|
2968
|
+
}
|
|
2969
|
+
const savedScrollTop = feedEl.scrollTop;
|
|
2811
2970
|
feedEl.style.position = "fixed";
|
|
2812
2971
|
feedEl.style.left = `${feedRect.left}px`;
|
|
2813
2972
|
feedEl.style.top = `${feedRect.top}px`;
|
|
@@ -2819,7 +2978,20 @@
|
|
|
2819
2978
|
feedEl.style.aspectRatio = "unset";
|
|
2820
2979
|
feedEl.style.maxHeight = "none";
|
|
2821
2980
|
document.body.appendChild(feedEl);
|
|
2981
|
+
feedEl.scrollTop = savedScrollTop;
|
|
2822
2982
|
this.overlayEl.classList.remove("skw-active", "skw-feed-ready");
|
|
2983
|
+
let thumbOverlay = null;
|
|
2984
|
+
if (this._openThumbnailUrl) {
|
|
2985
|
+
const targetItemId2 = canTransfer ? this._openItemId : activeItemId;
|
|
2986
|
+
const targetEl = targetItemId2 && this.feedManager?.itemEls.get(targetItemId2);
|
|
2987
|
+
const videoContainer = targetEl?.querySelector('[data-ref="videoContainer"]');
|
|
2988
|
+
if (videoContainer) {
|
|
2989
|
+
thumbOverlay = document.createElement("img");
|
|
2990
|
+
thumbOverlay.src = this._openThumbnailUrl;
|
|
2991
|
+
thumbOverlay.style.cssText = "position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .4s cubic-bezier(.32,.72,0,1);pointer-events:none;z-index:2;";
|
|
2992
|
+
videoContainer.appendChild(thumbOverlay);
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2823
2995
|
const slotRadius = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--skw-radius").trim()) || 12;
|
|
2824
2996
|
const scaleX = targetSlotRect.width / feedRect.width;
|
|
2825
2997
|
const scaleY = targetSlotRect.height / feedRect.height;
|
|
@@ -2829,13 +3001,16 @@
|
|
|
2829
3001
|
feedEl.style.transformOrigin = "0 0";
|
|
2830
3002
|
feedEl.style.overflow = "hidden";
|
|
2831
3003
|
feedEl.style.scrollSnapType = "none";
|
|
3004
|
+
feedEl.style.pointerEvents = "none";
|
|
2832
3005
|
feedEl.getBoundingClientRect();
|
|
2833
3006
|
feedEl.classList.add("skw-flip-animating");
|
|
2834
3007
|
requestAnimationFrame(() => {
|
|
2835
3008
|
feedEl.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
2836
3009
|
feedEl.style.borderRadius = `${endRadius}px`;
|
|
3010
|
+
if (thumbOverlay) thumbOverlay.style.opacity = "1";
|
|
2837
3011
|
});
|
|
2838
3012
|
await this._waitForTransitionEnd(feedEl, 450);
|
|
3013
|
+
if (thumbOverlay) thumbOverlay.remove();
|
|
2839
3014
|
let transferVideo = null;
|
|
2840
3015
|
let transferHls = null;
|
|
2841
3016
|
if (canTransfer) {
|
|
@@ -2860,6 +3035,7 @@
|
|
|
2860
3035
|
feedEl.style.transformOrigin = "";
|
|
2861
3036
|
feedEl.style.overflow = "";
|
|
2862
3037
|
feedEl.style.scrollSnapType = "";
|
|
3038
|
+
feedEl.style.pointerEvents = "";
|
|
2863
3039
|
feedEl.style.transform = "";
|
|
2864
3040
|
feedEl.style.borderRadius = "";
|
|
2865
3041
|
feedWrapper.insertBefore(feedEl, feedWrapper.firstChild);
|
|
@@ -2989,11 +3165,20 @@
|
|
|
2989
3165
|
}
|
|
2990
3166
|
promoteToActive(itemId) {
|
|
2991
3167
|
const hls = this.hlsInstances.get(itemId);
|
|
2992
|
-
if (hls)
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3168
|
+
if (!hls) return;
|
|
3169
|
+
hls.config.maxBufferLength = WidgetPlayerPool.ACTIVE_HLS_CONFIG.maxBufferLength;
|
|
3170
|
+
hls.config.maxMaxBufferLength = WidgetPlayerPool.ACTIVE_HLS_CONFIG.maxMaxBufferLength;
|
|
3171
|
+
hls.autoLevelCapping = -1;
|
|
3172
|
+
const top = hls.levels ? hls.levels.length - 1 : -1;
|
|
3173
|
+
if (top > 0 && hls.currentLevel < top) {
|
|
3174
|
+
hls.currentLevel = top;
|
|
3175
|
+
const player = this.assignments.get(itemId);
|
|
3176
|
+
if (player) {
|
|
3177
|
+
player.currentTime = player.currentTime;
|
|
3178
|
+
}
|
|
3179
|
+
setTimeout(() => {
|
|
3180
|
+
if (!hls.destroyed) hls.currentLevel = -1;
|
|
3181
|
+
}, 4e3);
|
|
2997
3182
|
}
|
|
2998
3183
|
}
|
|
2999
3184
|
_destroyHls(itemId) {
|
|
@@ -3598,7 +3783,7 @@
|
|
|
3598
3783
|
|
|
3599
3784
|
/* Video container */
|
|
3600
3785
|
.sk-video-container{position:absolute;inset:0;width:100%;height:100%;overflow:hidden;background-size:cover;background-position:center}
|
|
3601
|
-
.sk-video-container video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .
|
|
3786
|
+
.sk-video-container video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .35s ease}
|
|
3602
3787
|
|
|
3603
3788
|
/* Tap zone */
|
|
3604
3789
|
.sk-tap-zone{position:absolute;inset:0;z-index:3;cursor:pointer}
|
|
@@ -3614,7 +3799,7 @@
|
|
|
3614
3799
|
|
|
3615
3800
|
/* Widget slot */
|
|
3616
3801
|
.skw-slot{position:relative;overflow:hidden;cursor:pointer}
|
|
3617
|
-
.skw-slot video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .
|
|
3802
|
+
.skw-slot video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .4s ease}
|
|
3618
3803
|
.skw-slot-thumb{position:absolute;inset:0;background-size:cover;background-position:center}
|
|
3619
3804
|
.skw-slot-overlay{position:absolute;inset:0;z-index:4;pointer-events:none}
|
|
3620
3805
|
.skw-slot-overlay>*{pointer-events:auto}
|