Browse Source

Implement event deletion logic with relay handling in App.svelte and add connectToRelay method in NostrClient

This commit enhances the event deletion process by introducing conditional publishing to external relays based on user roles and ownership. It also adds a new method in the NostrClient class to connect to a single relay, improving the flexibility of relay management. The version is bumped to v0.12.3 to reflect these changes.
main
mleku 3 months ago
parent
commit
27af174753
No known key found for this signature in database
  1. 49
      app/web/src/App.svelte
  2. 58
      app/web/src/nostr.js
  3. 2
      pkg/version/version

49
app/web/src/App.svelte

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<script>
import LoginModal from './LoginModal.svelte';
import { initializeNostrClient, fetchUserProfile, fetchAllEvents, fetchUserEvents, nostrClient } from './nostr.js';
import { initializeNostrClient, fetchUserProfile, fetchAllEvents, fetchUserEvents, nostrClient, NostrClient } from './nostr.js';
let isDarkTheme = false;
let showLoginModal = false;
@ -213,16 +213,45 @@ @@ -213,16 +213,45 @@
const signedDeleteEvent = await userSigner.signEvent(deleteEventTemplate);
console.log('Signed delete event:', signedDeleteEvent);
// Publish the delete event to the relay
const result = await nostrClient.publish(signedDeleteEvent);
console.log('Delete event published:', result);
if (result.success && result.okCount > 0) {
// Remove from local list
allEvents = allEvents.filter(event => event.id !== eventId);
alert(`Event deleted successfully (accepted by ${result.okCount} relay(s))`);
// Determine if we should publish to external relays
// Only publish to external relays if:
// 1. User is deleting their own event, OR
// 2. User is admin/owner AND deleting their own event
const isDeletingOwnEvent = event.pubkey === userPubkey;
const isAdminOrOwner = (userRole === 'admin' || userRole === 'owner');
const shouldPublishToExternalRelays = isDeletingOwnEvent;
if (shouldPublishToExternalRelays) {
// Publish the delete event to all relays (including external ones)
const result = await nostrClient.publish(signedDeleteEvent);
console.log('Delete event published:', result);
if (result.success && result.okCount > 0) {
// Remove from local list
allEvents = allEvents.filter(event => event.id !== eventId);
alert(`Event deleted successfully (accepted by ${result.okCount} relay(s))`);
} else {
throw new Error('No relays accepted the delete event');
}
} else {
throw new Error('No relays accepted the delete event');
// Admin/owner deleting someone else's event - only publish to local relay
// We need to publish only to the local relay, not external ones
const localRelayUrl = `wss://${window.location.host}/ws`;
// Create a modified client that only connects to the local relay
const localClient = new NostrClient();
await localClient.connectToRelay(localRelayUrl);
const result = await localClient.publish(signedDeleteEvent);
console.log('Delete event published to local relay only:', result);
if (result.success && result.okCount > 0) {
// Remove from local list
allEvents = allEvents.filter(event => event.id !== eventId);
alert(`Event deleted successfully (local relay only - admin/owner deleting other user's event)`);
} else {
throw new Error('Local relay did not accept the delete event');
}
}
} catch (error) {
console.error('Failed to delete event:', error);

58
app/web/src/nostr.js

@ -73,6 +73,61 @@ class NostrClient { @@ -73,6 +73,61 @@ class NostrClient {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
async connectToRelay(relayUrl) {
console.log(`Connecting to single relay: ${relayUrl}`);
return new Promise((resolve) => {
try {
console.log(`Attempting to connect to ${relayUrl}`);
const ws = new WebSocket(relayUrl);
ws.onopen = () => {
console.log(`✓ Successfully connected to ${relayUrl}`);
resolve(true);
};
ws.onerror = (error) => {
console.error(`✗ Error connecting to ${relayUrl}:`, error);
resolve(false);
};
ws.onclose = (event) => {
console.warn(
`Connection closed to ${relayUrl}:`,
event.code,
event.reason,
);
};
ws.onmessage = (event) => {
console.log(`Message from ${relayUrl}:`, event.data);
try {
this.handleMessage(relayUrl, JSON.parse(event.data));
} catch (error) {
console.error(
`Failed to parse message from ${relayUrl}:`,
error,
event.data,
);
}
};
this.relays.set(relayUrl, ws);
// Timeout after 5 seconds
setTimeout(() => {
if (ws.readyState !== WebSocket.OPEN) {
console.warn(`Connection timeout for ${relayUrl}`);
resolve(false);
}
}, 5000);
} catch (error) {
console.error(`Failed to create WebSocket for ${relayUrl}:`, error);
resolve(false);
}
});
}
handleMessage(relayUrl, message) {
console.log(`Processing message from ${relayUrl}:`, message);
const [type, subscriptionId, event, ...rest] = message;
@ -238,6 +293,9 @@ class NostrClient { @@ -238,6 +293,9 @@ class NostrClient {
// Create a global client instance
export const nostrClient = new NostrClient();
// Export the class for creating new instances
export { NostrClient };
// IndexedDB helpers for caching events (kind 0 profiles)
const DB_NAME = "nostrCache";
const DB_VERSION = 1;

2
pkg/version/version

@ -1 +1 @@ @@ -1 +1 @@
v0.12.2
v0.12.3
Loading…
Cancel
Save