clay-server 2.17.0-beta.8 → 2.17.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.
package/lib/public/app.js CHANGED
@@ -8,7 +8,7 @@ import { initMateKnowledge, requestKnowledgeList, renderKnowledgeList, handleKno
8
8
  import { initRewind, setRewindMode, showRewindModal, clearPendingRewindUuid, addRewindButton } from './modules/rewind.js';
9
9
  import { initNotifications, showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundEnabled } from './modules/notifications.js';
10
10
  import { initInput, clearPendingImages, handleInputSync, autoResize, builtinCommands, sendMessage } from './modules/input.js';
11
- import { initQrCode } from './modules/qrcode.js';
11
+ import { initQrCode, triggerShare } from './modules/qrcode.js';
12
12
  import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
13
13
  import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
14
14
  import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, openArchive, closeArchive, isArchiveOpen, hideNotes, showNotes, isNotesVisible } from './modules/sticky-notes.js';
@@ -5168,6 +5168,8 @@ import { initLongPress } from './modules/longpress.js';
5168
5168
 
5169
5169
  // --- QR code ---
5170
5170
  initQrCode();
5171
+ var sharePill = document.getElementById("share-pill");
5172
+ if (sharePill) sharePill.addEventListener("click", triggerShare);
5171
5173
 
5172
5174
  // --- File browser ---
5173
5175
  initFileBrowser({
@@ -244,6 +244,25 @@
244
244
  margin-top: 2px;
245
245
  font-weight: 400;
246
246
  }
247
+ .qr-share-btn {
248
+ display: inline-flex;
249
+ align-items: center;
250
+ gap: 6px;
251
+ margin-top: 12px;
252
+ padding: 8px 16px;
253
+ border: 1px solid #ddd;
254
+ border-radius: 8px;
255
+ background: #fff;
256
+ color: #333;
257
+ font-family: inherit;
258
+ font-size: 13px;
259
+ font-weight: 500;
260
+ cursor: pointer;
261
+ transition: background 0.15s;
262
+ }
263
+ .qr-share-btn:hover { background: #f5f5f5; }
264
+ .qr-share-btn .lucide { width: 14px; height: 14px; }
265
+ .qr-share-btn.hidden { display: none; }
247
266
 
248
267
  /* --- Notification menu --- */
249
268
  #notif-menu-wrap {
@@ -75,6 +75,31 @@ button.top-bar-pill.pill-accent:hover { background: color-mix(in srgb, var(--acc
75
75
  .top-bar-install-btn.hidden { display: none; }
76
76
  .pwa-standalone .top-bar-install-btn { display: none !important; }
77
77
 
78
+ /* Share button — desktop only, same style as install pill */
79
+ .top-bar-share-btn {
80
+ display: inline-flex;
81
+ align-items: center;
82
+ gap: 4px;
83
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
84
+ color: var(--accent);
85
+ border: none;
86
+ border-radius: 10px;
87
+ padding: 2px 10px;
88
+ font-family: inherit;
89
+ font-size: 11px;
90
+ font-weight: 600;
91
+ cursor: pointer;
92
+ white-space: nowrap;
93
+ line-height: 1;
94
+ transition: background 0.15s;
95
+ }
96
+ .top-bar-share-btn .lucide { width: 12px; height: 12px; }
97
+ .top-bar-share-btn:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }
98
+ @media (max-width: 768px) {
99
+ .top-bar-share-btn { display: none; }
100
+ }
101
+ .pwa-standalone .top-bar-share-btn { display: none !important; }
102
+
78
103
  /* PWA install modal */
79
104
  .pwa-modal {
80
105
  position: fixed;
@@ -31,6 +31,7 @@
31
31
  <div id="top-bar">
32
32
  <div class="top-bar-left-pills">
33
33
  <button id="pwa-install-pill" class="top-bar-install-btn hidden" title="Open as app"><i data-lucide="download"></i> Open as app</button>
34
+ <button id="share-pill" class="top-bar-share-btn" title="Share"><i data-lucide="qr-code"></i> Share</button>
34
35
  <div id="update-pill-wrap" class="top-bar-update hidden">
35
36
  <button id="update-pill" class="top-bar-update-btn"><i data-lucide="arrow-up-circle"></i> <span id="update-version"></span> is available. Update now</button>
36
37
  <div id="update-popover" class="top-bar-popover">
@@ -723,6 +724,7 @@
723
724
  <div id="qr-overlay-inner">
724
725
  <div id="qr-canvas"></div>
725
726
  <div id="qr-url"></div>
727
+ <button id="qr-share-btn" class="qr-share-btn hidden"><i data-lucide="share-2"></i> Share</button>
726
728
  </div>
727
729
  </div>
728
730
 
@@ -308,7 +308,7 @@ function showPopover() {
308
308
  // Avatar row (overlapping banner)
309
309
  html += '<div class="profile-avatar-row">';
310
310
  html += '<div class="profile-popover-avatar">';
311
- html += '<img class="profile-popover-avatar-img" src="' + avatarUrl(currentStyle, seed, 80) + '" alt="avatar">';
311
+ html += '<img class="profile-popover-avatar-img" src="' + (profile.avatarCustom || avatarUrl(currentStyle, seed, 80)) + '" alt="avatar">';
312
312
  html += '</div>';
313
313
  html += '<div class="profile-name-display">' + escapeAttr(displayName || 'Awesome Clay User') + '</div>';
314
314
  html += '</div>';
@@ -12,16 +12,18 @@ function getShareUrl() {
12
12
  export function triggerShare() {
13
13
  var url = getShareUrl();
14
14
 
15
- // Use Web Share API if available
16
- if (navigator.share) {
15
+ // Use Web Share API on mobile only
16
+ var isMobile = window.innerWidth <= 768 || /Mobi|Android/i.test(navigator.userAgent);
17
+ if (isMobile && navigator.share) {
17
18
  navigator.share({ title: document.title || "Clay", url: url }).catch(function () {});
18
19
  return;
19
20
  }
20
21
 
21
- // Fallback: show QR overlay
22
+ // Show QR overlay
22
23
  var qrOverlay = document.getElementById("qr-overlay");
23
24
  var qrCanvas = document.getElementById("qr-canvas");
24
25
  var qrUrl = document.getElementById("qr-url");
26
+ var qrShareBtn = document.getElementById("qr-share-btn");
25
27
 
26
28
  var qr = qrcode(0, "M");
27
29
  qr.addData(url);
@@ -29,6 +31,15 @@ export function triggerShare() {
29
31
  qrCanvas.innerHTML = qr.createSvgTag(5, 0);
30
32
  qrUrl.innerHTML = url + '<span class="qr-hint">click to copy</span>';
31
33
 
34
+ // Show browser share button if Web Share API is available
35
+ if (qrShareBtn) {
36
+ if (navigator.share) {
37
+ qrShareBtn.classList.remove("hidden");
38
+ } else {
39
+ qrShareBtn.classList.add("hidden");
40
+ }
41
+ }
42
+
32
43
  qrOverlay.classList.remove("hidden");
33
44
  }
34
45
 
@@ -58,6 +69,15 @@ export function initQrCode() {
58
69
  e.stopPropagation();
59
70
  });
60
71
 
72
+ // Browser share button
73
+ var qrShareBtn = document.getElementById("qr-share-btn");
74
+ if (qrShareBtn) {
75
+ qrShareBtn.addEventListener("click", function () {
76
+ var url = getShareUrl();
77
+ navigator.share({ title: document.title || "Clay", url: url }).catch(function () {});
78
+ });
79
+ }
80
+
61
81
  // ESC to close
62
82
  document.addEventListener("keydown", function (e) {
63
83
  if (e.key === "Escape" && !qrOverlay.classList.contains("hidden")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.17.0-beta.8",
3
+ "version": "2.17.0",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",