mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-31 21:17:47 +00:00
Keep Lovelace cast active, remove media app
This commit is contained in:
parent
3fd0becfd4
commit
369d0538d1
@ -1,18 +1,26 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
|
<head>
|
||||||
<script type="module" src="<%= latestReceiverJS %>"></script>
|
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
|
||||||
<%= renderTemplate('_style_base') %>
|
<script type="module" src="<%= latestReceiverJS %>"></script>
|
||||||
<style>
|
<%= renderTemplate('_style_base') %>
|
||||||
body {
|
<style>
|
||||||
background-color: white;
|
body {
|
||||||
font-size: initial;
|
background-color: white;
|
||||||
}
|
font-size: initial;
|
||||||
</style>
|
}
|
||||||
<script>
|
.castMediaElement {
|
||||||
var _gaq=[['_setAccount','UA-57927901-10'],['_trackPageview']];
|
display: none;
|
||||||
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
}
|
||||||
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
|
</style>
|
||||||
s.parentNode.insertBefore(g,s)}(document,'script'));
|
<script>
|
||||||
</script>
|
var _gaq=[['_setAccount','UA-57927901-10'],['_trackPageview']];
|
||||||
|
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
||||||
|
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
|
||||||
|
s.parentNode.insertBefore(g,s)}(document,'script'));
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<video class="castMediaElement"></video>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -9,129 +9,55 @@ import { ReceivedMessage } from "./types";
|
|||||||
const lovelaceController = new HcMain();
|
const lovelaceController = new HcMain();
|
||||||
document.body.append(lovelaceController);
|
document.body.append(lovelaceController);
|
||||||
|
|
||||||
const mediaPlayer = document.createElement("cast-media-player");
|
const removeTouchControls = () => {
|
||||||
mediaPlayer.style.display = "none";
|
|
||||||
document.body.append(mediaPlayer);
|
|
||||||
const playerStylesAdded = false;
|
|
||||||
|
|
||||||
let controls: HTMLElement | null;
|
|
||||||
|
|
||||||
const setTouchControlsVisibility = (visible: boolean) => {
|
|
||||||
if (!castContext.getDeviceCapabilities().touch_input_supported) {
|
if (!castContext.getDeviceCapabilities().touch_input_supported) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
controls =
|
const controls = document.body.querySelector(
|
||||||
controls ||
|
"touch-controls"
|
||||||
(document.body.querySelector("touch-controls") as HTMLElement | null);
|
) as HTMLElement | null;
|
||||||
if (controls) {
|
if (controls) {
|
||||||
controls.style.display = visible ? "initial" : "none";
|
controls.remove();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const showLovelaceController = () => {
|
|
||||||
mediaPlayer.style.display = "none";
|
|
||||||
lovelaceController.style.display = "initial";
|
|
||||||
document.body.setAttribute("style", "overflow-y: auto !important");
|
document.body.setAttribute("style", "overflow-y: auto !important");
|
||||||
setTouchControlsVisibility(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const showMediaPlayer = () => {
|
const playMedia = () => {
|
||||||
lovelaceController.style.display = "none";
|
const playerManager = castContext.getPlayerManager();
|
||||||
mediaPlayer.style.display = "initial";
|
const loadRequestData = new cast.framework.messages.LoadRequestData();
|
||||||
document.body.removeAttribute("style");
|
loadRequestData.autoplay = true;
|
||||||
setTouchControlsVisibility(true);
|
loadRequestData.media = new cast.framework.messages.MediaInformation();
|
||||||
if (!playerStylesAdded) {
|
loadRequestData.media.contentId =
|
||||||
const style = document.createElement("style");
|
"https://www.home-assistant.io/images/blog/2018-09-thinking-big/social.png";
|
||||||
style.innerHTML = `
|
loadRequestData.media.contentType = "image/jpeg";
|
||||||
body {
|
loadRequestData.media.streamType = cast.framework.messages.StreamType.NONE;
|
||||||
--logo-image: url('https://www.home-assistant.io/images/home-assistant-logo.svg');
|
const metadata = new cast.framework.messages.GenericMediaMetadata();
|
||||||
--logo-repeat: no-repeat;
|
metadata.title = "Home Assistant Lovelace";
|
||||||
--playback-logo-image: url('https://www.home-assistant.io/images/home-assistant-logo.svg');
|
loadRequestData.media.metadata = metadata;
|
||||||
--theme-hue: 200;
|
|
||||||
--progress-color: #03a9f4;
|
loadRequestData.requestId = 0;
|
||||||
--splash-image: url('https://home-assistant.io/images/cast/splash.png');
|
playerManager.load(loadRequestData);
|
||||||
--splash-size: cover;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
document.head.appendChild(style);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const options = new cast.framework.CastReceiverOptions();
|
const options = new cast.framework.CastReceiverOptions();
|
||||||
options.disableIdleTimeout = true;
|
options.disableIdleTimeout = true;
|
||||||
|
// @ts-ignore
|
||||||
|
options.skipPlayersLoad = true;
|
||||||
options.customNamespaces = {
|
options.customNamespaces = {
|
||||||
[CAST_NS]: cast.framework.system.MessageType.JSON,
|
[CAST_NS]: cast.framework.system.MessageType.JSON,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The docs say we need to set options.touchScreenOptimizeApp = true
|
|
||||||
// https://developers.google.com/cast/docs/caf_receiver/customize_ui#accessing_ui_controls
|
|
||||||
// This doesn't work.
|
|
||||||
// @ts-ignore
|
|
||||||
options.touchScreenOptimizedApp = true;
|
|
||||||
|
|
||||||
// The class reference say we can set a uiConfig in options to set it
|
|
||||||
// https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.CastReceiverOptions#uiConfig
|
|
||||||
// This doesn't work either.
|
|
||||||
// @ts-ignore
|
|
||||||
options.uiConfig = new cast.framework.ui.UiConfig();
|
|
||||||
// @ts-ignore
|
|
||||||
options.uiConfig.touchScreenOptimizedApp = true;
|
|
||||||
|
|
||||||
castContext.setInactivityTimeout(86400); // 1 day
|
|
||||||
|
|
||||||
castContext.addCustomMessageListener(
|
castContext.addCustomMessageListener(
|
||||||
CAST_NS,
|
CAST_NS,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
(ev: ReceivedMessage<HassMessage>) => {
|
(ev: ReceivedMessage<HassMessage>) => {
|
||||||
// We received a show Lovelace command, stop media from playing, hide media player and show Lovelace controller
|
// Remove touch controls, so touch can be used
|
||||||
if (
|
removeTouchControls();
|
||||||
playerManager.getPlayerState() !==
|
|
||||||
cast.framework.messages.PlayerState.IDLE
|
|
||||||
) {
|
|
||||||
playerManager.stop();
|
|
||||||
} else {
|
|
||||||
showLovelaceController();
|
|
||||||
}
|
|
||||||
const msg = ev.data;
|
const msg = ev.data;
|
||||||
msg.senderId = ev.senderId;
|
msg.senderId = ev.senderId;
|
||||||
lovelaceController.processIncomingMessage(msg);
|
lovelaceController.processIncomingMessage(msg);
|
||||||
}
|
// Play media so the media state will not be idle, to prevent the app from getting closed
|
||||||
);
|
playMedia();
|
||||||
|
|
||||||
const playerManager = castContext.getPlayerManager();
|
|
||||||
|
|
||||||
playerManager.setMessageInterceptor(
|
|
||||||
cast.framework.messages.MessageType.LOAD,
|
|
||||||
(loadRequestData) => {
|
|
||||||
// We received a play media command, hide Lovelace and show media player
|
|
||||||
showMediaPlayer();
|
|
||||||
const media = loadRequestData.media;
|
|
||||||
// Special handling if it came from Google Assistant
|
|
||||||
if (media.entity) {
|
|
||||||
media.contentId = media.entity;
|
|
||||||
media.streamType = cast.framework.messages.StreamType.LIVE;
|
|
||||||
media.contentType = "application/vnd.apple.mpegurl";
|
|
||||||
// @ts-ignore
|
|
||||||
media.hlsVideoSegmentFormat =
|
|
||||||
cast.framework.messages.HlsVideoSegmentFormat.FMP4;
|
|
||||||
}
|
|
||||||
return loadRequestData;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
playerManager.addEventListener(
|
|
||||||
cast.framework.events.EventType.MEDIA_STATUS,
|
|
||||||
(event) => {
|
|
||||||
if (
|
|
||||||
event.mediaStatus?.playerState ===
|
|
||||||
cast.framework.messages.PlayerState.IDLE &&
|
|
||||||
event.mediaStatus?.idleReason &&
|
|
||||||
event.mediaStatus?.idleReason !==
|
|
||||||
cast.framework.messages.IdleReason.INTERRUPTED
|
|
||||||
) {
|
|
||||||
// media finished or stopped, return to default Lovelace
|
|
||||||
showLovelaceController();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ export class HcMain extends HassElement {
|
|||||||
this._sendStatus();
|
this._sendStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.addEventListener("dialog-closed", this._dialogClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _sendStatus(senderId?: string) {
|
private _sendStatus(senderId?: string) {
|
||||||
@ -131,6 +132,10 @@ export class HcMain extends HassElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _dialogClosed = () => {
|
||||||
|
document.body.setAttribute("style", "overflow-y: auto !important");
|
||||||
|
};
|
||||||
|
|
||||||
private async _handleGetStatusMessage(msg: GetStatusMessage) {
|
private async _handleGetStatusMessage(msg: GetStatusMessage) {
|
||||||
this._sendStatus(msg.senderId!);
|
this._sendStatus(msg.senderId!);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user