livechat 0.4.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4589546ac2f8ee66f5fab13591998a651425a7afdb8811fd9b24dd50e7baa65
4
- data.tar.gz: 8e49eba0d5232f569ce96cb681ead311749247ef3eeb476d2ea4e2fe53bda2ad
3
+ metadata.gz: f42dfde953e1643e5cc5fbfce81dc237376788709890a6254a4800bec927f51d
4
+ data.tar.gz: 76e741f442b6b847d3aa4edd37432ee55f2fe6ac9d8d38a356bf716023f4e146
5
5
  SHA512:
6
- metadata.gz: a5ecb5d39149403a4da90f828ddd0bad398c0ad431300237a11063d18db31f989ab4f899ab834ba9801c88085d02367541e8e88b61db0563039d475eca1febac
7
- data.tar.gz: 2160a9f6928f2acd664a36267faac734bdb462311d0ad1efe2429f56687de91f22e149c483e1561e65666aec1cb6b8db457f53b6ca92bdf3c89f2d1f14699a0c
6
+ metadata.gz: 20ed071145a817ffa93933ea8db69585a64edc7bfd88931420126a2a82a5c096ff34b5b94fff2a12c3a092de20dd742e1df637355df20994f7d93c57965a0e7a
7
+ data.tar.gz: d77df77a8b6c6a9bf050403fb05c791fa02dd5fa350aa663e0d23b2445d1269110690321c3f8f8f9593fecba1a9e3013cb30e4b6a5f3d9327f042ecba6b80ae7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.2
4
+
5
+ - Breathing room between the widget's pending-file chips and the composer —
6
+ the chip row now has bottom padding, so it no longer sits flush against the
7
+ message input.
8
+
9
+ ## 0.4.1
10
+
11
+ - Consistent attachment UI across both sides. The inbox reply now shows the
12
+ same quiet paperclip + file chips (with per-file remove) as the visitor
13
+ widget, instead of the browser's raw "Choose Files" control — progressively
14
+ enhanced, so the native input still works without JavaScript. Also fixed the
15
+ widget's attach button rendering as a solid-blue second button (a CSS
16
+ specificity slip); it's now a quiet paperclip, with the accent reserved for
17
+ Send.
18
+
3
19
  ## 0.4.0
4
20
 
5
21
  - **File attachments.** Visitors and agents can attach images and documents to
@@ -98,7 +98,19 @@
98
98
  .reply textarea { resize: vertical; min-height: 44px; max-height: 200px; padding: 8px 10px;
99
99
  border: 1px solid var(--border); border-radius: 10px; font: inherit;
100
100
  background: var(--bg); color: var(--text); }
101
- .reply input[type=file] { font-size: 12px; color: var(--muted); }
101
+ .reply input[type=file].reply-file { font-size: 12px; color: var(--muted); }
102
+ .reply button.attach { align-self: flex-end; width: 42px; min-width: 42px; height: 42px; padding: 0;
103
+ display: flex; align-items: center; justify-content: center; color: var(--muted);
104
+ background: var(--surface); border: 1px solid var(--border); border-radius: 10px; }
105
+ .reply button.attach:hover { color: var(--text); background: var(--bg); }
106
+ .reply .chips { display: flex; flex-wrap: wrap; gap: 6px; }
107
+ .reply .chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
108
+ padding: 4px 6px 4px 10px; border: 1px solid var(--border); border-radius: 999px;
109
+ background: var(--bg); font-size: 12px; }
110
+ .reply .chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
111
+ .reply .chip-x { padding: 0 2px; border: none; background: none; color: var(--muted);
112
+ font-size: 16px; line-height: 1; cursor: pointer; }
113
+ .reply .chip-x:hover { color: var(--text); }
102
114
  .reply button.send { align-self: flex-end; width: 42px; min-width: 42px; height: 42px; padding: 0;
103
115
  display: flex; align-items: center; justify-content: center;
104
116
  background: var(--accent); border-color: var(--accent); color: var(--accent-text);
@@ -65,8 +65,10 @@
65
65
  <div class="compose">
66
66
  <%= form.text_area :body, rows: 2, autofocus: true, required: !Livechat.attachments_enabled?,
67
67
  placeholder: t('livechat.dashboard.reply_placeholder', default: 'Write your reply…') %>
68
+ <%# dashboard.js hides this and swaps in a paperclip button + file chips.
69
+ Left plain as a no-JS fallback so agents can still attach without it. %>
68
70
  <% if Livechat.attachments_enabled? %>
69
- <%= form.file_field :files, multiple: true,
71
+ <%= form.file_field :files, multiple: true, class: 'reply-file',
70
72
  aria: { label: t('livechat.dashboard.attach', default: 'Attach files') } %>
71
73
  <% end %>
72
74
  </div>
@@ -23,8 +23,78 @@
23
23
  ready(function () {
24
24
  watchIndex();
25
25
  watchThread();
26
+ enhanceReplyAttachments();
26
27
  });
27
28
 
29
+ // Progressive enhancement for the reply form's file input: hide the raw
30
+ // control and swap in a quiet paperclip plus file chips, matching the
31
+ // visitor widget. Without JS the native input stays and still works.
32
+ function enhanceReplyAttachments() {
33
+ var form = document.querySelector("form.reply");
34
+ if (!form) return;
35
+ var input = form.querySelector("input[type=file]");
36
+ if (!input) return;
37
+
38
+ input.hidden = true;
39
+ var canEdit = typeof DataTransfer !== "undefined"; // per-file removal needs it
40
+
41
+ var button = document.createElement("button");
42
+ button.type = "button";
43
+ button.className = "attach";
44
+ var label = input.getAttribute("aria-label") || "Attach files";
45
+ button.setAttribute("aria-label", label);
46
+ button.title = label;
47
+ // Paperclip (Heroicons, MIT) — same icon as the widget.
48
+ button.innerHTML =
49
+ '<svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">' +
50
+ '<path fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" ' +
51
+ 'stroke-linejoin="round" d="M18.4 8.6 9.9 17a3.5 3.5 0 0 1-5-5l8.5-8.4a2.3 2.3 0 0 1 ' +
52
+ '3.3 3.3l-8.5 8.4a1.1 1.1 0 0 1-1.6-1.6l7.8-7.8"/></svg>';
53
+ button.addEventListener("click", function () { input.click(); });
54
+ form.insertBefore(button, form.firstChild);
55
+
56
+ var chips = document.createElement("div");
57
+ chips.className = "chips";
58
+ chips.hidden = true;
59
+ var compose = form.querySelector(".compose") || form;
60
+ compose.insertBefore(chips, compose.firstChild);
61
+
62
+ input.addEventListener("change", render);
63
+
64
+ function render() {
65
+ var files = Array.prototype.slice.call(input.files);
66
+ chips.textContent = "";
67
+ chips.hidden = files.length === 0;
68
+ files.forEach(function (file, index) {
69
+ var chip = document.createElement("span");
70
+ chip.className = "chip";
71
+ var name = document.createElement("span");
72
+ name.className = "chip-name";
73
+ name.textContent = file.name;
74
+ chip.appendChild(name);
75
+ if (canEdit) {
76
+ var remove = document.createElement("button");
77
+ remove.type = "button";
78
+ remove.className = "chip-x";
79
+ remove.setAttribute("aria-label", "Remove file");
80
+ remove.innerHTML = "&times;";
81
+ remove.addEventListener("click", function () { removeAt(index); });
82
+ chip.appendChild(remove);
83
+ }
84
+ chips.appendChild(chip);
85
+ });
86
+ }
87
+
88
+ function removeAt(index) {
89
+ var kept = new DataTransfer();
90
+ Array.prototype.slice.call(input.files).forEach(function (file, i) {
91
+ if (i !== index) kept.items.add(file);
92
+ });
93
+ input.files = kept.files;
94
+ render();
95
+ }
96
+ }
97
+
28
98
  // The conversation list keeps itself fresh: when the server's token moves
29
99
  // (new message, new thread, resolve/reopen), just reload — unless the
30
100
  // agent is mid-search, whose typing must never be eaten.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Livechat
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.2'
5
5
  end
@@ -829,12 +829,14 @@
829
829
  "#lvc-form button:disabled{opacity:.6;cursor:default}" +
830
830
  "#lvc-root[dir=rtl] #lvc-form button svg{transform:scaleX(-1)}" +
831
831
  // Attach button sits alongside the send button, quieter (it's secondary).
832
- "#lvc-attach{border:none;background:none;color:var(--lvc-muted);width:36px;min-width:36px;" +
832
+ // Selector repeats the id twice so the quiet look outranks the shared
833
+ // `#lvc-form button` accent-fill rule (else the paperclip goes solid blue).
834
+ "#lvc-root #lvc-attach{border:none;background:none;color:var(--lvc-muted);width:38px;min-width:38px;" +
833
835
  "height:40px;align-self:flex-end;display:flex;align-items:center;justify-content:center;" +
834
836
  "cursor:pointer;border-radius:10px}" +
835
- "#lvc-attach:hover{background:var(--lvc-bg);color:var(--lvc-text)}" +
837
+ "#lvc-root #lvc-attach:hover{background:var(--lvc-bg);color:var(--lvc-text)}" +
836
838
  // Pending-file chips above the composer.
837
- "#lvc-files{display:flex;flex-wrap:wrap;gap:6px;padding:8px 12px 0}" +
839
+ "#lvc-files{display:flex;flex-wrap:wrap;gap:6px;padding:10px 12px}" +
838
840
  "#lvc-files[hidden]{display:none}" +
839
841
  "#lvc-root .lvc-chip{display:inline-flex;align-items:center;gap:6px;max-width:100%;" +
840
842
  "padding:4px 6px 4px 10px;border:1px solid var(--lvc-border);border-radius:999px;" +
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.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Shmarov