@@ -127,6 +127,10 @@ export class CardElementManager {
|
||||
this._api.getQueryStringManager().requestExecution,
|
||||
);
|
||||
|
||||
this._api.getConditionsManager()?.setState({
|
||||
user_agent: navigator.userAgent,
|
||||
});
|
||||
|
||||
// Manually request query string execute as the card will be
|
||||
// disconnected/reconnected when dashboard 'tab' changes happen within HA.
|
||||
this._api.getQueryStringManager().requestExecution();
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
import { localize } from '../localize/localize';
|
||||
import { FrigateCardError } from '../types';
|
||||
import { desparsifyArrays } from '../utils/basic';
|
||||
import { isCompanionApp } from '../utils/companion';
|
||||
import { CardConditionAPI, KeysState } from './types';
|
||||
|
||||
interface MicrophoneConditionState {
|
||||
@@ -39,6 +40,7 @@ interface ConditionState {
|
||||
microphone?: MicrophoneConditionState;
|
||||
user?: CurrentUser;
|
||||
keys?: KeysState;
|
||||
user_agent?: string;
|
||||
}
|
||||
|
||||
class OverrideConfigurationError extends FrigateCardError {}
|
||||
@@ -353,6 +355,15 @@ export class ConditionsManager {
|
||||
(conditionObj.shift === undefined ||
|
||||
conditionObj.shift === !!state.keys[conditionObj.key].shift)
|
||||
);
|
||||
case 'user_agent':
|
||||
return (
|
||||
!!state.user_agent &&
|
||||
(!conditionObj.user_agent || conditionObj.user_agent === state.user_agent) &&
|
||||
(conditionObj.companion === undefined ||
|
||||
conditionObj.companion === isCompanionApp(state.user_agent)) &&
|
||||
(conditionObj.user_agent_re === undefined ||
|
||||
new RegExp(conditionObj.user_agent_re).test(state.user_agent))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ export interface CardDownloadAPI {
|
||||
export interface CardElementAPI {
|
||||
getActionsManager(): ActionsManager;
|
||||
getCameraManager(): CameraManager;
|
||||
getConditionsManager(): ConditionsManager;
|
||||
getConfigManager(): ConfigManager;
|
||||
getDefaultManager(): DefaultManager;
|
||||
getExpandManager(): ExpandManager;
|
||||
|
||||
@@ -726,6 +726,25 @@ const keyConditionSchema = z.object({
|
||||
alt: z.boolean().optional(),
|
||||
meta: z.boolean().optional(),
|
||||
});
|
||||
const userAgentConditionSchema = z.object({
|
||||
condition: z.literal('user_agent'),
|
||||
user_agent: z.string().optional(),
|
||||
user_agent_re: z
|
||||
.string()
|
||||
.refine(
|
||||
(val) => {
|
||||
try {
|
||||
new RegExp(val);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{ message: 'Invalid regular expression' },
|
||||
)
|
||||
.optional(),
|
||||
companion: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const frigateCardConditionSchema = z.discriminatedUnion('condition', [
|
||||
// Stock conditions:
|
||||
@@ -745,6 +764,7 @@ export const frigateCardConditionSchema = z.discriminatedUnion('condition', [
|
||||
interactionConditionSchema,
|
||||
microphoneConditionSchema,
|
||||
keyConditionSchema,
|
||||
userAgentConditionSchema,
|
||||
]);
|
||||
export type FrigateCardCondition = z.infer<typeof frigateCardConditionSchema>;
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export const isCompanionApp = (userAgent: string): boolean => {
|
||||
return !!userAgent.match(/Home ?Assistant/);
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import { localize } from '../localize/localize';
|
||||
import { ExtendedHomeAssistant, FrigateCardError } from '../types';
|
||||
import { ViewMedia } from '../view/media';
|
||||
import { errorToConsole } from './basic';
|
||||
import { isCompanionApp } from './companion';
|
||||
import { homeAssistantSignPath } from './ha';
|
||||
|
||||
export const downloadURL = (url: string, filename = 'download'): void => {
|
||||
@@ -11,11 +12,7 @@ export const downloadURL = (url: string, filename = 'download'): void => {
|
||||
const isSameOrigin = new URL(url).origin === window.location.origin;
|
||||
const dataURL = url.startsWith('data:');
|
||||
|
||||
if (
|
||||
navigator.userAgent.startsWith('Home Assistant/') ||
|
||||
navigator.userAgent.startsWith('HomeAssistant/') ||
|
||||
(!isSameOrigin && !dataURL)
|
||||
) {
|
||||
if (isCompanionApp(navigator.userAgent) || (!isSameOrigin && !dataURL)) {
|
||||
// Home Assistant companion apps cannot download files without opening a
|
||||
// new browser window.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user