nostr-components 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -46
- package/dist/assets/{base-styles-DC0ilu4S.js → base-styles-Dmuzg8I4.js} +3 -3
- package/dist/assets/{base-styles-DC0ilu4S.js.map → base-styles-Dmuzg8I4.js.map} +1 -1
- package/dist/assets/{copy-delegation-CcagQMIW.js → copy-delegation-xzt-t_do.js} +5 -5
- package/dist/assets/{copy-delegation-CcagQMIW.js.map → copy-delegation-xzt-t_do.js.map} +1 -1
- package/dist/assets/dark-nostrich-running.gif +0 -0
- package/dist/assets/default_dp-NQ3TGrtT.png +0 -0
- package/dist/assets/default_dp.png +0 -0
- package/dist/assets/default_dp_32.png +0 -0
- package/dist/assets/{dialog-component-Dqg0QU9I.js → dialog-component-Da1ZIYh9.js} +7 -2
- package/dist/assets/dialog-component-Da1ZIYh9.js.map +1 -0
- package/dist/assets/{dialog-likers-D3c7WIMp.js → dialog-likers-Bq6kUbS0.js} +4 -4
- package/dist/assets/{dialog-likers-D3c7WIMp.js.map → dialog-likers-Bq6kUbS0.js.map} +1 -1
- package/dist/assets/light-nostrich-running.gif +0 -0
- package/dist/assets/{nostr-service-m3Hgc5Xx.js → nostr-service-CA0Qx4nJ.js} +3 -3
- package/dist/assets/{nostr-service-m3Hgc5Xx.js.map → nostr-service-CA0Qx4nJ.js.map} +1 -1
- package/dist/assets/nostr-user-component-r-MUbTL6.js +2 -0
- package/dist/assets/nostr-user-component-r-MUbTL6.js.map +1 -0
- package/dist/assets/{pure-laCRX9eG.js → pure-DOoUcNQv.js} +2 -2
- package/dist/assets/{pure-laCRX9eG.js.map → pure-DOoUcNQv.js.map} +1 -1
- package/dist/assets/{theme-C1r1Zw8r.js → theme-BN1Bvweb.js} +2 -2
- package/dist/assets/{theme-C1r1Zw8r.js.map → theme-BN1Bvweb.js.map} +1 -1
- package/dist/assets/{user-resolver-DqI5KGh6.js → user-resolver-ArI0680e.js} +2 -2
- package/dist/assets/{user-resolver-DqI5KGh6.js.map → user-resolver-ArI0680e.js.map} +1 -1
- package/dist/assets/zap-utils-BiKkJPt6.js +2 -0
- package/dist/assets/zap-utils-BiKkJPt6.js.map +1 -0
- package/dist/components/nostr-comment.es.js +6 -6
- package/dist/components/nostr-comment.es.js.map +1 -1
- package/dist/components/nostr-dm.es.js +2 -2
- package/dist/components/nostr-dm.es.js.map +1 -1
- package/dist/components/nostr-follow-button.es.js +3 -3
- package/dist/components/nostr-follow-button.es.js.map +1 -1
- package/dist/components/nostr-like.es.js +6 -6
- package/dist/components/nostr-like.es.js.map +1 -1
- package/dist/components/nostr-live-chat.es.js +3 -3
- package/dist/components/nostr-live-chat.es.js.map +1 -1
- package/dist/components/nostr-post.es.js +2 -2
- package/dist/components/nostr-post.es.js.map +1 -1
- package/dist/components/nostr-profile-badge.es.js +3 -3
- package/dist/components/nostr-profile-badge.es.js.map +1 -1
- package/dist/components/nostr-profile.es.js +5 -5
- package/dist/components/nostr-profile.es.js.map +1 -1
- package/dist/components/nostr-zap.es.js +5 -5
- package/dist/components/nostr-zap.es.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/nostr-comment.d.ts +4 -0
- package/dist/nostr-components.es.js +1 -1
- package/dist/nostr-components.es.js.map +1 -1
- package/dist/nostr-components.umd.js +69 -40
- package/dist/nostr-components.umd.js.map +1 -1
- 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-login-service.d.ts +26 -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 +32 -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 +48 -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 +57 -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 +1 -1
- package/dist/assets/dialog-component-Dqg0QU9I.js.map +0 -1
- package/dist/assets/nostr-user-component-XEnanH-d.js +0 -2
- package/dist/assets/nostr-user-component-XEnanH-d.js.map +0 -1
- package/dist/assets/zap-utils-BZcaCsT_.js +0 -2
- package/dist/assets/zap-utils-BZcaCsT_.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{m as v,e as s,g as m,
|
|
1
|
+
import{m as v,e as s,g as m,N as d,p as b}from"../assets/base-styles-Dmuzg8I4.js";import{N as y}from"../assets/nostr-user-component-r-MUbTL6.js";import{D as w}from"../assets/nostr-service-CA0Qx4nJ.js";import{r as x,a as C,b as E,d as N}from"../assets/copy-delegation-xzt-t_do.js";import"../assets/user-resolver-ArI0680e.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
2
|
${e.nip05?C(h):""}
|
|
3
3
|
${a===!0?E(g||""):""}
|
|
4
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>
|
|
@@ -93,8 +93,8 @@ import{m as v,e as s,g as m,a as d,p as b}from"../assets/base-styles-DC0ilu4S.js
|
|
|
93
93
|
border-radius: var(--nostrc-border-radius-full);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
`)}const
|
|
96
|
+
`)}const D="nc:profile_badge";class I 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(D,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
97
|
${$()}
|
|
98
98
|
${A(i)}
|
|
99
|
-
`}}customElements.define("nostr-profile-badge",
|
|
99
|
+
`}}customElements.get("nostr-profile-badge")||customElements.define("nostr-profile-badge",I);export{I as default};
|
|
100
100
|
//# sourceMappingURL=nostr-profile-badge.es.js.map
|
|
@@ -1 +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":"oUAmBO,SAASA,EAAmB,CACjC,UAAAC,EACA,QAAAC,EACA,aAAAC,EACA,YAAAC,EACA,QAAAC,EACA,SAAAC,EACA,WAAAC,CACF,EAAsC,CAEpC,GAAIN,EACF,OAAOO,EAAA,EAGT,GAAIN,GAAWE,GAAe,KAC5B,OAAOK,EAAYN,GAAgB,EAAE,EAGvC,MAAMO,EAAUN,EAAY,aAC1BA,EAAY,MACZO,GAASN,GAAA,YAAAA,EAAS,OAAQ,EAAE,EACxBO,EAAcC,EAAWH,CAAO,EAChCI,EAAeD,EAAWT,EAAY,SAAWW,CAAqB,EACtEC,GAAOX,GAAA,YAAAA,EAAS,OAAQ,GACxBY,GAAQb,GAAA,YAAAA,EAAa,QAAS,GAC9Bc,EAASL,GAAWR,GAAA,YAAAA,EAAS,SAAU,EAAE,EAE/C,OAAOc,EACL,aAAaL,CAAY,iCAAiCF,CAAW,sCACrE,GAAGQ,EAAW,CAAE,KAAMV,CAAA,CAAS,CAAC;AAAA,OAC7BN,EAAY,MAAQiB,EAAYJ,CAAK,EAAI,EAAE;AAAA,OAC3CX,IAAa,GAAOgB,EAAWN,GAAQ,EAAE,EAAI,EAAE;AAAA,OAC/CT,IAAe,KAAQF,GAAA,MAAAA,EAAS,QAAS,gCAAgCa,CAAM,2BAA6B,EAAE,EAAA,CAErH,CAEA,SAASV,GAAwB,CAC/B,OAAOW,EACL,4CACA;AAAA,wDAAA,CAGJ,CAEA,SAASV,EAAYN,EAA8B,CACjD,OAAOgB,EACL,wCACAN,EAAWV,CAAY,CAAA,CAE3B,CAEA,SAASgB,EAAgBI,EAAqBC,EAA8B,CAC1E,MAAO;AAAA;AAAA;AAAA,UAGCD,CAAW;AAAA;AAAA;AAAA,UAGXC,CAAY;AAAA;AAAA;AAAA,GAItB,CC7EO,SAASC,GAAgC,CAqF9C,OAAOC,EApFc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoFiB,CACxC,CChFA,MAAMC,EAAY,mBAoBlB,MAAqBC,UAA0BC,CAAmB,CAGhE,WAAW,oBAAqB,CAC9B,MAAO,CACL,GAAG,MAAM,mBACT,YACA,aAAA,CAEJ,CAEA,mBAAoB,QAClBC,EAAA,MAAM,oBAAN,MAAAA,EAAA,WAEA,KAAK,yBAAA,EACLC,EAAqB,CACnB,qBAAsB,KAAK,qBAAqB,KAAK,IAAI,CAAA,CAC1D,EACD,KAAK,OAAA,CACP,CAEA,yBAAyBC,EAAcC,EAAyBC,EAAyB,OACnFD,IAAaC,KACjBJ,EAAA,MAAM,2BAAN,MAAAA,EAAA,UAAiCE,EAAMC,EAAUC,IAE7CF,IAAS,aAAeA,IAAS,gBACnC,KAAK,OAAA,EAET,CAGU,eAAeG,EAAmB,CAC1C,KAAK,OAAA,CACP,CAEU,YAAYC,EAAgBC,EAAiC,CACrE,KAAK,OAAA,CACP,CAGQ,gBAAiB,SACvB,MAAMC,IACJR,EAAA,KAAK,OAAL,YAAAA,EAAW,OACX,KAAK,aAAa,MAAM,KACxBS,EAAA,KAAK,UAAL,YAAAA,EAAc,QACd,KAAK,aAAa,OAAO,EAEvBD,GACF,KAAK,iBAAiBX,EAAW,KAAK,QAAS,mBAAmBW,CAAG,CAAC,CAE1E,CAEQ,0BAA2B,CAGjC,KAAK,cAAc,QAAS,iCAAmCE,GAAa,CAC3DA,EAAE,OACL,QAAQ,mEAAmE,GACrF,KAAK,eAAA,CAET,CAAC,CAGH,CAEU,eAAgB,CACxB,MAAMC,EAAgB,KAAK,eAAA,EACrBxC,EAAgBwC,IAAYC,EAAS,QACrCxC,EAAgBuC,IAAYC,EAAS,MAGrCnC,EAAgBoC,EAAsB,KAAK,aAAa,aAAa,CAAC,EACtErC,EAAgBqC,EAAsB,KAAK,aAAa,WAAW,CAAC,EACpExC,EAAgBD,EAAU,MAAM,YAAY,KAAK,YAAY,EAAI,GAEjE0C,EAA2C,CAC/C,UAAA3C,EACA,QAAAC,EACA,aAAAC,EACA,YAAc,KAAK,QACnB,QAAc,KAAK,KACnB,SAAAG,EACA,WAAAC,CAAA,EAGF,KAAK,WAAY,UAAY;AAAA,QACzBkB,GAAuB;AAAA,QACvBzB,EAAmB4C,CAAa,CAAC;AAAA,KAEvC,CACF,CAEA,eAAe,OAAO,sBAAuBhB,CAAiB"}
|
|
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\nif (!customElements.get('nostr-profile-badge')) {\n customElements.define('nostr-profile-badge', NostrProfileBadge);\n}\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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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
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 $,
|
|
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 $,N as p}from"../assets/base-styles-Dmuzg8I4.js";import{N as z}from"../assets/nostr-user-component-r-MUbTL6.js";import{r as F,a as C,b as E,c as N,d as A}from"../assets/copy-delegation-xzt-t_do.js";import"../assets/nostr-service-CA0Qx4nJ.js";import"../assets/user-resolver-ArI0680e.js";function l(e,o,t){const s=k(e);return`
|
|
2
2
|
<div class="stat" data-orientation="horizontal" aria-busy="${t}" aria-live="polite">
|
|
3
3
|
<div class="stat-inner">
|
|
4
4
|
<div class="stat-value">
|
|
@@ -7,7 +7,7 @@ var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configura
|
|
|
7
7
|
<div class="stat-name">${s}</div>
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
|
-
`}function R(e){const{isLoading:o,isError:t,errorMessage:s,npub:i,userProfile:r,isStatsLoading:d,isStatsFollowersLoading:c,isStatsFollowsLoading:b,isZapsLoading:
|
|
10
|
+
`}function R(e){const{isLoading:o,isError:t,errorMessage:s,npub:i,userProfile:r,isStatsLoading:d,isStatsFollowersLoading:c,isStatsFollowsLoading:b,isZapsLoading:m,stats:a,showFollow:v,showNpub:w}=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
11
|
<nostr-follow-button
|
|
12
12
|
npub="${i}">
|
|
13
13
|
</nostr-follow-button>
|
|
@@ -38,7 +38,7 @@ var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configura
|
|
|
38
38
|
|
|
39
39
|
${o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':C(u)}
|
|
40
40
|
|
|
41
|
-
${
|
|
41
|
+
${w?o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':E(i):""}
|
|
42
42
|
|
|
43
43
|
<div class="margin-bottom-md"> </div>
|
|
44
44
|
|
|
@@ -60,7 +60,7 @@ var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configura
|
|
|
60
60
|
|
|
61
61
|
${l("Replies",a.replies,d)}
|
|
62
62
|
|
|
63
|
-
${l("Zaps",a.zaps,
|
|
63
|
+
${l("Zaps",a.zaps,m)}
|
|
64
64
|
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
@@ -283,5 +283,5 @@ var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configura
|
|
|
283
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
284
|
${_()}
|
|
285
285
|
${R(d)}
|
|
286
|
-
`}}customElements.define("nostr-profile",O);
|
|
286
|
+
`}}customElements.get("nostr-profile")||customElements.define("nostr-profile",O);export{O as default};
|
|
287
287
|
//# sourceMappingURL=nostr-profile.es.js.map
|
|
@@ -1 +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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"}
|
|
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\nif (!customElements.get('nostr-profile')) {\n customElements.define('nostr-profile', NostrProfile);\n}\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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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zap-utils-
|
|
2
|
-
var Jt=Object.defineProperty;var $t=(e,t,n)=>t in e?Jt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Z=(e,t,n)=>$t(e,typeof t!="symbol"?t+"":t,n);import{N as Gt}from"../assets/nostr-user-component-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zap-utils-BiKkJPt6.js","assets/nostr-service-CA0Qx4nJ.js","assets/nostr-login-service-D2FmscPI.js","assets/preload-helper-D7HrI6pR.js","assets/utils--bxLbhGF.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
var Jt=Object.defineProperty;var $t=(e,t,n)=>t in e?Jt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Z=(e,t,n)=>$t(e,typeof t!="symbol"?t+"":t,n);import{N as Gt}from"../assets/nostr-user-component-r-MUbTL6.js";import{h as Qt,g as St,j as G,e as X,k as kt,i as At,N}from"../assets/base-styles-Dmuzg8I4.js";import"../assets/dialog-component-Da1ZIYh9.js";import{getProfileMetadata as Wt,getZapEndpoint as Xt,fetchInvoice as te,listenForZapReceipt as ee,getBatchedProfileMetadata as ne,extractProfileMetadataContent as Nt,fetchTotalZapAmount as oe}from"../assets/zap-utils-BiKkJPt6.js";import{_ as re}from"../assets/preload-helper-D7HrI6pR.js";import{i as ae}from"../assets/utils--bxLbhGF.js";import{e as ie}from"../assets/nostr-login-service-D2FmscPI.js";import"../assets/user-resolver-ArI0680e.js";import"../assets/nostr-service-CA0Qx4nJ.js";const se=(e="light")=>{const t=e==="dark";return`
|
|
3
3
|
/* === ZAP DIALOG CONTENT STYLES === */
|
|
4
4
|
.zap-dialog-content {
|
|
5
5
|
text-align: center;
|
|
@@ -476,7 +476,7 @@ Minimum version required to store current data is: `+a+`.
|
|
|
476
476
|
${e.map((o,r)=>an(o,t[r],r)).join("")}
|
|
477
477
|
</div>
|
|
478
478
|
</div>
|
|
479
|
-
`}async function ln(e,t){const n=e.querySelector(".zappers-list");if(!n)return;const o=[...new Set(t.map(r=>r.authorPubkey))];console.log("Nostr-Components: Zappers dialog: Fetching profiles for",o.length,"unique authors");try{const r=await ne(o),a=new Map;r.forEach(i=>{a.set(i.id,i.profile)});const s=new Map;o.forEach(i=>{s.set(i,G(i))});for(let i=0;i<t.length;i++){const c=t[i],l=a.get(c.authorPubkey),u=s.get(c.authorPubkey)||c.authorPubkey;let y;if(l){const d=Nt(l);y={...c,authorName:d.display_name||d.name||u,authorPicture:d.picture,authorNpub:u}}else y={...c,authorName:u,authorNpub:u};const p=n.querySelector(`[data-zap-index="${i}"]`);if(p){const d=Vt(y,i);p.outerHTML=d}}console.log("Nostr-Components: Zappers dialog: Progressive enhancement completed for",t.length,"zap entries")}catch(r){console.error("Nostr-Components: Zappers dialog: Error in batched profile enhancement",r),console.log("Nostr-Components: Zappers dialog: Falling back to individual profile fetching"),await un(e,t)}}async function un(e,t){const n=e.querySelector(".zappers-list");if(!n)return;const o=new Map,r=t.map(async(a,s)=>{if(o.has(a.authorPubkey)){const i=o.get(a.authorPubkey);return{index:s,enhanced:{...a,authorName:i.authorName,authorPicture:i.authorPicture,authorNpub:i.authorNpub}}}try{const{getProfileMetadata:i}=await re(async()=>{const{getProfileMetadata:p}=await import("../assets/zap-utils-
|
|
479
|
+
`}async function ln(e,t){const n=e.querySelector(".zappers-list");if(!n)return;const o=[...new Set(t.map(r=>r.authorPubkey))];console.log("Nostr-Components: Zappers dialog: Fetching profiles for",o.length,"unique authors");try{const r=await ne(o),a=new Map;r.forEach(i=>{a.set(i.id,i.profile)});const s=new Map;o.forEach(i=>{s.set(i,G(i))});for(let i=0;i<t.length;i++){const c=t[i],l=a.get(c.authorPubkey),u=s.get(c.authorPubkey)||c.authorPubkey;let y;if(l){const d=Nt(l);y={...c,authorName:d.display_name||d.name||u,authorPicture:d.picture,authorNpub:u}}else y={...c,authorName:u,authorNpub:u};const p=n.querySelector(`[data-zap-index="${i}"]`);if(p){const d=Vt(y,i);p.outerHTML=d}}console.log("Nostr-Components: Zappers dialog: Progressive enhancement completed for",t.length,"zap entries")}catch(r){console.error("Nostr-Components: Zappers dialog: Error in batched profile enhancement",r),console.log("Nostr-Components: Zappers dialog: Falling back to individual profile fetching"),await un(e,t)}}async function un(e,t){const n=e.querySelector(".zappers-list");if(!n)return;const o=new Map,r=t.map(async(a,s)=>{if(o.has(a.authorPubkey)){const i=o.get(a.authorPubkey);return{index:s,enhanced:{...a,authorName:i.authorName,authorPicture:i.authorPicture,authorNpub:i.authorNpub}}}try{const{getProfileMetadata:i}=await re(async()=>{const{getProfileMetadata:p}=await import("../assets/zap-utils-BiKkJPt6.js");return{getProfileMetadata:p}},__vite__mapDeps([0,1,2,3,4])),c=await i(a.authorPubkey),l=Nt(c),u=G(a.authorPubkey),y={...a,authorName:l.display_name||l.name||u,authorPicture:l.picture,authorNpub:u};return o.set(a.authorPubkey,y),{index:s,enhanced:y}}catch(i){console.error("Nostr-Components: Zappers dialog: Error fetching profile for",a.authorPubkey,i);const c=G(a.authorPubkey),l={...a,authorName:c,authorNpub:c};return o.set(a.authorPubkey,l),{index:s,enhanced:l}}});for(const a of r)try{const{index:s,enhanced:i}=await a,c=n.querySelector(`[data-zap-index="${s}"]`);if(c){const l=Vt(i,s);c.outerHTML=l}}catch(s){console.error("Nostr-Components: Zappers dialog: Error processing profile enhancement",s)}}function dn({isLoading:e,isError:t,isSuccess:n,errorMessage:o,buttonText:r,totalZapAmount:a,isAmountLoading:s,hasZaps:i=!1}){if(t)return pn(o||"");if(e)return fn(s);const c=Kt(),l=`<span>${X(r)}</span>`;return jt(c,l,a,s,i)}function fn(e){return jt(Kt(),'<span class="button-text-skeleton"></span>',null,e)}function pn(e){return gn('<div class="error-icon">⚠</div>',X(e))}function gn(e,t){return`
|
|
480
480
|
<div class="nostr-zap-button-container">
|
|
481
481
|
<div class="nostr-zap-button-left-container">
|
|
482
482
|
${e}
|
|
@@ -687,8 +687,8 @@ Minimum version required to store current data is: `+a+`.
|
|
|
687
687
|
max-width: 250px;
|
|
688
688
|
white-space: pre-line;
|
|
689
689
|
}
|
|
690
|
-
`)}class mn extends Gt{constructor(){super();Z(this,"zapActionStatus",this.channel("zapAction"));Z(this,"zapListStatus",this.channel("zapList"));Z(this,"totalZapAmount",null);Z(this,"cachedZapDetails",[]);Z(this,"cachedAmountDialog",null)
|
|
690
|
+
`)}class mn extends Gt{constructor(){super();Z(this,"zapActionStatus",this.channel("zapAction"));Z(this,"zapListStatus",this.channel("zapList"));Z(this,"totalZapAmount",null);Z(this,"cachedZapDetails",[]);Z(this,"cachedAmountDialog",null)}connectedCallback(){var n;(n=super.connectedCallback)==null||n.call(this),this.zapListStatus.get()==N.Idle&&this.initChannelStatus("zapList",N.Loading,{reflectOverall:!1}),this.attachDelegatedListeners(),this.render()}static get observedAttributes(){return[...super.observedAttributes,"text","amount","default-amount","url"]}attributeChangedCallback(n,o,r){o!==r&&(super.attributeChangedCallback(n,o,r),this.render())}disconnectedCallback(){this.cachedAmountDialog&&typeof this.cachedAmountDialog.close=="function"&&this.cachedAmountDialog.close()}onStatusChange(n){this.render()}onUserReady(n,o){this.render(),this.updateZapCount()}validateInputs(){if(!super.validateInputs())return this.zapActionStatus.set(N.Idle),this.zapListStatus.set(N.Idle),!1;const n=this.getAttribute("text"),o=this.getAttribute("amount"),r=this.getAttribute("default-amount"),a=this.getAttribute("url"),s=this.tagName.toLowerCase();let i=null;if(n&&n.length>128)i="Max text length: 128 characters";else if(o){const c=Number(o);isNaN(c)||c<=0?i="Invalid amount":c>21e4&&(i="Amount too high (max 210,000 sats)")}else if(r){const c=Number(r);isNaN(c)||c<=0?i="Invalid default-amount":c>21e4&&(i="Default-amount too high (max 210,000 sats)")}else a&&(At(a)||(i="Invalid URL format"));return i?(this.zapActionStatus.set(N.Error,i),this.zapListStatus.set(N.Error,i),this.userStatus.set(N.Idle),console.error(`Nostr-Components: ${s}: ${i}`),!1):!0}async handleZapClick(){if(this.userStatus.get()===N.Ready){this.zapActionStatus.set(N.Loading),this.render();try{if(await ie(),!this.user){this.zapActionStatus.set(N.Error,"Could not resolve user to zap."),this.render();return}const n=this.getRelays().join(","),o=this.user.npub;this.cachedAmountDialog=await Qe({npub:o,relays:n,cachedDialogComponent:this.cachedAmountDialog,theme:this.theme==="dark"?"dark":"light",fixedAmount:(()=>{const r=this.getAttribute("amount");if(!r)return;const a=Number(r);if(isNaN(a)||a<=0||a>21e4){console.error("Nostr-Components: Zap button: Max zap amount: 210,000 sats");return}return a})(),defaultAmount:(()=>{const r=this.getAttribute("default-amount");if(!r)return 21;const a=Number(r);return isNaN(a)||a<=0||a>21e4?(console.error("Nostr-Components: Zap button: Max zap amount: 210,000 sats"),21):a})(),url:this.getAttribute("url")||void 0,anon:!1}),this.zapActionStatus.set(N.Ready)}catch(n){this.zapActionStatus.set(N.Error,(n==null?void 0:n.message)||"Unable to zap")}finally{this.render()}}}async handleHelpClick(){try{await nn(this.theme==="dark"?"dark":"light")}catch(n){console.error("Error showing help dialog:",n)}}async handleZappersClick(){if(this.cachedZapDetails.length!==0)try{await sn({zapDetails:this.cachedZapDetails,theme:this.theme==="dark"?"dark":"light"})}catch(n){console.error("Nostr-Components: Zap button: Error opening zappers dialog",n)}}attachDelegatedListeners(){this.delegateEvent("click",".nostr-zap-button",n=>{var o,r;(o=n.preventDefault)==null||o.call(n),(r=n.stopPropagation)==null||r.call(n),this.handleZapClick()}),this.delegateEvent("click",".help-icon",n=>{var o,r;(o=n.preventDefault)==null||o.call(n),(r=n.stopPropagation)==null||r.call(n),this.handleHelpClick()}),this.delegateEvent("click",".total-zap-amount",n=>{var o,r;(o=n.preventDefault)==null||o.call(n),(r=n.stopPropagation)==null||r.call(n),this.handleZappersClick()})}async updateZapCount(){if(this.user)try{this.zapListStatus.set(N.Loading),this.render(),await this.ensureNostrConnected();const n=await oe({pubkey:this.user.pubkey,relays:this.getRelays(),url:this.getAttribute("url")||void 0});this.totalZapAmount=n.totalAmount,this.cachedZapDetails=n.zapDetails,this.zapListStatus.set(N.Ready)}catch(n){console.error("Nostr-Components: Zap button: Failed to fetch zap count",n),this.totalZapAmount=null,this.zapListStatus.set(N.Error)}finally{this.render()}}renderContent(){const n=this.userStatus.get()==N.Loading,o=this.zapListStatus.get()==N.Loading,r=this.computeOverall()===N.Error,a=this.errorMessage,s=this.getAttribute("text")||"Zap",i={isLoading:n,isAmountLoading:o,isError:r,isSuccess:!1,errorMessage:a,buttonText:s,totalZapAmount:this.totalZapAmount,hasZaps:this.cachedZapDetails.length>0};this.shadowRoot.innerHTML=`
|
|
691
691
|
${hn()}
|
|
692
692
|
${dn(i)}
|
|
693
|
-
`}}customElements.define("nostr-zap",mn);
|
|
693
|
+
`}}customElements.get("nostr-zap")||customElements.define("nostr-zap",mn);export{mn as default};
|
|
694
694
|
//# sourceMappingURL=nostr-zap.es.js.map
|