mirror of
https://github.com/DigiLive/mushroom-strategy.git
synced 2025-07-30 01:47:14 +02:00
Add Notice Manager (#239)
* Adds the ability to create and dismiss persistent HASS notifications. * Bump Strategy version to v2.3.5
This commit is contained in:
@ -9,5 +9,6 @@
|
|||||||
"semi": true,
|
"semi": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "es5",
|
||||||
"useTabs": false
|
"useTabs": false
|
||||||
}
|
}
|
||||||
|
@ -66,11 +66,11 @@ We welcome contributions and feedback!
|
|||||||
|
|
||||||
[hacsBadge]: https://img.shields.io/badge/HACS-Default-blue
|
[hacsBadge]: https://img.shields.io/badge/HACS-Default-blue
|
||||||
|
|
||||||
[releaseBadge]: https://img.shields.io/github/v/tag/digilive/mushroom-strategy?filter=v2.3.4&label=Release
|
[releaseBadge]: https://img.shields.io/github/v/tag/digilive/mushroom-strategy?filter=v2.3.5&label=Release
|
||||||
|
|
||||||
<!-- Repository References -->
|
<!-- Repository References -->
|
||||||
|
|
||||||
[releaseUrl]: https://github.com/DigiLive/mushroom-strategy/releases/tag/v2.3.4
|
[releaseUrl]: https://github.com/DigiLive/mushroom-strategy/releases/tag/v2.3.5
|
||||||
|
|
||||||
<!-- Other References -->
|
<!-- Other References -->
|
||||||
|
|
||||||
|
1
dist/mushroom-strategy.js
vendored
1
dist/mushroom-strategy.js
vendored
File diff suppressed because one or more lines are too long
@ -68,11 +68,11 @@ support helps us grow and improve.
|
|||||||
|
|
||||||
[hacsBadge]: https://img.shields.io/badge/HACS-Default-blue
|
[hacsBadge]: https://img.shields.io/badge/HACS-Default-blue
|
||||||
|
|
||||||
[releaseBadge]: https://img.shields.io/github/v/tag/digilive/mushroom-strategy?filter=v2.3.4&label=Release
|
[releaseBadge]: https://img.shields.io/github/v/tag/digilive/mushroom-strategy?filter=v2.3.5&label=Release
|
||||||
|
|
||||||
<!-- Repository References -->
|
<!-- Repository References -->
|
||||||
|
|
||||||
[releaseUrl]: https://github.com/DigiLive/mushroom-strategy/releases/tag/v2.3.4
|
[releaseUrl]: https://github.com/DigiLive/mushroom-strategy/releases/tag/v2.3.5
|
||||||
|
|
||||||
<!-- Other References -->
|
<!-- Other References -->
|
||||||
|
|
||||||
|
19
package-lock.json
generated
19
package-lock.json
generated
@ -1,17 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "mushroom-strategy",
|
"name": "mushroom-strategy",
|
||||||
"version": "2.3.4",
|
"version": "2.3.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mushroom-strategy",
|
"name": "mushroom-strategy",
|
||||||
"version": "2.3.2",
|
"version": "2.3.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deepmerge": "^4"
|
"deepmerge": "^4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/semver": "^7.7.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||||
"@typescript-eslint/parser": "^8.32.1",
|
"@typescript-eslint/parser": "^8.32.1",
|
||||||
"eslint": "^9.27.0",
|
"eslint": "^9.27.0",
|
||||||
@ -20,6 +21,7 @@
|
|||||||
"home-assistant-js-websocket": "^9.5.0",
|
"home-assistant-js-websocket": "^9.5.0",
|
||||||
"markdownlint-cli2": "^0.18.1",
|
"markdownlint-cli2": "^0.18.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
|
"semver": "^7.7.2",
|
||||||
"superstruct": "^2.0.2",
|
"superstruct": "^2.0.2",
|
||||||
"ts-loader": "^9.5.2",
|
"ts-loader": "^9.5.2",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
@ -560,6 +562,13 @@
|
|||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/semver": {
|
||||||
|
"version": "7.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
|
||||||
|
"integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
"version": "2.0.11",
|
"version": "2.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
||||||
@ -4072,9 +4081,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.1",
|
"version": "7.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mushroom-strategy",
|
"name": "mushroom-strategy",
|
||||||
"version": "2.3.4",
|
"version": "2.3.5",
|
||||||
"description": "Automatically generate a dashboard of Mushroom cards.",
|
"description": "Automatically generate a dashboard of Mushroom cards.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"dashboard",
|
"dashboard",
|
||||||
@ -30,6 +30,7 @@
|
|||||||
"deepmerge": "^4"
|
"deepmerge": "^4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/semver": "^7.7.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||||
"@typescript-eslint/parser": "^8.32.1",
|
"@typescript-eslint/parser": "^8.32.1",
|
||||||
"eslint": "^9.27.0",
|
"eslint": "^9.27.0",
|
||||||
@ -38,6 +39,7 @@
|
|||||||
"home-assistant-js-websocket": "^9.5.0",
|
"home-assistant-js-websocket": "^9.5.0",
|
||||||
"markdownlint-cli2": "^0.18.1",
|
"markdownlint-cli2": "^0.18.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
|
"semver": "^7.7.2",
|
||||||
"superstruct": "^2.0.2",
|
"superstruct": "^2.0.2",
|
||||||
"ts-loader": "^9.5.2",
|
"ts-loader": "^9.5.2",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
|
@ -17,6 +17,10 @@ import { sanitizeClassName } from './utilities/auxiliaries';
|
|||||||
import { logMessage, lvlError, lvlInfo } from './utilities/debug';
|
import { logMessage, lvlError, lvlInfo } from './utilities/debug';
|
||||||
import RegistryFilter from './utilities/RegistryFilter';
|
import RegistryFilter from './utilities/RegistryFilter';
|
||||||
import { stackHorizontal } from './utilities/cardStacking';
|
import { stackHorizontal } from './utilities/cardStacking';
|
||||||
|
import { PersistentNotification } from './utilities/PersistentNotification';
|
||||||
|
import { HomeAssistant } from './types/homeassistant/types';
|
||||||
|
import semver from 'semver/preload';
|
||||||
|
import { NOTIFICATIONS } from './notifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mushroom Dashboard Strategy.<br>
|
* Mushroom Dashboard Strategy.<br>
|
||||||
@ -41,6 +45,8 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
static async generateDashboard(info: DashboardInfo): Promise<LovelaceConfig> {
|
static async generateDashboard(info: DashboardInfo): Promise<LovelaceConfig> {
|
||||||
await Registry.initialize(info);
|
await Registry.initialize(info);
|
||||||
|
|
||||||
|
await MushroomStrategy.handleNotifications(info.hass);
|
||||||
|
|
||||||
const views: StrategyViewConfig[] = [];
|
const views: StrategyViewConfig[] = [];
|
||||||
|
|
||||||
// Parallelize view imports and creation.
|
// Parallelize view imports and creation.
|
||||||
@ -90,7 +96,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
type: 'custom:mushroom-strategy',
|
type: 'custom:mushroom-strategy',
|
||||||
options: { area },
|
options: { area },
|
||||||
},
|
},
|
||||||
})),
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
return { views };
|
return { views };
|
||||||
@ -135,7 +141,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
{
|
{
|
||||||
...Registry.strategyOptions.domains['_'],
|
...Registry.strategyOptions.domains['_'],
|
||||||
...Registry.strategyOptions.domains[domain],
|
...Registry.strategyOptions.domains[domain],
|
||||||
},
|
}
|
||||||
).createCard();
|
).createCard();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -157,7 +163,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
if (domainCards.length) {
|
if (domainCards.length) {
|
||||||
domainCards = stackHorizontal(
|
domainCards = stackHorizontal(
|
||||||
domainCards,
|
domainCards,
|
||||||
Registry.strategyOptions.domains[domain].stack_count ?? Registry.strategyOptions.domains['_'].stack_count,
|
Registry.strategyOptions.domains[domain].stack_count ?? Registry.strategyOptions.domains['_'].stack_count
|
||||||
);
|
);
|
||||||
|
|
||||||
return { type: 'vertical-stack', cards: [headerCard, ...domainCards] };
|
return { type: 'vertical-stack', cards: [headerCard, ...domainCards] };
|
||||||
@ -176,7 +182,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
|
|
||||||
domainCards = stackHorizontal(
|
domainCards = stackHorizontal(
|
||||||
domainCards,
|
domainCards,
|
||||||
Registry.strategyOptions.domains[domain].stack_count ?? Registry.strategyOptions.domains['_'].stack_count,
|
Registry.strategyOptions.domains[domain].stack_count ?? Registry.strategyOptions.domains['_'].stack_count
|
||||||
);
|
);
|
||||||
|
|
||||||
return domainCards.length ? { type: 'vertical-stack', cards: [headerCard, ...domainCards] } : null;
|
return domainCards.length ? { type: 'vertical-stack', cards: [headerCard, ...domainCards] } : null;
|
||||||
@ -201,7 +207,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
try {
|
try {
|
||||||
const MiscellaneousCard = (await import('./cards/MiscellaneousCard')).default;
|
const MiscellaneousCard = (await import('./cards/MiscellaneousCard')).default;
|
||||||
let miscellaneousCards = miscellaneousEntities.map((entity) =>
|
let miscellaneousCards = miscellaneousEntities.map((entity) =>
|
||||||
new MiscellaneousCard(entity, Registry.strategyOptions.card_options?.[entity.entity_id]).getCard(),
|
new MiscellaneousCard(entity, Registry.strategyOptions.card_options?.[entity.entity_id]).getCard()
|
||||||
);
|
);
|
||||||
|
|
||||||
const headerCard = new HeaderCard(target, {
|
const headerCard = new HeaderCard(target, {
|
||||||
@ -213,7 +219,7 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
miscellaneousCards = stackHorizontal(
|
miscellaneousCards = stackHorizontal(
|
||||||
miscellaneousCards,
|
miscellaneousCards,
|
||||||
Registry.strategyOptions.domains['default'].stack_count ??
|
Registry.strategyOptions.domains['default'].stack_count ??
|
||||||
Registry.strategyOptions.domains['_'].stack_count,
|
Registry.strategyOptions.domains['_'].stack_count
|
||||||
);
|
);
|
||||||
|
|
||||||
viewCards.push({
|
viewCards.push({
|
||||||
@ -229,13 +235,46 @@ class MushroomStrategy extends HTMLTemplateElement {
|
|||||||
|
|
||||||
return { cards: viewCards };
|
return { cards: viewCards };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle persistent notifications.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* Goes through `NOTIFICATIONS` and shows each one whose version range matches the current version.
|
||||||
|
* If the current version is not applicable, the notification is dismissed.
|
||||||
|
*
|
||||||
|
* @param hass The Home Assistant instance.
|
||||||
|
* @returns A promise that resolves when all notifications have been handled.
|
||||||
|
*/
|
||||||
|
private static async handleNotifications(hass: HomeAssistant): Promise<void> {
|
||||||
|
const notificationManager = new PersistentNotification(hass, 'mushroom_strategy');
|
||||||
|
const currentVersion = STRATEGY_VERSION.replace(/^v/, '');
|
||||||
|
const version = semver.coerce(currentVersion) || '0.0.0';
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
NOTIFICATIONS.map(async (notification) => {
|
||||||
|
if (semver.gte(version, notification.fromVersion) && semver.lte(version, notification.toVersion)) {
|
||||||
|
return notificationManager.showNotification(notification.storageKey, notification.message, {
|
||||||
|
title: notification.title,
|
||||||
|
version: currentVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return notificationManager.dismissNotification(notification.storageKey);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logMessage(lvlError, 'Error while handling persistent notifications for Mushroom Strategy', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('ll-strategy-mushroom-strategy', MushroomStrategy);
|
customElements.define('ll-strategy-mushroom-strategy', MushroomStrategy);
|
||||||
|
|
||||||
const version = 'v2.3.4';
|
const STRATEGY_VERSION = 'v2.3.5';
|
||||||
console.info(
|
console.info(
|
||||||
'%c Mushroom Strategy %c '.concat(version, ' '),
|
'%c Mushroom Strategy %c '.concat(STRATEGY_VERSION, ' '),
|
||||||
'color: white; background: coral; font-weight: 700;',
|
'color: white; background: coral; font-weight: 700;',
|
||||||
'color: coral; background: white; font-weight: 700;',
|
'color: coral; background: white; font-weight: 700;'
|
||||||
);
|
);
|
||||||
|
13
src/notifications.ts
Normal file
13
src/notifications.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export const NOTIFICATIONS = [
|
||||||
|
{
|
||||||
|
storageKey: 'chips_deprecation',
|
||||||
|
title: 'Mushroom Strategy',
|
||||||
|
message:
|
||||||
|
'## Deprecation Notice\n' +
|
||||||
|
'As of v3.0.0, chips are replaced by badges.\n' +
|
||||||
|
'From that version on, you must rename all `chip` or `chips` references and settings in your YAML configuration.\n' +
|
||||||
|
'The [documentation](https://digilive.github.io/mushroom-strategy/options/home-view-options/) will be updated accordingly.',
|
||||||
|
fromVersion: '2.3.5',
|
||||||
|
toVersion: '3.0.0',
|
||||||
|
},
|
||||||
|
];
|
189
src/utilities/PersistentNotification.ts
Normal file
189
src/utilities/PersistentNotification.ts
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import { HomeAssistant } from '../types/homeassistant/types';
|
||||||
|
import { logMessage, lvlDebug, lvlError, lvlInfo } from './debug';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration options for persistent notifications.
|
||||||
|
*
|
||||||
|
* @property {string} [title] The title to display in the notification.
|
||||||
|
* @property {string} [storageKey] The key name for storing the notification state into local storage.
|
||||||
|
* @property {string} [version] Version string for the notification.
|
||||||
|
* @property {string} hassId User-defined id of the notification in Home Assistant.
|
||||||
|
*/
|
||||||
|
interface NotificationOptions {
|
||||||
|
title?: string;
|
||||||
|
storageKey?: string;
|
||||||
|
version?: string;
|
||||||
|
hassId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a notification's state in storage.
|
||||||
|
*
|
||||||
|
* @property {boolean} shown Whether the notification has been shown to the user.
|
||||||
|
* @property {string} timestamp timestamp of when the notification was last shown.
|
||||||
|
* @property {string} version Version of the notification when it was stored.
|
||||||
|
* @property {string} hassId Id of the notification in Home Assistant.
|
||||||
|
*/
|
||||||
|
interface StoredNotification {
|
||||||
|
shown: boolean;
|
||||||
|
timestamp: string;
|
||||||
|
version: string;
|
||||||
|
hassId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class for managing persistent notifications in Home Assistant.
|
||||||
|
* Handles showing, dismissing and tracking notifications to prevent duplicates.
|
||||||
|
*
|
||||||
|
* Notifications are stored in localStorage and can be versioned.
|
||||||
|
*
|
||||||
|
* @see https://www.home-assistant.io/integrations/persistent_notification/
|
||||||
|
*/
|
||||||
|
export class PersistentNotification {
|
||||||
|
private static readonly DEFAULT_NAMESPACE = 'mushroom_strategy';
|
||||||
|
private static readonly DEFAULT_TITLE = 'Mushroom Strategy Notification';
|
||||||
|
|
||||||
|
private readonly hass: HomeAssistant;
|
||||||
|
private readonly namespace: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new PersistentNotification instance.
|
||||||
|
*
|
||||||
|
* @param hass The Home Assistant instance for interacting with the Home Assistant API.
|
||||||
|
* @param namespace An optional configuration object.
|
||||||
|
*/
|
||||||
|
constructor(hass: HomeAssistant, namespace: string = PersistentNotification.DEFAULT_NAMESPACE) {
|
||||||
|
this.hass = hass;
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a persistent notification with the given message and options.
|
||||||
|
*
|
||||||
|
* @param storageKey The key name for the notification in the local storage.
|
||||||
|
* @param message The message to display in the notification.
|
||||||
|
* @param options Optional configuration options for the notification.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves when the notification is shown or the method has been called before with the same
|
||||||
|
* storage key.
|
||||||
|
*/
|
||||||
|
public async showNotification(storageKey: string, message: string, options: NotificationOptions = {}): Promise<void> {
|
||||||
|
if (this.hasBeenShown(storageKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const compiledKey = this.compileStorageKey(storageKey, options.storageKey);
|
||||||
|
const notificationId = options.hassId || compiledKey;
|
||||||
|
const title = options.title || PersistentNotification.DEFAULT_TITLE;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.hass.callService('persistent_notification', 'create', {
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
notification_id: notificationId,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.markAsShown(storageKey, options.version || '1.0.0', notificationId);
|
||||||
|
} catch (error) {
|
||||||
|
logMessage(lvlError, `Failed to show notification '${storageKey}'!`, error);
|
||||||
|
logMessage(lvlInfo, `[${title}] ${message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears a notification from the Home Assistant UI and localStorage.
|
||||||
|
*
|
||||||
|
* @param storageKey The key name of the notification in the local storage.
|
||||||
|
* @param customKey An optional custom key to use for storage.
|
||||||
|
*/
|
||||||
|
public async dismissNotification(storageKey: string, customKey?: string): Promise<void> {
|
||||||
|
storageKey = this.compileStorageKey(storageKey, customKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(storageKey);
|
||||||
|
const notification = stored ? (JSON.parse(stored) as StoredNotification) : null;
|
||||||
|
|
||||||
|
// Clear from storage
|
||||||
|
localStorage.removeItem(storageKey);
|
||||||
|
|
||||||
|
// Clear the notification if notificationId is provided
|
||||||
|
if (notification?.hassId) {
|
||||||
|
await this.hass.callService('persistent_notification', 'dismiss', {
|
||||||
|
notification_id: notification.hassId,
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logMessage(lvlDebug, `Notification '${storageKey}' cleared from storage!`);
|
||||||
|
} catch (error) {
|
||||||
|
logMessage(lvlError, `Failed to clear notification '${storageKey}'!`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a notification with the given id has been shown to the user.
|
||||||
|
*
|
||||||
|
* @param storageKey The key name of the notification in the local storage.
|
||||||
|
* @param customKey An optional custom key to use for storage.
|
||||||
|
* @returns True if the notification has been shown before, false otherwise.
|
||||||
|
*/
|
||||||
|
public hasBeenShown(storageKey: string, customKey?: string): boolean {
|
||||||
|
storageKey = this.compileStorageKey(storageKey, customKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(storageKey);
|
||||||
|
if (!stored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notification = JSON.parse(stored) as StoredNotification;
|
||||||
|
return notification.shown;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a storage key for a given name.
|
||||||
|
*
|
||||||
|
* If a customKey is provided, it will be used directly.
|
||||||
|
* Otherwise, a storage key will be generated by combining the namespace with this given id.
|
||||||
|
*
|
||||||
|
* @param name The name of the key.
|
||||||
|
* @param customKey An optional custom key to use for storage.
|
||||||
|
* @returns The storage key.
|
||||||
|
*/
|
||||||
|
private compileStorageKey(name: string, customKey?: string): string {
|
||||||
|
if (customKey) {
|
||||||
|
return customKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const namespace = this.namespace || PersistentNotification.DEFAULT_NAMESPACE;
|
||||||
|
return `${namespace}_${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a notification as shown.
|
||||||
|
*
|
||||||
|
* @param storageKey The key of the notification in localStorage.
|
||||||
|
* @param version The version of the notification.
|
||||||
|
* @param notificationId Id of the notification in Home Assistant.
|
||||||
|
*/
|
||||||
|
private markAsShown(storageKey: string, version: string, notificationId?: string): void {
|
||||||
|
storageKey = this.compileStorageKey(storageKey);
|
||||||
|
|
||||||
|
const notification: StoredNotification = {
|
||||||
|
shown: true,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
version,
|
||||||
|
hassId: notificationId,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem(storageKey, JSON.stringify(notification));
|
||||||
|
} catch (error) {
|
||||||
|
logMessage(lvlError, 'Failed to save the notification state!', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user