Skip to content

Commit cfd4670

Browse files
committed
fix(player): show buffering in default layout when stream type unknown
1 parent 1d3427d commit cfd4670

8 files changed

Lines changed: 69 additions & 30 deletions

File tree

packages/react/src/components/layouts/default/audio-layout.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ import { createDefaultMediaLayout, type DefaultMediaLayoutProps } from './shared
66
* DefaultAudioLayout
77
* -----------------------------------------------------------------------------------------------*/
88

9+
const MediaLayout = createDefaultMediaLayout({
10+
type: 'audio',
11+
smLayoutWhen: '(width < 576)',
12+
SmallLayout: DefaultAudioLayoutSmall,
13+
LargeLayout: DefaultAudioLayoutLarge,
14+
});
15+
916
export interface DefaultAudioLayoutProps extends DefaultMediaLayoutProps {}
1017

1118
/**
@@ -23,12 +30,9 @@ export interface DefaultAudioLayoutProps extends DefaultMediaLayoutProps {}
2330
* </MediaPlayer>
2431
* ```
2532
*/
26-
const DefaultAudioLayout = createDefaultMediaLayout({
27-
type: 'audio',
28-
smLayoutWhen: '(width < 576)',
29-
SmallLayout: DefaultAudioLayoutSmall,
30-
LargeLayout: DefaultAudioLayoutLarge,
31-
});
33+
function DefaultAudioLayout(props: DefaultAudioLayoutProps) {
34+
return <MediaLayout {...props} />;
35+
}
3236

3337
DefaultAudioLayout.displayName = 'DefaultAudioLayout';
3438
export { DefaultAudioLayout };

packages/react/src/components/layouts/default/shared-layout.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,17 @@ export interface CreateDefaultMediaLayout {
114114
smLayoutWhen: string;
115115
SmallLayout: React.FC;
116116
LargeLayout: React.FC;
117+
UnknownStreamType?: React.FC;
117118
}
118119

119-
export const createDefaultMediaLayout = ({
120+
export function createDefaultMediaLayout({
120121
type,
121122
smLayoutWhen,
122123
SmallLayout,
123124
LargeLayout,
124-
}: CreateDefaultMediaLayout) =>
125-
React.forwardRef<HTMLDivElement, DefaultMediaLayoutProps>(
125+
UnknownStreamType,
126+
}: CreateDefaultMediaLayout) {
127+
const Layout = React.forwardRef<HTMLDivElement, DefaultMediaLayoutProps>(
126128
(
127129
{
128130
className,
@@ -143,7 +145,7 @@ export const createDefaultMediaLayout = ({
143145
const $canLoad = useMediaState('canLoad'),
144146
$viewType = useMediaState('viewType'),
145147
$streamType = useMediaState('streamType'),
146-
isMatch = $viewType === type && $streamType !== 'unknown',
148+
isMatch = $viewType === type,
147149
isForcedLayout = typeof smallLayoutWhen === 'boolean',
148150
isSmallLayoutMatch = usePlayerQuery(isString(smallLayoutWhen) ? smallLayoutWhen : ''),
149151
isSmallLayout = isForcedLayout ? smallLayoutWhen : isSmallLayoutMatch;
@@ -169,7 +171,15 @@ export const createDefaultMediaLayout = ({
169171
Icons: icons,
170172
}}
171173
>
172-
{isSmallLayout ? <SmallLayout /> : <LargeLayout />}
174+
{$streamType === 'unknown' ? (
175+
UnknownStreamType ? (
176+
<UnknownStreamType />
177+
) : null
178+
) : isSmallLayout ? (
179+
<SmallLayout />
180+
) : (
181+
<LargeLayout />
182+
)}
173183
{children}
174184
</DefaultLayoutContext.Provider>
175185
) : null}
@@ -178,6 +188,10 @@ export const createDefaultMediaLayout = ({
178188
},
179189
);
180190

191+
Layout.displayName = 'DefaultMediaLayout';
192+
return Layout;
193+
}
194+
181195
/* -------------------------------------------------------------------------------------------------
182196
* DefaultTooltip
183197
* -----------------------------------------------------------------------------------------------*/

packages/react/src/components/layouts/default/video-layout.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import {
2626
* DefaultVideoLayout
2727
* -----------------------------------------------------------------------------------------------*/
2828

29+
const MediaLayout = createDefaultMediaLayout({
30+
type: 'video',
31+
smLayoutWhen: '(width < 576) or (height < 380)',
32+
SmallLayout: DefaultVideoLayoutSmall,
33+
LargeLayout: DefaultVideoLayoutLarge,
34+
UnknownStreamType: DefaultBufferingIndicator,
35+
});
36+
2937
export interface DefaultVideoLayoutProps extends DefaultMediaLayoutProps {}
3038

3139
/**
@@ -44,12 +52,9 @@ export interface DefaultVideoLayoutProps extends DefaultMediaLayoutProps {}
4452
* </MediaPlayer>
4553
* ```
4654
*/
47-
const DefaultVideoLayout = createDefaultMediaLayout({
48-
type: 'video',
49-
smLayoutWhen: '(width < 576) or (height < 380)',
50-
SmallLayout: DefaultVideoLayoutSmall,
51-
LargeLayout: DefaultVideoLayoutLarge,
52-
});
55+
function DefaultVideoLayout(props: DefaultVideoLayoutProps) {
56+
return <MediaLayout {...props} />;
57+
}
5358

5459
DefaultVideoLayout.displayName = 'DefaultVideoLayout';
5560
export { DefaultVideoLayout };

packages/vidstack/player/styles/default/layouts/video.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@
398398

399399
/* center big play button inside buffering indicator. */
400400
:where(.vds-video-layout[data-size='sm'] .vds-buffering-indicator) {
401+
--media-buffering-size: 64px;
401402
transform: translate(-2px, -4px);
402403
}
403404

packages/vidstack/src/components/layouts/default-layout.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
type ReadSignal,
88
} from 'maverick.js';
99

10-
import { PlayerQueryList, type MediaContext } from '../../core';
11-
import { useMediaContext } from '../../core/api/media-context';
10+
import { PlayerQueryList } from '../../core';
1211

1312
export class DefaultLayout extends Component<DefaultLayoutProps> {
1413
static props: DefaultLayoutProps = {
@@ -21,7 +20,6 @@ export class DefaultLayout extends Component<DefaultLayoutProps> {
2120
noModal: false,
2221
};
2322

24-
private _media!: MediaContext;
2523
private _whenQueryList!: PlayerQueryList;
2624
private _whenSmQueryList!: PlayerQueryList;
2725

@@ -30,8 +28,7 @@ export class DefaultLayout extends Component<DefaultLayoutProps> {
3028

3129
@prop
3230
get isMatch() {
33-
const { streamType } = this._media.$state;
34-
return this._whenQueryList.matches && streamType() !== 'unknown';
31+
return this._whenQueryList.matches;
3532
}
3633

3734
@prop
@@ -40,8 +37,6 @@ export class DefaultLayout extends Component<DefaultLayoutProps> {
4037
}
4138

4239
protected override onSetup(): void {
43-
this._media = useMediaContext();
44-
4540
const { when, smallWhen, thumbnails, translations, menuGroup, noModal } = this.$props;
4641

4742
this._whenQueryList = PlayerQueryList.create(when);

packages/vidstack/src/elements/define/layouts/default/audio-layout-element.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { Host } from 'maverick.js/element';
44
import { setAttribute } from 'maverick.js/std';
55

66
import { DefaultAudioLayout } from '../../../../components/layouts/default-layout';
7+
import type { MediaContext } from '../../../../core';
8+
import { useMediaContext } from '../../../../core/api/media-context';
79
import { $computed } from '../../../lit/directives/signal';
810
import { LitElement, type LitRenderer } from '../../../lit/lit-element';
911
import { SlotManager } from '../slot-manager';
@@ -27,7 +29,11 @@ export class MediaAudioLayoutElement
2729
{
2830
static tagName = 'media-audio-layout';
2931

32+
private _media!: MediaContext;
33+
3034
protected onSetup() {
35+
this._media = useMediaContext();
36+
3137
this.classList.add('vds-audio-layout');
3238
this.menuContainer = createMenuContainer('vds-audio-layout');
3339

@@ -50,7 +56,8 @@ export class MediaAudioLayoutElement
5056
}
5157

5258
private _render() {
53-
return this.isMatch
59+
const { streamType } = this._media.$state;
60+
return this.isMatch && streamType() !== 'unknown'
5461
? this.isSmallLayout
5562
? DefaultAudioLayoutSmall()
5663
: DefaultAudioLayoutLarge()

packages/vidstack/src/elements/define/layouts/default/video-layout-element.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
import { html } from 'lit-html';
2-
import { computed, effect, onDispose } from 'maverick.js';
2+
import { effect, onDispose } from 'maverick.js';
33
import { Host } from 'maverick.js/element';
44
import { setAttribute } from 'maverick.js/std';
55

66
import { DefaultVideoLayout } from '../../../../components/layouts/default-layout';
7-
import { $computed, $signal } from '../../../lit/directives/signal';
7+
import type { MediaContext } from '../../../../core';
8+
import { useMediaContext } from '../../../../core/api/media-context';
9+
import { $computed } from '../../../lit/directives/signal';
810
import { LitElement, type LitRenderer } from '../../../lit/lit-element';
911
import { SlotManager } from '../slot-manager';
1012
import { DefaultLayoutIconsLoader } from './icons-loader';
1113
import { createMenuContainer } from './shared-layout';
12-
import { DefaultVideoLayoutLarge, DefaultVideoLayoutSmall } from './video-layout';
14+
import {
15+
DefaultBufferingIndicator,
16+
DefaultVideoLayoutLarge,
17+
DefaultVideoLayoutSmall,
18+
} from './video-layout';
1319

1420
/**
1521
* @docs {@link https://www.vidstack.io/docs/player/core-concepts/layouts/default}
@@ -27,7 +33,11 @@ export class MediaVideoLayoutElement
2733
{
2834
static tagName = 'media-video-layout';
2935

36+
private _media!: MediaContext;
37+
3038
protected onSetup() {
39+
this._media = useMediaContext();
40+
3141
this.classList.add('vds-video-layout');
3242
this.menuContainer = createMenuContainer('vds-video-layout');
3343

@@ -50,8 +60,11 @@ export class MediaVideoLayoutElement
5060
}
5161

5262
private _render() {
63+
const { streamType } = this._media.$state;
5364
return this.isMatch
54-
? this.isSmallLayout
65+
? streamType() === 'unknown'
66+
? DefaultBufferingIndicator()
67+
: this.isSmallLayout
5568
? DefaultVideoLayoutSmall()
5669
: DefaultVideoLayoutLarge()
5770
: null;

packages/vidstack/src/elements/define/layouts/default/video-layout.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function StartDuration() {
103103
`;
104104
}
105105

106-
function DefaultBufferingIndicator() {
106+
export function DefaultBufferingIndicator() {
107107
return html`
108108
<div class="vds-buffering-indicator">
109109
<svg class="vds-buffering-icon" fill="none" viewBox="0 0 120 120" aria-hidden="true">

0 commit comments

Comments
 (0)