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.
- package/LICENSE +21 -0
- package/README.md +334 -0
- package/dist/assets/base-styles-CBypR3FR.js +145 -0
- package/dist/assets/base-styles-CBypR3FR.js.map +1 -0
- package/dist/assets/copy-delegation-C4uvRTVM.js +15 -0
- package/dist/assets/copy-delegation-C4uvRTVM.js.map +1 -0
- package/dist/assets/dialog-component-Dqg0QU9I.js +66 -0
- package/dist/assets/dialog-component-Dqg0QU9I.js.map +1 -0
- package/dist/assets/dialog-likers-BzTesCZa.js +238 -0
- package/dist/assets/dialog-likers-BzTesCZa.js.map +1 -0
- package/dist/assets/icons-Dr_d9MII.js +105 -0
- package/dist/assets/icons-Dr_d9MII.js.map +1 -0
- package/dist/assets/nip05-utils-BNBHUmkr.js +2 -0
- package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -0
- package/dist/assets/nostr-service-pr_crY62.js +78 -0
- package/dist/assets/nostr-service-pr_crY62.js.map +1 -0
- package/dist/assets/nostr-user-component-Q7GeeFyu.js +2 -0
- package/dist/assets/nostr-user-component-Q7GeeFyu.js.map +1 -0
- package/dist/assets/preload-helper-D7HrI6pR.js +2 -0
- package/dist/assets/preload-helper-D7HrI6pR.js.map +1 -0
- package/dist/assets/pure-jrVhRVpB.js +2 -0
- package/dist/assets/pure-jrVhRVpB.js.map +1 -0
- package/dist/assets/theme-C1r1Zw8r.js +2 -0
- package/dist/assets/theme-C1r1Zw8r.js.map +1 -0
- package/dist/assets/user-resolver-C-E6KdwY.js +2 -0
- package/dist/assets/user-resolver-C-E6KdwY.js.map +1 -0
- package/dist/assets/utils--bxLbhGF.js +2 -0
- package/dist/assets/utils--bxLbhGF.js.map +1 -0
- package/dist/assets/zap-utils-B1sz0Abx.js +2 -0
- package/dist/assets/zap-utils-B1sz0Abx.js.map +1 -0
- package/dist/components/nostr-comment.es.js +924 -0
- package/dist/components/nostr-comment.es.js.map +1 -0
- package/dist/components/nostr-dm.es.js +217 -0
- package/dist/components/nostr-dm.es.js.map +1 -0
- package/dist/components/nostr-follow-button.es.js +103 -0
- package/dist/components/nostr-follow-button.es.js.map +1 -0
- package/dist/components/nostr-like.es.js +296 -0
- package/dist/components/nostr-like.es.js.map +1 -0
- package/dist/components/nostr-live-chat.es.js +523 -0
- package/dist/components/nostr-live-chat.es.js.map +1 -0
- package/dist/components/nostr-post.es.js +441 -0
- package/dist/components/nostr-post.es.js.map +1 -0
- package/dist/components/nostr-profile-badge.es.js +100 -0
- package/dist/components/nostr-profile-badge.es.js.map +1 -0
- package/dist/components/nostr-profile.es.js +287 -0
- package/dist/components/nostr-profile.es.js.map +1 -0
- package/dist/components/nostr-zap.es.js +694 -0
- package/dist/components/nostr-zap.es.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/nostr-comment.d.ts +4 -0
- package/dist/nostr-components.es.js +2 -0
- package/dist/nostr-components.es.js.map +1 -0
- package/dist/nostr-components.umd.js +4200 -0
- package/dist/nostr-components.umd.js.map +1 -0
- package/dist/nostr-dm.d.ts +4 -0
- package/dist/nostr-follow-button.d.ts +4 -0
- package/dist/nostr-like.d.ts +4 -0
- package/dist/nostr-live-chat.d.ts +4 -0
- package/dist/nostr-post.d.ts +4 -0
- package/dist/nostr-profile-badge.d.ts +4 -0
- package/dist/nostr-profile.d.ts +4 -0
- package/dist/nostr-zap.d.ts +4 -0
- package/dist/src/base/base-component/nostr-base-component.d.ts +116 -0
- package/dist/src/base/copy-delegation.d.ts +5 -0
- package/dist/src/base/dialog-component/dialog-component.d.ts +67 -0
- package/dist/src/base/dialog-component/style.d.ts +5 -0
- package/dist/src/base/event-component/nostr-event-component.d.ts +53 -0
- package/dist/src/base/render-options.d.ts +5 -0
- package/dist/src/base/resolvers/event-resolver.d.ts +20 -0
- package/dist/src/base/resolvers/user-resolver.d.ts +19 -0
- package/dist/src/base/text-row/render-name.d.ts +7 -0
- package/dist/src/base/text-row/render-nip05.d.ts +1 -0
- package/dist/src/base/text-row/render-npub.d.ts +1 -0
- package/dist/src/base/text-row/render-text-row.d.ts +9 -0
- package/dist/src/base/user-component/nostr-user-component.d.ts +43 -0
- package/dist/src/common/base-styles.d.ts +44 -0
- package/dist/src/common/constants.d.ts +4 -0
- package/dist/src/common/date-utils.d.ts +9 -0
- package/dist/src/common/icons.d.ts +7 -0
- package/dist/src/common/nip05-utils.d.ts +13 -0
- package/dist/src/common/nostr-service.d.ts +40 -0
- package/dist/src/common/theme.d.ts +4 -0
- package/dist/src/common/types.d.ts +1 -0
- package/dist/src/common/utils.d.ts +34 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/nostr-comment/nostr-comment.d.ts +60 -0
- package/dist/src/nostr-comment/render.d.ts +15 -0
- package/dist/src/nostr-comment/utils.d.ts +81 -0
- package/dist/src/nostr-dm/nostr-dm.d.ts +34 -0
- package/dist/src/nostr-dm/render.d.ts +15 -0
- package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +24 -0
- package/dist/src/nostr-follow-button/render.d.ts +11 -0
- package/dist/src/nostr-follow-button/style.d.ts +1 -0
- package/dist/src/nostr-like/dialog-help-style.d.ts +1 -0
- package/dist/src/nostr-like/dialog-help.d.ts +2 -0
- package/dist/src/nostr-like/dialog-likers-style.d.ts +1 -0
- package/dist/src/nostr-like/dialog-likers.d.ts +24 -0
- package/dist/src/nostr-like/like-utils.d.ts +52 -0
- package/dist/src/nostr-like/nostr-like.d.ts +49 -0
- package/dist/src/nostr-like/render.d.ts +10 -0
- package/dist/src/nostr-like/style.d.ts +1 -0
- package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +65 -0
- package/dist/src/nostr-live-chat/render.d.ts +31 -0
- package/dist/src/nostr-post/nostr-post.d.ts +25 -0
- package/dist/src/nostr-post/parse-text.d.ts +8 -0
- package/dist/src/nostr-post/render-content.d.ts +5 -0
- package/dist/src/nostr-post/render.d.ts +19 -0
- package/dist/src/nostr-post/style.d.ts +1 -0
- package/dist/src/nostr-profile/nostr-profile.d.ts +24 -0
- package/dist/src/nostr-profile/render-stats.d.ts +1 -0
- package/dist/src/nostr-profile/render.d.ts +22 -0
- package/dist/src/nostr-profile/style.d.ts +1 -0
- package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +34 -0
- package/dist/src/nostr-profile-badge/render.d.ts +11 -0
- package/dist/src/nostr-profile-badge/style.d.ts +1 -0
- package/dist/src/nostr-zap/dialog-help-style.d.ts +5 -0
- package/dist/src/nostr-zap/dialog-help.d.ts +2 -0
- package/dist/src/nostr-zap/dialog-zap-style.d.ts +6 -0
- package/dist/src/nostr-zap/dialog-zap.d.ts +31 -0
- package/dist/src/nostr-zap/dialog-zappers-style.d.ts +1 -0
- package/dist/src/nostr-zap/dialog-zappers.d.ts +25 -0
- package/dist/src/nostr-zap/nostr-zap.d.ts +45 -0
- package/dist/src/nostr-zap/render.d.ts +9 -0
- package/dist/src/nostr-zap/style.d.ts +1 -0
- package/dist/src/nostr-zap/zap-utils.d.ts +53 -0
- package/dist/themes/dark.css +10 -0
- package/dist/themes/light.css +10 -0
- package/dist/themes.css +52 -0
- package/dist/vite.config.d.ts +2 -0
- package/dist/vite.config.esm.d.ts +2 -0
- package/dist/vite.config.umd.d.ts +2 -0
- package/package.json +95 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import{m as v,e as s,g as m,a as d,p as b}from"../assets/base-styles-CBypR3FR.js";import{N as y}from"../assets/nostr-user-component-Q7GeeFyu.js";import{h as w}from"../assets/nostr-service-pr_crY62.js";import{r as x,a as C,b as E,c as N}from"../assets/copy-delegation-C4uvRTVM.js";import"../assets/user-resolver-C-E6KdwY.js";function A({isLoading:n,isError:r,errorMessage:o,userProfile:e,ndkUser:t,showNpub:a,showFollow:c}){if(n)return L();if(r||e==null)return S(o||"");const i=e.displayName||e.name||v((t==null?void 0:t.npub)||""),p=s(i),f=s(e.picture||w),g=(t==null?void 0:t.npub)||"",h=(e==null?void 0:e.nip05)||"",u=s((t==null?void 0:t.pubkey)||"");return l(`<img src='${f}' alt='Nostr profile image of ${p}' loading="lazy" decoding="async"/>`,`${x({name:i})}
|
|
2
|
+
${e.nip05?C(h):""}
|
|
3
|
+
${a===!0?E(g||""):""}
|
|
4
|
+
${c===!0&&(t!=null&&t.pubkey)?`<nostr-follow-button pubkey="${u}"></nostr-follow-button>`:""}`)}function L(){return l('<div class="skeleton img-skeleton"></div>',`<div class="skeleton" style="width: 120px;"></div>
|
|
5
|
+
<div class="skeleton" style="width: 160px;"></div>`)}function S(n){return l('<div class="error-icon">⚠</div>',s(n))}function l(n,r){return`
|
|
6
|
+
<div class='nostr-profile-badge-container'>
|
|
7
|
+
<div class='nostr-profile-badge-left-container'>
|
|
8
|
+
${n}
|
|
9
|
+
</div>
|
|
10
|
+
<div class='nostr-profile-badge-right-container'>
|
|
11
|
+
${r}
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
`}function $(){return m(`
|
|
15
|
+
/* === PROFILE BADGE SPECIFIC CSS VARIABLES === */
|
|
16
|
+
:host {
|
|
17
|
+
--nostrc-profile-badge-bg: var(--nostrc-theme-bg, #ffffff);
|
|
18
|
+
--nostrc-profile-badge-text-primary: var(--nostrc-theme-text-primary, #333333);
|
|
19
|
+
--nostrc-profile-badge-text-secondary: var(--nostrc-theme-text-secondary, #666666);
|
|
20
|
+
--nostrc-profile-badge-border: var(--nostrc-theme-border, var(--nostrc-color-border));
|
|
21
|
+
--nostrc-profile-badge-font-family: var(--nostrc-font-family-primary);
|
|
22
|
+
--nostrc-profile-badge-font-size: var(--nostrc-font-size-base);
|
|
23
|
+
|
|
24
|
+
/* Hover state variables */
|
|
25
|
+
--nostrc-profile-badge-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));
|
|
26
|
+
--nostrc-profile-badge-hover-color: var(--nostrc-theme-text-primary, #333333);
|
|
27
|
+
--nostrc-profile-badge-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));
|
|
28
|
+
|
|
29
|
+
/* Make the host the visual profile badge surface */
|
|
30
|
+
display: block;
|
|
31
|
+
background: var(--nostrc-profile-badge-bg);
|
|
32
|
+
border: var(--nostrc-border-width) solid var(--nostrc-profile-badge-border);
|
|
33
|
+
border-radius: var(--nostrc-border-radius-md);
|
|
34
|
+
font-family: var(--nostrc-profile-badge-font-family);
|
|
35
|
+
font-size: var(--nostrc-profile-badge-font-size);
|
|
36
|
+
transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* === PROFILE BADGE CONTAINER PATTERN === */
|
|
40
|
+
.nostr-profile-badge-container {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: var(--nostrc-spacing-md);
|
|
43
|
+
padding: var(--nostrc-spacing-md);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Hover state */
|
|
47
|
+
:host(.is-clickable:hover) {
|
|
48
|
+
background: var(--nostrc-profile-badge-hover-bg);
|
|
49
|
+
color: var(--nostrc-profile-badge-hover-color);
|
|
50
|
+
border: var(--nostrc-profile-badge-hover-border);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:host(.is-error) .nostr-profile-badge-container {
|
|
54
|
+
justify-content: center;
|
|
55
|
+
align-items: center;
|
|
56
|
+
color: var(--nostrc-color-error-text);
|
|
57
|
+
border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.nostr-profile-badge-left-container {
|
|
61
|
+
width: 48px;
|
|
62
|
+
height: 48px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.nostr-profile-badge-left-container img {
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
border-radius: var(--nostrc-border-radius-full);
|
|
69
|
+
object-fit: cover;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.nostr-profile-badge-right-container {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
flex-grow: 1;
|
|
77
|
+
min-width: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Profile badge specific styling using component variables */
|
|
81
|
+
.nostr-profile-badge-container .nostr-profile-name {
|
|
82
|
+
color: var(--nostrc-profile-badge-text-primary);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.nostr-profile-badge-container .text-row {
|
|
86
|
+
color: var(--nostrc-profile-badge-text-secondary);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Skeleton specific styles */
|
|
90
|
+
.img-skeleton {
|
|
91
|
+
width: 48px;
|
|
92
|
+
height: 48px;
|
|
93
|
+
border-radius: var(--nostrc-border-radius-full);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
`)}const I="nc:profile_badge";class D extends y{static get observedAttributes(){return[...super.observedAttributes,"show-npub","show-follow"]}connectedCallback(){var r;(r=super.connectedCallback)==null||r.call(this),this.attachDelegatedListeners(),N({addDelegatedListener:this.addDelegatedListener.bind(this)}),this.render()}attributeChangedCallback(r,o,e){var t;o!==e&&((t=super.attributeChangedCallback)==null||t.call(this,r,o,e),(r==="show-npub"||r==="show-follow")&&this.render())}onStatusChange(r){this.render()}onUserReady(r,o){this.render()}onProfileClick(){var o,e;const r=((o=this.user)==null?void 0:o.npub)||this.getAttribute("npub")||((e=this.profile)==null?void 0:e.nip05)||this.getAttribute("nip05");r&&this.handleNjumpClick(I,this.profile,encodeURIComponent(r))}attachDelegatedListeners(){this.delegateEvent("click",".nostr-profile-badge-container",r=>{r.target.closest(".nc-copy-btn, .nostr-follow-button-container, nostr-follow-button")||this.onProfileClick()})}renderContent(){const r=this.computeOverall(),o=r===d.Loading,e=r===d.Error,t=b(this.getAttribute("show-follow")),a=b(this.getAttribute("show-npub")),c=e?super.renderError(this.errorMessage):"",i={isLoading:o,isError:e,errorMessage:c,userProfile:this.profile,ndkUser:this.user,showNpub:a,showFollow:t};this.shadowRoot.innerHTML=`
|
|
97
|
+
${$()}
|
|
98
|
+
${A(i)}
|
|
99
|
+
`}}customElements.define("nostr-profile-badge",D);
|
|
100
|
+
//# sourceMappingURL=nostr-profile-badge.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nostr-profile-badge.es.js","sources":["../../src/nostr-profile-badge/render.ts","../../src/nostr-profile-badge/style.ts","../../src/nostr-profile-badge/nostr-profile-badge.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { escapeHtml, maskNPub } from '../common/utils';\nimport { DEFAULT_PROFILE_IMAGE } from '../common/constants';\nimport { renderNpub } from '../base/text-row/render-npub';\nimport { renderNip05 } from '../base/text-row/render-nip05';\nimport { renderName } from '../base/text-row/render-name';\n\nexport interface RenderProfileBadgeOptions {\n isLoading: boolean;\n isError: boolean;\n errorMessage?: string;\n userProfile: NDKUserProfile | null;\n ndkUser: NDKUser | null;\n showNpub: boolean;\n showFollow: boolean;\n}\n\nexport function renderProfileBadge({\n isLoading,\n isError,\n errorMessage,\n userProfile,\n ndkUser,\n showNpub,\n showFollow\n}: RenderProfileBadgeOptions): string {\n\n if (isLoading) {\n return renderLoading();\n }\n\n if (isError || userProfile == null) {\n return renderError(errorMessage || '');\n }\n\n const rawName = userProfile.displayName ||\n userProfile.name ||\n maskNPub(ndkUser?.npub || '')\n const escapedName = escapeHtml(rawName);\n const profileImage = escapeHtml(userProfile.picture || DEFAULT_PROFILE_IMAGE);\n const npub = ndkUser?.npub || '';\n const nip05 = userProfile?.nip05 || '';\n const pubkey = escapeHtml(ndkUser?.pubkey || '');\n\n return renderContainer(\n `<img src='${profileImage}' alt='Nostr profile image of ${escapedName}' loading=\"lazy\" decoding=\"async\"/>`,\n `${renderName({ name: rawName })}\n ${userProfile.nip05 ? renderNip05(nip05) : ''}\n ${showNpub === true ? renderNpub(npub || '') : ''}\n ${showFollow === true && ndkUser?.pubkey ? `<nostr-follow-button pubkey=\"${pubkey}\"></nostr-follow-button>` : ''}`\n );\n}\n\nfunction renderLoading(): string {\n return renderContainer(\n '<div class=\"skeleton img-skeleton\"></div>',\n `<div class=\"skeleton\" style=\"width: 120px;\"></div>\n <div class=\"skeleton\" style=\"width: 160px;\"></div>`\n );\n}\n\nfunction renderError(errorMessage: string): string {\n return renderContainer(\n '<div class=\"error-icon\">⚠</div>',\n escapeHtml(errorMessage)\n );\n}\n\nfunction renderContainer(leftContent: string, rightContent: string): string {\n return `\n <div class='nostr-profile-badge-container'>\n <div class='nostr-profile-badge-left-container'>\n ${leftContent}\n </div>\n <div class='nostr-profile-badge-right-container'>\n ${rightContent}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getProfileBadgeStyles(): string {\n const customStyles = `\n /* === PROFILE BADGE SPECIFIC CSS VARIABLES === */\n :host {\n --nostrc-profile-badge-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-profile-badge-text-primary: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-badge-text-secondary: var(--nostrc-theme-text-secondary, #666666);\n --nostrc-profile-badge-border: var(--nostrc-theme-border, var(--nostrc-color-border));\n --nostrc-profile-badge-font-family: var(--nostrc-font-family-primary);\n --nostrc-profile-badge-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-profile-badge-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-profile-badge-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-badge-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));\n\n /* Make the host the visual profile badge surface */\n display: block;\n background: var(--nostrc-profile-badge-bg);\n border: var(--nostrc-border-width) solid var(--nostrc-profile-badge-border);\n border-radius: var(--nostrc-border-radius-md);\n font-family: var(--nostrc-profile-badge-font-family);\n font-size: var(--nostrc-profile-badge-font-size);\n transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);\n }\n \n /* === PROFILE BADGE CONTAINER PATTERN === */\n .nostr-profile-badge-container {\n display: flex;\n gap: var(--nostrc-spacing-md);\n padding: var(--nostrc-spacing-md);\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-profile-badge-hover-bg);\n color: var(--nostrc-profile-badge-hover-color);\n border: var(--nostrc-profile-badge-hover-border);\n }\n\n :host(.is-error) .nostr-profile-badge-container {\n justify-content: center;\n align-items: center;\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n \n .nostr-profile-badge-left-container {\n width: 48px;\n height: 48px;\n }\n \n .nostr-profile-badge-left-container img {\n width: 100%;\n height: 100%;\n border-radius: var(--nostrc-border-radius-full);\n object-fit: cover;\n }\n \n .nostr-profile-badge-right-container {\n display: flex;\n flex-direction: column;\n justify-content: center;\n flex-grow: 1;\n min-width: 0;\n }\n \n /* Profile badge specific styling using component variables */\n .nostr-profile-badge-container .nostr-profile-name {\n color: var(--nostrc-profile-badge-text-primary);\n }\n \n .nostr-profile-badge-container .text-row {\n color: var(--nostrc-profile-badge-text-secondary);\n }\n \n /* Skeleton specific styles */\n .img-skeleton {\n width: 48px;\n height: 48px;\n border-radius: var(--nostrc-border-radius-full);\n }\n \n `;\n \n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { parseBooleanAttribute } from '../common/utils';\nimport { renderProfileBadge, RenderProfileBadgeOptions } from './render';\nimport { getProfileBadgeStyles } from './style';\nimport { attachCopyDelegation } from '../base/copy-delegation';\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\n\nconst EVT_BADGE = 'nc:profile_badge';\n\n/**\n * NostrProfileBadge\n * =================\n * UI component (extends `NostrUserComponent`) that renders a compact user badge\n * with avatar/name/nip05 and optional npub + follow button.\n *\n * Observed attributes\n * - `show-npub` — boolean-like attribute to display the masked npub + copy\n * - `show-follow` — boolean-like attribute to display the follow button\n *\n * Events\n * - `nc:status` — (from base) status changes for connection/user\n * - `nc:user` — emitted when user & profile are ready (from parent)\n * - `nc:profile_badge` — fired on badge click (detail: `NDKUserProfile | null`);\n * default action opens `https://njump.me/<nip05|npub>`\n *\n * Note: Follow button placement to be improved in future versions\n */\nexport default class NostrProfileBadge extends NostrUserComponent {\n\n /** Lifecycle methods */\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'show-npub',\n 'show-follow',\n ];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n \n this.attachDelegatedListeners();\n attachCopyDelegation({\n addDelegatedListener: this.addDelegatedListener.bind(this),\n });\n this.render();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'show-npub' || name === 'show-follow') {\n this.render();\n }\n }\n\n /** Base class functions */\n protected onStatusChange(_status: NCStatus) {\n this.render();\n }\n\n protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null) {\n this.render();\n }\n\n /** Private functions */\n private onProfileClick() {\n const key =\n this.user?.npub ||\n this.getAttribute('npub') ||\n this.profile?.nip05 ||\n this.getAttribute('nip05');\n\n if (key) {\n this.handleNjumpClick(EVT_BADGE, this.profile, encodeURIComponent(key));\n }\n }\n\n private attachDelegatedListeners() {\n\n // Click anywhere on the profile badge (except follow button, copy buttons)\n this.delegateEvent('click', '.nostr-profile-badge-container', (e: Event) => {\n const target = e.target as HTMLElement;\n if (!target.closest('.nc-copy-btn, .nostr-follow-button-container, nostr-follow-button')) {\n this.onProfileClick();\n }\n });\n\n // Copy is handled via attachCopyDelegation() using `.nc-copy-btn`\n }\n\n protected renderContent() {\n const overall = this.computeOverall();\n const isLoading = overall === NCStatus.Loading;\n const isError = overall === NCStatus.Error;\n\n // Get attribute values\n const showFollow = parseBooleanAttribute(this.getAttribute('show-follow'));\n const showNpub = parseBooleanAttribute(this.getAttribute('show-npub'));\n const errorMessage = isError ? super.renderError(this.errorMessage) : '';\n\n const renderOptions: RenderProfileBadgeOptions = {\n isLoading : isLoading,\n isError : isError,\n errorMessage: errorMessage,\n userProfile : this.profile,\n ndkUser : this.user,\n showNpub : showNpub,\n showFollow : showFollow\n };\n\n this.shadowRoot!.innerHTML = `\n ${getProfileBadgeStyles()}\n ${renderProfileBadge(renderOptions)}\n `;\n }\n}\n\ncustomElements.define('nostr-profile-badge', NostrProfileBadge);\n"],"names":["renderProfileBadge","isLoading","isError","errorMessage","userProfile","ndkUser","showNpub","showFollow","renderLoading","renderError","rawName","maskNPub","escapedName","escapeHtml","profileImage","DEFAULT_PROFILE_IMAGE","npub","nip05","pubkey","renderContainer","renderName","renderNip05","renderNpub","leftContent","rightContent","getProfileBadgeStyles","getComponentStyles","EVT_BADGE","NostrProfileBadge","NostrUserComponent","_a","attachCopyDelegation","name","oldValue","newValue","_status","_user","_profile","key","_b","e","overall","NCStatus","parseBooleanAttribute","renderOptions"],"mappings":"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"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[o]=t;var n=(e,o,t)=>L(e,typeof o!="symbol"?o+"":o,t);import{e as k,g as $,a as p}from"../assets/base-styles-CBypR3FR.js";import{N as z}from"../assets/nostr-user-component-Q7GeeFyu.js";import{r as F,a as C,b as E,d as N,c as A}from"../assets/copy-delegation-C4uvRTVM.js";import"../assets/nostr-service-pr_crY62.js";import"../assets/user-resolver-C-E6KdwY.js";function l(e,o,t){const s=k(e);return`
|
|
2
|
+
<div class="stat" data-orientation="horizontal" aria-busy="${t}" aria-live="polite">
|
|
3
|
+
<div class="stat-inner">
|
|
4
|
+
<div class="stat-value">
|
|
5
|
+
${t?'<div style="width: 50px; height: 28px; border-radius: 5px" class="skeleton"></div>':o.toLocaleString()}
|
|
6
|
+
</div>
|
|
7
|
+
<div class="stat-name">${s}</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
`}function R(e){const{isLoading:o,isError:t,errorMessage:s,npub:i,userProfile:r,isStatsLoading:d,isStatsFollowersLoading:c,isStatsFollowsLoading:b,isZapsLoading:w,stats:a,showFollow:v,showNpub:m}=e;if(t)return Z(s||"");const h=(r==null?void 0:r.displayName)||(r==null?void 0:r.name)||"",u=(r==null?void 0:r.nip05)||"",x=(r==null?void 0:r.picture)||"",g=(r==null?void 0:r.about)||"",f=(r==null?void 0:r.website)||"",y=()=>!v||i===""?"":`
|
|
11
|
+
<nostr-follow-button
|
|
12
|
+
npub="${i}">
|
|
13
|
+
</nostr-follow-button>
|
|
14
|
+
`;return`
|
|
15
|
+
<div class="nostr-profile-container">
|
|
16
|
+
<div class="profile-banner">
|
|
17
|
+
${o?'<div style="width: 100%; height: 100%;" class="skeleton"></div>':r!=null&&r.banner?`<img src="${r.banner}" width="524px"/>`:'<div class="banner-placeholder"></div>'}
|
|
18
|
+
|
|
19
|
+
<div class="dp-container">
|
|
20
|
+
<div class="avatar" role="img" aria-label="${h}">
|
|
21
|
+
${o?'<div style="width: 100%; height: 100%; border-radius: 50%" class="skeleton"></div>':`<img
|
|
22
|
+
src="${x}"
|
|
23
|
+
alt="${h}"
|
|
24
|
+
width="142" height="142"
|
|
25
|
+
loading="lazy" decoding="async"
|
|
26
|
+
onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 142 142%22%3E%3Crect width=%22142%22 height=%22142%22 fill=%22%23ccc%22/%3E%3C/svg%3E'"
|
|
27
|
+
/>`}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="profile_actions">
|
|
33
|
+
${v?o?'<div style="width: 100px; height: 36px; border-radius: 18px;" class="skeleton"></div>':y():""}
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div class="profile_data">
|
|
37
|
+
${o?'<div style="width: 100px; height: 24px;" class="skeleton"></div>':F({name:h})}
|
|
38
|
+
|
|
39
|
+
${o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':C(u)}
|
|
40
|
+
|
|
41
|
+
${m?o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':E(i):""}
|
|
42
|
+
|
|
43
|
+
<div class="margin-bottom-md"> </div>
|
|
44
|
+
|
|
45
|
+
${o?'<div style="width: 100%; margin-bottom: 12px; height: 18px" class="skeleton"></div>':N({display:g,value:g})}
|
|
46
|
+
|
|
47
|
+
<div class="margin-bottom-md"> </div>
|
|
48
|
+
|
|
49
|
+
${o?'<div style="width: 150px" class="skeleton"></div>':f?`<div class="website">
|
|
50
|
+
<a target="_blank" href="${f}">${f}</a>
|
|
51
|
+
</div>`:""}
|
|
52
|
+
|
|
53
|
+
<div class="stats">
|
|
54
|
+
|
|
55
|
+
${l("Following",a.follows,b)}
|
|
56
|
+
|
|
57
|
+
${l("Followers",a.followers,c)}
|
|
58
|
+
|
|
59
|
+
${l("Notes",a.notes,d)}
|
|
60
|
+
|
|
61
|
+
${l("Replies",a.replies,d)}
|
|
62
|
+
|
|
63
|
+
${l("Zaps",a.zaps,w)}
|
|
64
|
+
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
`}function Z(e){return`
|
|
69
|
+
<div class='nostr-profile-container'>
|
|
70
|
+
<div class='nostr-profile-top-container'>
|
|
71
|
+
<div class="error-icon">⚠</div>
|
|
72
|
+
</div>
|
|
73
|
+
<div class='nostr-profile-bottom-container'>
|
|
74
|
+
${e}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
`}function _(){return $(`
|
|
78
|
+
/* === PROFILE CSS VARIABLES & CONTAINER PATTERN === */
|
|
79
|
+
:host {
|
|
80
|
+
/* Override follow button styles for profile context */
|
|
81
|
+
--nostrc-follow-btn-padding: 5px 8px !important;
|
|
82
|
+
--nostrc-follow-btn-font-size: 14px !important;
|
|
83
|
+
--nostrc-follow-btn-border-radius: 12px !important;
|
|
84
|
+
--nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border) !important;
|
|
85
|
+
--nostrc-follow-btn-horizontal-alignment: end !important;
|
|
86
|
+
--nostrc-follow-btn-min-height: auto !important;
|
|
87
|
+
--nostrc-follow-btn-width: 280px;
|
|
88
|
+
|
|
89
|
+
/* Component theme variables (fallback to global theme tokens) */
|
|
90
|
+
--nostrc-profile-bg: var(--nostrc-theme-bg, #ffffff);
|
|
91
|
+
--nostrc-profile-text-primary: var(--nostrc-theme-text-primary, #333333);
|
|
92
|
+
--nostrc-profile-text-secondary: var(--nostrc-theme-text-secondary, #666666);
|
|
93
|
+
--nostrc-profile-border: var(--nostrc-theme-border, var(--nostrc-border-width) solid var(--nostrc-color-border));
|
|
94
|
+
--nostrc-profile-banner-placeholder: var(--nostrc-profile-border);
|
|
95
|
+
--nostrc-profile-font-family: var(--nostrc-font-family-primary);
|
|
96
|
+
--nostrc-profile-font-size: var(--nostrc-font-size-base);
|
|
97
|
+
|
|
98
|
+
/* Hover state variables */
|
|
99
|
+
--nostrc-profile-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));
|
|
100
|
+
--nostrc-profile-hover-color: var(--nostrc-theme-text-primary, #333333);
|
|
101
|
+
--nostrc-profile-hover-border: var(--nostrc-theme-hover-border, var(--nostrc-border-width) solid var(--nostrc-color-border));
|
|
102
|
+
|
|
103
|
+
/* Make the host the visual profile surface */
|
|
104
|
+
display: block;
|
|
105
|
+
background: var(--nostrc-profile-bg);
|
|
106
|
+
color: var(--nostrc-profile-text-primary);
|
|
107
|
+
border: var(--nostrc-profile-border);
|
|
108
|
+
border-radius: var(--nostrc-border-radius-md);
|
|
109
|
+
font-family: var(--nostrc-profile-font-family);
|
|
110
|
+
font-size: var(--nostrc-profile-font-size);
|
|
111
|
+
transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.nostr-profile-container {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
align-items: stretch;
|
|
118
|
+
gap: var(--nostrc-spacing-md);
|
|
119
|
+
min-height: 500px;
|
|
120
|
+
padding: 0px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:host(.is-error) .nostr-profile-container {
|
|
124
|
+
justify-content: center;
|
|
125
|
+
align-items: center;
|
|
126
|
+
color: var(--nostrc-color-error-text);
|
|
127
|
+
border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Hover state */
|
|
131
|
+
:host(.is-clickable:hover) {
|
|
132
|
+
background: var(--nostrc-profile-hover-bg);
|
|
133
|
+
color: var(--nostrc-profile-hover-color);
|
|
134
|
+
border: var(--nostrc-profile-hover-border);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.nostr-profile-top-container img {
|
|
138
|
+
width: 100%;
|
|
139
|
+
height: 100%;
|
|
140
|
+
border-radius: 50%;
|
|
141
|
+
object-fit: cover;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.nostr-profile-bottom-container {
|
|
145
|
+
min-width: 0;
|
|
146
|
+
text-align: center;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.profile-banner {
|
|
150
|
+
position: relative;
|
|
151
|
+
width: 100%;
|
|
152
|
+
height: 214px;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.banner-placeholder {
|
|
158
|
+
width: 100%;
|
|
159
|
+
height: 100%;
|
|
160
|
+
background-color: var(--nostrc-profile-banner-placeholder);
|
|
161
|
+
border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.profile-banner img {
|
|
165
|
+
width: 100%;
|
|
166
|
+
height: 214px;
|
|
167
|
+
object-fit: cover;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.dp-container {
|
|
171
|
+
position: absolute;
|
|
172
|
+
top: 140px;
|
|
173
|
+
left: var(--nostrc-spacing-md);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.avatar {
|
|
177
|
+
--avatar-size: 142px;
|
|
178
|
+
--avatar-ring: 4px;
|
|
179
|
+
|
|
180
|
+
inline-size: var(--avatar-size);
|
|
181
|
+
block-size: var(--avatar-size);
|
|
182
|
+
border-radius: var(--nostrc-border-radius-full);
|
|
183
|
+
overflow: hidden;
|
|
184
|
+
|
|
185
|
+
/* ring + backfill in one place */
|
|
186
|
+
background-color: var(--nostrc-profile-bg);
|
|
187
|
+
border: var(--avatar-ring) solid var(--nostrc-profile-bg);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.avatar img {
|
|
191
|
+
inline-size: 100%;
|
|
192
|
+
block-size: 100%;
|
|
193
|
+
border-radius: var(--nostrc-border-radius-full);
|
|
194
|
+
display: block;
|
|
195
|
+
object-fit: cover;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.profile_actions {
|
|
199
|
+
height: 56px;
|
|
200
|
+
align-self: flex-end;
|
|
201
|
+
padding: 0 var(--nostrc-spacing-lg);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.profile_data {
|
|
205
|
+
padding: var(--nostrc-spacing-md);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.website {
|
|
209
|
+
font-weight: 400;
|
|
210
|
+
font-size: var(--nostrc-font-size-base);
|
|
211
|
+
line-height: 20px;
|
|
212
|
+
display: flex;
|
|
213
|
+
align-items: center;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.website a {
|
|
217
|
+
line-height: 20px;
|
|
218
|
+
outline: none;
|
|
219
|
+
color: var(--nostrc-profile-accent);
|
|
220
|
+
max-width: 350px;
|
|
221
|
+
overflow: hidden;
|
|
222
|
+
text-overflow: ellipsis;
|
|
223
|
+
word-wrap: normal;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.stats {
|
|
227
|
+
position: relative;
|
|
228
|
+
display: flex;
|
|
229
|
+
flex-direction: row;
|
|
230
|
+
flex-wrap: wrap;
|
|
231
|
+
justify-content: space-between;
|
|
232
|
+
align-items: center;
|
|
233
|
+
border-radius: 0;
|
|
234
|
+
border-top: none;
|
|
235
|
+
margin-top: var(--nostrc-spacing-md);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.stat {
|
|
239
|
+
position: relative;
|
|
240
|
+
display: inline-block;
|
|
241
|
+
padding-inline: var(--nostrc-spacing-md);
|
|
242
|
+
padding-block: var(--nostrc-spacing-xs);
|
|
243
|
+
border: none;
|
|
244
|
+
background: none;
|
|
245
|
+
width: fit-content;
|
|
246
|
+
height: 40px;
|
|
247
|
+
margin: 0 0 var(--nostrc-spacing-md);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.stat-inner {
|
|
251
|
+
display: flex;
|
|
252
|
+
flex-direction: column;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
align-items: center;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.stat-inner .stat-value {
|
|
258
|
+
font-weight: 100;
|
|
259
|
+
font-size: 1.5em;
|
|
260
|
+
color: var(--nostrc-profile-text-primary);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.stat-inner .stat-name {
|
|
264
|
+
font-weight: 400;
|
|
265
|
+
line-height: 16px;
|
|
266
|
+
text-transform: lowercase;
|
|
267
|
+
color: var(--nostrc-profile-text-secondary);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@media only screen and (max-width: 600px) {
|
|
271
|
+
.stat .stat-value {
|
|
272
|
+
font-size: 18px !important;
|
|
273
|
+
}
|
|
274
|
+
:host {
|
|
275
|
+
--nostrc-follow-btn-padding: 5px 8px !important;
|
|
276
|
+
--nostrc-follow-btn-font-size: 12px !important;
|
|
277
|
+
--nostrc-follow-btn-min-height: auto !important;
|
|
278
|
+
--nostrc-follow-btn-border-radius: 8px !important;
|
|
279
|
+
--nostrc-follow-btn-error-max-width: 150px !important;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
`)}const j="nc:profile";class O extends z{constructor(){super(...arguments);n(this,"profileStatus",this.channel("profile"));n(this,"isStatsLoading",!0);n(this,"isStatsFollowsLoading",!0);n(this,"isStatsFollowersLoading",!0);n(this,"isZapsLoading",!0);n(this,"stats",{follows:0,followers:0,notes:0,replies:0,zaps:0,relays:0});n(this,"getUserStats",async()=>{try{this.isStatsLoading=!0,this.isStatsFollowsLoading=!0,this.isStatsFollowersLoading=!0,this.isZapsLoading=!0,this.nostrService.fetchFollows(this.user).then(t=>{this.stats={...this.stats,follows:t},this.isStatsFollowsLoading=!1,this.render()}).catch(t=>{console.error("Error loading follows:",t),this.isStatsFollowsLoading=!1,this.render()}),this.nostrService.fetchFollowers(this.user).then(t=>{this.stats={...this.stats,followers:t},this.isStatsFollowersLoading=!1,this.render()}).catch(t=>{console.error("Error loading followers:",t),this.isStatsFollowersLoading=!1,this.render()}),this.nostrService.fetchNotesAndReplies(this.user).then(([t,s])=>{this.stats={...this.stats,notes:t,replies:s},this.isStatsLoading=!1,this.render()}).catch(t=>{console.error("Error loading notes and replies",t),this.isStatsLoading=!1,this.render()}),this.nostrService.fetchZaps(this.user).then(t=>{this.stats={...this.stats,zaps:t},this.isZapsLoading=!1,this.render()}).catch(t=>{console.error("Error loading Zaps:",t),this.isZapsLoading=!1,this.render()})}catch(t){this.profileStatus.set(p.Error),console.error("getUserStats failed:",t)}finally{this.render()}})}static get observedAttributes(){return[...super.observedAttributes,"show-npub","show-follow"]}async connectedCallback(){var t;(t=super.connectedCallback)==null||t.call(this),this.attachDelegatedListeners(),A({addDelegatedListener:this.addDelegatedListener.bind(this)}),this.render()}onStatusChange(t){this.render()}onUserReady(t,s){this.getUserStats(),this.render()}attributeChangedCallback(t,s,i){var r;s!==i&&((r=super.attributeChangedCallback)==null||r.call(this,t,s,i),(t==="show-npub"||t==="show-follow")&&this.render())}onProfileClick(){var s,i;if(this.profileStatus.get()===p.Error)return;const t=((s=this.user)==null?void 0:s.npub)||this.getAttribute("npub")||((i=this.profile)==null?void 0:i.nip05)||this.getAttribute("nip05");t&&this.handleNjumpClick(j,this.profile,encodeURIComponent(t))}attachDelegatedListeners(){this.delegateEvent("click",".profile-banner",t=>{t.target.closest(".nc-copy-btn, .nostr-follow-button-container, nostr-follow-button")||this.onProfileClick()})}renderContent(){var c;const t=this.computeOverall()===p.Loading,s=this.computeOverall()===p.Error,i=this.getAttribute("show-npub")==="true",r=this.getAttribute("show-follow")==="true",d={isLoading:t,isError:s,errorMessage:this.errorMessage,npub:((c=this.user)==null?void 0:c.npub)||"",userProfile:this.profile,isStatsLoading:this.isStatsLoading,isStatsFollowersLoading:this.isStatsFollowersLoading,isStatsFollowsLoading:this.isStatsFollowsLoading,isZapsLoading:this.isZapsLoading,stats:{notes:this.stats.notes,replies:this.stats.replies,follows:this.stats.follows,followers:this.stats.followers,zaps:this.stats.zaps,relays:this.stats.relays},showFollow:r,showNpub:i};this.shadowRoot.innerHTML=`
|
|
284
|
+
${_()}
|
|
285
|
+
${R(d)}
|
|
286
|
+
`}}customElements.define("nostr-profile",O);
|
|
287
|
+
//# sourceMappingURL=nostr-profile.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nostr-profile.es.js","sources":["../../src/nostr-profile/render-stats.ts","../../src/nostr-profile/render.ts","../../src/nostr-profile/style.ts","../../src/nostr-profile/nostr-profile.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { escapeHtml } from \"../common/utils\";\n\nexport function renderStats(\n label: string,\n value: number,\n isLoading: boolean\n): string {\n const safeLabel = escapeHtml(label)\n return `\n <div class=\"stat\" data-orientation=\"horizontal\" aria-busy=\"${isLoading}\" aria-live=\"polite\">\n <div class=\"stat-inner\">\n <div class=\"stat-value\">\n ${\n isLoading\n ? '<div style=\"width: 50px; height: 28px; border-radius: 5px\" class=\"skeleton\"></div>'\n : value.toLocaleString()\n }\n </div>\n <div class=\"stat-name\">${safeLabel}</div>\n </div>\n </div>\n `;\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { IRenderOptions } from '../base/render-options';\nimport { renderNpub } from '../base/text-row/render-npub';\nimport { renderNip05 } from '../base/text-row/render-nip05';\nimport { renderStats } from './render-stats';\nimport { renderName } from '../base/text-row/render-name';\nimport { renderTextRow } from '../base/text-row/render-text-row';\n\nexport interface Stats {\n notes: number;\n replies: number;\n follows: number;\n followers: number;\n zaps: number;\n relays: number;\n}\n\nexport interface RenderProfileOptions extends IRenderOptions {\n npub: string;\n userProfile: NDKUserProfile;\n isStatsLoading: boolean;\n isStatsFollowersLoading: boolean;\n isStatsFollowsLoading: boolean;\n isZapsLoading: boolean;\n stats: Stats;\n showFollow: boolean;\n showNpub: boolean;\n}\n\nexport function renderProfile(options: RenderProfileOptions): string {\n const {\n isLoading,\n isError,\n errorMessage,\n npub,\n userProfile,\n isStatsLoading,\n isStatsFollowersLoading,\n isStatsFollowsLoading,\n isZapsLoading,\n stats,\n showFollow,\n showNpub,\n } = options;\n\n if (isError) {\n return renderError(errorMessage || '');\n }\n\n // Extract profile data with null checks and default values\n const displayName = userProfile?.displayName || userProfile?.name || '';\n const nip05 = userProfile?.nip05 || '';\n const image = userProfile?.picture || '';\n const about = userProfile?.about || '';\n const website = userProfile?.website || '';\n\n const renderFollowButton = () => {\n if (!showFollow || npub === '') return '';\n return `\n <nostr-follow-button\n npub=\"${npub}\">\n </nostr-follow-button>\n `;\n };\n\n return `\n <div class=\"nostr-profile-container\">\n <div class=\"profile-banner\">\n ${isLoading\n ? '<div style=\"width: 100%; height: 100%;\" class=\"skeleton\"></div>'\n : userProfile?.banner\n ? `<img src=\"${userProfile.banner}\" width=\"524px\"/>`\n : '<div class=\"banner-placeholder\"></div>'\n }\n\n <div class=\"dp-container\">\n <div class=\"avatar\" role=\"img\" aria-label=\"${displayName}\">\n ${isLoading\n ? '<div style=\"width: 100%; height: 100%; border-radius: 50%\" class=\"skeleton\"></div>'\n : `<img\n src=\"${image}\"\n alt=\"${displayName}\"\n width=\"142\" height=\"142\"\n loading=\"lazy\" decoding=\"async\"\n onerror=\"this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 142 142%22%3E%3Crect width=%22142%22 height=%22142%22 fill=%22%23ccc%22/%3E%3C/svg%3E'\"\n />`\n }\n </div>\n </div>\n </div>\n\n <div class=\"profile_actions\">\n ${showFollow ?\n isLoading? '<div style=\"width: 100px; height: 36px; border-radius: 18px;\" class=\"skeleton\"></div>'\n : renderFollowButton()\n : ''\n }\n </div>\n \n <div class=\"profile_data\">\n ${isLoading\n ? '<div style=\"width: 100px; height: 24px;\" class=\"skeleton\"></div>'\n : renderName({ name: displayName })\n }\n \n ${isLoading\n ? '<div style=\"width: 75px; height: 20px;\" class=\"skeleton\"></div>'\n : renderNip05(nip05)\n }\n\n ${showNpub ?\n isLoading\n ? '<div style=\"width: 75px; height: 20px;\" class=\"skeleton\"></div>'\n : renderNpub(npub)\n : ''\n }\n\n <div class=\"margin-bottom-md\"> </div>\n \n ${isLoading\n ? `<div style=\"width: 100%; margin-bottom: 12px; height: 18px\" class=\"skeleton\"></div>`\n : renderTextRow({ display: about, value: about })\n }\n\n <div class=\"margin-bottom-md\"> </div>\n \n ${isLoading\n ? '<div style=\"width: 150px\" class=\"skeleton\"></div>'\n : website\n ? `<div class=\"website\">\n <a target=\"_blank\" href=\"${website}\">${website}</a>\n </div>`\n : ''\n }\n \n <div class=\"stats\">\n\n ${renderStats('Following', stats.follows, isStatsFollowsLoading)}\n \n ${renderStats('Followers', stats.followers, isStatsFollowersLoading)}\n\n ${renderStats('Notes', stats.notes, isStatsLoading)}\n \n ${renderStats('Replies', stats.replies, isStatsLoading)}\n \n ${renderStats('Zaps', stats.zaps, isZapsLoading)}\n \n </div>\n </div>\n </div>\n `;\n}\n\nfunction renderError(errorMessage: string): string {\n return `\n <div class='nostr-profile-container'>\n <div class='nostr-profile-top-container'>\n <div class=\"error-icon\">⚠</div>\n </div>\n <div class='nostr-profile-bottom-container'>\n ${errorMessage}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getProfileStyles(): string {\n const customStyles = `\n /* === PROFILE CSS VARIABLES & CONTAINER PATTERN === */\n :host {\n /* Override follow button styles for profile context */\n --nostrc-follow-btn-padding: 5px 8px !important;\n --nostrc-follow-btn-font-size: 14px !important;\n --nostrc-follow-btn-border-radius: 12px !important;\n --nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border) !important;\n --nostrc-follow-btn-horizontal-alignment: end !important;\n --nostrc-follow-btn-min-height: auto !important;\n --nostrc-follow-btn-width: 280px;\n\n /* Component theme variables (fallback to global theme tokens) */\n --nostrc-profile-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-profile-text-primary: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-text-secondary: var(--nostrc-theme-text-secondary, #666666);\n --nostrc-profile-border: var(--nostrc-theme-border, var(--nostrc-border-width) solid var(--nostrc-color-border));\n --nostrc-profile-banner-placeholder: var(--nostrc-profile-border);\n --nostrc-profile-font-family: var(--nostrc-font-family-primary);\n --nostrc-profile-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-profile-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-profile-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-hover-border: var(--nostrc-theme-hover-border, var(--nostrc-border-width) solid var(--nostrc-color-border));\n\n /* Make the host the visual profile surface */\n display: block;\n background: var(--nostrc-profile-bg);\n color: var(--nostrc-profile-text-primary);\n border: var(--nostrc-profile-border);\n border-radius: var(--nostrc-border-radius-md);\n font-family: var(--nostrc-profile-font-family);\n font-size: var(--nostrc-profile-font-size);\n transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);\n }\n\n .nostr-profile-container {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--nostrc-spacing-md);\n min-height: 500px;\n padding: 0px;\n }\n\n :host(.is-error) .nostr-profile-container {\n justify-content: center;\n align-items: center;\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-profile-hover-bg);\n color: var(--nostrc-profile-hover-color);\n border: var(--nostrc-profile-hover-border);\n }\n\n .nostr-profile-top-container img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n }\n\n .nostr-profile-bottom-container {\n min-width: 0;\n text-align: center;\n }\n\n .profile-banner {\n position: relative;\n width: 100%;\n height: 214px;\n cursor: pointer;\n border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;\n }\n\n .banner-placeholder {\n width: 100%;\n height: 100%;\n background-color: var(--nostrc-profile-banner-placeholder);\n border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;\n }\n\n .profile-banner img {\n width: 100%;\n height: 214px;\n object-fit: cover;\n }\n\n .dp-container {\n position: absolute;\n top: 140px;\n left: var(--nostrc-spacing-md);\n }\n\n .avatar {\n --avatar-size: 142px;\n --avatar-ring: 4px;\n\n inline-size: var(--avatar-size);\n block-size: var(--avatar-size);\n border-radius: var(--nostrc-border-radius-full);\n overflow: hidden;\n\n /* ring + backfill in one place */\n background-color: var(--nostrc-profile-bg);\n border: var(--avatar-ring) solid var(--nostrc-profile-bg);\n }\n\n .avatar img {\n inline-size: 100%;\n block-size: 100%;\n border-radius: var(--nostrc-border-radius-full);\n display: block;\n object-fit: cover;\n }\n\n .profile_actions {\n height: 56px;\n align-self: flex-end;\n padding: 0 var(--nostrc-spacing-lg);\n }\n\n .profile_data {\n padding: var(--nostrc-spacing-md);\n }\n\n .website {\n font-weight: 400;\n font-size: var(--nostrc-font-size-base);\n line-height: 20px;\n display: flex;\n align-items: center;\n }\n\n .website a {\n line-height: 20px;\n outline: none;\n color: var(--nostrc-profile-accent);\n max-width: 350px;\n overflow: hidden;\n text-overflow: ellipsis;\n word-wrap: normal;\n }\n\n .stats {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: center;\n border-radius: 0;\n border-top: none;\n margin-top: var(--nostrc-spacing-md);\n }\n\n .stat {\n position: relative;\n display: inline-block;\n padding-inline: var(--nostrc-spacing-md);\n padding-block: var(--nostrc-spacing-xs);\n border: none;\n background: none;\n width: fit-content;\n height: 40px;\n margin: 0 0 var(--nostrc-spacing-md);\n }\n\n .stat-inner {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n }\n\n .stat-inner .stat-value {\n font-weight: 100;\n font-size: 1.5em;\n color: var(--nostrc-profile-text-primary);\n }\n\n .stat-inner .stat-name {\n font-weight: 400;\n line-height: 16px;\n text-transform: lowercase;\n color: var(--nostrc-profile-text-secondary);\n }\n\n @media only screen and (max-width: 600px) {\n .stat .stat-value {\n font-size: 18px !important;\n }\n :host {\n --nostrc-follow-btn-padding: 5px 8px !important;\n --nostrc-follow-btn-font-size: 12px !important;\n --nostrc-follow-btn-min-height: auto !important;\n --nostrc-follow-btn-border-radius: 8px !important;\n --nostrc-follow-btn-error-max-width: 150px !important;\n }\n }\n\n `;\n \n // Use component styles - includes design tokens + utilities + custom styles\n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { renderProfile, RenderProfileOptions } from './render';\nimport { getProfileStyles } from './style';\nimport { attachCopyDelegation } from '../base/copy-delegation';\n\nconst EVT_PROFILE = 'nc:profile';\n\nexport default class NostrProfile extends NostrUserComponent {\n\n protected profileStatus = this.channel('profile');\n\n // Stats loading states\n private isStatsLoading: boolean = true;\n private isStatsFollowsLoading: boolean = true;\n private isStatsFollowersLoading: boolean = true;\n private isZapsLoading: boolean = true;\n\n private stats = {\n follows: 0,\n followers: 0,\n notes: 0,\n replies: 0,\n zaps: 0,\n relays: 0,\n };\n\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'show-npub',\n 'show-follow',\n ];\n }\n\n async connectedCallback() {\n super.connectedCallback?.();\n this.attachDelegatedListeners();\n attachCopyDelegation({\n addDelegatedListener: this.addDelegatedListener.bind(this),\n });\n this.render();\n }\n\n /** Base class functions */\n protected onStatusChange(_status: NCStatus) {\n this.render();\n }\n\n protected onUserReady(_user: any, _profile: any) {\n this.getUserStats();\n this.render();\n }\n\n getUserStats = async () => {\n try {\n this.isStatsLoading = true;\n this.isStatsFollowsLoading = true;\n this.isStatsFollowersLoading = true;\n this.isZapsLoading = true;\n\n // Fetch follows\n this.nostrService\n .fetchFollows(this.user!)\n .then((follows) => {\n this.stats = { ...this.stats, follows };\n this.isStatsFollowsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading follows:', err);\n this.isStatsFollowsLoading = false;\n this.render();\n });\n\n // Fetch followers\n this.nostrService\n .fetchFollowers(this.user!)\n .then((followers) => {\n this.stats = { ...this.stats, followers };\n this.isStatsFollowersLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading followers:', err);\n this.isStatsFollowersLoading = false;\n this.render();\n });\n\n // Fetch notes and replies\n this.nostrService\n .fetchNotesAndReplies(this.user!)\n .then(([ notes, replies ]) => {\n this.stats = { ...this.stats, notes, replies };\n this.isStatsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading notes and replies', err);\n this.isStatsLoading = false;\n this.render();\n });\n\n // Fetch zaps\n this.nostrService\n .fetchZaps(this.user!)\n .then((zaps) => {\n this.stats = { ...this.stats, zaps };\n this.isZapsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading Zaps:', err);\n this.isZapsLoading = false;\n this.render();\n });\n\n\n } catch (err) {\n this.profileStatus.set(NCStatus.Error);\n console.error('getUserStats failed:', err);\n } finally {\n this.render();\n }\n };\n\n attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'show-npub' || name === 'show-follow') {\n this.render();\n }\n }\n\n /** Private functions */\n private onProfileClick() {\n if (this.profileStatus.get() === NCStatus.Error) return;\n\n const key =\n this.user?.npub ||\n this.getAttribute('npub') ||\n this.profile?.nip05 ||\n this.getAttribute('nip05');\n\n if (key) {\n this.handleNjumpClick(EVT_PROFILE, this.profile, encodeURIComponent(key));\n }\n }\n\n private attachDelegatedListeners() {\n\n // Click anywhere on the profile badge (except follow button, copy buttons)\n this.delegateEvent('click', '.profile-banner', (e: Event) => {\n const target = e.target as HTMLElement;\n if (!target.closest('.nc-copy-btn, .nostr-follow-button-container, nostr-follow-button')) {\n this.onProfileClick();\n }\n });\n\n }\n\n protected renderContent() {\n const isLoading = this.computeOverall() === NCStatus.Loading;\n const isError = this.computeOverall() === NCStatus.Error;\n const showNpub = this.getAttribute('show-npub') === 'true';\n const showFollow = this.getAttribute('show-follow') === 'true';\n\n const renderOptions: RenderProfileOptions = {\n isLoading: isLoading,\n isError: isError,\n errorMessage: this.errorMessage,\n npub: this.user?.npub || '',\n userProfile: this.profile!,\n isStatsLoading: this.isStatsLoading,\n isStatsFollowersLoading: this.isStatsFollowersLoading,\n isStatsFollowsLoading: this.isStatsFollowsLoading,\n isZapsLoading: this.isZapsLoading,\n stats: {\n notes: this.stats.notes,\n replies: this.stats.replies,\n follows: this.stats.follows,\n followers: this.stats.followers,\n zaps: this.stats.zaps,\n relays: this.stats.relays,\n },\n showFollow: showFollow,\n showNpub: showNpub,\n };\n\n this.shadowRoot!.innerHTML = `\n ${getProfileStyles()}\n ${renderProfile(renderOptions)}\n `;\n\n }\n}\n\ncustomElements.define('nostr-profile', NostrProfile);\n"],"names":["renderStats","label","value","isLoading","safeLabel","escapeHtml","renderProfile","options","isError","errorMessage","npub","userProfile","isStatsLoading","isStatsFollowersLoading","isStatsFollowsLoading","isZapsLoading","stats","showFollow","showNpub","renderError","displayName","nip05","image","about","website","renderFollowButton","renderName","renderNip05","renderNpub","renderTextRow","getProfileStyles","getComponentStyles","EVT_PROFILE","NostrProfile","NostrUserComponent","__publicField","follows","err","followers","notes","replies","zaps","NCStatus","_a","attachCopyDelegation","_status","_user","_profile","name","oldValue","newValue","key","_b","e","renderOptions"],"mappings":"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"}
|