NIP-28 support!
This commit is contained in:
parent
842a0d4703
commit
053a1c8ed2
15 changed files with 906 additions and 22309 deletions
|
|
@ -12,8 +12,8 @@
|
||||||
renter a Svelte component upon loading this page.</p>
|
renter a Svelte component upon loading this page.</p>
|
||||||
|
|
||||||
<script src="public/bundle.js"
|
<script src="public/bundle.js"
|
||||||
data-chat-type="GLOBAL"
|
data-chat-type="NIP-28"
|
||||||
data-chat-tags="nostrica,nostrica2023"
|
data-chat-id="a6f436a59fdb5e23c757b1e30478742996c54413df777843e0a731af56a96eea"
|
||||||
data-relays="wss://relay.nostrica.com,wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
|
data-relays="wss://relay.nostrica.com,wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
|
|
||||||
876
package-lock.json
generated
876
package-lock.json
generated
File diff suppressed because it is too large
Load diff
12
package.json
12
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "nostri.chat",
|
"name": "nostri.chat",
|
||||||
"version": "0.1.5",
|
"version": "0.3.14159",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "svelte-kit sync && svelte-package",
|
"build": "svelte-kit sync && svelte-package",
|
||||||
|
|
@ -11,13 +11,14 @@
|
||||||
"@sveltejs/adapter-auto": "^1.0.0",
|
"@sveltejs/adapter-auto": "^1.0.0",
|
||||||
"@sveltejs/kit": "^1.0.0",
|
"@sveltejs/kit": "^1.0.0",
|
||||||
"@sveltejs/package": "^1.0.0",
|
"@sveltejs/package": "^1.0.0",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.14",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"rollup-plugin-svelte": "^7.1.0",
|
"rollup-plugin-polyfill-node": "^0.12.0",
|
||||||
|
"rollup-plugin-svelte": "^7.1.5",
|
||||||
"sirv-cli": "^2.0.2",
|
"sirv-cli": "^2.0.2",
|
||||||
"svelte": "^3.54.0",
|
"svelte": "^3.54.0",
|
||||||
"tailwindcss": "^3.2.4",
|
"tailwindcss": "^3.3.2",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.3",
|
||||||
"vite": "^4.0.0"
|
"vite": "^4.0.0"
|
||||||
|
|
@ -26,9 +27,10 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-connect/connect": "^0.2.3",
|
"@nostr-connect/connect": "^0.2.3",
|
||||||
"@nostr-dev-kit/ndk": "^0.3.32",
|
"@nostr-dev-kit/ndk": "^0.3.32",
|
||||||
|
"@rollup/plugin-alias": "^5.0.0",
|
||||||
"@rollup/plugin-commonjs": "^24.0.1",
|
"@rollup/plugin-commonjs": "^24.0.1",
|
||||||
"@rollup/plugin-json": "^6.0.0",
|
"@rollup/plugin-json": "^6.0.0",
|
||||||
"@rollup/plugin-typescript": "^11.0.0",
|
"@rollup/plugin-typescript": "^11.1.1",
|
||||||
"@sveltejs/adapter-node": "^1.1.7",
|
"@sveltejs/adapter-node": "^1.1.7",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import sveltePreprocess from "svelte-preprocess";
|
||||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||||
import tailwindcss from "tailwindcss";
|
import tailwindcss from "tailwindcss";
|
||||||
import autoprefixer from "autoprefixer";
|
import autoprefixer from "autoprefixer";
|
||||||
|
import nodePolyfills from 'rollup-plugin-polyfill-node';
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
import commonjs from "@rollup/plugin-commonjs";
|
||||||
import css from "rollup-plugin-css-only";
|
import css from "rollup-plugin-css-only";
|
||||||
|
|
@ -22,6 +23,12 @@ export default {
|
||||||
format: "iife",
|
format: "iife",
|
||||||
name: "app",
|
name: "app",
|
||||||
sourcemap: production,
|
sourcemap: production,
|
||||||
|
globals: {
|
||||||
|
"https": "https",
|
||||||
|
"http": "http",
|
||||||
|
"net": "net",
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
// compile svelte with tailwindcss as preprocess (including autoprefixer)
|
// compile svelte with tailwindcss as preprocess (including autoprefixer)
|
||||||
|
|
@ -45,6 +52,7 @@ export default {
|
||||||
}),
|
}),
|
||||||
json(),
|
json(),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
|
nodePolyfills( /* options */ ),
|
||||||
|
|
||||||
// export CSS in separate file for better performance
|
// export CSS in separate file for better performance
|
||||||
css({ output: "bundle.css" }),
|
css({ output: "bundle.css" }),
|
||||||
|
|
@ -64,6 +72,6 @@ export default {
|
||||||
!production && livereload("public/"),
|
!production && livereload("public/"),
|
||||||
|
|
||||||
// minify bundles in production mode
|
// minify bundles in production mode
|
||||||
// production && terser(),
|
production && terser(),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,12 @@
|
||||||
let prevChatConfiguration;
|
let prevChatConfiguration;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (chatConfiguration !== prevChatConfiguration && prevChatConfiguration && $chatAdapter) {
|
if (chatConfiguration !== prevChatConfiguration && $chatAdapter) {
|
||||||
$chatAdapter.setChatConfiguration(chatConfiguration.chatType, chatConfiguration.chatTags, chatConfiguration.chatReferenceTags);
|
$chatAdapter.setChatConfiguration(
|
||||||
|
chatConfiguration.chatType,
|
||||||
|
chatConfiguration.chatTags,
|
||||||
|
chatConfiguration.chatReferenceTags,
|
||||||
|
chatConfiguration.chatId);
|
||||||
events = [];
|
events = [];
|
||||||
responses = {};
|
responses = {};
|
||||||
rootNoteId = null;
|
rootNoteId = null;
|
||||||
|
|
@ -46,7 +50,7 @@
|
||||||
|
|
||||||
// if we are responding to an event, we want to tag the event and the pubkey
|
// if we are responding to an event, we want to tag the event and the pubkey
|
||||||
if ($selectedMessage) {
|
if ($selectedMessage) {
|
||||||
extraParams.tags.push(['e', $selectedMessage]);
|
extraParams.tags.push(['e', $selectedMessage, "wss://nos.lol", "root"]);
|
||||||
extraParams.tagPubKeys.push(getEventById($selectedMessage).pubkey);
|
extraParams.tagPubKeys.push(getEventById($selectedMessage).pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,6 +90,8 @@
|
||||||
|
|
||||||
if (chatConfiguration.chatType === 'GLOBAL') {
|
if (chatConfiguration.chatType === 'GLOBAL') {
|
||||||
isThread = message.tags.filter(tag => tag[0] === 'e').length >= 1;
|
isThread = message.tags.filter(tag => tag[0] === 'e').length >= 1;
|
||||||
|
} else if (chatConfiguration.chatType === 'GROUP') {
|
||||||
|
isThread = message.tags.filter(tag => tag[0] === 'e' && tag[1] !== chatConfiguration.chatId).length >= 1;
|
||||||
} else {
|
} else {
|
||||||
const pubkeysTagged = message.tags.filter(tag => tag[0] === 'p').map(tag => tag[1]);
|
const pubkeysTagged = message.tags.filter(tag => tag[0] === 'p').map(tag => tag[1]);
|
||||||
isThread = new Set(pubkeysTagged).size >= 2;
|
isThread = new Set(pubkeysTagged).size >= 2;
|
||||||
|
|
@ -147,6 +153,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let rootNoteId;
|
let rootNoteId;
|
||||||
|
let channelMetadata = {};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
$chatAdapter.on('message', messageReceived);
|
$chatAdapter.on('message', messageReceived);
|
||||||
|
|
@ -173,6 +180,10 @@
|
||||||
|
|
||||||
chatData.set({ profiles, ...$chatData })
|
chatData.set({ profiles, ...$chatData })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$chatAdapter.on('channelMetadata', (event) => {
|
||||||
|
channelMetadata = JSON.parse(event.content);
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let connectivityStatus = {};
|
let connectivityStatus = {};
|
||||||
|
|
@ -188,14 +199,25 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let connectedChatId;
|
||||||
|
|
||||||
|
$: if (connectedChatId !== $chatAdapter?.chatId) {
|
||||||
|
connectedChatId = $chatAdapter?.chatId;
|
||||||
|
channelMetadata = {};
|
||||||
|
}
|
||||||
|
|
||||||
$: profiles = $chatData.profiles;
|
$: profiles = $chatData.profiles;
|
||||||
|
|
||||||
function selectParent() {
|
function selectParent() {
|
||||||
|
if (chatConfiguration.chatType === 'GROUP') {
|
||||||
|
$selectedMessage = null;
|
||||||
|
} else {
|
||||||
// get the last tagged event in the tags array of the current $selectedMessage
|
// get the last tagged event in the tags array of the current $selectedMessage
|
||||||
const lastETag = getEventById($selectedMessage).tags.filter(tag => tag[0] === 'e').pop();
|
const lastETag = getEventById($selectedMessage).tags.filter(tag => tag[0] === 'e').pop();
|
||||||
const lastETagId = lastETag && lastETag[1];
|
const lastETagId = lastETag && lastETag[1];
|
||||||
|
|
||||||
$selectedMessage = lastETagId;
|
$selectedMessage = lastETagId;
|
||||||
|
}
|
||||||
|
|
||||||
scrollDown()
|
scrollDown()
|
||||||
}
|
}
|
||||||
|
|
@ -254,6 +276,21 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if channelMetadata.name}
|
||||||
|
<div class="flex flex-row gap-2 mb-3 bg-zinc-300 text-zinc-800 px-4 py-2 -mx-4 -mt-3">
|
||||||
|
{#if channelMetadata.picture}
|
||||||
|
<img src={channelMetadata.picture} class="w-12 h-12 rounded-full" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="font-extrabold text-xl">{channelMetadata.name}</div>
|
||||||
|
{#if channelMetadata.about}
|
||||||
|
<div class="text-sm truncate font-regular">{channelMetadata.about}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if $selectedMessage}
|
{#if $selectedMessage}
|
||||||
{#if !getEventById($selectedMessage)}
|
{#if !getEventById($selectedMessage)}
|
||||||
<h1>Couldn't find event with ID {$selectedMessage}</h1>
|
<h1>Couldn't find event with ID {$selectedMessage}</h1>
|
||||||
|
|
@ -299,9 +336,12 @@
|
||||||
{#if chatConfiguration.chatType === 'DM'}
|
{#if chatConfiguration.chatType === 'DM'}
|
||||||
<b>Encrypted chat:</b>
|
<b>Encrypted chat:</b>
|
||||||
only your chat partner can see these messages.
|
only your chat partner can see these messages.
|
||||||
{:else}
|
{:else if chatConfiguration.chatType === 'GROUP'}
|
||||||
<b>Public chat:</b>
|
<b>Public chat:</b>
|
||||||
anyone can see these messages.
|
anyone can see these messages.
|
||||||
|
{:else}
|
||||||
|
<b>Public notes:</b>
|
||||||
|
your followers see your messages on their timeline
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import QR from 'svelte-qr';
|
// import QR from 'svelte-qr';
|
||||||
import { chatAdapter } from './lib/store';
|
import { chatAdapter } from './lib/store';
|
||||||
import NstrAdapterNip07 from './lib/adapters/nip07.js';
|
import NstrAdapterNip07 from './lib/adapters/nip07.js';
|
||||||
import NstrAdapterNip46 from './lib/adapters/nip46.js';
|
import NstrAdapterNip46 from './lib/adapters/nip46.js';
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
|
|
||||||
<div class="bg-white w-full p-3"
|
<div class="bg-white w-full p-3"
|
||||||
on:click|preventDefault={Nip46Copy}>
|
on:click|preventDefault={Nip46Copy}>
|
||||||
<QR text={nip46URI} />
|
<!-- <QR text={nip46URI} /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="
|
<button class="
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
// delay-fetch responses
|
// delay-fetch responses
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
$chatAdapter.delayedSubscribe(
|
$chatAdapter.delayedSubscribe(
|
||||||
{kinds: [1, 9735], '#e': [event.id]}
|
{kinds: [1, 42, 9735], '#e': [event.id]}
|
||||||
, 'responses', 500)
|
, 'responses', 500)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@
|
||||||
<p class="flex flex-col items-center my-4">
|
<p class="flex flex-col items-center my-4">
|
||||||
⚡️
|
⚡️
|
||||||
<span class="text-orange-500 font-semibold">
|
<span class="text-orange-500 font-semibold">
|
||||||
{zappedAmount}
|
{zappedAmount/1000}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
export let chatTags;
|
export let chatTags;
|
||||||
export let chatReferenceTags;
|
export let chatReferenceTags;
|
||||||
export let relays;
|
export let relays;
|
||||||
|
export let chatId;
|
||||||
|
|
||||||
let showChat = false;
|
let showChat = false;
|
||||||
let dismissedIntro = true;
|
|
||||||
let minimizeChat = false;
|
let minimizeChat = false;
|
||||||
|
|
||||||
function toggleChat() {
|
function toggleChat() {
|
||||||
|
|
@ -18,10 +18,6 @@
|
||||||
showChat = !showChat;
|
showChat = !showChat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dismissIntro() {
|
|
||||||
dismissedIntro = true;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="
|
<div class="
|
||||||
|
|
@ -35,63 +31,16 @@
|
||||||
flex flex-col justify-end
|
flex flex-col justify-end
|
||||||
{minimizeChat ? 'hidden' : ''}
|
{minimizeChat ? 'hidden' : ''}
|
||||||
" style="max-height: 80vh;">
|
" style="max-height: 80vh;">
|
||||||
{#if !dismissedIntro}
|
|
||||||
<h1 class="
|
|
||||||
font-bold
|
|
||||||
text-2xl
|
|
||||||
text-purple-700">
|
|
||||||
NostriChat
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p class="text-gray-700 mb-3">
|
|
||||||
This is a FOSS chat app built on top of the Nostr protocol.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="text-gray-700 mb-3">
|
|
||||||
Choose how you would like to chat:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="text-gray-700 mb-3">
|
|
||||||
You can use it to ask for help
|
|
||||||
<span class="font-bold">PSBT.io</span>
|
|
||||||
to the creators of this site or to
|
|
||||||
anyone willing to help.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="text-gray-700 mb-3">
|
|
||||||
Keep in mind that this chat is public,
|
|
||||||
anyone can read it, so don't exchange
|
|
||||||
private information and use common-sense.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button class="
|
|
||||||
bg-purple-900
|
|
||||||
hover:bg-purple-700
|
|
||||||
w-full
|
|
||||||
p-2
|
|
||||||
py-4
|
|
||||||
text-xl
|
|
||||||
mt-3
|
|
||||||
rounded-xl
|
|
||||||
text-center
|
|
||||||
font-semibold
|
|
||||||
tracking-wide
|
|
||||||
uppercase
|
|
||||||
text-white
|
|
||||||
" on:click={dismissIntro}>
|
|
||||||
Continue
|
|
||||||
</button>
|
|
||||||
{:else}
|
|
||||||
<Container
|
<Container
|
||||||
{websiteOwnerPubkey}
|
{websiteOwnerPubkey}
|
||||||
chatConfiguration={{
|
chatConfiguration={{
|
||||||
chatType,
|
chatType,
|
||||||
chatTags,
|
chatTags,
|
||||||
|
chatId,
|
||||||
chatReferenceTags,
|
chatReferenceTags,
|
||||||
}}
|
}}
|
||||||
{relays}
|
{relays}
|
||||||
/>
|
/>
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ class NstrAdapter {
|
||||||
referenceTags;
|
referenceTags;
|
||||||
type;
|
type;
|
||||||
#websiteOwnerPubkey;
|
#websiteOwnerPubkey;
|
||||||
|
chatId;
|
||||||
relayUrls = [];
|
relayUrls = [];
|
||||||
|
|
||||||
#profileRequestQueue = [];
|
#profileRequestQueue = [];
|
||||||
|
|
@ -29,25 +30,24 @@ class NstrAdapter {
|
||||||
#delayedSubscriptions = {};
|
#delayedSubscriptions = {};
|
||||||
#delayedSubscriptionTimeouts = {};
|
#delayedSubscriptionTimeouts = {};
|
||||||
|
|
||||||
constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
|
constructor(clientPubkey, {tags, referenceTags, type='DM', chatId, websiteOwnerPubkey, relays} = {}) {
|
||||||
this.pubkey = clientPubkey;
|
this.pubkey = clientPubkey;
|
||||||
this.#websiteOwnerPubkey = websiteOwnerPubkey;
|
this.#websiteOwnerPubkey = websiteOwnerPubkey;
|
||||||
this.relayUrls = relays
|
this.relayUrls = relays
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
this.setChatConfiguration(type, tags, referenceTags);
|
this.setChatConfiguration(type, tags, referenceTags, chatId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setChatConfiguration(type, tags, referenceTags) {
|
setChatConfiguration(type, tags, referenceTags, chatId) {
|
||||||
log('chatConfiguration', {type, tags, referenceTags});
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
|
this.chatId = chatId;
|
||||||
this.referenceTags = referenceTags;
|
this.referenceTags = referenceTags;
|
||||||
|
|
||||||
// handle connection
|
// handle connection
|
||||||
if (this.#pool) { this.#disconnect() }
|
if (this.#pool) { this.#disconnect() }
|
||||||
this.#connect()
|
|
||||||
|
|
||||||
let filters = [];
|
let filters = [];
|
||||||
|
|
||||||
|
|
@ -61,6 +61,14 @@ class NstrAdapter {
|
||||||
'authors': [this.pubkey, this.#websiteOwnerPubkey]
|
'authors': [this.pubkey, this.#websiteOwnerPubkey]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'GROUP':
|
||||||
|
if (this.chatId) {
|
||||||
|
filters.push({
|
||||||
|
kinds: [41, 42],
|
||||||
|
"#e": [this.chatId],
|
||||||
|
limit: 200,
|
||||||
|
})
|
||||||
|
}
|
||||||
case 'GLOBAL':
|
case 'GLOBAL':
|
||||||
if (this.tags && this.tags.length > 0) {
|
if (this.tags && this.tags.length > 0) {
|
||||||
filters.push({kinds: [1], '#t': this.tags, limit: 20});
|
filters.push({kinds: [1], '#t': this.tags, limit: 20});
|
||||||
|
|
@ -73,6 +81,7 @@ class NstrAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters && filters.length > 0) {
|
if (filters && filters.length > 0) {
|
||||||
|
this.#connect()
|
||||||
this.subscribe(filters, (e) => { this.#emitMessage(e) })
|
this.subscribe(filters, (e) => { this.#emitMessage(e) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +105,8 @@ class NstrAdapter {
|
||||||
|
|
||||||
if (this.type === 'DM') {
|
if (this.type === 'DM') {
|
||||||
event = await this.sendKind4(message, {tagPubKeys, tags});
|
event = await this.sendKind4(message, {tagPubKeys, tags});
|
||||||
|
} else if (this.type === 'GROUP') {
|
||||||
|
event = await this.sendKind42(message, {tagPubKeys, tags, chatId: this.chatId});
|
||||||
} else {
|
} else {
|
||||||
event = await this.sendKind1(message, {tagPubKeys, tags});
|
event = await this.sendKind1(message, {tagPubKeys, tags});
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +135,46 @@ class NstrAdapter {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendKind42(message, {tagPubKeys, tags, chatId} = {}) {
|
||||||
|
if (!tags) { tags = []; }
|
||||||
|
|
||||||
|
if (this.tags) {
|
||||||
|
this.tags.forEach((t) => tags.push(['t', t]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if there is an e tag
|
||||||
|
const reply = !!tags.find((t) => t[0] === 'e');
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
tags.push(['e', chatId, "wss://nos.lol", reply ? "reply" : "root"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.referenceTags) {
|
||||||
|
this.referenceTags.forEach((t) => tags.push(['r', t]));
|
||||||
|
}
|
||||||
|
|
||||||
|
let event = {
|
||||||
|
kind: 42,
|
||||||
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
|
tags,
|
||||||
|
content: message,
|
||||||
|
pubkey: this.pubkey,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagPubKeys) {
|
||||||
|
for (let pubkey of tagPubKeys) {
|
||||||
|
if (pubkey) {
|
||||||
|
event.tags.push(['p', pubkey]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.id = getEventHash(event)
|
||||||
|
this.subscribeToEventAndResponses(event.id);
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
async sendKind1(message, {tagPubKeys, tags} = {}) {
|
async sendKind1(message, {tagPubKeys, tags} = {}) {
|
||||||
if (!tags) { tags = []; }
|
if (!tags) { tags = []; }
|
||||||
|
|
||||||
|
|
@ -191,8 +242,6 @@ class NstrAdapter {
|
||||||
return groups;
|
return groups;
|
||||||
}, groups);
|
}, groups);
|
||||||
|
|
||||||
console.log(`turned ${filters.length} filters into ${groups.length} groups`);
|
|
||||||
|
|
||||||
groups.forEach((filters) => {
|
groups.forEach((filters) => {
|
||||||
this.subscribe(filters, (e) => { this.#emitMessage(e)});
|
this.subscribe(filters, (e) => { this.#emitMessage(e)});
|
||||||
});
|
});
|
||||||
|
|
@ -246,7 +295,11 @@ class NstrAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case 1: this.#eventEmitter.emit('message', event); break;
|
case 1:
|
||||||
|
case 42:
|
||||||
|
this.#eventEmitter.emit('message', event); break;
|
||||||
|
case 41:
|
||||||
|
this.#eventEmitter.emit('channelMetadata', event); break;
|
||||||
case 4: this.#eventEmitter.emit('message', event); break;
|
case 4: this.#eventEmitter.emit('message', event); break;
|
||||||
case 5: this.#eventEmitter.emit('deleted', deletedEvents); break;
|
case 5: this.#eventEmitter.emit('deleted', deletedEvents); break;
|
||||||
case 7: this.#eventEmitter.emit('reaction', event); break;
|
case 7: this.#eventEmitter.emit('reaction', event); break;
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,17 @@
|
||||||
import 'websocket-polyfill';
|
import 'websocket-polyfill';
|
||||||
import Container from '../Container.svelte';
|
import Container from '../Container.svelte';
|
||||||
import Widget from '../Widget.svelte';
|
import Widget from '../Widget.svelte';
|
||||||
import { chatAdapter } from '$lib/store';
|
import { chatAdapter } from '../lib/store';
|
||||||
|
|
||||||
let chatStarted;
|
let chatStarted;
|
||||||
let chatType = 'GLOBAL';
|
let chatType = 'GROUP';
|
||||||
let websiteOwnerPubkey = 'fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52';
|
let websiteOwnerPubkey = 'fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52';
|
||||||
let chatTags = ['bitcoin'];
|
let chatTags = [];
|
||||||
|
let chatId = '9cef2eead5d91df42eba09be363f1272107e911685126ea5e261ac2d93299478';
|
||||||
let chatReferenceTags = [];
|
let chatReferenceTags = [];
|
||||||
const relays = [
|
const relays = [
|
||||||
'wss://relay.f7z.io',
|
'wss://relay.f7z.io',
|
||||||
'wss://relay.nostr.info',
|
'wss://nos.lol',
|
||||||
'wss://nostr-pub.wellorder.net',
|
|
||||||
'wss://relay.nos.lol',
|
|
||||||
'wss://nostr.walletofsatoshi.com',
|
|
||||||
'wss://relay.nostr.band',
|
'wss://relay.nostr.band',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -87,6 +85,7 @@
|
||||||
" style="{chatStarted ? 'max-height: 80vh;' : 'padding: 4rem 2rem !important;'}">
|
" style="{chatStarted ? 'max-height: 80vh;' : 'padding: 4rem 2rem !important;'}">
|
||||||
<Container chatConfiguration={{
|
<Container chatConfiguration={{
|
||||||
chatType,
|
chatType,
|
||||||
|
chatId,
|
||||||
chatTags,
|
chatTags,
|
||||||
chatReferenceTags,
|
chatReferenceTags,
|
||||||
}} {relays} bind:chatStarted={chatStarted} />
|
}} {relays} bind:chatStarted={chatStarted} />
|
||||||
|
|
@ -148,6 +147,60 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
|
<h2 class="text-3xl text-orange-600 font-black">
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<span>🫂</span>
|
||||||
|
<span class="flex flex-col">
|
||||||
|
<span>Public chat groups</span>
|
||||||
|
<span class="text-2xl text-slate-500 font-extralight block">public groups</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p class="
|
||||||
|
text-xl text-gray-500 text-justify
|
||||||
|
font-light
|
||||||
|
leading-8
|
||||||
|
">
|
||||||
|
Embed NIP-28 public chat groups on your site.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex flex-col lg:flex-row justify-between mt-10 gap-10 mb-6">
|
||||||
|
<div class="flex flex-col lg:w-1/2 items-center gap-4 border p-4 shadow-md rounded-lg w-fit">
|
||||||
|
<h3 class="
|
||||||
|
text-black
|
||||||
|
text-lg
|
||||||
|
font-semibold
|
||||||
|
">Group chat</h3>
|
||||||
|
<span class="inline-flex rounded-md">
|
||||||
|
<button type="button" class="
|
||||||
|
inline-flex items-center rounded-l-md border px-4 py-2 text-md font-medium
|
||||||
|
{chatType === 'GROUP' && chatId === '9cef2eead5d91df42eba09be363f1272107e911685126ea5e261ac2d93299478' ?
|
||||||
|
'text-white bg-orange-700 border-orange-900'
|
||||||
|
:
|
||||||
|
'border-gray-300 bg-white text-gray-700'}
|
||||||
|
:ring-indigo-500"
|
||||||
|
on:click={()=>{ chatType='GROUP'; chatTags=[]; chatId='9cef2eead5d91df42eba09be363f1272107e911685126ea5e261ac2d93299478' }}
|
||||||
|
>
|
||||||
|
#Test
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="
|
||||||
|
inline-flex items-center rounded-r-md border px-4 py-2 text-md font-medium
|
||||||
|
{chatType === 'GROUP' && chatId === 'a6f436a59fdb5e23c757b1e30478742996c54413df777843e0a731af56a96eea' ?
|
||||||
|
'text-white bg-orange-700 border-orange-900'
|
||||||
|
:
|
||||||
|
'border-gray-300 bg-white text-gray-700'}
|
||||||
|
:ring-indigo-500"
|
||||||
|
on:click={()=>{ chatType='GROUP'; chatTags=[]; chatId='a6f436a59fdb5e23c757b1e30478742996c54413df777843e0a731af56a96eea' }}
|
||||||
|
>
|
||||||
|
#NDK
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2 class="text-3xl text-orange-600 font-black">
|
<h2 class="text-3xl text-orange-600 font-black">
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<span>🔖</span>
|
<span>🔖</span>
|
||||||
|
|
@ -156,8 +209,6 @@
|
||||||
<span class="text-2xl text-slate-500 font-extralight block">public discussion/support</span>
|
<span class="text-2xl text-slate-500 font-extralight block">public discussion/support</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="
|
<p class="
|
||||||
|
|
@ -262,6 +313,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="text-xl font-semibold">Public group chat (GROUP)</div>
|
||||||
<pre class ="
|
<pre class ="
|
||||||
p-4
|
p-4
|
||||||
bg-white
|
bg-white
|
||||||
|
|
@ -269,14 +321,37 @@
|
||||||
">
|
">
|
||||||
<script
|
<script
|
||||||
src="https://nostri.chat/public/bundle.js"
|
src="https://nostri.chat/public/bundle.js"
|
||||||
<span class="text-green-600">// YOUR PUBKEY IN HEX FORMAT</span>
|
<b>data-chat-type</b>="<span class="text-orange-500">GROUP</span>"
|
||||||
<b>data-website-owner-pubkey</b>="<span class="text-orange-500">YOUR_PUBKEY"</span>
|
<b>data-chat-id</b>="<span class="text-orange-500"><GROUP_ID_IN_HEX_FORMAT></span>"
|
||||||
<span class="text-green-600">// THE TYPE OF CHAT YOU WANT: GLOBAL or DMs</span>
|
<b>data-relays</b>="<span class="text-orange-500">wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.band</span>"
|
||||||
<b>data-chat-type</b>="<span class="text-orange-500">GLOBAL" </span>
|
></script>
|
||||||
<span class="text-green-600">// If you use GLOBAL you can choose set a comma-separated list of hashtags</span>
|
<link rel="stylesheet" href="https://nostri.chat/public/bundle.css"></pre>
|
||||||
<b>data-chat-tags</b>="<span class="text-orange-500">nostrica,bitcoin"</span>
|
|
||||||
<span class="text-green-600">// Relays you'd like to use, change this this as you wish</span>
|
<div class="text-xl font-semibold">Public global notes (kind-1 short notes)</div>
|
||||||
<b>data-relays</b>="<span class="text-orange-500">wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"</span>
|
<pre class ="
|
||||||
|
p-4
|
||||||
|
bg-white
|
||||||
|
overflow-auto
|
||||||
|
">
|
||||||
|
<script
|
||||||
|
src="https://nostri.chat/public/bundle.js"
|
||||||
|
<b>data-chat-type</b>="<span class="text-orange-500">GLOBAL</span>"
|
||||||
|
<b>data-chat-tags</b>="<span class="text-orange-500">bitcoin</span>"
|
||||||
|
<b>data-relays</b>="<span class="text-orange-500">wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.band</span>"
|
||||||
|
></script>
|
||||||
|
<link rel="stylesheet" href="https://nostri.chat/public/bundle.css"></pre>
|
||||||
|
|
||||||
|
<div class="text-xl font-semibold">Encrypted DMs</div>
|
||||||
|
<pre class ="
|
||||||
|
p-4
|
||||||
|
bg-white
|
||||||
|
overflow-auto
|
||||||
|
">
|
||||||
|
<script
|
||||||
|
src="https://nostri.chat/public/bundle.js"
|
||||||
|
<b>data-chat-type</b>="<span class="text-orange-500">DM</span>"
|
||||||
|
<b>data-website-owner-pubkey</b>="<span class="text-orange-500">YOUR_PUBKEY_IN_HEX_FORMAT</span>"
|
||||||
|
<b>data-relays</b>="<span class="text-orange-500">wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.band</span>"
|
||||||
></script>
|
></script>
|
||||||
<link rel="stylesheet" href="https://nostri.chat/public/bundle.css"></pre>
|
<link rel="stylesheet" href="https://nostri.chat/public/bundle.css"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -285,10 +360,9 @@
|
||||||
|
|
||||||
<div class="md:hidden">
|
<div class="md:hidden">
|
||||||
<Widget chatConfiguration={{
|
<Widget chatConfiguration={{
|
||||||
chatType,
|
|
||||||
chatTags,
|
chatTags,
|
||||||
chatReferenceTags,
|
chatReferenceTags,
|
||||||
}} {websiteOwnerPubkey} {relays} bind:chatStarted={chatStarted} />
|
}} {websiteOwnerPubkey} {chatType} {chatId} {relays} bind:chatStarted={chatStarted} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="py-6 bg-orange-900 font-mono text-white text-center mt-12 px-10">
|
<footer class="py-6 bg-orange-900 font-mono text-white text-center mt-12 px-10">
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
<script
|
<script
|
||||||
src="/public/bundle.js"
|
src="/public/bundle.js"
|
||||||
data-website-owner-pubkey="fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"
|
data-website-owner-pubkey="fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"
|
||||||
data-chat-type="GLOBAL"
|
data-chat-type="GROUP"
|
||||||
data-chat-tags="nostrica"
|
data-chat-id="a6f436a59fdb5e23c757b1e30478742996c54413df777843e0a731af56a96eea"
|
||||||
data-relays="wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
|
data-relays="wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ var script = document.currentScript;
|
||||||
const websiteOwnerPubkey = script.getAttribute('data-website-owner-pubkey');
|
const websiteOwnerPubkey = script.getAttribute('data-website-owner-pubkey');
|
||||||
const chatType = script.getAttribute('data-chat-type');
|
const chatType = script.getAttribute('data-chat-type');
|
||||||
let chatTags = script.getAttribute('data-chat-tags');
|
let chatTags = script.getAttribute('data-chat-tags');
|
||||||
|
let chatId = script.getAttribute('data-chat-id');
|
||||||
let chatReferenceTags = script.getAttribute('data-chat-reference-tags');
|
let chatReferenceTags = script.getAttribute('data-chat-reference-tags');
|
||||||
let relays = script.getAttribute('data-relays');
|
let relays = script.getAttribute('data-relays');
|
||||||
script.parentNode.insertBefore(div, script);
|
script.parentNode.insertBefore(div, script);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
21977
static/public/bundle.js
21977
static/public/bundle.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue