Skip to content

Commit 39774ab

Browse files
committed
fix(player): correctly append search params to download url
closes #1409
1 parent 4734549 commit 39774ab

6 files changed

Lines changed: 29 additions & 17 deletions

File tree

packages/react/src/components/layouts/default/ui/buttons.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import * as React from 'react';
22

3-
import { uppercaseFirstChar } from 'maverick.js/std';
3+
import { isString, uppercaseFirstChar } from 'maverick.js/std';
44
import { getDownloadFile, isTrackCaptionKind } from 'vidstack';
55

66
import { useMediaState } from '../../../../hooks/use-media-state';
7+
import { appendParamsToURL } from '../../../../utils';
78
import { AirPlayButton } from '../../../ui/buttons/airplay-button';
89
import { CaptionButton } from '../../../ui/buttons/caption-button';
910
import { FullscreenButton } from '../../../ui/buttons/fullscreen-button';
@@ -280,13 +281,13 @@ function DefaultDownloadButton() {
280281
}),
281282
downloadText = useDefaultLayoutWord('Download');
282283

283-
return file ? (
284+
return isString(file?.url) ? (
284285
<DefaultTooltip content={downloadText} placement="top">
285286
<a
286287
role="button"
287288
className="vds-download-button vds-button"
288289
aria-label={downloadText}
289-
href={file.url + `?download=${file.name}`}
290+
href={appendParamsToURL(file.url, { download: file.name })}
290291
download={file.name}
291292
target="_blank"
292293
>

packages/react/src/components/layouts/plyr/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22

33
import { signal } from 'maverick.js';
44
import { composeRefs, useSignal } from 'maverick.js/react';
5-
import { isNumber, listenEvent } from 'maverick.js/std';
5+
import { isNumber, isString, listenEvent } from 'maverick.js/std';
66
import type { VTTCue } from 'media-captions';
77
import {
88
isKeyboardClick,
@@ -23,6 +23,7 @@ import { useMediaContext } from '../../../hooks/use-media-context';
2323
import { useMediaRemote } from '../../../hooks/use-media-remote';
2424
import { useMediaState } from '../../../hooks/use-media-state';
2525
import { isRemotionSource } from '../../../providers/remotion';
26+
import { appendParamsToURL } from '../../../utils';
2627
import { Primitive, type PrimitivePropsWithRef } from '../../primitives/nodes';
2728
import { AirPlayButton } from '../../ui/buttons/airplay-button';
2829
import { CaptionButton } from '../../ui/buttons/caption-button';
@@ -746,10 +747,10 @@ function PlyrDownloadButton() {
746747

747748
return slot(
748749
'download',
749-
file ? (
750+
isString(file?.url) ? (
750751
<a
751752
className="plyr__controls__item plyr__control"
752-
href={file.url + `?download=${file.name}`}
753+
href={appendParamsToURL(file.url, { download: file.name })}
753754
download={file.name}
754755
target="_blank"
755756
>

packages/react/src/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,13 @@ export function createVTTCue(startTime = 0, endTime = 0, text = ''): VTTCue {
1515

1616
return new window.VTTCue(startTime, endTime, text);
1717
}
18+
19+
export function appendParamsToURL(baseUrl: string, params: Record<string, any>) {
20+
const url = new URL(baseUrl);
21+
22+
for (const key of Object.keys(params)) {
23+
url.searchParams.set(key, params[key] + '');
24+
}
25+
26+
return url.toString();
27+
}

packages/vidstack/src/elements/define/layouts/default/ui/buttons.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { html } from 'lit-html';
22
import { ref as $ref, type RefOrCallback } from 'lit-html/directives/ref.js';
3-
import { isNil, noop, uppercaseFirstChar } from 'maverick.js/std';
3+
import { isNil, isString, noop, uppercaseFirstChar } from 'maverick.js/std';
44

55
import { useDefaultLayoutContext } from '../../../../../components/layouts/default/context';
66
import { i18n } from '../../../../../components/layouts/default/translations';
77
import type { TooltipPlacement } from '../../../../../components/ui/tooltip/tooltip-content';
88
import { useMediaState } from '../../../../../core/api/media-context';
9-
import { getDownloadFile } from '../../../../../utils/network';
9+
import { appendParamsToURL, getDownloadFile } from '../../../../../utils/network';
1010
import { $signal } from '../../../../lit/directives/signal';
1111
import { IconSlot, IconSlots } from '../slots';
1212
import { $i18n } from './utils';
@@ -232,15 +232,15 @@ export function DefaultDownloadButton() {
232232
download: $download,
233233
});
234234

235-
return file
235+
return isString(file?.url)
236236
? html`
237237
<media-tooltip class="vds-download-tooltip vds-tooltip">
238238
<media-tooltip-trigger>
239239
<a
240240
role="button"
241241
class="vds-download-button vds-button"
242242
aria-label=${$i18n(translations, 'Download')}
243-
href=${file.url + `?download=${file.name}`}
243+
href=${appendParamsToURL(file.url, { download: file.name })}
244244
download=${file.name}
245245
target="_blank"
246246
>

packages/vidstack/src/elements/define/layouts/plyr/ui.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { html, type TemplateResult } from 'lit-html';
22
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
33
import { computed, effect, peek, signal, type ReadSignal } from 'maverick.js';
4-
import { isKeyboardClick, isKeyboardEvent, listenEvent } from 'maverick.js/std';
4+
import { isKeyboardClick, isKeyboardEvent, isString, listenEvent } from 'maverick.js/std';
55
import type { VTTCue } from 'media-captions';
66

77
import {
@@ -12,7 +12,7 @@ import type { PlyrControl, PlyrMarker } from '../../../../components/layouts/ply
1212
import { i18n, type PlyrLayoutWord } from '../../../../components/layouts/plyr/translations';
1313
import { useMediaContext } from '../../../../core/api/media-context';
1414
import type { MediaSeekingRequestEvent } from '../../../../core/api/media-request-events';
15-
import { getDownloadFile } from '../../../../utils/network';
15+
import { appendParamsToURL, getDownloadFile } from '../../../../utils/network';
1616
import { $signal } from '../../../lit/directives/signal';
1717

1818
export function PlyrAudioLayout() {
@@ -464,11 +464,11 @@ function DownloadButton() {
464464
}),
465465
$downloadText = $i18n(translations, 'Download');
466466

467-
return file
467+
return isString(file?.url)
468468
? html`
469469
<a
470470
class="plyr__controls__item plyr__control"
471-
href=${file.url + `?download=${file.name}`}
471+
href=${appendParamsToURL(file.url, { download: file.name })}
472472
download=${file.name}
473473
target="_blank"
474474
>

packages/vidstack/src/utils/network.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import type { Src } from '../core/api/src-types';
1010
import { isAudioSrc, isVideoSrc } from './mime';
1111

1212
export function appendParamsToURL(baseUrl: string, params: Record<string, any>) {
13-
const searchParams = new URLSearchParams();
13+
const url = new URL(baseUrl);
1414

1515
for (const key of Object.keys(params)) {
16-
searchParams.set(key, params[key] + '');
16+
url.searchParams.set(key, params[key] + '');
1717
}
1818

19-
return baseUrl + '?' + searchParams.toString();
19+
return url.toString();
2020
}
2121

2222
export function preconnect(

0 commit comments

Comments
 (0)