nostr-components 0.2.6 → 0.2.7
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/dist/assets/{base-styles-CBypR3FR.js → base-styles-BSEzBDsk.js} +3 -3
- package/dist/assets/{base-styles-CBypR3FR.js.map → base-styles-BSEzBDsk.js.map} +1 -1
- package/dist/assets/{copy-delegation-C4uvRTVM.js → copy-delegation-B7y2q5Kn.js} +5 -5
- package/dist/assets/{copy-delegation-C4uvRTVM.js.map → copy-delegation-B7y2q5Kn.js.map} +1 -1
- package/dist/assets/{dialog-likers-BjiCHFan.js → dialog-likers-BqDn2P_3.js} +4 -4
- package/dist/assets/{dialog-likers-BjiCHFan.js.map → dialog-likers-BqDn2P_3.js.map} +1 -1
- package/dist/assets/{nostr-service-pr_crY62.js → nostr-service-CnaPxjc6.js} +2 -2
- package/dist/assets/{nostr-service-pr_crY62.js.map → nostr-service-CnaPxjc6.js.map} +1 -1
- package/dist/assets/{nostr-user-component-BOdux8_6.js → nostr-user-component-Cbs97dlK.js} +2 -2
- package/dist/assets/{nostr-user-component-BOdux8_6.js.map → nostr-user-component-Cbs97dlK.js.map} +1 -1
- package/dist/assets/{pure-jrVhRVpB.js → pure-DPo-pzxM.js} +2 -2
- package/dist/assets/{pure-jrVhRVpB.js.map → pure-DPo-pzxM.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-C-E6KdwY.js → user-resolver-CMmbtY9Y.js} +2 -2
- package/dist/assets/{user-resolver-C-E6KdwY.js.map → user-resolver-CMmbtY9Y.js.map} +1 -1
- package/dist/assets/{zap-utils-B1sz0Abx.js → zap-utils-KFUD_vTU.js} +2 -2
- package/dist/assets/{zap-utils-B1sz0Abx.js.map → zap-utils-KFUD_vTU.js.map} +1 -1
- package/dist/components/nostr-comment.es.js +5 -5
- package/dist/components/nostr-dm.es.js +2 -2
- package/dist/components/nostr-follow-button.es.js +2 -2
- package/dist/components/nostr-follow-button.es.js.map +1 -1
- package/dist/components/nostr-like.es.js +4 -4
- 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-profile-badge.es.js +3 -3
- package/dist/components/nostr-profile.es.js +2 -2
- package/dist/components/nostr-zap.es.js +4 -4
- package/dist/components/nostr-zap.es.js.map +1 -1
- package/dist/nostr-components.es.js +1 -1
- package/dist/nostr-components.es.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nostr-follow-button.es.js","sources":["../../src/nostr-follow-button/render.ts","../../src/nostr-follow-button/style.ts","../../src/nostr-follow-button/nostr-follow-button.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport {\n getLoadingNostrich,\n getNostrLogo,\n getSuccessAnimation,\n} from '../common/theme';\nimport { escapeHtml } from '../common/utils';\nimport { IRenderOptions } from '../base/render-options';\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\n\nexport interface RenderFollowButtonOptions extends IRenderOptions {\n isFollowed: boolean;\n isFollowing: boolean;\n showAvatar?: boolean;\n user?: NDKUser | null;\n profile?: NDKUserProfile | null;\n customText?: string;\n}\n\nexport function renderFollowButton({\n isLoading,\n isError,\n errorMessage,\n isFollowed,\n isFollowing,\n showAvatar = false,\n user,\n profile,\n customText = 'Follow me on nostr',\n}: RenderFollowButtonOptions): string {\n\n if (isFollowing) {\n return renderFollowing();\n }\n\n if (isLoading) {\n return renderLoading();\n }\n\n if (isError) {\n return renderError(errorMessage || '');\n }\n\n const iconContent = isFollowed\n ? getSuccessAnimation('light')\n : showAvatar && user && profile?.image\n ? `<img src=\"${escapeHtml(profile.image)}\" alt=\"${escapeHtml(profile.name || user.npub)}\" class=\"user-avatar\" />`\n : getNostrLogo();\n const textContent = isFollowed\n ? 'Followed'\n : `<span>${escapeHtml(customText)}</span>`;\n\n return renderContainer(iconContent, textContent);\n}\n\nfunction renderLoading(): string {\n return renderContainer(\n getLoadingNostrich(), // Use default values\n '<span>Loading...</span>'\n );\n}\n\nfunction renderFollowing(): string {\n return renderContainer(\n getLoadingNostrich(), // Use default values\n '<span>Following...</span>'\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-follow-button-container'>\n <div class='nostr-follow-button-left-container'>\n ${leftContent}\n </div>\n <div class='nostr-follow-button-right-container'>\n ${rightContent}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getFollowButtonStyles(): string {\n const customStyles = `\n /* === FOLLOW BUTTON CONTAINER PATTERN === */\n :host {\n /* Icon sizing (overridable) */\n --nostrc-icon-height: 25px;\n --nostrc-icon-width: 25px;\n\n /* Follow button CSS variables (overridable by parent components) */\n --nostrc-follow-btn-padding: var(--nostrc-spacing-sm) var(--nostrc-spacing-md);\n --nostrc-follow-btn-border-radius: var(--nostrc-border-radius-md);\n --nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border);\n --nostrc-follow-btn-min-height: auto;\n --nostrc-follow-btn-width: auto;\n --nostrc-follow-btn-horizontal-alignment: left;\n --nostrc-follow-btn-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-follow-btn-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-follow-btn-font-family: var(--nostrc-font-family-primary);\n --nostrc-follow-btn-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-follow-btn-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-follow-btn-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-follow-btn-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));\n\n /* Make the host the visual button surface */\n display: inline-flex;\n align-items: center;\n justify-content: var(--nostrc-follow-btn-horizontal-alignment);\n gap: var(--nostrc-spacing-md);\n background: var(--nostrc-follow-btn-bg);\n color: var(--nostrc-follow-btn-color);\n border: var(--nostrc-follow-btn-border);\n border-radius: var(--nostrc-follow-btn-border-radius);\n font-family: var(--nostrc-follow-btn-font-family);\n font-size: var(--nostrc-follow-btn-font-size);\n min-height: var(--nostrc-follow-btn-min-height);\n width: var(--nostrc-follow-btn-width);\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-follow-btn-hover-bg);\n color: var(--nostrc-follow-btn-hover-color);\n border: var(--nostrc-follow-btn-hover-border);\n }\n\n /* Focus state for accessibility */\n :host(:focus-visible) {\n outline: 2px solid var(--nostrc-color-primary, #007bff);\n outline-offset: 2px;\n }\n\n :host(.is-error) .nostr-follow-button-container {\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n\n .nostr-follow-button-container {\n display: flex;\n gap: var(--nostrc-spacing-md);\n width: fit-content;\n padding: var(--nostrc-follow-btn-padding);\n }\n \n .nostr-follow-button-right-container {\n margin: auto;\n }\n \n /* SVG Icon Styles */\n .nostr-follow-button-left-container svg {\n fill: var(--nostrc-follow-btn-color);\n display: inline-block;\n vertical-align: middle;\n width: var(--nostrc-icon-width);\n height: var(--nostrc-icon-height);\n }\n\n /* User Avatar Styles */\n .nostr-follow-button-left-container .user-avatar {\n width: var(--nostrc-icon-width);\n height: var(--nostrc-icon-height);\n border-radius: 50%;\n object-fit: cover;\n display: inline-block;\n vertical-align: middle;\n }\n `;\n \n // Use simple component styles - includes design tokens + utilities + custom styles\n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NDKNip07Signer } from '@nostr-dev-kit/ndk';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { renderFollowButton, RenderFollowButtonOptions } from './render';\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { getFollowButtonStyles } from './style';\n\n/**\n * TODO:\n * 1. To have a text attribute. Default value being \"Follow me on Nostr\"\n * 2. show-avatar attribute to show the avatar of the user, instead of nostr logo.\n */\nexport default class NostrFollowButton extends NostrUserComponent {\n\n protected followStatus = this.channel('follow');\n private isFollowed: boolean = false;\n\n static get observedAttributes() {\n return [...super.observedAttributes, 'show-avatar', 'text'];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n this.attachDelegatedListeners();\n this.render();\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 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.render();\n }\n\n /** Private functions */\n private async handleFollowClick() {\n if (this.computeOverall() !== NCStatus.Ready) return;\n const nip07signer = new NDKNip07Signer();\n\n this.followStatus.set(NCStatus.Loading);\n this.render();\n\n try {\n const ndk = this.nostrService.getNDK();\n ndk.signer = nip07signer;\n\n if (!this.user) {\n this.followStatus.set(NCStatus.Error, \"Could not resolve user to follow.\");\n this.render();\n return;\n\n }\n\n const signer = ndk.signer;\n if (!signer) {\n throw new Error('No signer available');\n }\n const signedUser = await signer.user();\n if (signedUser) {\n await signedUser.follow(this.user);\n }\n\n this.isFollowed = true;\n this.followStatus.set(NCStatus.Ready);\n } catch (err) {\n\n const error = err as Error;\n let errorMessage;\n if (error.message?.includes('NIP-07')) {\n errorMessage = `Looks like you don't have any nostr signing browser extension.\n Please checkout the following video to setup a signer extension - <a href=\"https://youtu.be/8thRYn14nB0?t=310\" target=\"_blank\">Video</a>`;\n } else {\n errorMessage = 'Please authorize, click the button to try again!';\n }\n this.followStatus.set(NCStatus.Error, errorMessage);\n } finally {\n this.render();\n }\n }\n\n private attachDelegatedListeners() {\n this.delegateEvent('click', '.nostr-follow-button-container', (e) => {\n e.preventDefault?.();\n e.stopPropagation?.();\n void this.handleFollowClick();\n });\n }\n\n protected renderContent() {\n const isLoading = this.computeOverall() == NCStatus.Loading;\n const isFollowing = this.followStatus.get() == NCStatus.Loading;\n const isError = this.computeOverall() === NCStatus.Error;\n const errorMessage = super.renderError(this.errorMessage);\n const showAvatar = this.hasAttribute('show-avatar');\n const customText = this.getAttribute('text') || 'Follow me on nostr';\n\n const renderOptions: RenderFollowButtonOptions = {\n isLoading : isLoading,\n isError : isError,\n errorMessage: errorMessage,\n isFollowed : this.isFollowed,\n isFollowing : isFollowing,\n showAvatar : showAvatar,\n user : this.user,\n profile : this.profile,\n customText : customText,\n };\n\n this.shadowRoot!.innerHTML = `\n ${getFollowButtonStyles()}\n ${renderFollowButton(renderOptions)}\n `\n }\n}\n\ncustomElements.define('nostr-follow-button', NostrFollowButton);\n"],"names":["renderFollowButton","isLoading","isError","errorMessage","isFollowed","isFollowing","showAvatar","user","profile","customText","renderFollowing","renderLoading","renderError","iconContent","getSuccessAnimation","escapeHtml","getNostrLogo","textContent","renderContainer","getLoadingNostrich","leftContent","rightContent","getFollowButtonStyles","getComponentStyles","NostrFollowButton","NostrUserComponent","__publicField","_a","name","oldValue","newValue","_status","_user","_profile","NCStatus","nip07signer","NDKNip07Signer","ndk","signer","signedUser","err","error","e","_b","renderOptions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nostr-follow-button.es.js","sources":["../../src/nostr-follow-button/render.ts","../../src/nostr-follow-button/style.ts","../../src/nostr-follow-button/nostr-follow-button.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport {\n getLoadingNostrich,\n getNostrLogo,\n getSuccessAnimation,\n} from '../common/theme';\nimport { escapeHtml } from '../common/utils';\nimport { IRenderOptions } from '../base/render-options';\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\n\nexport interface RenderFollowButtonOptions extends IRenderOptions {\n isFollowed: boolean;\n isFollowing: boolean;\n showAvatar?: boolean;\n user?: NDKUser | null;\n profile?: NDKUserProfile | null;\n customText?: string;\n}\n\nexport function renderFollowButton({\n isLoading,\n isError,\n errorMessage,\n isFollowed,\n isFollowing,\n showAvatar = false,\n user,\n profile,\n customText = 'Follow me on nostr',\n}: RenderFollowButtonOptions): string {\n\n if (isFollowing) {\n return renderFollowing();\n }\n\n if (isLoading) {\n return renderLoading();\n }\n\n if (isError) {\n return renderError(errorMessage || '');\n }\n\n const iconContent = isFollowed\n ? getSuccessAnimation('light')\n : showAvatar && user && profile?.image\n ? `<img src=\"${escapeHtml(profile.image)}\" alt=\"${escapeHtml(profile.name || user.npub)}\" class=\"user-avatar\" />`\n : getNostrLogo();\n const textContent = isFollowed\n ? 'Followed'\n : `<span>${escapeHtml(customText)}</span>`;\n\n return renderContainer(iconContent, textContent);\n}\n\nfunction renderLoading(): string {\n return renderContainer(\n getLoadingNostrich(), // Use default values\n '<span>Loading...</span>'\n );\n}\n\nfunction renderFollowing(): string {\n return renderContainer(\n getLoadingNostrich(), // Use default values\n '<span>Following...</span>'\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-follow-button-container'>\n <div class='nostr-follow-button-left-container'>\n ${leftContent}\n </div>\n <div class='nostr-follow-button-right-container'>\n ${rightContent}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getFollowButtonStyles(): string {\n const customStyles = `\n /* === FOLLOW BUTTON CONTAINER PATTERN === */\n :host {\n /* Icon sizing (overridable) */\n --nostrc-icon-height: 25px;\n --nostrc-icon-width: 25px;\n\n /* Follow button CSS variables (overridable by parent components) */\n --nostrc-follow-btn-padding: var(--nostrc-spacing-sm) var(--nostrc-spacing-md);\n --nostrc-follow-btn-border-radius: var(--nostrc-border-radius-md);\n --nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border);\n --nostrc-follow-btn-min-height: auto;\n --nostrc-follow-btn-width: auto;\n --nostrc-follow-btn-horizontal-alignment: left;\n --nostrc-follow-btn-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-follow-btn-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-follow-btn-font-family: var(--nostrc-font-family-primary);\n --nostrc-follow-btn-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-follow-btn-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-follow-btn-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-follow-btn-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));\n\n /* Make the host the visual button surface */\n display: inline-flex;\n align-items: center;\n justify-content: var(--nostrc-follow-btn-horizontal-alignment);\n gap: var(--nostrc-spacing-md);\n background: var(--nostrc-follow-btn-bg);\n color: var(--nostrc-follow-btn-color);\n border: var(--nostrc-follow-btn-border);\n border-radius: var(--nostrc-follow-btn-border-radius);\n font-family: var(--nostrc-follow-btn-font-family);\n font-size: var(--nostrc-follow-btn-font-size);\n min-height: var(--nostrc-follow-btn-min-height);\n width: var(--nostrc-follow-btn-width);\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-follow-btn-hover-bg);\n color: var(--nostrc-follow-btn-hover-color);\n border: var(--nostrc-follow-btn-hover-border);\n }\n\n /* Focus state for accessibility */\n :host(:focus-visible) {\n outline: 2px solid var(--nostrc-color-primary, #007bff);\n outline-offset: 2px;\n }\n\n :host(.is-error) .nostr-follow-button-container {\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n\n .nostr-follow-button-container {\n display: flex;\n gap: var(--nostrc-spacing-md);\n width: fit-content;\n padding: var(--nostrc-follow-btn-padding);\n }\n \n .nostr-follow-button-right-container {\n margin: auto;\n }\n \n /* SVG Icon Styles */\n .nostr-follow-button-left-container svg {\n fill: var(--nostrc-follow-btn-color);\n display: inline-block;\n vertical-align: middle;\n width: var(--nostrc-icon-width);\n height: var(--nostrc-icon-height);\n }\n\n /* User Avatar Styles */\n .nostr-follow-button-left-container .user-avatar {\n width: var(--nostrc-icon-width);\n height: var(--nostrc-icon-height);\n border-radius: 50%;\n object-fit: cover;\n display: inline-block;\n vertical-align: middle;\n }\n `;\n \n // Use simple component styles - includes design tokens + utilities + custom styles\n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NDKNip07Signer } from '@nostr-dev-kit/ndk';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { renderFollowButton, RenderFollowButtonOptions } from './render';\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { getFollowButtonStyles } from './style';\n\n/**\n * TODO:\n * 1. To have a text attribute. Default value being \"Follow me on Nostr\"\n * 2. show-avatar attribute to show the avatar of the user, instead of nostr logo.\n */\nexport default class NostrFollowButton extends NostrUserComponent {\n\n protected followStatus = this.channel('follow');\n private isFollowed: boolean = false;\n\n static get observedAttributes() {\n return [...super.observedAttributes, 'show-avatar', 'text'];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n this.attachDelegatedListeners();\n this.render();\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 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.render();\n }\n\n /** Private functions */\n private async handleFollowClick() {\n if (this.computeOverall() !== NCStatus.Ready) return;\n const nip07signer = new NDKNip07Signer();\n\n this.followStatus.set(NCStatus.Loading);\n this.render();\n\n try {\n const ndk = this.nostrService.getNDK();\n ndk.signer = nip07signer;\n\n if (!this.user) {\n this.followStatus.set(NCStatus.Error, \"Could not resolve user to follow.\");\n this.render();\n return;\n\n }\n\n const signer = ndk.signer;\n if (!signer) {\n throw new Error('No signer available');\n }\n const signedUser = await signer.user();\n if (signedUser) {\n await signedUser.follow(this.user);\n }\n\n this.isFollowed = true;\n this.followStatus.set(NCStatus.Ready);\n } catch (err) {\n\n const error = err as Error;\n let errorMessage;\n if (error.message?.includes('NIP-07')) {\n errorMessage = `Looks like you don't have any nostr signing browser extension.\n Please checkout the following video to setup a signer extension - <a href=\"https://youtu.be/8thRYn14nB0?t=310\" target=\"_blank\">Video</a>`;\n } else {\n errorMessage = 'Please authorize, click the button to try again!';\n }\n this.followStatus.set(NCStatus.Error, errorMessage);\n } finally {\n this.render();\n }\n }\n\n private attachDelegatedListeners() {\n this.delegateEvent('click', '.nostr-follow-button-container', (e) => {\n e.preventDefault?.();\n e.stopPropagation?.();\n void this.handleFollowClick();\n });\n }\n\n protected renderContent() {\n const isLoading = this.computeOverall() == NCStatus.Loading;\n const isFollowing = this.followStatus.get() == NCStatus.Loading;\n const isError = this.computeOverall() === NCStatus.Error;\n const errorMessage = super.renderError(this.errorMessage);\n const showAvatar = this.hasAttribute('show-avatar');\n const customText = this.getAttribute('text') || 'Follow me on nostr';\n\n const renderOptions: RenderFollowButtonOptions = {\n isLoading : isLoading,\n isError : isError,\n errorMessage: errorMessage,\n isFollowed : this.isFollowed,\n isFollowing : isFollowing,\n showAvatar : showAvatar,\n user : this.user,\n profile : this.profile,\n customText : customText,\n };\n\n this.shadowRoot!.innerHTML = `\n ${getFollowButtonStyles()}\n ${renderFollowButton(renderOptions)}\n `\n }\n}\n\ncustomElements.define('nostr-follow-button', NostrFollowButton);\n"],"names":["renderFollowButton","isLoading","isError","errorMessage","isFollowed","isFollowing","showAvatar","user","profile","customText","renderFollowing","renderLoading","renderError","iconContent","getSuccessAnimation","escapeHtml","getNostrLogo","textContent","renderContainer","getLoadingNostrich","leftContent","rightContent","getFollowButtonStyles","getComponentStyles","NostrFollowButton","NostrUserComponent","__publicField","_a","name","oldValue","newValue","_status","_user","_profile","NCStatus","nip07signer","NDKNip07Signer","ndk","signer","signedUser","err","error","e","_b","renderOptions"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/dialog-likers-
|
|
2
|
-
var m=Object.defineProperty;var w=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var d=(r,e,t)=>w(r,typeof e!="symbol"?e+"":e,t);import{_ as y}from"../assets/preload-helper-D7HrI6pR.js";import{e as b,g as L,
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/dialog-likers-BqDn2P_3.js","assets/preload-helper-D7HrI6pR.js","assets/dialog-component-Da1ZIYh9.js","assets/zap-utils-KFUD_vTU.js","assets/nostr-service-CnaPxjc6.js","assets/utils--bxLbhGF.js","assets/base-styles-BSEzBDsk.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
var m=Object.defineProperty;var w=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var d=(r,e,t)=>w(r,typeof e!="symbol"?e+"":e,t);import{_ as y}from"../assets/preload-helper-D7HrI6pR.js";import{e as b,g as L,c as x,N as i,i as C}from"../assets/base-styles-BSEzBDsk.js";import{S as f,d as g}from"../assets/nostr-service-CnaPxjc6.js";import"../assets/dialog-component-Da1ZIYh9.js";function S({isLoading:r,isError:e,errorMessage:t,buttonText:n,isLiked:o,likeCount:s,hasLikes:a=!1,isCountLoading:l=!1,theme:u="light"}){if(e)return E(t||"");const c=N(o,u),h=o?"<span>Liked</span>":`<span>${b(n)}</span>`;return U(c,h,s,a,o,r,l)}function E(r){return A('<div class="error-icon">⚠</div>',b(r))}function A(r,e){return`
|
|
3
3
|
<div class="nostr-like-button-container">
|
|
4
4
|
<div class="nostr-like-button-left-container">
|
|
5
5
|
${r}
|
|
@@ -289,8 +289,8 @@ var m=Object.defineProperty;var w=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configura
|
|
|
289
289
|
<li>Works with a browser extension like <a href="https://getalby.com" target="_blank" rel="noopener noreferrer">Alby</a> or nos2x</li>
|
|
290
290
|
</ul>
|
|
291
291
|
</div>
|
|
292
|
-
`,e.showModal()};new TextDecoder("utf-8");new TextEncoder;function k(r){r.indexOf("://")===-1&&(r="wss://"+r);let e=new URL(r);return e.pathname=e.pathname.replace(/\/+/g,"/"),e.pathname.endsWith("/")&&(e.pathname=e.pathname.slice(0,-1)),(e.port==="80"&&e.protocol==="ws:"||e.port==="443"&&e.protocol==="wss:")&&(e.port=""),e.searchParams.sort(),e.hash="",e.toString()}async function I(r,e){const t=k(r),n=new f;try{const o=await n.querySync(e,{kinds:[17],"#k":["web"],"#i":[t],limit:1e3}),s=[];let a=0,l=0;for(const c of o)s.push({authorPubkey:c.pubkey,date:new Date(c.created_at*1e3),content:c.content}),c.content==="-"?l++:a++;return s.sort((c,h)=>h.date.getTime()-c.date.getTime()),{totalCount:a-l,likeDetails:s,likedCount:a,dislikedCount:l}}catch(o){throw o instanceof Error?o:new Error(String(o))}finally{n.close(e)}}function v(r,e){return{kind:17,content:e,tags:[["k","web"],["i",r]],created_at:Math.floor(Date.now()/1e3)}}function M(r){return v(r,"+")}function H(r){return v(r,"-")}async function P(r,e,t){const n=new f,o=r;try{const s=await n.querySync(t,{kinds:[17],authors:[e],"#k":["web"],"#i":[o],limit:1});if(s.length===0)return!1;const a=s[0];return a.content==="+"||a.content===""}catch(s){return console.error("Nostr-Components: Like button: Error checking user like status",s),!1}finally{n.close(t)}}async function T(){try{if(typeof window<"u"&&window.nostr)return await window.nostr.getPublicKey()}catch(r){console.error("Nostr-Components: Like button: Error getting user pubkey",r)}return null}async function p(r){try{if(typeof window<"u"&&window.nostr)return await window.nostr.signEvent(r);throw new Error("NIP-07 extension not available")}catch(e){throw console.error("Nostr-Components: Like button: Error signing event",e),e}}function _(){return typeof window<"u"&&!!window.nostr}class F extends x{constructor(){super();d(this,"likeActionStatus",this.channel("likeAction"));d(this,"likeListStatus",this.channel("likeList"));d(this,"currentUrl","");d(this,"isLiked",!1);d(this,"likeCount",0);d(this,"cachedLikeDetails",null);d(this,"loadSeq",0)}connectedCallback(){var t;(t=super.connectedCallback)==null||t.call(this),this.likeListStatus.get()===i.Idle&&this.initChannelStatus("likeList",i.Loading,{reflectOverall:!1}),this.attachDelegatedListeners(),this.render()}static get observedAttributes(){return[...super.observedAttributes,"url","text"]}attributeChangedCallback(t,n,o){n!==o&&(super.attributeChangedCallback(t,n,o),(t==="url"||t==="text")&&(this.likeActionStatus.set(i.Ready),this.likeListStatus.set(i.Loading),this.isLiked=!1,this.errorMessage="",this.updateLikeCount(),this.render()))}validateInputs(){if(!super.validateInputs())return this.likeActionStatus.set(i.Idle),this.likeListStatus.set(i.Idle),!1;const t=this.getAttribute("url"),n=this.getAttribute("text"),o=this.tagName.toLowerCase();let s=null;return t&&(C(t)||(s="Invalid URL format")),n&&n.length>32&&(s="Max text length: 32 characters"),s?(this.likeActionStatus.set(i.Error,s),this.likeListStatus.set(i.Error,s),console.error(`Nostr-Components: ${o}: ${s}`),!1):!0}onStatusChange(t){this.render()}onNostrRelaysConnected(){this.updateLikeCount(),this.render()}ensureCurrentUrl(){this.currentUrl||(this.currentUrl=k(this.getAttribute("url")||window.location.href))}async updateLikeCount(){const t=++this.loadSeq;try{await this.ensureNostrConnected(),this.currentUrl=k(this.getAttribute("url")||window.location.href),this.likeListStatus.set(i.Loading),this.render();const n=await I(this.currentUrl,this.getRelays());if(t!==this.loadSeq)return;this.likeCount=n.totalCount,this.cachedLikeDetails=n,this.likeListStatus.set(i.Ready)}catch(n){console.error("[NostrLike] Failed to fetch like count:",n),this.likeListStatus.set(i.Error,"Failed to load likes")}finally{this.render()}}async handleLikeClick(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}if(this.likeActionStatus.set(i.Loading),!_()){this.likeActionStatus.set(i.Error,"Please install a Nostr browser extension (Alby, nos2x, etc.)"),this.render();return}try{const t=await T();t&&(this.isLiked=await P(this.currentUrl,t,this.getRelays()))}catch(t){console.error("[NostrLike] Failed to check user like status:",t),this.likeActionStatus.set(i.Error,"Failed to check user like status")}finally{this.render()}if(this.isLiked){if(!window.confirm("You have already liked this. Do you want to unlike it?")){this.likeActionStatus.set(i.Ready),this.render();return}await this.handleUnlike()}else await this.handleLike()}async handleLike(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}this.likeActionStatus.set(i.Loading),this.render();try{const t=M(this.currentUrl),n=await p(t);await new g(this.nostrService.getNDK(),n).publish(),this.isLiked=!0,this.likeCount++,this.likeActionStatus.set(i.Ready),await this.updateLikeCount()}catch(t){console.error("[NostrLike] Failed to like:",t),this.isLiked=!1,this.likeCount--;const n=t instanceof Error?t.message:"Failed to like";this.likeActionStatus.set(i.Error,n)}finally{this.render()}}async handleUnlike(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}this.likeActionStatus.set(i.Loading),this.render();try{const t=H(this.currentUrl),n=await p(t);await new g(this.nostrService.getNDK(),n).publish(),this.isLiked=!1,this.likeCount>0&&this.likeCount--,this.likeActionStatus.set(i.Ready),await this.updateLikeCount()}catch(t){console.error("[NostrLike] Failed to unlike:",t),this.isLiked=!0,this.likeCount++;const n=t instanceof Error?t.message:"Failed to unlike";this.likeActionStatus.set(i.Error,n)}finally{this.render()}}async handleCountClick(){if(!(this.likeCount===0||!this.cachedLikeDetails))try{const{openLikersDialog:t}=await y(async()=>{const{openLikersDialog:n}=await import("../assets/dialog-likers-
|
|
292
|
+
`,e.showModal()};new TextDecoder("utf-8");new TextEncoder;function k(r){r.indexOf("://")===-1&&(r="wss://"+r);let e=new URL(r);return e.pathname=e.pathname.replace(/\/+/g,"/"),e.pathname.endsWith("/")&&(e.pathname=e.pathname.slice(0,-1)),(e.port==="80"&&e.protocol==="ws:"||e.port==="443"&&e.protocol==="wss:")&&(e.port=""),e.searchParams.sort(),e.hash="",e.toString()}async function I(r,e){const t=k(r),n=new f;try{const o=await n.querySync(e,{kinds:[17],"#k":["web"],"#i":[t],limit:1e3}),s=[];let a=0,l=0;for(const c of o)s.push({authorPubkey:c.pubkey,date:new Date(c.created_at*1e3),content:c.content}),c.content==="-"?l++:a++;return s.sort((c,h)=>h.date.getTime()-c.date.getTime()),{totalCount:a-l,likeDetails:s,likedCount:a,dislikedCount:l}}catch(o){throw o instanceof Error?o:new Error(String(o))}finally{n.close(e)}}function v(r,e){return{kind:17,content:e,tags:[["k","web"],["i",r]],created_at:Math.floor(Date.now()/1e3)}}function M(r){return v(r,"+")}function H(r){return v(r,"-")}async function P(r,e,t){const n=new f,o=r;try{const s=await n.querySync(t,{kinds:[17],authors:[e],"#k":["web"],"#i":[o],limit:1});if(s.length===0)return!1;const a=s[0];return a.content==="+"||a.content===""}catch(s){return console.error("Nostr-Components: Like button: Error checking user like status",s),!1}finally{n.close(t)}}async function T(){try{if(typeof window<"u"&&window.nostr)return await window.nostr.getPublicKey()}catch(r){console.error("Nostr-Components: Like button: Error getting user pubkey",r)}return null}async function p(r){try{if(typeof window<"u"&&window.nostr)return await window.nostr.signEvent(r);throw new Error("NIP-07 extension not available")}catch(e){throw console.error("Nostr-Components: Like button: Error signing event",e),e}}function _(){return typeof window<"u"&&!!window.nostr}class F extends x{constructor(){super();d(this,"likeActionStatus",this.channel("likeAction"));d(this,"likeListStatus",this.channel("likeList"));d(this,"currentUrl","");d(this,"isLiked",!1);d(this,"likeCount",0);d(this,"cachedLikeDetails",null);d(this,"loadSeq",0)}connectedCallback(){var t;(t=super.connectedCallback)==null||t.call(this),this.likeListStatus.get()===i.Idle&&this.initChannelStatus("likeList",i.Loading,{reflectOverall:!1}),this.attachDelegatedListeners(),this.render()}static get observedAttributes(){return[...super.observedAttributes,"url","text"]}attributeChangedCallback(t,n,o){n!==o&&(super.attributeChangedCallback(t,n,o),(t==="url"||t==="text")&&(this.likeActionStatus.set(i.Ready),this.likeListStatus.set(i.Loading),this.isLiked=!1,this.errorMessage="",this.updateLikeCount(),this.render()))}validateInputs(){if(!super.validateInputs())return this.likeActionStatus.set(i.Idle),this.likeListStatus.set(i.Idle),!1;const t=this.getAttribute("url"),n=this.getAttribute("text"),o=this.tagName.toLowerCase();let s=null;return t&&(C(t)||(s="Invalid URL format")),n&&n.length>32&&(s="Max text length: 32 characters"),s?(this.likeActionStatus.set(i.Error,s),this.likeListStatus.set(i.Error,s),console.error(`Nostr-Components: ${o}: ${s}`),!1):!0}onStatusChange(t){this.render()}onNostrRelaysConnected(){this.updateLikeCount(),this.render()}ensureCurrentUrl(){this.currentUrl||(this.currentUrl=k(this.getAttribute("url")||window.location.href))}async updateLikeCount(){const t=++this.loadSeq;try{await this.ensureNostrConnected(),this.currentUrl=k(this.getAttribute("url")||window.location.href),this.likeListStatus.set(i.Loading),this.render();const n=await I(this.currentUrl,this.getRelays());if(t!==this.loadSeq)return;this.likeCount=n.totalCount,this.cachedLikeDetails=n,this.likeListStatus.set(i.Ready)}catch(n){console.error("[NostrLike] Failed to fetch like count:",n),this.likeListStatus.set(i.Error,"Failed to load likes")}finally{this.render()}}async handleLikeClick(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}if(this.likeActionStatus.set(i.Loading),!_()){this.likeActionStatus.set(i.Error,"Please install a Nostr browser extension (Alby, nos2x, etc.)"),this.render();return}try{const t=await T();t&&(this.isLiked=await P(this.currentUrl,t,this.getRelays()))}catch(t){console.error("[NostrLike] Failed to check user like status:",t),this.likeActionStatus.set(i.Error,"Failed to check user like status")}finally{this.render()}if(this.isLiked){if(!window.confirm("You have already liked this. Do you want to unlike it?")){this.likeActionStatus.set(i.Ready),this.render();return}await this.handleUnlike()}else await this.handleLike()}async handleLike(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}this.likeActionStatus.set(i.Loading),this.render();try{const t=M(this.currentUrl),n=await p(t);await new g(this.nostrService.getNDK(),n).publish(),this.isLiked=!0,this.likeCount++,this.likeActionStatus.set(i.Ready),await this.updateLikeCount()}catch(t){console.error("[NostrLike] Failed to like:",t),this.isLiked=!1,this.likeCount--;const n=t instanceof Error?t.message:"Failed to like";this.likeActionStatus.set(i.Error,n)}finally{this.render()}}async handleUnlike(){if(this.ensureCurrentUrl(),!this.currentUrl){this.likeActionStatus.set(i.Error,"Invalid URL"),this.render();return}this.likeActionStatus.set(i.Loading),this.render();try{const t=H(this.currentUrl),n=await p(t);await new g(this.nostrService.getNDK(),n).publish(),this.isLiked=!1,this.likeCount>0&&this.likeCount--,this.likeActionStatus.set(i.Ready),await this.updateLikeCount()}catch(t){console.error("[NostrLike] Failed to unlike:",t),this.isLiked=!0,this.likeCount++;const n=t instanceof Error?t.message:"Failed to unlike";this.likeActionStatus.set(i.Error,n)}finally{this.render()}}async handleCountClick(){if(!(this.likeCount===0||!this.cachedLikeDetails))try{const{openLikersDialog:t}=await y(async()=>{const{openLikersDialog:n}=await import("../assets/dialog-likers-BqDn2P_3.js");return{openLikersDialog:n}},__vite__mapDeps([0,1,2,3,4,5,6]));await t({likeDetails:this.cachedLikeDetails.likeDetails,theme:this.theme==="dark"?"dark":"light"})}catch(t){console.error("[NostrLike] Error opening likers dialog:",t)}}async handleHelpClick(){try{await $(this.theme==="dark"?"dark":"light")}catch(t){console.error("[NostrLike] Error showing help dialog:",t)}}attachDelegatedListeners(){this.delegateEvent("click",".nostr-like-button",t=>{var n,o;(n=t.preventDefault)==null||n.call(t),(o=t.stopPropagation)==null||o.call(t),this.handleLikeClick()}),this.delegateEvent("click",".like-count",t=>{var n,o;(n=t.preventDefault)==null||n.call(t),(o=t.stopPropagation)==null||o.call(t),this.handleCountClick()}),this.delegateEvent("click",".help-icon",t=>{var n,o;(n=t.preventDefault)==null||n.call(t),(o=t.stopPropagation)==null||o.call(t),this.handleHelpClick()})}renderContent(){const t=this.likeActionStatus.get()===i.Loading||this.conn.get()===i.Loading,n=this.likeListStatus.get()===i.Loading,o=this.computeOverall()===i.Error,s=this.errorMessage,a=this.getAttribute("text")||"Like",l={isLoading:t,isError:o,errorMessage:s,buttonText:a,isLiked:this.isLiked,likeCount:this.likeCount,hasLikes:this.likeCount>0,isCountLoading:n,theme:this.theme};this.shadowRoot.innerHTML=`
|
|
293
293
|
${z()}
|
|
294
294
|
${S(l)}
|
|
295
|
-
`}}customElements.define("nostr-like",F);
|
|
295
|
+
`}}customElements.define("nostr-like",F);export{F as default};
|
|
296
296
|
//# sourceMappingURL=nostr-like.es.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var P=Object.defineProperty;var H=(h,f,t)=>f in h?P(h,f,{enumerable:!0,configurable:!0,writable:!0,value:t}):h[f]=t;var a=(h,f,t)=>H(h,typeof f!="symbol"?f+"":f,t);import{_ as L}from"../assets/preload-helper-D7HrI6pR.js";import{
|
|
1
|
+
var P=Object.defineProperty;var H=(h,f,t)=>f in h?P(h,f,{enumerable:!0,configurable:!0,writable:!0,value:t}):h[f]=t;var a=(h,f,t)=>H(h,typeof f!="symbol"?f+"":f,t);import{_ as L}from"../assets/preload-helper-D7HrI6pR.js";import{b as A,c as D,a as v,N as $,d as M,e as S}from"../assets/nostr-service-CnaPxjc6.js";import{a as R,b as C}from"../assets/theme-BN1Bvweb.js";import{r as U}from"../assets/nip05-utils-BNBHUmkr.js";import"../assets/icons-Dr_d9MII.js";function K(h){try{return new Date(h*1e3).toLocaleString()}catch{return""}}function _(h){try{const f=Date.now(),t=h*1e3,r=f-t,e=Math.floor(r/1e3);if(e<60)return"just now";if(e<3600){const s=Math.floor(e/60);return`${s} ${s===1?"min":"mins"} ago`}if(e<86400){const s=Math.floor(e/3600);return`${s} ${s===1?"hour":"hours"} ago`}if(e<2592e3){const s=Math.floor(e/86400);return`${s} ${s===1?"day":"days"} ago`}if(e<31536e3){const s=Math.floor(e/2592e3);return`${s} ${s===1?"month":"months"} ago`}const o=Math.floor(e/31536e3);return`${o} ${o===1?"year":"years"} ago`}catch{return""}}function I(h){return h==="me"||h==="them"?h:"them"}function y(h){return h==null?"":String(h).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function O({theme:h,recipientNpub:f,recipientName:t,recipientPicture:r,message:e,messages:o,isLoading:s,isFinding:l,isError:p,errorMessage:i,currentUserName:d,currentUserPicture:b,showWelcome:k,welcomeText:u,startChatText:n,maxMessageLength:g}){const m=typeof g=="number"?g:1e3,N=(e||"").length,E=Math.max(0,m-N),T=E<=10?"nostr-chat-char-counter warn":"nostr-chat-char-counter";return`
|
|
2
2
|
<div class="nostr-chat-container ${p?"nostr-chat-error":""}">
|
|
3
3
|
<div class="nostr-chat-header">
|
|
4
4
|
<div class="nostr-chat-header-left">
|
|
@@ -495,7 +495,7 @@ var P=Object.defineProperty;var H=(h,f,t)=>f in h?P(h,f,{enumerable:!0,configura
|
|
|
495
495
|
text-align: center;
|
|
496
496
|
}
|
|
497
497
|
</style>
|
|
498
|
-
`}const x=class x extends HTMLElement{constructor(){super();a(this,"rendered",!1);a(this,"nostrService",A.getInstance());a(this,"dmSubscription",null);a(this,"theme","light");a(this,"recipientNpub",null);a(this,"recipientNip05",null);a(this,"recipientName",null);a(this,"recipientPicture",null);a(this,"recipientPubkey",null);a(this,"message","");a(this,"messages",[]);a(this,"currentUserPubkey",null);a(this,"currentUserNpub",null);a(this,"currentUserName",null);a(this,"currentUserPicture",null);a(this,"displayType","embed");a(this,"isOpen",!1);a(this,"showWelcome",!1);a(this,"welcomeText",x.DEFAULT_WELCOME_TEXT);a(this,"startChatText",x.DEFAULT_START_CHAT_TEXT);a(this,"onlineText",x.DEFAULT_ONLINE_TEXT);a(this,"helpText",x.DEFAULT_HELP_TEXT);a(this,"MESSAGE_MAX_LENGTH",1e3);a(this,"isLoading",!1);a(this,"isFinding",!1);a(this,"isError",!1);a(this,"errorMessage","");a(this,"keySupplier",null);a(this,"boundHandleFind",null);a(this,"boundHandleSend",null);a(this,"boundHandleTextareaChange",null);a(this,"boundHandleLauncherClick",null);a(this,"boundHandleCloseClick",null);a(this,"boundHandleStartChat",null);a(this,"boundHandleNpubKeydown",null);a(this,"resubscribeTimer",null);a(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(r=>r.trim()).filter(r=>r.length>0).filter((r,e,o)=>o.indexOf(r)===e):D});a(this,"getTheme",()=>{const t=this.getAttribute("theme"),r=(t||"").toLowerCase();r==="light"||r==="dark"?this.theme=r:(t&&console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'. Falling back to 'light'.`),this.theme="light")});a(this,"getRecipient",()=>{const t=this.getAttribute("pubkey");if(t)try{this.recipientPubkey=t,this.recipientNpub=v.npubEncode(t),this.lookupRecipient(this.recipientNpub);return}catch(o){const s=`Invalid recipient pubkey "${t}": ${o instanceof Error?o.message:String(o)}`;this.isError=!0,this.errorMessage=s,console.error("nostr-live-chat:",s,o),this.render();return}const r=this.getAttribute("nip05");if(r){this.recipientNip05=r,this.lookupRecipientByNip05();return}const e=this.getAttribute("npub");e&&(this.recipientNpub=e,this.lookupRecipient())});this.attachShadow({mode:"open"})}async getCurrentUserInfo(){var t,r,e,o,s,l,p,i,d,b;try{const k=this.nostrService.getNDK();let u=null;if(typeof window<"u"&&window.nostr){const n=window.nostr;console.log("Nostr extension found, checking for public key...");try{const g=!!(n.enable&&typeof n.enable=="function"&&n.getPublicKey&&typeof n.getPublicKey=="function");if(console.log("Is this nos2x extension?",g),g){console.log("Using nos2x specific flow");try{await n.enable(),console.log("nos2x extension enabled"),await new Promise(m=>setTimeout(m,100));const c=await n.getPublicKey();console.log("nos2x returned pubkey:",c),c&&typeof c=="string"&&c.length===64&&(u=c,console.log("Successfully got pubkey from nos2x:",u))}catch(c){console.error("Error with nos2x extension:",c)}}else{if(typeof n.enable=="function"){console.log("Attempting to enable generic extension...");try{await n.enable(),console.log("Extension enabled successfully")}catch(c){console.warn("Extension enable failed, continuing anyway:",c)}}if(typeof n.getPublicKey=="function"){console.log("Calling getPublicKey()...");try{u=await n.getPublicKey(),console.log("Got pubkey from extension:",u)}catch(c){console.error("Error getting public key:",c)}}else if(n.getPublicKey){console.log("Found getPublicKey property, resolving...");try{u=await Promise.resolve(n.getPublicKey),console.log("Got pubkey from extension (property):",u)}catch(c){console.error("Error resolving public key:",c)}}}}catch(g){console.error("Error in extension interaction:",g)}}if(!u){let n=null;if(this.keySupplier)try{n=await this.keySupplier()}catch{}if(n)try{const{NDKPrivateKeySigner:g}=await L(async()=>{const{NDKPrivateKeySigner:E}=await import("../assets/nostr-service-pr_crY62.js").then(T=>T.k);return{NDKPrivateKeySigner:E}},[]);let c=n;n.startsWith("nsec")&&(c=v.decode(n).data),u=(await new g(c).user()).pubkey}catch{}}if(u){this.currentUserPubkey=u,this.currentUserNpub=v.npubEncode(u),console.log("Got pubkey from extension and will use it:",u);try{const n=k.getUser({pubkey:u});console.log("Fetching profile for user:",u),await n.fetchProfile(),console.log("Fetched profile:",n.profile),this.currentUserName=((t=n.profile)==null?void 0:t.displayName)||((r=n.profile)==null?void 0:r.name)||((e=this.currentUserNpub)==null?void 0:e.substring(0,10))||null,this.currentUserPicture=((o=n.profile)==null?void 0:o.image)||null,this.currentUserName||console.warn("No username found in profile"),this.currentUserPicture||console.warn("No profile picture found"),console.log("Profile info set:",{name:this.currentUserName,picture:this.currentUserPicture,npub:this.currentUserNpub})}catch(n){console.error("Error fetching profile:",n),this.currentUserName=((s=this.currentUserNpub)==null?void 0:s.substring(0,10))||null}this.render()}else{console.log("Checking for direct nos2x logs in console...");try{if(await new Promise(n=>setTimeout(n,500)),typeof window<"u"&&window.nostr){console.log("Trying direct call to extension again...");try{const n=await window.nostr.getPublicKey();if(n&&typeof n=="string"){console.log("Got pubkey on second try:",n),this.currentUserPubkey=n,this.currentUserNpub=v.npubEncode(n);try{const g=k.getUser({pubkey:n});console.log("Fetching profile for user on second try:",n),await g.fetchProfile(),console.log("Fetched profile on second try:",g.profile),this.currentUserName=((l=g.profile)==null?void 0:l.displayName)||((p=g.profile)==null?void 0:p.name)||((i=this.currentUserNpub)==null?void 0:i.substring(0,10))||null,this.currentUserPicture=((d=g.profile)==null?void 0:d.image)||null,this.render();return}catch(g){console.error("Error fetching profile on second try:",g),this.currentUserName=((b=this.currentUserNpub)==null?void 0:b.substring(0,10))||null,this.render();return}}}catch(n){console.error("Error getting pubkey on direct second try:",n)}}}catch(n){console.error("Error in fallback pubkey detection:",n)}console.warn("No pubkey available from extension - trying fallback method")}}catch{}}getDisplayType(){const t=this.getAttribute("display-type"),r=["fab","bottom-bar","full","embed"],o=(t?String(t):"").toLowerCase(),s=r.includes(o)?o:"embed";this.displayType=s,this.displayType==="full"?this.isOpen=!0:this.displayType==="fab"||this.displayType==="bottom-bar"?(this.isOpen===void 0||this.isOpen===null)&&(this.isOpen=!1):this.isOpen=!1,this.getAttribute("display-type")!==s&&this.setAttribute("display-type",s)}connectedCallback(){if(!this.rendered){this.getTheme(),this.getDisplayType();const t=this.getAttribute("welcome-text");t&&(this.welcomeText=t);const r=this.getAttribute("start-chat-text");r&&(this.startChatText=r);const e=this.getAttribute("online-text");e&&(this.onlineText=e);const o=this.getAttribute("help-text");o&&(this.helpText=o),this.getRecipient(),this.nostrService.connectToNostr(this.getRelays()),this.getCurrentUserInfo(),this.render(),this.rendered=!0}}static get observedAttributes(){return["npub","pubkey","nip05","relays","theme","display-type","welcome-text","start-chat-text","online-text","help-text","history-days"]}unsubscribeFromDms(){if(this.dmSubscription){try{this.dmSubscription.stop()}catch{}this.dmSubscription=null}this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}clearRecipientAndChatState(){this.recipientPubkey=null,this.recipientNpub=null,this.recipientNip05=null,this.recipientName=null,this.recipientPicture=null,this.messages=[],this.message="",this.showWelcome=!1,this.isLoading=!1,this.isFinding=!1,this.isError=!1,this.errorMessage=""}attributeChangedCallback(t,r,e){if(this.rendered)if(t==="npub"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNpub=e,this.lookupRecipient());return}else if(t==="pubkey"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}if(e!==r){this.unsubscribeFromDms(),this.clearRecipientAndChatState();try{this.recipientPubkey=e,this.recipientNpub=v.npubEncode(e),this.lookupRecipient(this.recipientNpub)}catch{}}return}else if(t==="nip05"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNip05=e,this.lookupRecipientByNip05());return}else if(t==="relays"){if(e!==r){const o=this.getRelays();this.recipientPubkey&&!this.showWelcome?(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.unsubscribeFromDms(),this.nostrService.connectToNostr(o),this.subscribeToDms()},300)):this.nostrService.connectToNostr(o)}}else t==="theme"?(this.getTheme(),this.render()):t==="display-type"?(this.getDisplayType(),this.render()):t==="welcome-text"?(this.welcomeText=e!==null?e:x.DEFAULT_WELCOME_TEXT,this.render()):t==="start-chat-text"?(this.startChatText=e!==null?e:x.DEFAULT_START_CHAT_TEXT,this.render()):t==="online-text"?(this.onlineText=e!==null?e:x.DEFAULT_ONLINE_TEXT,this.render()):t==="help-text"?(this.helpText=e!==null?e:x.DEFAULT_HELP_TEXT,this.render()):t==="history-days"&&e!==r&&this.recipientPubkey&&!this.showWelcome&&(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.subscribeToDms()},250))}async lookupRecipient(t){var r,e,o;this.unsubscribeFromDms(),this.messages=[],this.showWelcome=!1,this.isFinding=!0,this.render();try{const s=t||this.recipientNpub;if(!s)return;const{type:l,data:p}=v.decode(s);if(l!=="npub")throw new Error("Invalid npub");this.recipientPubkey=p;const i=this.nostrService.getNDK().getUser({pubkey:this.recipientPubkey});await i.fetchProfile(),this.recipientName=((r=i.profile)==null?void 0:r.displayName)||((e=i.profile)==null?void 0:e.name)||s.substring(0,10),this.recipientPicture=((o=i.profile)==null?void 0:o.image)||null,this.showWelcome=!0,this.messages=[],this.isError=!1,this.errorMessage="",this.render()}catch(s){this.isError=!0,this.errorMessage=s.message}finally{this.isFinding=!1,this.render()}}async lookupRecipientByNip05(t){this.isFinding=!0,this.render();try{const r=t||this.recipientNip05;if(!r)return;const e=await U(r),o=v.npubEncode(e);this.recipientNpub=o,this.isError=!1,this.errorMessage="",await this.lookupRecipient(o)}catch(r){this.isError=!0,this.errorMessage=r.message}finally{this.isFinding=!1,this.render()}}handleFindClick(){const r=this.shadowRoot.querySelector(".nostr-chat-npub-input").value.trim();this.isError=!1,this.errorMessage="",this.render(),r&&(r.startsWith("npub")?(this.recipientNpub=r,this.lookupRecipient()):r.includes("@")?(this.recipientNip05=r,this.lookupRecipientByNip05()):(this.isError=!0,this.errorMessage="Invalid input. Please provide an npub or nip05 address.",this.render()))}async handleSendClick(){var r,e;if(!this.message.trim()||!this.recipientPubkey)return;if(this.message.length>this.MESSAGE_MAX_LENGTH){this.isError=!0,this.errorMessage=`Message is too long (max ${this.MESSAGE_MAX_LENGTH} characters).`,this.render();return}this.isLoading=!0,this.render();let t=null;try{const o=this.nostrService.getNDK();let s;if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey&&window.nostr.signEvent)try{s=new $}catch(d){console.error("Error creating NIP-07 signer:",d),this.isError=!0,this.errorMessage=`Error connecting to Nostr extension: ${d.message}`,this.isLoading=!1,this.render();return}if(!s)throw new Error("No signer available. Please install a NIP-07 extension or set a private key.");o.signer=s;const l=new M(o,{kind:S.EncryptedDirectMessage,tags:[["p",this.recipientPubkey]],created_at:Math.floor(Date.now()/1e3)});let p=!1;if(typeof((e=(r=window.nostr)==null?void 0:r.nip04)==null?void 0:e.encrypt)=="function")try{l.content=await window.nostr.nip04.encrypt(this.recipientPubkey,this.message.trim()),p=!0}catch(d){console.error("NIP-07 encryption failed, falling back to local encryption:",d)}if(!p)throw new Error("No private key available for encryption. Please use a NIP-07 extension.");t=`temp_${Date.now()}`,this.messages.push({id:t,text:this.message,sender:"me",timestamp:l.created_at,status:"sending"}),this.message="",this.render(),await l.publish();const i=this.messages.find(d=>d.id===t);i&&(this.messages.find(b=>b.id===l.id&&b.id!==t)?this.messages=this.messages.filter(b=>b.id!==t):(i.id=l.id,i.status="sent"),this.render())}catch(o){if(this.isError=!0,this.errorMessage=o.message,t){const s=this.messages.find(l=>l.id===t);s&&(s.status="failed"),this.render()}}finally{this.isLoading=!1,this.render()}}handleTextareaChange(t){var s;const r=t.target;this.message=r.value;const e=Math.max(0,this.MESSAGE_MAX_LENGTH-this.message.length),o=(s=this.shadowRoot)==null?void 0:s.querySelector(".nostr-chat-char-counter");o&&(o.textContent=`${e} chars left`,o.classList.toggle("warn",e<=10))}handleStartChat(){this.showWelcome=!1,this.subscribeToDms(),this.render()}async subscribeToDms(){if(this.dmSubscription&&this.dmSubscription.stop(),!this.recipientPubkey)return;let t=null;try{if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey)t={pubkey:await window.nostr.getPublicKey()};else{let i=null;if(this.keySupplier)try{i=await this.keySupplier()}catch{}if(i){const{NDKPrivateKeySigner:d}=await L(async()=>{const{NDKPrivateKeySigner:u}=await import("../assets/nostr-service-pr_crY62.js").then(n=>n.k);return{NDKPrivateKeySigner:u}},[]);let b=i;i.startsWith("nsec")&&(b=v.decode(i).data),t=await new d(b).user()}}}catch(i){console.error("Failed to determine current user for subscription",i)}if(!t){this.isError=!0,this.errorMessage="No signer available. Please install a NIP-07 extension or set a private key to start the chat.",this.render();return}this.messages=[];const r=this.getAttribute("history-days");let e;if(!r)e=void 0;else if(r.toLowerCase()==="all"||parseInt(r,10)<=0)e=void 0;else{const i=Math.max(1,parseInt(r,10)||30);e=Math.floor((Date.now()-i*24*60*60*1e3)/1e3)}const o={kinds:[S.EncryptedDirectMessage],"#p":[t.pubkey],authors:[this.recipientPubkey]},s={kinds:[S.EncryptedDirectMessage],"#p":[this.recipientPubkey],authors:[t.pubkey]},l=e!==void 0?{...o,since:e}:o,p=e!==void 0?{...s,since:e}:s;this.dmSubscription=this.nostrService.getNDK().subscribe([l,p],{closeOnEose:!1,groupable:!1}),this.dmSubscription.on("event",async i=>{var d;try{!this.currentUserPubkey&&t&&(this.currentUserPubkey=t.pubkey,this.currentUserNpub=v.npubEncode(t.pubkey));const b=i.pubkey===t.pubkey,k=b?(d=i.tags.find(c=>c[0]==="p"))==null?void 0:d[1]:i.pubkey;if(!k){try{console.debug("nostr-live-chat: skipping event with missing peer",i.id)}catch{}return}if(k!==this.recipientPubkey)return;if(b){const c=this.messages.find(m=>m.id===i.id);if(c){c.status==="sending"&&(c.status="sent",this.render());return}}let u="";if(!k){try{console.debug("nostr-live-chat: missing peer prior to decrypt, skipping",i.id)}catch{}return}if(!i.content||i.content.trim()===""){try{console.debug("nostr-live-chat: missing or empty content prior to decrypt, skipping",i.id)}catch{}return}if(window.nostr&&window.nostr.nip04&&typeof window.nostr.nip04.decrypt=="function")try{u=await window.nostr.nip04.decrypt(k,i.content)}catch(c){console.error("Failed to decrypt DM content:",c);return}else throw new Error("No private key available for decryption. Please use a NIP-07 extension.");if(b){const c=this.messages.find(m=>m.status==="sending"&&m.sender==="me"&&m.text===u&&Math.abs(m.timestamp-i.created_at)<2);if(c){c.id=i.id,c.status="sent",this.render();return}}const n={id:i.id,text:u,sender:b?"me":"them",timestamp:i.created_at,status:"sent"};this.messages.find(c=>c.id===n.id)||(this.messages.push(n),this.messages.sort((c,m)=>c.timestamp-m.timestamp),this.render())}catch(b){console.error("Failed to decrypt DM content:",b)}})}attachEventListeners(){const t=this.shadowRoot.querySelector(".nostr-chat-launcher");t&&(this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick),this.boundHandleLauncherClick=()=>{this.isOpen=!0,this.render()},t.addEventListener("click",this.boundHandleLauncherClick));const r=this.shadowRoot.querySelector(".nostr-chat-close-btn");r&&(this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick),this.boundHandleCloseClick=i=>{i==null||i.stopPropagation(),(this.displayType==="fab"||this.displayType==="bottom-bar")&&(this.isOpen=!1),this.render()},r.addEventListener("click",this.boundHandleCloseClick));const e=this.shadowRoot.querySelector(".nostr-chat-find-btn");e&&(this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind),this.boundHandleFind=this.handleFindClick.bind(this),e.addEventListener("click",this.boundHandleFind));const o=this.shadowRoot.querySelector(".nostr-chat-send-btn");o&&(this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend),this.boundHandleSend=this.handleSendClick.bind(this),o.addEventListener("click",this.boundHandleSend));const s=this.shadowRoot.querySelector(".nostr-chat-start-btn");s&&(this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat),this.boundHandleStartChat=this.handleStartChat.bind(this),s.addEventListener("click",this.boundHandleStartChat));const l=this.shadowRoot.querySelector(".nostr-chat-textarea");l&&(this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange),this.boundHandleTextareaChange=this.handleTextareaChange.bind(this),l.addEventListener("input",this.boundHandleTextareaChange));const p=this.shadowRoot.querySelector(".nostr-chat-npub-input");p&&(this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.boundHandleNpubKeydown=i=>{i.key==="Enter"&&this.handleFindClick()},p.addEventListener("keydown",this.boundHandleNpubKeydown))}disconnectedCallback(){var i,d,b,k,u,n,g;this.dmSubscription&&this.dmSubscription.stop();const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".nostr-chat-launcher");t&&this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick);const r=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-close-btn");r&&this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick);const e=(b=this.shadowRoot)==null?void 0:b.querySelector(".nostr-chat-find-btn");e&&this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind);const o=(k=this.shadowRoot)==null?void 0:k.querySelector(".nostr-chat-send-btn");o&&this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend);const s=(u=this.shadowRoot)==null?void 0:u.querySelector(".nostr-chat-start-btn");s&&this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat);const l=(n=this.shadowRoot)==null?void 0:n.querySelector(".nostr-chat-textarea");l&&this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange);const p=(g=this.shadowRoot)==null?void 0:g.querySelector(".nostr-chat-npub-input");p&&this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}setKeySupplier(t){this.keySupplier=t}escapeHtml(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}render(){const t={theme:this.theme,recipientNpub:this.recipientNpub,recipientName:this.recipientName,recipientPicture:this.recipientPicture,message:this.message,messages:this.messages,isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,errorMessage:this.errorMessage,currentUserName:this.currentUserName,currentUserPicture:this.currentUserPicture,showWelcome:this.showWelcome,welcomeText:this.welcomeText,startChatText:this.startChatText,onlineText:this.onlineText,helpText:this.helpText,maxMessageLength:this.MESSAGE_MAX_LENGTH},r=z(this.theme),{onlineText:e,helpText:o,...s}=t,l=O(s);let p=r;this.displayType==="embed"?p+=l:this.displayType==="full"?p+=`
|
|
498
|
+
`}const x=class x extends HTMLElement{constructor(){super();a(this,"rendered",!1);a(this,"nostrService",A.getInstance());a(this,"dmSubscription",null);a(this,"theme","light");a(this,"recipientNpub",null);a(this,"recipientNip05",null);a(this,"recipientName",null);a(this,"recipientPicture",null);a(this,"recipientPubkey",null);a(this,"message","");a(this,"messages",[]);a(this,"currentUserPubkey",null);a(this,"currentUserNpub",null);a(this,"currentUserName",null);a(this,"currentUserPicture",null);a(this,"displayType","embed");a(this,"isOpen",!1);a(this,"showWelcome",!1);a(this,"welcomeText",x.DEFAULT_WELCOME_TEXT);a(this,"startChatText",x.DEFAULT_START_CHAT_TEXT);a(this,"onlineText",x.DEFAULT_ONLINE_TEXT);a(this,"helpText",x.DEFAULT_HELP_TEXT);a(this,"MESSAGE_MAX_LENGTH",1e3);a(this,"isLoading",!1);a(this,"isFinding",!1);a(this,"isError",!1);a(this,"errorMessage","");a(this,"keySupplier",null);a(this,"boundHandleFind",null);a(this,"boundHandleSend",null);a(this,"boundHandleTextareaChange",null);a(this,"boundHandleLauncherClick",null);a(this,"boundHandleCloseClick",null);a(this,"boundHandleStartChat",null);a(this,"boundHandleNpubKeydown",null);a(this,"resubscribeTimer",null);a(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(r=>r.trim()).filter(r=>r.length>0).filter((r,e,o)=>o.indexOf(r)===e):D});a(this,"getTheme",()=>{const t=this.getAttribute("theme"),r=(t||"").toLowerCase();r==="light"||r==="dark"?this.theme=r:(t&&console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'. Falling back to 'light'.`),this.theme="light")});a(this,"getRecipient",()=>{const t=this.getAttribute("pubkey");if(t)try{this.recipientPubkey=t,this.recipientNpub=v.npubEncode(t),this.lookupRecipient(this.recipientNpub);return}catch(o){const s=`Invalid recipient pubkey "${t}": ${o instanceof Error?o.message:String(o)}`;this.isError=!0,this.errorMessage=s,console.error("nostr-live-chat:",s,o),this.render();return}const r=this.getAttribute("nip05");if(r){this.recipientNip05=r,this.lookupRecipientByNip05();return}const e=this.getAttribute("npub");e&&(this.recipientNpub=e,this.lookupRecipient())});this.attachShadow({mode:"open"})}async getCurrentUserInfo(){var t,r,e,o,s,l,p,i,d,b;try{const k=this.nostrService.getNDK();let u=null;if(typeof window<"u"&&window.nostr){const n=window.nostr;console.log("Nostr extension found, checking for public key...");try{const g=!!(n.enable&&typeof n.enable=="function"&&n.getPublicKey&&typeof n.getPublicKey=="function");if(console.log("Is this nos2x extension?",g),g){console.log("Using nos2x specific flow");try{await n.enable(),console.log("nos2x extension enabled"),await new Promise(m=>setTimeout(m,100));const c=await n.getPublicKey();console.log("nos2x returned pubkey:",c),c&&typeof c=="string"&&c.length===64&&(u=c,console.log("Successfully got pubkey from nos2x:",u))}catch(c){console.error("Error with nos2x extension:",c)}}else{if(typeof n.enable=="function"){console.log("Attempting to enable generic extension...");try{await n.enable(),console.log("Extension enabled successfully")}catch(c){console.warn("Extension enable failed, continuing anyway:",c)}}if(typeof n.getPublicKey=="function"){console.log("Calling getPublicKey()...");try{u=await n.getPublicKey(),console.log("Got pubkey from extension:",u)}catch(c){console.error("Error getting public key:",c)}}else if(n.getPublicKey){console.log("Found getPublicKey property, resolving...");try{u=await Promise.resolve(n.getPublicKey),console.log("Got pubkey from extension (property):",u)}catch(c){console.error("Error resolving public key:",c)}}}}catch(g){console.error("Error in extension interaction:",g)}}if(!u){let n=null;if(this.keySupplier)try{n=await this.keySupplier()}catch{}if(n)try{const{NDKPrivateKeySigner:g}=await L(async()=>{const{NDKPrivateKeySigner:E}=await import("../assets/nostr-service-CnaPxjc6.js").then(T=>T.k);return{NDKPrivateKeySigner:E}},[]);let c=n;n.startsWith("nsec")&&(c=v.decode(n).data),u=(await new g(c).user()).pubkey}catch{}}if(u){this.currentUserPubkey=u,this.currentUserNpub=v.npubEncode(u),console.log("Got pubkey from extension and will use it:",u);try{const n=k.getUser({pubkey:u});console.log("Fetching profile for user:",u),await n.fetchProfile(),console.log("Fetched profile:",n.profile),this.currentUserName=((t=n.profile)==null?void 0:t.displayName)||((r=n.profile)==null?void 0:r.name)||((e=this.currentUserNpub)==null?void 0:e.substring(0,10))||null,this.currentUserPicture=((o=n.profile)==null?void 0:o.image)||null,this.currentUserName||console.warn("No username found in profile"),this.currentUserPicture||console.warn("No profile picture found"),console.log("Profile info set:",{name:this.currentUserName,picture:this.currentUserPicture,npub:this.currentUserNpub})}catch(n){console.error("Error fetching profile:",n),this.currentUserName=((s=this.currentUserNpub)==null?void 0:s.substring(0,10))||null}this.render()}else{console.log("Checking for direct nos2x logs in console...");try{if(await new Promise(n=>setTimeout(n,500)),typeof window<"u"&&window.nostr){console.log("Trying direct call to extension again...");try{const n=await window.nostr.getPublicKey();if(n&&typeof n=="string"){console.log("Got pubkey on second try:",n),this.currentUserPubkey=n,this.currentUserNpub=v.npubEncode(n);try{const g=k.getUser({pubkey:n});console.log("Fetching profile for user on second try:",n),await g.fetchProfile(),console.log("Fetched profile on second try:",g.profile),this.currentUserName=((l=g.profile)==null?void 0:l.displayName)||((p=g.profile)==null?void 0:p.name)||((i=this.currentUserNpub)==null?void 0:i.substring(0,10))||null,this.currentUserPicture=((d=g.profile)==null?void 0:d.image)||null,this.render();return}catch(g){console.error("Error fetching profile on second try:",g),this.currentUserName=((b=this.currentUserNpub)==null?void 0:b.substring(0,10))||null,this.render();return}}}catch(n){console.error("Error getting pubkey on direct second try:",n)}}}catch(n){console.error("Error in fallback pubkey detection:",n)}console.warn("No pubkey available from extension - trying fallback method")}}catch{}}getDisplayType(){const t=this.getAttribute("display-type"),r=["fab","bottom-bar","full","embed"],o=(t?String(t):"").toLowerCase(),s=r.includes(o)?o:"embed";this.displayType=s,this.displayType==="full"?this.isOpen=!0:this.displayType==="fab"||this.displayType==="bottom-bar"?(this.isOpen===void 0||this.isOpen===null)&&(this.isOpen=!1):this.isOpen=!1,this.getAttribute("display-type")!==s&&this.setAttribute("display-type",s)}connectedCallback(){if(!this.rendered){this.getTheme(),this.getDisplayType();const t=this.getAttribute("welcome-text");t&&(this.welcomeText=t);const r=this.getAttribute("start-chat-text");r&&(this.startChatText=r);const e=this.getAttribute("online-text");e&&(this.onlineText=e);const o=this.getAttribute("help-text");o&&(this.helpText=o),this.getRecipient(),this.nostrService.connectToNostr(this.getRelays()),this.getCurrentUserInfo(),this.render(),this.rendered=!0}}static get observedAttributes(){return["npub","pubkey","nip05","relays","theme","display-type","welcome-text","start-chat-text","online-text","help-text","history-days"]}unsubscribeFromDms(){if(this.dmSubscription){try{this.dmSubscription.stop()}catch{}this.dmSubscription=null}this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}clearRecipientAndChatState(){this.recipientPubkey=null,this.recipientNpub=null,this.recipientNip05=null,this.recipientName=null,this.recipientPicture=null,this.messages=[],this.message="",this.showWelcome=!1,this.isLoading=!1,this.isFinding=!1,this.isError=!1,this.errorMessage=""}attributeChangedCallback(t,r,e){if(this.rendered)if(t==="npub"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNpub=e,this.lookupRecipient());return}else if(t==="pubkey"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}if(e!==r){this.unsubscribeFromDms(),this.clearRecipientAndChatState();try{this.recipientPubkey=e,this.recipientNpub=v.npubEncode(e),this.lookupRecipient(this.recipientNpub)}catch{}}return}else if(t==="nip05"){if(e===null){this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.render();return}e!==r&&(this.unsubscribeFromDms(),this.clearRecipientAndChatState(),this.recipientNip05=e,this.lookupRecipientByNip05());return}else if(t==="relays"){if(e!==r){const o=this.getRelays();this.recipientPubkey&&!this.showWelcome?(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.unsubscribeFromDms(),this.nostrService.connectToNostr(o),this.subscribeToDms()},300)):this.nostrService.connectToNostr(o)}}else t==="theme"?(this.getTheme(),this.render()):t==="display-type"?(this.getDisplayType(),this.render()):t==="welcome-text"?(this.welcomeText=e!==null?e:x.DEFAULT_WELCOME_TEXT,this.render()):t==="start-chat-text"?(this.startChatText=e!==null?e:x.DEFAULT_START_CHAT_TEXT,this.render()):t==="online-text"?(this.onlineText=e!==null?e:x.DEFAULT_ONLINE_TEXT,this.render()):t==="help-text"?(this.helpText=e!==null?e:x.DEFAULT_HELP_TEXT,this.render()):t==="history-days"&&e!==r&&this.recipientPubkey&&!this.showWelcome&&(this.resubscribeTimer&&clearTimeout(this.resubscribeTimer),this.resubscribeTimer=window.setTimeout(()=>{this.subscribeToDms()},250))}async lookupRecipient(t){var r,e,o;this.unsubscribeFromDms(),this.messages=[],this.showWelcome=!1,this.isFinding=!0,this.render();try{const s=t||this.recipientNpub;if(!s)return;const{type:l,data:p}=v.decode(s);if(l!=="npub")throw new Error("Invalid npub");this.recipientPubkey=p;const i=this.nostrService.getNDK().getUser({pubkey:this.recipientPubkey});await i.fetchProfile(),this.recipientName=((r=i.profile)==null?void 0:r.displayName)||((e=i.profile)==null?void 0:e.name)||s.substring(0,10),this.recipientPicture=((o=i.profile)==null?void 0:o.image)||null,this.showWelcome=!0,this.messages=[],this.isError=!1,this.errorMessage="",this.render()}catch(s){this.isError=!0,this.errorMessage=s.message}finally{this.isFinding=!1,this.render()}}async lookupRecipientByNip05(t){this.isFinding=!0,this.render();try{const r=t||this.recipientNip05;if(!r)return;const e=await U(r),o=v.npubEncode(e);this.recipientNpub=o,this.isError=!1,this.errorMessage="",await this.lookupRecipient(o)}catch(r){this.isError=!0,this.errorMessage=r.message}finally{this.isFinding=!1,this.render()}}handleFindClick(){const r=this.shadowRoot.querySelector(".nostr-chat-npub-input").value.trim();this.isError=!1,this.errorMessage="",this.render(),r&&(r.startsWith("npub")?(this.recipientNpub=r,this.lookupRecipient()):r.includes("@")?(this.recipientNip05=r,this.lookupRecipientByNip05()):(this.isError=!0,this.errorMessage="Invalid input. Please provide an npub or nip05 address.",this.render()))}async handleSendClick(){var r,e;if(!this.message.trim()||!this.recipientPubkey)return;if(this.message.length>this.MESSAGE_MAX_LENGTH){this.isError=!0,this.errorMessage=`Message is too long (max ${this.MESSAGE_MAX_LENGTH} characters).`,this.render();return}this.isLoading=!0,this.render();let t=null;try{const o=this.nostrService.getNDK();let s;if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey&&window.nostr.signEvent)try{s=new $}catch(d){console.error("Error creating NIP-07 signer:",d),this.isError=!0,this.errorMessage=`Error connecting to Nostr extension: ${d.message}`,this.isLoading=!1,this.render();return}if(!s)throw new Error("No signer available. Please install a NIP-07 extension or set a private key.");o.signer=s;const l=new M(o,{kind:S.EncryptedDirectMessage,tags:[["p",this.recipientPubkey]],created_at:Math.floor(Date.now()/1e3)});let p=!1;if(typeof((e=(r=window.nostr)==null?void 0:r.nip04)==null?void 0:e.encrypt)=="function")try{l.content=await window.nostr.nip04.encrypt(this.recipientPubkey,this.message.trim()),p=!0}catch(d){console.error("NIP-07 encryption failed, falling back to local encryption:",d)}if(!p)throw new Error("No private key available for encryption. Please use a NIP-07 extension.");t=`temp_${Date.now()}`,this.messages.push({id:t,text:this.message,sender:"me",timestamp:l.created_at,status:"sending"}),this.message="",this.render(),await l.publish();const i=this.messages.find(d=>d.id===t);i&&(this.messages.find(b=>b.id===l.id&&b.id!==t)?this.messages=this.messages.filter(b=>b.id!==t):(i.id=l.id,i.status="sent"),this.render())}catch(o){if(this.isError=!0,this.errorMessage=o.message,t){const s=this.messages.find(l=>l.id===t);s&&(s.status="failed"),this.render()}}finally{this.isLoading=!1,this.render()}}handleTextareaChange(t){var s;const r=t.target;this.message=r.value;const e=Math.max(0,this.MESSAGE_MAX_LENGTH-this.message.length),o=(s=this.shadowRoot)==null?void 0:s.querySelector(".nostr-chat-char-counter");o&&(o.textContent=`${e} chars left`,o.classList.toggle("warn",e<=10))}handleStartChat(){this.showWelcome=!1,this.subscribeToDms(),this.render()}async subscribeToDms(){if(this.dmSubscription&&this.dmSubscription.stop(),!this.recipientPubkey)return;let t=null;try{if(typeof window<"u"&&window.nostr&&window.nostr.getPublicKey)t={pubkey:await window.nostr.getPublicKey()};else{let i=null;if(this.keySupplier)try{i=await this.keySupplier()}catch{}if(i){const{NDKPrivateKeySigner:d}=await L(async()=>{const{NDKPrivateKeySigner:u}=await import("../assets/nostr-service-CnaPxjc6.js").then(n=>n.k);return{NDKPrivateKeySigner:u}},[]);let b=i;i.startsWith("nsec")&&(b=v.decode(i).data),t=await new d(b).user()}}}catch(i){console.error("Failed to determine current user for subscription",i)}if(!t){this.isError=!0,this.errorMessage="No signer available. Please install a NIP-07 extension or set a private key to start the chat.",this.render();return}this.messages=[];const r=this.getAttribute("history-days");let e;if(!r)e=void 0;else if(r.toLowerCase()==="all"||parseInt(r,10)<=0)e=void 0;else{const i=Math.max(1,parseInt(r,10)||30);e=Math.floor((Date.now()-i*24*60*60*1e3)/1e3)}const o={kinds:[S.EncryptedDirectMessage],"#p":[t.pubkey],authors:[this.recipientPubkey]},s={kinds:[S.EncryptedDirectMessage],"#p":[this.recipientPubkey],authors:[t.pubkey]},l=e!==void 0?{...o,since:e}:o,p=e!==void 0?{...s,since:e}:s;this.dmSubscription=this.nostrService.getNDK().subscribe([l,p],{closeOnEose:!1,groupable:!1}),this.dmSubscription.on("event",async i=>{var d;try{!this.currentUserPubkey&&t&&(this.currentUserPubkey=t.pubkey,this.currentUserNpub=v.npubEncode(t.pubkey));const b=i.pubkey===t.pubkey,k=b?(d=i.tags.find(c=>c[0]==="p"))==null?void 0:d[1]:i.pubkey;if(!k){try{console.debug("nostr-live-chat: skipping event with missing peer",i.id)}catch{}return}if(k!==this.recipientPubkey)return;if(b){const c=this.messages.find(m=>m.id===i.id);if(c){c.status==="sending"&&(c.status="sent",this.render());return}}let u="";if(!k){try{console.debug("nostr-live-chat: missing peer prior to decrypt, skipping",i.id)}catch{}return}if(!i.content||i.content.trim()===""){try{console.debug("nostr-live-chat: missing or empty content prior to decrypt, skipping",i.id)}catch{}return}if(window.nostr&&window.nostr.nip04&&typeof window.nostr.nip04.decrypt=="function")try{u=await window.nostr.nip04.decrypt(k,i.content)}catch(c){console.error("Failed to decrypt DM content:",c);return}else throw new Error("No private key available for decryption. Please use a NIP-07 extension.");if(b){const c=this.messages.find(m=>m.status==="sending"&&m.sender==="me"&&m.text===u&&Math.abs(m.timestamp-i.created_at)<2);if(c){c.id=i.id,c.status="sent",this.render();return}}const n={id:i.id,text:u,sender:b?"me":"them",timestamp:i.created_at,status:"sent"};this.messages.find(c=>c.id===n.id)||(this.messages.push(n),this.messages.sort((c,m)=>c.timestamp-m.timestamp),this.render())}catch(b){console.error("Failed to decrypt DM content:",b)}})}attachEventListeners(){const t=this.shadowRoot.querySelector(".nostr-chat-launcher");t&&(this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick),this.boundHandleLauncherClick=()=>{this.isOpen=!0,this.render()},t.addEventListener("click",this.boundHandleLauncherClick));const r=this.shadowRoot.querySelector(".nostr-chat-close-btn");r&&(this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick),this.boundHandleCloseClick=i=>{i==null||i.stopPropagation(),(this.displayType==="fab"||this.displayType==="bottom-bar")&&(this.isOpen=!1),this.render()},r.addEventListener("click",this.boundHandleCloseClick));const e=this.shadowRoot.querySelector(".nostr-chat-find-btn");e&&(this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind),this.boundHandleFind=this.handleFindClick.bind(this),e.addEventListener("click",this.boundHandleFind));const o=this.shadowRoot.querySelector(".nostr-chat-send-btn");o&&(this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend),this.boundHandleSend=this.handleSendClick.bind(this),o.addEventListener("click",this.boundHandleSend));const s=this.shadowRoot.querySelector(".nostr-chat-start-btn");s&&(this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat),this.boundHandleStartChat=this.handleStartChat.bind(this),s.addEventListener("click",this.boundHandleStartChat));const l=this.shadowRoot.querySelector(".nostr-chat-textarea");l&&(this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange),this.boundHandleTextareaChange=this.handleTextareaChange.bind(this),l.addEventListener("input",this.boundHandleTextareaChange));const p=this.shadowRoot.querySelector(".nostr-chat-npub-input");p&&(this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.boundHandleNpubKeydown=i=>{i.key==="Enter"&&this.handleFindClick()},p.addEventListener("keydown",this.boundHandleNpubKeydown))}disconnectedCallback(){var i,d,b,k,u,n,g;this.dmSubscription&&this.dmSubscription.stop();const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".nostr-chat-launcher");t&&this.boundHandleLauncherClick&&t.removeEventListener("click",this.boundHandleLauncherClick);const r=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-close-btn");r&&this.boundHandleCloseClick&&r.removeEventListener("click",this.boundHandleCloseClick);const e=(b=this.shadowRoot)==null?void 0:b.querySelector(".nostr-chat-find-btn");e&&this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind);const o=(k=this.shadowRoot)==null?void 0:k.querySelector(".nostr-chat-send-btn");o&&this.boundHandleSend&&o.removeEventListener("click",this.boundHandleSend);const s=(u=this.shadowRoot)==null?void 0:u.querySelector(".nostr-chat-start-btn");s&&this.boundHandleStartChat&&s.removeEventListener("click",this.boundHandleStartChat);const l=(n=this.shadowRoot)==null?void 0:n.querySelector(".nostr-chat-textarea");l&&this.boundHandleTextareaChange&&l.removeEventListener("input",this.boundHandleTextareaChange);const p=(g=this.shadowRoot)==null?void 0:g.querySelector(".nostr-chat-npub-input");p&&this.boundHandleNpubKeydown&&p.removeEventListener("keydown",this.boundHandleNpubKeydown),this.resubscribeTimer&&(clearTimeout(this.resubscribeTimer),this.resubscribeTimer=null)}setKeySupplier(t){this.keySupplier=t}escapeHtml(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}render(){const t={theme:this.theme,recipientNpub:this.recipientNpub,recipientName:this.recipientName,recipientPicture:this.recipientPicture,message:this.message,messages:this.messages,isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,errorMessage:this.errorMessage,currentUserName:this.currentUserName,currentUserPicture:this.currentUserPicture,showWelcome:this.showWelcome,welcomeText:this.welcomeText,startChatText:this.startChatText,onlineText:this.onlineText,helpText:this.helpText,maxMessageLength:this.MESSAGE_MAX_LENGTH},r=z(this.theme),{onlineText:e,helpText:o,...s}=t,l=O(s);let p=r;this.displayType==="embed"?p+=l:this.displayType==="full"?p+=`
|
|
499
499
|
<div class="nostr-chat-float-panel open">${l}</div>
|
|
500
500
|
`:this.displayType==="fab"?p+=`
|
|
501
501
|
${this.isOpen?"":`
|
|
@@ -519,5 +519,5 @@ var P=Object.defineProperty;var H=(h,f,t)=>f in h?P(h,f,{enumerable:!0,configura
|
|
|
519
519
|
<div class="nostr-chat-float-panel ${this.isOpen?"open":""}">
|
|
520
520
|
${l}
|
|
521
521
|
</div>
|
|
522
|
-
`),this.shadowRoot.innerHTML=p,this.attachEventListeners(),setTimeout(()=>{var d;const i=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-history");i&&(i.scrollTop=i.scrollHeight)},0)}};a(x,"DEFAULT_WELCOME_TEXT","Welcome! How can we help you today?"),a(x,"DEFAULT_START_CHAT_TEXT","Start chat"),a(x,"DEFAULT_ONLINE_TEXT","We're Online!"),a(x,"DEFAULT_HELP_TEXT","How may I help you today?");let F=x;customElements.define("nostr-live-chat",F);
|
|
522
|
+
`),this.shadowRoot.innerHTML=p,this.attachEventListeners(),setTimeout(()=>{var d;const i=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-chat-history");i&&(i.scrollTop=i.scrollHeight)},0)}};a(x,"DEFAULT_WELCOME_TEXT","Welcome! How can we help you today?"),a(x,"DEFAULT_START_CHAT_TEXT","Start chat"),a(x,"DEFAULT_ONLINE_TEXT","We're Online!"),a(x,"DEFAULT_HELP_TEXT","How may I help you today?");let F=x;customElements.define("nostr-live-chat",F);export{F as default};
|
|
523
523
|
//# sourceMappingURL=nostr-live-chat.es.js.map
|