livechat 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +8 -2
- data/lib/livechat/version.rb +1 -1
- data/lib/livechat/widget.js +61 -21
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b796f38ce15d2bbedc3b49cceeb0bfc8c5ee26610a6841d956aa3711c18da550
|
|
4
|
+
data.tar.gz: d163445e0442f0f155227210a12a2bdd3f87ec01523a96f29bb898de0550a079
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a0947576d889216cf1b1330093baa73c5dcae8b55f10b682f19953a02d8e1ac071d02d38bc51ae23cd11352bec7dbba9f77520d199167b1553d9ccf75598894
|
|
7
|
+
data.tar.gz: 59c6ad9b5a10cc2b2a2c13ce50693e4d9c492982e098c6ec42edb84c3b343c96154c988a4dc356d8e259bebc433295c10571a216cc5f451d102a653a26c81f2d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- Unread count badges on `data-livechat-open` elements, so launcher-less
|
|
6
|
+
setups (`show_launcher = false`) still surface waiting replies.
|
|
7
|
+
- Message prefill: `data-livechat-message="…"` on any opener, or
|
|
8
|
+
`window.Livechat.open("…")` — seeds the message box for contextual asks,
|
|
9
|
+
never overwriting a visitor's draft.
|
|
10
|
+
|
|
3
11
|
## 0.1.0
|
|
4
12
|
|
|
5
13
|
- Initial release: floating chat widget (guests + signed-in visitors, one
|
data/README.md
CHANGED
|
@@ -134,8 +134,14 @@ reply. Gated by `config.authorize_agent` (development-only until you set it).
|
|
|
134
134
|
|
|
135
135
|
## Widget API
|
|
136
136
|
|
|
137
|
-
- `window.Livechat.open()` / `window.Livechat.close()`
|
|
138
|
-
|
|
137
|
+
- `window.Livechat.open()` / `window.Livechat.close()` —
|
|
138
|
+
`open("Hi, I need help with…")` prefills the message box (never over a
|
|
139
|
+
visitor's draft)
|
|
140
|
+
- Any element with `data-livechat-open` opens the panel on click; add
|
|
141
|
+
`data-livechat-message="…"` to prefill — great for contextual buttons
|
|
142
|
+
("Request verification", "Ask about billing")
|
|
143
|
+
- While replies are unread, every `data-livechat-open` element carries a
|
|
144
|
+
small count badge — so hiding the launcher doesn't hide the answer
|
|
139
145
|
- `<%= livechat_button %>` renders a plain, unstyled opener button
|
|
140
146
|
- `config.show_launcher = false` hides the bubble entirely — bring your own
|
|
141
147
|
entry point
|
data/lib/livechat/version.rb
CHANGED
data/lib/livechat/widget.js
CHANGED
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
injectStyles();
|
|
84
84
|
mount();
|
|
85
85
|
applyBrandColor();
|
|
86
|
+
syncOpenerBadges(); // a Turbo visit brings fresh openers — restamp them
|
|
86
87
|
|
|
87
88
|
if (sessionGet("livechat_open") === "1") {
|
|
88
89
|
openPanel();
|
|
@@ -100,7 +101,7 @@
|
|
|
100
101
|
if (!opener) return;
|
|
101
102
|
event.preventDefault();
|
|
102
103
|
event.stopPropagation();
|
|
103
|
-
openPanel();
|
|
104
|
+
openPanel(opener.getAttribute("data-livechat-message"));
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
// --- mounting ---------------------------------------------------------------
|
|
@@ -287,24 +288,33 @@
|
|
|
287
288
|
|
|
288
289
|
// --- open / close -----------------------------------------------------------
|
|
289
290
|
|
|
290
|
-
|
|
291
|
+
// prefill (optional string, from data-livechat-message or
|
|
292
|
+
// Livechat.open("…")) seeds the input — but never over a visitor's draft.
|
|
293
|
+
function openPanel(prefill) {
|
|
291
294
|
mount();
|
|
292
|
-
if (isOpen)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
295
|
+
if (!isOpen) {
|
|
296
|
+
isOpen = true;
|
|
297
|
+
sessionSet("livechat_open", "1");
|
|
298
|
+
|
|
299
|
+
// The panel is built once and then hidden/shown — closing must never
|
|
300
|
+
// throw away the rendered thread or a half-written message.
|
|
301
|
+
var panel = document.getElementById("lvc-panel");
|
|
302
|
+
if (!panel) {
|
|
303
|
+
panel = buildPanel();
|
|
304
|
+
root.appendChild(panel);
|
|
305
|
+
}
|
|
306
|
+
panel.hidden = false;
|
|
307
|
+
setUnread(0);
|
|
308
|
+
poll();
|
|
309
|
+
schedulePoll();
|
|
310
|
+
}
|
|
311
|
+
if (inputEl) {
|
|
312
|
+
if (typeof prefill === "string" && prefill && !inputEl.value.trim()) {
|
|
313
|
+
inputEl.value = prefill;
|
|
314
|
+
autogrow();
|
|
315
|
+
}
|
|
316
|
+
inputEl.focus();
|
|
302
317
|
}
|
|
303
|
-
panel.hidden = false;
|
|
304
|
-
setUnread(0);
|
|
305
|
-
poll();
|
|
306
|
-
schedulePoll();
|
|
307
|
-
if (inputEl) inputEl.focus();
|
|
308
318
|
}
|
|
309
319
|
|
|
310
320
|
function closePanel() {
|
|
@@ -356,10 +366,35 @@
|
|
|
356
366
|
.catch(function () { fetching = false; });
|
|
357
367
|
}
|
|
358
368
|
|
|
369
|
+
var unreadCount = 0;
|
|
370
|
+
|
|
359
371
|
function setUnread(count) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
372
|
+
unreadCount = count;
|
|
373
|
+
if (badgeEl) {
|
|
374
|
+
badgeEl.hidden = !(count > 0);
|
|
375
|
+
badgeEl.textContent = count > 9 ? "9+" : String(count);
|
|
376
|
+
}
|
|
377
|
+
syncOpenerBadges();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Hosts that hide the launcher still get an unread indicator: every
|
|
381
|
+
// data-livechat-open element carries a small count badge while replies
|
|
382
|
+
// are waiting, and loses it the moment the panel opens.
|
|
383
|
+
function syncOpenerBadges() {
|
|
384
|
+
var openers = document.querySelectorAll("[data-livechat-open]");
|
|
385
|
+
for (var i = 0; i < openers.length; i++) {
|
|
386
|
+
var badge = openers[i].querySelector(".lvc-opener-badge");
|
|
387
|
+
if (unreadCount > 0) {
|
|
388
|
+
if (!badge) {
|
|
389
|
+
badge = document.createElement("span");
|
|
390
|
+
badge.className = "lvc-opener-badge";
|
|
391
|
+
openers[i].appendChild(badge);
|
|
392
|
+
}
|
|
393
|
+
badge.textContent = unreadCount > 9 ? "9+" : String(unreadCount);
|
|
394
|
+
} else if (badge) {
|
|
395
|
+
badge.remove();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
363
398
|
}
|
|
364
399
|
|
|
365
400
|
function syncEmailRow() {
|
|
@@ -553,7 +588,12 @@
|
|
|
553
588
|
"color:var(--lvc-accent-text);width:40px;min-width:40px;height:40px;align-self:flex-end;" +
|
|
554
589
|
"display:flex;align-items:center;justify-content:center;cursor:pointer}" +
|
|
555
590
|
"#lvc-form button:disabled{opacity:.6;cursor:default}" +
|
|
556
|
-
"#lvc-root[dir=rtl] #lvc-form button svg{transform:scaleX(-1)}"
|
|
591
|
+
"#lvc-root[dir=rtl] #lvc-form button svg{transform:scaleX(-1)}" +
|
|
592
|
+
// Lives in host DOM (on data-livechat-open elements), so no #lvc-root prefix.
|
|
593
|
+
".lvc-opener-badge{display:inline-flex;min-width:18px;height:18px;padding:0 5px;" +
|
|
594
|
+
"margin-inline-start:6px;border-radius:999px;background:#dc2626;color:#fff;" +
|
|
595
|
+
"font-size:11px;font-weight:700;line-height:18px;align-items:center;" +
|
|
596
|
+
"justify-content:center;vertical-align:middle}";
|
|
557
597
|
|
|
558
598
|
var style = document.createElement("style");
|
|
559
599
|
style.id = "lvc-styles";
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: livechat
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yaroslav Shmarov
|
|
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
118
118
|
- !ruby/object:Gem::Version
|
|
119
119
|
version: '0'
|
|
120
120
|
requirements: []
|
|
121
|
-
rubygems_version:
|
|
121
|
+
rubygems_version: 3.6.9
|
|
122
122
|
specification_version: 4
|
|
123
123
|
summary: 'Open-source live chat for Rails: a drop-in support widget plus a team inbox,
|
|
124
124
|
in your own database.'
|