Add optional media thumbnails in popup

This commit is contained in:
hensm
2022-09-10 16:14:31 +01:00
parent 12ac28830d
commit 1ae0123952
6 changed files with 90 additions and 29 deletions

View File

@@ -396,6 +396,14 @@
"message": "Auto-expand media controls for connected devices", "message": "Auto-expand media controls for connected devices",
"description": "Receiver selector expand active checkbox label." "description": "Receiver selector expand active checkbox label."
}, },
"optionsReceiverSelectorShowMediaImages": {
"message": "Show media images",
"description": "Receiver selector show media images checkbox label."
},
"optionsReceiverSelectorShowMediaImagesDescription": {
"message": "Loads media thumbnail/branding images from remote servers.",
"description": "Receiver selector show media images option description."
},
"optionsSiteWhitelistCategoryName": { "optionsSiteWhitelistCategoryName": {
"message": "Site whitelist", "message": "Site whitelist",

View File

@@ -58,6 +58,8 @@ export interface Options {
receiverSelectorWaitForConnection: boolean; receiverSelectorWaitForConnection: boolean;
/** Auto-expand active sessions managed by the extension. */ /** Auto-expand active sessions managed by the extension. */
receiverSelectorExpandActive: boolean; receiverSelectorExpandActive: boolean;
/** Show media images in receiver selector. */
receiverSelectorShowMediaImages: boolean;
/** User agent replacement whitelist enabled. */ /** User agent replacement whitelist enabled. */
siteWhitelistEnabled: boolean; siteWhitelistEnabled: boolean;
@@ -97,6 +99,7 @@ export default {
receiverSelectorCloseIfFocusLost: true, receiverSelectorCloseIfFocusLost: true,
receiverSelectorWaitForConnection: true, receiverSelectorWaitForConnection: true,
receiverSelectorExpandActive: true, receiverSelectorExpandActive: true,
receiverSelectorShowMediaImages: false,
siteWhitelistEnabled: true, siteWhitelistEnabled: true,
siteWhitelist: [{ pattern: "https://www.netflix.com/*", isEnabled: true }], siteWhitelist: [{ pattern: "https://www.netflix.com/*", isEnabled: true }],

View File

@@ -362,22 +362,6 @@
</div> </div>
--> -->
<div class="option option--inline">
<div class="option__control">
<input
id="receiverSelectorCloseIfFocusLost"
type="checkbox"
bind:checked={opts.receiverSelectorCloseIfFocusLost}
/>
</div>
<label
class="option__label"
for="receiverSelectorCloseIfFocusLost"
>
{_("optionsReceiverSelectorCloseIfFocusLost")}
</label>
</div>
<div class="option option--inline"> <div class="option option--inline">
<div class="option__control"> <div class="option__control">
<input <input
@@ -393,6 +377,41 @@
{_("optionsReceiverSelectorExpandActive")} {_("optionsReceiverSelectorExpandActive")}
</label> </label>
</div> </div>
<div class="option option--inline">
<div class="option__control">
<input
id="receiverSelectorShowMediaImages"
type="checkbox"
bind:checked={opts.receiverSelectorShowMediaImages}
/>
</div>
<label
class="option__label"
for="receiverSelectorShowMediaImages"
>
{_("optionsReceiverSelectorShowMediaImages")}
</label>
<div class="option__description">
{_("optionsReceiverSelectorShowMediaImagesDescription")}
</div>
</div>
<div class="option option--inline">
<div class="option__control">
<input
id="receiverSelectorCloseIfFocusLost"
type="checkbox"
bind:checked={opts.receiverSelectorCloseIfFocusLost}
/>
</div>
<label
class="option__label"
for="receiverSelectorCloseIfFocusLost"
>
{_("optionsReceiverSelectorCloseIfFocusLost")}
</label>
</div>
</fieldset> </fieldset>
{/if} {/if}

View File

@@ -467,6 +467,7 @@
<div class="receiver__expanded"> <div class="receiver__expanded">
<ReceiverMedia <ReceiverMedia
status={mediaStatus} status={mediaStatus}
showImage={opts?.receiverSelectorShowMediaImages}
{device} {device}
{textTracks} {textTracks}
on:togglePlayback={() => handleMediaPlayPause()} on:togglePlayback={() => handleMediaPlayPause()}

View File

@@ -4,7 +4,7 @@
import type { ReceiverDevice } from "../../types"; import type { ReceiverDevice } from "../../types";
import { MediaStatus, _MediaCommand } from "../../cast/sdk/types"; import { MediaStatus, _MediaCommand } from "../../cast/sdk/types";
import type { Image, Volume } from "../../cast/sdk/classes"; import type { Volume } from "../../cast/sdk/classes";
import { import {
MetadataType, MetadataType,
PlayerState, PlayerState,
@@ -27,6 +27,7 @@
export let status: MediaStatus; export let status: MediaStatus;
export let device: ReceiverDevice; export let device: ReceiverDevice;
export let textTracks: Track[] = []; export let textTracks: Track[] = [];
export let showImage = false;
$: isPlayingOrPaused = $: isPlayingOrPaused =
status.playerState === PlayerState.PLAYING || status.playerState === PlayerState.PLAYING ||
@@ -38,14 +39,13 @@
let mediaTitle: Optional<string>; let mediaTitle: Optional<string>;
let mediaSubtitle: Optional<string>; let mediaSubtitle: Optional<string>;
let mediaImage: Optional<Image>; let mediaImageSet: Optional<string>;
// Choose subset of metadata depending on metadata type // Choose subset of metadata depending on metadata type
$: { $: {
const metadata = status?.media?.metadata; const metadata = status?.media?.metadata;
mediaTitle = metadata?.title; mediaTitle = metadata?.title;
mediaImage = metadata?.images?.[0];
mediaSubtitle = undefined; mediaSubtitle = undefined;
if (metadata) { if (metadata) {
@@ -71,6 +71,18 @@
mediaSubtitle = metadata.subtitle; mediaSubtitle = metadata.subtitle;
} }
} }
if (showImage && metadata?.images?.length) {
let imageSet: string[] = [];
for (const image of metadata.images) {
let sizeString = image.url;
if (image.width) sizeString += ` ${image.width}w`;
imageSet.push(sizeString);
}
mediaImageSet = imageSet.join(",");
} else {
mediaImageSet = undefined;
}
} }
// Keep track of update times for currentTime estimations // Keep track of update times for currentTime estimations
@@ -155,17 +167,22 @@
} }
</script> </script>
<div class="media" style:--media-image="url({mediaImage?.url})"> <div class="media">
{#if mediaTitle} {#if mediaTitle}
<div class="media__metadata"> <div class="media__metadata">
<div class="media__title" title={mediaTitle}> {#if mediaImageSet}
{mediaTitle} <img class="media__image" srcset={mediaImageSet} alt="" />
</div>
{#if mediaSubtitle}
<div class="media__subtitle">
{mediaSubtitle}
</div>
{/if} {/if}
<div class="media__metadata-text">
<div class="media__title" title={mediaTitle}>
{mediaTitle}
</div>
{#if mediaSubtitle}
<div class="media__subtitle">
{mediaSubtitle}
</div>
{/if}
</div>
</div> </div>
{/if} {/if}

View File

@@ -163,10 +163,24 @@ body {
.media__metadata, .media__metadata,
.media__controls { .media__controls {
padding: 5px 10px; padding: 5px;
} }
.media__metadata { .media__metadata {
display: flex;
gap: 10px;
}
.media__image {
align-self: start;
border: 1px solid var(--border-color);
border-radius: 4px;
flex-grow: 0;
max-height: 70px;
max-width: 120px;
}
.media__metadata-text {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -177,7 +191,6 @@ body {
.media__subtitle { .media__subtitle {
color: var(--secondary-color); color: var(--secondary-color);
} }
.media__title,
.media__subtitle { .media__subtitle {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;