electron-notify-manager 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +323 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +6 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/NotificationManager.d.ts +45 -0
  7. package/dist/src/NotificationManager.d.ts.map +1 -0
  8. package/dist/src/NotificationManager.js +337 -0
  9. package/dist/src/NotificationManager.js.map +1 -0
  10. package/dist/src/NotificationWindow.d.ts +19 -0
  11. package/dist/src/NotificationWindow.d.ts.map +1 -0
  12. package/dist/src/NotificationWindow.js +165 -0
  13. package/dist/src/NotificationWindow.js.map +1 -0
  14. package/dist/src/constants.d.ts +22 -0
  15. package/dist/src/constants.d.ts.map +1 -0
  16. package/dist/src/constants.js +39 -0
  17. package/dist/src/constants.js.map +1 -0
  18. package/dist/src/core/NotificationQueue.d.ts +14 -0
  19. package/dist/src/core/NotificationQueue.d.ts.map +1 -0
  20. package/dist/src/core/NotificationQueue.js +35 -0
  21. package/dist/src/core/NotificationQueue.js.map +1 -0
  22. package/dist/src/errors.d.ts +23 -0
  23. package/dist/src/errors.d.ts.map +1 -0
  24. package/dist/src/errors.js +43 -0
  25. package/dist/src/errors.js.map +1 -0
  26. package/dist/src/ipc/IpcChannels.d.ts +9 -0
  27. package/dist/src/ipc/IpcChannels.d.ts.map +1 -0
  28. package/dist/src/ipc/IpcChannels.js +11 -0
  29. package/dist/src/ipc/IpcChannels.js.map +1 -0
  30. package/dist/src/position/PositionCalculator.d.ts +22 -0
  31. package/dist/src/position/PositionCalculator.d.ts.map +1 -0
  32. package/dist/src/position/PositionCalculator.js +77 -0
  33. package/dist/src/position/PositionCalculator.js.map +1 -0
  34. package/dist/src/positionCalculator.d.ts +19 -0
  35. package/dist/src/positionCalculator.d.ts.map +1 -0
  36. package/dist/src/positionCalculator.js +50 -0
  37. package/dist/src/positionCalculator.js.map +1 -0
  38. package/dist/src/types/config.types.d.ts +11 -0
  39. package/dist/src/types/config.types.d.ts.map +1 -0
  40. package/dist/src/types/config.types.js +3 -0
  41. package/dist/src/types/config.types.js.map +1 -0
  42. package/dist/src/types/index.d.ts +8 -0
  43. package/dist/src/types/index.d.ts.map +1 -0
  44. package/dist/src/types/index.js +3 -0
  45. package/dist/src/types/index.js.map +1 -0
  46. package/dist/src/types/ipc.types.d.ts +12 -0
  47. package/dist/src/types/ipc.types.d.ts.map +1 -0
  48. package/dist/src/types/ipc.types.js +3 -0
  49. package/dist/src/types/ipc.types.js.map +1 -0
  50. package/dist/src/types/notification.types.d.ts +28 -0
  51. package/dist/src/types/notification.types.d.ts.map +1 -0
  52. package/dist/src/types/notification.types.js +3 -0
  53. package/dist/src/types/notification.types.js.map +1 -0
  54. package/dist/src/types/position.types.d.ts +12 -0
  55. package/dist/src/types/position.types.d.ts.map +1 -0
  56. package/dist/src/types/position.types.js +3 -0
  57. package/dist/src/types/position.types.js.map +1 -0
  58. package/dist/src/types/theme.types.d.ts +8 -0
  59. package/dist/src/types/theme.types.d.ts.map +1 -0
  60. package/dist/src/types/theme.types.js +3 -0
  61. package/dist/src/types/theme.types.js.map +1 -0
  62. package/dist/src/utils/idGenerator.d.ts +7 -0
  63. package/dist/src/utils/idGenerator.d.ts.map +1 -0
  64. package/dist/src/utils/idGenerator.js +16 -0
  65. package/dist/src/utils/idGenerator.js.map +1 -0
  66. package/dist/src/utils/logger.d.ts +12 -0
  67. package/dist/src/utils/logger.d.ts.map +1 -0
  68. package/dist/src/utils/logger.js +38 -0
  69. package/dist/src/utils/logger.js.map +1 -0
  70. package/dist/src/utils/themeDetector.d.ts +3 -0
  71. package/dist/src/utils/themeDetector.d.ts.map +1 -0
  72. package/dist/src/utils/themeDetector.js +11 -0
  73. package/dist/src/utils/themeDetector.js.map +1 -0
  74. package/dist/src/utils/validators.d.ts +10 -0
  75. package/dist/src/utils/validators.d.ts.map +1 -0
  76. package/dist/src/utils/validators.js +95 -0
  77. package/dist/src/utils/validators.js.map +1 -0
  78. package/dist/types.d.ts +4 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +3 -0
  81. package/dist/types.js.map +1 -0
  82. package/package.json +50 -0
  83. package/renderer/notification.css +172 -0
  84. package/renderer/notification.html +52 -0
  85. package/renderer/notification.js +137 -0
  86. package/renderer/notification.ts +150 -0
  87. package/renderer/preload.js +38 -0
  88. package/renderer/preload.ts +56 -0
  89. package/renderer/scripts/animationController.ts +12 -0
  90. package/renderer/scripts/icons.ts +36 -0
  91. package/renderer/scripts/notification.js +188 -0
  92. package/renderer/scripts/progressBar.ts +10 -0
  93. package/renderer/styles/animations.css +28 -0
  94. package/renderer/styles/notification.css +186 -0
  95. package/renderer/styles/themes.css +94 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeDetector.js","sourceRoot":"","sources":["../../../src/utils/themeDetector.ts"],"names":[],"mappings":";;AAGA,oCAKC;AARD,uCAAuC;AAGvC,SAAgB,YAAY,CAAC,SAAoB;IAC/C,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,sBAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { NotificationManagerOptions } from '../types/config.types';
2
+ import type { NotificationOptions } from '../types/notification.types';
3
+ import type { NotificationPosition } from '../types/position.types';
4
+ import type { NotificationVariant, ThemeMode } from '../types/theme.types';
5
+ export declare function isValidPosition(value: unknown): value is NotificationPosition;
6
+ export declare function isValidVariant(value: unknown): value is NotificationVariant;
7
+ export declare function isValidThemeMode(value: unknown): value is ThemeMode;
8
+ export declare function validateManagerOptions(options: unknown): asserts options is NotificationManagerOptions;
9
+ export declare function validateNotificationOptions(options: unknown): asserts options is NotificationOptions;
10
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../../src/utils/validators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE3E,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAE7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAEnE;AAkBD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,0BAA0B,CAuBtG;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,CA8CpG"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidPosition = isValidPosition;
4
+ exports.isValidVariant = isValidVariant;
5
+ exports.isValidThemeMode = isValidThemeMode;
6
+ exports.validateManagerOptions = validateManagerOptions;
7
+ exports.validateNotificationOptions = validateNotificationOptions;
8
+ const constants_1 = require("../constants");
9
+ const errors_1 = require("../errors");
10
+ function isValidPosition(value) {
11
+ return typeof value === 'string' && constants_1.VALID_POSITIONS.includes(value);
12
+ }
13
+ function isValidVariant(value) {
14
+ return typeof value === 'string' && constants_1.VALID_VARIANTS.includes(value);
15
+ }
16
+ function isValidThemeMode(value) {
17
+ return typeof value === 'string' && constants_1.VALID_THEME_MODES.includes(value);
18
+ }
19
+ function assertNumber(name, value) {
20
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
21
+ throw new errors_1.NotificationError(`${name} must be a finite number`, errors_1.ErrorCode.INVALID_OPTIONS);
22
+ }
23
+ }
24
+ function assertNonNegativeInt(name, value) {
25
+ assertNumber(name, value);
26
+ if (value < 0) {
27
+ throw new errors_1.NotificationError(`${name} must be >= 0`, errors_1.ErrorCode.INVALID_OPTIONS);
28
+ }
29
+ if (!Number.isInteger(value)) {
30
+ throw new errors_1.NotificationError(`${name} must be an integer`, errors_1.ErrorCode.INVALID_OPTIONS);
31
+ }
32
+ }
33
+ function validateManagerOptions(options) {
34
+ if (typeof options !== 'object' || options === null) {
35
+ throw new errors_1.NotificationError('Manager options must be an object', errors_1.ErrorCode.INVALID_OPTIONS);
36
+ }
37
+ const o = options;
38
+ if (o.position !== undefined && !isValidPosition(o.position)) {
39
+ throw new errors_1.NotificationError(`Invalid position: ${String(o.position)}`, errors_1.ErrorCode.INVALID_POSITION);
40
+ }
41
+ const numeric = [
42
+ { key: 'WIDTH', name: 'width', field: 'width' },
43
+ { key: 'HEIGHT', name: 'height', field: 'height' },
44
+ { key: 'MARGIN', name: 'margin', field: 'margin' },
45
+ { key: 'GAP', name: 'gap', field: 'gap' },
46
+ ];
47
+ for (const n of numeric) {
48
+ if (o[n.name] !== undefined) {
49
+ assertNonNegativeInt(n.name, o[n.name]);
50
+ }
51
+ }
52
+ }
53
+ function validateNotificationOptions(options) {
54
+ if (typeof options !== 'object' || options === null) {
55
+ throw new errors_1.NotificationError('Notification options must be an object', errors_1.ErrorCode.INVALID_OPTIONS);
56
+ }
57
+ const o = options;
58
+ if (typeof o.title !== 'string' || o.title.trim().length === 0) {
59
+ throw new errors_1.NotificationError('title is required and must be a non-empty string', errors_1.ErrorCode.INVALID_OPTIONS);
60
+ }
61
+ if (typeof o.description !== 'string' || o.description.trim().length === 0) {
62
+ throw new errors_1.NotificationError('description is required and must be a non-empty string', errors_1.ErrorCode.INVALID_OPTIONS);
63
+ }
64
+ if (o.duration !== undefined) {
65
+ assertNonNegativeInt('duration', o.duration);
66
+ }
67
+ if (o.variant !== undefined && !isValidVariant(o.variant)) {
68
+ throw new errors_1.NotificationError(`variant is invalid: ${String(o.variant)}`, errors_1.ErrorCode.INVALID_OPTIONS);
69
+ }
70
+ if (o.theme !== undefined && !isValidThemeMode(o.theme)) {
71
+ throw new errors_1.NotificationError(`theme is invalid: ${String(o.theme)}`, errors_1.ErrorCode.INVALID_OPTIONS);
72
+ }
73
+ if (o.image !== undefined && (typeof o.image !== 'string' || o.image.trim().length === 0)) {
74
+ throw new errors_1.NotificationError('image must be a non-empty string if provided', errors_1.ErrorCode.INVALID_OPTIONS);
75
+ }
76
+ if (o.onClick !== undefined && typeof o.onClick !== 'function') {
77
+ throw new errors_1.NotificationError('onClick must be a function if provided', errors_1.ErrorCode.INVALID_OPTIONS);
78
+ }
79
+ if (o.onClose !== undefined && typeof o.onClose !== 'function') {
80
+ throw new errors_1.NotificationError('onClose must be a function if provided', errors_1.ErrorCode.INVALID_OPTIONS);
81
+ }
82
+ if (o.progress !== undefined) {
83
+ assertNumber('progress', o.progress);
84
+ if (o.progress < 0 || o.progress > 100) {
85
+ throw new errors_1.NotificationError('progress must be between 0 and 100', errors_1.ErrorCode.INVALID_OPTIONS);
86
+ }
87
+ }
88
+ if (o.progressLabel !== undefined && (typeof o.progressLabel !== 'string' || o.progressLabel.trim().length === 0)) {
89
+ throw new errors_1.NotificationError('progressLabel must be a non-empty string if provided', errors_1.ErrorCode.INVALID_OPTIONS);
90
+ }
91
+ if (o.loadingText !== undefined && (typeof o.loadingText !== 'string' || o.loadingText.trim().length === 0)) {
92
+ throw new errors_1.NotificationError('loadingText must be a non-empty string if provided', errors_1.ErrorCode.INVALID_OPTIONS);
93
+ }
94
+ }
95
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/utils/validators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type { CloseReason } from './src/types/notification.types';
2
+ export type { NotificationPosition } from './src/types/position.types';
3
+ export type { ThemeMode } from './src/types/theme.types';
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "electron-notify-manager",
3
+ "version": "1.0.0",
4
+ "description": "In-app toast notifications for Electron using BrowserWindow (not OS native notifications).",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc -p tsconfig.build.json",
9
+ "build:watch": "tsc -p tsconfig.build.json --watch",
10
+ "clean": "rimraf dist",
11
+ "test": "jest",
12
+ "test:coverage": "jest --coverage",
13
+ "prepublishOnly": "npm run clean && npm run build"
14
+ },
15
+ "files": [
16
+ "dist/",
17
+ "renderer/"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/feruzlabs/electron-notify-manager"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/feruzlabs/electron-notify-manager/issues"
25
+ },
26
+ "homepage": "https://github.com/feruzlabs/electron-notify-manager#readme",
27
+ "keywords": [
28
+ "electron",
29
+ "notification",
30
+ "toast",
31
+ "notify"
32
+ ],
33
+ "devDependencies": {
34
+ "@types/node": "^20.0.0",
35
+ "@types/jest": "^29.5.0",
36
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
37
+ "@typescript-eslint/parser": "^7.0.0",
38
+ "electron": "^28.0.0",
39
+ "eslint": "^8.57.0",
40
+ "jest": "^29.7.0",
41
+ "rimraf": "^5.0.0",
42
+ "ts-node": "^10.9.2",
43
+ "ts-jest": "^29.2.0",
44
+ "typescript": "^5.0.0"
45
+ },
46
+ "peerDependencies": {
47
+ "electron": ">=13.0.0"
48
+ },
49
+ "license": "MIT"
50
+ }
@@ -0,0 +1,172 @@
1
+ :root {
2
+ --bg: rgba(20, 20, 30, 0.92);
3
+ --border: rgba(255, 255, 255, 0.08);
4
+ --title: rgba(255, 255, 255, 0.95);
5
+ --desc: rgba(255, 255, 255, 0.65);
6
+ --shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
7
+ --progress: #4f8ef7;
8
+ --radius: 12px;
9
+ }
10
+
11
+ * {
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ html,
16
+ body {
17
+ width: 100%;
18
+ height: 100%;
19
+ margin: 0;
20
+ background: transparent;
21
+ overflow: hidden;
22
+ font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Apple Color Emoji",
23
+ "Segoe UI Emoji";
24
+ }
25
+
26
+ .root {
27
+ width: 100%;
28
+ height: 100%;
29
+ border-radius: var(--radius);
30
+ background: var(--bg);
31
+ border: 1px solid var(--border);
32
+ box-shadow: var(--shadow);
33
+ backdrop-filter: blur(20px) saturate(180%);
34
+ -webkit-backdrop-filter: blur(20px) saturate(180%);
35
+
36
+ display: flex;
37
+ align-items: center;
38
+ gap: 12px;
39
+ padding: 14px 14px 14px 14px;
40
+ position: relative;
41
+
42
+ opacity: 0;
43
+ transform: translateX(22px);
44
+ transition: opacity 180ms ease, transform 260ms ease;
45
+ }
46
+
47
+ .root.entering {
48
+ opacity: 0;
49
+ }
50
+
51
+ .root.entered {
52
+ opacity: 1;
53
+ transform: translateX(0px);
54
+ }
55
+
56
+ .root.exiting {
57
+ opacity: 0;
58
+ transform: translateX(22px);
59
+ transition: opacity 160ms ease, transform 220ms ease;
60
+ }
61
+
62
+ .image {
63
+ width: 44px;
64
+ height: 44px;
65
+ border-radius: 10px;
66
+ background: rgba(255, 255, 255, 0.06);
67
+ border: 1px solid rgba(255, 255, 255, 0.06);
68
+ overflow: hidden;
69
+ flex: 0 0 auto;
70
+ display: block;
71
+ }
72
+
73
+ .image img {
74
+ width: 100%;
75
+ height: 100%;
76
+ object-fit: cover;
77
+ display: block;
78
+ }
79
+
80
+ .defaultIcon {
81
+ width: 100%;
82
+ height: 100%;
83
+ display: none;
84
+ }
85
+
86
+ .defaultIcon svg {
87
+ width: 100%;
88
+ height: 100%;
89
+ display: block;
90
+ }
91
+
92
+ .content {
93
+ min-width: 0;
94
+ flex: 1 1 auto;
95
+ padding-right: 24px; /* room for close button */
96
+ }
97
+
98
+ .title {
99
+ color: var(--title);
100
+ font-size: 14px;
101
+ font-weight: 600;
102
+ line-height: 1.2;
103
+ margin-bottom: 6px;
104
+ white-space: nowrap;
105
+ overflow: hidden;
106
+ text-overflow: ellipsis;
107
+ }
108
+
109
+ .desc {
110
+ color: var(--desc);
111
+ font-size: 12px;
112
+ line-height: 1.35;
113
+ display: -webkit-box;
114
+ -webkit-line-clamp: 2;
115
+ -webkit-box-orient: vertical;
116
+ overflow: hidden;
117
+ }
118
+
119
+ .close {
120
+ position: absolute;
121
+ top: 8px;
122
+ right: 8px;
123
+ width: 26px;
124
+ height: 26px;
125
+ border-radius: 8px;
126
+ border: 1px solid rgba(255, 255, 255, 0.06);
127
+ background: rgba(255, 255, 255, 0.04);
128
+ color: rgba(255, 255, 255, 0.7);
129
+ cursor: pointer;
130
+ outline: none;
131
+ transition: background 120ms ease, border-color 120ms ease, color 120ms ease, transform 120ms ease;
132
+ display: grid;
133
+ place-items: center;
134
+ font-size: 18px;
135
+ line-height: 1;
136
+ padding: 0;
137
+ }
138
+
139
+ .close:hover {
140
+ background: rgba(255, 80, 80, 0.12);
141
+ border-color: rgba(255, 80, 80, 0.35);
142
+ color: rgba(255, 160, 160, 0.95);
143
+ transform: translateY(-1px);
144
+ }
145
+
146
+ .progressWrap {
147
+ position: absolute;
148
+ left: 0;
149
+ right: 0;
150
+ bottom: 0;
151
+ height: 3px;
152
+ background: rgba(255, 255, 255, 0.06);
153
+ border-bottom-left-radius: var(--radius);
154
+ border-bottom-right-radius: var(--radius);
155
+ overflow: hidden;
156
+ }
157
+
158
+ .progress {
159
+ height: 100%;
160
+ width: 100%;
161
+ background: var(--progress);
162
+ transform-origin: left center;
163
+ transform: scaleX(1);
164
+ }
165
+
166
+ @media (prefers-reduced-motion: reduce) {
167
+ .root,
168
+ .root.exiting {
169
+ transition: none;
170
+ }
171
+ }
172
+
@@ -0,0 +1,52 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Notification</title>
7
+ <link rel="stylesheet" href="./styles/themes.css" />
8
+ <link rel="stylesheet" href="./styles/animations.css" />
9
+ <link rel="stylesheet" href="./styles/notification.css" />
10
+ </head>
11
+ <body>
12
+ <div
13
+ id="notification"
14
+ class="notification entering"
15
+ data-variant="default"
16
+ data-theme="dark"
17
+ role="button"
18
+ tabindex="0"
19
+ aria-label="Notification"
20
+ >
21
+ <div class="icon-area" id="iconArea" aria-hidden="true">
22
+ <img id="image" class="icon-image" alt="" />
23
+ <div id="iconSvg" class="icon-svg"></div>
24
+ </div>
25
+
26
+ <div class="content">
27
+ <div class="title" id="title"></div>
28
+ <div class="description" id="desc"></div>
29
+ <div class="progress-info" id="progressInfo">
30
+ <span class="progress-label" id="progressLabel"></span>
31
+ <span class="progress-percent" id="progressPercent"></span>
32
+ </div>
33
+ </div>
34
+
35
+ <button class="close-btn" id="closeBtn" aria-label="Close">
36
+ <svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">
37
+ <path
38
+ d="M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 0 0 5.7 7.11L10.59 12 5.7 16.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z"
39
+ fill="currentColor"
40
+ />
41
+ </svg>
42
+ </button>
43
+
44
+ <div class="bottom-bar" id="bottomBar" aria-hidden="true">
45
+ <div class="bottom-bar-fill" id="bottomBarFill"></div>
46
+ </div>
47
+ </div>
48
+
49
+ <script src="./scripts/notification.js"></script>
50
+ </body>
51
+ </html>
52
+
@@ -0,0 +1,137 @@
1
+ /* eslint-disable */
2
+ 'use strict';
3
+
4
+ // Runtime file used by `notification.html` directly.
5
+ // Source-of-truth TypeScript is `notification.ts`.
6
+
7
+ /**
8
+ * @param {string} key
9
+ * @param {string} fallback
10
+ */
11
+ function getParam(key, fallback = '') {
12
+ const sp = new URLSearchParams(window.location.search);
13
+ const v = sp.get(key);
14
+ return v == null ? fallback : v;
15
+ }
16
+
17
+ /**
18
+ * @param {string} key
19
+ * @param {number} fallback
20
+ */
21
+ function getNumberParam(key, fallback) {
22
+ const raw = getParam(key, '');
23
+ const n = Number(raw);
24
+ return Number.isFinite(n) ? n : fallback;
25
+ }
26
+
27
+ const id = getParam('id', '');
28
+ const title = getParam('title', '');
29
+ const description = getParam('description', '');
30
+ const image = getParam('image', '');
31
+ const duration = Math.max(0, Math.floor(getNumberParam('duration', 4000)));
32
+
33
+ const root = document.getElementById('root');
34
+ const titleEl = document.getElementById('title');
35
+ const descEl = document.getElementById('desc');
36
+ const closeBtn = document.getElementById('closeBtn');
37
+ const imgWrap = document.getElementById('imageWrap');
38
+ const imgEl = document.getElementById('image');
39
+ const defaultIconEl = document.getElementById('defaultIcon');
40
+ const progressEl = document.getElementById('progress');
41
+
42
+ titleEl.textContent = title;
43
+ descEl.textContent = description;
44
+
45
+ const hasImage = typeof image === 'string' && image.trim().length > 0;
46
+ if (hasImage) {
47
+ imgEl.src = image;
48
+ imgEl.style.display = 'block';
49
+ defaultIconEl.style.display = 'none';
50
+ } else {
51
+ imgEl.removeAttribute('src');
52
+ imgEl.style.display = 'none';
53
+ defaultIconEl.style.display = 'block';
54
+ }
55
+
56
+ let closing = false;
57
+ let autoTimer = null;
58
+
59
+ function enter() {
60
+ requestAnimationFrame(() => {
61
+ root.classList.remove('entering');
62
+ root.classList.add('entered');
63
+ });
64
+ }
65
+
66
+ /**
67
+ * @param {'timeout'|'manual'} reason
68
+ */
69
+ function requestClose(reason) {
70
+ if (closing) return;
71
+ closing = true;
72
+
73
+ if (autoTimer) {
74
+ clearTimeout(autoTimer);
75
+ autoTimer = null;
76
+ }
77
+
78
+ root.classList.remove('entered');
79
+ root.classList.add('exiting');
80
+
81
+ // Let animation play then ask main to close/destroy.
82
+ setTimeout(() => {
83
+ window.electronNotify.sendClose(id);
84
+ }, 220);
85
+
86
+ // Prevent click handler from firing late.
87
+ root.style.pointerEvents = 'none';
88
+ }
89
+
90
+ function startProgress() {
91
+ if (duration <= 0) {
92
+ // sticky: hide progress track
93
+ progressEl.style.opacity = '0';
94
+ return;
95
+ }
96
+
97
+ progressEl.style.opacity = '1';
98
+ progressEl.animate(
99
+ [{ transform: 'scaleX(1)' }, { transform: 'scaleX(0)' }],
100
+ { duration, easing: 'linear', fill: 'forwards' }
101
+ );
102
+
103
+ autoTimer = setTimeout(() => requestClose('timeout'), duration);
104
+ }
105
+
106
+ closeBtn.addEventListener('click', (e) => {
107
+ e.preventDefault();
108
+ e.stopPropagation();
109
+ requestClose('manual');
110
+ });
111
+
112
+ root.addEventListener('click', () => {
113
+ if (closing) return;
114
+ window.electronNotify.sendClick(id);
115
+ requestClose('manual');
116
+ });
117
+
118
+ root.addEventListener('keydown', (e) => {
119
+ if (e.key === 'Enter' || e.key === ' ') {
120
+ e.preventDefault();
121
+ root.click();
122
+ } else if (e.key === 'Escape') {
123
+ e.preventDefault();
124
+ requestClose('manual');
125
+ }
126
+ });
127
+
128
+ window.electronNotify.onReposition((_payload) => {
129
+ root.animate(
130
+ [{ transform: 'translateY(-2px)' }, { transform: 'translateY(0px)' }],
131
+ { duration: 240, easing: 'ease-out' }
132
+ );
133
+ });
134
+
135
+ enter();
136
+ startProgress();
137
+