feat: Add casting capability to user_agent condition (#2480)
This commit is contained in:
committed by
dermotduffy
parent
261a7e1a92
commit
9eb503deff
@@ -356,6 +356,7 @@ conditions:
|
|||||||
| `condition` | Must be `user_agent`. |
|
| `condition` | Must be `user_agent`. |
|
||||||
| `user_agent` | Exactly matches a user-agent, e.g. `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` |
|
| `user_agent` | Exactly matches a user-agent, e.g. `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` |
|
||||||
| `user_agent_re` | Matches a user-agent based on a regular expression, e.g. `Chrome/`. |
|
| `user_agent_re` | Matches a user-agent based on a regular expression, e.g. `Chrome/`. |
|
||||||
|
| `casting` | If `true` matches if the card is being cast to a Chromecast / TV device, if `false` matches if the card is _NOT_ being cast. |
|
||||||
| `companion` | If `true` matches if the user-agent is the Home Assistant companion app, if `false` matches if the user-agent is _NOT_ the Home Assistant companion app. |
|
| `companion` | If `true` matches if the user-agent is the Home Assistant companion app, if `false` matches if the user-agent is _NOT_ the Home Assistant companion app. |
|
||||||
|
|
||||||
When multiple parameters are specified they must all match for the condition to
|
When multiple parameters are specified they must all match for the condition to
|
||||||
@@ -436,6 +437,7 @@ conditions:
|
|||||||
- condition: user_agent
|
- condition: user_agent
|
||||||
user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
||||||
user_agent_re: "Chrome/"
|
user_agent_re: "Chrome/"
|
||||||
|
casting: true
|
||||||
companion: true
|
companion: true
|
||||||
- condition: view
|
- condition: view
|
||||||
views:
|
views:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TemplateRenderer } from '../card-controller/templates';
|
import { TemplateRenderer } from '../card-controller/templates';
|
||||||
import { getConfigValue } from '../config/management';
|
import { getConfigValue } from '../config/management';
|
||||||
import { AdvancedCameraCardCondition } from '../config/schema/conditions/types';
|
import { AdvancedCameraCardCondition } from '../config/schema/conditions/types';
|
||||||
|
import { isBeingCasted } from '../utils/casting';
|
||||||
import { isCompanionApp } from '../utils/companion';
|
import { isCompanionApp } from '../utils/companion';
|
||||||
import {
|
import {
|
||||||
ConditionsEvaluationResult,
|
ConditionsEvaluationResult,
|
||||||
@@ -275,6 +276,8 @@ export class ConditionsManager implements ConditionsManagerReadonlyInterface {
|
|||||||
result:
|
result:
|
||||||
!!newState?.userAgent &&
|
!!newState?.userAgent &&
|
||||||
(!condition.user_agent || condition.user_agent === newState.userAgent) &&
|
(!condition.user_agent || condition.user_agent === newState.userAgent) &&
|
||||||
|
(condition.casting === undefined ||
|
||||||
|
condition.casting === isBeingCasted(newState.userAgent)) &&
|
||||||
(condition.companion === undefined ||
|
(condition.companion === undefined ||
|
||||||
condition.companion === isCompanionApp(newState.userAgent)) &&
|
condition.companion === isCompanionApp(newState.userAgent)) &&
|
||||||
(condition.user_agent_re === undefined ||
|
(condition.user_agent_re === undefined ||
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ export const userAgentConditionSchema = z.object({
|
|||||||
condition: z.literal('user_agent'),
|
condition: z.literal('user_agent'),
|
||||||
user_agent: z.string().optional(),
|
user_agent: z.string().optional(),
|
||||||
user_agent_re: regexSchema.optional(),
|
user_agent_re: regexSchema.optional(),
|
||||||
|
casting: z.boolean().optional(),
|
||||||
companion: z.boolean().optional(),
|
companion: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Determine if the card is currently being casted.
|
* Determine if the card is currently being casted.
|
||||||
* @returns
|
|
||||||
*/
|
*/
|
||||||
export const isBeingCasted = (): boolean => {
|
export const isBeingCasted = (userAgent: string = navigator.userAgent): boolean => {
|
||||||
return !!navigator.userAgent.match(/CrKey\//);
|
return !!userAgent.match(/CrKey\//);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -952,6 +952,24 @@ describe('ConditionsManager', () => {
|
|||||||
expect(manager.getEvaluation().result).toBeFalsy();
|
expect(manager.getEvaluation().result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should match casting', () => {
|
||||||
|
const stateManager = new ConditionStateManager();
|
||||||
|
const manager = new ConditionsManager(
|
||||||
|
[{ condition: 'user_agent' as const, casting: true }],
|
||||||
|
stateManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(manager.getEvaluation().result).toBeFalsy();
|
||||||
|
stateManager.setState({
|
||||||
|
userAgent: 'CrKey/1.0',
|
||||||
|
});
|
||||||
|
expect(manager.getEvaluation().result).toBeTruthy();
|
||||||
|
stateManager.setState({
|
||||||
|
userAgent: userAgent,
|
||||||
|
});
|
||||||
|
expect(manager.getEvaluation().result).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
it('should match companion app', () => {
|
it('should match companion app', () => {
|
||||||
const stateManager = new ConditionStateManager();
|
const stateManager = new ConditionStateManager();
|
||||||
const manager = new ConditionsManager(
|
const manager = new ConditionsManager(
|
||||||
|
|||||||
Reference in New Issue
Block a user