nostr-components 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.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +334 -0
  3. package/dist/assets/base-styles-CBypR3FR.js +145 -0
  4. package/dist/assets/base-styles-CBypR3FR.js.map +1 -0
  5. package/dist/assets/copy-delegation-C4uvRTVM.js +15 -0
  6. package/dist/assets/copy-delegation-C4uvRTVM.js.map +1 -0
  7. package/dist/assets/dialog-component-Dqg0QU9I.js +66 -0
  8. package/dist/assets/dialog-component-Dqg0QU9I.js.map +1 -0
  9. package/dist/assets/dialog-likers-BzTesCZa.js +238 -0
  10. package/dist/assets/dialog-likers-BzTesCZa.js.map +1 -0
  11. package/dist/assets/icons-Dr_d9MII.js +105 -0
  12. package/dist/assets/icons-Dr_d9MII.js.map +1 -0
  13. package/dist/assets/nip05-utils-BNBHUmkr.js +2 -0
  14. package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -0
  15. package/dist/assets/nostr-service-pr_crY62.js +78 -0
  16. package/dist/assets/nostr-service-pr_crY62.js.map +1 -0
  17. package/dist/assets/nostr-user-component-Q7GeeFyu.js +2 -0
  18. package/dist/assets/nostr-user-component-Q7GeeFyu.js.map +1 -0
  19. package/dist/assets/preload-helper-D7HrI6pR.js +2 -0
  20. package/dist/assets/preload-helper-D7HrI6pR.js.map +1 -0
  21. package/dist/assets/pure-jrVhRVpB.js +2 -0
  22. package/dist/assets/pure-jrVhRVpB.js.map +1 -0
  23. package/dist/assets/theme-C1r1Zw8r.js +2 -0
  24. package/dist/assets/theme-C1r1Zw8r.js.map +1 -0
  25. package/dist/assets/user-resolver-C-E6KdwY.js +2 -0
  26. package/dist/assets/user-resolver-C-E6KdwY.js.map +1 -0
  27. package/dist/assets/utils--bxLbhGF.js +2 -0
  28. package/dist/assets/utils--bxLbhGF.js.map +1 -0
  29. package/dist/assets/zap-utils-B1sz0Abx.js +2 -0
  30. package/dist/assets/zap-utils-B1sz0Abx.js.map +1 -0
  31. package/dist/components/nostr-comment.es.js +924 -0
  32. package/dist/components/nostr-comment.es.js.map +1 -0
  33. package/dist/components/nostr-dm.es.js +217 -0
  34. package/dist/components/nostr-dm.es.js.map +1 -0
  35. package/dist/components/nostr-follow-button.es.js +103 -0
  36. package/dist/components/nostr-follow-button.es.js.map +1 -0
  37. package/dist/components/nostr-like.es.js +296 -0
  38. package/dist/components/nostr-like.es.js.map +1 -0
  39. package/dist/components/nostr-live-chat.es.js +523 -0
  40. package/dist/components/nostr-live-chat.es.js.map +1 -0
  41. package/dist/components/nostr-post.es.js +441 -0
  42. package/dist/components/nostr-post.es.js.map +1 -0
  43. package/dist/components/nostr-profile-badge.es.js +100 -0
  44. package/dist/components/nostr-profile-badge.es.js.map +1 -0
  45. package/dist/components/nostr-profile.es.js +287 -0
  46. package/dist/components/nostr-profile.es.js.map +1 -0
  47. package/dist/components/nostr-zap.es.js +694 -0
  48. package/dist/components/nostr-zap.es.js.map +1 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/nostr-comment.d.ts +4 -0
  51. package/dist/nostr-components.es.js +2 -0
  52. package/dist/nostr-components.es.js.map +1 -0
  53. package/dist/nostr-components.umd.js +4200 -0
  54. package/dist/nostr-components.umd.js.map +1 -0
  55. package/dist/nostr-dm.d.ts +4 -0
  56. package/dist/nostr-follow-button.d.ts +4 -0
  57. package/dist/nostr-like.d.ts +4 -0
  58. package/dist/nostr-live-chat.d.ts +4 -0
  59. package/dist/nostr-post.d.ts +4 -0
  60. package/dist/nostr-profile-badge.d.ts +4 -0
  61. package/dist/nostr-profile.d.ts +4 -0
  62. package/dist/nostr-zap.d.ts +4 -0
  63. package/dist/src/base/base-component/nostr-base-component.d.ts +116 -0
  64. package/dist/src/base/copy-delegation.d.ts +5 -0
  65. package/dist/src/base/dialog-component/dialog-component.d.ts +67 -0
  66. package/dist/src/base/dialog-component/style.d.ts +5 -0
  67. package/dist/src/base/event-component/nostr-event-component.d.ts +53 -0
  68. package/dist/src/base/render-options.d.ts +5 -0
  69. package/dist/src/base/resolvers/event-resolver.d.ts +20 -0
  70. package/dist/src/base/resolvers/user-resolver.d.ts +19 -0
  71. package/dist/src/base/text-row/render-name.d.ts +7 -0
  72. package/dist/src/base/text-row/render-nip05.d.ts +1 -0
  73. package/dist/src/base/text-row/render-npub.d.ts +1 -0
  74. package/dist/src/base/text-row/render-text-row.d.ts +9 -0
  75. package/dist/src/base/user-component/nostr-user-component.d.ts +43 -0
  76. package/dist/src/common/base-styles.d.ts +44 -0
  77. package/dist/src/common/constants.d.ts +4 -0
  78. package/dist/src/common/date-utils.d.ts +9 -0
  79. package/dist/src/common/icons.d.ts +7 -0
  80. package/dist/src/common/nip05-utils.d.ts +13 -0
  81. package/dist/src/common/nostr-service.d.ts +40 -0
  82. package/dist/src/common/theme.d.ts +4 -0
  83. package/dist/src/common/types.d.ts +1 -0
  84. package/dist/src/common/utils.d.ts +34 -0
  85. package/dist/src/index.d.ts +10 -0
  86. package/dist/src/nostr-comment/nostr-comment.d.ts +60 -0
  87. package/dist/src/nostr-comment/render.d.ts +15 -0
  88. package/dist/src/nostr-comment/utils.d.ts +81 -0
  89. package/dist/src/nostr-dm/nostr-dm.d.ts +34 -0
  90. package/dist/src/nostr-dm/render.d.ts +15 -0
  91. package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +24 -0
  92. package/dist/src/nostr-follow-button/render.d.ts +11 -0
  93. package/dist/src/nostr-follow-button/style.d.ts +1 -0
  94. package/dist/src/nostr-like/dialog-help-style.d.ts +1 -0
  95. package/dist/src/nostr-like/dialog-help.d.ts +2 -0
  96. package/dist/src/nostr-like/dialog-likers-style.d.ts +1 -0
  97. package/dist/src/nostr-like/dialog-likers.d.ts +24 -0
  98. package/dist/src/nostr-like/like-utils.d.ts +52 -0
  99. package/dist/src/nostr-like/nostr-like.d.ts +49 -0
  100. package/dist/src/nostr-like/render.d.ts +10 -0
  101. package/dist/src/nostr-like/style.d.ts +1 -0
  102. package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +65 -0
  103. package/dist/src/nostr-live-chat/render.d.ts +31 -0
  104. package/dist/src/nostr-post/nostr-post.d.ts +25 -0
  105. package/dist/src/nostr-post/parse-text.d.ts +8 -0
  106. package/dist/src/nostr-post/render-content.d.ts +5 -0
  107. package/dist/src/nostr-post/render.d.ts +19 -0
  108. package/dist/src/nostr-post/style.d.ts +1 -0
  109. package/dist/src/nostr-profile/nostr-profile.d.ts +24 -0
  110. package/dist/src/nostr-profile/render-stats.d.ts +1 -0
  111. package/dist/src/nostr-profile/render.d.ts +22 -0
  112. package/dist/src/nostr-profile/style.d.ts +1 -0
  113. package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +34 -0
  114. package/dist/src/nostr-profile-badge/render.d.ts +11 -0
  115. package/dist/src/nostr-profile-badge/style.d.ts +1 -0
  116. package/dist/src/nostr-zap/dialog-help-style.d.ts +5 -0
  117. package/dist/src/nostr-zap/dialog-help.d.ts +2 -0
  118. package/dist/src/nostr-zap/dialog-zap-style.d.ts +6 -0
  119. package/dist/src/nostr-zap/dialog-zap.d.ts +31 -0
  120. package/dist/src/nostr-zap/dialog-zappers-style.d.ts +1 -0
  121. package/dist/src/nostr-zap/dialog-zappers.d.ts +25 -0
  122. package/dist/src/nostr-zap/nostr-zap.d.ts +45 -0
  123. package/dist/src/nostr-zap/render.d.ts +9 -0
  124. package/dist/src/nostr-zap/style.d.ts +1 -0
  125. package/dist/src/nostr-zap/zap-utils.d.ts +53 -0
  126. package/dist/themes/dark.css +10 -0
  127. package/dist/themes/light.css +10 -0
  128. package/dist/themes.css +52 -0
  129. package/dist/vite.config.d.ts +2 -0
  130. package/dist/vite.config.esm.d.ts +2 -0
  131. package/dist/vite.config.umd.d.ts +2 -0
  132. package/package.json +95 -0
@@ -0,0 +1,523 @@
1
+ var P=Object.defineProperty;var H=(h,f,t)=>f in h?P(h,f,{enumerable:!0,configurable:!0,writable:!0,value:t}):h[f]=t;var a=(h,f,t)=>H(h,typeof f!="symbol"?f+"":f,t);import{_ as L}from"../assets/preload-helper-D7HrI6pR.js";import{N as A,D,c as v,d as $,e as M,g as S}from"../assets/nostr-service-pr_crY62.js";import{g as R,a as C}from"../assets/theme-C1r1Zw8r.js";import{r as U}from"../assets/nip05-utils-BNBHUmkr.js";import"../assets/icons-Dr_d9MII.js";function K(h){try{return new Date(h*1e3).toLocaleString()}catch{return""}}function _(h){try{const f=Date.now(),t=h*1e3,r=f-t,e=Math.floor(r/1e3);if(e<60)return"just now";if(e<3600){const s=Math.floor(e/60);return`${s} ${s===1?"min":"mins"} ago`}if(e<86400){const s=Math.floor(e/3600);return`${s} ${s===1?"hour":"hours"} ago`}if(e<2592e3){const s=Math.floor(e/86400);return`${s} ${s===1?"day":"days"} ago`}if(e<31536e3){const s=Math.floor(e/2592e3);return`${s} ${s===1?"month":"months"} ago`}const o=Math.floor(e/31536e3);return`${o} ${o===1?"year":"years"} ago`}catch{return""}}function I(h){return h==="me"||h==="them"?h:"them"}function y(h){return h==null?"":String(h).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function O({theme:h,recipientNpub:f,recipientName:t,recipientPicture:r,message:e,messages:o,isLoading:s,isFinding:l,isError:p,errorMessage:i,currentUserName:d,currentUserPicture:b,showWelcome:k,welcomeText:u,startChatText:n,maxMessageLength:g}){const m=typeof g=="number"?g:1e3,N=(e||"").length,E=Math.max(0,m-N),T=E<=10?"nostr-chat-char-counter warn":"nostr-chat-char-counter";return`
2
+ <div class="nostr-chat-container ${p?"nostr-chat-error":""}">
3
+ <div class="nostr-chat-header">
4
+ <div class="nostr-chat-header-left">
5
+ ${f&&t?`
6
+ <div class="nostr-chat-recipient">
7
+ <div class="nostr-chat-recipient-info">
8
+ <img
9
+ src="${y(r)||""}"
10
+ alt="${y(t)||""}"
11
+ class="nostr-chat-recipient-avatar"
12
+ onerror="this.onerror=null; this.src='https://via.placeholder.com/40';"
13
+ >
14
+ <span class="nostr-chat-recipient-name">${y(t)||y(f)}</span>
15
+ </div>
16
+ </div>
17
+ `:`
18
+ <div class="nostr-chat-recipient-placeholder">
19
+ ${R(24,24)}
20
+ <span>Nostr Live Chat</span>
21
+ </div>
22
+ `}
23
+ </div>
24
+ <div class="nostr-chat-header-right">
25
+ ${d?`
26
+ <div class="nostr-chat-self">
27
+ <img
28
+ src="${y(b)||""}"
29
+ alt="${y(d)||"You"}"
30
+ class="nostr-chat-self-avatar"
31
+ onerror="this.onerror=null; this.src='https://via.placeholder.com/32';"
32
+ >
33
+ <span class="nostr-chat-self-name">${y(d)}</span>
34
+ </div>
35
+ `:""}
36
+ <button class="nostr-chat-close-btn" title="Minimize">×</button>
37
+ </div>
38
+ </div>
39
+
40
+ <div class="nostr-chat-content">
41
+ ${f?k?`
42
+ <div class="nostr-chat-welcome">
43
+ <div class="nostr-chat-welcome-text">${y(u)||"Welcome!"}</div>
44
+ <button class="nostr-chat-start-btn">${y(n)||"Start chat"}</button>
45
+ </div>
46
+ `:`
47
+ <div class="nostr-chat-history">
48
+ ${o.map(w=>`
49
+ <div class="nostr-chat-message-row nostr-chat-message-${I(w.sender)} ${w.sender==="me"&&w.status==="sending"?"sending":""} ${w.sender==="me"&&w.status==="failed"?"failed":""}">
50
+ <div class="nostr-chat-message-bubble">${y(w.text)}</div>
51
+ <div class="nostr-chat-message-meta">
52
+ <span class="nostr-chat-message-timestamp" title="${y(K(w.timestamp))}">${y(_(w.timestamp))}</span>
53
+ </div>
54
+ </div>
55
+ `).join("")}
56
+ </div>
57
+ <div class="nostr-chat-actions">
58
+ <textarea
59
+ class="nostr-chat-textarea"
60
+ placeholder="Type your message..."
61
+ maxlength="${m}"
62
+ >${y(e)}</textarea>
63
+ <div class="${T}" aria-live="polite">${E} chars left</div>
64
+ <button class="nostr-chat-send-btn" ${s?"disabled":""}>
65
+ ${s?C():"Send"}
66
+ </button>
67
+ </div>
68
+ `:`
69
+ <div class="nostr-chat-npub-input-container">
70
+ <input type="text" class="nostr-chat-npub-input" placeholder="Enter recipient's npub/nip05 address..." />
71
+ <button class="nostr-chat-find-btn" ${l?"disabled":""}>
72
+ ${l?`${C()} <span>Finding...</span>`:"<span>Find</span>"}
73
+ </button>
74
+ </div>
75
+ `}
76
+ </div>
77
+
78
+ ${p?`<small class="nostr-chat-error-message">${y(i)}</small>`:""}
79
+ </div>
80
+ `}function z(h){return`
81
+ <style>
82
+ :host {
83
+ --nstrc-chat-background-dark: #222222;
84
+ --nstrc-chat-background-light: #FFFFFF;
85
+ --nstrc-chat-text-color-dark: #FFFFFF;
86
+ --nstrc-chat-text-color-light: #000000;
87
+ --nstrc-chat-border-dark: 1px solid #444444;
88
+ --nstrc-chat-border-light: 1px solid #DDDDDD;
89
+ --nstrc-chat-input-background-dark: #333333;
90
+ --nstrc-chat-input-background-light: #F9F9F9;
91
+ --nstrc-chat-my-message-background-dark: #5A3E85;
92
+ --nstrc-chat-my-message-background-light: #E6DDF4;
93
+ /* Unified accent variables with light/dark variants */
94
+ --nstrc-chat-accent-color-dark: #5A3E85;
95
+ --nstrc-chat-accent-color-light: #7E4FD2;
96
+ --nstrc-chat-accent-text-color-dark: #FFFFFF;
97
+ --nstrc-chat-accent-text-color-light: #FFFFFF;
98
+ --nstrc-chat-their-message-background-dark: #3A3A3A;
99
+ --nstrc-chat-their-message-background-light: #F0F0F0;
100
+ --nstrc-chat-button-background-dark: #5A3E85;
101
+ --nstrc-chat-button-background-light: #7E4FD2;
102
+ --nstrc-chat-button-text-dark: #FFFFFF;
103
+ --nstrc-chat-button-text-light: #FFFFFF;
104
+ --nstrc-chat-error-color: #FF4D4F;
105
+ --nstrc-chat-border-radius: 12px;
106
+
107
+ --nstrc-chat-background: var(--nstrc-chat-background-${h});
108
+ --nstrc-chat-text-color: var(--nstrc-chat-text-color-${h});
109
+ --nstrc-chat-border: var(--nstrc-chat-border-${h});
110
+ --nstrc-chat-input-background: var(--nstrc-chat-input-background-${h});
111
+ --nstrc-chat-my-message-background: var(--nstrc-chat-my-message-background-${h});
112
+ --nstrc-chat-their-message-background: var(--nstrc-chat-their-message-background-${h});
113
+ --nstrc-chat-button-background: var(--nstrc-chat-button-background-${h});
114
+ --nstrc-chat-button-text: var(--nstrc-chat-button-text-${h});
115
+ --nstrc-chat-accent-color: var(--nstrc-chat-accent-color-${h});
116
+ --nstrc-chat-accent-text-color: var(--nstrc-chat-accent-text-color-${h});
117
+ }
118
+
119
+ /* Floating modes shrink the host so it doesn't affect page layout */
120
+ :host([display-type="fab"]),
121
+ :host([display-type="bottom-bar"]),
122
+ :host([display-type="full"]) {
123
+ width: 0;
124
+ height: 0;
125
+ }
126
+
127
+ /* Floating panel wrapper */
128
+ .nostr-chat-float-panel {
129
+ position: fixed;
130
+ bottom: 20px;
131
+ right: 20px;
132
+ z-index: 2147483000;
133
+ box-shadow: 0 8px 24px rgba(0,0,0,0.18);
134
+ border-radius: var(--nstrc-chat-border-radius);
135
+ display: none;
136
+ }
137
+ .nostr-chat-float-panel.open { display: block; }
138
+
139
+ /* Close (minimize) button for floating panel */
140
+ .nostr-chat-close-btn {
141
+ width: 32px;
142
+ height: 32px;
143
+ border-radius: 50%;
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: center;
147
+ font-weight: 700;
148
+ font-size: 16px;
149
+ cursor: pointer;
150
+ background: rgba(0,0,0,0.1);
151
+ color: var(--nstrc-chat-text-color);
152
+ border: none;
153
+ transition: background-color 0.2s ease;
154
+ }
155
+ .nostr-chat-close-btn:hover {
156
+ background: rgba(0,0,0,0.2);
157
+ }
158
+
159
+ /* Hide close button in embed mode */
160
+ :host([display-type="embed"]) .nostr-chat-close-btn {
161
+ display: none;
162
+ }
163
+
164
+ /* Launcher: FAB */
165
+ .nostr-chat-launcher.fab {
166
+ position: fixed;
167
+ bottom: 20px;
168
+ right: 20px;
169
+ z-index: 2147483000;
170
+ display: flex;
171
+ align-items: center;
172
+ gap: 10px;
173
+ font-family: Inter, sans-serif;
174
+ }
175
+ .nostr-chat-launcher .bubble {
176
+ background: var(--nstrc-chat-background);
177
+ color: var(--nstrc-chat-text-color);
178
+ border: var(--nstrc-chat-border);
179
+ border-radius: 14px;
180
+ padding: 10px 12px;
181
+ box-shadow: 0 6px 20px rgba(0,0,0,0.12);
182
+ }
183
+ .nostr-chat-launcher .bubble .title { font-weight: 700; font-size: 14px; }
184
+ .nostr-chat-launcher .bubble .subtitle { font-size: 12px; opacity: 0.8; }
185
+ .nostr-chat-launcher .fab-btn {
186
+ width: 64px;
187
+ height: 64px;
188
+ border-radius: 50%;
189
+ background: var(--nstrc-chat-accent-color);
190
+ color: var(--nstrc-chat-accent-text-color);
191
+ display: flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ border: none;
195
+ cursor: pointer;
196
+ box-shadow: 0 6px 20px rgba(0,0,0,0.18);
197
+ font-size: 24px; /* Larger emoji/icon */
198
+ }
199
+
200
+ /* Launcher: Bottom bar */
201
+ .nostr-chat-launcher.bottom-bar {
202
+ position: fixed;
203
+ left: 50%;
204
+ transform: translateX(-50%);
205
+ bottom: 20px;
206
+ z-index: 2147483000;
207
+ }
208
+ .nostr-chat-launcher .bar-btn {
209
+ padding: 12px 20px;
210
+ border-radius: 999px;
211
+ background: var(--nstrc-chat-accent-color);
212
+ color: var(--nstrc-chat-accent-text-color);
213
+ border: none;
214
+ cursor: pointer;
215
+ font-weight: 700;
216
+ box-shadow: 0 6px 20px rgba(0,0,0,0.18);
217
+ }
218
+
219
+ .nostr-chat-container {
220
+ display: flex;
221
+ flex-direction: column;
222
+ font-family: Inter, sans-serif;
223
+ width: 100%;
224
+ height: 100%;
225
+ max-width: 400px;
226
+ max-height: 600px;
227
+ box-sizing: border-box;
228
+ border-radius: var(--nstrc-chat-border-radius);
229
+ border: var(--nstrc-chat-border);
230
+ background-color: var(--nstrc-chat-background);
231
+ color: var(--nstrc-chat-text-color);
232
+ overflow: hidden;
233
+ }
234
+
235
+ .nostr-chat-header {
236
+ padding: 12px 16px;
237
+ border-bottom: var(--nstrc-chat-border);
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: space-between;
241
+ flex-shrink: 0;
242
+ }
243
+
244
+ .nostr-chat-header-right {
245
+ display: flex;
246
+ align-items: center;
247
+ gap: 12px;
248
+ }
249
+
250
+ .nostr-chat-recipient, .nostr-chat-recipient-placeholder {
251
+ display: flex;
252
+ align-items: center; /* Ensures vertical centering */
253
+ gap: 12px;
254
+ }
255
+
256
+ .nostr-chat-recipient-avatar {
257
+ width: 36px;
258
+ height: 36px;
259
+ border-radius: 50%;
260
+ object-fit: cover;
261
+ }
262
+
263
+ .nostr-chat-recipient-info {
264
+ display: flex;
265
+ align-items: center;
266
+ gap: 8px;
267
+ }
268
+
269
+ .nostr-chat-recipient-name {
270
+ font-weight: 600;
271
+ font-size: 16px;
272
+ display: flex;
273
+ align-items: center;
274
+ height: 36px; /* Match avatar height */
275
+ }
276
+
277
+ .nostr-chat-self {
278
+ display: flex;
279
+ align-items: center;
280
+ gap: 8px;
281
+ opacity: 0.85;
282
+ font-size: 12px;
283
+ }
284
+ .nostr-chat-self-avatar {
285
+ width: 24px;
286
+ height: 24px;
287
+ border-radius: 50%;
288
+ object-fit: cover;
289
+ }
290
+
291
+ .nostr-chat-content {
292
+ padding: 16px;
293
+ display: flex;
294
+ flex-direction: column;
295
+ gap: 12px;
296
+ flex-grow: 1;
297
+ overflow-y: auto;
298
+ }
299
+
300
+ /* Scrollbar styling for dark theme */
301
+ .nostr-chat-content::-webkit-scrollbar,
302
+ .nostr-chat-history::-webkit-scrollbar {
303
+ width: 8px;
304
+ }
305
+ .nostr-chat-content::-webkit-scrollbar-track,
306
+ .nostr-chat-history::-webkit-scrollbar-track {
307
+ background: transparent;
308
+ }
309
+ .nostr-chat-content::-webkit-scrollbar-thumb,
310
+ .nostr-chat-history::-webkit-scrollbar-thumb {
311
+ background: rgba(255, 255, 255, 0.2);
312
+ border-radius: 4px;
313
+ }
314
+ .nostr-chat-content::-webkit-scrollbar-thumb:hover,
315
+ .nostr-chat-history::-webkit-scrollbar-thumb:hover {
316
+ background: rgba(255, 255, 255, 0.3);
317
+ }
318
+
319
+ .nostr-chat-history {
320
+ display: flex;
321
+ flex-direction: column;
322
+ gap: 10px;
323
+ flex-grow: 1;
324
+ overflow-y: auto;
325
+ padding-right: 10px; /* For scrollbar */
326
+ padding-bottom: 16px;
327
+ }
328
+
329
+ .nostr-chat-message-row {
330
+ display: flex;
331
+ width: 100%;
332
+ flex-direction: column;
333
+ align-items: flex-start;
334
+ }
335
+
336
+ .nostr-chat-message-me {
337
+ justify-content: flex-end;
338
+ align-items: flex-end;
339
+ }
340
+
341
+ .nostr-chat-message-them {
342
+ justify-content: flex-start;
343
+ align-items: flex-start;
344
+ }
345
+
346
+ .nostr-chat-message-bubble {
347
+ padding: 8px 12px;
348
+ border-radius: 18px;
349
+ max-width: 75%;
350
+ word-wrap: break-word;
351
+ }
352
+
353
+ .nostr-chat-message-me .nostr-chat-message-bubble {
354
+ background-color: var(--nstrc-chat-accent-color);
355
+ color: var(--nstrc-chat-accent-text-color);
356
+ border-radius: 15px 15px 0 15px;
357
+ opacity: 1;
358
+ }
359
+
360
+ .nostr-chat-message-me.sending .nostr-chat-message-bubble {
361
+ opacity: 0.5;
362
+ }
363
+
364
+ .nostr-chat-message-me.failed .nostr-chat-message-bubble {
365
+ opacity: 1;
366
+ border: 1px dashed var(--nstrc-chat-error-color);
367
+ }
368
+
369
+ .nostr-chat-message-them .nostr-chat-message-bubble {
370
+ background-color: var(--nstrc-chat-their-message-background);
371
+ border-bottom-left-radius: 4px;
372
+ }
373
+
374
+ /* Message timestamp under bubble, always visible but with opacity change on hover */
375
+ .nostr-chat-message-meta {
376
+ font-size: 10px;
377
+ margin-top: 4px;
378
+ opacity: 0.5;
379
+ color: var(--nstrc-chat-text-color);
380
+ max-width: 75%;
381
+ transition: opacity 0.2s ease;
382
+ height: 14px; /* Fixed height to prevent layout jumps */
383
+ }
384
+ .nostr-chat-message-row:hover .nostr-chat-message-meta {
385
+ opacity: 0.9;
386
+ }
387
+ .nostr-chat-message-me .nostr-chat-message-meta {
388
+ text-align: right;
389
+ }
390
+ .nostr-chat-message-them .nostr-chat-message-meta {
391
+ text-align: left;
392
+ }
393
+
394
+ /* Slightly highlight timestamp for the last message */
395
+ .nostr-chat-history > .nostr-chat-message-row:last-of-type .nostr-chat-message-meta {
396
+ opacity: 0.75;
397
+ }
398
+
399
+ .nostr-chat-npub-input-container {
400
+ display: flex;
401
+ gap: 8px;
402
+ align-items: center;
403
+ padding: 20px 0;
404
+ }
405
+
406
+ .nostr-chat-npub-input {
407
+ flex: 1;
408
+ padding: 10px;
409
+ box-sizing: border-box;
410
+ border-radius: 4px;
411
+ border: var(--nstrc-chat-border);
412
+ background-color: var(--nstrc-chat-input-background);
413
+ color: var(--nstrc-chat-text-color);
414
+ }
415
+
416
+ .nostr-chat-actions {
417
+ display: flex;
418
+ gap: 8px;
419
+ flex-shrink: 0;
420
+ border-top: var(--nstrc-chat-border);
421
+ padding-top: 12px;
422
+ }
423
+
424
+ .nostr-chat-welcome {
425
+ display: flex;
426
+ flex-direction: column;
427
+ gap: 12px;
428
+ align-items: center;
429
+ justify-content: center;
430
+ text-align: center;
431
+ padding: 12px 8px;
432
+ }
433
+ .nostr-chat-welcome-text {
434
+ opacity: 0.9;
435
+ }
436
+ .nostr-chat-start-btn {
437
+ padding: 10px 16px;
438
+ border-radius: 20px;
439
+ border: none;
440
+ background-color: var(--nstrc-chat-button-background);
441
+ color: var(--nstrc-chat-button-text);
442
+ cursor: pointer;
443
+ display: inline-flex;
444
+ align-items: center;
445
+ justify-content: center;
446
+ font-weight: 600;
447
+ }
448
+
449
+ .nostr-chat-textarea {
450
+ flex-grow: 1;
451
+ height: 40px;
452
+ box-sizing: border-box;
453
+ padding: 10px;
454
+ border-radius: 20px;
455
+ border: var(--nstrc-chat-border);
456
+ background-color: var(--nstrc-chat-input-background);
457
+ color: var(--nstrc-chat-text-color);
458
+ font-family: Inter, sans-serif;
459
+ resize: none;
460
+ overflow-y: auto;
461
+ }
462
+
463
+ /* Character counter */
464
+ .nostr-chat-char-counter {
465
+ align-self: center;
466
+ font-size: 12px;
467
+ opacity: 0.75;
468
+ color: var(--nstrc-chat-text-color);
469
+ white-space: nowrap;
470
+ min-width: max-content;
471
+ }
472
+ .nostr-chat-char-counter.warn {
473
+ color: #ff8c00; /* Brighter orange color for warning */
474
+ opacity: 1;
475
+ font-weight: 700;
476
+ }
477
+
478
+ .nostr-chat-find-btn, .nostr-chat-send-btn {
479
+ padding: 10px 16px;
480
+ border-radius: 20px;
481
+ border: none;
482
+ background-color: var(--nstrc-chat-button-background);
483
+ color: var(--nstrc-chat-button-text);
484
+ cursor: pointer;
485
+ display: flex;
486
+ align-items: center;
487
+ justify-content: center;
488
+ font-weight: 600;
489
+ }
490
+
491
+ .nostr-chat-error-message {
492
+ color: var(--nstrc-chat-error-color);
493
+ font-size: 14px;
494
+ padding: 0 16px 16px;
495
+ text-align: center;
496
+ }
497
+ </style>
498
+ `}const x=class x extends HTMLElement{constructor(){super();a(this,"rendered",!1);a(this,"nostrService",A.getInstance());a(this,"dmSubscription",null);a(this,"theme","light");a(this,"recipientNpub",null);a(this,"recipientNip05",null);a(this,"recipientName",null);a(this,"recipientPicture",null);a(this,"recipientPubkey",null);a(this,"message","");a(this,"messages",[]);a(this,"currentUserPubkey",null);a(this,"currentUserNpub",null);a(this,"currentUserName",null);a(this,"currentUserPicture",null);a(this,"displayType","embed");a(this,"isOpen",!1);a(this,"showWelcome",!1);a(this,"welcomeText",x.DEFAULT_WELCOME_TEXT);a(this,"startChatText",x.DEFAULT_START_CHAT_TEXT);a(this,"onlineText",x.DEFAULT_ONLINE_TEXT);a(this,"helpText",x.DEFAULT_HELP_TEXT);a(this,"MESSAGE_MAX_LENGTH",1e3);a(this,"isLoading",!1);a(this,"isFinding",!1);a(this,"isError",!1);a(this,"errorMessage","");a(this,"keySupplier",null);a(this,"boundHandleFind",null);a(this,"boundHandleSend",null);a(this,"boundHandleTextareaChange",null);a(this,"boundHandleLauncherClick",null);a(this,"boundHandleCloseClick",null);a(this,"boundHandleStartChat",null);a(this,"boundHandleNpubKeydown",null);a(this,"resubscribeTimer",null);a(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(r=>r.trim()).filter(r=>r.length>0).filter((r,e,o)=>o.indexOf(r)===e):D});a(this,"getTheme",()=>{const t=this.getAttribute("theme"),r=(t||"").toLowerCase();r==="light"||r==="dark"?this.theme=r:(t&&console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'. Falling back to 'light'.`),this.theme="light")});a(this,"getRecipient",()=>{const t=this.getAttribute("pubkey");if(t)try{this.recipientPubkey=t,this.recipientNpub=v.npubEncode(t),this.lookupRecipient(this.recipientNpub);return}catch(o){const s=`Invalid recipient pubkey "${t}": ${o instanceof Error?o.message:String(o)}`;this.isError=!0,this.errorMessage=s,console.error("nostr-live-chat:",s,o),this.render();return}const r=this.getAttribute("nip05");if(r){this.recipientNip05=r,this.lookupRecipientByNip05();return}const e=this.getAttribute("npub");e&&(this.recipientNpub=e,this.lookupRecipient())});this.attachShadow({mode:"open"})}async getCurrentUserInfo(){var t,r,e,o,s,l,p,i,d,b;try{const k=this.nostrService.getNDK();let u=null;if(typeof window<"u"&&window.nostr){const n=window.nostr;console.log("Nostr extension found, checking for public key...");try{const g=!!(n.enable&&typeof n.enable=="function"&&n.getPublicKey&&typeof n.getPublicKey=="function");if(console.log("Is this nos2x extension?",g),g){console.log("Using nos2x specific flow");try{await n.enable(),console.log("nos2x extension enabled"),await new Promise(m=>setTimeout(m,100));const c=await n.getPublicKey();console.log("nos2x returned pubkey:",c),c&&typeof c=="string"&&c.length===64&&(u=c,console.log("Successfully got pubkey from nos2x:",u))}catch(c){console.error("Error with nos2x extension:",c)}}else{if(typeof n.enable=="function"){console.log("Attempting to enable generic extension...");try{await n.enable(),console.log("Extension enabled successfully")}catch(c){console.warn("Extension enable failed, continuing anyway:",c)}}if(typeof n.getPublicKey=="function"){console.log("Calling getPublicKey()...");try{u=await n.getPublicKey(),console.log("Got pubkey from extension:",u)}catch(c){console.error("Error getting public key:",c)}}else if(n.getPublicKey){console.log("Found getPublicKey property, resolving...");try{u=await Promise.resolve(n.getPublicKey),console.log("Got pubkey from extension (property):",u)}catch(c){console.error("Error resolving public key:",c)}}}}catch(g){console.error("Error in extension interaction:",g)}}if(!u){let n=null;if(this.keySupplier)try{n=await this.keySupplier()}catch{}if(n)try{const{NDKPrivateKeySigner:g}=await L(async()=>{const{NDKPrivateKeySigner:E}=await import("../assets/nostr-service-pr_crY62.js").then(T=>T.k);return{NDKPrivateKeySigner:E}},[]);let c=n;n.startsWith("nsec")&&(c=v.decode(n).data),u=(await new g(c).user()).pubkey}catch{}}if(u){this.currentUserPubkey=u,this.currentUserNpub=v.npubEncode(u),console.log("Got pubkey from extension and will use it:",u);try{const n=k.getUser({pubkey:u});console.log("Fetching profile for user:",u),await n.fetchProfile(),console.log("Fetched profile:",n.profile),this.currentUserName=((t=n.profile)==null?void 0:t.displayName)||((r=n.profile)==null?void 0:r.name)||((e=this.currentUserNpub)==null?void 0:e.substring(0,10))||null,this.currentUserPicture=((o=n.profile)==null?void 0:o.image)||null,this.currentUserName||console.warn("No username found in profile"),this.currentUserPicture||console.warn("No profile picture found"),console.log("Profile info set:",{name:this.currentUserName,picture:this.currentUserPicture,npub:this.currentUserNpub})}catch(n){console.error("Error fetching profile:",n),this.currentUserName=((s=this.currentUserNpub)==null?void 0:s.substring(0,10))||null}this.render()}else{console.log("Checking for direct nos2x logs in console...");try{if(await new Promise(n=>setTimeout(n,500)),typeof window<"u"&&window.nostr){console.log("Trying direct call to extension again...");try{const n=await window.nostr.getPublicKey();if(n&&typeof n=="string"){console.log("Got pubkey on second try:",n),this.currentUserPubkey=n,this.currentUserNpub=v.npubEncode(n);try{const g=k.getUser({pubkey:n});console.log("Fetching profile for user on second try:",n),await g.fetchProfile(),console.log("Fetched profile on second try:",g.profile),this.currentUserName=((l=g.profile)==null?void 0:l.displayName)||((p=g.profile)==null?void 0:p.name)||((i=this.currentUserNpub)==null?void 0:i.substring(0,10))||null,this.currentUserPicture=((d=g.profile)==null?void 0:d.image)||null,this.render();return}catch(g){console.error("Error fetching profile on second try:",g),this.currentUserName=((b=this.currentUserNpub)==null?void 0:b.substring(0,10))||null,this.render();return}}}catch(n){console.error("Error getting pubkey on direct second try:",n)}}}catch(n){console.error("Error in fallback pubkey detection:",n)}console.warn("No pubkey available from extension - trying fallback method")}}catch{}}getDisplayType(){const t=this.getAttribute("display-type"),r=["fab","bottom-bar","full","embed"],o=(t?String(t):"").toLowerCase(),s=r.includes(o)?o:"embed";this.displayType=s,this.displayType==="full"?this.isOpen=!0:this.displayType==="fab"||this.displayType==="bottom-bar"?(this.isOpen===void 0||this.isOpen===null)&&(this.isOpen=!1):this.isOpen=!1,this.getAttribute("display-type")!==s&&this.setAttribute("display-type",s)}connectedCallback(){if(!this.rendered){this.getTheme(),this.getDisplayType();const t=this.getAttribute("welcome-text");t&&(this.welcomeText=t);const r=this.getAttribute("start-chat-text");r&&(this.startChatText=r);const e=this.getAttribute("online-text");e&&(this.onlineText=e);const o=this.getAttribute("help-text");o&&(this.helpText=o),this.getRecipient(),this.nostrService.connectToNostr(this.getRelays()),this.getCurrentUserInfo(),this.render(),this.rendered=!0}}static get observedAttributes(){return["npub","pubkey","nip05","relays","theme","display-type","welcome-text","start-chat-text","online-text","help-text","history-days"]}unsubscribeFromDms(){if(this.dmSubscription){try{this.dmSubscription.stop()}catch{}this.dmSubscription=null}this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}clearRecipientAndChatState(){this.recipientPubkey=null,this.recipientNpub=null,this.recipientNip05=null,this.recipientName=null,this.recipientPicture=null,this.messages=[],this.message="",this.showWelcome=!1,this.isLoading=!1,this.isFinding=!1,this.isError=!1,this.errorMessage=""}attributeChangedCallback(t,r,e){if(this.rendered)if(t==="npub"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNpub=e,this.lookupRecipient());return}else if(t==="pubkey"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}if(e!==r){this.unsubscribeFromDms(),this.clearRecipientAndChatState();try{this.recipientPubkey=e,this.recipientNpub=v.npubEncode(e),this.lookupRecipient(this.recipientNpub)}catch{}}return}else if(t==="nip05"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNip05=e,this.lookupRecipientByNip05());return}else if(t==="relays"){if(e!==r){const o=this.getRelays();this.recipientPubkey&&!this.showWelcome?(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.unsubscribeFromDms(),this.nostrService.connectToNostr(o),this.subscribeToDms()},300)):this.nostrService.connectToNostr(o)}}else t==="theme"?(this.getTheme(),this.render()):t==="display-type"?(this.getDisplayType(),this.render()):t==="welcome-text"?(this.welcomeText=e!==null?e:x.DEFAULT_WELCOME_TEXT,this.render()):t==="start-chat-text"?(this.startChatText=e!==null?e:x.DEFAULT_START_CHAT_TEXT,this.render()):t==="online-text"?(this.onlineText=e!==null?e:x.DEFAULT_ONLINE_TEXT,this.render()):t==="help-text"?(this.helpText=e!==null?e:x.DEFAULT_HELP_TEXT,this.render()):t==="history-days"&&e!==r&&this.recipientPubkey&&!this.showWelcome&&(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.subscribeToDms()},250))}async lookupRecipient(t){var r,e,o;this.unsubscribeFromDms(),this.messages=[],this.showWelcome=!1,this.isFinding=!0,this.render();try{const s=t||this.recipientNpub;if(!s)return;const{type:l,data:p}=v.decode(s);if(l!=="npub")throw new Error("Invalid npub");this.recipientPubkey=p;const i=this.nostrService.getNDK().getUser({pubkey:this.recipientPubkey});await i.fetchProfile(),this.recipientName=((r=i.profile)==null?void 0:r.displayName)||((e=i.profile)==null?void 0:e.name)||s.substring(0,10),this.recipientPicture=((o=i.profile)==null?void 0:o.image)||null,this.showWelcome=!0,this.messages=[],this.isError=!1,this.errorMessage="",this.render()}catch(s){this.isError=!0,this.errorMessage=s.message}finally{this.isFinding=!1,this.render()}}async lookupRecipientByNip05(t){this.isFinding=!0,this.render();try{const r=t||this.recipientNip05;if(!r)return;const e=await U(r),o=v.npubEncode(e);this.recipientNpub=o,this.isError=!1,this.errorMessage="",await this.lookupRecipient(o)}catch(r){this.isError=!0,this.errorMessage=r.message}finally{this.isFinding=!1,this.render()}}handleFindClick(){const r=this.shadowRoot.querySelector(".nostr-chat-npub-input").value.trim();this.isError=!1,this.errorMessage="",this.render(),r&&(r.startsWith("npub")?(this.recipientNpub=r,this.lookupRecipient()):r.includes("@")?(this.recipientNip05=r,this.lookupRecipientByNip05()):(this.isError=!0,this.errorMessage="Invalid input. Please provide an npub or nip05 address.",this.render()))}async handleSendClick(){var r,e;if(!this.message.trim()||!this.recipientPubkey)return;if(this.message.length>this.MESSAGE_MAX_LENGTH){this.isError=!0,this.errorMessage=`Message is too long (max ${this.MESSAGE_MAX_LENGTH} characters).`,this.render();return}this.isLoading=!0,this.render();let t=null;try{const o=this.nostrService.getNDK();let s;if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey&&window.nostr.signEvent)try{s=new $}catch(d){console.error("Error creating NIP-07 signer:",d),this.isError=!0,this.errorMessage=`Error connecting to Nostr extension: ${d.message}`,this.isLoading=!1,this.render();return}if(!s)throw new Error("No signer available. Please install a NIP-07 extension or set a private key.");o.signer=s;const l=new M(o,{kind:S.EncryptedDirectMessage,tags:[["p",this.recipientPubkey]],created_at:Math.floor(Date.now()/1e3)});let p=!1;if(typeof((e=(r=window.nostr)==null?void 0:r.nip04)==null?void 0:e.encrypt)=="function")try{l.content=await window.nostr.nip04.encrypt(this.recipientPubkey,this.message.trim()),p=!0}catch(d){console.error("NIP-07 encryption failed, falling back to local encryption:",d)}if(!p)throw new Error("No private key available for encryption. Please use a NIP-07 extension.");t=`temp_${Date.now()}`,this.messages.push({id:t,text:this.message,sender:"me",timestamp:l.created_at,status:"sending"}),this.message="",this.render(),await l.publish();const i=this.messages.find(d=>d.id===t);i&&(this.messages.find(b=>b.id===l.id&&b.id!==t)?this.messages=this.messages.filter(b=>b.id!==t):(i.id=l.id,i.status="sent"),this.render())}catch(o){if(this.isError=!0,this.errorMessage=o.message,t){const s=this.messages.find(l=>l.id===t);s&&(s.status="failed"),this.render()}}finally{this.isLoading=!1,this.render()}}handleTextareaChange(t){var s;const r=t.target;this.message=r.value;const e=Math.max(0,this.MESSAGE_MAX_LENGTH-this.message.length),o=(s=this.shadowRoot)==null?void 0:s.querySelector(".nostr-chat-char-counter");o&&(o.textContent=`${e} chars left`,o.classList.toggle("warn",e<=10))}handleStartChat(){this.showWelcome=!1,this.subscribeToDms(),this.render()}async subscribeToDms(){if(this.dmSubscription&&this.dmSubscription.stop(),!this.recipientPubkey)return;let t=null;try{if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey)t={pubkey:await window.nostr.getPublicKey()};else{let i=null;if(this.keySupplier)try{i=await this.keySupplier()}catch{}if(i){const{NDKPrivateKeySigner:d}=await L(async()=>{const{NDKPrivateKeySigner:u}=await import("../assets/nostr-service-pr_crY62.js").then(n=>n.k);return{NDKPrivateKeySigner:u}},[]);let b=i;i.startsWith("nsec")&&(b=v.decode(i).data),t=await new d(b).user()}}}catch(i){console.error("Failed to determine current user for subscription",i)}if(!t){this.isError=!0,this.errorMessage="No signer available. Please install a NIP-07 extension or set a private key to start the chat.",this.render();return}this.messages=[];const r=this.getAttribute("history-days");let e;if(!r)e=void 0;else if(r.toLowerCase()==="all"||parseInt(r,10)<=0)e=void 0;else{const i=Math.max(1,parseInt(r,10)||30);e=Math.floor((Date.now()-i*24*60*60*1e3)/1e3)}const o={kinds:[S.EncryptedDirectMessage],"#p":[t.pubkey],authors:[this.recipientPubkey]},s={kinds:[S.EncryptedDirectMessage],"#p":[this.recipientPubkey],authors:[t.pubkey]},l=e!==void 0?{...o,since:e}:o,p=e!==void 0?{...s,since:e}:s;this.dmSubscription=this.nostrService.getNDK().subscribe([l,p],{closeOnEose:!1,groupable:!1}),this.dmSubscription.on("event",async i=>{var d;try{!this.currentUserPubkey&&t&&(this.currentUserPubkey=t.pubkey,this.currentUserNpub=v.npubEncode(t.pubkey));const b=i.pubkey===t.pubkey,k=b?(d=i.tags.find(c=>c[0]==="p"))==null?void 0:d[1]:i.pubkey;if(!k){try{console.debug("nostr-live-chat: skipping event with missing peer",i.id)}catch{}return}if(k!==this.recipientPubkey)return;if(b){const c=this.messages.find(m=>m.id===i.id);if(c){c.status==="sending"&&(c.status="sent",this.render());return}}let u="";if(!k){try{console.debug("nostr-live-chat: missing peer prior to decrypt, skipping",i.id)}catch{}return}if(!i.content||i.content.trim()===""){try{console.debug("nostr-live-chat: missing or empty content prior to decrypt, skipping",i.id)}catch{}return}if(window.nostr&&window.nostr.nip04&&typeof window.nostr.nip04.decrypt=="function")try{u=await window.nostr.nip04.decrypt(k,i.content)}catch(c){console.error("Failed to decrypt DM content:",c);return}else throw new Error("No private key available for decryption. Please use a NIP-07 extension.");if(b){const c=this.messages.find(m=>m.status==="sending"&&m.sender==="me"&&m.text===u&&Math.abs(m.timestamp-i.created_at)<2);if(c){c.id=i.id,c.status="sent",this.render();return}}const n={id:i.id,text:u,sender:b?"me":"them",timestamp:i.created_at,status:"sent"};this.messages.find(c=>c.id===n.id)||(this.messages.push(n),this.messages.sort((c,m)=>c.timestamp-m.timestamp),this.render())}catch(b){console.error("Failed to decrypt DM content:",b)}})}attachEventListeners(){const t=this.shadowRoot.querySelector(".nostr-chat-launcher");t&&(this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick),this.boundHandleLauncherClick=()=>{this.isOpen=!0,this.render()},t.addEventListener("click",this.boundHandleLauncherClick));const r=this.shadowRoot.querySelector(".nostr-chat-close-btn");r&&(this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick),this.boundHandleCloseClick=i=>{i==null||i.stopPropagation(),(this.displayType==="fab"||this.displayType==="bottom-bar")&&(this.isOpen=!1),this.render()},r.addEventListener("click",this.boundHandleCloseClick));const e=this.shadowRoot.querySelector(".nostr-chat-find-btn");e&&(this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind),this.boundHandleFind=this.handleFindClick.bind(this),e.addEventListener("click",this.boundHandleFind));const o=this.shadowRoot.querySelector(".nostr-chat-send-btn");o&&(this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend),this.boundHandleSend=this.handleSendClick.bind(this),o.addEventListener("click",this.boundHandleSend));const s=this.shadowRoot.querySelector(".nostr-chat-start-btn");s&&(this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat),this.boundHandleStartChat=this.handleStartChat.bind(this),s.addEventListener("click",this.boundHandleStartChat));const l=this.shadowRoot.querySelector(".nostr-chat-textarea");l&&(this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange),this.boundHandleTextareaChange=this.handleTextareaChange.bind(this),l.addEventListener("input",this.boundHandleTextareaChange));const p=this.shadowRoot.querySelector(".nostr-chat-npub-input");p&&(this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.boundHandleNpubKeydown=i=>{i.key==="Enter"&&this.handleFindClick()},p.addEventListener("keydown",this.boundHandleNpubKeydown))}disconnectedCallback(){var i,d,b,k,u,n,g;this.dmSubscription&&this.dmSubscription.stop();const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".nostr-chat-launcher");t&&this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick);const r=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-close-btn");r&&this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick);const e=(b=this.shadowRoot)==null?void 0:b.querySelector(".nostr-chat-find-btn");e&&this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind);const o=(k=this.shadowRoot)==null?void 0:k.querySelector(".nostr-chat-send-btn");o&&this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend);const s=(u=this.shadowRoot)==null?void 0:u.querySelector(".nostr-chat-start-btn");s&&this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat);const l=(n=this.shadowRoot)==null?void 0:n.querySelector(".nostr-chat-textarea");l&&this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange);const p=(g=this.shadowRoot)==null?void 0:g.querySelector(".nostr-chat-npub-input");p&&this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}setKeySupplier(t){this.keySupplier=t}escapeHtml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){const t={theme:this.theme,recipientNpub:this.recipientNpub,recipientName:this.recipientName,recipientPicture:this.recipientPicture,message:this.message,messages:this.messages,isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,errorMessage:this.errorMessage,currentUserName:this.currentUserName,currentUserPicture:this.currentUserPicture,showWelcome:this.showWelcome,welcomeText:this.welcomeText,startChatText:this.startChatText,onlineText:this.onlineText,helpText:this.helpText,maxMessageLength:this.MESSAGE_MAX_LENGTH},r=z(this.theme),{onlineText:e,helpText:o,...s}=t,l=O(s);let p=r;this.displayType==="embed"?p+=l:this.displayType==="full"?p+=`
499
+ <div class="nostr-chat-float-panel open">${l}</div>
500
+ `:this.displayType==="fab"?p+=`
501
+ ${this.isOpen?"":`
502
+ <div class="nostr-chat-launcher fab" role="button" aria-label="Open live chat">
503
+ <div class="bubble">
504
+ <div class="title">${this.escapeHtml(this.onlineText)}</div>
505
+ <div class="subtitle">${this.escapeHtml(this.helpText)}</div>
506
+ </div>
507
+ <button class="fab-btn" aria-label="Open chat">💬</button>
508
+ </div>
509
+ `}
510
+ <div class="nostr-chat-float-panel ${this.isOpen?"open":""}">
511
+ ${l}
512
+ </div>
513
+ `:this.displayType==="bottom-bar"&&(p+=`
514
+ ${this.isOpen?"":`
515
+ <div class="nostr-chat-launcher bottom-bar" role="button" aria-label="Open live chat">
516
+ <button class="bar-btn">Live chat</button>
517
+ </div>
518
+ `}
519
+ <div class="nostr-chat-float-panel ${this.isOpen?"open":""}">
520
+ ${l}
521
+ </div>
522
+ `),this.shadowRoot.innerHTML=p,this.attachEventListeners(),setTimeout(()=>{var d;const i=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-history");i&&(i.scrollTop=i.scrollHeight)},0)}};a(x,"DEFAULT_WELCOME_TEXT","Welcome! How can we help you today?"),a(x,"DEFAULT_START_CHAT_TEXT","Start chat"),a(x,"DEFAULT_ONLINE_TEXT","We're Online!"),a(x,"DEFAULT_HELP_TEXT","How may I help you today?");let F=x;customElements.define("nostr-live-chat",F);
523
+ //# sourceMappingURL=nostr-live-chat.es.js.map