aumera-on-screen-widget 0.0.1 → 0.0.2
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.
- package/df-btn.js +179 -51
- package/package.json +2 -2
package/df-btn.js
CHANGED
|
@@ -89,6 +89,14 @@ if (!config.project) {
|
|
|
89
89
|
height: 48px
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
.df-btn-header {
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: space-between;
|
|
96
|
+
width: 100%;
|
|
97
|
+
height: 48px;
|
|
98
|
+
}
|
|
99
|
+
|
|
92
100
|
.df-btn-text:before {
|
|
93
101
|
min-width: 56px;
|
|
94
102
|
height: 48px;
|
|
@@ -118,11 +126,12 @@ if (!config.project) {
|
|
|
118
126
|
width: ${config.width || "400px"};
|
|
119
127
|
transition: all .45s cubic-bezier(.4, 0, .2, 1);
|
|
120
128
|
${config.position === "left" ? "float: left;" : "float: right;"}
|
|
121
|
-
opacity: 1
|
|
129
|
+
opacity: 1;
|
|
130
|
+
border-radius: 0 0 16px 16px;
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
.df-btn:not(.df-closed) > .df-btn-content {
|
|
125
|
-
|
|
134
|
+
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
.df-closed > .df-btn-content {
|
|
@@ -131,6 +140,48 @@ if (!config.project) {
|
|
|
131
140
|
opacity: 0
|
|
132
141
|
}
|
|
133
142
|
|
|
143
|
+
.maximize-minimize-btn {
|
|
144
|
+
width: 16px;
|
|
145
|
+
height: 16px;
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
margin-right: 12px;
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
justify-content: center;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.df-btn.df-maximized {
|
|
154
|
+
width: 100vw !important;
|
|
155
|
+
height: 100vh !important;
|
|
156
|
+
top: 0 !important;
|
|
157
|
+
left: 0 !important;
|
|
158
|
+
right: 0 !important;
|
|
159
|
+
bottom: 0 !important;
|
|
160
|
+
margin: 0 !important;
|
|
161
|
+
border-radius: 0 !important;
|
|
162
|
+
}
|
|
163
|
+
.df-btn.df-maximized .df-btn-content {
|
|
164
|
+
width: 100vw !important;
|
|
165
|
+
height: calc(100vh - 56px) !important;
|
|
166
|
+
opacity: 1 !important;
|
|
167
|
+
display: block !important;
|
|
168
|
+
}
|
|
169
|
+
.df-btn.df-closed .df-btn-content {
|
|
170
|
+
width: 0 !important;
|
|
171
|
+
height: 0 !important;
|
|
172
|
+
opacity: 0 !important;
|
|
173
|
+
display: none !important;
|
|
174
|
+
}
|
|
175
|
+
.close-btn {
|
|
176
|
+
width: 16px;
|
|
177
|
+
height: 16px;
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
margin-left: 12px;
|
|
180
|
+
display: flex;
|
|
181
|
+
align-items: center;
|
|
182
|
+
justify-content: center;
|
|
183
|
+
}
|
|
184
|
+
|
|
134
185
|
@media screen and (max-width: 720px){
|
|
135
186
|
.df-btn {
|
|
136
187
|
border-radius: 28px;
|
|
@@ -165,9 +216,8 @@ if (!config.project) {
|
|
|
165
216
|
}
|
|
166
217
|
|
|
167
218
|
.df-btn-text:before {
|
|
168
|
-
background-image: url('${
|
|
169
|
-
|
|
170
|
-
}')
|
|
219
|
+
background-image: url('${config.logoDark || origin + "/assets/logo_dark.svg"
|
|
220
|
+
}')
|
|
171
221
|
}
|
|
172
222
|
|
|
173
223
|
.df-btn:not(.df-closed) > .df-btn-text:before {
|
|
@@ -177,83 +227,161 @@ if (!config.project) {
|
|
|
177
227
|
|
|
178
228
|
@keyframes shake {
|
|
179
229
|
0%, 100% { transform: translateX(0); }
|
|
180
|
-
10%, 30%, 50%, 70%, 90% { transform: translateX(-${config.shakeAmplitude
|
|
181
|
-
|
|
230
|
+
10%, 30%, 50%, 70%, 90% { transform: translateX(-${config.shakeAmplitude
|
|
231
|
+
}px); }
|
|
232
|
+
20%, 40%, 60%, 80% { transform: translateX(${config.shakeAmplitude
|
|
233
|
+
}px); }
|
|
182
234
|
}
|
|
183
235
|
|
|
184
236
|
.df-btn.shake {
|
|
185
|
-
animation: shake ${config.shakeDuration/1000
|
|
237
|
+
animation: shake ${config.shakeDuration / 1000
|
|
238
|
+
}s cubic-bezier(.36,.07,.19,.97) both;
|
|
186
239
|
}
|
|
187
240
|
`;
|
|
188
241
|
|
|
189
242
|
document.head.appendChild(style);
|
|
190
243
|
document.write(`
|
|
191
244
|
<button class="df-btn df-closed" onclick="dfToggle()">
|
|
192
|
-
${config.showNotification
|
|
245
|
+
${config.showNotification
|
|
246
|
+
? '<div class="df-notification">Click to check messages</div>'
|
|
247
|
+
: ""
|
|
248
|
+
}
|
|
249
|
+
<div class="df-btn-header">
|
|
193
250
|
<div class="df-btn-text">${config.openText || "Chat"}</div>
|
|
194
|
-
|
|
251
|
+
</div>
|
|
252
|
+
<iframe class="df-btn-content" src="https://chat.dev.aumera.ai?orgId=1" allow="microphone *"></iframe>
|
|
195
253
|
</button>
|
|
196
254
|
`);
|
|
197
255
|
|
|
198
256
|
let dfToggled = false;
|
|
199
257
|
let inactivityTimer = null;
|
|
200
258
|
let shakeInterval = null;
|
|
259
|
+
let maximized = false;
|
|
201
260
|
|
|
202
261
|
const startInactivityTimer = () => {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (
|
|
207
|
-
notification.
|
|
262
|
+
// Only start inactivity timer if button is closed
|
|
263
|
+
if (!dfToggled) {
|
|
264
|
+
inactivityTimer = setTimeout(() => {
|
|
265
|
+
if (config.showNotification) {
|
|
266
|
+
const notification = document.querySelector(".df-notification");
|
|
267
|
+
if (notification) {
|
|
268
|
+
notification.classList.add("show");
|
|
269
|
+
}
|
|
208
270
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
}
|
|
271
|
+
|
|
272
|
+
if (config.animation === "shake") {
|
|
273
|
+
const button = document.querySelector(".df-btn");
|
|
274
|
+
const shakeButton = () => {
|
|
275
|
+
button.classList.add("shake");
|
|
276
|
+
setTimeout(() => {
|
|
277
|
+
button.classList.remove("shake");
|
|
278
|
+
}, config.shakeDuration);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Initial shake
|
|
282
|
+
shakeButton();
|
|
283
|
+
|
|
284
|
+
// Set up interval for repeated shakes
|
|
285
|
+
shakeInterval = setInterval(shakeButton, config.shakeInterval);
|
|
286
|
+
}
|
|
287
|
+
}, 5000);
|
|
288
|
+
}
|
|
227
289
|
};
|
|
228
290
|
|
|
229
|
-
const
|
|
291
|
+
const clearInactivityAndShake = () => {
|
|
230
292
|
if (inactivityTimer) {
|
|
231
293
|
clearTimeout(inactivityTimer);
|
|
294
|
+
inactivityTimer = null;
|
|
232
295
|
}
|
|
233
296
|
if (shakeInterval) {
|
|
234
297
|
clearInterval(shakeInterval);
|
|
298
|
+
shakeInterval = null;
|
|
235
299
|
}
|
|
236
|
-
startInactivityTimer();
|
|
237
300
|
};
|
|
238
301
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
302
|
+
// Add close and maximize/minimize buttons dynamically when chat is open
|
|
303
|
+
function updateHeaderButtons() {
|
|
304
|
+
const header = document.querySelector('.df-btn-header');
|
|
305
|
+
if (!header) return;
|
|
306
|
+
// Remove existing buttons if any
|
|
307
|
+
const oldClose = header.querySelector('.close-btn');
|
|
308
|
+
if (oldClose) header.removeChild(oldClose);
|
|
309
|
+
const oldMax = header.querySelector('.maximize-minimize-btn');
|
|
310
|
+
if (oldMax) header.removeChild(oldMax);
|
|
311
|
+
const btnText = header.querySelector('.df-btn-text');
|
|
312
|
+
const btn = document.querySelector('.df-btn');
|
|
313
|
+
if (!btn) return;
|
|
314
|
+
// If open
|
|
315
|
+
if (!btn.classList.contains('df-closed')) {
|
|
316
|
+
// Set text to Close
|
|
317
|
+
if (btnText) btnText.innerText = '';
|
|
318
|
+
// remove right padding from df-btn-text
|
|
319
|
+
btnText.style.paddingRight = '0';
|
|
320
|
+
// Add maximize/minimize button (right)
|
|
321
|
+
const maxBtn = document.createElement('div');
|
|
322
|
+
maxBtn.className = 'maximize-minimize-btn';
|
|
323
|
+
const maximized = btn.classList.contains('df-maximized');
|
|
324
|
+
maxBtn.innerHTML = `<img class="maximize-minimize-icon" src="${origin}/assets/${maximized ? 'collapse' : 'expand'}.svg" alt="${maximized ? 'Minimize' : 'Maximize'}" style="width:24px;height:24px;cursor:pointer;" />`;
|
|
325
|
+
header.appendChild(maxBtn);
|
|
326
|
+
maxBtn.addEventListener('click', (e) => {
|
|
327
|
+
e.stopPropagation();
|
|
328
|
+
maximizeMinimize();
|
|
329
|
+
});
|
|
330
|
+
// Add close button (left)
|
|
331
|
+
const closeBtn = document.createElement('div');
|
|
332
|
+
closeBtn.className = 'close-btn';
|
|
333
|
+
closeBtn.innerHTML = `<img src="${origin}/assets/close.svg" alt="Close" style="width:20px;height:20px;cursor:pointer;" />`;
|
|
334
|
+
header.insertBefore(closeBtn, btnText);
|
|
335
|
+
closeBtn.addEventListener('click', (e) => {
|
|
336
|
+
e.stopPropagation();
|
|
337
|
+
dfToggle();
|
|
338
|
+
});
|
|
339
|
+
} else {
|
|
340
|
+
// Set text to openText
|
|
341
|
+
if (btnText) btnText.innerText = config.openText || 'Chat';
|
|
342
|
+
// add right padding to df-btn-text only if screen size is greater than 720px
|
|
343
|
+
if (window.innerWidth > 720) {
|
|
344
|
+
btnText.style.paddingRight = '24px';
|
|
250
345
|
}
|
|
251
346
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function maximizeMinimize() {
|
|
350
|
+
const btn = document.querySelector('.df-btn');
|
|
351
|
+
if (!btn) return;
|
|
352
|
+
btn.classList.toggle('df-maximized');
|
|
353
|
+
updateHeaderButtons();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function dfToggle() {
|
|
357
|
+
const btn = document.querySelector('.df-btn');
|
|
358
|
+
if (!btn) return;
|
|
359
|
+
btn.classList.toggle('df-closed');
|
|
360
|
+
// Always remove maximized state when closing
|
|
361
|
+
if (btn.classList.contains('df-closed')) {
|
|
362
|
+
btn.classList.remove('df-maximized');
|
|
363
|
+
}
|
|
364
|
+
updateHeaderButtons();
|
|
365
|
+
clearInactivityAndShake();
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Patch window.dfToggle to our new function
|
|
369
|
+
window.dfToggle = dfToggle;
|
|
370
|
+
window.maximizeMinimize = maximizeMinimize;
|
|
371
|
+
// Initial call
|
|
372
|
+
updateHeaderButtons();
|
|
373
|
+
|
|
374
|
+
// Remove onclick from button, handle open/close in JS
|
|
375
|
+
const btn = document.querySelector('.df-btn');
|
|
376
|
+
btn.onclick = null;
|
|
377
|
+
btn.addEventListener('click', (e) => {
|
|
378
|
+
// Only toggle if chat is closed (popover mode)
|
|
379
|
+
if (btn.classList.contains('df-closed')) {
|
|
380
|
+
dfToggle();
|
|
381
|
+
}
|
|
382
|
+
// If open, do nothing (let header buttons handle maximize/minimize/close)
|
|
383
|
+
});
|
|
255
384
|
|
|
256
|
-
// Start the inactivity timer when the page loads
|
|
385
|
+
// Start the inactivity timer when the page loads (button is initially closed)
|
|
257
386
|
startInactivityTimer();
|
|
258
|
-
|
|
259
387
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aumera-on-screen-widget",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A lightweight, customizable chat widget for websites",
|
|
5
5
|
"main": "df-btn.js",
|
|
6
6
|
"scripts": {
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"README.md",
|
|
29
29
|
"LICENSE"
|
|
30
30
|
]
|
|
31
|
-
}
|
|
31
|
+
}
|