Added custom events and updated reply events handling
Implemented support for creating custom events. Also integrated functionality to generate reply events by retrieving them from relays first, with compatibility for multiple eventId formats like nevent, note, and hexadecimal strings.
This commit is contained in:
@@ -32,18 +32,19 @@
|
||||
<div class="tabs">
|
||||
<div class="tab active" data-tab="tab1">Post</div>
|
||||
<div class="tab" data-tab="tab2">Reply</div>
|
||||
<div class="tab" data-tab="tab3">Create Profile</div>
|
||||
<div class="tab" data-tab="tab3">Create/Edit Profile</div>
|
||||
<div class="tab" data-tab="tab4">Custom Event</div>
|
||||
</div>
|
||||
<div class="tab-content active" id="tab1">
|
||||
<h3>Post</h3>
|
||||
<label for="final-content">Message Content:</label>
|
||||
<textarea id="final-content" rows="3" placeholder="Enter your message content..."></textarea>
|
||||
<label for="post-content">Message Content:</label>
|
||||
<textarea id="post-content" rows="3" placeholder="Enter your message content..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" id="tab2">
|
||||
<h3>Reply</h3>
|
||||
<label for="nevent">Nevent:</label>
|
||||
<textarea id="nevent" placeholder="Enter the nevent for the note..."></textarea>
|
||||
<label for="reply-id">EventId/NoteId/Nevent:</label>
|
||||
<textarea id="reply-id" placeholder="Enter the nevent for the note..."></textarea>
|
||||
<label for="reply-content">Message Content:</label>
|
||||
<textarea id="reply-content" rows="3" placeholder="Enter your message content..."></textarea>
|
||||
</div>
|
||||
@@ -67,6 +68,16 @@
|
||||
<label for="lud16">Lightning Address:</label>
|
||||
<textarea id="lud16" placeholder="Enter your lightning address..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" id="tab4">
|
||||
<h3>Custom Event</h3>
|
||||
<label for="kind">Event Kind:</label>
|
||||
<textarea id="kind" placeholder="Enter your event kind. Ex: 0, 1, 30000..."></textarea>
|
||||
<label for="content">Content:</label>
|
||||
<textarea id="content" rows="3" placeholder="A short bio..."></textarea>
|
||||
<label for="tags">Tags:</label>
|
||||
<textarea id="tags" rows="3" placeholder="Tags in format [['p', 'pubkey...'], ['e', 'event_id', wss://nos.lol, 'pubkey...']]"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<button onclick="createFinalEvent()">Create Event That Will Be Published Publicly</button>
|
||||
|
||||
@@ -107,12 +118,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Load the official nostr-tools bundle first -->
|
||||
<!-- <script src="./nostr.bundle.js"></script> -->
|
||||
<script src="https://laantungir.net/nostr-login-lite/nostr.bundle.js"></script>
|
||||
<script src="./nostr.bundle.js"></script>
|
||||
<!-- <script src="https://laantungir.net/nostr-login-lite/nostr.bundle.js"></script> -->
|
||||
|
||||
<!-- Load NOSTR_LOGIN_LITE main library -->
|
||||
<script src="https://laantungir.net/nostr-login-lite/nostr-lite.js"></script>
|
||||
<!-- <script src="./nostr-lite.js"></script> -->
|
||||
<!-- <script src="https://laantungir.net/nostr-login-lite/nostr-lite.js"></script> -->
|
||||
<script src="./nostr-lite.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -770,6 +781,79 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Load event from id
|
||||
async function loadReplyTagsForEvent(id, knownRelays) {
|
||||
if (!id) return;
|
||||
|
||||
console.log('INFO', `Loading event`, id);
|
||||
|
||||
try {
|
||||
const pool = new window.NostrTools.SimplePool();
|
||||
const relays = [relayUrl, 'wss://relay.laantungir.net', 'wss://nos.lol', 'wss://relay.primal.net', 'wss://relay.damus.io', 'wss://relay.nostr.band'].concat(knownRelays);
|
||||
|
||||
// Enable tracking
|
||||
pool.trackRelays = true;
|
||||
|
||||
// Query for an event
|
||||
const events = await pool.querySync(relays, {
|
||||
ids: [id],
|
||||
limit: 1
|
||||
});
|
||||
|
||||
const event = events[0];
|
||||
let returnEventTags = [];
|
||||
let relaysSeenOn = [];
|
||||
if (event) {
|
||||
const seenRelays = pool.seenOn.get(event.id);
|
||||
relaysSeenOn = seenRelays ? Array.from(seenRelays).map(r => r.url) : [];
|
||||
}
|
||||
|
||||
pool.close(relays);
|
||||
|
||||
if (events.length > 0) {
|
||||
// event is a nostr event with tags
|
||||
const refs = window.NostrTools.nip10.parse(events[0])
|
||||
|
||||
// get the root event of the thread
|
||||
if (refs.root) {
|
||||
const relay = refs.root.relays.length > 0 ? refs.root.relays[0] : '';
|
||||
if (refs.root.author) {
|
||||
returnEventTags.push(['e', refs.root.id, relay, 'root', refs.root.author]);
|
||||
}
|
||||
else {
|
||||
returnEventTags.push(['e', refs.root.id, relay, 'root']);
|
||||
}
|
||||
returnEventTags.push(['e', id, relaysSeenOn[0], 'reply', event.pubkey]);
|
||||
if (refs.root.author)
|
||||
returnEventTags.push(['p', refs.root.author, relay]);
|
||||
returnEventTags.push(['p', event.pubkey, relaysSeenOn[0]]);
|
||||
} else {
|
||||
returnEventTags.push(['e', id, relaysSeenOn[0], 'root']);
|
||||
returnEventTags.push(['p', event.pubkey]);
|
||||
}
|
||||
|
||||
// get any referenced profiles
|
||||
for (let profile of refs.profiles) {
|
||||
if (!returnEventTags.some(tag => tag[0] === 'p' && tag[1] === profile.pubkey)) {
|
||||
if (profile.relays.length > 0) {
|
||||
returnEventTags.push(['p', profile.pubkey, profile.relays[0]]);
|
||||
}
|
||||
else {
|
||||
returnEventTags.push(['p', profile.pubkey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [events[0], returnEventTags];
|
||||
} else {
|
||||
console.log('INFO', 'Event not found');
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log('ERROR', `Profile loading failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Create final event (kind 1)
|
||||
async function createFinalEvent() {
|
||||
// Get the active tab
|
||||
@@ -777,8 +861,9 @@
|
||||
|
||||
// Get content based on active tab
|
||||
let content = '';
|
||||
let nevent = '';
|
||||
let neventData;
|
||||
let replyEventId = '';
|
||||
let replyEvent = {};
|
||||
let replyTags = [];
|
||||
let name = '';
|
||||
let about = '';
|
||||
let profilePic = '';
|
||||
@@ -787,14 +872,16 @@
|
||||
let banner = '';
|
||||
let nip05 = '';
|
||||
let lud16 = '';
|
||||
let tags = '';
|
||||
let kind = '';
|
||||
|
||||
switch(activeTab) {
|
||||
case 'tab1': // Post
|
||||
content = document.getElementById('final-content').value.trim();
|
||||
content = document.getElementById('post-content').value.trim();
|
||||
break;
|
||||
case 'tab2': // Reply
|
||||
content = document.getElementById('reply-content').value.trim();
|
||||
nevent = document.getElementById('nevent').value.trim();
|
||||
replyEventId = document.getElementById('reply-id').value.trim();
|
||||
break;
|
||||
case 'tab3': // Create Profile
|
||||
name = document.getElementById('name').value.trim();
|
||||
@@ -806,8 +893,13 @@
|
||||
nip05 = document.getElementById('nip05').value.trim();
|
||||
lud16 = document.getElementById('lud16').value.trim();
|
||||
break;
|
||||
case 'tab4': // Custom Event
|
||||
kind = document.getElementById('kind').value.trim();
|
||||
content = document.getElementById('content').value.trim();
|
||||
tags = document.getElementById('tags').value.trim();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Validate content based on tab
|
||||
if (activeTab === 'tab1') {
|
||||
if (!content) {
|
||||
@@ -819,14 +911,33 @@
|
||||
alert('Please enter message content');
|
||||
return;
|
||||
}
|
||||
if (!nevent.startsWith('nevent')) {
|
||||
alert('Please enter a valid nevent');
|
||||
let eventId = '';
|
||||
let knownRelays = [];
|
||||
try {
|
||||
if (replyEventId.startsWith('nevent')) {
|
||||
const replyEventData = window.NostrTools.nip19.decode(replyEventId).data;
|
||||
eventId = replyEventData.id;
|
||||
knownRelays = replyEventData.relays;
|
||||
} else if (replyEventId.startsWith('note')) {
|
||||
eventId = window.NostrTools.nip19.decode(replyEventId).data;
|
||||
} else {
|
||||
eventId = replyEventId;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert('Error decoding nevent string', error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
const regex = /^[0-9a-f]{64}$/;
|
||||
if (!regex.test(eventId)) {
|
||||
alert('Invalid event ID');
|
||||
}
|
||||
|
||||
try {
|
||||
neventData = window.NostrTools.nip19.decode(nevent).data;
|
||||
[ replyEvent, replyTags ] = await loadReplyTagsForEvent(eventId, knownRelays);
|
||||
} catch (error) {
|
||||
alert('Error decoding nevent string', error.message);
|
||||
alert('Error fetching reply event', error.message);
|
||||
return;
|
||||
}
|
||||
} else if (activeTab === 'tab3') {
|
||||
@@ -834,6 +945,22 @@
|
||||
alert('Please enter your name');
|
||||
return;
|
||||
}
|
||||
} else if (activeTab === 'tab4') {
|
||||
if (!kind) {
|
||||
alert('Please enter the event kind');
|
||||
return;
|
||||
}
|
||||
if (!/^-?\d+$/.test(kind)) {
|
||||
alert("Please enter a valid integer for event kind.");
|
||||
return; // Prevent form submission
|
||||
}
|
||||
try {
|
||||
kind = Number(kind);
|
||||
tags = JSON.parse(tags.replace(/'/g, '"'))
|
||||
} catch (error) {
|
||||
alert('Error parsing tags', error.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -853,12 +980,9 @@
|
||||
eventTemplate = {
|
||||
kind: 1,
|
||||
content: content,
|
||||
tags: [['e', neventData.id, neventData.relays[0], 'root'], ['p', neventData.author]],
|
||||
tags: replyTags,
|
||||
created_at: Math.floor(Date.now() / 1000)
|
||||
};
|
||||
neventData.relays.slice(1).forEach(relay => {
|
||||
eventTemplate.tags.push(['r', relay]);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'tab3': // Create Profile
|
||||
@@ -878,6 +1002,15 @@
|
||||
created_at: Math.floor(Date.now() / 1000)
|
||||
};
|
||||
break;
|
||||
|
||||
case 'tab4': // Create Profile
|
||||
eventTemplate = {
|
||||
kind: kind,
|
||||
content: content,
|
||||
tags: tags,
|
||||
created_at: Math.floor(Date.now() / 1000)
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
// Your existing event publishing logic here
|
||||
@@ -2084,7 +2217,7 @@
|
||||
bounceCounter = 0;
|
||||
|
||||
// Clear UI elements
|
||||
document.getElementById('final-content').value = '';
|
||||
document.getElementById('post-content').value = '';
|
||||
document.getElementById('final-event-display').textContent = '';
|
||||
document.getElementById('bounces-container').innerHTML = '';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user