mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 23:06:40 +00:00
Cache thumbnails (#2924)
This commit is contained in:
parent
e2ed1a9fd9
commit
bbc32278d8
@ -6,6 +6,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import HassMediaPlayerEntity from "../util/hass-media-player-model";
|
||||
import { fetchMediaPlayerThumbnailWithCache } from "../data/media-player";
|
||||
|
||||
import computeStateName from "../common/entity/compute_state_name";
|
||||
import EventsMixin from "../mixins/events-mixin";
|
||||
@ -271,10 +272,13 @@ class HaMediaPlayerCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
|
||||
// We have a new picture url
|
||||
try {
|
||||
const { content_type: contentType, content } = await this.hass.callWS({
|
||||
type: "media_player_thumbnail",
|
||||
entity_id: playerObj.stateObj.entity_id,
|
||||
});
|
||||
const {
|
||||
content_type: contentType,
|
||||
content,
|
||||
} = await fetchMediaPlayerThumbnailWithCache(
|
||||
this.hass,
|
||||
playerObj.stateObj.entity_id
|
||||
);
|
||||
this._coverShowing = true;
|
||||
this._coverLoadError = false;
|
||||
this.$.cover.style.backgroundImage = `url(data:${contentType};base64,${content})`;
|
||||
|
47
src/common/util/time-cache-function-promise.ts
Normal file
47
src/common/util/time-cache-function-promise.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { HomeAssistant } from "../../types";
|
||||
|
||||
interface ResultCache<T> {
|
||||
[entityId: string]: Promise<T> | undefined;
|
||||
}
|
||||
|
||||
export const timeCachePromiseFunc = async <T>(
|
||||
cacheKey: string,
|
||||
cacheTime: number,
|
||||
func: (
|
||||
hass: HomeAssistant,
|
||||
entityId: string,
|
||||
...args: Array<unknown>
|
||||
) => Promise<T>,
|
||||
hass: HomeAssistant,
|
||||
entityId: string,
|
||||
...args: Array<unknown>
|
||||
): Promise<T> => {
|
||||
let cache: ResultCache<T> | undefined = (hass as any)[cacheKey];
|
||||
|
||||
if (!cache) {
|
||||
cache = hass[cacheKey] = {};
|
||||
}
|
||||
|
||||
const lastResult = cache[entityId];
|
||||
|
||||
if (lastResult) {
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
const result = func(hass, entityId, ...args);
|
||||
cache[entityId] = result;
|
||||
|
||||
result.then(
|
||||
// When successful, set timer to clear cache
|
||||
() =>
|
||||
setTimeout(() => {
|
||||
cache![entityId] = undefined;
|
||||
}, cacheTime),
|
||||
// On failure, clear cache right away
|
||||
() => {
|
||||
cache![entityId] = undefined;
|
||||
}
|
||||
);
|
||||
|
||||
return result;
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
import { HomeAssistant, CameraEntity } from "../types";
|
||||
import { timeCachePromiseFunc } from "../common/util/time-cache-function-promise";
|
||||
|
||||
export interface CameraThumbnail {
|
||||
content_type: string;
|
||||
@ -14,6 +15,11 @@ export const computeMJPEGStreamUrl = (entity: CameraEntity) =>
|
||||
entity.attributes.access_token
|
||||
}`;
|
||||
|
||||
export const fetchThumbnailWithCache = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string
|
||||
) => timeCachePromiseFunc("_cameraTmb", 9000, fetchThumbnail, hass, entityId);
|
||||
|
||||
export const fetchThumbnail = (hass: HomeAssistant, entityId: string) =>
|
||||
hass.callWS<CameraThumbnail>({
|
||||
type: "camera_thumbnail",
|
||||
|
@ -1,4 +1,35 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
import { timeCachePromiseFunc } from "../common/util/time-cache-function-promise";
|
||||
|
||||
export const SUPPORT_PAUSE = 1;
|
||||
export const SUPPORT_NEXT_TRACK = 32;
|
||||
export const SUPPORTS_PLAY = 16384;
|
||||
export const OFF_STATES = ["off", "idle"];
|
||||
|
||||
export interface MediaPlayerThumbnail {
|
||||
content_type: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export const fetchMediaPlayerThumbnailWithCache = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string
|
||||
) =>
|
||||
timeCachePromiseFunc(
|
||||
"_media_playerTmb",
|
||||
9000,
|
||||
fetchMediaPlayerThumbnail,
|
||||
hass,
|
||||
entityId
|
||||
);
|
||||
|
||||
export const fetchMediaPlayerThumbnail = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string
|
||||
) => {
|
||||
return hass.callWS<MediaPlayerThumbnail>({
|
||||
type: "media_player_thumbnail",
|
||||
entity_id: entityId,
|
||||
});
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ import { HomeAssistant } from "../../../types";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { b64toBlob } from "../../../common/file/b64-to-blob";
|
||||
import { fetchThumbnail } from "../../../data/camera";
|
||||
import { fetchThumbnailWithCache } from "../../../data/camera";
|
||||
|
||||
const UPDATE_INTERVAL = 10000;
|
||||
const DEFAULT_FILTER = "grayscale(100%)";
|
||||
@ -179,10 +179,10 @@ class HuiImage extends LitElement {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const { content_type: contentType, content } = await fetchThumbnail(
|
||||
this.hass,
|
||||
this.cameraImage
|
||||
);
|
||||
const {
|
||||
content_type: contentType,
|
||||
content,
|
||||
} = await fetchThumbnailWithCache(this.hass, this.cameraImage);
|
||||
if (this._cameraImageSrc) {
|
||||
URL.revokeObjectURL(this._cameraImageSrc);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user